grib2io.templates

   1from dataclasses import dataclass, field
   2import datetime
   3from collections import defaultdict
   4
   5from . import tables
   6from . import utils
   7
   8
   9_section_attrs = {0:['discipline'],
  10                  1:['originatingCenter', 'originatingSubCenter', 'masterTableInfo', 'localTableInfo',
  11                     'significanceOfReferenceTime', 'year', 'month', 'day', 'hour', 'minute', 'second',
  12                     'refDate', 'productionStatus', 'typeOfData'],
  13                  2:[],
  14                  3:['interpretationOfListOfNumbers','gridDefinitionTemplateNumber','shapeOfEarth', 
  15                     'earthRadius', 'earthMajorAxis', 'earthMinorAxis',
  16                     'resolutionAndComponentFlags', 'ny', 'nx', 'scanModeFlags'],
  17                  4:['productDefinitionTemplateNumber','fullName', 'units', 'shortName','leadTime',
  18                     'unitOfFirstFixedSurface','valueOfFirstFixedSurface',
  19                     'unitOfSecondFixedSurface','valueOfSecondFixedSurface',
  20                     'validDate','duration','level'],
  21                  5:['dataRepresentationTemplateNumber','numberOfPackedValues','typeOfValues'],
  22                  6:['bitMapFlag'],
  23                  7:[],
  24                  8:[],}
  25
  26
  27class Grib2Metadata():
  28    """
  29    Class to hold GRIB2 metadata both as numeric code value as stored in
  30    GRIB2 and its plain langauge definition.
  31
  32    **`value : int`**
  33
  34    GRIB2 metadata integer code value.
  35
  36    **`table : str, optional`**
  37
  38    GRIB2 table to lookup the `value`. Default is None.
  39    """
  40    __slots__ = ('value','table')
  41    def __init__(self, value, table=None):
  42        self.value = value
  43        self.table = table
  44    def __call__(self):
  45        return self.value
  46    def __hash__(self):
  47        return hash(self.value)   # AS- added hash() to self.value as pandas was raising error about some non integer returns from hash method
  48    def __repr__(self):
  49        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
  50    def __str__(self):
  51        return f'{self.value} - {self.definition}'
  52    def __eq__(self,other):
  53        return self.value == other or self.definition[0] == other
  54    def __gt__(self,other):
  55        return self.value > other
  56    def __ge__(self,other):
  57        return self.value >= other
  58    def __lt__(self,other):
  59        return self.value < other
  60    def __le__(self,other):
  61        return self.value <= other
  62    def __contains__(self,other):
  63        return other in self.definition
  64    def __hash__(self):
  65        return hash(self.value)
  66    @property
  67    def definition(self):
  68        return tables.get_value_from_table(self.value,self.table)
  69
  70# ----------------------------------------------------------------------------------------
  71# Descriptor Classes for Section 0 metadata.
  72# ----------------------------------------------------------------------------------------
  73class IndicatorSection:
  74    """
  75    GRIB2 Section 0, [Indicator Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
  76    """
  77    def __get__(self, obj, objtype=None):
  78        return obj.section0
  79    def __set__(self, obj, value):
  80        obj.section0 = value
  81
  82class Discipline:
  83    """
  84    Discipline [From Table 0.0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)
  85    """
  86    def __get__(self, obj, objtype=None):
  87        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
  88    def __set__(self, obj, value):
  89        obj.section0[2] = value
  90
  91
  92# ----------------------------------------------------------------------------------------
  93# Descriptor Classes for Section 1 metadata.
  94# ----------------------------------------------------------------------------------------
  95class IdentificationSection:
  96    """
  97    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
  98    """
  99    def __get__(self, obj, objtype=None):
 100        return obj.section1
 101    def __set__(self, obj, value):
 102        obj.section1 = value
 103
 104class OriginatingCenter:
 105    """Identification of originating/generating center
 106    [(See Table 0)](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)
 107    """
 108    def __get__(self, obj, objtype=None):
 109        return Grib2Metadata(obj.section1[0],table='originating_centers')
 110    def __set__(self, obj, value):
 111        obj.section1[0] = value
 112
 113class OriginatingSubCenter:
 114    """Identification of originating/generating subcenter
 115    [(See Table C)](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)
 116    """
 117    def __get__(self, obj, objtype=None):
 118        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
 119    def __set__(self, obj, value):
 120        obj.section1[1] = value
 121
 122class MasterTableInfo:
 123    """GRIB master tables version number (currently 2)
 124    [(See Table 1.0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)
 125    """
 126    def __get__(self, obj, objtype=None):
 127        return Grib2Metadata(obj.section1[2],table='1.0')
 128    def __set__(self, obj, value):
 129        obj.section1[2] = value
 130
 131class LocalTableInfo:
 132    """Version number of GRIB local tables used to augment Master Tables
 133    [(See Table 1.1)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
 134    def __get__(self, obj, objtype=None):
 135        return Grib2Metadata(obj.section1[3],table='1.1')
 136    def __set__(self, obj, value):
 137        obj.section1[3] = value
 138
 139class SignificanceOfReferenceTime:
 140    """Significance of reference time [(See Table 1.2)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
 141    def __get__(self, obj, objtype=None):
 142        return Grib2Metadata(obj.section1[4],table='1.2')
 143    def __set__(self, obj, value):
 144        obj.section1[4] = value
 145
 146class Year:
 147    """Year of reference time"""
 148    def __get__(self, obj, objtype=None):
 149        return obj.section1[5]
 150    def __set__(self, obj, value):
 151        obj.section1[5] = value
 152
 153class Month:
 154    """Month of reference time"""
 155    def __get__(self, obj, objtype=None):
 156        return obj.section1[6]
 157    def __set__(self, obj, value):
 158        obj.section1[6] = value
 159
 160class Day:
 161    """Day of reference time"""
 162    def __get__(self, obj, objtype=None):
 163        return obj.section1[7]
 164    def __set__(self, obj, value):
 165        obj.section1[7] = value
 166
 167class Hour:
 168    """Hour of reference time"""
 169    def __get__(self, obj, objtype=None):
 170        return obj.section1[8]
 171    def __set__(self, obj, value):
 172        obj.section1[8] = value
 173
 174class Minute:
 175    """Minute of reference time"""
 176    def __get__(self, obj, objtype=None):
 177        return obj.section1[9]
 178    def __set__(self, obj, value):
 179        obj.section1[9] = value
 180
 181class Second:
 182    """Second of reference time"""
 183    def __get__(self, obj, objtype=None):
 184        return obj.section1[10]
 185    def __set__(self, obj, value):
 186        obj.section1[10] = value
 187
 188class RefDate:
 189    """Reference date as a `datetime.datetime` object"""
 190    def __get__(self, obj, objtype=None):
 191        return datetime.datetime(*obj.section1[5:11])
 192    def __set__(self, obj, value):
 193        if isinstance(value,datetime.datetime):
 194            obj.section1[5] = value.year
 195            obj.section1[6] = value.month
 196            obj.section1[7] = value.day
 197            obj.section1[8] = value.hour
 198            obj.section1[9] = value.minute
 199            obj.section1[10] = value.second
 200        else:
 201            msg = 'Reference date must be a datetime.datetime object.'
 202            raise TypeError(msg)
 203
 204class ProductionStatus:
 205    """Production Status of Processed data in the GRIB message
 206    [(See Table 1.3)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)
 207    """
 208    def __get__(self, obj, objtype=None):
 209        return Grib2Metadata(obj.section1[11],table='1.3')
 210    def __set__(self, obj, value):
 211        obj.section1[11] = value
 212
 213class TypeOfData:
 214    """Type of processed data in this GRIB message
 215    [(See Table 1.4)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)
 216    """
 217    def __get__(self, obj, objtype=None):
 218        return Grib2Metadata(obj.section1[12],table='1.4')
 219    def __set__(self, obj, value):
 220        obj.section1[12] = value
 221
 222# ----------------------------------------------------------------------------------------
 223# Descriptor Classes for Section 2 metadata.
 224# ----------------------------------------------------------------------------------------
 225
 226# ----------------------------------------------------------------------------------------
 227# Descriptor Classes for Section 3 metadata.
 228# ----------------------------------------------------------------------------------------
 229class GridDefinitionSection:
 230    """
 231    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
 232    """
 233    def __get__(self, obj, objtype=None):
 234        return obj.section3[0:5]
 235    def __set__(self, obj, value):
 236        raise RuntimeError
 237
 238class SourceOfGridDefinition:
 239    """Source of grid definition
 240    [(See Table 3.0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml
 241    """
 242    def __get__(self, obj, objtype=None):
 243        return Grib2Metadata(obj.section3[0],table='3.0')
 244    def __set__(self, obj, value):
 245        raise RuntimeError
 246
 247class NumberOfDataPoints:
 248    """Number of Data Points"""
 249    def __get__(self, obj, objtype=None):
 250        return obj.section3[1]
 251    def __set__(self, obj, value):
 252        raise RuntimeError
 253
 254class InterpretationOfListOfNumbers:
 255    """Interpretation of List of Numbers"""
 256    def __get__(self, obj, objtype=None):
 257        return Grib2Metadata(obj.section3[3],table='3.11')
 258    def __set__(self, obj, value):
 259        raise RuntimeError
 260
 261class GridDefinitionTemplateNumber:
 262    """Grid definition template number
 263    [(See Table 3.1)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml
 264    """
 265    def __get__(self, obj, objtype=None):
 266        return Grib2Metadata(obj.section3[4],table='3.1')
 267    def __set__(self, obj, value):
 268        raise RuntimeError
 269
 270class GridDefinitionTemplate:
 271    """Grid definition template"""
 272    def __get__(self, obj, objtype=None):
 273        return obj.section3[5:]
 274    def __set__(self, obj, value):
 275        raise RuntimeError
 276
 277class EarthParams:
 278    def __get__(self, obj, objtype=None):
 279        if obj.gridDefinitionSection[4] in {50,51,52,1200}:
 280            return None
 281        return tables.earth_params[str(obj.section3[5])]
 282    def __set__(self, obj, value):
 283        raise RuntimeError
 284
 285class DxSign:
 286    def __get__(self, obj, objtype=None):
 287        if obj.section3[4] in {0,1,203,205,32768,32769} and \
 288        obj.section3[17] > obj.section3[20]:
 289            return -1.0
 290        return 1.0
 291    def __set__(self, obj, value):
 292        raise RuntimeError
 293
 294class DySign:
 295    def __get__(self, obj, objtype=None):
 296        if obj.section3[4] in {0,1,203,205,32768,32769} and \
 297        obj.section3[16] > obj.section3[19]:
 298            return -1.0
 299        return 1.0
 300    def __set__(self, obj, value):
 301        raise RuntimeError
 302
 303class LLScaleFactor:
 304    def __get__(self, obj, objtype=None):
 305        if obj.section3[4] in {0,1,203,205,32768,32769}:
 306            llscalefactor = float(obj.section3[14])
 307            if llscalefactor == 0:
 308                return 1
 309            return llscalefactor
 310        return 1
 311    def __set__(self, obj, value):
 312        raise RuntimeError
 313
 314class LLDivisor:
 315    def __get__(self, obj, objtype=None):
 316        if obj.section3[4] in {0,1,203,205,32768,32769}:
 317            lldivisor = float(obj.section3[15])
 318            if lldivisor <= 0:
 319                return 1.e6
 320            return lldivisor
 321        return 1.e6
 322    def __set__(self, obj, value):
 323        raise RuntimeError
 324
 325class XYDivisor:
 326    def __get__(self, obj, objtype=None):
 327        if obj.section3[4] in {0,1,203,205,32768,32769}:
 328            return obj._lldivisor
 329        return 1.e3
 330    def __set__(self, obj, value):
 331        raise RuntimeError
 332
 333class ShapeOfEarth:
 334    def __get__(self, obj, objtype=None):
 335        return Grib2Metadata(obj.section3[5],table='3.2')
 336    def __set__(self, obj, value):
 337        obj.section3[5] = value
 338
 339class EarthRadius:
 340    def __get__(self, obj, objtype=None):
 341        earthparams = obj._earthparams
 342        if earthparams['shape'] == 'spherical':
 343            if earthparams['radius'] is None:
 344                return obj.section3[7]/(10.**obj.section3[6])
 345            else:
 346                return earthparams['radius']
 347        if earthparams['shape'] == 'oblateSpheriod':
 348            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
 349                return obj.section3[7]/(10.**obj.section3[6])
 350            else:
 351                return earthparams['radius']
 352    def __set__(self, obj, value):
 353        raise RuntimeError
 354
 355class EarthMajorAxis:
 356    def __get__(self, obj, objtype=None):
 357        earthparams = obj._earthparams
 358        if earthparams['shape'] == 'spherical':
 359            return None
 360        if earthparams['shape'] == 'oblateSpheriod':
 361            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
 362                return obj.section3[9]/(10.**obj.section3[8])
 363            else:
 364                return earthparams['major_axis']
 365    def __set__(self, obj, value):
 366        raise RuntimeError
 367
 368class EarthMinorAxis:
 369    def __get__(self, obj, objtype=None):
 370        earthparams = obj._earthparams
 371        if earthparams['shape'] == 'spherical':
 372            return None
 373        if earthparams['shape'] == 'oblateSpheriod':
 374            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
 375                return obj.section3[11]/(10.**section3[10])
 376            else:
 377                return earthparams['minor_axis']
 378    def __set__(self, obj, value):
 379        raise RuntimeError
 380
 381class Nx:
 382    def __get__(self, obj, objtype=None):
 383        return obj.section3[12]
 384    def __set__(self, obj, value):
 385        obj.section3[12] = value
 386        obj.section3[1] = value * obj.section3[13]
 387
 388class Ny:
 389    def __get__(self, obj, objtype=None):
 390        return obj.section3[13]
 391    def __set__(self, obj, value):
 392        obj.section3[13] = value
 393        obj.section3[1] = value * obj.section3[12]
 394
 395class ScanModeFlags:
 396    _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}
 397    def __get__(self, obj, objtype=None):
 398        if obj.gdtn == 50:
 399            return [None, None, None, None]
 400        else:
 401            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
 402    def __set__(self, obj, value):
 403        obj.section3[self._key[obj.gdtn]+5] = value
 404
 405class ResolutionAndComponentFlags:
 406    _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}
 407    def __get__(self, obj, objtype=None):
 408        if obj.gdtn == 50:
 409            return [None for i in range(8)]
 410        else:
 411            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
 412    def __set__(self, obj, value):
 413        obj.section3[self._key[obj.gdtn]+5] = value
 414
 415class LatitudeFirstGridpoint:
 416    _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}
 417    def __get__(self, obj, objtype=None):
 418        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 419    def __set__(self, obj, value):
 420        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 421
 422class LongitudeFirstGridpoint:
 423    _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}
 424    def __get__(self, obj, objtype=None):
 425        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 426    def __set__(self, obj, value):
 427        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 428
 429class LatitudeLastGridpoint:
 430    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:14}
 431    def __get__(self, obj, objtype=None):
 432        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 433    def __set__(self, obj, value):
 434        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 435
 436class LongitudeLastGridpoint:
 437    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:15}
 438    def __get__(self, obj, objtype=None):
 439        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 440    def __set__(self, obj, value):
 441        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 442
 443class GridlengthXDirection:
 444    _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}
 445    def __get__(self, obj, objtype=None):
 446        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
 447    def __set__(self, obj, value):
 448        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 449
 450class GridlengthYDirection:
 451    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 40:17, 41:17, 203:17, 204:17, 205:17, 32768:17, 32769:17}
 452    def __get__(self, obj, objtype=None):
 453        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
 454    def __set__(self, obj, value):
 455        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 456
 457class LatitudeSouthernPole:
 458    _key = {1:19, 30:20, 31:20, 41:19}
 459    def __get__(self, obj, objtype=None):
 460        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 461    def __set__(self, obj, value):
 462        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 463
 464class LongitudeSouthernPole:
 465    _key = {1:20, 30:21, 31:21, 41:20}
 466    def __get__(self, obj, objtype=None):
 467        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 468    def __set__(self, obj, value):
 469        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 470
 471class AnglePoleRotation:
 472    _key = {1:21, 41:21}
 473    def __get__(self, obj, objtype=None):
 474        return obj.section3[self._key[obj.gdtn]+5]
 475    def __set__(self, obj, value):
 476        obj.section3[self._key[obj.gdtn]+5] = int(value)
 477
 478class LatitudeTrueScale:
 479    _key = {10:12, 20:12, 30:12, 31:12}
 480    def __get__(self, obj, objtype=None):
 481        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 482    def __set__(self, obj, value):
 483        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 484
 485class GridOrientation:
 486    _key = {10:16, 20:13, 30:13, 31:13}
 487    def __get__(self, obj, objtype=None):
 488        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 489    def __set__(self, obj, value):
 490        if obj.gdtn == 10 and (value < 0 or value > 90):
 491            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
 492        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 493
 494class ProjectionCenterFlag:
 495    _key = {20:16, 30:16, 31:16}
 496    def __get__(self, obj, objtype=None):
 497        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
 498    def __set__(self, obj, value):
 499        obj.section3[self._key[obj.gdtn]+5] = value
 500
 501class StandardLatitude1:
 502    _key = {30:18, 31:18}
 503    def __get__(self, obj, objtype=None):
 504        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 505    def __set__(self, obj, value):
 506        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 507
 508class StandardLatitude2:
 509    _key = {30:19, 31:19}
 510    def __get__(self, obj, objtype=None):
 511        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 512    def __set__(self, obj, value):
 513        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 514
 515class SpectralFunctionParameters:
 516    def __get__(self, obj, objtype=None):
 517        return obj.section3[0:3]
 518    def __set__(self, obj, value):
 519        obj.section3[0:3] = value[0:3]
 520
 521class ProjParameters:
 522    def __get__(self, obj, objtype=None):
 523        projparams = {}
 524        projparams['a'] = 1.0
 525        projparams['b'] = 1.0
 526        if obj.earthRadius is not None:
 527            projparams['a'] = obj.earthRadius
 528            projparams['b'] = obj.earthRadius
 529        else:
 530            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
 531            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
 532        if obj.gdtn == 0:
 533            projparams['proj'] = 'longlat'
 534        elif obj.gdtn == 1:
 535            projparams['o_proj'] = 'longlat'
 536            projparams['proj'] = 'ob_tran'
 537            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
 538            projparams['o_lon_p'] = obj.anglePoleRotation
 539            projparams['lon_0'] = obj.longitudeSouthernPole
 540        elif obj.gdtn == 10:
 541            projparams['proj'] = 'merc'
 542            projparams['lat_ts'] = obj.latitudeTrueScale
 543            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
 544        elif obj.gdtn == 20:
 545            if obj.projectionCenterFlag == 0:
 546                lat0 = 90.0
 547            elif obj.projectionCenterFlag == 1:
 548                lat0 = -90.0
 549            projparams['proj'] = 'stere'
 550            projparams['lat_ts'] = obj.latitudeTrueScale
 551            projparams['lat_0'] = lat0
 552            projparams['lon_0'] = obj.gridOrientation
 553        elif obj.gdtn == 30:
 554            projparams['proj'] = 'lcc'
 555            projparams['lat_1'] = obj.standardLatitude1
 556            projparams['lat_2'] = obj.standardLatitude2
 557            projparams['lat_0'] = obj.latitudeTrueScale
 558            projparams['lon_0'] = obj.gridOrientation
 559        elif obj.gdtn == 31:
 560            projparams['proj'] = 'aea'
 561            projparams['lat_1'] = obj.standardLatitude1
 562            projparams['lat_2'] = obj.standardLatitude2
 563            projparams['lat_0'] = obj.latitudeTrueScale
 564            projparams['lon_0'] = obj.gridOrientation
 565        elif obj.gdtn == 40:
 566            projparams['proj'] = 'eqc'
 567        return projparams
 568    def __set__(self, obj, value):
 569        raise RuntimeError
 570
 571@dataclass(init=False)
 572class GridDefinitionTemplate0():
 573    _len = 19
 574    _num = 0
 575    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 576    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 577    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 578    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 579    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 580    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 581    @classmethod
 582    @property
 583    def _attrs(cls):
 584        return list(cls.__dataclass_fields__.keys())
 585
 586@dataclass(init=False)
 587class GridDefinitionTemplate1():
 588    _len = 22
 589    _num = 1
 590    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 591    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 592    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 593    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 594    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 595    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 596    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 597    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 598    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 599    @classmethod
 600    @property
 601    def _attrs(cls):
 602        return list(cls.__dataclass_fields__.keys())
 603
 604@dataclass(init=False)
 605class GridDefinitionTemplate10():
 606    _len = 19
 607    _num = 10
 608    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 609    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 610    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 611    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 612    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 613    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 614    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 615    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 616    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 617    @classmethod
 618    @property
 619    def _attrs(cls):
 620        return list(cls.__dataclass_fields__.keys())
 621
 622@dataclass(init=False)
 623class GridDefinitionTemplate20():
 624    _len = 18
 625    _num = 20
 626    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 627    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 628    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 629    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 630    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 631    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 632    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 633    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 634    @classmethod
 635    @property
 636    def _attrs(cls):
 637        return list(cls.__dataclass_fields__.keys())
 638
 639@dataclass(init=False)
 640class GridDefinitionTemplate30():
 641    _len = 22
 642    _num = 30
 643    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 644    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 645    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 646    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 647    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 648    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 649    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 650    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 651    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 652    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 653    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 654    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 655    @classmethod
 656    @property
 657    def _attrs(cls):
 658        return list(cls.__dataclass_fields__.keys())
 659
 660@dataclass(init=False)
 661class GridDefinitionTemplate31():
 662    _len = 22
 663    _num = 31
 664    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 665    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 666    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 667    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 668    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 669    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 670    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 671    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 672    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 673    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 674    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 675    @classmethod
 676    @property
 677    def _attrs(cls):
 678        return list(cls.__dataclass_fields__.keys())
 679
 680@dataclass(init=False)
 681class GridDefinitionTemplate40():
 682    _len = 19
 683    _num = 40
 684    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 685    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 686    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 687    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 688    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 689    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 690    @classmethod
 691    @property
 692    def _attrs(cls):
 693        return list(cls.__dataclass_fields__.keys())
 694
 695@dataclass(init=False)
 696class GridDefinitionTemplate41():
 697    _len = 22
 698    _num = 41
 699    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 700    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 701    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 702    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 703    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 704    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 705    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 706    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 707    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 708    @classmethod
 709    @property
 710    def _attrs(cls):
 711        return list(cls.__dataclass_fields__.keys())
 712
 713@dataclass(init=False)
 714class GridDefinitionTemplate50():
 715    _len = 5
 716    _num = 50
 717    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
 718    @classmethod
 719    @property
 720    def _attrs(cls):
 721        return list(cls.__dataclass_fields__.keys())
 722
 723_gdt_by_gdtn = {0: GridDefinitionTemplate0,
 724    1: GridDefinitionTemplate1,
 725    10: GridDefinitionTemplate10,
 726    20: GridDefinitionTemplate20,
 727    30: GridDefinitionTemplate30,
 728    31: GridDefinitionTemplate31,
 729    40: GridDefinitionTemplate40,
 730    41: GridDefinitionTemplate41,
 731    50: GridDefinitionTemplate50,
 732    }
 733
 734def gdt_class_by_gdtn(gdtn):
 735    return _gdt_by_gdtn[gdtn]
 736
 737# ----------------------------------------------------------------------------------------
 738# Descriptor Classes for Section 4 metadata.
 739# ----------------------------------------------------------------------------------------
 740class ProductDefinitionTemplateNumber:
 741    def __get__(self, obj, objtype=None):
 742        return Grib2Metadata(obj.section4[1],table='4.0')
 743    def __set__(self, obj, value):
 744        raise RuntimeError
 745
 746#  since PDT begins at position 2 of section4, code written with +2 for added readability with grib2 documentation
 747class ProductDefinitionTemplate:
 748    def __get__(self, obj, objtype=None):
 749        return obj.section4[2:]
 750    def __set__(self, obj, value):
 751        raise RuntimeError
 752
 753class ParameterCategory:
 754    _key = defaultdict(lambda: 0)
 755    def __get__(self, obj, objtype=None):
 756        return obj.section4[0+2]
 757    def __set__(self, obj, value):
 758        obj.section4[self._key[obj.pdtn]+2] = value
 759
 760class ParameterNumber:
 761    _key = defaultdict(lambda: 1)
 762    def __get__(self, obj, objtype=None):
 763        return obj.section4[1+2]
 764    def __set__(self, obj, value):
 765        obj.section4[self._key[obj.pdtn]+2] = value
 766
 767class VarInfo:
 768    def __get__(self, obj, objtype=None):
 769        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
 770    def __set__(self, obj, value):
 771        raise RuntimeError
 772
 773class FullName:
 774    def __get__(self, obj, objtype=None):
 775        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
 776    def __set__(self, obj, value):
 777        raise RuntimeError
 778
 779class Units:
 780    def __get__(self, obj, objtype=None):
 781        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
 782    def __set__(self, obj, value):
 783        raise RuntimeError
 784
 785class ShortName:
 786    def __get__(self, obj, objtype=None):
 787        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[2]
 788    def __set__(self, obj, value):
 789        raise RuntimeError
 790
 791class TypeOfGeneratingProcess:
 792    _key = defaultdict(lambda: 2, {48:13})
 793    #_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}
 794    def __get__(self, obj, objtype=None):
 795        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
 796    def __set__(self, obj, value):
 797        obj.section4[self._key[obj.pdtn]+2] = value
 798
 799class BackgroundGeneratingProcessIdentifier:
 800    _key = defaultdict(lambda: 3, {48:14})
 801    #_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}
 802    def __get__(self, obj, objtype=None):
 803        return obj.section4[self._key[obj.pdtn]+2]
 804    def __set__(self, obj, value):
 805        obj.section4[self._key[obj.pdtn]+2] = value
 806
 807class GeneratingProcess:
 808    _key = defaultdict(lambda: 4, {48:15})
 809    #_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}
 810    def __get__(self, obj, objtype=None):
 811        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
 812    def __set__(self, obj, value):
 813        obj.section4[self._key[obj.pdtn]+2] = value
 814
 815class HoursAfterDataCutoff:
 816    _key = defaultdict(lambda: 5, {48:16})
 817    def __get__(self, obj, objtype=None):
 818        return obj.section4[self._key[obj.pdtn]+2]
 819    def __set__(self, obj, value):
 820        obj.section4[self._key[obj.pdtn]+2] = value
 821
 822class MinutesAfterDataCutoff:
 823    _key = defaultdict(lambda: 6, {48:17})
 824    def __get__(self, obj, objtype=None):
 825        return obj.section4[self._key[obj.pdtn]+2]
 826    def __set__(self, obj, value):
 827        obj.section4[self._key[obj.pdtn]+2] = value
 828
 829class UnitOfTimeRange:
 830    _key = defaultdict(lambda: 7, {48:18})
 831    #_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}
 832    def __get__(self, obj, objtype=None):
 833        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
 834    def __set__(self, obj, value):
 835        obj.section4[self._key[obj.pdtn]+2] = value
 836
 837class ForecastTime:
 838    _key = defaultdict(lambda: 8, {48:19})
 839    def __get__(self, obj, objtype=None):
 840        return obj.section4[self._key[obj.pdtn]+2]
 841    def __set__(self, obj, value):
 842        obj.section4[self._key[obj.pdtn]+2] = value
 843
 844class LeadTime:
 845    def __get__(self, obj, objtype=None):
 846        return utils.get_leadtime(obj.section1,obj.section4[1],
 847                                  obj.section4[2:])
 848    def __set__(self, obj, value):
 849        raise NotImplementedError
 850
 851class FixedSfc1Info:
 852    _key = defaultdict(lambda: 9, {48:20})
 853    #_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}
 854    def __get__(self, obj, objtype=None):
 855        if obj.section4[self._key[obj.pdtn]+2] == 255:
 856            return [None, None]
 857        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
 858    def __set__(self, obj, value):
 859        raise NotImplementedError
 860
 861class FixedSfc2Info:
 862    _key = defaultdict(lambda: 12, {48:23})
 863    #_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}
 864    def __get__(self, obj, objtype=None):
 865        if obj.section4[self._key[obj.pdtn]+2] == 255:
 866            return [None, None]
 867        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
 868    def __set__(self, obj, value):
 869        raise NotImplementedError
 870
 871class TypeOfFirstFixedSurface:
 872    _key = defaultdict(lambda: 9, {48:20})
 873    #_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}
 874    def __get__(self, obj, objtype=None):
 875        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
 876    def __set__(self, obj, value):
 877        obj.section4[self._key[obj.pdtn]+2] = value
 878
 879class ScaleFactorOfFirstFixedSurface:
 880    _key = defaultdict(lambda: 10, {48:21})
 881    #_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}
 882    def __get__(self, obj, objtype=None):
 883        return obj.section4[self._key[obj.pdtn]+2]
 884    def __set__(self, obj, value):
 885        obj.section4[self._key[obj.pdtn]+2] = value
 886
 887class ScaledValueOfFirstFixedSurface:
 888    _key = defaultdict(lambda: 11, {48:22})
 889    #_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}
 890    def __get__(self, obj, objtype=None):
 891        return obj.section4[self._key[obj.pdtn]+2]
 892    def __set__(self, obj, value):
 893        obj.section4[self._key[obj.pdtn]+2] = value
 894
 895class UnitOfFirstFixedSurface:
 896    def __get__(self, obj, objtype=None):
 897        return obj._fixedsfc1info[1]
 898    def __set__(self, obj, value):
 899        pass
 900
 901class ValueOfFirstFixedSurface:
 902    def __get__(self, obj, objtype=None):
 903        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn]+2]/\
 904                            (10.**obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn]+2])
 905    def __set__(self, obj, value):
 906        pass
 907
 908class TypeOfSecondFixedSurface:
 909    _key = defaultdict(lambda: 12, {48:23})
 910    #_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}
 911    def __get__(self, obj, objtype=None):
 912        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
 913    def __set__(self, obj, value):
 914        obj.section4[self._key[obj.pdtn]+2] = value
 915
 916class ScaleFactorOfSecondFixedSurface:
 917    _key = defaultdict(lambda: 13, {48:24})
 918    #_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}
 919    def __get__(self, obj, objtype=None):
 920        return obj.section4[self._key[obj.pdtn]+2]
 921    def __set__(self, obj, value):
 922        obj.section4[self._key[obj.pdtn]+2] = value
 923
 924class ScaledValueOfSecondFixedSurface:
 925    _key = defaultdict(lambda: 14, {48:25})
 926    #_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}
 927    def __get__(self, obj, objtype=None):
 928        return obj.section4[self._key[obj.pdtn]+2]
 929    def __set__(self, obj, value):
 930        obj.section4[self._key[obj.pdtn]+2] = value
 931
 932class UnitOfSecondFixedSurface:
 933    def __get__(self, obj, objtype=None):
 934        return obj._fixedsfc2info[1]
 935    def __set__(self, obj, value):
 936        pass
 937
 938class ValueOfSecondFixedSurface:
 939    def __get__(self, obj, objtype=None):
 940        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn]+2]/\
 941                            (10.**obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn]+2])
 942    def __set__(self, obj, value):
 943        pass
 944
 945class Level:
 946    def __get__(self, obj, objtype=None):
 947        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
 948    def __set__(self, obj, value):
 949        pass
 950
 951class TypeOfEnsembleForecast:
 952    _key = {1:15, 11:15}
 953    def __get__(self, obj, objtype=None):
 954        pdtn = obj.section4[1]
 955        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
 956    def __set__(self, obj, value):
 957        pdtn = obj.section4[1]
 958        obj.section4[self._key[pdtn]+2] = value
 959
 960class PerturbationNumber:
 961    _key = {1:16, 11:16}
 962    def __get__(self, obj, objtype=None):
 963        pdtn = obj.section4[1]
 964        return obj.section4[self._key[pdtn]+2]
 965    def __set__(self, obj, value):
 966        pdtn = obj.section4[1]
 967        obj.section4[self._key[pdtn]+2] = value
 968
 969class NumberOfEnsembleForecasts:
 970    _key = {1:17, 2:16, 11:17, 12:16}
 971    def __get__(self, obj, objtype=None):
 972        pdtn = obj.section4[1]
 973        return obj.section4[self._key[pdtn]+2]
 974    def __set__(self, obj, value):
 975        pdtn = obj.section4[1]
 976        obj.section4[self._key[pdtn]+2] = value
 977
 978class TypeOfDerivedForecast:
 979    _key = {2:15, 12:15}
 980    def __get__(self, obj, objtype=None):
 981        pdtn = obj.section4[1]
 982        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
 983    def __set__(self, obj, value):
 984        pdtn = obj.section4[1]
 985        obj.section4[self._key[pdtn]+2] = value
 986
 987class ForecastProbabilityNumber:
 988    _key = {5:15, 9:15}
 989    def __get__(self, obj, objtype=None):
 990        pdtn = obj.section4[1]
 991        return obj.section4[self._key[pdtn]+2]
 992    def __set__(self, obj, value):
 993        pdtn = obj.section4[1]
 994        obj.section4[self._key[pdtn]+2] = value
 995
 996class TotalNumberOfForecastProbabilities:
 997    _key = {5:16, 9:16}
 998    def __get__(self, obj, objtype=None):
 999        pdtn = obj.section4[1]
1000        return obj.section4[self._key[pdtn]+2]
1001    def __set__(self, obj, value):
1002        pdtn = obj.section4[1]
1003        obj.section4[self._key[pdtn]+2] = value
1004
1005class TypeOfProbability:
1006    _key = {5:17, 9:17}
1007    def __get__(self, obj, objtype=None):
1008        pdtn = obj.section4[1]
1009        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1010    def __set__(self, obj, value):
1011        pdtn = obj.section4[1]
1012        obj.section4[self._key[pdtn]+2] = value
1013
1014class ScaleFactorOfThresholdLowerLimit:
1015    _key = {5:18, 9:18}
1016    def __get__(self, obj, objtype=None):
1017        pdtn = obj.section4[1]
1018        return obj.section4[self._key[pdtn]+2]
1019    def __set__(self, obj, value):
1020        pdtn = obj.section4[1]
1021        obj.section4[self._key[pdtn]+2] = value
1022
1023class ScaledValueOfThresholdLowerLimit:
1024    _key = {5:19, 9:19}
1025    def __get__(self, obj, objtype=None):
1026        pdtn = obj.section4[1]
1027        return obj.section4[self._key[pdtn]+2]
1028    def __set__(self, obj, value):
1029        pdtn = obj.section4[1]
1030        obj.section4[self._key[pdtn]+2] = value
1031
1032class ThresholdLowerLimit:
1033    def __get__(self, obj, objtype=None):
1034        if obj.section4[18+2] == -127 and \
1035           obj.section4[19+2] == 255:
1036            return 0.0
1037        else:
1038            return obj.section4[19+2]/(10.**obj.section4[18+2])
1039    def __set__(self, obj, value):
1040        pass
1041
1042class ThresholdUpperLimit:
1043    def __get__(self, obj, objtype=None):
1044        if obj.section4[20+2] == -127 and \
1045           obj.section4[21+2] == 255:
1046            return 0.0
1047        else:
1048            return obj.section4[21+2]/(10.**obj.section4[20+2])
1049    def __set__(self, obj, value):
1050        pass
1051
1052class Threshold:
1053    def __get__(self, obj, objtype=None):
1054        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1055    def __set__(self, obj, value):
1056        pass
1057
1058class PercentileValue:
1059    _key = {6:15, 10:15}
1060    def __get__(self, obj, objtype=None):
1061        pdtn = obj.section4[1]
1062        return obj.section4[self._key[pdtn]+2]
1063    def __set__(self, obj, value):
1064        pdtn = obj.section4[1]
1065        obj.section4[self._key[pdtn]+2] = value
1066
1067class YearOfEndOfTimePeriod:
1068    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1069    def __get__(self, obj, objtype=None):
1070        pdtn = obj.section4[1]
1071        return obj.section4[self._key[pdtn]+2]
1072    def __set__(self, obj, value):
1073        pdtn = obj.section4[1]
1074        obj.section4[self._key[pdtn]+2] = value
1075
1076class MonthOfEndOfTimePeriod:
1077    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1078    def __get__(self, obj, objtype=None):
1079        pdtn = obj.section4[1]
1080        return obj.section4[self._key[pdtn]+2]
1081    def __set__(self, obj, value):
1082        pdtn = obj.section4[1]
1083        obj.section4[self._key[pdtn]+2] = value
1084
1085class DayOfEndOfTimePeriod:
1086    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1087    def __get__(self, obj, objtype=None):
1088        pdtn = obj.section4[1]
1089        return obj.section4[self._key[pdtn]+2]
1090    def __set__(self, obj, value):
1091        pdtn = obj.section4[1]
1092        obj.section4[self._key[pdtn]+2] = value
1093
1094class HourOfEndOfTimePeriod:
1095    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1096    def __get__(self, obj, objtype=None):
1097        pdtn = obj.section4[1]
1098        return obj.section4[self._key[pdtn]+2]
1099    def __set__(self, obj, value):
1100        pdtn = obj.section4[1]
1101        obj.section4[self._key[pdtn]+2] = value
1102
1103class MinuteOfEndOfTimePeriod:
1104    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1105    def __get__(self, obj, objtype=None):
1106        pdtn = obj.section4[1]
1107        return obj.section4[self._key[pdtn]+2]
1108    def __set__(self, obj, value):
1109        pdtn = obj.section4[1]
1110        obj.section4[self._key[pdtn]+2] = value
1111
1112class SecondOfEndOfTimePeriod:
1113    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1114    def __get__(self, obj, objtype=None):
1115        pdtn = obj.section4[1]
1116        return obj.section4[self._key[pdtn]+2]
1117    def __set__(self, obj, value):
1118        pdtn = obj.section4[1]
1119        obj.section4[self._key[pdtn]+2] = value
1120
1121class Duration:
1122    def __get__(self, obj, objtype=None):
1123        return utils.get_duration(obj.section4[1],obj.section4[2:])
1124    def __set__(self, obj, value):
1125        pass
1126
1127class ValidDate:
1128    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1129    def __get__(self, obj, objtype=None):
1130        pdtn = obj.section4[1]
1131        try:
1132            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1133            return datetime.datetime(*obj.section4[s])
1134        except(KeyError):
1135            return obj.refDate + obj.leadTime
1136    def __set__(self, obj, value):
1137        pass
1138
1139class NumberOfTimeRanges:
1140    _key = {8:21, 9:28, 10:22, 11:24, 12:23}
1141    def __get__(self, obj, objtype=None):
1142        pdtn = obj.section4[1]
1143        return obj.section4[self._key[pdtn]+2]
1144    def __set__(self, obj, value):
1145        pdtn = obj.section4[1]
1146        obj.section4[self._key[pdtn]+2] = value
1147
1148class NumberOfMissingValues:
1149    _key = {8:22, 9:29, 10:23, 11:25, 12:24}
1150    def __get__(self, obj, objtype=None):
1151        pdtn = obj.section4[1]
1152        return obj.section4[self._key[pdtn]+2]
1153    def __set__(self, obj, value):
1154        pdtn = obj.section4[1]
1155        obj.section4[self._key[pdtn]+2] = value
1156
1157class StatisticalProcess:
1158    _key = {8:23, 9:30, 10:24, 11:26, 12:25, 15:15}
1159    def __get__(self, obj, objtype=None):
1160        pdtn = obj.section4[1]
1161        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.10')
1162    def __set__(self, obj, value):
1163        pdtn = obj.section4[1]
1164        obj.section4[self._key[pdtn]+2] = value
1165
1166class TypeOfTimeIncrementOfStatisticalProcess:
1167    _key = {8:24, 9:31, 10:25, 11:27, 12:26}
1168    def __get__(self, obj, objtype=None):
1169        pdtn = obj.section4[1]
1170        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.11')
1171    def __set__(self, obj, value):
1172        pdtn = obj.section4[1]
1173        obj.section4[self._key[pdtn]+2] = value
1174
1175class UnitOfTimeRangeOfStatisticalProcess:
1176    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
1177    def __get__(self, obj, objtype=None):
1178        pdtn = obj.section4[1]
1179        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1180    def __set__(self, obj, value):
1181        pdtn = obj.section4[1]
1182        obj.section4[self._key[pdtn]+2] = value
1183
1184class TimeRangeOfStatisticalProcess:
1185    _key = {8:26, 9:33, 10:27, 11:29, 12:28}
1186    def __get__(self, obj, objtype=None):
1187        pdtn = obj.section4[1]
1188        return obj.section4[self._key[pdtn]+2]
1189    def __set__(self, obj, value):
1190        pdtn = obj.section4[1]
1191        obj.section4[self._key[pdtn]+2] = value
1192
1193class UnitOfTimeRangeOfSuccessiveFields:
1194    _key = {8:27, 9:34, 10:28, 11:30, 12:29}
1195    def __get__(self, obj, objtype=None):
1196        pdtn = obj.section4[1]
1197        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1198    def __set__(self, obj, value):
1199        pdtn = obj.section4[1]
1200        obj.section4[self._key[pdtn]+2] = value
1201
1202class TimeIncrementOfSuccessiveFields:
1203    _key = {8:28, 9:35, 10:29, 11:31, 12:30}
1204    def __get__(self, obj, objtype=None):
1205        pdtn = obj.section4[1]
1206        return obj.section4[self._key[pdtn]+2]
1207    def __set__(self, obj, value):
1208        pdtn = obj.section4[1]
1209        obj.section4[self._key[pdtn]+2] = value
1210
1211class TypeOfStatisticalProcessing:
1212    _key = {15:16}
1213    def __get__(self, obj, objtype=None):
1214        pdtn = obj.section4[1]
1215        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1216    def __set__(self, obj, value):
1217        pdtn = obj.section4[1]
1218        obj.section4[self._key[pdtn]+2] = value
1219
1220class NumberOfDataPointsForSpatialProcessing:
1221    _key = {15:17}
1222    def __get__(self, obj, objtype=None):
1223        pdtn = obj.section4[1]
1224        return obj.section4[self._key[pdtn]+2]
1225    def __set__(self, obj, value):
1226        pdtn = obj.section4[1]
1227        obj.section4[self._key[pdtn]+2] = value
1228
1229class TypeOfAerosol:
1230    _key = {48:2}
1231    def __get__(self, obj, objtype=None):
1232        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1233    def __set__(self, obj, value):
1234        obj.section4[self._key[obj.pdtn]+2] = value
1235
1236class TypeOfIntervalForAerosolSize:
1237    _key = {48:3}
1238    def __get__(self, obj, objtype=None):
1239        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1240    def __set__(self, obj, value):
1241        obj.section4[self._key[obj.pdtn]+2] = value
1242
1243class ScaleFactorOfFirstSize:
1244    _key = {48:4}
1245    def __get__(self, obj, objtype=None):
1246        return obj.section4[self._key[obj.pdtn]+2]
1247    def __set__(self, obj, value):
1248        obj.section4[self._key[obj.pdtn]+2] = value
1249
1250class ScaledValueOfFirstSize:
1251    _key = {48:5}
1252    def __get__(self, obj, objtype=None):
1253        return obj.section4[self._key[obj.pdtn]+2]
1254    def __set__(self, obj, value):
1255        obj.section4[self._key[obj.pdtn]+2] = value
1256
1257class ScaleFactorOfSecondSize:
1258    _key = {48:6}
1259    def __get__(self, obj, objtype=None):
1260        return obj.section4[self._key[obj.pdtn]+2]
1261    def __set__(self, obj, value):
1262        obj.section4[self._key[obj.pdtn]+2] = value
1263
1264class ScaledValueOfSecondSize:
1265    _key = {48:7}
1266    def __get__(self, obj, objtype=None):
1267        return obj.section4[self._key[obj.pdtn]+2]
1268    def __set__(self, obj, value):
1269        obj.section4[self._key[obj.pdtn]+2] = value
1270
1271class TypeOfIntervalForAerosolWavelength:
1272    _key = {48:8}
1273    def __get__(self, obj, objtype=None):
1274        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1275    def __set__(self, obj, value):
1276        obj.section4[self._key[obj.pdtn]+2] = value
1277
1278class ScaleFactorOfFirstWavelength:
1279    _key = {48:9}
1280    def __get__(self, obj, objtype=None):
1281        return obj.section4[self._key[obj.pdtn]+2]
1282    def __set__(self, obj, value):
1283        obj.section4[self._key[obj.pdtn]+2] = value
1284
1285class ScaledValueOfFirstWavelength:
1286    _key = {48:10}
1287    def __get__(self, obj, objtype=None):
1288        return obj.section4[self._key[obj.pdtn]+2]
1289    def __set__(self, obj, value):
1290        obj.section4[self._key[obj.pdtn]+2] = value
1291
1292class ScaleFactorOfSecondWavelength:
1293    _key = {48:11}
1294    def __get__(self, obj, objtype=None):
1295        return obj.section4[self._key[obj.pdtn]+2]
1296    def __set__(self, obj, value):
1297        obj.section4[self._key[obj.pdtn]+2] = value
1298
1299class ScaledValueOfSecondWavelength:
1300    _key = {48:12}
1301    def __get__(self, obj, objtype=None):
1302        return obj.section4[self._key[obj.pdtn]+2]
1303    def __set__(self, obj, value):
1304        obj.section4[self._key[obj.pdtn]+2] = value
1305
1306@dataclass(init=False)
1307class ProductDefinitionTemplate0():
1308    _len = 15
1309    _num = 0
1310    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1311    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1312    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1313    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1314    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1315    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1316    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1317    unitOfTimeRange: Grib2Metadata = field(init=False,repr=False,default=UnitOfTimeRange())
1318    forecastTime: int = field(init=False,repr=False,default=ForecastTime())
1319    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1320    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1321    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1322    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1323    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1324    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1325    @classmethod
1326    @property
1327    def _attrs(cls):
1328        return list(cls.__dataclass_fields__.keys())
1329
1330@dataclass(init=False)
1331class ProductDefinitionTemplate1(ProductDefinitionTemplate0):
1332    _len = 18
1333    _num = 1
1334    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1335    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1336    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1337    @classmethod
1338    @property
1339    def _attrs(cls):
1340        return list(cls.__dataclass_fields__.keys())
1341
1342@dataclass(init=False)
1343class ProductDefinitionTemplate2(ProductDefinitionTemplate0):
1344    _len = 17
1345    _num = 2
1346    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1347    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1348    @classmethod
1349    @property
1350    def _attrs(cls):
1351        return list(cls.__dataclass_fields__.keys())
1352
1353@dataclass(init=False)
1354class ProductDefinitionTemplate5(ProductDefinitionTemplate0):
1355    _len = 22
1356    _num = 5
1357    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1358    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1359    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1360    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1361    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1362    threshold: str = field(init=False, repr=False, default=Threshold())
1363    @classmethod
1364    @property
1365    def _attrs(cls):
1366        return list(cls.__dataclass_fields__.keys())
1367
1368@dataclass(init=False)
1369class ProductDefinitionTemplate6(ProductDefinitionTemplate0):
1370    _len = 16
1371    _num = 6
1372    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1373    @classmethod
1374    @property
1375    def _attrs(cls):
1376        return list(cls.__dataclass_fields__.keys())
1377
1378@dataclass(init=False)
1379class ProductDefinitionTemplate8(ProductDefinitionTemplate0):
1380    _len = 29
1381    _num = 8
1382    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1383    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1384    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1385    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1386    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1387    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1388    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1389    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1390    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1391    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1392    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1393    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1394    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1395    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1396    @classmethod
1397    @property
1398    def _attrs(cls):
1399        return list(cls.__dataclass_fields__.keys())
1400
1401@dataclass(init=False)
1402class ProductDefinitionTemplate9(ProductDefinitionTemplate0):
1403    _len = 36
1404    _num = 9
1405    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1406    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1407    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1408    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1409    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1410    threshold: str = field(init=False, repr=False, default=Threshold())
1411    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1412    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1413    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1414    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1415    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1416    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1417    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1418    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1419    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1420    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1421    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1422    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1423    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1424    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1425    @classmethod
1426    @property
1427    def _attrs(cls):
1428        return list(cls.__dataclass_fields__.keys())
1429
1430@dataclass(init=False)
1431class ProductDefinitionTemplate10(ProductDefinitionTemplate0):
1432    _len = 30
1433    _num = 10
1434    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1435    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1436    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1437    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1438    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1439    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1440    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1441    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1442    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1443    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1444    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1445    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1446    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1447    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1448    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1449    @classmethod
1450    @property
1451    def _attrs(cls):
1452        return list(cls.__dataclass_fields__.keys())
1453
1454@dataclass(init=False)
1455class ProductDefinitionTemplate11(ProductDefinitionTemplate0):
1456    _len = 32
1457    _num = 11
1458    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1459    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1460    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1461    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1462    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1463    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1464    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1465    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1466    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1467    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1468    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1469    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1470    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1471    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1472    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1473    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1474    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1475    @classmethod
1476    @property
1477    def _attrs(cls):
1478        return list(cls.__dataclass_fields__.keys())
1479
1480@dataclass(init=False)
1481class ProductDefinitionTemplate12(ProductDefinitionTemplate0):
1482    _len = 31
1483    _num = 12
1484    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1485    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1486    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1487    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1488    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1489    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1490    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1491    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1492    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1493    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1494    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1495    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1496    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1497    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1498    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1499    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1500    @classmethod
1501    @property
1502    def _attrs(cls):
1503        return list(cls.__dataclass_fields__.keys())
1504
1505@dataclass(init=False)
1506class ProductDefinitionTemplate15(ProductDefinitionTemplate0):
1507    _len = 18
1508    _num = 15
1509    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1510    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
1511    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
1512    @classmethod
1513    @property
1514    def _attrs(cls):
1515        return list(cls.__dataclass_fields__.keys())
1516
1517@dataclass(init=False)
1518class ProductDefinitionTemplate48(ProductDefinitionTemplate0):
1519    _len = 26
1520    _num = 48
1521    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
1522    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
1523    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
1524    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
1525    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
1526    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
1527    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
1528    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
1529    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
1530    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
1531    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
1532    @classmethod
1533    @property
1534    def _attrs(cls):
1535        return list(cls.__dataclass_fields__.keys())
1536
1537_pdt_by_pdtn = {
1538    0: ProductDefinitionTemplate0,
1539    1: ProductDefinitionTemplate1,
1540    2: ProductDefinitionTemplate2,
1541    5: ProductDefinitionTemplate5,
1542    6: ProductDefinitionTemplate6,
1543    8: ProductDefinitionTemplate8,
1544    9: ProductDefinitionTemplate9,
1545    10: ProductDefinitionTemplate10,
1546    11: ProductDefinitionTemplate11,
1547    12: ProductDefinitionTemplate12,
1548    15: ProductDefinitionTemplate15,
1549    48: ProductDefinitionTemplate48,
1550    }
1551
1552def pdt_class_by_pdtn(pdtn):
1553    return _pdt_by_pdtn[pdtn]
1554
1555# ----------------------------------------------------------------------------------------
1556# Descriptor Classes for Section 5 metadata.
1557# ----------------------------------------------------------------------------------------
1558class NumberOfPackedValues:
1559    def __get__(self, obj, objtype=None):
1560        return obj.section5[0]
1561    def __set__(self, obj, value):
1562        pass
1563
1564class DataRepresentationTemplateNumber:
1565    def __get__(self, obj, objtype=None):
1566        return Grib2Metadata(obj.section5[1],table='5.0')
1567    def __set__(self, obj, value):
1568        pass
1569
1570class DataRepresentationTemplate:
1571    def __get__(self, obj, objtype=None):
1572        return obj.section5[2:]
1573    def __set__(self, obj, value):
1574        raise NotImplementedError
1575
1576class RefValue:
1577    def __get__(self, obj, objtype=None):
1578        return utils.ieee_int_to_float(obj.section5[0+2])
1579    def __set__(self, obj, value):
1580        pass
1581
1582class BinScaleFactor:
1583    def __get__(self, obj, objtype=None):
1584        return obj.section5[1+2]
1585    def __set__(self, obj, value):
1586        obj.section5[1+2] = value
1587
1588class DecScaleFactor:
1589    def __get__(self, obj, objtype=None):
1590        return obj.section5[2+2]
1591    def __set__(self, obj, value):
1592        obj.section5[2+2] = value
1593
1594class NBitsPacking:
1595    def __get__(self, obj, objtype=None):
1596        return obj.section5[3+2]
1597    def __set__(self, obj, value):
1598        obj.section5[3+2] = value
1599
1600class TypeOfValues:
1601    def __get__(self, obj, objtype=None):
1602        return Grib2Metadata(obj.section5[4+2],table='5.1')
1603    def __set__(self, obj, value):
1604        obj.section5[4+2] = value
1605
1606class GroupSplittingMethod:
1607    def __get__(self, obj, objtype=None):
1608        return Grib2Metadata(obj.section5[5+2],table='5.4')
1609    def __set__(self, obj, value):
1610        obj.section5[5+2] = value
1611
1612class TypeOfMissingValueManagement:
1613    def __get__(self, obj, objtype=None):
1614        return Grib2Metadata(obj.section5[6+2],table='5.5')
1615    def __set__(self, obj, value):
1616        obj.section5[5+2] = value
1617
1618class PriMissingValue:
1619    def __get__(self, obj, objtype=None):
1620        if obj.typeOfValues == 0:
1621            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
1622        elif obj.typeOfValues == 1:
1623            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
1624    def __set__(self, obj, value):
1625        if obj.typeOfValues == 0:
1626            obj.section5[7+2] = utils.ieee_float_to_int(value)
1627        elif self.typeOfValues == 1:
1628            obj.section5[7+2] = int(value)
1629        obj.section5[6+2] = 1
1630
1631class SecMissingValue:
1632    def __get__(self, obj, objtype=None):
1633        if obj.typeOfValues == 0:
1634            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
1635        elif obj.typeOfValues == 1:
1636            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
1637    def __set__(self, obj, value):
1638        if obj.typeOfValues == 0:
1639            obj.section5[8+2] = utils.ieee_float_to_int(value)
1640        elif self.typeOfValues == 1:
1641            obj.section5[8+2] = int(value)
1642        obj.section5[6+2] = 2
1643
1644class NGroups:
1645    def __get__(self, obj, objtype=None):
1646        return obj.section5[9+2]
1647    def __set__(self, obj, value):
1648        pass
1649
1650class RefGroupWidth:
1651    def __get__(self, obj, objtype=None):
1652        return obj.section5[10+2]
1653    def __set__(self, obj, value):
1654        pass
1655
1656class NBitsGroupWidth:
1657    def __get__(self, obj, objtype=None):
1658        return obj.section5[11+2]
1659    def __set__(self, obj, value):
1660        pass
1661
1662class RefGroupLength:
1663    def __get__(self, obj, objtype=None):
1664        return obj.section5[12+2]
1665    def __set__(self, obj, value):
1666        pass
1667
1668class GroupLengthIncrement:
1669    def __get__(self, obj, objtype=None):
1670        return obj.section5[13+2]
1671    def __set__(self, obj, value):
1672        pass
1673
1674class LengthOfLastGroup:
1675    def __get__(self, obj, objtype=None):
1676        return obj.section5[14+2]
1677    def __set__(self, obj, value):
1678        pass
1679
1680class NBitsScaledGroupLength:
1681    def __get__(self, obj, objtype=None):
1682        return obj.section5[15+2]
1683    def __set__(self, obj, value):
1684        pass
1685
1686class SpatialDifferenceOrder:
1687    def __get__(self, obj, objtype=None):
1688        return Grib2Metadata(obj.section5[16+2],table='5.6')
1689    def __set__(self, obj, value):
1690        obj.section5[16+2] = value
1691
1692class NBytesSpatialDifference:
1693    def __get__(self, obj, objtype=None):
1694        return obj.section5[17+2]
1695    def __set__(self, obj, value):
1696        pass
1697
1698class Precision:
1699    def __get__(self, obj, objtype=None):
1700        return Grib2Metadata(obj.section5[0+2],table='5.7')
1701    def __set__(self, obj, value):
1702        obj.section5[0+2] = value
1703
1704class TypeOfCompression:
1705    def __get__(self, obj, objtype=None):
1706        return Grib2Metadata(obj.section5[5+2],table='5.40')
1707    def __set__(self, obj, value):
1708        obj.section5[5+2] = value
1709
1710class TargetCompressionRatio:
1711    def __get__(self, obj, objtype=None):
1712        return obj.section5[6+2]
1713    def __set__(self, obj, value):
1714        pass
1715
1716class RealOfCoefficient:
1717    def __get__(self, obj, objtype=None):
1718        return utils.ieee_int_to_float(obj.section5[4+2])
1719    def __set__(self, obj, value):
1720        obj.section5[4+2] = utils.ieee_float_to_int(float(value))
1721
1722@dataclass(init=False)
1723class DataRepresentationTemplate0():
1724    _len = 5
1725    _num = 0
1726    _packingScheme = 'simple'
1727    refValue: float = field(init=False, repr=False, default=RefValue())
1728    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1729    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1730    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1731    @classmethod
1732    @property
1733    def _attrs(cls):
1734        return list(cls.__dataclass_fields__.keys())
1735
1736@dataclass(init=False)
1737class DataRepresentationTemplate2():
1738    _len = 16
1739    _num = 2
1740    _packingScheme = 'complex'
1741    refValue: float = field(init=False, repr=False, default=RefValue())
1742    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1743    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1744    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1745    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
1746    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
1747    priMissingValue: [float, int] = field(init=False, repr=False, default=PriMissingValue())
1748    secMissingValue: [float, int] = field(init=False, repr=False, default=SecMissingValue())
1749    nGroups: int = field(init=False, repr=False, default=NGroups())
1750    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
1751    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
1752    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
1753    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
1754    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
1755    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
1756    @classmethod
1757    @property
1758    def _attrs(cls):
1759        return list(cls.__dataclass_fields__.keys())
1760
1761@dataclass(init=False)
1762class DataRepresentationTemplate3():
1763    _len = 18
1764    _num = 3
1765    _packingScheme = 'complex-spdiff'
1766    refValue: float = field(init=False, repr=False, default=RefValue())
1767    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1768    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1769    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1770    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
1771    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
1772    priMissingValue: [float, int] = field(init=False, repr=False, default=PriMissingValue())
1773    secMissingValue: [float, int] = field(init=False, repr=False, default=SecMissingValue())
1774    nGroups: int = field(init=False, repr=False, default=NGroups())
1775    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
1776    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
1777    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
1778    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
1779    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
1780    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
1781    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
1782    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
1783    @classmethod
1784    @property
1785    def _attrs(cls):
1786        return list(cls.__dataclass_fields__.keys())
1787
1788@dataclass(init=False)
1789class DataRepresentationTemplate4():
1790    _len = 1
1791    _num = 4
1792    _packingScheme = 'ieee-float'
1793    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
1794    @classmethod
1795    @property
1796    def _attrs(cls):
1797        return list(cls.__dataclass_fields__.keys())
1798
1799@dataclass(init=False)
1800class DataRepresentationTemplate40():
1801    _len = 7
1802    _num = 40
1803    _packingScheme = 'jpeg'
1804    refValue: float = field(init=False, repr=False, default=RefValue())
1805    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1806    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1807    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1808    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
1809    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
1810    @classmethod
1811    @property
1812    def _attrs(cls):
1813        return list(cls.__dataclass_fields__.keys())
1814
1815@dataclass(init=False)
1816class DataRepresentationTemplate41():
1817    _len = 5
1818    _num = 41
1819    _packingScheme = 'png'
1820    refValue: float = field(init=False, repr=False, default=RefValue())
1821    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1822    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1823    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1824    @classmethod
1825    @property
1826    def _attrs(cls):
1827        return list(cls.__dataclass_fields__.keys())
1828
1829@dataclass(init=False)
1830class DataRepresentationTemplate50():
1831    _len = 5
1832    _num = 0
1833    _packingScheme = 'spectral-simple'
1834    refValue: float = field(init=False, repr=False, default=RefValue())
1835    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1836    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1837    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1838    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
1839    @classmethod
1840    @property
1841    def _attrs(cls):
1842        return list(cls.__dataclass_fields__.keys())
1843
1844_drt_by_drtn = {
1845    0: DataRepresentationTemplate0,
1846    2: DataRepresentationTemplate2,
1847    3: DataRepresentationTemplate3,
1848    4: DataRepresentationTemplate4,
1849    40: DataRepresentationTemplate40,
1850    41: DataRepresentationTemplate41,
1851    50: DataRepresentationTemplate50,
1852    }
1853
1854def drt_class_by_drtn(drtn):
1855    return _drt_by_drtn[drtn]
class Grib2Metadata:
28class Grib2Metadata():
29    """
30    Class to hold GRIB2 metadata both as numeric code value as stored in
31    GRIB2 and its plain langauge definition.
32
33    **`value : int`**
34
35    GRIB2 metadata integer code value.
36
37    **`table : str, optional`**
38
39    GRIB2 table to lookup the `value`. Default is None.
40    """
41    __slots__ = ('value','table')
42    def __init__(self, value, table=None):
43        self.value = value
44        self.table = table
45    def __call__(self):
46        return self.value
47    def __hash__(self):
48        return hash(self.value)   # AS- added hash() to self.value as pandas was raising error about some non integer returns from hash method
49    def __repr__(self):
50        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
51    def __str__(self):
52        return f'{self.value} - {self.definition}'
53    def __eq__(self,other):
54        return self.value == other or self.definition[0] == other
55    def __gt__(self,other):
56        return self.value > other
57    def __ge__(self,other):
58        return self.value >= other
59    def __lt__(self,other):
60        return self.value < other
61    def __le__(self,other):
62        return self.value <= other
63    def __contains__(self,other):
64        return other in self.definition
65    def __hash__(self):
66        return hash(self.value)
67    @property
68    def definition(self):
69        return tables.get_value_from_table(self.value,self.table)

Class to hold GRIB2 metadata both as numeric code value as stored in GRIB2 and its plain langauge definition.

value : int

GRIB2 metadata integer code value.

table : str, optional

GRIB2 table to lookup the value. Default is None.

Grib2Metadata(value, table=None)
42    def __init__(self, value, table=None):
43        self.value = value
44        self.table = table
class IndicatorSection:
74class IndicatorSection:
75    """
76    GRIB2 Section 0, [Indicator Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
77    """
78    def __get__(self, obj, objtype=None):
79        return obj.section0
80    def __set__(self, obj, value):
81        obj.section0 = value

GRIB2 Section 0, Indicator Section

IndicatorSection()
class Discipline:
83class Discipline:
84    """
85    Discipline [From Table 0.0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)
86    """
87    def __get__(self, obj, objtype=None):
88        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
89    def __set__(self, obj, value):
90        obj.section0[2] = value

Discipline From Table 0.0

Discipline()
class IdentificationSection:
 96class IdentificationSection:
 97    """
 98    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
 99    """
100    def __get__(self, obj, objtype=None):
101        return obj.section1
102    def __set__(self, obj, value):
103        obj.section1 = value

GRIB2 Section 1, Identification Section

IdentificationSection()
class OriginatingCenter:
105class OriginatingCenter:
106    """Identification of originating/generating center
107    [(See Table 0)](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)
108    """
109    def __get__(self, obj, objtype=None):
110        return Grib2Metadata(obj.section1[0],table='originating_centers')
111    def __set__(self, obj, value):
112        obj.section1[0] = value

Identification of originating/generating center (See Table 0)

OriginatingCenter()
class OriginatingSubCenter:
114class OriginatingSubCenter:
115    """Identification of originating/generating subcenter
116    [(See Table C)](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)
117    """
118    def __get__(self, obj, objtype=None):
119        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
120    def __set__(self, obj, value):
121        obj.section1[1] = value

Identification of originating/generating subcenter (See Table C)

OriginatingSubCenter()
class MasterTableInfo:
123class MasterTableInfo:
124    """GRIB master tables version number (currently 2)
125    [(See Table 1.0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)
126    """
127    def __get__(self, obj, objtype=None):
128        return Grib2Metadata(obj.section1[2],table='1.0')
129    def __set__(self, obj, value):
130        obj.section1[2] = value

GRIB master tables version number (currently 2) (See Table 1.0)

MasterTableInfo()
class LocalTableInfo:
132class LocalTableInfo:
133    """Version number of GRIB local tables used to augment Master Tables
134    [(See Table 1.1)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
135    def __get__(self, obj, objtype=None):
136        return Grib2Metadata(obj.section1[3],table='1.1')
137    def __set__(self, obj, value):
138        obj.section1[3] = value

Version number of GRIB local tables used to augment Master Tables (See Table 1.1)

LocalTableInfo()
class SignificanceOfReferenceTime:
140class SignificanceOfReferenceTime:
141    """Significance of reference time [(See Table 1.2)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
142    def __get__(self, obj, objtype=None):
143        return Grib2Metadata(obj.section1[4],table='1.2')
144    def __set__(self, obj, value):
145        obj.section1[4] = value

Significance of reference time (See Table 1.2)

SignificanceOfReferenceTime()
class Year:
147class Year:
148    """Year of reference time"""
149    def __get__(self, obj, objtype=None):
150        return obj.section1[5]
151    def __set__(self, obj, value):
152        obj.section1[5] = value

Year of reference time

Year()
class Month:
154class Month:
155    """Month of reference time"""
156    def __get__(self, obj, objtype=None):
157        return obj.section1[6]
158    def __set__(self, obj, value):
159        obj.section1[6] = value

Month of reference time

Month()
class Day:
161class Day:
162    """Day of reference time"""
163    def __get__(self, obj, objtype=None):
164        return obj.section1[7]
165    def __set__(self, obj, value):
166        obj.section1[7] = value

Day of reference time

Day()
class Hour:
168class Hour:
169    """Hour of reference time"""
170    def __get__(self, obj, objtype=None):
171        return obj.section1[8]
172    def __set__(self, obj, value):
173        obj.section1[8] = value

Hour of reference time

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

Minute of reference time

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

Second of reference time

Second()
class RefDate:
189class RefDate:
190    """Reference date as a `datetime.datetime` object"""
191    def __get__(self, obj, objtype=None):
192        return datetime.datetime(*obj.section1[5:11])
193    def __set__(self, obj, value):
194        if isinstance(value,datetime.datetime):
195            obj.section1[5] = value.year
196            obj.section1[6] = value.month
197            obj.section1[7] = value.day
198            obj.section1[8] = value.hour
199            obj.section1[9] = value.minute
200            obj.section1[10] = value.second
201        else:
202            msg = 'Reference date must be a datetime.datetime object.'
203            raise TypeError(msg)

Reference date as a datetime.datetime object

RefDate()
class ProductionStatus:
205class ProductionStatus:
206    """Production Status of Processed data in the GRIB message
207    [(See Table 1.3)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)
208    """
209    def __get__(self, obj, objtype=None):
210        return Grib2Metadata(obj.section1[11],table='1.3')
211    def __set__(self, obj, value):
212        obj.section1[11] = value

Production Status of Processed data in the GRIB message (See Table 1.3)

ProductionStatus()
class TypeOfData:
214class TypeOfData:
215    """Type of processed data in this GRIB message
216    [(See Table 1.4)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)
217    """
218    def __get__(self, obj, objtype=None):
219        return Grib2Metadata(obj.section1[12],table='1.4')
220    def __set__(self, obj, value):
221        obj.section1[12] = value

Type of processed data in this GRIB message (See Table 1.4)

TypeOfData()
class GridDefinitionSection:
230class GridDefinitionSection:
231    """
232    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
233    """
234    def __get__(self, obj, objtype=None):
235        return obj.section3[0:5]
236    def __set__(self, obj, value):
237        raise RuntimeError

GRIB2 Section 3, Grid Definition Section

GridDefinitionSection()
class SourceOfGridDefinition:
239class SourceOfGridDefinition:
240    """Source of grid definition
241    [(See Table 3.0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml
242    """
243    def __get__(self, obj, objtype=None):
244        return Grib2Metadata(obj.section3[0],table='3.0')
245    def __set__(self, obj, value):
246        raise RuntimeError

Source of grid definition [(See Table 3.0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml

SourceOfGridDefinition()
class NumberOfDataPoints:
248class NumberOfDataPoints:
249    """Number of Data Points"""
250    def __get__(self, obj, objtype=None):
251        return obj.section3[1]
252    def __set__(self, obj, value):
253        raise RuntimeError

Number of Data Points

NumberOfDataPoints()
class InterpretationOfListOfNumbers:
255class InterpretationOfListOfNumbers:
256    """Interpretation of List of Numbers"""
257    def __get__(self, obj, objtype=None):
258        return Grib2Metadata(obj.section3[3],table='3.11')
259    def __set__(self, obj, value):
260        raise RuntimeError

Interpretation of List of Numbers

InterpretationOfListOfNumbers()
class GridDefinitionTemplateNumber:
262class GridDefinitionTemplateNumber:
263    """Grid definition template number
264    [(See Table 3.1)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml
265    """
266    def __get__(self, obj, objtype=None):
267        return Grib2Metadata(obj.section3[4],table='3.1')
268    def __set__(self, obj, value):
269        raise RuntimeError

Grid definition template number [(See Table 3.1)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml

GridDefinitionTemplateNumber()
class GridDefinitionTemplate:
271class GridDefinitionTemplate:
272    """Grid definition template"""
273    def __get__(self, obj, objtype=None):
274        return obj.section3[5:]
275    def __set__(self, obj, value):
276        raise RuntimeError

Grid definition template

GridDefinitionTemplate()
class EarthParams:
278class EarthParams:
279    def __get__(self, obj, objtype=None):
280        if obj.gridDefinitionSection[4] in {50,51,52,1200}:
281            return None
282        return tables.earth_params[str(obj.section3[5])]
283    def __set__(self, obj, value):
284        raise RuntimeError
EarthParams()
class DxSign:
286class DxSign:
287    def __get__(self, obj, objtype=None):
288        if obj.section3[4] in {0,1,203,205,32768,32769} and \
289        obj.section3[17] > obj.section3[20]:
290            return -1.0
291        return 1.0
292    def __set__(self, obj, value):
293        raise RuntimeError
DxSign()
class DySign:
295class DySign:
296    def __get__(self, obj, objtype=None):
297        if obj.section3[4] in {0,1,203,205,32768,32769} and \
298        obj.section3[16] > obj.section3[19]:
299            return -1.0
300        return 1.0
301    def __set__(self, obj, value):
302        raise RuntimeError
DySign()
class LLScaleFactor:
304class LLScaleFactor:
305    def __get__(self, obj, objtype=None):
306        if obj.section3[4] in {0,1,203,205,32768,32769}:
307            llscalefactor = float(obj.section3[14])
308            if llscalefactor == 0:
309                return 1
310            return llscalefactor
311        return 1
312    def __set__(self, obj, value):
313        raise RuntimeError
LLScaleFactor()
class LLDivisor:
315class LLDivisor:
316    def __get__(self, obj, objtype=None):
317        if obj.section3[4] in {0,1,203,205,32768,32769}:
318            lldivisor = float(obj.section3[15])
319            if lldivisor <= 0:
320                return 1.e6
321            return lldivisor
322        return 1.e6
323    def __set__(self, obj, value):
324        raise RuntimeError
LLDivisor()
class XYDivisor:
326class XYDivisor:
327    def __get__(self, obj, objtype=None):
328        if obj.section3[4] in {0,1,203,205,32768,32769}:
329            return obj._lldivisor
330        return 1.e3
331    def __set__(self, obj, value):
332        raise RuntimeError
XYDivisor()
class ShapeOfEarth:
334class ShapeOfEarth:
335    def __get__(self, obj, objtype=None):
336        return Grib2Metadata(obj.section3[5],table='3.2')
337    def __set__(self, obj, value):
338        obj.section3[5] = value
ShapeOfEarth()
class EarthRadius:
340class EarthRadius:
341    def __get__(self, obj, objtype=None):
342        earthparams = obj._earthparams
343        if earthparams['shape'] == 'spherical':
344            if earthparams['radius'] is None:
345                return obj.section3[7]/(10.**obj.section3[6])
346            else:
347                return earthparams['radius']
348        if earthparams['shape'] == 'oblateSpheriod':
349            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
350                return obj.section3[7]/(10.**obj.section3[6])
351            else:
352                return earthparams['radius']
353    def __set__(self, obj, value):
354        raise RuntimeError
EarthRadius()
class EarthMajorAxis:
356class EarthMajorAxis:
357    def __get__(self, obj, objtype=None):
358        earthparams = obj._earthparams
359        if earthparams['shape'] == 'spherical':
360            return None
361        if earthparams['shape'] == 'oblateSpheriod':
362            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
363                return obj.section3[9]/(10.**obj.section3[8])
364            else:
365                return earthparams['major_axis']
366    def __set__(self, obj, value):
367        raise RuntimeError
EarthMajorAxis()
class EarthMinorAxis:
369class EarthMinorAxis:
370    def __get__(self, obj, objtype=None):
371        earthparams = obj._earthparams
372        if earthparams['shape'] == 'spherical':
373            return None
374        if earthparams['shape'] == 'oblateSpheriod':
375            if earthparams['radius'] is None and earthparams['major_axis'] is None and earthparams['minor_axis'] is None:
376                return obj.section3[11]/(10.**section3[10])
377            else:
378                return earthparams['minor_axis']
379    def __set__(self, obj, value):
380        raise RuntimeError
EarthMinorAxis()
class Nx:
382class Nx:
383    def __get__(self, obj, objtype=None):
384        return obj.section3[12]
385    def __set__(self, obj, value):
386        obj.section3[12] = value
387        obj.section3[1] = value * obj.section3[13]
Nx()
class Ny:
389class Ny:
390    def __get__(self, obj, objtype=None):
391        return obj.section3[13]
392    def __set__(self, obj, value):
393        obj.section3[13] = value
394        obj.section3[1] = value * obj.section3[12]
Ny()
class ScanModeFlags:
396class ScanModeFlags:
397    _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}
398    def __get__(self, obj, objtype=None):
399        if obj.gdtn == 50:
400            return [None, None, None, None]
401        else:
402            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
403    def __set__(self, obj, value):
404        obj.section3[self._key[obj.gdtn]+5] = value
ScanModeFlags()
class ResolutionAndComponentFlags:
406class ResolutionAndComponentFlags:
407    _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}
408    def __get__(self, obj, objtype=None):
409        if obj.gdtn == 50:
410            return [None for i in range(8)]
411        else:
412            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
413    def __set__(self, obj, value):
414        obj.section3[self._key[obj.gdtn]+5] = value
ResolutionAndComponentFlags()
class LatitudeFirstGridpoint:
416class LatitudeFirstGridpoint:
417    _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}
418    def __get__(self, obj, objtype=None):
419        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
420    def __set__(self, obj, value):
421        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LatitudeFirstGridpoint()
class LongitudeFirstGridpoint:
423class LongitudeFirstGridpoint:
424    _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}
425    def __get__(self, obj, objtype=None):
426        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
427    def __set__(self, obj, value):
428        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LongitudeFirstGridpoint()
class LatitudeLastGridpoint:
430class LatitudeLastGridpoint:
431    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:14}
432    def __get__(self, obj, objtype=None):
433        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
434    def __set__(self, obj, value):
435        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LatitudeLastGridpoint()
class LongitudeLastGridpoint:
437class LongitudeLastGridpoint:
438    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:15}
439    def __get__(self, obj, objtype=None):
440        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
441    def __set__(self, obj, value):
442        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LongitudeLastGridpoint()
class GridlengthXDirection:
444class GridlengthXDirection:
445    _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}
446    def __get__(self, obj, objtype=None):
447        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
448    def __set__(self, obj, value):
449        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
GridlengthXDirection()
class GridlengthYDirection:
451class GridlengthYDirection:
452    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 40:17, 41:17, 203:17, 204:17, 205:17, 32768:17, 32769:17}
453    def __get__(self, obj, objtype=None):
454        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
455    def __set__(self, obj, value):
456        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
GridlengthYDirection()
class LatitudeSouthernPole:
458class LatitudeSouthernPole:
459    _key = {1:19, 30:20, 31:20, 41:19}
460    def __get__(self, obj, objtype=None):
461        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
462    def __set__(self, obj, value):
463        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LatitudeSouthernPole()
class LongitudeSouthernPole:
465class LongitudeSouthernPole:
466    _key = {1:20, 30:21, 31:21, 41:20}
467    def __get__(self, obj, objtype=None):
468        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
469    def __set__(self, obj, value):
470        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LongitudeSouthernPole()
class AnglePoleRotation:
472class AnglePoleRotation:
473    _key = {1:21, 41:21}
474    def __get__(self, obj, objtype=None):
475        return obj.section3[self._key[obj.gdtn]+5]
476    def __set__(self, obj, value):
477        obj.section3[self._key[obj.gdtn]+5] = int(value)
AnglePoleRotation()
class LatitudeTrueScale:
479class LatitudeTrueScale:
480    _key = {10:12, 20:12, 30:12, 31:12}
481    def __get__(self, obj, objtype=None):
482        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
483    def __set__(self, obj, value):
484        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
LatitudeTrueScale()
class GridOrientation:
486class GridOrientation:
487    _key = {10:16, 20:13, 30:13, 31:13}
488    def __get__(self, obj, objtype=None):
489        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
490    def __set__(self, obj, value):
491        if obj.gdtn == 10 and (value < 0 or value > 90):
492            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
493        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
GridOrientation()
class ProjectionCenterFlag:
495class ProjectionCenterFlag:
496    _key = {20:16, 30:16, 31:16}
497    def __get__(self, obj, objtype=None):
498        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
499    def __set__(self, obj, value):
500        obj.section3[self._key[obj.gdtn]+5] = value
ProjectionCenterFlag()
class StandardLatitude1:
502class StandardLatitude1:
503    _key = {30:18, 31:18}
504    def __get__(self, obj, objtype=None):
505        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
506    def __set__(self, obj, value):
507        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
StandardLatitude1()
class StandardLatitude2:
509class StandardLatitude2:
510    _key = {30:19, 31:19}
511    def __get__(self, obj, objtype=None):
512        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
513    def __set__(self, obj, value):
514        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
StandardLatitude2()
class SpectralFunctionParameters:
516class SpectralFunctionParameters:
517    def __get__(self, obj, objtype=None):
518        return obj.section3[0:3]
519    def __set__(self, obj, value):
520        obj.section3[0:3] = value[0:3]
SpectralFunctionParameters()
class ProjParameters:
522class ProjParameters:
523    def __get__(self, obj, objtype=None):
524        projparams = {}
525        projparams['a'] = 1.0
526        projparams['b'] = 1.0
527        if obj.earthRadius is not None:
528            projparams['a'] = obj.earthRadius
529            projparams['b'] = obj.earthRadius
530        else:
531            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
532            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
533        if obj.gdtn == 0:
534            projparams['proj'] = 'longlat'
535        elif obj.gdtn == 1:
536            projparams['o_proj'] = 'longlat'
537            projparams['proj'] = 'ob_tran'
538            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
539            projparams['o_lon_p'] = obj.anglePoleRotation
540            projparams['lon_0'] = obj.longitudeSouthernPole
541        elif obj.gdtn == 10:
542            projparams['proj'] = 'merc'
543            projparams['lat_ts'] = obj.latitudeTrueScale
544            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
545        elif obj.gdtn == 20:
546            if obj.projectionCenterFlag == 0:
547                lat0 = 90.0
548            elif obj.projectionCenterFlag == 1:
549                lat0 = -90.0
550            projparams['proj'] = 'stere'
551            projparams['lat_ts'] = obj.latitudeTrueScale
552            projparams['lat_0'] = lat0
553            projparams['lon_0'] = obj.gridOrientation
554        elif obj.gdtn == 30:
555            projparams['proj'] = 'lcc'
556            projparams['lat_1'] = obj.standardLatitude1
557            projparams['lat_2'] = obj.standardLatitude2
558            projparams['lat_0'] = obj.latitudeTrueScale
559            projparams['lon_0'] = obj.gridOrientation
560        elif obj.gdtn == 31:
561            projparams['proj'] = 'aea'
562            projparams['lat_1'] = obj.standardLatitude1
563            projparams['lat_2'] = obj.standardLatitude2
564            projparams['lat_0'] = obj.latitudeTrueScale
565            projparams['lon_0'] = obj.gridOrientation
566        elif obj.gdtn == 40:
567            projparams['proj'] = 'eqc'
568        return projparams
569    def __set__(self, obj, value):
570        raise RuntimeError
ProjParameters()
@dataclass(init=False)
class GridDefinitionTemplate0:
572@dataclass(init=False)
573class GridDefinitionTemplate0():
574    _len = 19
575    _num = 0
576    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
577    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
578    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
579    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
580    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
581    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
582    @classmethod
583    @property
584    def _attrs(cls):
585        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate0()
@dataclass(init=False)
class GridDefinitionTemplate1:
587@dataclass(init=False)
588class GridDefinitionTemplate1():
589    _len = 22
590    _num = 1
591    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
592    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
593    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
594    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
595    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
596    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
597    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
598    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
599    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
600    @classmethod
601    @property
602    def _attrs(cls):
603        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate1()
@dataclass(init=False)
class GridDefinitionTemplate10:
605@dataclass(init=False)
606class GridDefinitionTemplate10():
607    _len = 19
608    _num = 10
609    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
610    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
611    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
612    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
613    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
614    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
615    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
616    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
617    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
618    @classmethod
619    @property
620    def _attrs(cls):
621        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate10()
@dataclass(init=False)
class GridDefinitionTemplate20:
623@dataclass(init=False)
624class GridDefinitionTemplate20():
625    _len = 18
626    _num = 20
627    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
628    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
629    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
630    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
631    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
632    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
633    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
634    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
635    @classmethod
636    @property
637    def _attrs(cls):
638        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate20()
@dataclass(init=False)
class GridDefinitionTemplate30:
640@dataclass(init=False)
641class GridDefinitionTemplate30():
642    _len = 22
643    _num = 30
644    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
645    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
646    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
647    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
648    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
649    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
650    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
651    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
652    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
653    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
654    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
655    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
656    @classmethod
657    @property
658    def _attrs(cls):
659        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate30()
@dataclass(init=False)
class GridDefinitionTemplate31:
661@dataclass(init=False)
662class GridDefinitionTemplate31():
663    _len = 22
664    _num = 31
665    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
666    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
667    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
668    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
669    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
670    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
671    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
672    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
673    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
674    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
675    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
676    @classmethod
677    @property
678    def _attrs(cls):
679        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate31()
@dataclass(init=False)
class GridDefinitionTemplate40:
681@dataclass(init=False)
682class GridDefinitionTemplate40():
683    _len = 19
684    _num = 40
685    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
686    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
687    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
688    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
689    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
690    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
691    @classmethod
692    @property
693    def _attrs(cls):
694        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate40()
@dataclass(init=False)
class GridDefinitionTemplate41:
696@dataclass(init=False)
697class GridDefinitionTemplate41():
698    _len = 22
699    _num = 41
700    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
701    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
702    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
703    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
704    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
705    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
706    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
707    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
708    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
709    @classmethod
710    @property
711    def _attrs(cls):
712        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate41()
@dataclass(init=False)
class GridDefinitionTemplate50:
714@dataclass(init=False)
715class GridDefinitionTemplate50():
716    _len = 5
717    _num = 50
718    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
719    @classmethod
720    @property
721    def _attrs(cls):
722        return list(cls.__dataclass_fields__.keys())
GridDefinitionTemplate50()
def gdt_class_by_gdtn(gdtn):
735def gdt_class_by_gdtn(gdtn):
736    return _gdt_by_gdtn[gdtn]
class ProductDefinitionTemplateNumber:
741class ProductDefinitionTemplateNumber:
742    def __get__(self, obj, objtype=None):
743        return Grib2Metadata(obj.section4[1],table='4.0')
744    def __set__(self, obj, value):
745        raise RuntimeError
ProductDefinitionTemplateNumber()
class ProductDefinitionTemplate:
748class ProductDefinitionTemplate:
749    def __get__(self, obj, objtype=None):
750        return obj.section4[2:]
751    def __set__(self, obj, value):
752        raise RuntimeError
ProductDefinitionTemplate()
class ParameterCategory:
754class ParameterCategory:
755    _key = defaultdict(lambda: 0)
756    def __get__(self, obj, objtype=None):
757        return obj.section4[0+2]
758    def __set__(self, obj, value):
759        obj.section4[self._key[obj.pdtn]+2] = value
ParameterCategory()
class ParameterNumber:
761class ParameterNumber:
762    _key = defaultdict(lambda: 1)
763    def __get__(self, obj, objtype=None):
764        return obj.section4[1+2]
765    def __set__(self, obj, value):
766        obj.section4[self._key[obj.pdtn]+2] = value
ParameterNumber()
class VarInfo:
768class VarInfo:
769    def __get__(self, obj, objtype=None):
770        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
771    def __set__(self, obj, value):
772        raise RuntimeError
VarInfo()
class FullName:
774class FullName:
775    def __get__(self, obj, objtype=None):
776        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
777    def __set__(self, obj, value):
778        raise RuntimeError
FullName()
class Units:
780class Units:
781    def __get__(self, obj, objtype=None):
782        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
783    def __set__(self, obj, value):
784        raise RuntimeError
Units()
class ShortName:
786class ShortName:
787    def __get__(self, obj, objtype=None):
788        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[2]
789    def __set__(self, obj, value):
790        raise RuntimeError
ShortName()
class TypeOfGeneratingProcess:
792class TypeOfGeneratingProcess:
793    _key = defaultdict(lambda: 2, {48:13})
794    #_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}
795    def __get__(self, obj, objtype=None):
796        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
797    def __set__(self, obj, value):
798        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfGeneratingProcess()
class BackgroundGeneratingProcessIdentifier:
800class BackgroundGeneratingProcessIdentifier:
801    _key = defaultdict(lambda: 3, {48:14})
802    #_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}
803    def __get__(self, obj, objtype=None):
804        return obj.section4[self._key[obj.pdtn]+2]
805    def __set__(self, obj, value):
806        obj.section4[self._key[obj.pdtn]+2] = value
BackgroundGeneratingProcessIdentifier()
class GeneratingProcess:
808class GeneratingProcess:
809    _key = defaultdict(lambda: 4, {48:15})
810    #_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}
811    def __get__(self, obj, objtype=None):
812        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
813    def __set__(self, obj, value):
814        obj.section4[self._key[obj.pdtn]+2] = value
GeneratingProcess()
class HoursAfterDataCutoff:
816class HoursAfterDataCutoff:
817    _key = defaultdict(lambda: 5, {48:16})
818    def __get__(self, obj, objtype=None):
819        return obj.section4[self._key[obj.pdtn]+2]
820    def __set__(self, obj, value):
821        obj.section4[self._key[obj.pdtn]+2] = value
HoursAfterDataCutoff()
class MinutesAfterDataCutoff:
823class MinutesAfterDataCutoff:
824    _key = defaultdict(lambda: 6, {48:17})
825    def __get__(self, obj, objtype=None):
826        return obj.section4[self._key[obj.pdtn]+2]
827    def __set__(self, obj, value):
828        obj.section4[self._key[obj.pdtn]+2] = value
MinutesAfterDataCutoff()
class UnitOfTimeRange:
830class UnitOfTimeRange:
831    _key = defaultdict(lambda: 7, {48:18})
832    #_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}
833    def __get__(self, obj, objtype=None):
834        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
835    def __set__(self, obj, value):
836        obj.section4[self._key[obj.pdtn]+2] = value
UnitOfTimeRange()
class ForecastTime:
838class ForecastTime:
839    _key = defaultdict(lambda: 8, {48:19})
840    def __get__(self, obj, objtype=None):
841        return obj.section4[self._key[obj.pdtn]+2]
842    def __set__(self, obj, value):
843        obj.section4[self._key[obj.pdtn]+2] = value
ForecastTime()
class LeadTime:
845class LeadTime:
846    def __get__(self, obj, objtype=None):
847        return utils.get_leadtime(obj.section1,obj.section4[1],
848                                  obj.section4[2:])
849    def __set__(self, obj, value):
850        raise NotImplementedError
LeadTime()
class FixedSfc1Info:
852class FixedSfc1Info:
853    _key = defaultdict(lambda: 9, {48:20})
854    #_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}
855    def __get__(self, obj, objtype=None):
856        if obj.section4[self._key[obj.pdtn]+2] == 255:
857            return [None, None]
858        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
859    def __set__(self, obj, value):
860        raise NotImplementedError
FixedSfc1Info()
class FixedSfc2Info:
862class FixedSfc2Info:
863    _key = defaultdict(lambda: 12, {48:23})
864    #_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}
865    def __get__(self, obj, objtype=None):
866        if obj.section4[self._key[obj.pdtn]+2] == 255:
867            return [None, None]
868        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
869    def __set__(self, obj, value):
870        raise NotImplementedError
FixedSfc2Info()
class TypeOfFirstFixedSurface:
872class TypeOfFirstFixedSurface:
873    _key = defaultdict(lambda: 9, {48:20})
874    #_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}
875    def __get__(self, obj, objtype=None):
876        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
877    def __set__(self, obj, value):
878        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfFirstFixedSurface()
class ScaleFactorOfFirstFixedSurface:
880class ScaleFactorOfFirstFixedSurface:
881    _key = defaultdict(lambda: 10, {48:21})
882    #_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}
883    def __get__(self, obj, objtype=None):
884        return obj.section4[self._key[obj.pdtn]+2]
885    def __set__(self, obj, value):
886        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfFirstFixedSurface()
class ScaledValueOfFirstFixedSurface:
888class ScaledValueOfFirstFixedSurface:
889    _key = defaultdict(lambda: 11, {48:22})
890    #_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}
891    def __get__(self, obj, objtype=None):
892        return obj.section4[self._key[obj.pdtn]+2]
893    def __set__(self, obj, value):
894        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfFirstFixedSurface()
class UnitOfFirstFixedSurface:
896class UnitOfFirstFixedSurface:
897    def __get__(self, obj, objtype=None):
898        return obj._fixedsfc1info[1]
899    def __set__(self, obj, value):
900        pass
UnitOfFirstFixedSurface()
class ValueOfFirstFixedSurface:
902class ValueOfFirstFixedSurface:
903    def __get__(self, obj, objtype=None):
904        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn]+2]/\
905                            (10.**obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn]+2])
906    def __set__(self, obj, value):
907        pass
ValueOfFirstFixedSurface()
class TypeOfSecondFixedSurface:
909class TypeOfSecondFixedSurface:
910    _key = defaultdict(lambda: 12, {48:23})
911    #_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}
912    def __get__(self, obj, objtype=None):
913        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
914    def __set__(self, obj, value):
915        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfSecondFixedSurface()
class ScaleFactorOfSecondFixedSurface:
917class ScaleFactorOfSecondFixedSurface:
918    _key = defaultdict(lambda: 13, {48:24})
919    #_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}
920    def __get__(self, obj, objtype=None):
921        return obj.section4[self._key[obj.pdtn]+2]
922    def __set__(self, obj, value):
923        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfSecondFixedSurface()
class ScaledValueOfSecondFixedSurface:
925class ScaledValueOfSecondFixedSurface:
926    _key = defaultdict(lambda: 14, {48:25})
927    #_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}
928    def __get__(self, obj, objtype=None):
929        return obj.section4[self._key[obj.pdtn]+2]
930    def __set__(self, obj, value):
931        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfSecondFixedSurface()
class UnitOfSecondFixedSurface:
933class UnitOfSecondFixedSurface:
934    def __get__(self, obj, objtype=None):
935        return obj._fixedsfc2info[1]
936    def __set__(self, obj, value):
937        pass
UnitOfSecondFixedSurface()
class ValueOfSecondFixedSurface:
939class ValueOfSecondFixedSurface:
940    def __get__(self, obj, objtype=None):
941        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn]+2]/\
942                            (10.**obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn]+2])
943    def __set__(self, obj, value):
944        pass
ValueOfSecondFixedSurface()
class Level:
946class Level:
947    def __get__(self, obj, objtype=None):
948        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
949    def __set__(self, obj, value):
950        pass
Level()
class TypeOfEnsembleForecast:
952class TypeOfEnsembleForecast:
953    _key = {1:15, 11:15}
954    def __get__(self, obj, objtype=None):
955        pdtn = obj.section4[1]
956        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
957    def __set__(self, obj, value):
958        pdtn = obj.section4[1]
959        obj.section4[self._key[pdtn]+2] = value
TypeOfEnsembleForecast()
class PerturbationNumber:
961class PerturbationNumber:
962    _key = {1:16, 11:16}
963    def __get__(self, obj, objtype=None):
964        pdtn = obj.section4[1]
965        return obj.section4[self._key[pdtn]+2]
966    def __set__(self, obj, value):
967        pdtn = obj.section4[1]
968        obj.section4[self._key[pdtn]+2] = value
PerturbationNumber()
class NumberOfEnsembleForecasts:
970class NumberOfEnsembleForecasts:
971    _key = {1:17, 2:16, 11:17, 12:16}
972    def __get__(self, obj, objtype=None):
973        pdtn = obj.section4[1]
974        return obj.section4[self._key[pdtn]+2]
975    def __set__(self, obj, value):
976        pdtn = obj.section4[1]
977        obj.section4[self._key[pdtn]+2] = value
NumberOfEnsembleForecasts()
class TypeOfDerivedForecast:
979class TypeOfDerivedForecast:
980    _key = {2:15, 12:15}
981    def __get__(self, obj, objtype=None):
982        pdtn = obj.section4[1]
983        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
984    def __set__(self, obj, value):
985        pdtn = obj.section4[1]
986        obj.section4[self._key[pdtn]+2] = value
TypeOfDerivedForecast()
class ForecastProbabilityNumber:
988class ForecastProbabilityNumber:
989    _key = {5:15, 9:15}
990    def __get__(self, obj, objtype=None):
991        pdtn = obj.section4[1]
992        return obj.section4[self._key[pdtn]+2]
993    def __set__(self, obj, value):
994        pdtn = obj.section4[1]
995        obj.section4[self._key[pdtn]+2] = value
ForecastProbabilityNumber()
class TotalNumberOfForecastProbabilities:
 997class TotalNumberOfForecastProbabilities:
 998    _key = {5:16, 9:16}
 999    def __get__(self, obj, objtype=None):
1000        pdtn = obj.section4[1]
1001        return obj.section4[self._key[pdtn]+2]
1002    def __set__(self, obj, value):
1003        pdtn = obj.section4[1]
1004        obj.section4[self._key[pdtn]+2] = value
TotalNumberOfForecastProbabilities()
class TypeOfProbability:
1006class TypeOfProbability:
1007    _key = {5:17, 9:17}
1008    def __get__(self, obj, objtype=None):
1009        pdtn = obj.section4[1]
1010        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1011    def __set__(self, obj, value):
1012        pdtn = obj.section4[1]
1013        obj.section4[self._key[pdtn]+2] = value
TypeOfProbability()
class ScaleFactorOfThresholdLowerLimit:
1015class ScaleFactorOfThresholdLowerLimit:
1016    _key = {5:18, 9:18}
1017    def __get__(self, obj, objtype=None):
1018        pdtn = obj.section4[1]
1019        return obj.section4[self._key[pdtn]+2]
1020    def __set__(self, obj, value):
1021        pdtn = obj.section4[1]
1022        obj.section4[self._key[pdtn]+2] = value
ScaleFactorOfThresholdLowerLimit()
class ScaledValueOfThresholdLowerLimit:
1024class ScaledValueOfThresholdLowerLimit:
1025    _key = {5:19, 9:19}
1026    def __get__(self, obj, objtype=None):
1027        pdtn = obj.section4[1]
1028        return obj.section4[self._key[pdtn]+2]
1029    def __set__(self, obj, value):
1030        pdtn = obj.section4[1]
1031        obj.section4[self._key[pdtn]+2] = value
ScaledValueOfThresholdLowerLimit()
class ThresholdLowerLimit:
1033class ThresholdLowerLimit:
1034    def __get__(self, obj, objtype=None):
1035        if obj.section4[18+2] == -127 and \
1036           obj.section4[19+2] == 255:
1037            return 0.0
1038        else:
1039            return obj.section4[19+2]/(10.**obj.section4[18+2])
1040    def __set__(self, obj, value):
1041        pass
ThresholdLowerLimit()
class ThresholdUpperLimit:
1043class ThresholdUpperLimit:
1044    def __get__(self, obj, objtype=None):
1045        if obj.section4[20+2] == -127 and \
1046           obj.section4[21+2] == 255:
1047            return 0.0
1048        else:
1049            return obj.section4[21+2]/(10.**obj.section4[20+2])
1050    def __set__(self, obj, value):
1051        pass
ThresholdUpperLimit()
class Threshold:
1053class Threshold:
1054    def __get__(self, obj, objtype=None):
1055        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1056    def __set__(self, obj, value):
1057        pass
Threshold()
class PercentileValue:
1059class PercentileValue:
1060    _key = {6:15, 10:15}
1061    def __get__(self, obj, objtype=None):
1062        pdtn = obj.section4[1]
1063        return obj.section4[self._key[pdtn]+2]
1064    def __set__(self, obj, value):
1065        pdtn = obj.section4[1]
1066        obj.section4[self._key[pdtn]+2] = value
PercentileValue()
class YearOfEndOfTimePeriod:
1068class YearOfEndOfTimePeriod:
1069    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1070    def __get__(self, obj, objtype=None):
1071        pdtn = obj.section4[1]
1072        return obj.section4[self._key[pdtn]+2]
1073    def __set__(self, obj, value):
1074        pdtn = obj.section4[1]
1075        obj.section4[self._key[pdtn]+2] = value
YearOfEndOfTimePeriod()
class MonthOfEndOfTimePeriod:
1077class MonthOfEndOfTimePeriod:
1078    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1079    def __get__(self, obj, objtype=None):
1080        pdtn = obj.section4[1]
1081        return obj.section4[self._key[pdtn]+2]
1082    def __set__(self, obj, value):
1083        pdtn = obj.section4[1]
1084        obj.section4[self._key[pdtn]+2] = value
MonthOfEndOfTimePeriod()
class DayOfEndOfTimePeriod:
1086class DayOfEndOfTimePeriod:
1087    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1088    def __get__(self, obj, objtype=None):
1089        pdtn = obj.section4[1]
1090        return obj.section4[self._key[pdtn]+2]
1091    def __set__(self, obj, value):
1092        pdtn = obj.section4[1]
1093        obj.section4[self._key[pdtn]+2] = value
DayOfEndOfTimePeriod()
class HourOfEndOfTimePeriod:
1095class HourOfEndOfTimePeriod:
1096    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1097    def __get__(self, obj, objtype=None):
1098        pdtn = obj.section4[1]
1099        return obj.section4[self._key[pdtn]+2]
1100    def __set__(self, obj, value):
1101        pdtn = obj.section4[1]
1102        obj.section4[self._key[pdtn]+2] = value
HourOfEndOfTimePeriod()
class MinuteOfEndOfTimePeriod:
1104class MinuteOfEndOfTimePeriod:
1105    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1106    def __get__(self, obj, objtype=None):
1107        pdtn = obj.section4[1]
1108        return obj.section4[self._key[pdtn]+2]
1109    def __set__(self, obj, value):
1110        pdtn = obj.section4[1]
1111        obj.section4[self._key[pdtn]+2] = value
MinuteOfEndOfTimePeriod()
class SecondOfEndOfTimePeriod:
1113class SecondOfEndOfTimePeriod:
1114    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1115    def __get__(self, obj, objtype=None):
1116        pdtn = obj.section4[1]
1117        return obj.section4[self._key[pdtn]+2]
1118    def __set__(self, obj, value):
1119        pdtn = obj.section4[1]
1120        obj.section4[self._key[pdtn]+2] = value
SecondOfEndOfTimePeriod()
class Duration:
1122class Duration:
1123    def __get__(self, obj, objtype=None):
1124        return utils.get_duration(obj.section4[1],obj.section4[2:])
1125    def __set__(self, obj, value):
1126        pass
Duration()
class ValidDate:
1128class ValidDate:
1129    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1130    def __get__(self, obj, objtype=None):
1131        pdtn = obj.section4[1]
1132        try:
1133            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1134            return datetime.datetime(*obj.section4[s])
1135        except(KeyError):
1136            return obj.refDate + obj.leadTime
1137    def __set__(self, obj, value):
1138        pass
ValidDate()
class NumberOfTimeRanges:
1140class NumberOfTimeRanges:
1141    _key = {8:21, 9:28, 10:22, 11:24, 12:23}
1142    def __get__(self, obj, objtype=None):
1143        pdtn = obj.section4[1]
1144        return obj.section4[self._key[pdtn]+2]
1145    def __set__(self, obj, value):
1146        pdtn = obj.section4[1]
1147        obj.section4[self._key[pdtn]+2] = value
NumberOfTimeRanges()
class NumberOfMissingValues:
1149class NumberOfMissingValues:
1150    _key = {8:22, 9:29, 10:23, 11:25, 12:24}
1151    def __get__(self, obj, objtype=None):
1152        pdtn = obj.section4[1]
1153        return obj.section4[self._key[pdtn]+2]
1154    def __set__(self, obj, value):
1155        pdtn = obj.section4[1]
1156        obj.section4[self._key[pdtn]+2] = value
NumberOfMissingValues()
class StatisticalProcess:
1158class StatisticalProcess:
1159    _key = {8:23, 9:30, 10:24, 11:26, 12:25, 15:15}
1160    def __get__(self, obj, objtype=None):
1161        pdtn = obj.section4[1]
1162        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.10')
1163    def __set__(self, obj, value):
1164        pdtn = obj.section4[1]
1165        obj.section4[self._key[pdtn]+2] = value
StatisticalProcess()
class TypeOfTimeIncrementOfStatisticalProcess:
1167class TypeOfTimeIncrementOfStatisticalProcess:
1168    _key = {8:24, 9:31, 10:25, 11:27, 12:26}
1169    def __get__(self, obj, objtype=None):
1170        pdtn = obj.section4[1]
1171        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.11')
1172    def __set__(self, obj, value):
1173        pdtn = obj.section4[1]
1174        obj.section4[self._key[pdtn]+2] = value
TypeOfTimeIncrementOfStatisticalProcess()
class UnitOfTimeRangeOfStatisticalProcess:
1176class UnitOfTimeRangeOfStatisticalProcess:
1177    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
1178    def __get__(self, obj, objtype=None):
1179        pdtn = obj.section4[1]
1180        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1181    def __set__(self, obj, value):
1182        pdtn = obj.section4[1]
1183        obj.section4[self._key[pdtn]+2] = value
UnitOfTimeRangeOfStatisticalProcess()
class TimeRangeOfStatisticalProcess:
1185class TimeRangeOfStatisticalProcess:
1186    _key = {8:26, 9:33, 10:27, 11:29, 12:28}
1187    def __get__(self, obj, objtype=None):
1188        pdtn = obj.section4[1]
1189        return obj.section4[self._key[pdtn]+2]
1190    def __set__(self, obj, value):
1191        pdtn = obj.section4[1]
1192        obj.section4[self._key[pdtn]+2] = value
TimeRangeOfStatisticalProcess()
class UnitOfTimeRangeOfSuccessiveFields:
1194class UnitOfTimeRangeOfSuccessiveFields:
1195    _key = {8:27, 9:34, 10:28, 11:30, 12:29}
1196    def __get__(self, obj, objtype=None):
1197        pdtn = obj.section4[1]
1198        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1199    def __set__(self, obj, value):
1200        pdtn = obj.section4[1]
1201        obj.section4[self._key[pdtn]+2] = value
UnitOfTimeRangeOfSuccessiveFields()
class TimeIncrementOfSuccessiveFields:
1203class TimeIncrementOfSuccessiveFields:
1204    _key = {8:28, 9:35, 10:29, 11:31, 12:30}
1205    def __get__(self, obj, objtype=None):
1206        pdtn = obj.section4[1]
1207        return obj.section4[self._key[pdtn]+2]
1208    def __set__(self, obj, value):
1209        pdtn = obj.section4[1]
1210        obj.section4[self._key[pdtn]+2] = value
TimeIncrementOfSuccessiveFields()
class TypeOfStatisticalProcessing:
1212class TypeOfStatisticalProcessing:
1213    _key = {15:16}
1214    def __get__(self, obj, objtype=None):
1215        pdtn = obj.section4[1]
1216        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1217    def __set__(self, obj, value):
1218        pdtn = obj.section4[1]
1219        obj.section4[self._key[pdtn]+2] = value
TypeOfStatisticalProcessing()
class NumberOfDataPointsForSpatialProcessing:
1221class NumberOfDataPointsForSpatialProcessing:
1222    _key = {15:17}
1223    def __get__(self, obj, objtype=None):
1224        pdtn = obj.section4[1]
1225        return obj.section4[self._key[pdtn]+2]
1226    def __set__(self, obj, value):
1227        pdtn = obj.section4[1]
1228        obj.section4[self._key[pdtn]+2] = value
NumberOfDataPointsForSpatialProcessing()
class TypeOfAerosol:
1230class TypeOfAerosol:
1231    _key = {48:2}
1232    def __get__(self, obj, objtype=None):
1233        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1234    def __set__(self, obj, value):
1235        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfAerosol()
class TypeOfIntervalForAerosolSize:
1237class TypeOfIntervalForAerosolSize:
1238    _key = {48:3}
1239    def __get__(self, obj, objtype=None):
1240        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1241    def __set__(self, obj, value):
1242        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfIntervalForAerosolSize()
class ScaleFactorOfFirstSize:
1244class ScaleFactorOfFirstSize:
1245    _key = {48:4}
1246    def __get__(self, obj, objtype=None):
1247        return obj.section4[self._key[obj.pdtn]+2]
1248    def __set__(self, obj, value):
1249        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfFirstSize()
class ScaledValueOfFirstSize:
1251class ScaledValueOfFirstSize:
1252    _key = {48:5}
1253    def __get__(self, obj, objtype=None):
1254        return obj.section4[self._key[obj.pdtn]+2]
1255    def __set__(self, obj, value):
1256        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfFirstSize()
class ScaleFactorOfSecondSize:
1258class ScaleFactorOfSecondSize:
1259    _key = {48:6}
1260    def __get__(self, obj, objtype=None):
1261        return obj.section4[self._key[obj.pdtn]+2]
1262    def __set__(self, obj, value):
1263        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfSecondSize()
class ScaledValueOfSecondSize:
1265class ScaledValueOfSecondSize:
1266    _key = {48:7}
1267    def __get__(self, obj, objtype=None):
1268        return obj.section4[self._key[obj.pdtn]+2]
1269    def __set__(self, obj, value):
1270        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfSecondSize()
class TypeOfIntervalForAerosolWavelength:
1272class TypeOfIntervalForAerosolWavelength:
1273    _key = {48:8}
1274    def __get__(self, obj, objtype=None):
1275        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1276    def __set__(self, obj, value):
1277        obj.section4[self._key[obj.pdtn]+2] = value
TypeOfIntervalForAerosolWavelength()
class ScaleFactorOfFirstWavelength:
1279class ScaleFactorOfFirstWavelength:
1280    _key = {48:9}
1281    def __get__(self, obj, objtype=None):
1282        return obj.section4[self._key[obj.pdtn]+2]
1283    def __set__(self, obj, value):
1284        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfFirstWavelength()
class ScaledValueOfFirstWavelength:
1286class ScaledValueOfFirstWavelength:
1287    _key = {48:10}
1288    def __get__(self, obj, objtype=None):
1289        return obj.section4[self._key[obj.pdtn]+2]
1290    def __set__(self, obj, value):
1291        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfFirstWavelength()
class ScaleFactorOfSecondWavelength:
1293class ScaleFactorOfSecondWavelength:
1294    _key = {48:11}
1295    def __get__(self, obj, objtype=None):
1296        return obj.section4[self._key[obj.pdtn]+2]
1297    def __set__(self, obj, value):
1298        obj.section4[self._key[obj.pdtn]+2] = value
ScaleFactorOfSecondWavelength()
class ScaledValueOfSecondWavelength:
1300class ScaledValueOfSecondWavelength:
1301    _key = {48:12}
1302    def __get__(self, obj, objtype=None):
1303        return obj.section4[self._key[obj.pdtn]+2]
1304    def __set__(self, obj, value):
1305        obj.section4[self._key[obj.pdtn]+2] = value
ScaledValueOfSecondWavelength()
@dataclass(init=False)
class ProductDefinitionTemplate0:
1307@dataclass(init=False)
1308class ProductDefinitionTemplate0():
1309    _len = 15
1310    _num = 0
1311    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1312    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1313    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1314    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1315    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1316    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1317    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1318    unitOfTimeRange: Grib2Metadata = field(init=False,repr=False,default=UnitOfTimeRange())
1319    forecastTime: int = field(init=False,repr=False,default=ForecastTime())
1320    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1321    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1322    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1323    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1324    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1325    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1326    @classmethod
1327    @property
1328    def _attrs(cls):
1329        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate0()
@dataclass(init=False)
class ProductDefinitionTemplate1(ProductDefinitionTemplate0):
1331@dataclass(init=False)
1332class ProductDefinitionTemplate1(ProductDefinitionTemplate0):
1333    _len = 18
1334    _num = 1
1335    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1336    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1337    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1338    @classmethod
1339    @property
1340    def _attrs(cls):
1341        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate1()
@dataclass(init=False)
class ProductDefinitionTemplate2(ProductDefinitionTemplate0):
1343@dataclass(init=False)
1344class ProductDefinitionTemplate2(ProductDefinitionTemplate0):
1345    _len = 17
1346    _num = 2
1347    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1348    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1349    @classmethod
1350    @property
1351    def _attrs(cls):
1352        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate2()
@dataclass(init=False)
class ProductDefinitionTemplate5(ProductDefinitionTemplate0):
1354@dataclass(init=False)
1355class ProductDefinitionTemplate5(ProductDefinitionTemplate0):
1356    _len = 22
1357    _num = 5
1358    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1359    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1360    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1361    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1362    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1363    threshold: str = field(init=False, repr=False, default=Threshold())
1364    @classmethod
1365    @property
1366    def _attrs(cls):
1367        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate5()
@dataclass(init=False)
class ProductDefinitionTemplate6(ProductDefinitionTemplate0):
1369@dataclass(init=False)
1370class ProductDefinitionTemplate6(ProductDefinitionTemplate0):
1371    _len = 16
1372    _num = 6
1373    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1374    @classmethod
1375    @property
1376    def _attrs(cls):
1377        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate6()
@dataclass(init=False)
class ProductDefinitionTemplate8(ProductDefinitionTemplate0):
1379@dataclass(init=False)
1380class ProductDefinitionTemplate8(ProductDefinitionTemplate0):
1381    _len = 29
1382    _num = 8
1383    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1384    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1385    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1386    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1387    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1388    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1389    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1390    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1391    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1392    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1393    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1394    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1395    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1396    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1397    @classmethod
1398    @property
1399    def _attrs(cls):
1400        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate8()
@dataclass(init=False)
class ProductDefinitionTemplate9(ProductDefinitionTemplate0):
1402@dataclass(init=False)
1403class ProductDefinitionTemplate9(ProductDefinitionTemplate0):
1404    _len = 36
1405    _num = 9
1406    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1407    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1408    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1409    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1410    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1411    threshold: str = field(init=False, repr=False, default=Threshold())
1412    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1413    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1414    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1415    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1416    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1417    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1418    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1419    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1420    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1421    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1422    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1423    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1424    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1425    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1426    @classmethod
1427    @property
1428    def _attrs(cls):
1429        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate9()
@dataclass(init=False)
class ProductDefinitionTemplate10(ProductDefinitionTemplate0):
1431@dataclass(init=False)
1432class ProductDefinitionTemplate10(ProductDefinitionTemplate0):
1433    _len = 30
1434    _num = 10
1435    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1436    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1437    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1438    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1439    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1440    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1441    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1442    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1443    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1444    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1445    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1446    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1447    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1448    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1449    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1450    @classmethod
1451    @property
1452    def _attrs(cls):
1453        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate10()
@dataclass(init=False)
class ProductDefinitionTemplate11(ProductDefinitionTemplate0):
1455@dataclass(init=False)
1456class ProductDefinitionTemplate11(ProductDefinitionTemplate0):
1457    _len = 32
1458    _num = 11
1459    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1460    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1461    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1462    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1463    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1464    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1465    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1466    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1467    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1468    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1469    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1470    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1471    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1472    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1473    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1474    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1475    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1476    @classmethod
1477    @property
1478    def _attrs(cls):
1479        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate11()
@dataclass(init=False)
class ProductDefinitionTemplate12(ProductDefinitionTemplate0):
1481@dataclass(init=False)
1482class ProductDefinitionTemplate12(ProductDefinitionTemplate0):
1483    _len = 31
1484    _num = 12
1485    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1486    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1487    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1488    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1489    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1490    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1491    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1492    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1493    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1494    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1495    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1496    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1497    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1498    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1499    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1500    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1501    @classmethod
1502    @property
1503    def _attrs(cls):
1504        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate12()
@dataclass(init=False)
class ProductDefinitionTemplate15(ProductDefinitionTemplate0):
1506@dataclass(init=False)
1507class ProductDefinitionTemplate15(ProductDefinitionTemplate0):
1508    _len = 18
1509    _num = 15
1510    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1511    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
1512    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
1513    @classmethod
1514    @property
1515    def _attrs(cls):
1516        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate15()
@dataclass(init=False)
class ProductDefinitionTemplate48(ProductDefinitionTemplate0):
1518@dataclass(init=False)
1519class ProductDefinitionTemplate48(ProductDefinitionTemplate0):
1520    _len = 26
1521    _num = 48
1522    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
1523    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
1524    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
1525    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
1526    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
1527    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
1528    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
1529    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
1530    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
1531    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
1532    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
1533    @classmethod
1534    @property
1535    def _attrs(cls):
1536        return list(cls.__dataclass_fields__.keys())
ProductDefinitionTemplate48()
def pdt_class_by_pdtn(pdtn):
1553def pdt_class_by_pdtn(pdtn):
1554    return _pdt_by_pdtn[pdtn]
class NumberOfPackedValues:
1559class NumberOfPackedValues:
1560    def __get__(self, obj, objtype=None):
1561        return obj.section5[0]
1562    def __set__(self, obj, value):
1563        pass
NumberOfPackedValues()
class DataRepresentationTemplateNumber:
1565class DataRepresentationTemplateNumber:
1566    def __get__(self, obj, objtype=None):
1567        return Grib2Metadata(obj.section5[1],table='5.0')
1568    def __set__(self, obj, value):
1569        pass
DataRepresentationTemplateNumber()
class DataRepresentationTemplate:
1571class DataRepresentationTemplate:
1572    def __get__(self, obj, objtype=None):
1573        return obj.section5[2:]
1574    def __set__(self, obj, value):
1575        raise NotImplementedError
DataRepresentationTemplate()
class RefValue:
1577class RefValue:
1578    def __get__(self, obj, objtype=None):
1579        return utils.ieee_int_to_float(obj.section5[0+2])
1580    def __set__(self, obj, value):
1581        pass
RefValue()
class BinScaleFactor:
1583class BinScaleFactor:
1584    def __get__(self, obj, objtype=None):
1585        return obj.section5[1+2]
1586    def __set__(self, obj, value):
1587        obj.section5[1+2] = value
BinScaleFactor()
class DecScaleFactor:
1589class DecScaleFactor:
1590    def __get__(self, obj, objtype=None):
1591        return obj.section5[2+2]
1592    def __set__(self, obj, value):
1593        obj.section5[2+2] = value
DecScaleFactor()
class NBitsPacking:
1595class NBitsPacking:
1596    def __get__(self, obj, objtype=None):
1597        return obj.section5[3+2]
1598    def __set__(self, obj, value):
1599        obj.section5[3+2] = value
NBitsPacking()
class TypeOfValues:
1601class TypeOfValues:
1602    def __get__(self, obj, objtype=None):
1603        return Grib2Metadata(obj.section5[4+2],table='5.1')
1604    def __set__(self, obj, value):
1605        obj.section5[4+2] = value
TypeOfValues()
class GroupSplittingMethod:
1607class GroupSplittingMethod:
1608    def __get__(self, obj, objtype=None):
1609        return Grib2Metadata(obj.section5[5+2],table='5.4')
1610    def __set__(self, obj, value):
1611        obj.section5[5+2] = value
GroupSplittingMethod()
class TypeOfMissingValueManagement:
1613class TypeOfMissingValueManagement:
1614    def __get__(self, obj, objtype=None):
1615        return Grib2Metadata(obj.section5[6+2],table='5.5')
1616    def __set__(self, obj, value):
1617        obj.section5[5+2] = value
TypeOfMissingValueManagement()
class PriMissingValue:
1619class PriMissingValue:
1620    def __get__(self, obj, objtype=None):
1621        if obj.typeOfValues == 0:
1622            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
1623        elif obj.typeOfValues == 1:
1624            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
1625    def __set__(self, obj, value):
1626        if obj.typeOfValues == 0:
1627            obj.section5[7+2] = utils.ieee_float_to_int(value)
1628        elif self.typeOfValues == 1:
1629            obj.section5[7+2] = int(value)
1630        obj.section5[6+2] = 1
PriMissingValue()
class SecMissingValue:
1632class SecMissingValue:
1633    def __get__(self, obj, objtype=None):
1634        if obj.typeOfValues == 0:
1635            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
1636        elif obj.typeOfValues == 1:
1637            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
1638    def __set__(self, obj, value):
1639        if obj.typeOfValues == 0:
1640            obj.section5[8+2] = utils.ieee_float_to_int(value)
1641        elif self.typeOfValues == 1:
1642            obj.section5[8+2] = int(value)
1643        obj.section5[6+2] = 2
SecMissingValue()
class NGroups:
1645class NGroups:
1646    def __get__(self, obj, objtype=None):
1647        return obj.section5[9+2]
1648    def __set__(self, obj, value):
1649        pass
NGroups()
class RefGroupWidth:
1651class RefGroupWidth:
1652    def __get__(self, obj, objtype=None):
1653        return obj.section5[10+2]
1654    def __set__(self, obj, value):
1655        pass
RefGroupWidth()
class NBitsGroupWidth:
1657class NBitsGroupWidth:
1658    def __get__(self, obj, objtype=None):
1659        return obj.section5[11+2]
1660    def __set__(self, obj, value):
1661        pass
NBitsGroupWidth()
class RefGroupLength:
1663class RefGroupLength:
1664    def __get__(self, obj, objtype=None):
1665        return obj.section5[12+2]
1666    def __set__(self, obj, value):
1667        pass
RefGroupLength()
class GroupLengthIncrement:
1669class GroupLengthIncrement:
1670    def __get__(self, obj, objtype=None):
1671        return obj.section5[13+2]
1672    def __set__(self, obj, value):
1673        pass
GroupLengthIncrement()
class LengthOfLastGroup:
1675class LengthOfLastGroup:
1676    def __get__(self, obj, objtype=None):
1677        return obj.section5[14+2]
1678    def __set__(self, obj, value):
1679        pass
LengthOfLastGroup()
class NBitsScaledGroupLength:
1681class NBitsScaledGroupLength:
1682    def __get__(self, obj, objtype=None):
1683        return obj.section5[15+2]
1684    def __set__(self, obj, value):
1685        pass
NBitsScaledGroupLength()
class SpatialDifferenceOrder:
1687class SpatialDifferenceOrder:
1688    def __get__(self, obj, objtype=None):
1689        return Grib2Metadata(obj.section5[16+2],table='5.6')
1690    def __set__(self, obj, value):
1691        obj.section5[16+2] = value
SpatialDifferenceOrder()
class NBytesSpatialDifference:
1693class NBytesSpatialDifference:
1694    def __get__(self, obj, objtype=None):
1695        return obj.section5[17+2]
1696    def __set__(self, obj, value):
1697        pass
NBytesSpatialDifference()
class Precision:
1699class Precision:
1700    def __get__(self, obj, objtype=None):
1701        return Grib2Metadata(obj.section5[0+2],table='5.7')
1702    def __set__(self, obj, value):
1703        obj.section5[0+2] = value
Precision()
class TypeOfCompression:
1705class TypeOfCompression:
1706    def __get__(self, obj, objtype=None):
1707        return Grib2Metadata(obj.section5[5+2],table='5.40')
1708    def __set__(self, obj, value):
1709        obj.section5[5+2] = value
TypeOfCompression()
class TargetCompressionRatio:
1711class TargetCompressionRatio:
1712    def __get__(self, obj, objtype=None):
1713        return obj.section5[6+2]
1714    def __set__(self, obj, value):
1715        pass
TargetCompressionRatio()
class RealOfCoefficient:
1717class RealOfCoefficient:
1718    def __get__(self, obj, objtype=None):
1719        return utils.ieee_int_to_float(obj.section5[4+2])
1720    def __set__(self, obj, value):
1721        obj.section5[4+2] = utils.ieee_float_to_int(float(value))
RealOfCoefficient()
@dataclass(init=False)
class DataRepresentationTemplate0:
1723@dataclass(init=False)
1724class DataRepresentationTemplate0():
1725    _len = 5
1726    _num = 0
1727    _packingScheme = 'simple'
1728    refValue: float = field(init=False, repr=False, default=RefValue())
1729    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1730    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1731    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1732    @classmethod
1733    @property
1734    def _attrs(cls):
1735        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate0()
@dataclass(init=False)
class DataRepresentationTemplate2:
1737@dataclass(init=False)
1738class DataRepresentationTemplate2():
1739    _len = 16
1740    _num = 2
1741    _packingScheme = 'complex'
1742    refValue: float = field(init=False, repr=False, default=RefValue())
1743    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1744    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1745    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1746    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
1747    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
1748    priMissingValue: [float, int] = field(init=False, repr=False, default=PriMissingValue())
1749    secMissingValue: [float, int] = field(init=False, repr=False, default=SecMissingValue())
1750    nGroups: int = field(init=False, repr=False, default=NGroups())
1751    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
1752    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
1753    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
1754    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
1755    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
1756    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
1757    @classmethod
1758    @property
1759    def _attrs(cls):
1760        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate2()
@dataclass(init=False)
class DataRepresentationTemplate3:
1762@dataclass(init=False)
1763class DataRepresentationTemplate3():
1764    _len = 18
1765    _num = 3
1766    _packingScheme = 'complex-spdiff'
1767    refValue: float = field(init=False, repr=False, default=RefValue())
1768    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1769    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1770    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1771    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
1772    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
1773    priMissingValue: [float, int] = field(init=False, repr=False, default=PriMissingValue())
1774    secMissingValue: [float, int] = field(init=False, repr=False, default=SecMissingValue())
1775    nGroups: int = field(init=False, repr=False, default=NGroups())
1776    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
1777    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
1778    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
1779    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
1780    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
1781    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
1782    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
1783    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
1784    @classmethod
1785    @property
1786    def _attrs(cls):
1787        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate3()
@dataclass(init=False)
class DataRepresentationTemplate4:
1789@dataclass(init=False)
1790class DataRepresentationTemplate4():
1791    _len = 1
1792    _num = 4
1793    _packingScheme = 'ieee-float'
1794    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
1795    @classmethod
1796    @property
1797    def _attrs(cls):
1798        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate4()
@dataclass(init=False)
class DataRepresentationTemplate40:
1800@dataclass(init=False)
1801class DataRepresentationTemplate40():
1802    _len = 7
1803    _num = 40
1804    _packingScheme = 'jpeg'
1805    refValue: float = field(init=False, repr=False, default=RefValue())
1806    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1807    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1808    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1809    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
1810    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
1811    @classmethod
1812    @property
1813    def _attrs(cls):
1814        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate40()
@dataclass(init=False)
class DataRepresentationTemplate41:
1816@dataclass(init=False)
1817class DataRepresentationTemplate41():
1818    _len = 5
1819    _num = 41
1820    _packingScheme = 'png'
1821    refValue: float = field(init=False, repr=False, default=RefValue())
1822    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1823    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1824    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1825    @classmethod
1826    @property
1827    def _attrs(cls):
1828        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate41()
@dataclass(init=False)
class DataRepresentationTemplate50:
1830@dataclass(init=False)
1831class DataRepresentationTemplate50():
1832    _len = 5
1833    _num = 0
1834    _packingScheme = 'spectral-simple'
1835    refValue: float = field(init=False, repr=False, default=RefValue())
1836    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
1837    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
1838    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
1839    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
1840    @classmethod
1841    @property
1842    def _attrs(cls):
1843        return list(cls.__dataclass_fields__.keys())
DataRepresentationTemplate50()
def drt_class_by_drtn(drtn):
1855def drt_class_by_drtn(drtn):
1856    return _drt_by_drtn[drtn]