grib2io.templates

GRIB2 section templates classes and metadata descriptor classes.

   1"""GRIB2 section templates classes and metadata descriptor classes."""
   2from dataclasses import dataclass, field
   3from collections import defaultdict
   4import datetime
   5from typing import Union
   6
   7from numpy import timedelta64, datetime64
   8
   9from . import tables
  10from . import utils
  11
  12# This dict is used by grib2io.Grib2Message.attrs_by_section() method
  13# to get attr names that defined in the Grib2Message base class.
  14_section_attrs = {0:['discipline'],
  15                  1:['originatingCenter', 'originatingSubCenter', 'masterTableInfo', 'localTableInfo',
  16                     'significanceOfReferenceTime', 'year', 'month', 'day', 'hour', 'minute', 'second',
  17                     'refDate', 'productionStatus', 'typeOfData'],
  18                  2:[],
  19                  3:['sourceOfGridDefinition', 'numberOfDataPoints', 'interpretationOfListOfNumbers',
  20                     'gridDefinitionTemplateNumber', 'shapeOfEarth', 'earthRadius', 'earthMajorAxis',
  21                     'earthMinorAxis', 'resolutionAndComponentFlags', 'ny', 'nx', 'scanModeFlags'],
  22                  4:[],
  23                  5:['dataRepresentationTemplateNumber','numberOfPackedValues','typeOfValues'],
  24                  6:['bitMapFlag'],
  25                  7:[],
  26                  8:[],}
  27
  28
  29def _calculate_scale_factor(value: float):
  30    """
  31    Calculate the scale factor for a given value.
  32
  33    Parameters
  34    ----------
  35    value : float
  36        Value for which to calculate the scale factor.
  37
  38    Returns
  39    -------
  40    int
  41        Scale factor for the value.
  42    """
  43    return len(f"{value}".split(".")[1].rstrip("0"))
  44
  45
  46class Grib2Metadata:
  47    """
  48    Class to hold GRIB2 metadata.
  49
  50    Stores both numeric code value as stored in GRIB2 and its plain language
  51    definition.
  52
  53    Attributes
  54    ----------
  55    value : int
  56        GRIB2 metadata integer code value.
  57    table : str, optional
  58        GRIB2 table to lookup the `value`. Default is None.
  59    definition : str
  60        Plain language description of numeric metadata.
  61    """
  62    __slots__ = ('value','table')
  63    def __init__(self, value, table=None):
  64        self.value = value
  65        self.table = table
  66    def __call__(self):
  67        return self.value
  68    def __hash__(self):
  69        # AS- added hash() to self.value as pandas was raising error about some
  70        # non integer returns from hash method
  71        return hash(self.value)
  72    def __repr__(self):
  73        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
  74    def __str__(self):
  75        return f'{self.value} - {self.definition}'
  76    def __eq__(self,other):
  77        return self.value == other or self.definition[0] == other
  78    def __gt__(self,other):
  79        return self.value > other
  80    def __ge__(self,other):
  81        return self.value >= other
  82    def __lt__(self,other):
  83        return self.value < other
  84    def __le__(self,other):
  85        return self.value <= other
  86    def __contains__(self,other):
  87        return other in self.definition
  88    def __hash__(self):
  89        return hash(self.value)
  90    def __index__(self):
  91        return int(self.value)
  92    @property
  93    def definition(self):
  94        return tables.get_value_from_table(self.value,self.table)
  95    def show_table(self):
  96        """Provide the table related to this metadata."""
  97        return tables.get_table(self.table)
  98
  99# ----------------------------------------------------------------------------------------
 100# Descriptor Classes for Section 0 metadata.
 101# ----------------------------------------------------------------------------------------
 102class IndicatorSection:
 103    """
 104    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
 105    """
 106    def __get__(self, obj, objtype=None):
 107        return obj.section0
 108    def __set__(self, obj, value):
 109        obj.section0 = value
 110
 111class Discipline:
 112    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
 113    def __get__(self, obj, objtype=None):
 114        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
 115    def __set__(self, obj, value):
 116        obj.section0[2] = value
 117
 118
 119# ----------------------------------------------------------------------------------------
 120# Descriptor Classes for Section 1 metadata.
 121# ----------------------------------------------------------------------------------------
 122class IdentificationSection:
 123    """
 124    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
 125    """
 126    def __get__(self, obj, objtype=None):
 127        return obj.section1
 128    def __set__(self, obj, value):
 129        obj.section1 = value
 130
 131class OriginatingCenter:
 132    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
 133    def __get__(self, obj, objtype=None):
 134        return Grib2Metadata(obj.section1[0],table='originating_centers')
 135    def __set__(self, obj, value):
 136        obj.section1[0] = value
 137
 138class OriginatingSubCenter:
 139    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
 140    def __get__(self, obj, objtype=None):
 141        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
 142    def __set__(self, obj, value):
 143        obj.section1[1] = value
 144
 145class MasterTableInfo:
 146    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
 147    def __get__(self, obj, objtype=None):
 148        return Grib2Metadata(obj.section1[2],table='1.0')
 149    def __set__(self, obj, value):
 150        obj.section1[2] = value
 151
 152class LocalTableInfo:
 153    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
 154    def __get__(self, obj, objtype=None):
 155        return Grib2Metadata(obj.section1[3],table='1.1')
 156    def __set__(self, obj, value):
 157        obj.section1[3] = value
 158
 159class SignificanceOfReferenceTime:
 160    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
 161    def __get__(self, obj, objtype=None):
 162        return Grib2Metadata(obj.section1[4],table='1.2')
 163    def __set__(self, obj, value):
 164        obj.section1[4] = value
 165
 166class Year:
 167    """Year of reference time"""
 168    def __get__(self, obj, objtype=None):
 169        return obj.section1[5]
 170    def __set__(self, obj, value):
 171        obj.section1[5] = value
 172
 173class Month:
 174    """Month of reference time"""
 175    def __get__(self, obj, objtype=None):
 176        return obj.section1[6]
 177    def __set__(self, obj, value):
 178        obj.section1[6] = value
 179
 180class Day:
 181    """Day of reference time"""
 182    def __get__(self, obj, objtype=None):
 183        return obj.section1[7]
 184    def __set__(self, obj, value):
 185        obj.section1[7] = value
 186
 187class Hour:
 188    """Hour of reference time"""
 189    def __get__(self, obj, objtype=None):
 190        return obj.section1[8]
 191    def __set__(self, obj, value):
 192        obj.section1[8] = value
 193
 194class Minute:
 195    """Minute of reference time"""
 196    def __get__(self, obj, objtype=None):
 197        return obj.section1[9]
 198    def __set__(self, obj, value):
 199        obj.section1[9] = value
 200
 201class Second:
 202    """Second of reference time"""
 203    def __get__(self, obj, objtype=None):
 204        return obj.section1[10]
 205    def __set__(self, obj, value):
 206        obj.section1[10] = value
 207
 208class RefDate:
 209    """Reference Date. NOTE: This is a `datetime.datetime` object."""
 210    def __get__(self, obj, objtype=None):
 211        return datetime.datetime(*obj.section1[5:11])
 212    def __set__(self, obj, value):
 213        if isinstance(value, datetime64):
 214            timestamp = (value - datetime64("1970-01-01T00:00:00")) / timedelta64(
 215                1, "s"
 216            )
 217            value = datetime.datetime.utcfromtimestamp(timestamp)
 218        if isinstance(value, datetime.datetime):
 219            obj.section1[5] = value.year
 220            obj.section1[6] = value.month
 221            obj.section1[7] = value.day
 222            obj.section1[8] = value.hour
 223            obj.section1[9] = value.minute
 224            obj.section1[10] = value.second
 225        else:
 226            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
 227            raise TypeError(msg)
 228
 229class ProductionStatus:
 230    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
 231    def __get__(self, obj, objtype=None):
 232        return Grib2Metadata(obj.section1[11],table='1.3')
 233    def __set__(self, obj, value):
 234        obj.section1[11] = value
 235
 236class TypeOfData:
 237    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
 238    def __get__(self, obj, objtype=None):
 239        return Grib2Metadata(obj.section1[12],table='1.4')
 240    def __set__(self, obj, value):
 241        obj.section1[12] = value
 242
 243# ----------------------------------------------------------------------------------------
 244# Descriptor Classes for Section 2 metadata.
 245# ----------------------------------------------------------------------------------------
 246
 247# ----------------------------------------------------------------------------------------
 248# Descriptor Classes for Section 3 metadata.
 249# ----------------------------------------------------------------------------------------
 250class GridDefinitionSection:
 251    """
 252    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
 253    """
 254    def __get__(self, obj, objtype=None):
 255        return obj.section3[0:5]
 256    def __set__(self, obj, value):
 257        raise RuntimeError
 258
 259class SourceOfGridDefinition:
 260    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
 261    def __get__(self, obj, objtype=None):
 262        return Grib2Metadata(obj.section3[0],table='3.0')
 263    def __set__(self, obj, value):
 264        raise RuntimeError
 265
 266class NumberOfDataPoints:
 267    """Number of Data Points"""
 268    def __get__(self, obj, objtype=None):
 269        return obj.section3[1]
 270    def __set__(self, obj, value):
 271        raise RuntimeError
 272
 273class InterpretationOfListOfNumbers:
 274    """Interpretation of List of Numbers"""
 275    def __get__(self, obj, objtype=None):
 276        return Grib2Metadata(obj.section3[3],table='3.11')
 277    def __set__(self, obj, value):
 278        raise RuntimeError
 279
 280class GridDefinitionTemplateNumber:
 281    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
 282    def __get__(self, obj, objtype=None):
 283        return Grib2Metadata(obj.section3[4],table='3.1')
 284    def __set__(self, obj, value):
 285        raise RuntimeError
 286
 287class GridDefinitionTemplate:
 288    """Grid definition template"""
 289    def __get__(self, obj, objtype=None):
 290        return obj.section3[5:]
 291    def __set__(self, obj, value):
 292        raise RuntimeError
 293
 294class EarthParams:
 295    """Metadata about the shape of the Earth"""
 296    def __get__(self, obj, objtype=None):
 297        if obj.section3[5] in {50,51,52,1200}:
 298            return None
 299        return tables.get_table('earth_params')[str(obj.section3[5])]
 300    def __set__(self, obj, value):
 301        raise RuntimeError
 302
 303class DxSign:
 304    """Sign of Grid Length in X-Direction"""
 305    def __get__(self, obj, objtype=None):
 306        if obj.section3[4] in {0,1,203,205,32768,32769} and \
 307        obj.section3[17] > obj.section3[20]:
 308            return -1.0
 309        return 1.0
 310    def __set__(self, obj, value):
 311        raise RuntimeError
 312
 313class DySign:
 314    """Sign of Grid Length in Y-Direction"""
 315    def __get__(self, obj, objtype=None):
 316        if obj.section3[4] in {0,1,203,205,32768,32769} and \
 317        obj.section3[16] > obj.section3[19]:
 318            return -1.0
 319        return 1.0
 320    def __set__(self, obj, value):
 321        raise RuntimeError
 322
 323class LLScaleFactor:
 324    """Scale Factor for Lats/Lons"""
 325    def __get__(self, obj, objtype=None):
 326        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
 327            llscalefactor = float(obj.section3[14])
 328            if llscalefactor == 0:
 329                return 1
 330            return llscalefactor
 331        return 1
 332    def __set__(self, obj, value):
 333        raise RuntimeError
 334
 335class LLDivisor:
 336    """Divisor Value for scaling Lats/Lons"""
 337    def __get__(self, obj, objtype=None):
 338        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
 339            lldivisor = float(obj.section3[15])
 340            if lldivisor <= 0:
 341                return 1.e6
 342            return lldivisor
 343        return 1.e6
 344    def __set__(self, obj, value):
 345        raise RuntimeError
 346
 347class XYDivisor:
 348    """Divisor Value for scaling grid lengths"""
 349    def __get__(self, obj, objtype=None):
 350        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
 351            return obj._lldivisor
 352        return 1.e3
 353    def __set__(self, obj, value):
 354        raise RuntimeError
 355
 356class ShapeOfEarth:
 357    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
 358    def __get__(self, obj, objtype=None):
 359        return Grib2Metadata(obj.section3[5],table='3.2')
 360    def __set__(self, obj, value):
 361        obj.section3[5] = value
 362
 363class EarthShape:
 364    """Description of the shape of the Earth"""
 365    def __get__(self, obj, objtype=None):
 366        return obj._earthparams['shape']
 367    def __set__(self, obj, value):
 368        raise RuntimeError
 369
 370class EarthRadius:
 371    """Radius of the Earth (Assumes "spherical")"""
 372    def __get__(self, obj, objtype=None):
 373        ep = obj._earthparams
 374        if ep['shape'] == 'spherical':
 375            if ep['radius'] is None:
 376                return obj.section3[7]/(10.**obj.section3[6])
 377            else:
 378                return ep['radius']
 379        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 380            return None
 381    def __set__(self, obj, value):
 382        raise RuntimeError
 383
 384class EarthMajorAxis:
 385    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
 386    def __get__(self, obj, objtype=None):
 387        ep = obj._earthparams
 388        if ep['shape'] == 'spherical':
 389            return None
 390        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 391            if ep['major_axis'] is None and ep['minor_axis'] is None:
 392                return obj.section3[9]/(10.**obj.section3[8])
 393            else:
 394                return ep['major_axis']
 395    def __set__(self, obj, value):
 396        raise RuntimeError
 397
 398class EarthMinorAxis:
 399    """Minor Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
 400    def __get__(self, obj, objtype=None):
 401        ep = obj._earthparams
 402        if ep['shape'] == 'spherical':
 403            return None
 404        if ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 405            if ep['major_axis'] is None and ep['minor_axis'] is None:
 406                return obj.section3[11]/(10.**section3[10])
 407            else:
 408                return ep['minor_axis']
 409    def __set__(self, obj, value):
 410        raise RuntimeError
 411
 412class Nx:
 413    """Number of grid points in the X-direction (generally East-West)"""
 414    def __get__(self, obj, objtype=None):
 415        return obj.section3[12]
 416    def __set__(self, obj, value):
 417        obj.section3[12] = value
 418        obj.section3[1] = value * obj.section3[13]
 419
 420class Ny:
 421    """Number of grid points in the Y-direction (generally North-South)"""
 422    def __get__(self, obj, objtype=None):
 423        return obj.section3[13]
 424    def __set__(self, obj, value):
 425        obj.section3[13] = value
 426        obj.section3[1] = value * obj.section3[12]
 427
 428class ScanModeFlags:
 429    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
 430    _key = {0:18, 1:18, 10:15, 20:17, 30:17, 31:17, 40:18, 41:18, 90:16, 110:15, 203:18, 204:18, 205:18, 32768:18, 32769:18}
 431    def __get__(self, obj, objtype=None):
 432        if obj.gdtn == 50:
 433            return [None, None, None, None]
 434        else:
 435            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
 436    def __set__(self, obj, value):
 437        obj.section3[self._key[obj.gdtn]+5] = value
 438
 439class ResolutionAndComponentFlags:
 440    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
 441    _key = {0:13, 1:13, 10:11, 20:11, 30:11, 31:11, 40:13, 41:13, 90:11, 110:11, 203:13, 204:13, 205:13, 32768:13, 32769:13}
 442    def __get__(self, obj, objtype=None):
 443        if obj.gdtn == 50:
 444            return [None for i in range(8)]
 445        else:
 446            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
 447    def __set__(self, obj, value):
 448        obj.section3[self._key[obj.gdtn]+5] = value
 449
 450class LatitudeFirstGridpoint:
 451    """Latitude of first gridpoint"""
 452    _key = {0:11, 1:11, 10:9, 20:9, 30:9, 31:9, 40:11, 41:11, 110:9, 203:11, 204:11, 205:11, 32768:11, 32769:11}
 453    def __get__(self, obj, objtype=None):
 454        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 455    def __set__(self, obj, value):
 456        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 457
 458class LongitudeFirstGridpoint:
 459    """Longitude of first gridpoint"""
 460    _key = {0:12, 1:12, 10:10, 20:10, 30:10, 31:10, 40:12, 41:12, 110:10, 203:12, 204:12, 205:12, 32768:12, 32769:12}
 461    def __get__(self, obj, objtype=None):
 462        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 463    def __set__(self, obj, value):
 464        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 465
 466class LatitudeLastGridpoint:
 467    """Latitude of last gridpoint"""
 468    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:19}
 469    def __get__(self, obj, objtype=None):
 470        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 471    def __set__(self, obj, value):
 472        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 473
 474class LongitudeLastGridpoint:
 475    """Longitude of last gridpoint"""
 476    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:20}
 477    def __get__(self, obj, objtype=None):
 478        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 479    def __set__(self, obj, value):
 480        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 481
 482class LatitudeCenterGridpoint:
 483    """Latitude of center gridpoint"""
 484    _key = {32768:14, 32769:14}
 485    def __get__(self, obj, objtype=None):
 486        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 487    def __set__(self, obj, value):
 488        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 489
 490class LongitudeCenterGridpoint:
 491    """Longitude of center gridpoint"""
 492    _key = {32768:15, 32769:15}
 493    def __get__(self, obj, objtype=None):
 494        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 495    def __set__(self, obj, value):
 496        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 497
 498class GridlengthXDirection:
 499    """Grid lenth in the X-Direction"""
 500    _key = {0:16, 1:16, 10:17, 20:14, 30:14, 31:14, 40:16, 41:16, 203:16, 204:16, 205:16, 32768:16, 32769:16}
 501    def __get__(self, obj, objtype=None):
 502        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
 503    def __set__(self, obj, value):
 504        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 505
 506class GridlengthYDirection:
 507    """Grid lenth in the Y-Direction"""
 508    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
 509    def __get__(self, obj, objtype=None):
 510        if obj.gdtn in {40, 41}:
 511            return obj.gridlengthXDirection
 512        else:
 513            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
 514    def __set__(self, obj, value):
 515        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 516
 517class NumberOfParallels:
 518    """Number of parallels between a pole and the equator"""
 519    _key = {40:17, 41:17}
 520    def __get__(self, obj, objtype=None):
 521        return obj.section3[self._key[obj.gdtn]+5]
 522    def __set__(self, obj, value):
 523        raise RuntimeError
 524
 525class LatitudeSouthernPole:
 526    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
 527    _key = {1:19, 30:20, 31:20, 41:19}
 528    def __get__(self, obj, objtype=None):
 529        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 530    def __set__(self, obj, value):
 531        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 532
 533class LongitudeSouthernPole:
 534    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
 535    _key = {1:20, 30:21, 31:21, 41:20}
 536    def __get__(self, obj, objtype=None):
 537        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 538    def __set__(self, obj, value):
 539        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 540
 541class AnglePoleRotation:
 542    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
 543    _key = {1:21, 41:21}
 544    def __get__(self, obj, objtype=None):
 545        return obj.section3[self._key[obj.gdtn]+5]
 546    def __set__(self, obj, value):
 547        obj.section3[self._key[obj.gdtn]+5] = int(value)
 548
 549class LatitudeTrueScale:
 550    """Latitude at which grid lengths are specified"""
 551    _key = {10:12, 20:12, 30:12, 31:12}
 552    def __get__(self, obj, objtype=None):
 553        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 554    def __set__(self, obj, value):
 555        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 556
 557class GridOrientation:
 558    """Longitude at which the grid is oriented"""
 559    _key = {10:16, 20:13, 30:13, 31:13}
 560    def __get__(self, obj, objtype=None):
 561        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 562    def __set__(self, obj, value):
 563        if obj.gdtn == 10 and (value < 0 or value > 90):
 564            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
 565        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 566
 567class ProjectionCenterFlag:
 568    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
 569    _key = {20:16, 30:16, 31:16}
 570    def __get__(self, obj, objtype=None):
 571        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
 572    def __set__(self, obj, value):
 573        obj.section3[self._key[obj.gdtn]+5] = value
 574
 575class StandardLatitude1:
 576    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
 577    _key = {30:18, 31:18}
 578    def __get__(self, obj, objtype=None):
 579        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 580    def __set__(self, obj, value):
 581        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 582
 583class StandardLatitude2:
 584    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
 585    _key = {30:19, 31:19}
 586    def __get__(self, obj, objtype=None):
 587        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 588    def __set__(self, obj, value):
 589        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 590
 591class SpectralFunctionParameters:
 592    """Spectral Function Parameters"""
 593    def __get__(self, obj, objtype=None):
 594        return obj.section3[0:3]
 595    def __set__(self, obj, value):
 596        obj.section3[0:3] = value[0:3]
 597
 598class ProjParameters:
 599    """PROJ Parameters to define the reference system"""
 600    def __get__(self, obj, objtype=None):
 601        projparams = {}
 602        projparams['a'] = 1.0
 603        projparams['b'] = 1.0
 604        if obj.earthRadius is not None:
 605            projparams['a'] = obj.earthRadius
 606            projparams['b'] = obj.earthRadius
 607        else:
 608            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
 609            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
 610        if obj.gdtn == 0:
 611            projparams['proj'] = 'longlat'
 612        elif obj.gdtn == 1:
 613            projparams['o_proj'] = 'longlat'
 614            projparams['proj'] = 'ob_tran'
 615            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
 616            projparams['o_lon_p'] = obj.anglePoleRotation
 617            projparams['lon_0'] = obj.longitudeSouthernPole
 618        elif obj.gdtn == 10:
 619            projparams['proj'] = 'merc'
 620            projparams['lat_ts'] = obj.latitudeTrueScale
 621            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
 622        elif obj.gdtn == 20:
 623            if obj.projectionCenterFlag == 0:
 624                lat0 = 90.0
 625            elif obj.projectionCenterFlag == 1:
 626                lat0 = -90.0
 627            projparams['proj'] = 'stere'
 628            projparams['lat_ts'] = obj.latitudeTrueScale
 629            projparams['lat_0'] = lat0
 630            projparams['lon_0'] = obj.gridOrientation
 631        elif obj.gdtn == 30:
 632            projparams['proj'] = 'lcc'
 633            projparams['lat_1'] = obj.standardLatitude1
 634            projparams['lat_2'] = obj.standardLatitude2
 635            projparams['lat_0'] = obj.latitudeTrueScale
 636            projparams['lon_0'] = obj.gridOrientation
 637        elif obj.gdtn == 31:
 638            projparams['proj'] = 'aea'
 639            projparams['lat_1'] = obj.standardLatitude1
 640            projparams['lat_2'] = obj.standardLatitude2
 641            projparams['lat_0'] = obj.latitudeTrueScale
 642            projparams['lon_0'] = obj.gridOrientation
 643        elif obj.gdtn == 40:
 644            projparams['proj'] = 'eqc'
 645        elif obj.gdtn == 32769:
 646            projparams['proj'] = 'aeqd'
 647            projparams['lon_0'] = obj.longitudeCenterGridpoint
 648            projparams['lat_0'] = obj.latitudeCenterGridpoint
 649        return projparams
 650    def __set__(self, obj, value):
 651        raise RuntimeError
 652
 653@dataclass(init=False)
 654class GridDefinitionTemplate0:
 655    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
 656    _len = 19
 657    _num = 0
 658    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 659    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 660    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 661    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 662    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 663    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 664    @classmethod
 665    @property
 666    def _attrs(cls):
 667        return list(cls.__dataclass_fields__.keys())
 668
 669@dataclass(init=False)
 670class GridDefinitionTemplate1:
 671    """[Grid Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-1.shtml)"""
 672    _len = 22
 673    _num = 1
 674    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 675    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 676    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 677    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 678    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 679    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 680    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 681    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 682    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 683    @classmethod
 684    @property
 685    def _attrs(cls):
 686        return list(cls.__dataclass_fields__.keys())
 687
 688@dataclass(init=False)
 689class GridDefinitionTemplate10:
 690    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
 691    _len = 19
 692    _num = 10
 693    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 694    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 695    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 696    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 697    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 698    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 699    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 700    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 701    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 702    @classmethod
 703    @property
 704    def _attrs(cls):
 705        return list(cls.__dataclass_fields__.keys())
 706
 707@dataclass(init=False)
 708class GridDefinitionTemplate20:
 709    """[Grid Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-20.shtml)"""
 710    _len = 18
 711    _num = 20
 712    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 713    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 714    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 715    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 716    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 717    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 718    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 719    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 720    @classmethod
 721    @property
 722    def _attrs(cls):
 723        return list(cls.__dataclass_fields__.keys())
 724
 725@dataclass(init=False)
 726class GridDefinitionTemplate30:
 727    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
 728    _len = 22
 729    _num = 30
 730    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 731    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 732    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 733    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 734    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 735    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 736    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 737    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 738    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 739    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 740    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 741    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 742    @classmethod
 743    @property
 744    def _attrs(cls):
 745        return list(cls.__dataclass_fields__.keys())
 746
 747@dataclass(init=False)
 748class GridDefinitionTemplate31:
 749    """[Grid Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-31.shtml)"""
 750    _len = 22
 751    _num = 31
 752    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 753    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 754    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 755    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 756    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 757    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 758    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 759    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 760    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 761    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 762    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 763    @classmethod
 764    @property
 765    def _attrs(cls):
 766        return list(cls.__dataclass_fields__.keys())
 767
 768@dataclass(init=False)
 769class GridDefinitionTemplate40:
 770    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
 771    _len = 19
 772    _num = 40
 773    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 774    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 775    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 776    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 777    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 778    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 779    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
 780    @classmethod
 781    @property
 782    def _attrs(cls):
 783        return list(cls.__dataclass_fields__.keys())
 784
 785@dataclass(init=False)
 786class GridDefinitionTemplate41:
 787    """[Grid Definition Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-41.shtml)"""
 788    _len = 22
 789    _num = 41
 790    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 791    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 792    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 793    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 794    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 795    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 796    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
 797    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 798    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 799    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 800    @classmethod
 801    @property
 802    def _attrs(cls):
 803        return list(cls.__dataclass_fields__.keys())
 804
 805@dataclass(init=False)
 806class GridDefinitionTemplate50:
 807    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
 808    _len = 5
 809    _num = 50
 810    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
 811    @classmethod
 812    @property
 813    def _attrs(cls):
 814        return list(cls.__dataclass_fields__.keys())
 815
 816@dataclass(init=False)
 817class GridDefinitionTemplate32768:
 818    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
 819    _len = 19
 820    _num = 32768
 821    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 822    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 823    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
 824    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
 825    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 826    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 827    @classmethod
 828    @property
 829    def _attrs(cls):
 830        return list(cls.__dataclass_fields__.keys())
 831
 832@dataclass(init=False)
 833class GridDefinitionTemplate32769:
 834    """[Grid Definition Template 32769](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32769.shtml)"""
 835    _len = 19
 836    _num = 32769
 837    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 838    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 839    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
 840    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
 841    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 842    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 843    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 844    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 845    @classmethod
 846    @property
 847    def _attrs(cls):
 848        return list(cls.__dataclass_fields__.keys())
 849
 850_gdt_by_gdtn = {0: GridDefinitionTemplate0,
 851    1: GridDefinitionTemplate1,
 852    10: GridDefinitionTemplate10,
 853    20: GridDefinitionTemplate20,
 854    30: GridDefinitionTemplate30,
 855    31: GridDefinitionTemplate31,
 856    40: GridDefinitionTemplate40,
 857    41: GridDefinitionTemplate41,
 858    50: GridDefinitionTemplate50,
 859    32768: GridDefinitionTemplate32768,
 860    32769: GridDefinitionTemplate32769,
 861    }
 862
 863def gdt_class_by_gdtn(gdtn: int):
 864    """
 865    Provides a Grid Definition Template class via the template number
 866
 867    Parameters
 868    ----------
 869    gdtn
 870        Grid definition template number.
 871
 872    Returns
 873    -------
 874    gdt_class_by_gdtn
 875        Grid definition template class object (not an instance).
 876    """
 877    return _gdt_by_gdtn[gdtn]
 878
 879# ----------------------------------------------------------------------------------------
 880# Descriptor Classes for Section 4 metadata.
 881# ----------------------------------------------------------------------------------------
 882class ProductDefinitionTemplateNumber:
 883    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
 884    def __get__(self, obj, objtype=None):
 885        return Grib2Metadata(obj.section4[1],table='4.0')
 886    def __set__(self, obj, value):
 887        raise RuntimeError
 888
 889#  since PDT begins at position 2 of section4, code written with +2 for added readability with grib2 documentation
 890class ProductDefinitionTemplate:
 891    """Product Definition Template"""
 892    def __get__(self, obj, objtype=None):
 893        return obj.section4[2:]
 894    def __set__(self, obj, value):
 895        raise RuntimeError
 896
 897class ParameterCategory:
 898    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
 899    _key = defaultdict(lambda: 0)
 900    def __get__(self, obj, objtype=None):
 901        return obj.section4[0+2]
 902    def __set__(self, obj, value):
 903        obj.section4[self._key[obj.pdtn]+2] = value
 904
 905class ParameterNumber:
 906    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
 907    _key = defaultdict(lambda: 1)
 908    def __get__(self, obj, objtype=None):
 909        return obj.section4[1+2]
 910    def __set__(self, obj, value):
 911        obj.section4[self._key[obj.pdtn]+2] = value
 912
 913class VarInfo:
 914    """
 915    Variable Information.
 916
 917    These are the metadata returned for a specific variable according to
 918    discipline, parameter category, and parameter number.
 919    """
 920    def __get__(self, obj, objtype=None):
 921        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
 922    def __set__(self, obj, value):
 923        raise RuntimeError
 924
 925class FullName:
 926    """Full name of the Variable."""
 927    def __get__(self, obj, objtype=None):
 928        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
 929    def __set__(self, obj, value):
 930        raise RuntimeError
 931
 932class Units:
 933    """Units of the Variable."""
 934    def __get__(self, obj, objtype=None):
 935        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
 936    def __set__(self, obj, value):
 937        raise RuntimeError
 938
 939class ShortName:
 940    """ Short name of the variable (i.e. the variable abbreviation)."""
 941    def __get__(self, obj, objtype=None):
 942        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[2]
 943    def __set__(self, obj, value):
 944        raise RuntimeError
 945
 946class TypeOfGeneratingProcess:
 947    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
 948    _key = defaultdict(lambda: 2, {48:13})
 949    #_key = {0:2, 1:2, 2:2, 5:2, 6:2, 8:2, 9:2, 10:2, 11:2, 12:2, 15:2, 48:13}
 950    def __get__(self, obj, objtype=None):
 951        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
 952    def __set__(self, obj, value):
 953        obj.section4[self._key[obj.pdtn]+2] = value
 954
 955class BackgroundGeneratingProcessIdentifier:
 956    """Background Generating Process Identifier"""
 957    _key = defaultdict(lambda: 3, {48:14})
 958    #_key = {0:3, 1:3, 2:3, 5:3, 6:3, 8:3, 9:3, 10:3, 11:3, 12:3, 15:3, 48:14}
 959    def __get__(self, obj, objtype=None):
 960        return obj.section4[self._key[obj.pdtn]+2]
 961    def __set__(self, obj, value):
 962        obj.section4[self._key[obj.pdtn]+2] = value
 963
 964class GeneratingProcess:
 965    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
 966    _key = defaultdict(lambda: 4, {48:15})
 967    #_key = {0:4, 1:4, 2:4, 5:4, 6:4, 8:4, 9:4, 10:4, 11:4, 12:4, 15:4, 48:15}
 968    def __get__(self, obj, objtype=None):
 969        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
 970    def __set__(self, obj, value):
 971        obj.section4[self._key[obj.pdtn]+2] = value
 972
 973class HoursAfterDataCutoff:
 974    """Hours of observational data cutoff after reference time."""
 975    _key = defaultdict(lambda: 5, {48:16})
 976    def __get__(self, obj, objtype=None):
 977        return obj.section4[self._key[obj.pdtn]+2]
 978    def __set__(self, obj, value):
 979        obj.section4[self._key[obj.pdtn]+2] = value
 980
 981class MinutesAfterDataCutoff:
 982    """Minutes of observational data cutoff after reference time."""
 983    _key = defaultdict(lambda: 6, {48:17})
 984    def __get__(self, obj, objtype=None):
 985        return obj.section4[self._key[obj.pdtn]+2]
 986    def __set__(self, obj, value):
 987        obj.section4[self._key[obj.pdtn]+2] = value
 988
 989class UnitOfForecastTime:
 990    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
 991    _key = defaultdict(lambda: 7, {48:18})
 992    #_key = {0:7, 1:7, 2:7, 5:7, 6:7, 8:7, 9:7, 10:7, 11:7, 12:7, 15:7, 48:18}
 993    def __get__(self, obj, objtype=None):
 994        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
 995    def __set__(self, obj, value):
 996        obj.section4[self._key[obj.pdtn]+2] = value
 997
 998class ValueOfForecastTime:
 999    """Value of forecast time in units defined by `UnitofForecastTime`."""
1000    _key = defaultdict(lambda: 8, {48:19})
1001    def __get__(self, obj, objtype=None):
1002        return obj.section4[self._key[obj.pdtn]+2]
1003    def __set__(self, obj, value):
1004        obj.section4[self._key[obj.pdtn]+2] = value
1005
1006class LeadTime:
1007    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
1008
1009    def __get__(self, obj, objtype=None):
1010        return utils.get_leadtime(obj.section1, obj.section4[1], obj.section4[2:])
1011
1012    def __set__(self, obj, value):
1013        pdt = obj.section4[2:]
1014
1015        # For the tables below, the key is the PDTN and the value is the slice
1016        # of the PDT that contains the end date of the accumulation.
1017        # This is only needed for PDTNs 8-12.
1018        _key = {
1019            8: slice(15, 21),
1020            9: slice(22, 28),
1021            10: slice(16, 22),
1022            11: slice(18, 24),
1023            12: slice(17, 23),
1024        }
1025
1026        accumulation_offset = 0
1027        if obj.pdtn in _key:
1028            accumulation_end_date = _key[obj.pdtn]
1029            accumulation_key = accumulation_end_date.stop + 5
1030            accumulation_offset = int(
1031                timedelta64(pdt[accumulation_key], "h") / timedelta64(1, "h")
1032            )
1033            accumulation_offset = accumulation_offset / (
1034                tables.get_value_from_table(
1035                    pdt[accumulation_key - 1], "scale_time_hours"
1036                )
1037            )
1038
1039            refdate = datetime.datetime(*obj.section1[5:11])
1040            pdt[_key[obj.pdtn]] = (
1041                datetime.timedelta(hours=accumulation_offset) + refdate
1042            ).timetuple()[:6]
1043
1044        # All messages need the leadTime value set, but for PDTNs 8-12, the
1045        # leadTime value has to be set to the beginning of the accumulation
1046        # period which is done here by subtracting the already calculated
1047        # value accumulation_offset.
1048        lead_time_index = 8
1049        if obj.pdtn == 48:
1050            lead_time_index = 19
1051
1052        ivalue = int(timedelta64(value, "h") / timedelta64(1, "h"))
1053
1054        pdt[lead_time_index] = (
1055            ivalue
1056            / (
1057                tables.get_value_from_table(
1058                    pdt[lead_time_index - 1], "scale_time_hours"
1059                )
1060            )
1061            - accumulation_offset
1062        )
1063
1064class FixedSfc1Info:
1065    """Information of the first fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1066    _key = defaultdict(lambda: 9, {48:20})
1067    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1068    def __get__(self, obj, objtype=None):
1069        if obj.section4[self._key[obj.pdtn]+2] == 255:
1070            return [None, None]
1071        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1072    def __set__(self, obj, value):
1073        raise NotImplementedError
1074
1075class FixedSfc2Info:
1076    """Information of the second fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1077    _key = defaultdict(lambda: 12, {48:23})
1078    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1079    def __get__(self, obj, objtype=None):
1080        if obj.section4[self._key[obj.pdtn]+2] == 255:
1081            return [None, None]
1082        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1083    def __set__(self, obj, value):
1084        raise NotImplementedError
1085
1086class TypeOfFirstFixedSurface:
1087    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1088    _key = defaultdict(lambda: 9, {48:20})
1089    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1090    def __get__(self, obj, objtype=None):
1091        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1092    def __set__(self, obj, value):
1093        obj.section4[self._key[obj.pdtn]+2] = value
1094
1095class ScaleFactorOfFirstFixedSurface:
1096    """Scale Factor of First Fixed Surface"""
1097    _key = defaultdict(lambda: 10, {48:21})
1098    #_key = {0:10, 1:10, 2:10, 5:10, 6:10, 8:10, 9:10, 10:10, 11:10, 12:10, 15:10, 48:21}
1099    def __get__(self, obj, objtype=None):
1100        return obj.section4[self._key[obj.pdtn]+2]
1101    def __set__(self, obj, value):
1102        obj.section4[self._key[obj.pdtn]+2] = value
1103
1104class ScaledValueOfFirstFixedSurface:
1105    """Scaled Value Of First Fixed Surface"""
1106    _key = defaultdict(lambda: 11, {48:22})
1107    #_key = {0:11, 1:11, 2:11, 5:11, 6:11, 8:11, 9:11, 10:11, 11:11, 12:11, 15:11, 48:22}
1108    def __get__(self, obj, objtype=None):
1109        return obj.section4[self._key[obj.pdtn]+2]
1110    def __set__(self, obj, value):
1111        obj.section4[self._key[obj.pdtn]+2] = value
1112
1113class UnitOfFirstFixedSurface:
1114    """Units of First Fixed Surface"""
1115    def __get__(self, obj, objtype=None):
1116        return obj._fixedsfc1info[1]
1117    def __set__(self, obj, value):
1118        pass
1119
1120class ValueOfFirstFixedSurface:
1121    """Value of First Fixed Surface"""
1122    def __get__(self, obj, objtype=None):
1123        scale_factor = getattr(obj, "scaleFactorOfFirstFixedSurface")
1124        scaled_value = getattr(obj, "scaledValueOfFirstFixedSurface")
1125        return scaled_value / (10.**scale_factor)
1126    def __set__(self, obj, value):
1127        scale = _calculate_scale_factor(value)
1128        setattr(obj, "scaleFactorOfFirstFixedSurface", scale)
1129        setattr(obj, "scaledValueOfFirstFixedSurface", value * 10**scale)
1130
1131class TypeOfSecondFixedSurface:
1132    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1133    _key = defaultdict(lambda: 12, {48:23})
1134    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1135    def __get__(self, obj, objtype=None):
1136        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1137    def __set__(self, obj, value):
1138        obj.section4[self._key[obj.pdtn]+2] = value
1139
1140class ScaleFactorOfSecondFixedSurface:
1141    """Scale Factor of Second Fixed Surface"""
1142    _key = defaultdict(lambda: 13, {48:24})
1143    #_key = {0:13, 1:13, 2:13, 5:13, 6:13, 8:13, 9:13, 10:13, 11:13, 12:13, 15:13, 48:24}
1144    def __get__(self, obj, objtype=None):
1145        return obj.section4[self._key[obj.pdtn]+2]
1146    def __set__(self, obj, value):
1147        obj.section4[self._key[obj.pdtn]+2] = value
1148
1149class ScaledValueOfSecondFixedSurface:
1150    """Scaled Value Of Second Fixed Surface"""
1151    _key = defaultdict(lambda: 14, {48:25})
1152    #_key = {0:14, 1:14, 2:14, 5:14, 6:14, 8:14, 9:14, 10:14, 11:14, 12:14, 15:14, 48:25}
1153    def __get__(self, obj, objtype=None):
1154        return obj.section4[self._key[obj.pdtn]+2]
1155    def __set__(self, obj, value):
1156        obj.section4[self._key[obj.pdtn]+2] = value
1157
1158class UnitOfSecondFixedSurface:
1159    """Units of Second Fixed Surface"""
1160    def __get__(self, obj, objtype=None):
1161        return obj._fixedsfc2info[1]
1162    def __set__(self, obj, value):
1163        pass
1164
1165class ValueOfSecondFixedSurface:
1166    """Value of Second Fixed Surface"""
1167    def __get__(self, obj, objtype=None):
1168        scale_factor = getattr(obj, "scaleFactorOfSecondFixedSurface")
1169        scaled_value = getattr(obj, "scaledValueOfSecondFixedSurface")
1170        return scaled_value / (10.**scale_factor)
1171    def __set__(self, obj, value):
1172        scale = _calculate_scale_factor(value)
1173        setattr(obj, "scaleFactorOfSecondFixedSurface", scale)
1174        setattr(obj, "scaledValueOfSecondFixedSurface", value * 10**scale)
1175
1176class Level:
1177    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1178    def __get__(self, obj, objtype=None):
1179        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1180    def __set__(self, obj, value):
1181        pass
1182
1183class TypeOfEnsembleForecast:
1184    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1185    _key = {1:15, 11:15}
1186    def __get__(self, obj, objtype=None):
1187        pdtn = obj.section4[1]
1188        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1189    def __set__(self, obj, value):
1190        pdtn = obj.section4[1]
1191        obj.section4[self._key[pdtn]+2] = value
1192
1193class PerturbationNumber:
1194    """Ensemble Perturbation Number"""
1195    _key = {1:16, 11:16}
1196    def __get__(self, obj, objtype=None):
1197        pdtn = obj.section4[1]
1198        return obj.section4[self._key[pdtn]+2]
1199    def __set__(self, obj, value):
1200        pdtn = obj.section4[1]
1201        obj.section4[self._key[pdtn]+2] = value
1202
1203class NumberOfEnsembleForecasts:
1204    """Total Number of Ensemble Forecasts"""
1205    _key = {1:17, 2:16, 11:17, 12:16}
1206    def __get__(self, obj, objtype=None):
1207        pdtn = obj.section4[1]
1208        return obj.section4[self._key[pdtn]+2]
1209    def __set__(self, obj, value):
1210        pdtn = obj.section4[1]
1211        obj.section4[self._key[pdtn]+2] = value
1212
1213class TypeOfDerivedForecast:
1214    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1215    _key = {2:15, 12:15}
1216    def __get__(self, obj, objtype=None):
1217        pdtn = obj.section4[1]
1218        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1219    def __set__(self, obj, value):
1220        pdtn = obj.section4[1]
1221        obj.section4[self._key[pdtn]+2] = value
1222
1223class ForecastProbabilityNumber:
1224    """Forecast Probability Number"""
1225    _key = {5:15, 9:15}
1226    def __get__(self, obj, objtype=None):
1227        pdtn = obj.section4[1]
1228        return obj.section4[self._key[pdtn]+2]
1229    def __set__(self, obj, value):
1230        pdtn = obj.section4[1]
1231        obj.section4[self._key[pdtn]+2] = value
1232
1233class TotalNumberOfForecastProbabilities:
1234    """Total Number of Forecast Probabilities"""
1235    _key = {5:16, 9:16}
1236    def __get__(self, obj, objtype=None):
1237        pdtn = obj.section4[1]
1238        return obj.section4[self._key[pdtn]+2]
1239    def __set__(self, obj, value):
1240        pdtn = obj.section4[1]
1241        obj.section4[self._key[pdtn]+2] = value
1242
1243class TypeOfProbability:
1244    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1245    _key = {5:17, 9:17}
1246    def __get__(self, obj, objtype=None):
1247        pdtn = obj.section4[1]
1248        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1249    def __set__(self, obj, value):
1250        pdtn = obj.section4[1]
1251        obj.section4[self._key[pdtn]+2] = value
1252
1253class ScaleFactorOfThresholdLowerLimit:
1254    """Scale Factor of Threshold Lower Limit"""
1255    _key = {5:18, 9:18}
1256    def __get__(self, obj, objtype=None):
1257        pdtn = obj.section4[1]
1258        return obj.section4[self._key[pdtn]+2]
1259    def __set__(self, obj, value):
1260        pdtn = obj.section4[1]
1261        obj.section4[self._key[pdtn]+2] = value
1262
1263class ScaledValueOfThresholdLowerLimit:
1264    """Scaled Value of Threshold Lower Limit"""
1265    _key = {5:19, 9:19}
1266    def __get__(self, obj, objtype=None):
1267        pdtn = obj.section4[1]
1268        return obj.section4[self._key[pdtn]+2]
1269    def __set__(self, obj, value):
1270        pdtn = obj.section4[1]
1271        obj.section4[self._key[pdtn]+2] = value
1272
1273class ScaleFactorOfThresholdUpperLimit:
1274    """Scale Factor of Threshold Upper Limit"""
1275    _key = {5:20, 9:20}
1276    def __get__(self, obj, objtype=None):
1277        pdtn = obj.section4[1]
1278        return obj.section4[self._key[pdtn]+2]
1279    def __set__(self, obj, value):
1280        pdtn = obj.section4[1]
1281        obj.section4[self._key[pdtn]+2] = value
1282
1283class ScaledValueOfThresholdUpperLimit:
1284    """Scaled Value of Threshold Upper Limit"""
1285    _key = {5:21, 9:21}
1286    def __get__(self, obj, objtype=None):
1287        pdtn = obj.section4[1]
1288        return obj.section4[self._key[pdtn]+2]
1289    def __set__(self, obj, value):
1290        pdtn = obj.section4[1]
1291        obj.section4[self._key[pdtn]+2] = value
1292
1293class ThresholdLowerLimit:
1294    """Threshold Lower Limit"""
1295    def __get__(self, obj, objtype=None):
1296        scale_factor = getattr(obj, "scaleFactorOfThresholdLowerLimit")
1297        scaled_value = getattr(obj, "scaledValueOfThresholdLowerLimit")
1298        if scale_factor == -127 and scaled_value == 255:
1299            return 0.0
1300        return scaled_value / (10.**scale_factor)
1301    def __set__(self, obj, value):
1302        scale = _calculate_scale_factor(value)
1303        setattr(obj, "scaleFactorOfThresholdLowerLimit", scale)
1304        setattr(obj, "scaledValueOfThresholdLowerLimit", value * 10**scale)
1305
1306class ThresholdUpperLimit:
1307    """Threshold Upper Limit"""
1308    def __get__(self, obj, objtype=None):
1309        scale_factor = getattr(obj, "scaleFactorOfThresholdUpperLimit")
1310        scaled_value = getattr(obj, "scaledValueOfThresholdUpperLimit")
1311        if scale_factor == -127 and scaled_value == 255:
1312            return 0.0
1313        return scaled_value / (10.**scale_factor)
1314    def __set__(self, obj, value):
1315        scale = _calculate_scale_factor(value)
1316        setattr(obj, "scaleFactorOfThresholdUpperLimit", scale)
1317        setattr(obj, "scaledValueOfThresholdUpperLimit", value * 10**scale)
1318
1319class Threshold:
1320    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1321    def __get__(self, obj, objtype=None):
1322        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1323    def __set__(self, obj, value):
1324        pass
1325
1326class PercentileValue:
1327    """Percentile Value"""
1328    _key = {6:15, 10:15}
1329    def __get__(self, obj, objtype=None):
1330        pdtn = obj.section4[1]
1331        return obj.section4[self._key[pdtn]+2]
1332    def __set__(self, obj, value):
1333        pdtn = obj.section4[1]
1334        obj.section4[self._key[pdtn]+2] = value
1335
1336class YearOfEndOfTimePeriod:
1337    """Year of End of Forecast Time Period"""
1338    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1339    def __get__(self, obj, objtype=None):
1340        pdtn = obj.section4[1]
1341        return obj.section4[self._key[pdtn]+2]
1342    def __set__(self, obj, value):
1343        pdtn = obj.section4[1]
1344        obj.section4[self._key[pdtn]+2] = value
1345
1346class MonthOfEndOfTimePeriod:
1347    """Month Year of End of Forecast Time Period"""
1348    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1349    def __get__(self, obj, objtype=None):
1350        pdtn = obj.section4[1]
1351        return obj.section4[self._key[pdtn]+2]
1352    def __set__(self, obj, value):
1353        pdtn = obj.section4[1]
1354        obj.section4[self._key[pdtn]+2] = value
1355
1356class DayOfEndOfTimePeriod:
1357    """Day Year of End of Forecast Time Period"""
1358    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1359    def __get__(self, obj, objtype=None):
1360        pdtn = obj.section4[1]
1361        return obj.section4[self._key[pdtn]+2]
1362    def __set__(self, obj, value):
1363        pdtn = obj.section4[1]
1364        obj.section4[self._key[pdtn]+2] = value
1365
1366class HourOfEndOfTimePeriod:
1367    """Hour Year of End of Forecast Time Period"""
1368    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1369    def __get__(self, obj, objtype=None):
1370        pdtn = obj.section4[1]
1371        return obj.section4[self._key[pdtn]+2]
1372    def __set__(self, obj, value):
1373        pdtn = obj.section4[1]
1374        obj.section4[self._key[pdtn]+2] = value
1375
1376class MinuteOfEndOfTimePeriod:
1377    """Minute Year of End of Forecast Time Period"""
1378    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1379    def __get__(self, obj, objtype=None):
1380        pdtn = obj.section4[1]
1381        return obj.section4[self._key[pdtn]+2]
1382    def __set__(self, obj, value):
1383        pdtn = obj.section4[1]
1384        obj.section4[self._key[pdtn]+2] = value
1385
1386class SecondOfEndOfTimePeriod:
1387    """Second Year of End of Forecast Time Period"""
1388    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1389    def __get__(self, obj, objtype=None):
1390        pdtn = obj.section4[1]
1391        return obj.section4[self._key[pdtn]+2]
1392    def __set__(self, obj, value):
1393        pdtn = obj.section4[1]
1394        obj.section4[self._key[pdtn]+2] = value
1395
1396class Duration:
1397    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1398    def __get__(self, obj, objtype=None):
1399        return utils.get_duration(obj.section4[1],obj.section4[2:])
1400    def __set__(self, obj, value):
1401        pass
1402
1403class ValidDate:
1404    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1405    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1406    def __get__(self, obj, objtype=None):
1407        pdtn = obj.section4[1]
1408        try:
1409            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1410            return datetime.datetime(*obj.section4[s])
1411        except(KeyError):
1412            return obj.refDate + obj.leadTime
1413    def __set__(self, obj, value):
1414        pass
1415
1416class NumberOfTimeRanges:
1417    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1418    _key = {8:21, 9:28, 10:22, 11:24, 12:23}
1419    def __get__(self, obj, objtype=None):
1420        pdtn = obj.section4[1]
1421        return obj.section4[self._key[pdtn]+2]
1422    def __set__(self, obj, value):
1423        pdtn = obj.section4[1]
1424        obj.section4[self._key[pdtn]+2] = value
1425
1426class NumberOfMissingValues:
1427    """Total number of data values missing in statistical process"""
1428    _key = {8:22, 9:29, 10:23, 11:25, 12:24}
1429    def __get__(self, obj, objtype=None):
1430        pdtn = obj.section4[1]
1431        return obj.section4[self._key[pdtn]+2]
1432    def __set__(self, obj, value):
1433        pdtn = obj.section4[1]
1434        obj.section4[self._key[pdtn]+2] = value
1435
1436class StatisticalProcess:
1437    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1438    _key = {8:23, 9:30, 10:24, 11:26, 12:25, 15:15}
1439    def __get__(self, obj, objtype=None):
1440        pdtn = obj.section4[1]
1441        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.10')
1442    def __set__(self, obj, value):
1443        pdtn = obj.section4[1]
1444        obj.section4[self._key[pdtn]+2] = value
1445
1446class TypeOfTimeIncrementOfStatisticalProcess:
1447    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1448    _key = {8:24, 9:31, 10:25, 11:27, 12:26}
1449    def __get__(self, obj, objtype=None):
1450        pdtn = obj.section4[1]
1451        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.11')
1452    def __set__(self, obj, value):
1453        pdtn = obj.section4[1]
1454        obj.section4[self._key[pdtn]+2] = value
1455
1456class UnitOfTimeRangeOfStatisticalProcess:
1457    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1458    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
1459    def __get__(self, obj, objtype=None):
1460        pdtn = obj.section4[1]
1461        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1462    def __set__(self, obj, value):
1463        pdtn = obj.section4[1]
1464        obj.section4[self._key[pdtn]+2] = value
1465
1466class TimeRangeOfStatisticalProcess:
1467    """Time Range of Statistical Process"""
1468    _key = {8:26, 9:33, 10:27, 11:29, 12:28}
1469    def __get__(self, obj, objtype=None):
1470        pdtn = obj.section4[1]
1471        return obj.section4[self._key[pdtn]+2]
1472    def __set__(self, obj, value):
1473        pdtn = obj.section4[1]
1474        obj.section4[self._key[pdtn]+2] = value
1475
1476class UnitOfTimeRangeOfSuccessiveFields:
1477    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1478    _key = {8:27, 9:34, 10:28, 11:30, 12:29}
1479    def __get__(self, obj, objtype=None):
1480        pdtn = obj.section4[1]
1481        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1482    def __set__(self, obj, value):
1483        pdtn = obj.section4[1]
1484        obj.section4[self._key[pdtn]+2] = value
1485
1486class TimeIncrementOfSuccessiveFields:
1487    """Time Increment of Successive Fields"""
1488    _key = {8:28, 9:35, 10:29, 11:31, 12:30}
1489    def __get__(self, obj, objtype=None):
1490        pdtn = obj.section4[1]
1491        return obj.section4[self._key[pdtn]+2]
1492    def __set__(self, obj, value):
1493        pdtn = obj.section4[1]
1494        obj.section4[self._key[pdtn]+2] = value
1495
1496class TypeOfStatisticalProcessing:
1497    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1498    _key = {15:16}
1499    def __get__(self, obj, objtype=None):
1500        pdtn = obj.section4[1]
1501        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1502    def __set__(self, obj, value):
1503        pdtn = obj.section4[1]
1504        obj.section4[self._key[pdtn]+2] = value
1505
1506class NumberOfDataPointsForSpatialProcessing:
1507    """Number of Data Points for Spatial Processing"""
1508    _key = {15:17}
1509    def __get__(self, obj, objtype=None):
1510        pdtn = obj.section4[1]
1511        return obj.section4[self._key[pdtn]+2]
1512    def __set__(self, obj, value):
1513        pdtn = obj.section4[1]
1514        obj.section4[self._key[pdtn]+2] = value
1515
1516class NumberOfContributingSpectralBands:
1517    """Number of Contributing Spectral Bands (NB)"""
1518    _key = {32:9}
1519    def __get__(self, obj, objtype=None):
1520        pdtn = obj.section4[1]
1521        return obj.section4[self._key[pdtn]+2]
1522    def __set__(self, obj, value):
1523        pdtn = obj.section4[1]
1524        obj.section4[self._key[pdtn]+2] = value
1525
1526class SatelliteSeries:
1527    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1528    _key = {32:10}
1529    def __get__(self, obj, objtype=None):
1530        pdtn = obj.section4[1]
1531        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1532    def __set__(self, obj, value):
1533        pass
1534
1535class SatelliteNumber:
1536    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1537    _key = {32:11}
1538    def __get__(self, obj, objtype=None):
1539        pdtn = obj.section4[1]
1540        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1541    def __set__(self, obj, value):
1542        pass
1543
1544class InstrumentType:
1545    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1546    _key = {32:12}
1547    def __get__(self, obj, objtype=None):
1548        pdtn = obj.section4[1]
1549        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1550    def __set__(self, obj, value):
1551        pass
1552
1553class ScaleFactorOfCentralWaveNumber:
1554    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1555    _key = {32:13}
1556    def __get__(self, obj, objtype=None):
1557        pdtn = obj.section4[1]
1558        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1559    def __set__(self, obj, value):
1560        pass
1561
1562class ScaledValueOfCentralWaveNumber:
1563    """Scaled Value Of Central WaveNumber of band NB"""
1564    _key = {32:14}
1565    def __get__(self, obj, objtype=None):
1566        pdtn = obj.section4[1]
1567        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1568    def __set__(self, obj, value):
1569        pass
1570
1571class TypeOfAerosol:
1572    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1573    _key = {48:2}
1574    def __get__(self, obj, objtype=None):
1575        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1576    def __set__(self, obj, value):
1577        obj.section4[self._key[obj.pdtn]+2] = value
1578
1579class TypeOfIntervalForAerosolSize:
1580    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1581    _key = {48:3}
1582    def __get__(self, obj, objtype=None):
1583        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1584    def __set__(self, obj, value):
1585        obj.section4[self._key[obj.pdtn]+2] = value
1586
1587class ScaleFactorOfFirstSize:
1588    """Scale Factor of First Size"""
1589    _key = {48:4}
1590    def __get__(self, obj, objtype=None):
1591        return obj.section4[self._key[obj.pdtn]+2]
1592    def __set__(self, obj, value):
1593        obj.section4[self._key[obj.pdtn]+2] = value
1594
1595class ScaledValueOfFirstSize:
1596    """Scaled Value of First Size"""
1597    _key = {48:5}
1598    def __get__(self, obj, objtype=None):
1599        return obj.section4[self._key[obj.pdtn]+2]
1600    def __set__(self, obj, value):
1601        obj.section4[self._key[obj.pdtn]+2] = value
1602
1603class ScaleFactorOfSecondSize:
1604    """Scale Factor of Second Size"""
1605    _key = {48:6}
1606    def __get__(self, obj, objtype=None):
1607        return obj.section4[self._key[obj.pdtn]+2]
1608    def __set__(self, obj, value):
1609        obj.section4[self._key[obj.pdtn]+2] = value
1610
1611class ScaledValueOfSecondSize:
1612    """Scaled Value of Second Size"""
1613    _key = {48:7}
1614    def __get__(self, obj, objtype=None):
1615        return obj.section4[self._key[obj.pdtn]+2]
1616    def __set__(self, obj, value):
1617        obj.section4[self._key[obj.pdtn]+2] = value
1618
1619class TypeOfIntervalForAerosolWavelength:
1620    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1621    _key = {48:8}
1622    def __get__(self, obj, objtype=None):
1623        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1624    def __set__(self, obj, value):
1625        obj.section4[self._key[obj.pdtn]+2] = value
1626
1627class ScaleFactorOfFirstWavelength:
1628    """Scale Factor of First Wavelength"""
1629    _key = {48:9}
1630    def __get__(self, obj, objtype=None):
1631        return obj.section4[self._key[obj.pdtn]+2]
1632    def __set__(self, obj, value):
1633        obj.section4[self._key[obj.pdtn]+2] = value
1634
1635class ScaledValueOfFirstWavelength:
1636    """Scaled Value of First Wavelength"""
1637    _key = {48:10}
1638    def __get__(self, obj, objtype=None):
1639        return obj.section4[self._key[obj.pdtn]+2]
1640    def __set__(self, obj, value):
1641        obj.section4[self._key[obj.pdtn]+2] = value
1642
1643class ScaleFactorOfSecondWavelength:
1644    """Scale Factor of Second Wavelength"""
1645    _key = {48:11}
1646    def __get__(self, obj, objtype=None):
1647        return obj.section4[self._key[obj.pdtn]+2]
1648    def __set__(self, obj, value):
1649        obj.section4[self._key[obj.pdtn]+2] = value
1650
1651class ScaledValueOfSecondWavelength:
1652    """Scaled Value of Second Wavelength"""
1653    _key = {48:12}
1654    def __get__(self, obj, objtype=None):
1655        return obj.section4[self._key[obj.pdtn]+2]
1656    def __set__(self, obj, value):
1657        obj.section4[self._key[obj.pdtn]+2] = value
1658
1659"""
1660GRIB2 Section 4, Product Definition Template Classes
1661"""
1662
1663@dataclass(init=False)
1664class ProductDefinitionTemplateBase:
1665    """Base attributes for Product Definition Templates"""
1666    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1667    fullName: str = field(init=False, repr=False, default=FullName())
1668    units: str = field(init=False, repr=False, default=Units())
1669    shortName: str = field(init=False, repr=False, default=ShortName())
1670    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1671    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1672    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1673    level: str = field(init=False, repr=False, default=Level())
1674    # Begin template here...
1675    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1676    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1677    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1678    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1679    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1680    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1681    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1682    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1683    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1684    @classmethod
1685    @property
1686    def _attrs(cls):
1687        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1688
1689@dataclass(init=False)
1690class ProductDefinitionTemplateSurface:
1691    """Surface attributes for Product Definition Templates"""
1692    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
1693    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
1694    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1695    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1696    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1697    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1698    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1699    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1700    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
1701    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
1702    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
1703    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
1704    @classmethod
1705    @property
1706    def _attrs(cls):
1707        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1708
1709@dataclass(init=False)
1710class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1711    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
1712    _len = 15
1713    _num = 0
1714    @classmethod
1715    @property
1716    def _attrs(cls):
1717        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1718
1719@dataclass(init=False)
1720class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1721    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
1722    _len = 18
1723    _num = 1
1724    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1725    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1726    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1727    @classmethod
1728    @property
1729    def _attrs(cls):
1730        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1731
1732@dataclass(init=False)
1733class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1734    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
1735    _len = 17
1736    _num = 2
1737    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1738    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1739    @classmethod
1740    @property
1741    def _attrs(cls):
1742        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1743
1744@dataclass(init=False)
1745class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1746    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
1747    _len = 22
1748    _num = 5
1749    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1750    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1751    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1752    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1753    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1754    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1755    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1756    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1757    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1758    threshold: str = field(init=False, repr=False, default=Threshold())
1759    @classmethod
1760    @property
1761    def _attrs(cls):
1762        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1763
1764@dataclass(init=False)
1765class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1766    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
1767    _len = 16
1768    _num = 6
1769    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1770    @classmethod
1771    @property
1772    def _attrs(cls):
1773        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1774
1775@dataclass(init=False)
1776class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1777    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
1778    _len = 29
1779    _num = 8
1780    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1781    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1782    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1783    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1784    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1785    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1786    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1787    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1788    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1789    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1790    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1791    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1792    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1793    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1794    @classmethod
1795    @property
1796    def _attrs(cls):
1797        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1798
1799@dataclass(init=False)
1800class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1801    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
1802    _len = 36
1803    _num = 9
1804    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1805    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1806    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1807    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1808    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1809    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1810    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1811    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1812    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1813    threshold: str = field(init=False, repr=False, default=Threshold())
1814    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1815    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1816    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1817    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1818    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1819    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1820    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1821    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1822    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1823    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1824    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1825    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1826    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1827    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1828    @classmethod
1829    @property
1830    def _attrs(cls):
1831        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1832
1833@dataclass(init=False)
1834class ProductDefinitionTemplate10(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1835    """[Product Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-10.shtml)"""
1836    _len = 30
1837    _num = 10
1838    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1839    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1840    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1841    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1842    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1843    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1844    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1845    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1846    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1847    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1848    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1849    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1850    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1851    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1852    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1853    @classmethod
1854    @property
1855    def _attrs(cls):
1856        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1857
1858@dataclass(init=False)
1859class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1860    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
1861    _len = 32
1862    _num = 11
1863    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1864    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1865    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1866    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1867    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1868    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1869    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1870    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1871    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1872    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1873    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1874    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1875    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1876    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1877    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1878    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1879    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1880    @classmethod
1881    @property
1882    def _attrs(cls):
1883        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1884
1885@dataclass(init=False)
1886class ProductDefinitionTemplate12(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1887    """[Product Definition Template 12](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-12.shtml)"""
1888    _len = 31
1889    _num = 12
1890    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1891    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1892    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1893    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1894    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1895    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1896    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1897    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1898    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1899    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1900    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1901    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1902    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1903    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1904    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1905    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1906    @classmethod
1907    @property
1908    def _attrs(cls):
1909        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1910
1911@dataclass(init=False)
1912class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1913    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
1914    _len = 18
1915    _num = 15
1916    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1917    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
1918    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
1919    @classmethod
1920    @property
1921    def _attrs(cls):
1922        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1923
1924@dataclass(init=False)
1925class ProductDefinitionTemplate31:
1926    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
1927    _len = 5
1928    _num = 31
1929    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1930    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1931    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1932    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1933    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1934    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1935    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1936    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1937    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1938    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1939    @classmethod
1940    @property
1941    def _attrs(cls):
1942        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1943
1944@dataclass(init=False)
1945class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
1946    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
1947    _len = 10
1948    _num = 32
1949    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1950    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1951    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1952    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1953    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1954    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1955    @classmethod
1956    @property
1957    def _attrs(cls):
1958        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1959
1960@dataclass(init=False)
1961class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1962    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
1963    _len = 26
1964    _num = 48
1965    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
1966    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
1967    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
1968    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
1969    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
1970    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
1971    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
1972    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
1973    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
1974    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
1975    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
1976    @classmethod
1977    @property
1978    def _attrs(cls):
1979        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1980
1981_pdt_by_pdtn = {
1982    0: ProductDefinitionTemplate0,
1983    1: ProductDefinitionTemplate1,
1984    2: ProductDefinitionTemplate2,
1985    5: ProductDefinitionTemplate5,
1986    6: ProductDefinitionTemplate6,
1987    8: ProductDefinitionTemplate8,
1988    9: ProductDefinitionTemplate9,
1989    10: ProductDefinitionTemplate10,
1990    11: ProductDefinitionTemplate11,
1991    12: ProductDefinitionTemplate12,
1992    15: ProductDefinitionTemplate15,
1993    31: ProductDefinitionTemplate31,
1994    32: ProductDefinitionTemplate32,
1995    48: ProductDefinitionTemplate48,
1996    }
1997
1998def pdt_class_by_pdtn(pdtn: int):
1999    """
2000    Provide a Product Definition Template class via the template number.
2001
2002    Parameters
2003    ----------
2004    pdtn
2005        Product definition template number.
2006
2007    Returns
2008    -------
2009    pdt_class_by_pdtn
2010        Product definition template class object (not an instance).
2011    """
2012    return _pdt_by_pdtn[pdtn]
2013
2014# ----------------------------------------------------------------------------------------
2015# Descriptor Classes for Section 5 metadata.
2016# ----------------------------------------------------------------------------------------
2017class NumberOfPackedValues:
2018    """Number of Packed Values"""
2019    def __get__(self, obj, objtype=None):
2020        return obj.section5[0]
2021    def __set__(self, obj, value):
2022        pass
2023
2024class DataRepresentationTemplateNumber:
2025    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
2026    def __get__(self, obj, objtype=None):
2027        return Grib2Metadata(obj.section5[1],table='5.0')
2028    def __set__(self, obj, value):
2029        pass
2030
2031class DataRepresentationTemplate:
2032    """Data Representation Template"""
2033    def __get__(self, obj, objtype=None):
2034        return obj.section5[2:]
2035    def __set__(self, obj, value):
2036        raise NotImplementedError
2037
2038class RefValue:
2039    """Reference Value (represented as an IEEE 32-bit floating point value)"""
2040    def __get__(self, obj, objtype=None):
2041        return utils.ieee_int_to_float(obj.section5[0+2])
2042    def __set__(self, obj, value):
2043        pass
2044
2045class BinScaleFactor:
2046    """Binary Scale Factor"""
2047    def __get__(self, obj, objtype=None):
2048        return obj.section5[1+2]
2049    def __set__(self, obj, value):
2050        obj.section5[1+2] = value
2051
2052class DecScaleFactor:
2053    """Decimal Scale Factor"""
2054    def __get__(self, obj, objtype=None):
2055        return obj.section5[2+2]
2056    def __set__(self, obj, value):
2057        obj.section5[2+2] = value
2058
2059class NBitsPacking:
2060    """Minimum number of bits for packing"""
2061    def __get__(self, obj, objtype=None):
2062        return obj.section5[3+2]
2063    def __set__(self, obj, value):
2064        obj.section5[3+2] = value
2065
2066class TypeOfValues:
2067    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2068    def __get__(self, obj, objtype=None):
2069        return Grib2Metadata(obj.section5[4+2],table='5.1')
2070    def __set__(self, obj, value):
2071        obj.section5[4+2] = value
2072
2073class GroupSplittingMethod:
2074    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2075    def __get__(self, obj, objtype=None):
2076        return Grib2Metadata(obj.section5[5+2],table='5.4')
2077    def __set__(self, obj, value):
2078        obj.section5[5+2] = value
2079
2080class TypeOfMissingValueManagement:
2081    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2082    def __get__(self, obj, objtype=None):
2083        return Grib2Metadata(obj.section5[6+2],table='5.5')
2084    def __set__(self, obj, value):
2085        obj.section5[6+2] = value
2086
2087class PriMissingValue:
2088    """Primary Missing Value"""
2089    def __get__(self, obj, objtype=None):
2090        if obj.typeOfValues == 0:
2091            return utils.ieee_int_to_float(obj.section5[7+2]) if obj.section5[6+2] in {1,2} and obj.section5[7+2] != 255 else None
2092        elif obj.typeOfValues == 1:
2093            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2094    def __set__(self, obj, value):
2095        if obj.typeOfValues == 0:
2096            obj.section5[7+2] = utils.ieee_float_to_int(value)
2097        elif self.typeOfValues == 1:
2098            obj.section5[7+2] = int(value)
2099        obj.section5[6+2] = 1
2100
2101class SecMissingValue:
2102    """Secondary Missing Value"""
2103    def __get__(self, obj, objtype=None):
2104        if obj.typeOfValues == 0:
2105            return utils.ieee_int_to_float(obj.section5[8+2]) if obj.section5[6+2] in {1,2} and obj.section5[8+2] != 255 else None
2106        elif obj.typeOfValues == 1:
2107            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2108    def __set__(self, obj, value):
2109        if obj.typeOfValues == 0:
2110            obj.section5[8+2] = utils.ieee_float_to_int(value)
2111        elif self.typeOfValues == 1:
2112            obj.section5[8+2] = int(value)
2113        obj.section5[6+2] = 2
2114
2115class NGroups:
2116    """Number of Groups"""
2117    def __get__(self, obj, objtype=None):
2118        return obj.section5[9+2]
2119    def __set__(self, obj, value):
2120        pass
2121
2122class RefGroupWidth:
2123    """Reference Group Width"""
2124    def __get__(self, obj, objtype=None):
2125        return obj.section5[10+2]
2126    def __set__(self, obj, value):
2127        pass
2128
2129class NBitsGroupWidth:
2130    """Number of bits for Group Width"""
2131    def __get__(self, obj, objtype=None):
2132        return obj.section5[11+2]
2133    def __set__(self, obj, value):
2134        pass
2135
2136class RefGroupLength:
2137    """Reference Group Length"""
2138    def __get__(self, obj, objtype=None):
2139        return obj.section5[12+2]
2140    def __set__(self, obj, value):
2141        pass
2142
2143class GroupLengthIncrement:
2144    """Group Length Increment"""
2145    def __get__(self, obj, objtype=None):
2146        return obj.section5[13+2]
2147    def __set__(self, obj, value):
2148        pass
2149
2150class LengthOfLastGroup:
2151    """Length of Last Group"""
2152    def __get__(self, obj, objtype=None):
2153        return obj.section5[14+2]
2154    def __set__(self, obj, value):
2155        pass
2156
2157class NBitsScaledGroupLength:
2158    """Number of bits of Scaled Group Length"""
2159    def __get__(self, obj, objtype=None):
2160        return obj.section5[15+2]
2161    def __set__(self, obj, value):
2162        pass
2163
2164class SpatialDifferenceOrder:
2165    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2166    def __get__(self, obj, objtype=None):
2167        return Grib2Metadata(obj.section5[16+2],table='5.6')
2168    def __set__(self, obj, value):
2169        obj.section5[16+2] = value
2170
2171class NBytesSpatialDifference:
2172    """Number of bytes for Spatial Differencing"""
2173    def __get__(self, obj, objtype=None):
2174        return obj.section5[17+2]
2175    def __set__(self, obj, value):
2176        pass
2177
2178class Precision:
2179    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2180    def __get__(self, obj, objtype=None):
2181        return Grib2Metadata(obj.section5[0+2],table='5.7')
2182    def __set__(self, obj, value):
2183        obj.section5[0+2] = value
2184
2185class TypeOfCompression:
2186    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2187    def __get__(self, obj, objtype=None):
2188        return Grib2Metadata(obj.section5[5+2],table='5.40')
2189    def __set__(self, obj, value):
2190        obj.section5[5+2] = value
2191
2192class TargetCompressionRatio:
2193    """Target Compression Ratio"""
2194    def __get__(self, obj, objtype=None):
2195        return obj.section5[6+2]
2196    def __set__(self, obj, value):
2197        pass
2198
2199class RealOfCoefficient:
2200    """Real of Coefficient"""
2201    def __get__(self, obj, objtype=None):
2202        return utils.ieee_int_to_float(obj.section5[4+2])
2203    def __set__(self, obj, value):
2204        obj.section5[4+2] = utils.ieee_float_to_int(float(value))
2205
2206class CompressionOptionsMask:
2207    """Compression Options Mask for AEC/CCSDS"""
2208    def __get__(self, obj, objtype=None):
2209        return obj.section5[5+2]
2210    def __set__(self, obj, value):
2211        obj.section5[5+2] = value
2212
2213class BlockSize:
2214    """Block Size for AEC/CCSDS"""
2215    def __get__(self, obj, objtype=None):
2216        return obj.section5[6+2]
2217    def __set__(self, obj, value):
2218        obj.section5[6+2] = value
2219
2220class RefSampleInterval:
2221    """Reference Sample Interval for AEC/CCSDS"""
2222    def __get__(self, obj, objtype=None):
2223        return obj.section5[7+2]
2224    def __set__(self, obj, value):
2225        obj.section5[7+2] = value
2226
2227@dataclass(init=False)
2228class DataRepresentationTemplate0:
2229    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
2230    _len = 5
2231    _num = 0
2232    _packingScheme = 'simple'
2233    refValue: float = field(init=False, repr=False, default=RefValue())
2234    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2235    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2236    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2237    @classmethod
2238    @property
2239    def _attrs(cls):
2240        return list(cls.__dataclass_fields__.keys())
2241
2242@dataclass(init=False)
2243class DataRepresentationTemplate2:
2244    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
2245    _len = 16
2246    _num = 2
2247    _packingScheme = 'complex'
2248    refValue: float = field(init=False, repr=False, default=RefValue())
2249    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2250    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2251    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2252    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2253    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2254    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2255    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2256    nGroups: int = field(init=False, repr=False, default=NGroups())
2257    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2258    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2259    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2260    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2261    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2262    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2263    @classmethod
2264    @property
2265    def _attrs(cls):
2266        return list(cls.__dataclass_fields__.keys())
2267
2268@dataclass(init=False)
2269class DataRepresentationTemplate3:
2270    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
2271    _len = 18
2272    _num = 3
2273    _packingScheme = 'complex-spdiff'
2274    refValue: float = field(init=False, repr=False, default=RefValue())
2275    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2276    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2277    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2278    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2279    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2280    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2281    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2282    nGroups: int = field(init=False, repr=False, default=NGroups())
2283    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2284    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2285    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2286    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2287    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2288    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2289    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
2290    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
2291    @classmethod
2292    @property
2293    def _attrs(cls):
2294        return list(cls.__dataclass_fields__.keys())
2295
2296@dataclass(init=False)
2297class DataRepresentationTemplate4:
2298    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
2299    _len = 1
2300    _num = 4
2301    _packingScheme = 'ieee-float'
2302    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
2303    @classmethod
2304    @property
2305    def _attrs(cls):
2306        return list(cls.__dataclass_fields__.keys())
2307
2308@dataclass(init=False)
2309class DataRepresentationTemplate40:
2310    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
2311    _len = 7
2312    _num = 40
2313    _packingScheme = 'jpeg'
2314    refValue: float = field(init=False, repr=False, default=RefValue())
2315    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2316    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2317    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2318    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
2319    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
2320    @classmethod
2321    @property
2322    def _attrs(cls):
2323        return list(cls.__dataclass_fields__.keys())
2324
2325@dataclass(init=False)
2326class DataRepresentationTemplate41:
2327    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
2328    _len = 5
2329    _num = 41
2330    _packingScheme = 'png'
2331    refValue: float = field(init=False, repr=False, default=RefValue())
2332    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2333    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2334    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2335    @classmethod
2336    @property
2337    def _attrs(cls):
2338        return list(cls.__dataclass_fields__.keys())
2339
2340@dataclass(init=False)
2341class DataRepresentationTemplate42:
2342    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
2343    _len = 8
2344    _num = 42
2345    _packingScheme = 'aec'
2346    refValue: float = field(init=False, repr=False, default=RefValue())
2347    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2348    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2349    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2350    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
2351    blockSize: int = field(init=False, repr=False, default=BlockSize())
2352    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
2353    @classmethod
2354    @property
2355    def _attrs(cls):
2356        return list(cls.__dataclass_fields__.keys())
2357
2358@dataclass(init=False)
2359class DataRepresentationTemplate50:
2360    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
2361    _len = 5
2362    _num = 0
2363    _packingScheme = 'spectral-simple'
2364    refValue: float = field(init=False, repr=False, default=RefValue())
2365    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2366    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2367    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2368    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
2369    @classmethod
2370    @property
2371    def _attrs(cls):
2372        return list(cls.__dataclass_fields__.keys())
2373
2374_drt_by_drtn = {
2375    0: DataRepresentationTemplate0,
2376    2: DataRepresentationTemplate2,
2377    3: DataRepresentationTemplate3,
2378    4: DataRepresentationTemplate4,
2379    40: DataRepresentationTemplate40,
2380    41: DataRepresentationTemplate41,
2381    42: DataRepresentationTemplate42,
2382    50: DataRepresentationTemplate50,
2383    }
2384
2385def drt_class_by_drtn(drtn: int):
2386    """
2387    Provide a Data Representation Template class via the template number.
2388
2389    Parameters
2390    ----------
2391    drtn
2392        Data Representation template number.
2393
2394    Returns
2395    -------
2396    drt_class_by_drtn
2397        Data Representation template class object (not an instance).
2398    """
2399    return _drt_by_drtn[drtn]
class Grib2Metadata:
47class Grib2Metadata:
48    """
49    Class to hold GRIB2 metadata.
50
51    Stores both numeric code value as stored in GRIB2 and its plain language
52    definition.
53
54    Attributes
55    ----------
56    value : int
57        GRIB2 metadata integer code value.
58    table : str, optional
59        GRIB2 table to lookup the `value`. Default is None.
60    definition : str
61        Plain language description of numeric metadata.
62    """
63    __slots__ = ('value','table')
64    def __init__(self, value, table=None):
65        self.value = value
66        self.table = table
67    def __call__(self):
68        return self.value
69    def __hash__(self):
70        # AS- added hash() to self.value as pandas was raising error about some
71        # non integer returns from hash method
72        return hash(self.value)
73    def __repr__(self):
74        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
75    def __str__(self):
76        return f'{self.value} - {self.definition}'
77    def __eq__(self,other):
78        return self.value == other or self.definition[0] == other
79    def __gt__(self,other):
80        return self.value > other
81    def __ge__(self,other):
82        return self.value >= other
83    def __lt__(self,other):
84        return self.value < other
85    def __le__(self,other):
86        return self.value <= other
87    def __contains__(self,other):
88        return other in self.definition
89    def __hash__(self):
90        return hash(self.value)
91    def __index__(self):
92        return int(self.value)
93    @property
94    def definition(self):
95        return tables.get_value_from_table(self.value,self.table)
96    def show_table(self):
97        """Provide the table related to this metadata."""
98        return tables.get_table(self.table)

Class to hold GRIB2 metadata.

Stores both numeric code value as stored in GRIB2 and its plain language definition.

Attributes
  • value (int): GRIB2 metadata integer code value.
  • table (str, optional): GRIB2 table to lookup the value. Default is None.
  • definition (str): Plain language description of numeric metadata.
Grib2Metadata(value, table=None)
64    def __init__(self, value, table=None):
65        self.value = value
66        self.table = table
value
table
definition
93    @property
94    def definition(self):
95        return tables.get_value_from_table(self.value,self.table)
def show_table(self):
96    def show_table(self):
97        """Provide the table related to this metadata."""
98        return tables.get_table(self.table)

Provide the table related to this metadata.

class IndicatorSection:
103class IndicatorSection:
104    """
105    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
106    """
107    def __get__(self, obj, objtype=None):
108        return obj.section0
109    def __set__(self, obj, value):
110        obj.section0 = value
class Discipline:
112class Discipline:
113    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
114    def __get__(self, obj, objtype=None):
115        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
116    def __set__(self, obj, value):
117        obj.section0[2] = value
class IdentificationSection:
123class IdentificationSection:
124    """
125    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
126    """
127    def __get__(self, obj, objtype=None):
128        return obj.section1
129    def __set__(self, obj, value):
130        obj.section1 = value

GRIB2 Section 1, Identification Section

class OriginatingCenter:
132class OriginatingCenter:
133    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
134    def __get__(self, obj, objtype=None):
135        return Grib2Metadata(obj.section1[0],table='originating_centers')
136    def __set__(self, obj, value):
137        obj.section1[0] = value
class OriginatingSubCenter:
139class OriginatingSubCenter:
140    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
141    def __get__(self, obj, objtype=None):
142        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
143    def __set__(self, obj, value):
144        obj.section1[1] = value
class MasterTableInfo:
146class MasterTableInfo:
147    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
148    def __get__(self, obj, objtype=None):
149        return Grib2Metadata(obj.section1[2],table='1.0')
150    def __set__(self, obj, value):
151        obj.section1[2] = value
class LocalTableInfo:
153class LocalTableInfo:
154    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
155    def __get__(self, obj, objtype=None):
156        return Grib2Metadata(obj.section1[3],table='1.1')
157    def __set__(self, obj, value):
158        obj.section1[3] = value
class SignificanceOfReferenceTime:
160class SignificanceOfReferenceTime:
161    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
162    def __get__(self, obj, objtype=None):
163        return Grib2Metadata(obj.section1[4],table='1.2')
164    def __set__(self, obj, value):
165        obj.section1[4] = value
class Year:
167class Year:
168    """Year of reference time"""
169    def __get__(self, obj, objtype=None):
170        return obj.section1[5]
171    def __set__(self, obj, value):
172        obj.section1[5] = value

Year of reference time

class Month:
174class Month:
175    """Month of reference time"""
176    def __get__(self, obj, objtype=None):
177        return obj.section1[6]
178    def __set__(self, obj, value):
179        obj.section1[6] = value

Month of reference time

class Day:
181class Day:
182    """Day of reference time"""
183    def __get__(self, obj, objtype=None):
184        return obj.section1[7]
185    def __set__(self, obj, value):
186        obj.section1[7] = value

Day of reference time

class Hour:
188class Hour:
189    """Hour of reference time"""
190    def __get__(self, obj, objtype=None):
191        return obj.section1[8]
192    def __set__(self, obj, value):
193        obj.section1[8] = value

Hour of reference time

class Minute:
195class Minute:
196    """Minute of reference time"""
197    def __get__(self, obj, objtype=None):
198        return obj.section1[9]
199    def __set__(self, obj, value):
200        obj.section1[9] = value

Minute of reference time

class Second:
202class Second:
203    """Second of reference time"""
204    def __get__(self, obj, objtype=None):
205        return obj.section1[10]
206    def __set__(self, obj, value):
207        obj.section1[10] = value

Second of reference time

class RefDate:
209class RefDate:
210    """Reference Date. NOTE: This is a `datetime.datetime` object."""
211    def __get__(self, obj, objtype=None):
212        return datetime.datetime(*obj.section1[5:11])
213    def __set__(self, obj, value):
214        if isinstance(value, datetime64):
215            timestamp = (value - datetime64("1970-01-01T00:00:00")) / timedelta64(
216                1, "s"
217            )
218            value = datetime.datetime.utcfromtimestamp(timestamp)
219        if isinstance(value, datetime.datetime):
220            obj.section1[5] = value.year
221            obj.section1[6] = value.month
222            obj.section1[7] = value.day
223            obj.section1[8] = value.hour
224            obj.section1[9] = value.minute
225            obj.section1[10] = value.second
226        else:
227            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
228            raise TypeError(msg)

Reference Date. NOTE: This is a datetime.datetime object.

class ProductionStatus:
230class ProductionStatus:
231    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
232    def __get__(self, obj, objtype=None):
233        return Grib2Metadata(obj.section1[11],table='1.3')
234    def __set__(self, obj, value):
235        obj.section1[11] = value
class TypeOfData:
237class TypeOfData:
238    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
239    def __get__(self, obj, objtype=None):
240        return Grib2Metadata(obj.section1[12],table='1.4')
241    def __set__(self, obj, value):
242        obj.section1[12] = value
class GridDefinitionSection:
251class GridDefinitionSection:
252    """
253    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
254    """
255    def __get__(self, obj, objtype=None):
256        return obj.section3[0:5]
257    def __set__(self, obj, value):
258        raise RuntimeError

GRIB2 Section 3, Grid Definition Section

class SourceOfGridDefinition:
260class SourceOfGridDefinition:
261    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
262    def __get__(self, obj, objtype=None):
263        return Grib2Metadata(obj.section3[0],table='3.0')
264    def __set__(self, obj, value):
265        raise RuntimeError
class NumberOfDataPoints:
267class NumberOfDataPoints:
268    """Number of Data Points"""
269    def __get__(self, obj, objtype=None):
270        return obj.section3[1]
271    def __set__(self, obj, value):
272        raise RuntimeError

Number of Data Points

class InterpretationOfListOfNumbers:
274class InterpretationOfListOfNumbers:
275    """Interpretation of List of Numbers"""
276    def __get__(self, obj, objtype=None):
277        return Grib2Metadata(obj.section3[3],table='3.11')
278    def __set__(self, obj, value):
279        raise RuntimeError

Interpretation of List of Numbers

class GridDefinitionTemplateNumber:
281class GridDefinitionTemplateNumber:
282    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
283    def __get__(self, obj, objtype=None):
284        return Grib2Metadata(obj.section3[4],table='3.1')
285    def __set__(self, obj, value):
286        raise RuntimeError
class GridDefinitionTemplate:
288class GridDefinitionTemplate:
289    """Grid definition template"""
290    def __get__(self, obj, objtype=None):
291        return obj.section3[5:]
292    def __set__(self, obj, value):
293        raise RuntimeError

Grid definition template

class EarthParams:
295class EarthParams:
296    """Metadata about the shape of the Earth"""
297    def __get__(self, obj, objtype=None):
298        if obj.section3[5] in {50,51,52,1200}:
299            return None
300        return tables.get_table('earth_params')[str(obj.section3[5])]
301    def __set__(self, obj, value):
302        raise RuntimeError

Metadata about the shape of the Earth

class DxSign:
304class DxSign:
305    """Sign of Grid Length in X-Direction"""
306    def __get__(self, obj, objtype=None):
307        if obj.section3[4] in {0,1,203,205,32768,32769} and \
308        obj.section3[17] > obj.section3[20]:
309            return -1.0
310        return 1.0
311    def __set__(self, obj, value):
312        raise RuntimeError

Sign of Grid Length in X-Direction

class DySign:
314class DySign:
315    """Sign of Grid Length in Y-Direction"""
316    def __get__(self, obj, objtype=None):
317        if obj.section3[4] in {0,1,203,205,32768,32769} and \
318        obj.section3[16] > obj.section3[19]:
319            return -1.0
320        return 1.0
321    def __set__(self, obj, value):
322        raise RuntimeError

Sign of Grid Length in Y-Direction

class LLScaleFactor:
324class LLScaleFactor:
325    """Scale Factor for Lats/Lons"""
326    def __get__(self, obj, objtype=None):
327        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
328            llscalefactor = float(obj.section3[14])
329            if llscalefactor == 0:
330                return 1
331            return llscalefactor
332        return 1
333    def __set__(self, obj, value):
334        raise RuntimeError

Scale Factor for Lats/Lons

class LLDivisor:
336class LLDivisor:
337    """Divisor Value for scaling Lats/Lons"""
338    def __get__(self, obj, objtype=None):
339        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
340            lldivisor = float(obj.section3[15])
341            if lldivisor <= 0:
342                return 1.e6
343            return lldivisor
344        return 1.e6
345    def __set__(self, obj, value):
346        raise RuntimeError

Divisor Value for scaling Lats/Lons

class XYDivisor:
348class XYDivisor:
349    """Divisor Value for scaling grid lengths"""
350    def __get__(self, obj, objtype=None):
351        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
352            return obj._lldivisor
353        return 1.e3
354    def __set__(self, obj, value):
355        raise RuntimeError

Divisor Value for scaling grid lengths

class ShapeOfEarth:
357class ShapeOfEarth:
358    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
359    def __get__(self, obj, objtype=None):
360        return Grib2Metadata(obj.section3[5],table='3.2')
361    def __set__(self, obj, value):
362        obj.section3[5] = value
class EarthShape:
364class EarthShape:
365    """Description of the shape of the Earth"""
366    def __get__(self, obj, objtype=None):
367        return obj._earthparams['shape']
368    def __set__(self, obj, value):
369        raise RuntimeError

Description of the shape of the Earth

class EarthRadius:
371class EarthRadius:
372    """Radius of the Earth (Assumes "spherical")"""
373    def __get__(self, obj, objtype=None):
374        ep = obj._earthparams
375        if ep['shape'] == 'spherical':
376            if ep['radius'] is None:
377                return obj.section3[7]/(10.**obj.section3[6])
378            else:
379                return ep['radius']
380        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
381            return None
382    def __set__(self, obj, value):
383        raise RuntimeError

Radius of the Earth (Assumes "spherical")

class EarthMajorAxis:
385class EarthMajorAxis:
386    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
387    def __get__(self, obj, objtype=None):
388        ep = obj._earthparams
389        if ep['shape'] == 'spherical':
390            return None
391        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
392            if ep['major_axis'] is None and ep['minor_axis'] is None:
393                return obj.section3[9]/(10.**obj.section3[8])
394            else:
395                return ep['major_axis']
396    def __set__(self, obj, value):
397        raise RuntimeError

Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")

class EarthMinorAxis:
399class EarthMinorAxis:
400    """Minor Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
401    def __get__(self, obj, objtype=None):
402        ep = obj._earthparams
403        if ep['shape'] == 'spherical':
404            return None
405        if ep['shape'] in {'ellipsoid','oblateSpheriod'}:
406            if ep['major_axis'] is None and ep['minor_axis'] is None:
407                return obj.section3[11]/(10.**section3[10])
408            else:
409                return ep['minor_axis']
410    def __set__(self, obj, value):
411        raise RuntimeError

Minor Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")

class Nx:
413class Nx:
414    """Number of grid points in the X-direction (generally East-West)"""
415    def __get__(self, obj, objtype=None):
416        return obj.section3[12]
417    def __set__(self, obj, value):
418        obj.section3[12] = value
419        obj.section3[1] = value * obj.section3[13]

Number of grid points in the X-direction (generally East-West)

class Ny:
421class Ny:
422    """Number of grid points in the Y-direction (generally North-South)"""
423    def __get__(self, obj, objtype=None):
424        return obj.section3[13]
425    def __set__(self, obj, value):
426        obj.section3[13] = value
427        obj.section3[1] = value * obj.section3[12]

Number of grid points in the Y-direction (generally North-South)

class ScanModeFlags:
429class ScanModeFlags:
430    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
431    _key = {0:18, 1:18, 10:15, 20:17, 30:17, 31:17, 40:18, 41:18, 90:16, 110:15, 203:18, 204:18, 205:18, 32768:18, 32769:18}
432    def __get__(self, obj, objtype=None):
433        if obj.gdtn == 50:
434            return [None, None, None, None]
435        else:
436            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
437    def __set__(self, obj, value):
438        obj.section3[self._key[obj.gdtn]+5] = value
class ResolutionAndComponentFlags:
440class ResolutionAndComponentFlags:
441    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
442    _key = {0:13, 1:13, 10:11, 20:11, 30:11, 31:11, 40:13, 41:13, 90:11, 110:11, 203:13, 204:13, 205:13, 32768:13, 32769:13}
443    def __get__(self, obj, objtype=None):
444        if obj.gdtn == 50:
445            return [None for i in range(8)]
446        else:
447            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
448    def __set__(self, obj, value):
449        obj.section3[self._key[obj.gdtn]+5] = value
class LatitudeFirstGridpoint:
451class LatitudeFirstGridpoint:
452    """Latitude of first gridpoint"""
453    _key = {0:11, 1:11, 10:9, 20:9, 30:9, 31:9, 40:11, 41:11, 110:9, 203:11, 204:11, 205:11, 32768:11, 32769:11}
454    def __get__(self, obj, objtype=None):
455        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
456    def __set__(self, obj, value):
457        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of first gridpoint

class LongitudeFirstGridpoint:
459class LongitudeFirstGridpoint:
460    """Longitude of first gridpoint"""
461    _key = {0:12, 1:12, 10:10, 20:10, 30:10, 31:10, 40:12, 41:12, 110:10, 203:12, 204:12, 205:12, 32768:12, 32769:12}
462    def __get__(self, obj, objtype=None):
463        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
464    def __set__(self, obj, value):
465        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of first gridpoint

class LatitudeLastGridpoint:
467class LatitudeLastGridpoint:
468    """Latitude of last gridpoint"""
469    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:19}
470    def __get__(self, obj, objtype=None):
471        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
472    def __set__(self, obj, value):
473        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of last gridpoint

class LongitudeLastGridpoint:
475class LongitudeLastGridpoint:
476    """Longitude of last gridpoint"""
477    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:20}
478    def __get__(self, obj, objtype=None):
479        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
480    def __set__(self, obj, value):
481        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of last gridpoint

class LatitudeCenterGridpoint:
483class LatitudeCenterGridpoint:
484    """Latitude of center gridpoint"""
485    _key = {32768:14, 32769:14}
486    def __get__(self, obj, objtype=None):
487        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
488    def __set__(self, obj, value):
489        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of center gridpoint

class LongitudeCenterGridpoint:
491class LongitudeCenterGridpoint:
492    """Longitude of center gridpoint"""
493    _key = {32768:15, 32769:15}
494    def __get__(self, obj, objtype=None):
495        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
496    def __set__(self, obj, value):
497        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of center gridpoint

class GridlengthXDirection:
499class GridlengthXDirection:
500    """Grid lenth in the X-Direction"""
501    _key = {0:16, 1:16, 10:17, 20:14, 30:14, 31:14, 40:16, 41:16, 203:16, 204:16, 205:16, 32768:16, 32769:16}
502    def __get__(self, obj, objtype=None):
503        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
504    def __set__(self, obj, value):
505        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the X-Direction

class GridlengthYDirection:
507class GridlengthYDirection:
508    """Grid lenth in the Y-Direction"""
509    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
510    def __get__(self, obj, objtype=None):
511        if obj.gdtn in {40, 41}:
512            return obj.gridlengthXDirection
513        else:
514            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
515    def __set__(self, obj, value):
516        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the Y-Direction

class NumberOfParallels:
518class NumberOfParallels:
519    """Number of parallels between a pole and the equator"""
520    _key = {40:17, 41:17}
521    def __get__(self, obj, objtype=None):
522        return obj.section3[self._key[obj.gdtn]+5]
523    def __set__(self, obj, value):
524        raise RuntimeError

Number of parallels between a pole and the equator

class LatitudeSouthernPole:
526class LatitudeSouthernPole:
527    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
528    _key = {1:19, 30:20, 31:20, 41:19}
529    def __get__(self, obj, objtype=None):
530        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
531    def __set__(self, obj, value):
532        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of the Southern Pole for a Rotated Lat/Lon Grid

class LongitudeSouthernPole:
534class LongitudeSouthernPole:
535    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
536    _key = {1:20, 30:21, 31:21, 41:20}
537    def __get__(self, obj, objtype=None):
538        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
539    def __set__(self, obj, value):
540        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of the Southern Pole for a Rotated Lat/Lon Grid

class AnglePoleRotation:
542class AnglePoleRotation:
543    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
544    _key = {1:21, 41:21}
545    def __get__(self, obj, objtype=None):
546        return obj.section3[self._key[obj.gdtn]+5]
547    def __set__(self, obj, value):
548        obj.section3[self._key[obj.gdtn]+5] = int(value)

Angle of Pole Rotation for a Rotated Lat/Lon Grid

class LatitudeTrueScale:
550class LatitudeTrueScale:
551    """Latitude at which grid lengths are specified"""
552    _key = {10:12, 20:12, 30:12, 31:12}
553    def __get__(self, obj, objtype=None):
554        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
555    def __set__(self, obj, value):
556        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude at which grid lengths are specified

class GridOrientation:
558class GridOrientation:
559    """Longitude at which the grid is oriented"""
560    _key = {10:16, 20:13, 30:13, 31:13}
561    def __get__(self, obj, objtype=None):
562        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
563    def __set__(self, obj, value):
564        if obj.gdtn == 10 and (value < 0 or value > 90):
565            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
566        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude at which the grid is oriented

class ProjectionCenterFlag:
568class ProjectionCenterFlag:
569    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
570    _key = {20:16, 30:16, 31:16}
571    def __get__(self, obj, objtype=None):
572        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
573    def __set__(self, obj, value):
574        obj.section3[self._key[obj.gdtn]+5] = value
class StandardLatitude1:
576class StandardLatitude1:
577    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
578    _key = {30:18, 31:18}
579    def __get__(self, obj, objtype=None):
580        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
581    def __set__(self, obj, value):
582        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

First Standard Latitude (from the pole at which the secant cone cuts the sphere)

class StandardLatitude2:
584class StandardLatitude2:
585    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
586    _key = {30:19, 31:19}
587    def __get__(self, obj, objtype=None):
588        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
589    def __set__(self, obj, value):
590        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Second Standard Latitude (from the pole at which the secant cone cuts the sphere)

class SpectralFunctionParameters:
592class SpectralFunctionParameters:
593    """Spectral Function Parameters"""
594    def __get__(self, obj, objtype=None):
595        return obj.section3[0:3]
596    def __set__(self, obj, value):
597        obj.section3[0:3] = value[0:3]

Spectral Function Parameters

class ProjParameters:
599class ProjParameters:
600    """PROJ Parameters to define the reference system"""
601    def __get__(self, obj, objtype=None):
602        projparams = {}
603        projparams['a'] = 1.0
604        projparams['b'] = 1.0
605        if obj.earthRadius is not None:
606            projparams['a'] = obj.earthRadius
607            projparams['b'] = obj.earthRadius
608        else:
609            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
610            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
611        if obj.gdtn == 0:
612            projparams['proj'] = 'longlat'
613        elif obj.gdtn == 1:
614            projparams['o_proj'] = 'longlat'
615            projparams['proj'] = 'ob_tran'
616            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
617            projparams['o_lon_p'] = obj.anglePoleRotation
618            projparams['lon_0'] = obj.longitudeSouthernPole
619        elif obj.gdtn == 10:
620            projparams['proj'] = 'merc'
621            projparams['lat_ts'] = obj.latitudeTrueScale
622            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
623        elif obj.gdtn == 20:
624            if obj.projectionCenterFlag == 0:
625                lat0 = 90.0
626            elif obj.projectionCenterFlag == 1:
627                lat0 = -90.0
628            projparams['proj'] = 'stere'
629            projparams['lat_ts'] = obj.latitudeTrueScale
630            projparams['lat_0'] = lat0
631            projparams['lon_0'] = obj.gridOrientation
632        elif obj.gdtn == 30:
633            projparams['proj'] = 'lcc'
634            projparams['lat_1'] = obj.standardLatitude1
635            projparams['lat_2'] = obj.standardLatitude2
636            projparams['lat_0'] = obj.latitudeTrueScale
637            projparams['lon_0'] = obj.gridOrientation
638        elif obj.gdtn == 31:
639            projparams['proj'] = 'aea'
640            projparams['lat_1'] = obj.standardLatitude1
641            projparams['lat_2'] = obj.standardLatitude2
642            projparams['lat_0'] = obj.latitudeTrueScale
643            projparams['lon_0'] = obj.gridOrientation
644        elif obj.gdtn == 40:
645            projparams['proj'] = 'eqc'
646        elif obj.gdtn == 32769:
647            projparams['proj'] = 'aeqd'
648            projparams['lon_0'] = obj.longitudeCenterGridpoint
649            projparams['lat_0'] = obj.latitudeCenterGridpoint
650        return projparams
651    def __set__(self, obj, value):
652        raise RuntimeError

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate0:
654@dataclass(init=False)
655class GridDefinitionTemplate0:
656    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
657    _len = 19
658    _num = 0
659    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
660    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
661    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
662    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
663    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
664    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
665    @classmethod
666    @property
667    def _attrs(cls):
668        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

@dataclass(init=False)
class GridDefinitionTemplate1:
670@dataclass(init=False)
671class GridDefinitionTemplate1:
672    """[Grid Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-1.shtml)"""
673    _len = 22
674    _num = 1
675    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
676    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
677    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
678    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
679    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
680    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
681    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
682    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
683    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
684    @classmethod
685    @property
686    def _attrs(cls):
687        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

latitudeSouthernPole: float

Latitude of the Southern Pole for a Rotated Lat/Lon Grid

longitudeSouthernPole: float

Longitude of the Southern Pole for a Rotated Lat/Lon Grid

anglePoleRotation: float

Angle of Pole Rotation for a Rotated Lat/Lon Grid

@dataclass(init=False)
class GridDefinitionTemplate10:
689@dataclass(init=False)
690class GridDefinitionTemplate10:
691    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
692    _len = 19
693    _num = 10
694    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
695    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
696    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
697    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
698    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
699    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
700    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
701    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
702    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
703    @classmethod
704    @property
705    def _attrs(cls):
706        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projParameters: dict

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate20:
708@dataclass(init=False)
709class GridDefinitionTemplate20:
710    """[Grid Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-20.shtml)"""
711    _len = 18
712    _num = 20
713    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
714    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
715    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
716    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
717    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
718    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
719    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
720    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
721    @classmethod
722    @property
723    def _attrs(cls):
724        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
projParameters: dict

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate30:
726@dataclass(init=False)
727class GridDefinitionTemplate30:
728    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
729    _len = 22
730    _num = 30
731    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
732    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
733    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
734    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
735    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
736    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
737    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
738    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
739    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
740    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
741    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
742    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
743    @classmethod
744    @property
745    def _attrs(cls):
746        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
standardLatitude1: float

First Standard Latitude (from the pole at which the secant cone cuts the sphere)

standardLatitude2: float

Second Standard Latitude (from the pole at which the secant cone cuts the sphere)

latitudeSouthernPole: float

Latitude of the Southern Pole for a Rotated Lat/Lon Grid

longitudeSouthernPole: float

Longitude of the Southern Pole for a Rotated Lat/Lon Grid

projParameters: dict

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate31:
748@dataclass(init=False)
749class GridDefinitionTemplate31:
750    """[Grid Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-31.shtml)"""
751    _len = 22
752    _num = 31
753    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
754    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
755    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
756    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
757    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
758    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
759    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
760    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
761    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
762    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
763    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
764    @classmethod
765    @property
766    def _attrs(cls):
767        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
standardLatitude1: float

First Standard Latitude (from the pole at which the secant cone cuts the sphere)

standardLatitude2: float

Second Standard Latitude (from the pole at which the secant cone cuts the sphere)

latitudeSouthernPole: float

Latitude of the Southern Pole for a Rotated Lat/Lon Grid

longitudeSouthernPole: float

Longitude of the Southern Pole for a Rotated Lat/Lon Grid

@dataclass(init=False)
class GridDefinitionTemplate40:
769@dataclass(init=False)
770class GridDefinitionTemplate40:
771    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
772    _len = 19
773    _num = 40
774    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
775    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
776    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
777    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
778    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
779    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
780    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
781    @classmethod
782    @property
783    def _attrs(cls):
784        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

numberOfParallels: int

Number of parallels between a pole and the equator

@dataclass(init=False)
class GridDefinitionTemplate41:
786@dataclass(init=False)
787class GridDefinitionTemplate41:
788    """[Grid Definition Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-41.shtml)"""
789    _len = 22
790    _num = 41
791    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
792    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
793    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
794    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
795    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
796    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
797    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
798    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
799    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
800    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
801    @classmethod
802    @property
803    def _attrs(cls):
804        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

numberOfParallels: int

Number of parallels between a pole and the equator

latitudeSouthernPole: float

Latitude of the Southern Pole for a Rotated Lat/Lon Grid

longitudeSouthernPole: float

Longitude of the Southern Pole for a Rotated Lat/Lon Grid

anglePoleRotation: float

Angle of Pole Rotation for a Rotated Lat/Lon Grid

@dataclass(init=False)
class GridDefinitionTemplate50:
806@dataclass(init=False)
807class GridDefinitionTemplate50:
808    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
809    _len = 5
810    _num = 50
811    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
812    @classmethod
813    @property
814    def _attrs(cls):
815        return list(cls.__dataclass_fields__.keys())
spectralFunctionParameters: list

Spectral Function Parameters

@dataclass(init=False)
class GridDefinitionTemplate32768:
817@dataclass(init=False)
818class GridDefinitionTemplate32768:
819    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
820    _len = 19
821    _num = 32768
822    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
823    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
824    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
825    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
826    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
827    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
828    @classmethod
829    @property
830    def _attrs(cls):
831        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeCenterGridpoint: float

Latitude of center gridpoint

longitudeCenterGridpoint: float

Longitude of center gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

@dataclass(init=False)
class GridDefinitionTemplate32769:
833@dataclass(init=False)
834class GridDefinitionTemplate32769:
835    """[Grid Definition Template 32769](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32769.shtml)"""
836    _len = 19
837    _num = 32769
838    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
839    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
840    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
841    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
842    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
843    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
844    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
845    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
846    @classmethod
847    @property
848    def _attrs(cls):
849        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeCenterGridpoint: float

Latitude of center gridpoint

longitudeCenterGridpoint: float

Longitude of center gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

def gdt_class_by_gdtn(gdtn: int):
864def gdt_class_by_gdtn(gdtn: int):
865    """
866    Provides a Grid Definition Template class via the template number
867
868    Parameters
869    ----------
870    gdtn
871        Grid definition template number.
872
873    Returns
874    -------
875    gdt_class_by_gdtn
876        Grid definition template class object (not an instance).
877    """
878    return _gdt_by_gdtn[gdtn]

Provides a Grid Definition Template class via the template number

Parameters
  • gdtn: Grid definition template number.
Returns
  • gdt_class_by_gdtn: Grid definition template class object (not an instance).
class ProductDefinitionTemplateNumber:
883class ProductDefinitionTemplateNumber:
884    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
885    def __get__(self, obj, objtype=None):
886        return Grib2Metadata(obj.section4[1],table='4.0')
887    def __set__(self, obj, value):
888        raise RuntimeError
class ProductDefinitionTemplate:
891class ProductDefinitionTemplate:
892    """Product Definition Template"""
893    def __get__(self, obj, objtype=None):
894        return obj.section4[2:]
895    def __set__(self, obj, value):
896        raise RuntimeError

Product Definition Template

class ParameterCategory:
898class ParameterCategory:
899    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
900    _key = defaultdict(lambda: 0)
901    def __get__(self, obj, objtype=None):
902        return obj.section4[0+2]
903    def __set__(self, obj, value):
904        obj.section4[self._key[obj.pdtn]+2] = value
class ParameterNumber:
906class ParameterNumber:
907    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
908    _key = defaultdict(lambda: 1)
909    def __get__(self, obj, objtype=None):
910        return obj.section4[1+2]
911    def __set__(self, obj, value):
912        obj.section4[self._key[obj.pdtn]+2] = value
class VarInfo:
914class VarInfo:
915    """
916    Variable Information.
917
918    These are the metadata returned for a specific variable according to
919    discipline, parameter category, and parameter number.
920    """
921    def __get__(self, obj, objtype=None):
922        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
923    def __set__(self, obj, value):
924        raise RuntimeError

Variable Information.

These are the metadata returned for a specific variable according to discipline, parameter category, and parameter number.

class FullName:
926class FullName:
927    """Full name of the Variable."""
928    def __get__(self, obj, objtype=None):
929        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
930    def __set__(self, obj, value):
931        raise RuntimeError

Full name of the Variable.

class Units:
933class Units:
934    """Units of the Variable."""
935    def __get__(self, obj, objtype=None):
936        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
937    def __set__(self, obj, value):
938        raise RuntimeError

Units of the Variable.

class ShortName:
940class ShortName:
941    """ Short name of the variable (i.e. the variable abbreviation)."""
942    def __get__(self, obj, objtype=None):
943        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[2]
944    def __set__(self, obj, value):
945        raise RuntimeError

Short name of the variable (i.e. the variable abbreviation).

class TypeOfGeneratingProcess:
947class TypeOfGeneratingProcess:
948    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
949    _key = defaultdict(lambda: 2, {48:13})
950    #_key = {0:2, 1:2, 2:2, 5:2, 6:2, 8:2, 9:2, 10:2, 11:2, 12:2, 15:2, 48:13}
951    def __get__(self, obj, objtype=None):
952        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
953    def __set__(self, obj, value):
954        obj.section4[self._key[obj.pdtn]+2] = value
class BackgroundGeneratingProcessIdentifier:
956class BackgroundGeneratingProcessIdentifier:
957    """Background Generating Process Identifier"""
958    _key = defaultdict(lambda: 3, {48:14})
959    #_key = {0:3, 1:3, 2:3, 5:3, 6:3, 8:3, 9:3, 10:3, 11:3, 12:3, 15:3, 48:14}
960    def __get__(self, obj, objtype=None):
961        return obj.section4[self._key[obj.pdtn]+2]
962    def __set__(self, obj, value):
963        obj.section4[self._key[obj.pdtn]+2] = value

Background Generating Process Identifier

class GeneratingProcess:
965class GeneratingProcess:
966    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
967    _key = defaultdict(lambda: 4, {48:15})
968    #_key = {0:4, 1:4, 2:4, 5:4, 6:4, 8:4, 9:4, 10:4, 11:4, 12:4, 15:4, 48:15}
969    def __get__(self, obj, objtype=None):
970        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
971    def __set__(self, obj, value):
972        obj.section4[self._key[obj.pdtn]+2] = value
class HoursAfterDataCutoff:
974class HoursAfterDataCutoff:
975    """Hours of observational data cutoff after reference time."""
976    _key = defaultdict(lambda: 5, {48:16})
977    def __get__(self, obj, objtype=None):
978        return obj.section4[self._key[obj.pdtn]+2]
979    def __set__(self, obj, value):
980        obj.section4[self._key[obj.pdtn]+2] = value

Hours of observational data cutoff after reference time.

class MinutesAfterDataCutoff:
982class MinutesAfterDataCutoff:
983    """Minutes of observational data cutoff after reference time."""
984    _key = defaultdict(lambda: 6, {48:17})
985    def __get__(self, obj, objtype=None):
986        return obj.section4[self._key[obj.pdtn]+2]
987    def __set__(self, obj, value):
988        obj.section4[self._key[obj.pdtn]+2] = value

Minutes of observational data cutoff after reference time.

class UnitOfForecastTime:
990class UnitOfForecastTime:
991    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
992    _key = defaultdict(lambda: 7, {48:18})
993    #_key = {0:7, 1:7, 2:7, 5:7, 6:7, 8:7, 9:7, 10:7, 11:7, 12:7, 15:7, 48:18}
994    def __get__(self, obj, objtype=None):
995        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
996    def __set__(self, obj, value):
997        obj.section4[self._key[obj.pdtn]+2] = value
class ValueOfForecastTime:
 999class ValueOfForecastTime:
1000    """Value of forecast time in units defined by `UnitofForecastTime`."""
1001    _key = defaultdict(lambda: 8, {48:19})
1002    def __get__(self, obj, objtype=None):
1003        return obj.section4[self._key[obj.pdtn]+2]
1004    def __set__(self, obj, value):
1005        obj.section4[self._key[obj.pdtn]+2] = value

Value of forecast time in units defined by UnitofForecastTime.

class LeadTime:
1007class LeadTime:
1008    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
1009
1010    def __get__(self, obj, objtype=None):
1011        return utils.get_leadtime(obj.section1, obj.section4[1], obj.section4[2:])
1012
1013    def __set__(self, obj, value):
1014        pdt = obj.section4[2:]
1015
1016        # For the tables below, the key is the PDTN and the value is the slice
1017        # of the PDT that contains the end date of the accumulation.
1018        # This is only needed for PDTNs 8-12.
1019        _key = {
1020            8: slice(15, 21),
1021            9: slice(22, 28),
1022            10: slice(16, 22),
1023            11: slice(18, 24),
1024            12: slice(17, 23),
1025        }
1026
1027        accumulation_offset = 0
1028        if obj.pdtn in _key:
1029            accumulation_end_date = _key[obj.pdtn]
1030            accumulation_key = accumulation_end_date.stop + 5
1031            accumulation_offset = int(
1032                timedelta64(pdt[accumulation_key], "h") / timedelta64(1, "h")
1033            )
1034            accumulation_offset = accumulation_offset / (
1035                tables.get_value_from_table(
1036                    pdt[accumulation_key - 1], "scale_time_hours"
1037                )
1038            )
1039
1040            refdate = datetime.datetime(*obj.section1[5:11])
1041            pdt[_key[obj.pdtn]] = (
1042                datetime.timedelta(hours=accumulation_offset) + refdate
1043            ).timetuple()[:6]
1044
1045        # All messages need the leadTime value set, but for PDTNs 8-12, the
1046        # leadTime value has to be set to the beginning of the accumulation
1047        # period which is done here by subtracting the already calculated
1048        # value accumulation_offset.
1049        lead_time_index = 8
1050        if obj.pdtn == 48:
1051            lead_time_index = 19
1052
1053        ivalue = int(timedelta64(value, "h") / timedelta64(1, "h"))
1054
1055        pdt[lead_time_index] = (
1056            ivalue
1057            / (
1058                tables.get_value_from_table(
1059                    pdt[lead_time_index - 1], "scale_time_hours"
1060                )
1061            )
1062            - accumulation_offset
1063        )

Forecast Lead Time. NOTE: This is a datetime.timedelta object.

class FixedSfc1Info:
1065class FixedSfc1Info:
1066    """Information of the first fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1067    _key = defaultdict(lambda: 9, {48:20})
1068    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1069    def __get__(self, obj, objtype=None):
1070        if obj.section4[self._key[obj.pdtn]+2] == 255:
1071            return [None, None]
1072        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1073    def __set__(self, obj, value):
1074        raise NotImplementedError

Information of the first fixed surface via table 4.5

class FixedSfc2Info:
1076class FixedSfc2Info:
1077    """Information of the second fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1078    _key = defaultdict(lambda: 12, {48:23})
1079    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1080    def __get__(self, obj, objtype=None):
1081        if obj.section4[self._key[obj.pdtn]+2] == 255:
1082            return [None, None]
1083        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1084    def __set__(self, obj, value):
1085        raise NotImplementedError

Information of the second fixed surface via table 4.5

class TypeOfFirstFixedSurface:
1087class TypeOfFirstFixedSurface:
1088    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1089    _key = defaultdict(lambda: 9, {48:20})
1090    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1091    def __get__(self, obj, objtype=None):
1092        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1093    def __set__(self, obj, value):
1094        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstFixedSurface:
1096class ScaleFactorOfFirstFixedSurface:
1097    """Scale Factor of First Fixed Surface"""
1098    _key = defaultdict(lambda: 10, {48:21})
1099    #_key = {0:10, 1:10, 2:10, 5:10, 6:10, 8:10, 9:10, 10:10, 11:10, 12:10, 15:10, 48:21}
1100    def __get__(self, obj, objtype=None):
1101        return obj.section4[self._key[obj.pdtn]+2]
1102    def __set__(self, obj, value):
1103        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Fixed Surface

class ScaledValueOfFirstFixedSurface:
1105class ScaledValueOfFirstFixedSurface:
1106    """Scaled Value Of First Fixed Surface"""
1107    _key = defaultdict(lambda: 11, {48:22})
1108    #_key = {0:11, 1:11, 2:11, 5:11, 6:11, 8:11, 9:11, 10:11, 11:11, 12:11, 15:11, 48:22}
1109    def __get__(self, obj, objtype=None):
1110        return obj.section4[self._key[obj.pdtn]+2]
1111    def __set__(self, obj, value):
1112        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of First Fixed Surface

class UnitOfFirstFixedSurface:
1114class UnitOfFirstFixedSurface:
1115    """Units of First Fixed Surface"""
1116    def __get__(self, obj, objtype=None):
1117        return obj._fixedsfc1info[1]
1118    def __set__(self, obj, value):
1119        pass

Units of First Fixed Surface

class ValueOfFirstFixedSurface:
1121class ValueOfFirstFixedSurface:
1122    """Value of First Fixed Surface"""
1123    def __get__(self, obj, objtype=None):
1124        scale_factor = getattr(obj, "scaleFactorOfFirstFixedSurface")
1125        scaled_value = getattr(obj, "scaledValueOfFirstFixedSurface")
1126        return scaled_value / (10.**scale_factor)
1127    def __set__(self, obj, value):
1128        scale = _calculate_scale_factor(value)
1129        setattr(obj, "scaleFactorOfFirstFixedSurface", scale)
1130        setattr(obj, "scaledValueOfFirstFixedSurface", value * 10**scale)

Value of First Fixed Surface

class TypeOfSecondFixedSurface:
1132class TypeOfSecondFixedSurface:
1133    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1134    _key = defaultdict(lambda: 12, {48:23})
1135    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1136    def __get__(self, obj, objtype=None):
1137        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1138    def __set__(self, obj, value):
1139        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfSecondFixedSurface:
1141class ScaleFactorOfSecondFixedSurface:
1142    """Scale Factor of Second Fixed Surface"""
1143    _key = defaultdict(lambda: 13, {48:24})
1144    #_key = {0:13, 1:13, 2:13, 5:13, 6:13, 8:13, 9:13, 10:13, 11:13, 12:13, 15:13, 48:24}
1145    def __get__(self, obj, objtype=None):
1146        return obj.section4[self._key[obj.pdtn]+2]
1147    def __set__(self, obj, value):
1148        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Fixed Surface

class ScaledValueOfSecondFixedSurface:
1150class ScaledValueOfSecondFixedSurface:
1151    """Scaled Value Of Second Fixed Surface"""
1152    _key = defaultdict(lambda: 14, {48:25})
1153    #_key = {0:14, 1:14, 2:14, 5:14, 6:14, 8:14, 9:14, 10:14, 11:14, 12:14, 15:14, 48:25}
1154    def __get__(self, obj, objtype=None):
1155        return obj.section4[self._key[obj.pdtn]+2]
1156    def __set__(self, obj, value):
1157        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of Second Fixed Surface

class UnitOfSecondFixedSurface:
1159class UnitOfSecondFixedSurface:
1160    """Units of Second Fixed Surface"""
1161    def __get__(self, obj, objtype=None):
1162        return obj._fixedsfc2info[1]
1163    def __set__(self, obj, value):
1164        pass

Units of Second Fixed Surface

class ValueOfSecondFixedSurface:
1166class ValueOfSecondFixedSurface:
1167    """Value of Second Fixed Surface"""
1168    def __get__(self, obj, objtype=None):
1169        scale_factor = getattr(obj, "scaleFactorOfSecondFixedSurface")
1170        scaled_value = getattr(obj, "scaledValueOfSecondFixedSurface")
1171        return scaled_value / (10.**scale_factor)
1172    def __set__(self, obj, value):
1173        scale = _calculate_scale_factor(value)
1174        setattr(obj, "scaleFactorOfSecondFixedSurface", scale)
1175        setattr(obj, "scaledValueOfSecondFixedSurface", value * 10**scale)

Value of Second Fixed Surface

class Level:
1177class Level:
1178    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1179    def __get__(self, obj, objtype=None):
1180        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1181    def __set__(self, obj, value):
1182        pass

Level (same as provided by wgrib2)

class TypeOfEnsembleForecast:
1184class TypeOfEnsembleForecast:
1185    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1186    _key = {1:15, 11:15}
1187    def __get__(self, obj, objtype=None):
1188        pdtn = obj.section4[1]
1189        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1190    def __set__(self, obj, value):
1191        pdtn = obj.section4[1]
1192        obj.section4[self._key[pdtn]+2] = value
class PerturbationNumber:
1194class PerturbationNumber:
1195    """Ensemble Perturbation Number"""
1196    _key = {1:16, 11:16}
1197    def __get__(self, obj, objtype=None):
1198        pdtn = obj.section4[1]
1199        return obj.section4[self._key[pdtn]+2]
1200    def __set__(self, obj, value):
1201        pdtn = obj.section4[1]
1202        obj.section4[self._key[pdtn]+2] = value

Ensemble Perturbation Number

class NumberOfEnsembleForecasts:
1204class NumberOfEnsembleForecasts:
1205    """Total Number of Ensemble Forecasts"""
1206    _key = {1:17, 2:16, 11:17, 12:16}
1207    def __get__(self, obj, objtype=None):
1208        pdtn = obj.section4[1]
1209        return obj.section4[self._key[pdtn]+2]
1210    def __set__(self, obj, value):
1211        pdtn = obj.section4[1]
1212        obj.section4[self._key[pdtn]+2] = value

Total Number of Ensemble Forecasts

class TypeOfDerivedForecast:
1214class TypeOfDerivedForecast:
1215    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1216    _key = {2:15, 12:15}
1217    def __get__(self, obj, objtype=None):
1218        pdtn = obj.section4[1]
1219        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1220    def __set__(self, obj, value):
1221        pdtn = obj.section4[1]
1222        obj.section4[self._key[pdtn]+2] = value
class ForecastProbabilityNumber:
1224class ForecastProbabilityNumber:
1225    """Forecast Probability Number"""
1226    _key = {5:15, 9:15}
1227    def __get__(self, obj, objtype=None):
1228        pdtn = obj.section4[1]
1229        return obj.section4[self._key[pdtn]+2]
1230    def __set__(self, obj, value):
1231        pdtn = obj.section4[1]
1232        obj.section4[self._key[pdtn]+2] = value

Forecast Probability Number

class TotalNumberOfForecastProbabilities:
1234class TotalNumberOfForecastProbabilities:
1235    """Total Number of Forecast Probabilities"""
1236    _key = {5:16, 9:16}
1237    def __get__(self, obj, objtype=None):
1238        pdtn = obj.section4[1]
1239        return obj.section4[self._key[pdtn]+2]
1240    def __set__(self, obj, value):
1241        pdtn = obj.section4[1]
1242        obj.section4[self._key[pdtn]+2] = value

Total Number of Forecast Probabilities

class TypeOfProbability:
1244class TypeOfProbability:
1245    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1246    _key = {5:17, 9:17}
1247    def __get__(self, obj, objtype=None):
1248        pdtn = obj.section4[1]
1249        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1250    def __set__(self, obj, value):
1251        pdtn = obj.section4[1]
1252        obj.section4[self._key[pdtn]+2] = value
class ScaleFactorOfThresholdLowerLimit:
1254class ScaleFactorOfThresholdLowerLimit:
1255    """Scale Factor of Threshold Lower Limit"""
1256    _key = {5:18, 9:18}
1257    def __get__(self, obj, objtype=None):
1258        pdtn = obj.section4[1]
1259        return obj.section4[self._key[pdtn]+2]
1260    def __set__(self, obj, value):
1261        pdtn = obj.section4[1]
1262        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Lower Limit

class ScaledValueOfThresholdLowerLimit:
1264class ScaledValueOfThresholdLowerLimit:
1265    """Scaled Value of Threshold Lower Limit"""
1266    _key = {5:19, 9:19}
1267    def __get__(self, obj, objtype=None):
1268        pdtn = obj.section4[1]
1269        return obj.section4[self._key[pdtn]+2]
1270    def __set__(self, obj, value):
1271        pdtn = obj.section4[1]
1272        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Lower Limit

class ScaleFactorOfThresholdUpperLimit:
1274class ScaleFactorOfThresholdUpperLimit:
1275    """Scale Factor of Threshold Upper Limit"""
1276    _key = {5:20, 9:20}
1277    def __get__(self, obj, objtype=None):
1278        pdtn = obj.section4[1]
1279        return obj.section4[self._key[pdtn]+2]
1280    def __set__(self, obj, value):
1281        pdtn = obj.section4[1]
1282        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Upper Limit

class ScaledValueOfThresholdUpperLimit:
1284class ScaledValueOfThresholdUpperLimit:
1285    """Scaled Value of Threshold Upper Limit"""
1286    _key = {5:21, 9:21}
1287    def __get__(self, obj, objtype=None):
1288        pdtn = obj.section4[1]
1289        return obj.section4[self._key[pdtn]+2]
1290    def __set__(self, obj, value):
1291        pdtn = obj.section4[1]
1292        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Upper Limit

class ThresholdLowerLimit:
1294class ThresholdLowerLimit:
1295    """Threshold Lower Limit"""
1296    def __get__(self, obj, objtype=None):
1297        scale_factor = getattr(obj, "scaleFactorOfThresholdLowerLimit")
1298        scaled_value = getattr(obj, "scaledValueOfThresholdLowerLimit")
1299        if scale_factor == -127 and scaled_value == 255:
1300            return 0.0
1301        return scaled_value / (10.**scale_factor)
1302    def __set__(self, obj, value):
1303        scale = _calculate_scale_factor(value)
1304        setattr(obj, "scaleFactorOfThresholdLowerLimit", scale)
1305        setattr(obj, "scaledValueOfThresholdLowerLimit", value * 10**scale)

Threshold Lower Limit

class ThresholdUpperLimit:
1307class ThresholdUpperLimit:
1308    """Threshold Upper Limit"""
1309    def __get__(self, obj, objtype=None):
1310        scale_factor = getattr(obj, "scaleFactorOfThresholdUpperLimit")
1311        scaled_value = getattr(obj, "scaledValueOfThresholdUpperLimit")
1312        if scale_factor == -127 and scaled_value == 255:
1313            return 0.0
1314        return scaled_value / (10.**scale_factor)
1315    def __set__(self, obj, value):
1316        scale = _calculate_scale_factor(value)
1317        setattr(obj, "scaleFactorOfThresholdUpperLimit", scale)
1318        setattr(obj, "scaledValueOfThresholdUpperLimit", value * 10**scale)

Threshold Upper Limit

class Threshold:
1320class Threshold:
1321    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1322    def __get__(self, obj, objtype=None):
1323        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1324    def __set__(self, obj, value):
1325        pass

Threshold string (same as wgrib2)

class PercentileValue:
1327class PercentileValue:
1328    """Percentile Value"""
1329    _key = {6:15, 10:15}
1330    def __get__(self, obj, objtype=None):
1331        pdtn = obj.section4[1]
1332        return obj.section4[self._key[pdtn]+2]
1333    def __set__(self, obj, value):
1334        pdtn = obj.section4[1]
1335        obj.section4[self._key[pdtn]+2] = value

Percentile Value

class YearOfEndOfTimePeriod:
1337class YearOfEndOfTimePeriod:
1338    """Year of End of Forecast Time Period"""
1339    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1340    def __get__(self, obj, objtype=None):
1341        pdtn = obj.section4[1]
1342        return obj.section4[self._key[pdtn]+2]
1343    def __set__(self, obj, value):
1344        pdtn = obj.section4[1]
1345        obj.section4[self._key[pdtn]+2] = value

Year of End of Forecast Time Period

class MonthOfEndOfTimePeriod:
1347class MonthOfEndOfTimePeriod:
1348    """Month Year of End of Forecast Time Period"""
1349    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1350    def __get__(self, obj, objtype=None):
1351        pdtn = obj.section4[1]
1352        return obj.section4[self._key[pdtn]+2]
1353    def __set__(self, obj, value):
1354        pdtn = obj.section4[1]
1355        obj.section4[self._key[pdtn]+2] = value

Month Year of End of Forecast Time Period

class DayOfEndOfTimePeriod:
1357class DayOfEndOfTimePeriod:
1358    """Day Year of End of Forecast Time Period"""
1359    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1360    def __get__(self, obj, objtype=None):
1361        pdtn = obj.section4[1]
1362        return obj.section4[self._key[pdtn]+2]
1363    def __set__(self, obj, value):
1364        pdtn = obj.section4[1]
1365        obj.section4[self._key[pdtn]+2] = value

Day Year of End of Forecast Time Period

class HourOfEndOfTimePeriod:
1367class HourOfEndOfTimePeriod:
1368    """Hour Year of End of Forecast Time Period"""
1369    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1370    def __get__(self, obj, objtype=None):
1371        pdtn = obj.section4[1]
1372        return obj.section4[self._key[pdtn]+2]
1373    def __set__(self, obj, value):
1374        pdtn = obj.section4[1]
1375        obj.section4[self._key[pdtn]+2] = value

Hour Year of End of Forecast Time Period

class MinuteOfEndOfTimePeriod:
1377class MinuteOfEndOfTimePeriod:
1378    """Minute Year of End of Forecast Time Period"""
1379    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1380    def __get__(self, obj, objtype=None):
1381        pdtn = obj.section4[1]
1382        return obj.section4[self._key[pdtn]+2]
1383    def __set__(self, obj, value):
1384        pdtn = obj.section4[1]
1385        obj.section4[self._key[pdtn]+2] = value

Minute Year of End of Forecast Time Period

class SecondOfEndOfTimePeriod:
1387class SecondOfEndOfTimePeriod:
1388    """Second Year of End of Forecast Time Period"""
1389    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1390    def __get__(self, obj, objtype=None):
1391        pdtn = obj.section4[1]
1392        return obj.section4[self._key[pdtn]+2]
1393    def __set__(self, obj, value):
1394        pdtn = obj.section4[1]
1395        obj.section4[self._key[pdtn]+2] = value

Second Year of End of Forecast Time Period

class Duration:
1397class Duration:
1398    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1399    def __get__(self, obj, objtype=None):
1400        return utils.get_duration(obj.section4[1],obj.section4[2:])
1401    def __set__(self, obj, value):
1402        pass

Duration of time period. NOTE: This is a datetime.timedelta object.

class ValidDate:
1404class ValidDate:
1405    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1406    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1407    def __get__(self, obj, objtype=None):
1408        pdtn = obj.section4[1]
1409        try:
1410            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1411            return datetime.datetime(*obj.section4[s])
1412        except(KeyError):
1413            return obj.refDate + obj.leadTime
1414    def __set__(self, obj, value):
1415        pass

Valid Date of the forecast. NOTE: This is a datetime.datetime object.

class NumberOfTimeRanges:
1417class NumberOfTimeRanges:
1418    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1419    _key = {8:21, 9:28, 10:22, 11:24, 12:23}
1420    def __get__(self, obj, objtype=None):
1421        pdtn = obj.section4[1]
1422        return obj.section4[self._key[pdtn]+2]
1423    def __set__(self, obj, value):
1424        pdtn = obj.section4[1]
1425        obj.section4[self._key[pdtn]+2] = value

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

class NumberOfMissingValues:
1427class NumberOfMissingValues:
1428    """Total number of data values missing in statistical process"""
1429    _key = {8:22, 9:29, 10:23, 11:25, 12:24}
1430    def __get__(self, obj, objtype=None):
1431        pdtn = obj.section4[1]
1432        return obj.section4[self._key[pdtn]+2]
1433    def __set__(self, obj, value):
1434        pdtn = obj.section4[1]
1435        obj.section4[self._key[pdtn]+2] = value

Total number of data values missing in statistical process

class StatisticalProcess:
1437class StatisticalProcess:
1438    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1439    _key = {8:23, 9:30, 10:24, 11:26, 12:25, 15:15}
1440    def __get__(self, obj, objtype=None):
1441        pdtn = obj.section4[1]
1442        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.10')
1443    def __set__(self, obj, value):
1444        pdtn = obj.section4[1]
1445        obj.section4[self._key[pdtn]+2] = value
class TypeOfTimeIncrementOfStatisticalProcess:
1447class TypeOfTimeIncrementOfStatisticalProcess:
1448    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1449    _key = {8:24, 9:31, 10:25, 11:27, 12:26}
1450    def __get__(self, obj, objtype=None):
1451        pdtn = obj.section4[1]
1452        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.11')
1453    def __set__(self, obj, value):
1454        pdtn = obj.section4[1]
1455        obj.section4[self._key[pdtn]+2] = value
class UnitOfTimeRangeOfStatisticalProcess:
1457class UnitOfTimeRangeOfStatisticalProcess:
1458    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1459    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
1460    def __get__(self, obj, objtype=None):
1461        pdtn = obj.section4[1]
1462        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1463    def __set__(self, obj, value):
1464        pdtn = obj.section4[1]
1465        obj.section4[self._key[pdtn]+2] = value
class TimeRangeOfStatisticalProcess:
1467class TimeRangeOfStatisticalProcess:
1468    """Time Range of Statistical Process"""
1469    _key = {8:26, 9:33, 10:27, 11:29, 12:28}
1470    def __get__(self, obj, objtype=None):
1471        pdtn = obj.section4[1]
1472        return obj.section4[self._key[pdtn]+2]
1473    def __set__(self, obj, value):
1474        pdtn = obj.section4[1]
1475        obj.section4[self._key[pdtn]+2] = value

Time Range of Statistical Process

class UnitOfTimeRangeOfSuccessiveFields:
1477class UnitOfTimeRangeOfSuccessiveFields:
1478    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1479    _key = {8:27, 9:34, 10:28, 11:30, 12:29}
1480    def __get__(self, obj, objtype=None):
1481        pdtn = obj.section4[1]
1482        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1483    def __set__(self, obj, value):
1484        pdtn = obj.section4[1]
1485        obj.section4[self._key[pdtn]+2] = value
class TimeIncrementOfSuccessiveFields:
1487class TimeIncrementOfSuccessiveFields:
1488    """Time Increment of Successive Fields"""
1489    _key = {8:28, 9:35, 10:29, 11:31, 12:30}
1490    def __get__(self, obj, objtype=None):
1491        pdtn = obj.section4[1]
1492        return obj.section4[self._key[pdtn]+2]
1493    def __set__(self, obj, value):
1494        pdtn = obj.section4[1]
1495        obj.section4[self._key[pdtn]+2] = value

Time Increment of Successive Fields

class TypeOfStatisticalProcessing:
1497class TypeOfStatisticalProcessing:
1498    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1499    _key = {15:16}
1500    def __get__(self, obj, objtype=None):
1501        pdtn = obj.section4[1]
1502        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1503    def __set__(self, obj, value):
1504        pdtn = obj.section4[1]
1505        obj.section4[self._key[pdtn]+2] = value
class NumberOfDataPointsForSpatialProcessing:
1507class NumberOfDataPointsForSpatialProcessing:
1508    """Number of Data Points for Spatial Processing"""
1509    _key = {15:17}
1510    def __get__(self, obj, objtype=None):
1511        pdtn = obj.section4[1]
1512        return obj.section4[self._key[pdtn]+2]
1513    def __set__(self, obj, value):
1514        pdtn = obj.section4[1]
1515        obj.section4[self._key[pdtn]+2] = value

Number of Data Points for Spatial Processing

class NumberOfContributingSpectralBands:
1517class NumberOfContributingSpectralBands:
1518    """Number of Contributing Spectral Bands (NB)"""
1519    _key = {32:9}
1520    def __get__(self, obj, objtype=None):
1521        pdtn = obj.section4[1]
1522        return obj.section4[self._key[pdtn]+2]
1523    def __set__(self, obj, value):
1524        pdtn = obj.section4[1]
1525        obj.section4[self._key[pdtn]+2] = value

Number of Contributing Spectral Bands (NB)

class SatelliteSeries:
1527class SatelliteSeries:
1528    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1529    _key = {32:10}
1530    def __get__(self, obj, objtype=None):
1531        pdtn = obj.section4[1]
1532        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1533    def __set__(self, obj, value):
1534        pass

Satellte Series of band nb, where nb=1,NB if NB > 0

class SatelliteNumber:
1536class SatelliteNumber:
1537    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1538    _key = {32:11}
1539    def __get__(self, obj, objtype=None):
1540        pdtn = obj.section4[1]
1541        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1542    def __set__(self, obj, value):
1543        pass

Satellte Number of band nb, where nb=1,NB if NB > 0

class InstrumentType:
1545class InstrumentType:
1546    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1547    _key = {32:12}
1548    def __get__(self, obj, objtype=None):
1549        pdtn = obj.section4[1]
1550        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1551    def __set__(self, obj, value):
1552        pass

Instrument Type of band nb, where nb=1,NB if NB > 0

class ScaleFactorOfCentralWaveNumber:
1554class ScaleFactorOfCentralWaveNumber:
1555    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1556    _key = {32:13}
1557    def __get__(self, obj, objtype=None):
1558        pdtn = obj.section4[1]
1559        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1560    def __set__(self, obj, value):
1561        pass

Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0

class ScaledValueOfCentralWaveNumber:
1563class ScaledValueOfCentralWaveNumber:
1564    """Scaled Value Of Central WaveNumber of band NB"""
1565    _key = {32:14}
1566    def __get__(self, obj, objtype=None):
1567        pdtn = obj.section4[1]
1568        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1569    def __set__(self, obj, value):
1570        pass

Scaled Value Of Central WaveNumber of band NB

class TypeOfAerosol:
1572class TypeOfAerosol:
1573    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1574    _key = {48:2}
1575    def __get__(self, obj, objtype=None):
1576        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1577    def __set__(self, obj, value):
1578        obj.section4[self._key[obj.pdtn]+2] = value
class TypeOfIntervalForAerosolSize:
1580class TypeOfIntervalForAerosolSize:
1581    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1582    _key = {48:3}
1583    def __get__(self, obj, objtype=None):
1584        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1585    def __set__(self, obj, value):
1586        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstSize:
1588class ScaleFactorOfFirstSize:
1589    """Scale Factor of First Size"""
1590    _key = {48:4}
1591    def __get__(self, obj, objtype=None):
1592        return obj.section4[self._key[obj.pdtn]+2]
1593    def __set__(self, obj, value):
1594        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Size

class ScaledValueOfFirstSize:
1596class ScaledValueOfFirstSize:
1597    """Scaled Value of First Size"""
1598    _key = {48:5}
1599    def __get__(self, obj, objtype=None):
1600        return obj.section4[self._key[obj.pdtn]+2]
1601    def __set__(self, obj, value):
1602        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Size

class ScaleFactorOfSecondSize:
1604class ScaleFactorOfSecondSize:
1605    """Scale Factor of Second Size"""
1606    _key = {48:6}
1607    def __get__(self, obj, objtype=None):
1608        return obj.section4[self._key[obj.pdtn]+2]
1609    def __set__(self, obj, value):
1610        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Size

class ScaledValueOfSecondSize:
1612class ScaledValueOfSecondSize:
1613    """Scaled Value of Second Size"""
1614    _key = {48:7}
1615    def __get__(self, obj, objtype=None):
1616        return obj.section4[self._key[obj.pdtn]+2]
1617    def __set__(self, obj, value):
1618        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Size

class TypeOfIntervalForAerosolWavelength:
1620class TypeOfIntervalForAerosolWavelength:
1621    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1622    _key = {48:8}
1623    def __get__(self, obj, objtype=None):
1624        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1625    def __set__(self, obj, value):
1626        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstWavelength:
1628class ScaleFactorOfFirstWavelength:
1629    """Scale Factor of First Wavelength"""
1630    _key = {48:9}
1631    def __get__(self, obj, objtype=None):
1632        return obj.section4[self._key[obj.pdtn]+2]
1633    def __set__(self, obj, value):
1634        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Wavelength

class ScaledValueOfFirstWavelength:
1636class ScaledValueOfFirstWavelength:
1637    """Scaled Value of First Wavelength"""
1638    _key = {48:10}
1639    def __get__(self, obj, objtype=None):
1640        return obj.section4[self._key[obj.pdtn]+2]
1641    def __set__(self, obj, value):
1642        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Wavelength

class ScaleFactorOfSecondWavelength:
1644class ScaleFactorOfSecondWavelength:
1645    """Scale Factor of Second Wavelength"""
1646    _key = {48:11}
1647    def __get__(self, obj, objtype=None):
1648        return obj.section4[self._key[obj.pdtn]+2]
1649    def __set__(self, obj, value):
1650        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Wavelength

class ScaledValueOfSecondWavelength:
1652class ScaledValueOfSecondWavelength:
1653    """Scaled Value of Second Wavelength"""
1654    _key = {48:12}
1655    def __get__(self, obj, objtype=None):
1656        return obj.section4[self._key[obj.pdtn]+2]
1657    def __set__(self, obj, value):
1658        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplateBase:
1664@dataclass(init=False)
1665class ProductDefinitionTemplateBase:
1666    """Base attributes for Product Definition Templates"""
1667    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1668    fullName: str = field(init=False, repr=False, default=FullName())
1669    units: str = field(init=False, repr=False, default=Units())
1670    shortName: str = field(init=False, repr=False, default=ShortName())
1671    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1672    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1673    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1674    level: str = field(init=False, repr=False, default=Level())
1675    # Begin template here...
1676    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1677    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1678    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1679    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1680    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1681    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1682    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1683    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1684    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1685    @classmethod
1686    @property
1687    def _attrs(cls):
1688        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]

Base attributes for Product Definition Templates

fullName: str

Full name of the Variable.

units: str

Units of the Variable.

shortName: str

Short name of the variable (i.e. the variable abbreviation).

leadTime: datetime.timedelta

Forecast Lead Time. NOTE: This is a datetime.timedelta object.

duration: datetime.timedelta

Duration of time period. NOTE: This is a datetime.timedelta object.

validDate: datetime.datetime

Valid Date of the forecast. NOTE: This is a datetime.datetime object.

level: str

Level (same as provided by wgrib2)

parameterCategory: int
parameterNumber: int
typeOfGeneratingProcess: Grib2Metadata
generatingProcess: Grib2Metadata
backgroundGeneratingProcessIdentifier: int

Background Generating Process Identifier

hoursAfterDataCutoff: int

Hours of observational data cutoff after reference time.

minutesAfterDataCutoff: int

Minutes of observational data cutoff after reference time.

valueOfForecastTime: int

Value of forecast time in units defined by UnitofForecastTime.

@dataclass(init=False)
class ProductDefinitionTemplateSurface:
1690@dataclass(init=False)
1691class ProductDefinitionTemplateSurface:
1692    """Surface attributes for Product Definition Templates"""
1693    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
1694    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
1695    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1696    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1697    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1698    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1699    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1700    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1701    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
1702    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
1703    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
1704    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
1705    @classmethod
1706    @property
1707    def _attrs(cls):
1708        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]

Surface attributes for Product Definition Templates

typeOfFirstFixedSurface: Grib2Metadata
scaleFactorOfFirstFixedSurface: int

Scale Factor of First Fixed Surface

scaledValueOfFirstFixedSurface: int

Scaled Value Of First Fixed Surface

typeOfSecondFixedSurface: Grib2Metadata
scaleFactorOfSecondFixedSurface: int

Scale Factor of Second Fixed Surface

scaledValueOfSecondFixedSurface: int

Scaled Value Of Second Fixed Surface

unitOfFirstFixedSurface: str

Units of First Fixed Surface

valueOfFirstFixedSurface: int

Value of First Fixed Surface

unitOfSecondFixedSurface: str

Units of Second Fixed Surface

valueOfSecondFixedSurface: int

Value of Second Fixed Surface

@dataclass(init=False)
class ProductDefinitionTemplate0(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1710@dataclass(init=False)
1711class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1712    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
1713    _len = 15
1714    _num = 0
1715    @classmethod
1716    @property
1717    def _attrs(cls):
1718        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
@dataclass(init=False)
class ProductDefinitionTemplate1(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1720@dataclass(init=False)
1721class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1722    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
1723    _len = 18
1724    _num = 1
1725    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1726    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1727    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1728    @classmethod
1729    @property
1730    def _attrs(cls):
1731        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate2(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1733@dataclass(init=False)
1734class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1735    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
1736    _len = 17
1737    _num = 2
1738    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1739    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1740    @classmethod
1741    @property
1742    def _attrs(cls):
1743        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfDerivedForecast: Grib2Metadata
numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate5(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1745@dataclass(init=False)
1746class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1747    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
1748    _len = 22
1749    _num = 5
1750    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1751    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1752    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1753    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1754    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1755    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1756    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1757    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1758    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1759    threshold: str = field(init=False, repr=False, default=Threshold())
1760    @classmethod
1761    @property
1762    def _attrs(cls):
1763        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
forecastProbabilityNumber: int

Forecast Probability Number

totalNumberOfForecastProbabilities: int

Total Number of Forecast Probabilities

typeOfProbability: Grib2Metadata
scaleFactorOfThresholdLowerLimit: float

Scale Factor of Threshold Lower Limit

scaledValueOfThresholdLowerLimit: float

Scaled Value of Threshold Lower Limit

scaleFactorOfThresholdUpperLimit: float

Scale Factor of Threshold Upper Limit

scaledValueOfThresholdUpperLimit: float

Scaled Value of Threshold Upper Limit

thresholdLowerLimit: float

Threshold Lower Limit

thresholdUpperLimit: float

Threshold Upper Limit

threshold: str

Threshold string (same as wgrib2)

@dataclass(init=False)
class ProductDefinitionTemplate6(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1765@dataclass(init=False)
1766class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1767    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
1768    _len = 16
1769    _num = 6
1770    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1771    @classmethod
1772    @property
1773    def _attrs(cls):
1774        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
percentileValue: int

Percentile Value

@dataclass(init=False)
class ProductDefinitionTemplate8(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1776@dataclass(init=False)
1777class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1778    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
1779    _len = 29
1780    _num = 8
1781    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1782    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1783    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1784    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1785    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1786    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1787    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1788    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1789    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1790    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1791    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1792    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1793    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1794    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1795    @classmethod
1796    @property
1797    def _attrs(cls):
1798        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

numberOfMissingValues: int

Total number of data values missing in statistical process

statisticalProcess: Grib2Metadata
typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate9(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1800@dataclass(init=False)
1801class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1802    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
1803    _len = 36
1804    _num = 9
1805    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1806    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1807    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1808    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1809    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1810    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1811    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1812    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1813    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1814    threshold: str = field(init=False, repr=False, default=Threshold())
1815    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1816    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1817    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1818    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1819    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1820    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1821    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1822    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1823    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1824    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1825    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1826    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1827    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1828    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1829    @classmethod
1830    @property
1831    def _attrs(cls):
1832        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
forecastProbabilityNumber: int

Forecast Probability Number

totalNumberOfForecastProbabilities: int

Total Number of Forecast Probabilities

typeOfProbability: Grib2Metadata
scaleFactorOfThresholdLowerLimit: float

Scale Factor of Threshold Lower Limit

scaledValueOfThresholdLowerLimit: float

Scaled Value of Threshold Lower Limit

scaleFactorOfThresholdUpperLimit: float

Scale Factor of Threshold Upper Limit

scaledValueOfThresholdUpperLimit: float

Scaled Value of Threshold Upper Limit

thresholdLowerLimit: float

Threshold Lower Limit

thresholdUpperLimit: float

Threshold Upper Limit

threshold: str

Threshold string (same as wgrib2)

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

numberOfMissingValues: int

Total number of data values missing in statistical process

statisticalProcess: Grib2Metadata
typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate10(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1834@dataclass(init=False)
1835class ProductDefinitionTemplate10(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1836    """[Product Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-10.shtml)"""
1837    _len = 30
1838    _num = 10
1839    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1840    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1841    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1842    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1843    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1844    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1845    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1846    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1847    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1848    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1849    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1850    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1851    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1852    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1853    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1854    @classmethod
1855    @property
1856    def _attrs(cls):
1857        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
percentileValue: int

Percentile Value

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

numberOfMissingValues: int

Total number of data values missing in statistical process

statisticalProcess: Grib2Metadata
typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate11(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1859@dataclass(init=False)
1860class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1861    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
1862    _len = 32
1863    _num = 11
1864    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1865    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1866    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1867    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1868    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1869    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1870    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1871    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1872    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1873    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1874    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1875    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1876    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1877    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1878    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1879    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1880    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1881    @classmethod
1882    @property
1883    def _attrs(cls):
1884        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

numberOfMissingValues: int

Total number of data values missing in statistical process

statisticalProcess: Grib2Metadata
typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate12(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1886@dataclass(init=False)
1887class ProductDefinitionTemplate12(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1888    """[Product Definition Template 12](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-12.shtml)"""
1889    _len = 31
1890    _num = 12
1891    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1892    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1893    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1894    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1895    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1896    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1897    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1898    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1899    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1900    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1901    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1902    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1903    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1904    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1905    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1906    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1907    @classmethod
1908    @property
1909    def _attrs(cls):
1910        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfDerivedForecast: Grib2Metadata
numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field

numberOfMissingValues: int

Total number of data values missing in statistical process

statisticalProcess: Grib2Metadata
typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate15(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1912@dataclass(init=False)
1913class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1914    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
1915    _len = 18
1916    _num = 15
1917    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1918    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
1919    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
1920    @classmethod
1921    @property
1922    def _attrs(cls):
1923        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
statisticalProcess: Grib2Metadata
typeOfStatisticalProcessing: Grib2Metadata
numberOfDataPointsForSpatialProcessing: int

Number of Data Points for Spatial Processing

@dataclass(init=False)
class ProductDefinitionTemplate31:
1925@dataclass(init=False)
1926class ProductDefinitionTemplate31:
1927    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
1928    _len = 5
1929    _num = 31
1930    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1931    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1932    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1933    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1934    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1935    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1936    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1937    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1938    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1939    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1940    @classmethod
1941    @property
1942    def _attrs(cls):
1943        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
parameterCategory: int
parameterNumber: int
typeOfGeneratingProcess: Grib2Metadata
generatingProcess: Grib2Metadata
numberOfContributingSpectralBands: int

Number of Contributing Spectral Bands (NB)

satelliteSeries: list

Satellte Series of band nb, where nb=1,NB if NB > 0

satelliteNumber: list

Satellte Number of band nb, where nb=1,NB if NB > 0

instrumentType: list

Instrument Type of band nb, where nb=1,NB if NB > 0

scaleFactorOfCentralWaveNumber: list

Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0

scaledValueOfCentralWaveNumber: list

Scaled Value Of Central WaveNumber of band NB

@dataclass(init=False)
class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
1945@dataclass(init=False)
1946class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
1947    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
1948    _len = 10
1949    _num = 32
1950    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1951    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1952    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1953    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1954    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1955    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1956    @classmethod
1957    @property
1958    def _attrs(cls):
1959        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
numberOfContributingSpectralBands: int

Number of Contributing Spectral Bands (NB)

satelliteSeries: list

Satellte Series of band nb, where nb=1,NB if NB > 0

satelliteNumber: list

Satellte Number of band nb, where nb=1,NB if NB > 0

instrumentType: list

Instrument Type of band nb, where nb=1,NB if NB > 0

scaleFactorOfCentralWaveNumber: list

Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0

scaledValueOfCentralWaveNumber: list

Scaled Value Of Central WaveNumber of band NB

@dataclass(init=False)
class ProductDefinitionTemplate48(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1961@dataclass(init=False)
1962class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1963    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
1964    _len = 26
1965    _num = 48
1966    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
1967    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
1968    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
1969    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
1970    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
1971    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
1972    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
1973    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
1974    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
1975    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
1976    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
1977    @classmethod
1978    @property
1979    def _attrs(cls):
1980        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

def pdt_class_by_pdtn(pdtn: int):
1999def pdt_class_by_pdtn(pdtn: int):
2000    """
2001    Provide a Product Definition Template class via the template number.
2002
2003    Parameters
2004    ----------
2005    pdtn
2006        Product definition template number.
2007
2008    Returns
2009    -------
2010    pdt_class_by_pdtn
2011        Product definition template class object (not an instance).
2012    """
2013    return _pdt_by_pdtn[pdtn]

Provide a Product Definition Template class via the template number.

Parameters
  • pdtn: Product definition template number.
Returns
  • pdt_class_by_pdtn: Product definition template class object (not an instance).
class NumberOfPackedValues:
2018class NumberOfPackedValues:
2019    """Number of Packed Values"""
2020    def __get__(self, obj, objtype=None):
2021        return obj.section5[0]
2022    def __set__(self, obj, value):
2023        pass

Number of Packed Values

class DataRepresentationTemplateNumber:
2025class DataRepresentationTemplateNumber:
2026    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
2027    def __get__(self, obj, objtype=None):
2028        return Grib2Metadata(obj.section5[1],table='5.0')
2029    def __set__(self, obj, value):
2030        pass
class DataRepresentationTemplate:
2032class DataRepresentationTemplate:
2033    """Data Representation Template"""
2034    def __get__(self, obj, objtype=None):
2035        return obj.section5[2:]
2036    def __set__(self, obj, value):
2037        raise NotImplementedError

Data Representation Template

class RefValue:
2039class RefValue:
2040    """Reference Value (represented as an IEEE 32-bit floating point value)"""
2041    def __get__(self, obj, objtype=None):
2042        return utils.ieee_int_to_float(obj.section5[0+2])
2043    def __set__(self, obj, value):
2044        pass

Reference Value (represented as an IEEE 32-bit floating point value)

class BinScaleFactor:
2046class BinScaleFactor:
2047    """Binary Scale Factor"""
2048    def __get__(self, obj, objtype=None):
2049        return obj.section5[1+2]
2050    def __set__(self, obj, value):
2051        obj.section5[1+2] = value

Binary Scale Factor

class DecScaleFactor:
2053class DecScaleFactor:
2054    """Decimal Scale Factor"""
2055    def __get__(self, obj, objtype=None):
2056        return obj.section5[2+2]
2057    def __set__(self, obj, value):
2058        obj.section5[2+2] = value

Decimal Scale Factor

class NBitsPacking:
2060class NBitsPacking:
2061    """Minimum number of bits for packing"""
2062    def __get__(self, obj, objtype=None):
2063        return obj.section5[3+2]
2064    def __set__(self, obj, value):
2065        obj.section5[3+2] = value

Minimum number of bits for packing

class TypeOfValues:
2067class TypeOfValues:
2068    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2069    def __get__(self, obj, objtype=None):
2070        return Grib2Metadata(obj.section5[4+2],table='5.1')
2071    def __set__(self, obj, value):
2072        obj.section5[4+2] = value
class GroupSplittingMethod:
2074class GroupSplittingMethod:
2075    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2076    def __get__(self, obj, objtype=None):
2077        return Grib2Metadata(obj.section5[5+2],table='5.4')
2078    def __set__(self, obj, value):
2079        obj.section5[5+2] = value
class TypeOfMissingValueManagement:
2081class TypeOfMissingValueManagement:
2082    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2083    def __get__(self, obj, objtype=None):
2084        return Grib2Metadata(obj.section5[6+2],table='5.5')
2085    def __set__(self, obj, value):
2086        obj.section5[6+2] = value
class PriMissingValue:
2088class PriMissingValue:
2089    """Primary Missing Value"""
2090    def __get__(self, obj, objtype=None):
2091        if obj.typeOfValues == 0:
2092            return utils.ieee_int_to_float(obj.section5[7+2]) if obj.section5[6+2] in {1,2} and obj.section5[7+2] != 255 else None
2093        elif obj.typeOfValues == 1:
2094            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2095    def __set__(self, obj, value):
2096        if obj.typeOfValues == 0:
2097            obj.section5[7+2] = utils.ieee_float_to_int(value)
2098        elif self.typeOfValues == 1:
2099            obj.section5[7+2] = int(value)
2100        obj.section5[6+2] = 1

Primary Missing Value

class SecMissingValue:
2102class SecMissingValue:
2103    """Secondary Missing Value"""
2104    def __get__(self, obj, objtype=None):
2105        if obj.typeOfValues == 0:
2106            return utils.ieee_int_to_float(obj.section5[8+2]) if obj.section5[6+2] in {1,2} and obj.section5[8+2] != 255 else None
2107        elif obj.typeOfValues == 1:
2108            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2109    def __set__(self, obj, value):
2110        if obj.typeOfValues == 0:
2111            obj.section5[8+2] = utils.ieee_float_to_int(value)
2112        elif self.typeOfValues == 1:
2113            obj.section5[8+2] = int(value)
2114        obj.section5[6+2] = 2

Secondary Missing Value

class NGroups:
2116class NGroups:
2117    """Number of Groups"""
2118    def __get__(self, obj, objtype=None):
2119        return obj.section5[9+2]
2120    def __set__(self, obj, value):
2121        pass

Number of Groups

class RefGroupWidth:
2123class RefGroupWidth:
2124    """Reference Group Width"""
2125    def __get__(self, obj, objtype=None):
2126        return obj.section5[10+2]
2127    def __set__(self, obj, value):
2128        pass

Reference Group Width

class NBitsGroupWidth:
2130class NBitsGroupWidth:
2131    """Number of bits for Group Width"""
2132    def __get__(self, obj, objtype=None):
2133        return obj.section5[11+2]
2134    def __set__(self, obj, value):
2135        pass

Number of bits for Group Width

class RefGroupLength:
2137class RefGroupLength:
2138    """Reference Group Length"""
2139    def __get__(self, obj, objtype=None):
2140        return obj.section5[12+2]
2141    def __set__(self, obj, value):
2142        pass

Reference Group Length

class GroupLengthIncrement:
2144class GroupLengthIncrement:
2145    """Group Length Increment"""
2146    def __get__(self, obj, objtype=None):
2147        return obj.section5[13+2]
2148    def __set__(self, obj, value):
2149        pass

Group Length Increment

class LengthOfLastGroup:
2151class LengthOfLastGroup:
2152    """Length of Last Group"""
2153    def __get__(self, obj, objtype=None):
2154        return obj.section5[14+2]
2155    def __set__(self, obj, value):
2156        pass

Length of Last Group

class NBitsScaledGroupLength:
2158class NBitsScaledGroupLength:
2159    """Number of bits of Scaled Group Length"""
2160    def __get__(self, obj, objtype=None):
2161        return obj.section5[15+2]
2162    def __set__(self, obj, value):
2163        pass

Number of bits of Scaled Group Length

class SpatialDifferenceOrder:
2165class SpatialDifferenceOrder:
2166    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2167    def __get__(self, obj, objtype=None):
2168        return Grib2Metadata(obj.section5[16+2],table='5.6')
2169    def __set__(self, obj, value):
2170        obj.section5[16+2] = value
class NBytesSpatialDifference:
2172class NBytesSpatialDifference:
2173    """Number of bytes for Spatial Differencing"""
2174    def __get__(self, obj, objtype=None):
2175        return obj.section5[17+2]
2176    def __set__(self, obj, value):
2177        pass

Number of bytes for Spatial Differencing

class Precision:
2179class Precision:
2180    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2181    def __get__(self, obj, objtype=None):
2182        return Grib2Metadata(obj.section5[0+2],table='5.7')
2183    def __set__(self, obj, value):
2184        obj.section5[0+2] = value
class TypeOfCompression:
2186class TypeOfCompression:
2187    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2188    def __get__(self, obj, objtype=None):
2189        return Grib2Metadata(obj.section5[5+2],table='5.40')
2190    def __set__(self, obj, value):
2191        obj.section5[5+2] = value
class TargetCompressionRatio:
2193class TargetCompressionRatio:
2194    """Target Compression Ratio"""
2195    def __get__(self, obj, objtype=None):
2196        return obj.section5[6+2]
2197    def __set__(self, obj, value):
2198        pass

Target Compression Ratio

class RealOfCoefficient:
2200class RealOfCoefficient:
2201    """Real of Coefficient"""
2202    def __get__(self, obj, objtype=None):
2203        return utils.ieee_int_to_float(obj.section5[4+2])
2204    def __set__(self, obj, value):
2205        obj.section5[4+2] = utils.ieee_float_to_int(float(value))

Real of Coefficient

class CompressionOptionsMask:
2207class CompressionOptionsMask:
2208    """Compression Options Mask for AEC/CCSDS"""
2209    def __get__(self, obj, objtype=None):
2210        return obj.section5[5+2]
2211    def __set__(self, obj, value):
2212        obj.section5[5+2] = value

Compression Options Mask for AEC/CCSDS

class BlockSize:
2214class BlockSize:
2215    """Block Size for AEC/CCSDS"""
2216    def __get__(self, obj, objtype=None):
2217        return obj.section5[6+2]
2218    def __set__(self, obj, value):
2219        obj.section5[6+2] = value

Block Size for AEC/CCSDS

class RefSampleInterval:
2221class RefSampleInterval:
2222    """Reference Sample Interval for AEC/CCSDS"""
2223    def __get__(self, obj, objtype=None):
2224        return obj.section5[7+2]
2225    def __set__(self, obj, value):
2226        obj.section5[7+2] = value

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate0:
2228@dataclass(init=False)
2229class DataRepresentationTemplate0:
2230    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
2231    _len = 5
2232    _num = 0
2233    _packingScheme = 'simple'
2234    refValue: float = field(init=False, repr=False, default=RefValue())
2235    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2236    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2237    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2238    @classmethod
2239    @property
2240    def _attrs(cls):
2241        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

@dataclass(init=False)
class DataRepresentationTemplate2:
2243@dataclass(init=False)
2244class DataRepresentationTemplate2:
2245    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
2246    _len = 16
2247    _num = 2
2248    _packingScheme = 'complex'
2249    refValue: float = field(init=False, repr=False, default=RefValue())
2250    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2251    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2252    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2253    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2254    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2255    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2256    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2257    nGroups: int = field(init=False, repr=False, default=NGroups())
2258    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2259    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2260    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2261    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2262    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2263    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2264    @classmethod
2265    @property
2266    def _attrs(cls):
2267        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

groupSplittingMethod: Grib2Metadata
typeOfMissingValueManagement: Grib2Metadata
priMissingValue: Union[float, int]

Primary Missing Value

secMissingValue: Union[float, int]

Secondary Missing Value

nGroups: int

Number of Groups

refGroupWidth: int

Reference Group Width

nBitsGroupWidth: int

Number of bits for Group Width

refGroupLength: int

Reference Group Length

groupLengthIncrement: int

Group Length Increment

lengthOfLastGroup: int

Length of Last Group

nBitsScaledGroupLength: int

Number of bits of Scaled Group Length

@dataclass(init=False)
class DataRepresentationTemplate3:
2269@dataclass(init=False)
2270class DataRepresentationTemplate3:
2271    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
2272    _len = 18
2273    _num = 3
2274    _packingScheme = 'complex-spdiff'
2275    refValue: float = field(init=False, repr=False, default=RefValue())
2276    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2277    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2278    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2279    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2280    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2281    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2282    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2283    nGroups: int = field(init=False, repr=False, default=NGroups())
2284    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2285    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2286    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2287    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2288    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2289    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2290    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
2291    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
2292    @classmethod
2293    @property
2294    def _attrs(cls):
2295        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

groupSplittingMethod: Grib2Metadata
typeOfMissingValueManagement: Grib2Metadata
priMissingValue: Union[float, int]

Primary Missing Value

secMissingValue: Union[float, int]

Secondary Missing Value

nGroups: int

Number of Groups

refGroupWidth: int

Reference Group Width

nBitsGroupWidth: int

Number of bits for Group Width

refGroupLength: int

Reference Group Length

groupLengthIncrement: int

Group Length Increment

lengthOfLastGroup: int

Length of Last Group

nBitsScaledGroupLength: int

Number of bits of Scaled Group Length

spatialDifferenceOrder: Grib2Metadata
nBytesSpatialDifference: int

Number of bytes for Spatial Differencing

@dataclass(init=False)
class DataRepresentationTemplate4:
2297@dataclass(init=False)
2298class DataRepresentationTemplate4:
2299    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
2300    _len = 1
2301    _num = 4
2302    _packingScheme = 'ieee-float'
2303    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
2304    @classmethod
2305    @property
2306    def _attrs(cls):
2307        return list(cls.__dataclass_fields__.keys())
@dataclass(init=False)
class DataRepresentationTemplate40:
2309@dataclass(init=False)
2310class DataRepresentationTemplate40:
2311    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
2312    _len = 7
2313    _num = 40
2314    _packingScheme = 'jpeg'
2315    refValue: float = field(init=False, repr=False, default=RefValue())
2316    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2317    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2318    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2319    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
2320    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
2321    @classmethod
2322    @property
2323    def _attrs(cls):
2324        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

typeOfCompression: Grib2Metadata
targetCompressionRatio: int

Target Compression Ratio

@dataclass(init=False)
class DataRepresentationTemplate41:
2326@dataclass(init=False)
2327class DataRepresentationTemplate41:
2328    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
2329    _len = 5
2330    _num = 41
2331    _packingScheme = 'png'
2332    refValue: float = field(init=False, repr=False, default=RefValue())
2333    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2334    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2335    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2336    @classmethod
2337    @property
2338    def _attrs(cls):
2339        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

@dataclass(init=False)
class DataRepresentationTemplate42:
2341@dataclass(init=False)
2342class DataRepresentationTemplate42:
2343    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
2344    _len = 8
2345    _num = 42
2346    _packingScheme = 'aec'
2347    refValue: float = field(init=False, repr=False, default=RefValue())
2348    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2349    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2350    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2351    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
2352    blockSize: int = field(init=False, repr=False, default=BlockSize())
2353    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
2354    @classmethod
2355    @property
2356    def _attrs(cls):
2357        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

compressionOptionsMask: int

Compression Options Mask for AEC/CCSDS

blockSize: int

Block Size for AEC/CCSDS

refSampleInterval: int

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate50:
2359@dataclass(init=False)
2360class DataRepresentationTemplate50:
2361    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
2362    _len = 5
2363    _num = 0
2364    _packingScheme = 'spectral-simple'
2365    refValue: float = field(init=False, repr=False, default=RefValue())
2366    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2367    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2368    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2369    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
2370    @classmethod
2371    @property
2372    def _attrs(cls):
2373        return list(cls.__dataclass_fields__.keys())
refValue: float

Reference Value (represented as an IEEE 32-bit floating point value)

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

realOfCoefficient: float

Real of Coefficient

def drt_class_by_drtn(drtn: int):
2386def drt_class_by_drtn(drtn: int):
2387    """
2388    Provide a Data Representation Template class via the template number.
2389
2390    Parameters
2391    ----------
2392    drtn
2393        Data Representation template number.
2394
2395    Returns
2396    -------
2397    drt_class_by_drtn
2398        Data Representation template class object (not an instance).
2399    """
2400    return _drt_by_drtn[drtn]

Provide a Data Representation Template class via the template number.

Parameters
  • drtn: Data Representation template number.
Returns
  • drt_class_by_drtn: Data Representation template class object (not an instance).