grib2io.templates

GRIB2 section templates classes and metadata descriptor classes.

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

Class to hold GRIB2 metadata.

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

Attributes
  • value (int): GRIB2 metadata integer code value.
  • table (str, optional): GRIB2 table to lookup the value. Default is None.
  • definition (str): Plain language description of numeric metadata.
Grib2Metadata(value, table=None)
47    def __init__(self, value, table=None):
48        self.value = value
49        self.table = table
value
table
definition
76    @property
77    def definition(self):
78        return tables.get_value_from_table(self.value,self.table)
def show_table(self):
79    def show_table(self):
80        """Provide the table related to this metadata."""
81        return tables.get_table(self.table)

Provide the table related to this metadata.

class IndicatorSection:
86class IndicatorSection:
87    """
88    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
89    """
90    def __get__(self, obj, objtype=None):
91        return obj.section0
92    def __set__(self, obj, value):
93        obj.section0 = value
class Discipline:
 95class Discipline:
 96    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
 97    def __get__(self, obj, objtype=None):
 98        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
 99    def __set__(self, obj, value):
100        obj.section0[2] = value
class IdentificationSection:
106class IdentificationSection:
107    """
108    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
109    """
110    def __get__(self, obj, objtype=None):
111        return obj.section1
112    def __set__(self, obj, value):
113        obj.section1 = value

GRIB2 Section 1, Identification Section

class OriginatingCenter:
115class OriginatingCenter:
116    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
117    def __get__(self, obj, objtype=None):
118        return Grib2Metadata(obj.section1[0],table='originating_centers')
119    def __set__(self, obj, value):
120        obj.section1[0] = value
class OriginatingSubCenter:
122class OriginatingSubCenter:
123    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
124    def __get__(self, obj, objtype=None):
125        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
126    def __set__(self, obj, value):
127        obj.section1[1] = value
class MasterTableInfo:
129class MasterTableInfo:
130    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
131    def __get__(self, obj, objtype=None):
132        return Grib2Metadata(obj.section1[2],table='1.0')
133    def __set__(self, obj, value):
134        obj.section1[2] = value
class LocalTableInfo:
136class LocalTableInfo:
137    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
138    def __get__(self, obj, objtype=None):
139        return Grib2Metadata(obj.section1[3],table='1.1')
140    def __set__(self, obj, value):
141        obj.section1[3] = value
class SignificanceOfReferenceTime:
143class SignificanceOfReferenceTime:
144    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
145    def __get__(self, obj, objtype=None):
146        return Grib2Metadata(obj.section1[4],table='1.2')
147    def __set__(self, obj, value):
148        obj.section1[4] = value
class Year:
150class Year:
151    """Year of reference time"""
152    def __get__(self, obj, objtype=None):
153        return obj.section1[5]
154    def __set__(self, obj, value):
155        obj.section1[5] = value

Year of reference time

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

Month of reference time

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

Day of reference time

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

Hour of reference time

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

Minute of reference time

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

Second of reference time

class RefDate:
192class RefDate:
193    """Reference Date. NOTE: This is a `datetime.datetime` object."""
194    def __get__(self, obj, objtype=None):
195        return datetime.datetime(*obj.section1[5:11])
196    def __set__(self, obj, value):
197        if isinstance(value, datetime64):
198            timestamp = (value - datetime64("1970-01-01T00:00:00")) / timedelta64(
199                1, "s"
200            )
201            value = datetime.datetime.utcfromtimestamp(timestamp)
202        if isinstance(value, datetime.datetime):
203            obj.section1[5] = value.year
204            obj.section1[6] = value.month
205            obj.section1[7] = value.day
206            obj.section1[8] = value.hour
207            obj.section1[9] = value.minute
208            obj.section1[10] = value.second
209        else:
210            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
211            raise TypeError(msg)

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

class ProductionStatus:
213class ProductionStatus:
214    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
215    def __get__(self, obj, objtype=None):
216        return Grib2Metadata(obj.section1[11],table='1.3')
217    def __set__(self, obj, value):
218        obj.section1[11] = value
class TypeOfData:
220class TypeOfData:
221    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
222    def __get__(self, obj, objtype=None):
223        return Grib2Metadata(obj.section1[12],table='1.4')
224    def __set__(self, obj, value):
225        obj.section1[12] = value
class GridDefinitionSection:
234class GridDefinitionSection:
235    """
236    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
237    """
238    def __get__(self, obj, objtype=None):
239        return obj.section3[0:5]
240    def __set__(self, obj, value):
241        raise RuntimeError

GRIB2 Section 3, Grid Definition Section

class SourceOfGridDefinition:
243class SourceOfGridDefinition:
244    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
245    def __get__(self, obj, objtype=None):
246        return Grib2Metadata(obj.section3[0],table='3.0')
247    def __set__(self, obj, value):
248        raise RuntimeError
class NumberOfDataPoints:
250class NumberOfDataPoints:
251    """Number of Data Points"""
252    def __get__(self, obj, objtype=None):
253        return obj.section3[1]
254    def __set__(self, obj, value):
255        raise RuntimeError

Number of Data Points

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

Interpretation of List of Numbers

class GridDefinitionTemplateNumber:
264class GridDefinitionTemplateNumber:
265    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
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
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

class EarthParams:
278class EarthParams:
279    """Metadata about the shape of the Earth"""
280    def __get__(self, obj, objtype=None):
281        if obj.section3[5] in {50,51,52,1200}:
282            return None
283        return tables.get_table('earth_params')[str(obj.section3[5])]
284    def __set__(self, obj, value):
285        raise RuntimeError

Metadata about the shape of the Earth

class DxSign:
287class DxSign:
288    """Sign of Grid Length in X-Direction"""
289    def __get__(self, obj, objtype=None):
290        if obj.section3[4] in {0,1,203,205,32768,32769} and \
291        obj.section3[17] > obj.section3[20]:
292            return -1.0
293        return 1.0
294    def __set__(self, obj, value):
295        raise RuntimeError

Sign of Grid Length in X-Direction

class DySign:
297class DySign:
298    """Sign of Grid Length in Y-Direction"""
299    def __get__(self, obj, objtype=None):
300        if obj.section3[4] in {0,1,203,205,32768,32769} and \
301        obj.section3[16] > obj.section3[19]:
302            return -1.0
303        return 1.0
304    def __set__(self, obj, value):
305        raise RuntimeError

Sign of Grid Length in Y-Direction

class LLScaleFactor:
307class LLScaleFactor:
308    """Scale Factor for Lats/Lons"""
309    def __get__(self, obj, objtype=None):
310        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
311            llscalefactor = float(obj.section3[14])
312            if llscalefactor == 0:
313                return 1
314            return llscalefactor
315        return 1
316    def __set__(self, obj, value):
317        raise RuntimeError

Scale Factor for Lats/Lons

class LLDivisor:
319class LLDivisor:
320    """Divisor Value for scaling Lats/Lons"""
321    def __get__(self, obj, objtype=None):
322        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
323            lldivisor = float(obj.section3[15])
324            if lldivisor <= 0:
325                return 1.e6
326            return lldivisor
327        return 1.e6
328    def __set__(self, obj, value):
329        raise RuntimeError

Divisor Value for scaling Lats/Lons

class XYDivisor:
331class XYDivisor:
332    """Divisor Value for scaling grid lengths"""
333    def __get__(self, obj, objtype=None):
334        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
335            return obj._lldivisor
336        return 1.e3
337    def __set__(self, obj, value):
338        raise RuntimeError

Divisor Value for scaling grid lengths

class ShapeOfEarth:
340class ShapeOfEarth:
341    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
342    def __get__(self, obj, objtype=None):
343        return Grib2Metadata(obj.section3[5],table='3.2')
344    def __set__(self, obj, value):
345        obj.section3[5] = value
class EarthShape:
347class EarthShape:
348    """Description of the shape of the Earth"""
349    def __get__(self, obj, objtype=None):
350        return obj._earthparams['shape']
351    def __set__(self, obj, value):
352        raise RuntimeError

Description of the shape of the Earth

class EarthRadius:
354class EarthRadius:
355    """Radius of the Earth (Assumes "spherical")"""
356    def __get__(self, obj, objtype=None):
357        ep = obj._earthparams
358        if ep['shape'] == 'spherical':
359            if ep['radius'] is None:
360                return obj.section3[7]/(10.**obj.section3[6])
361            else:
362                return ep['radius']
363        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
364            return None
365    def __set__(self, obj, value):
366        raise RuntimeError

Radius of the Earth (Assumes "spherical")

class EarthMajorAxis:
368class EarthMajorAxis:
369    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
370    def __get__(self, obj, objtype=None):
371        ep = obj._earthparams
372        if ep['shape'] == 'spherical':
373            return None
374        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
375            if ep['major_axis'] is None and ep['minor_axis'] is None:
376                return obj.section3[9]/(10.**obj.section3[8])
377            else:
378                return ep['major_axis']
379    def __set__(self, obj, value):
380        raise RuntimeError

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

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

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

class Nx:
396class Nx:
397    """Number of grid points in the X-direction (generally East-West)"""
398    def __get__(self, obj, objtype=None):
399        return obj.section3[12]
400    def __set__(self, obj, value):
401        obj.section3[12] = value
402        obj.section3[1] = value * obj.section3[13]

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

class Ny:
404class Ny:
405    """Number of grid points in the Y-direction (generally North-South)"""
406    def __get__(self, obj, objtype=None):
407        return obj.section3[13]
408    def __set__(self, obj, value):
409        obj.section3[13] = value
410        obj.section3[1] = value * obj.section3[12]

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

class ScanModeFlags:
412class ScanModeFlags:
413    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
414    _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}
415    def __get__(self, obj, objtype=None):
416        if obj.gdtn == 50:
417            return [None, None, None, None]
418        else:
419            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
420    def __set__(self, obj, value):
421        obj.section3[self._key[obj.gdtn]+5] = value
class ResolutionAndComponentFlags:
423class ResolutionAndComponentFlags:
424    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
425    _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}
426    def __get__(self, obj, objtype=None):
427        if obj.gdtn == 50:
428            return [None for i in range(8)]
429        else:
430            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
431    def __set__(self, obj, value):
432        obj.section3[self._key[obj.gdtn]+5] = value
class LatitudeFirstGridpoint:
434class LatitudeFirstGridpoint:
435    """Latitude of first gridpoint"""
436    _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}
437    def __get__(self, obj, objtype=None):
438        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
439    def __set__(self, obj, value):
440        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of first gridpoint

class LongitudeFirstGridpoint:
442class LongitudeFirstGridpoint:
443    """Longitude of first gridpoint"""
444    _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}
445    def __get__(self, obj, objtype=None):
446        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
447    def __set__(self, obj, value):
448        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of first gridpoint

class LatitudeLastGridpoint:
450class LatitudeLastGridpoint:
451    """Latitude of last gridpoint"""
452    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:19}
453    def __get__(self, obj, objtype=None):
454        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
455    def __set__(self, obj, value):
456        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of last gridpoint

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

Longitude of last gridpoint

class LatitudeCenterGridpoint:
466class LatitudeCenterGridpoint:
467    """Latitude of center gridpoint"""
468    _key = {32768:14, 32769:14}
469    def __get__(self, obj, objtype=None):
470        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
471    def __set__(self, obj, value):
472        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of center gridpoint

class LongitudeCenterGridpoint:
474class LongitudeCenterGridpoint:
475    """Longitude of center gridpoint"""
476    _key = {32768:15, 32769:15}
477    def __get__(self, obj, objtype=None):
478        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
479    def __set__(self, obj, value):
480        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of center gridpoint

class GridlengthXDirection:
482class GridlengthXDirection:
483    """Grid lenth in the X-Direction"""
484    _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}
485    def __get__(self, obj, objtype=None):
486        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
487    def __set__(self, obj, value):
488        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the X-Direction

class GridlengthYDirection:
490class GridlengthYDirection:
491    """Grid lenth in the Y-Direction"""
492    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
493    def __get__(self, obj, objtype=None):
494        if obj.gdtn in {40, 41}:
495            return obj.gridlengthXDirection
496        else:
497            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
498    def __set__(self, obj, value):
499        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the Y-Direction

class NumberOfParallels:
501class NumberOfParallels:
502    """Number of parallels between a pole and the equator"""
503    _key = {40:17, 41:17}
504    def __get__(self, obj, objtype=None):
505        return obj.section3[self._key[obj.gdtn]+5]
506    def __set__(self, obj, value):
507        raise RuntimeError

Number of parallels between a pole and the equator

class LatitudeSouthernPole:
509class LatitudeSouthernPole:
510    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
511    _key = {1:19, 30:20, 31:20, 41:19}
512    def __get__(self, obj, objtype=None):
513        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
514    def __set__(self, obj, value):
515        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class LongitudeSouthernPole:
517class LongitudeSouthernPole:
518    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
519    _key = {1:20, 30:21, 31:21, 41:20}
520    def __get__(self, obj, objtype=None):
521        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
522    def __set__(self, obj, value):
523        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class AnglePoleRotation:
525class AnglePoleRotation:
526    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
527    _key = {1:21, 41:21}
528    def __get__(self, obj, objtype=None):
529        return obj.section3[self._key[obj.gdtn]+5]
530    def __set__(self, obj, value):
531        obj.section3[self._key[obj.gdtn]+5] = int(value)

Angle of Pole Rotation for a Rotated Lat/Lon Grid

class LatitudeTrueScale:
533class LatitudeTrueScale:
534    """Latitude at which grid lengths are specified"""
535    _key = {10:12, 20:12, 30:12, 31:12}
536    def __get__(self, obj, objtype=None):
537        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
538    def __set__(self, obj, value):
539        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude at which grid lengths are specified

class GridOrientation:
541class GridOrientation:
542    """Longitude at which the grid is oriented"""
543    _key = {10:16, 20:13, 30:13, 31:13}
544    def __get__(self, obj, objtype=None):
545        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
546    def __set__(self, obj, value):
547        if obj.gdtn == 10 and (value < 0 or value > 90):
548            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
549        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude at which the grid is oriented

class ProjectionCenterFlag:
551class ProjectionCenterFlag:
552    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
553    _key = {20:16, 30:16, 31:16}
554    def __get__(self, obj, objtype=None):
555        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
556    def __set__(self, obj, value):
557        obj.section3[self._key[obj.gdtn]+5] = value
class StandardLatitude1:
559class StandardLatitude1:
560    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
561    _key = {30:18, 31:18}
562    def __get__(self, obj, objtype=None):
563        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
564    def __set__(self, obj, value):
565        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class StandardLatitude2:
567class StandardLatitude2:
568    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
569    _key = {30:19, 31:19}
570    def __get__(self, obj, objtype=None):
571        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
572    def __set__(self, obj, value):
573        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class SpectralFunctionParameters:
575class SpectralFunctionParameters:
576    """Spectral Function Parameters"""
577    def __get__(self, obj, objtype=None):
578        return obj.section3[0:3]
579    def __set__(self, obj, value):
580        obj.section3[0:3] = value[0:3]

Spectral Function Parameters

class ProjParameters:
582class ProjParameters:
583    """PROJ Parameters to define the reference system"""
584    def __get__(self, obj, objtype=None):
585        projparams = {}
586        projparams['a'] = 1.0
587        projparams['b'] = 1.0
588        if obj.earthRadius is not None:
589            projparams['a'] = obj.earthRadius
590            projparams['b'] = obj.earthRadius
591        else:
592            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
593            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
594        if obj.gdtn == 0:
595            projparams['proj'] = 'longlat'
596        elif obj.gdtn == 1:
597            projparams['o_proj'] = 'longlat'
598            projparams['proj'] = 'ob_tran'
599            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
600            projparams['o_lon_p'] = obj.anglePoleRotation
601            projparams['lon_0'] = obj.longitudeSouthernPole
602        elif obj.gdtn == 10:
603            projparams['proj'] = 'merc'
604            projparams['lat_ts'] = obj.latitudeTrueScale
605            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
606        elif obj.gdtn == 20:
607            if obj.projectionCenterFlag == 0:
608                lat0 = 90.0
609            elif obj.projectionCenterFlag == 1:
610                lat0 = -90.0
611            projparams['proj'] = 'stere'
612            projparams['lat_ts'] = obj.latitudeTrueScale
613            projparams['lat_0'] = lat0
614            projparams['lon_0'] = obj.gridOrientation
615        elif obj.gdtn == 30:
616            projparams['proj'] = 'lcc'
617            projparams['lat_1'] = obj.standardLatitude1
618            projparams['lat_2'] = obj.standardLatitude2
619            projparams['lat_0'] = obj.latitudeTrueScale
620            projparams['lon_0'] = obj.gridOrientation
621        elif obj.gdtn == 31:
622            projparams['proj'] = 'aea'
623            projparams['lat_1'] = obj.standardLatitude1
624            projparams['lat_2'] = obj.standardLatitude2
625            projparams['lat_0'] = obj.latitudeTrueScale
626            projparams['lon_0'] = obj.gridOrientation
627        elif obj.gdtn == 40:
628            projparams['proj'] = 'eqc'
629        elif obj.gdtn == 32769:
630            projparams['proj'] = 'aeqd'
631            projparams['lon_0'] = obj.longitudeCenterGridpoint
632            projparams['lat_0'] = obj.latitudeCenterGridpoint
633        return projparams
634    def __set__(self, obj, value):
635        raise RuntimeError

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate0:
637@dataclass(init=False)
638class GridDefinitionTemplate0:
639    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
640    _len = 19
641    _num = 0
642    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
643    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
644    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
645    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
646    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
647    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
648    @classmethod
649    @property
650    def _attrs(cls):
651        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

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

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

latitudeSouthernPole: float

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

longitudeSouthernPole: float

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

anglePoleRotation: float

Angle of Pole Rotation for a Rotated Lat/Lon Grid

@dataclass(init=False)
class GridDefinitionTemplate10:
672@dataclass(init=False)
673class GridDefinitionTemplate10:
674    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
675    _len = 19
676    _num = 10
677    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
678    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
679    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
680    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
681    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
682    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
683    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
684    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
685    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
686    @classmethod
687    @property
688    def _attrs(cls):
689        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projParameters: dict

PROJ Parameters to define the reference system

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

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
projParameters: dict

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate30:
709@dataclass(init=False)
710class GridDefinitionTemplate30:
711    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
712    _len = 22
713    _num = 30
714    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
715    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
716    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
717    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
718    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
719    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
720    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
721    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
722    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
723    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
724    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
725    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
726    @classmethod
727    @property
728    def _attrs(cls):
729        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
standardLatitude1: float

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

standardLatitude2: float

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

latitudeSouthernPole: float

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

longitudeSouthernPole: float

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

projParameters: dict

PROJ Parameters to define the reference system

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

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeTrueScale: float

Latitude at which grid lengths are specified

gridOrientation: float

Longitude at which the grid is oriented

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

projectionCenterFlag: list
standardLatitude1: float

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

standardLatitude2: float

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

latitudeSouthernPole: float

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

longitudeSouthernPole: float

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

@dataclass(init=False)
class GridDefinitionTemplate40:
752@dataclass(init=False)
753class GridDefinitionTemplate40:
754    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
755    _len = 19
756    _num = 40
757    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
758    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
759    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
760    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
761    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
762    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
763    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
764    @classmethod
765    @property
766    def _attrs(cls):
767        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

numberOfParallels: int

Number of parallels between a pole and the equator

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

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

numberOfParallels: int

Number of parallels between a pole and the equator

latitudeSouthernPole: float

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

longitudeSouthernPole: float

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

anglePoleRotation: float

Angle of Pole Rotation for a Rotated Lat/Lon Grid

@dataclass(init=False)
class GridDefinitionTemplate50:
789@dataclass(init=False)
790class GridDefinitionTemplate50:
791    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
792    _len = 5
793    _num = 50
794    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
795    @classmethod
796    @property
797    def _attrs(cls):
798        return list(cls.__dataclass_fields__.keys())
spectralFunctionParameters: list

Spectral Function Parameters

@dataclass(init=False)
class GridDefinitionTemplate32768:
800@dataclass(init=False)
801class GridDefinitionTemplate32768:
802    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
803    _len = 19
804    _num = 32768
805    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
806    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
807    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
808    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
809    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
810    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
811    @classmethod
812    @property
813    def _attrs(cls):
814        return list(cls.__dataclass_fields__.keys())
latitudeFirstGridpoint: float

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeCenterGridpoint: float

Latitude of center gridpoint

longitudeCenterGridpoint: float

Longitude of center gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

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

Latitude of first gridpoint

longitudeFirstGridpoint: float

Longitude of first gridpoint

latitudeCenterGridpoint: float

Latitude of center gridpoint

longitudeCenterGridpoint: float

Longitude of center gridpoint

gridlengthXDirection: float

Grid lenth in the X-Direction

gridlengthYDirection: float

Grid lenth in the Y-Direction

latitudeLastGridpoint: float

Latitude of last gridpoint

longitudeLastGridpoint: float

Longitude of last gridpoint

def gdt_class_by_gdtn(gdtn: int):
847def gdt_class_by_gdtn(gdtn: int):
848    """
849    Provides a Grid Definition Template class via the template number
850
851    Parameters
852    ----------
853    gdtn
854        Grid definition template number.
855
856    Returns
857    -------
858    gdt_class_by_gdtn
859        Grid definition template class object (not an instance).
860    """
861    return _gdt_by_gdtn[gdtn]

Provides a Grid Definition Template class via the template number

Parameters
  • gdtn: Grid definition template number.
Returns
  • gdt_class_by_gdtn: Grid definition template class object (not an instance).
class ProductDefinitionTemplateNumber:
866class ProductDefinitionTemplateNumber:
867    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
868    def __get__(self, obj, objtype=None):
869        return Grib2Metadata(obj.section4[1],table='4.0')
870    def __set__(self, obj, value):
871        raise RuntimeError
class ProductDefinitionTemplate:
874class ProductDefinitionTemplate:
875    """Product Definition Template"""
876    def __get__(self, obj, objtype=None):
877        return obj.section4[2:]
878    def __set__(self, obj, value):
879        raise RuntimeError

Product Definition Template

class ParameterCategory:
881class ParameterCategory:
882    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
883    _key = defaultdict(lambda: 0)
884    def __get__(self, obj, objtype=None):
885        return obj.section4[0+2]
886    def __set__(self, obj, value):
887        obj.section4[self._key[obj.pdtn]+2] = value
class ParameterNumber:
889class ParameterNumber:
890    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
891    _key = defaultdict(lambda: 1)
892    def __get__(self, obj, objtype=None):
893        return obj.section4[1+2]
894    def __set__(self, obj, value):
895        obj.section4[self._key[obj.pdtn]+2] = value
class VarInfo:
897class VarInfo:
898    """
899    Variable Information.
900
901    These are the metadata returned for a specific variable according to
902    discipline, parameter category, and parameter number.
903    """
904    def __get__(self, obj, objtype=None):
905        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
906    def __set__(self, obj, value):
907        raise RuntimeError

Variable Information.

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

class FullName:
909class FullName:
910    """Full name of the Variable."""
911    def __get__(self, obj, objtype=None):
912        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
913    def __set__(self, obj, value):
914        raise RuntimeError

Full name of the Variable.

class Units:
916class Units:
917    """Units of the Variable."""
918    def __get__(self, obj, objtype=None):
919        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
920    def __set__(self, obj, value):
921        raise RuntimeError

Units of the Variable.

class ShortName:
923class ShortName:
924    """ Short name of the variable (i.e. the variable abbreviation)."""
925    def __get__(self, obj, objtype=None):
926        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[2]
927    def __set__(self, obj, value):
928        raise RuntimeError

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

class TypeOfGeneratingProcess:
930class TypeOfGeneratingProcess:
931    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
932    _key = defaultdict(lambda: 2, {48:13})
933    #_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}
934    def __get__(self, obj, objtype=None):
935        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
936    def __set__(self, obj, value):
937        obj.section4[self._key[obj.pdtn]+2] = value
class BackgroundGeneratingProcessIdentifier:
939class BackgroundGeneratingProcessIdentifier:
940    """Background Generating Process Identifier"""
941    _key = defaultdict(lambda: 3, {48:14})
942    #_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}
943    def __get__(self, obj, objtype=None):
944        return obj.section4[self._key[obj.pdtn]+2]
945    def __set__(self, obj, value):
946        obj.section4[self._key[obj.pdtn]+2] = value

Background Generating Process Identifier

class GeneratingProcess:
948class GeneratingProcess:
949    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
950    _key = defaultdict(lambda: 4, {48:15})
951    #_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}
952    def __get__(self, obj, objtype=None):
953        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
954    def __set__(self, obj, value):
955        obj.section4[self._key[obj.pdtn]+2] = value
class HoursAfterDataCutoff:
957class HoursAfterDataCutoff:
958    """Hours of observational data cutoff after reference time."""
959    _key = defaultdict(lambda: 5, {48:16})
960    def __get__(self, obj, objtype=None):
961        return obj.section4[self._key[obj.pdtn]+2]
962    def __set__(self, obj, value):
963        obj.section4[self._key[obj.pdtn]+2] = value

Hours of observational data cutoff after reference time.

class MinutesAfterDataCutoff:
965class MinutesAfterDataCutoff:
966    """Minutes of observational data cutoff after reference time."""
967    _key = defaultdict(lambda: 6, {48:17})
968    def __get__(self, obj, objtype=None):
969        return obj.section4[self._key[obj.pdtn]+2]
970    def __set__(self, obj, value):
971        obj.section4[self._key[obj.pdtn]+2] = value

Minutes of observational data cutoff after reference time.

class UnitOfForecastTime:
973class UnitOfForecastTime:
974    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
975    _key = defaultdict(lambda: 7, {48:18})
976    #_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}
977    def __get__(self, obj, objtype=None):
978        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
979    def __set__(self, obj, value):
980        obj.section4[self._key[obj.pdtn]+2] = value
class ValueOfForecastTime:
982class ValueOfForecastTime:
983    """Value of forecast time in units defined by `UnitofForecastTime`."""
984    _key = defaultdict(lambda: 8, {48:19})
985    def __get__(self, obj, objtype=None):
986        return obj.section4[self._key[obj.pdtn]+2]
987    def __set__(self, obj, value):
988        obj.section4[self._key[obj.pdtn]+2] = value

Value of forecast time in units defined by UnitofForecastTime.

class LeadTime:
 990class LeadTime:
 991    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
 992    def __get__(self, obj, objtype=None):
 993        return utils.get_leadtime(obj.section1,obj.section4[1],
 994                                  obj.section4[2:])
 995    def __set__(self, obj, value):
 996        pdt = obj.section4[2:]
 997
 998        _key = {
 999            8: slice(15, 21),
1000            9: slice(22, 28),
1001            10: slice(16, 22),
1002            11: slice(18, 24),
1003            12: slice(17, 23),
1004        }
1005        refdate = datetime.datetime(*obj.section1[5:11])
1006        ivalue = int(timedelta64(value, "h") / timedelta64(1, "h"))
1007        try:
1008            pdt[_key[obj.pdtn]] = (
1009                datetime.timedelta(hours=ivalue) + refdate
1010            ).timetuple()[:5]
1011        except KeyError:
1012            if obj.pdtn == 48:
1013                pdt[19] = ivalue / (
1014                    tables.get_value_from_table(pdt[18], "scale_time_hours")
1015                )
1016            else:
1017                pdt[8] = ivalue / (
1018                    tables.get_value_from_table(pdt[7], "scale_time_hours")
1019                )

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

class FixedSfc1Info:
1021class FixedSfc1Info:
1022    """Information of the first fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1023    _key = defaultdict(lambda: 9, {48:20})
1024    #_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}
1025    def __get__(self, obj, objtype=None):
1026        if obj.section4[self._key[obj.pdtn]+2] == 255:
1027            return [None, None]
1028        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1029    def __set__(self, obj, value):
1030        raise NotImplementedError

Information of the first fixed surface via table 4.5

class FixedSfc2Info:
1032class FixedSfc2Info:
1033    """Information of the second fixed surface via [table 4.5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1034    _key = defaultdict(lambda: 12, {48:23})
1035    #_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}
1036    def __get__(self, obj, objtype=None):
1037        if obj.section4[self._key[obj.pdtn]+2] == 255:
1038            return [None, None]
1039        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1040    def __set__(self, obj, value):
1041        raise NotImplementedError

Information of the second fixed surface via table 4.5

class TypeOfFirstFixedSurface:
1043class TypeOfFirstFixedSurface:
1044    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1045    _key = defaultdict(lambda: 9, {48:20})
1046    #_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}
1047    def __get__(self, obj, objtype=None):
1048        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1049    def __set__(self, obj, value):
1050        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstFixedSurface:
1052class ScaleFactorOfFirstFixedSurface:
1053    """Scale Factor of First Fixed Surface"""
1054    _key = defaultdict(lambda: 10, {48:21})
1055    #_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}
1056    def __get__(self, obj, objtype=None):
1057        return obj.section4[self._key[obj.pdtn]+2]
1058    def __set__(self, obj, value):
1059        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Fixed Surface

class ScaledValueOfFirstFixedSurface:
1061class ScaledValueOfFirstFixedSurface:
1062    """Scaled Value Of First Fixed Surface"""
1063    _key = defaultdict(lambda: 11, {48:22})
1064    #_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}
1065    def __get__(self, obj, objtype=None):
1066        return obj.section4[self._key[obj.pdtn]+2]
1067    def __set__(self, obj, value):
1068        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of First Fixed Surface

class UnitOfFirstFixedSurface:
1070class UnitOfFirstFixedSurface:
1071    """Units of First Fixed Surface"""
1072    def __get__(self, obj, objtype=None):
1073        return obj._fixedsfc1info[1]
1074    def __set__(self, obj, value):
1075        pass

Units of First Fixed Surface

class ValueOfFirstFixedSurface:
1077class ValueOfFirstFixedSurface:
1078    """Value of First Fixed Surface"""
1079    def __get__(self, obj, objtype=None):
1080        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn] + 2] / (
1081            10.0 ** obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn] + 2]
1082        )
1083    def __set__(self, obj, value):
1084        obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn] + 2] = value * (
1085            10.0 ** obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn] + 2]
1086        )

Value of First Fixed Surface

class TypeOfSecondFixedSurface:
1088class TypeOfSecondFixedSurface:
1089    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1090    _key = defaultdict(lambda: 12, {48:23})
1091    #_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}
1092    def __get__(self, obj, objtype=None):
1093        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1094    def __set__(self, obj, value):
1095        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfSecondFixedSurface:
1097class ScaleFactorOfSecondFixedSurface:
1098    """Scale Factor of Second Fixed Surface"""
1099    _key = defaultdict(lambda: 13, {48:24})
1100    #_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}
1101    def __get__(self, obj, objtype=None):
1102        return obj.section4[self._key[obj.pdtn]+2]
1103    def __set__(self, obj, value):
1104        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Fixed Surface

class ScaledValueOfSecondFixedSurface:
1106class ScaledValueOfSecondFixedSurface:
1107    """Scaled Value Of Second Fixed Surface"""
1108    _key = defaultdict(lambda: 14, {48:25})
1109    #_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}
1110    def __get__(self, obj, objtype=None):
1111        return obj.section4[self._key[obj.pdtn]+2]
1112    def __set__(self, obj, value):
1113        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of Second Fixed Surface

class UnitOfSecondFixedSurface:
1115class UnitOfSecondFixedSurface:
1116    """Units of Second Fixed Surface"""
1117    def __get__(self, obj, objtype=None):
1118        return obj._fixedsfc2info[1]
1119    def __set__(self, obj, value):
1120        pass

Units of Second Fixed Surface

class ValueOfSecondFixedSurface:
1122class ValueOfSecondFixedSurface:
1123    """Value of Second Fixed Surface"""
1124    def __get__(self, obj, objtype=None):
1125        return obj.section4[ScaledValueOfFirstFixedSurface._key[obj.pdtn]+2]/\
1126                            (10.**obj.section4[ScaleFactorOfFirstFixedSurface._key[obj.pdtn]+2])
1127    def __set__(self, obj, value):
1128        pass

Value of Second Fixed Surface

class Level:
1130class Level:
1131    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1132    def __get__(self, obj, objtype=None):
1133        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1134    def __set__(self, obj, value):
1135        pass

Level (same as provided by wgrib2)

class TypeOfEnsembleForecast:
1137class TypeOfEnsembleForecast:
1138    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1139    _key = {1:15, 11:15}
1140    def __get__(self, obj, objtype=None):
1141        pdtn = obj.section4[1]
1142        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1143    def __set__(self, obj, value):
1144        pdtn = obj.section4[1]
1145        obj.section4[self._key[pdtn]+2] = value
class PerturbationNumber:
1147class PerturbationNumber:
1148    """Ensemble Perturbation Number"""
1149    _key = {1:16, 11:16}
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

Ensemble Perturbation Number

class NumberOfEnsembleForecasts:
1157class NumberOfEnsembleForecasts:
1158    """Total Number of Ensemble Forecasts"""
1159    _key = {1:17, 2:16, 11:17, 12:16}
1160    def __get__(self, obj, objtype=None):
1161        pdtn = obj.section4[1]
1162        return obj.section4[self._key[pdtn]+2]
1163    def __set__(self, obj, value):
1164        pdtn = obj.section4[1]
1165        obj.section4[self._key[pdtn]+2] = value

Total Number of Ensemble Forecasts

class TypeOfDerivedForecast:
1167class TypeOfDerivedForecast:
1168    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1169    _key = {2:15, 12:15}
1170    def __get__(self, obj, objtype=None):
1171        pdtn = obj.section4[1]
1172        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1173    def __set__(self, obj, value):
1174        pdtn = obj.section4[1]
1175        obj.section4[self._key[pdtn]+2] = value
class ForecastProbabilityNumber:
1177class ForecastProbabilityNumber:
1178    """Forecast Probability Number"""
1179    _key = {5:15, 9:15}
1180    def __get__(self, obj, objtype=None):
1181        pdtn = obj.section4[1]
1182        return obj.section4[self._key[pdtn]+2]
1183    def __set__(self, obj, value):
1184        pdtn = obj.section4[1]
1185        obj.section4[self._key[pdtn]+2] = value

Forecast Probability Number

class TotalNumberOfForecastProbabilities:
1187class TotalNumberOfForecastProbabilities:
1188    """Total Number of Forecast Probabilities"""
1189    _key = {5:16, 9:16}
1190    def __get__(self, obj, objtype=None):
1191        pdtn = obj.section4[1]
1192        return obj.section4[self._key[pdtn]+2]
1193    def __set__(self, obj, value):
1194        pdtn = obj.section4[1]
1195        obj.section4[self._key[pdtn]+2] = value

Total Number of Forecast Probabilities

class TypeOfProbability:
1197class TypeOfProbability:
1198    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1199    _key = {5:17, 9:17}
1200    def __get__(self, obj, objtype=None):
1201        pdtn = obj.section4[1]
1202        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1203    def __set__(self, obj, value):
1204        pdtn = obj.section4[1]
1205        obj.section4[self._key[pdtn]+2] = value
class ScaleFactorOfThresholdLowerLimit:
1207class ScaleFactorOfThresholdLowerLimit:
1208    """Scale Factor of Threshold Lower Limit"""
1209    _key = {5:18, 9:18}
1210    def __get__(self, obj, objtype=None):
1211        pdtn = obj.section4[1]
1212        return obj.section4[self._key[pdtn]+2]
1213    def __set__(self, obj, value):
1214        pdtn = obj.section4[1]
1215        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Lower Limit

class ScaledValueOfThresholdLowerLimit:
1217class ScaledValueOfThresholdLowerLimit:
1218    """Scaled Value of Threshold Lower Limit"""
1219    _key = {5:19, 9:19}
1220    def __get__(self, obj, objtype=None):
1221        pdtn = obj.section4[1]
1222        return obj.section4[self._key[pdtn]+2]
1223    def __set__(self, obj, value):
1224        pdtn = obj.section4[1]
1225        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Lower Limit

class ScaleFactorOfThresholdUpperLimit:
1227class ScaleFactorOfThresholdUpperLimit:
1228    """Scale Factor of Threshold Upper Limit"""
1229    _key = {5:20, 9:20}
1230    def __get__(self, obj, objtype=None):
1231        pdtn = obj.section4[1]
1232        return obj.section4[self._key[pdtn]+2]
1233    def __set__(self, obj, value):
1234        pdtn = obj.section4[1]
1235        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Upper Limit

class ScaledValueOfThresholdUpperLimit:
1237class ScaledValueOfThresholdUpperLimit:
1238    """Scaled Value of Threshold Upper Limit"""
1239    _key = {5:21, 9:21}
1240    def __get__(self, obj, objtype=None):
1241        pdtn = obj.section4[1]
1242        return obj.section4[self._key[pdtn]+2]
1243    def __set__(self, obj, value):
1244        pdtn = obj.section4[1]
1245        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Upper Limit

class ThresholdLowerLimit:
1247class ThresholdLowerLimit:
1248    """Threshold Lower Limit"""
1249    def __get__(self, obj, objtype=None):
1250        if obj.section4[18+2] == -127 and \
1251           obj.section4[19+2] == 255:
1252            return 0.0
1253        else:
1254            return obj.section4[19+2]/(10.**obj.section4[18+2])
1255    def __set__(self, obj, value):
1256        pass

Threshold Lower Limit

class ThresholdUpperLimit:
1258class ThresholdUpperLimit:
1259    """Threshold Upper Limit"""
1260    def __get__(self, obj, objtype=None):
1261        if obj.section4[20+2] == -127 and \
1262           obj.section4[21+2] == 255:
1263            return 0.0
1264        else:
1265            return obj.section4[21+2]/(10.**obj.section4[20+2])
1266    def __set__(self, obj, value):
1267        pass

Threshold Upper Limit

class Threshold:
1269class Threshold:
1270    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1271    def __get__(self, obj, objtype=None):
1272        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1273    def __set__(self, obj, value):
1274        pass

Threshold string (same as wgrib2)

class PercentileValue:
1276class PercentileValue:
1277    """Percentile Value"""
1278    _key = {6:15, 10:15}
1279    def __get__(self, obj, objtype=None):
1280        pdtn = obj.section4[1]
1281        return obj.section4[self._key[pdtn]+2]
1282    def __set__(self, obj, value):
1283        pdtn = obj.section4[1]
1284        obj.section4[self._key[pdtn]+2] = value

Percentile Value

class YearOfEndOfTimePeriod:
1286class YearOfEndOfTimePeriod:
1287    """Year of End of Forecast Time Period"""
1288    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1289    def __get__(self, obj, objtype=None):
1290        pdtn = obj.section4[1]
1291        return obj.section4[self._key[pdtn]+2]
1292    def __set__(self, obj, value):
1293        pdtn = obj.section4[1]
1294        obj.section4[self._key[pdtn]+2] = value

Year of End of Forecast Time Period

class MonthOfEndOfTimePeriod:
1296class MonthOfEndOfTimePeriod:
1297    """Month Year of End of Forecast Time Period"""
1298    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1299    def __get__(self, obj, objtype=None):
1300        pdtn = obj.section4[1]
1301        return obj.section4[self._key[pdtn]+2]
1302    def __set__(self, obj, value):
1303        pdtn = obj.section4[1]
1304        obj.section4[self._key[pdtn]+2] = value

Month Year of End of Forecast Time Period

class DayOfEndOfTimePeriod:
1306class DayOfEndOfTimePeriod:
1307    """Day Year of End of Forecast Time Period"""
1308    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1309    def __get__(self, obj, objtype=None):
1310        pdtn = obj.section4[1]
1311        return obj.section4[self._key[pdtn]+2]
1312    def __set__(self, obj, value):
1313        pdtn = obj.section4[1]
1314        obj.section4[self._key[pdtn]+2] = value

Day Year of End of Forecast Time Period

class HourOfEndOfTimePeriod:
1316class HourOfEndOfTimePeriod:
1317    """Hour Year of End of Forecast Time Period"""
1318    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1319    def __get__(self, obj, objtype=None):
1320        pdtn = obj.section4[1]
1321        return obj.section4[self._key[pdtn]+2]
1322    def __set__(self, obj, value):
1323        pdtn = obj.section4[1]
1324        obj.section4[self._key[pdtn]+2] = value

Hour Year of End of Forecast Time Period

class MinuteOfEndOfTimePeriod:
1326class MinuteOfEndOfTimePeriod:
1327    """Minute Year of End of Forecast Time Period"""
1328    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1329    def __get__(self, obj, objtype=None):
1330        pdtn = obj.section4[1]
1331        return obj.section4[self._key[pdtn]+2]
1332    def __set__(self, obj, value):
1333        pdtn = obj.section4[1]
1334        obj.section4[self._key[pdtn]+2] = value

Minute Year of End of Forecast Time Period

class SecondOfEndOfTimePeriod:
1336class SecondOfEndOfTimePeriod:
1337    """Second Year of End of Forecast Time Period"""
1338    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1339    def __get__(self, obj, objtype=None):
1340        pdtn = obj.section4[1]
1341        return obj.section4[self._key[pdtn]+2]
1342    def __set__(self, obj, value):
1343        pdtn = obj.section4[1]
1344        obj.section4[self._key[pdtn]+2] = value

Second Year of End of Forecast Time Period

class Duration:
1346class Duration:
1347    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1348    def __get__(self, obj, objtype=None):
1349        return utils.get_duration(obj.section4[1],obj.section4[2:])
1350    def __set__(self, obj, value):
1351        pass

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

class ValidDate:
1353class ValidDate:
1354    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1355    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1356    def __get__(self, obj, objtype=None):
1357        pdtn = obj.section4[1]
1358        try:
1359            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1360            return datetime.datetime(*obj.section4[s])
1361        except(KeyError):
1362            return obj.refDate + obj.leadTime
1363    def __set__(self, obj, value):
1364        pass

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

class NumberOfTimeRanges:
1366class NumberOfTimeRanges:
1367    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1368    _key = {8:21, 9:28, 10:22, 11:24, 12:23}
1369    def __get__(self, obj, objtype=None):
1370        pdtn = obj.section4[1]
1371        return obj.section4[self._key[pdtn]+2]
1372    def __set__(self, obj, value):
1373        pdtn = obj.section4[1]
1374        obj.section4[self._key[pdtn]+2] = value

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

class NumberOfMissingValues:
1376class NumberOfMissingValues:
1377    """Total number of data values missing in statistical process"""
1378    _key = {8:22, 9:29, 10:23, 11:25, 12:24}
1379    def __get__(self, obj, objtype=None):
1380        pdtn = obj.section4[1]
1381        return obj.section4[self._key[pdtn]+2]
1382    def __set__(self, obj, value):
1383        pdtn = obj.section4[1]
1384        obj.section4[self._key[pdtn]+2] = value

Total number of data values missing in statistical process

class StatisticalProcess:
1386class StatisticalProcess:
1387    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1388    _key = {8:23, 9:30, 10:24, 11:26, 12:25, 15:15}
1389    def __get__(self, obj, objtype=None):
1390        pdtn = obj.section4[1]
1391        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.10')
1392    def __set__(self, obj, value):
1393        pdtn = obj.section4[1]
1394        obj.section4[self._key[pdtn]+2] = value
class TypeOfTimeIncrementOfStatisticalProcess:
1396class TypeOfTimeIncrementOfStatisticalProcess:
1397    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1398    _key = {8:24, 9:31, 10:25, 11:27, 12:26}
1399    def __get__(self, obj, objtype=None):
1400        pdtn = obj.section4[1]
1401        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.11')
1402    def __set__(self, obj, value):
1403        pdtn = obj.section4[1]
1404        obj.section4[self._key[pdtn]+2] = value
class UnitOfTimeRangeOfStatisticalProcess:
1406class UnitOfTimeRangeOfStatisticalProcess:
1407    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1408    _key = {8:25, 9:32, 10:26, 11:28, 12:27}
1409    def __get__(self, obj, objtype=None):
1410        pdtn = obj.section4[1]
1411        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1412    def __set__(self, obj, value):
1413        pdtn = obj.section4[1]
1414        obj.section4[self._key[pdtn]+2] = value
class TimeRangeOfStatisticalProcess:
1416class TimeRangeOfStatisticalProcess:
1417    """Time Range of Statistical Process"""
1418    _key = {8:26, 9:33, 10:27, 11:29, 12:28}
1419    def __get__(self, obj, objtype=None):
1420        pdtn = obj.section4[1]
1421        return obj.section4[self._key[pdtn]+2]
1422    def __set__(self, obj, value):
1423        pdtn = obj.section4[1]
1424        obj.section4[self._key[pdtn]+2] = value

Time Range of Statistical Process

class UnitOfTimeRangeOfSuccessiveFields:
1426class UnitOfTimeRangeOfSuccessiveFields:
1427    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1428    _key = {8:27, 9:34, 10:28, 11:30, 12:29}
1429    def __get__(self, obj, objtype=None):
1430        pdtn = obj.section4[1]
1431        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.4')
1432    def __set__(self, obj, value):
1433        pdtn = obj.section4[1]
1434        obj.section4[self._key[pdtn]+2] = value
class TimeIncrementOfSuccessiveFields:
1436class TimeIncrementOfSuccessiveFields:
1437    """Time Increment of Successive Fields"""
1438    _key = {8:28, 9:35, 10:29, 11:31, 12:30}
1439    def __get__(self, obj, objtype=None):
1440        pdtn = obj.section4[1]
1441        return obj.section4[self._key[pdtn]+2]
1442    def __set__(self, obj, value):
1443        pdtn = obj.section4[1]
1444        obj.section4[self._key[pdtn]+2] = value

Time Increment of Successive Fields

class TypeOfStatisticalProcessing:
1446class TypeOfStatisticalProcessing:
1447    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1448    _key = {15:16}
1449    def __get__(self, obj, objtype=None):
1450        pdtn = obj.section4[1]
1451        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1452    def __set__(self, obj, value):
1453        pdtn = obj.section4[1]
1454        obj.section4[self._key[pdtn]+2] = value
class NumberOfDataPointsForSpatialProcessing:
1456class NumberOfDataPointsForSpatialProcessing:
1457    """Number of Data Points for Spatial Processing"""
1458    _key = {15:17}
1459    def __get__(self, obj, objtype=None):
1460        pdtn = obj.section4[1]
1461        return obj.section4[self._key[pdtn]+2]
1462    def __set__(self, obj, value):
1463        pdtn = obj.section4[1]
1464        obj.section4[self._key[pdtn]+2] = value

Number of Data Points for Spatial Processing

class NumberOfContributingSpectralBands:
1466class NumberOfContributingSpectralBands:
1467    """Number of Contributing Spectral Bands (NB)"""
1468    _key = {32:9}
1469    def __get__(self, obj, objtype=None):
1470        pdtn = obj.section4[1]
1471        return obj.section4[self._key[pdtn]+2]
1472    def __set__(self, obj, value):
1473        pdtn = obj.section4[1]
1474        obj.section4[self._key[pdtn]+2] = value

Number of Contributing Spectral Bands (NB)

class SatelliteSeries:
1476class SatelliteSeries:
1477    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1478    _key = {32:10}
1479    def __get__(self, obj, objtype=None):
1480        pdtn = obj.section4[1]
1481        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1482    def __set__(self, obj, value):
1483        pass

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

class SatelliteNumber:
1485class SatelliteNumber:
1486    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1487    _key = {32:11}
1488    def __get__(self, obj, objtype=None):
1489        pdtn = obj.section4[1]
1490        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1491    def __set__(self, obj, value):
1492        pass

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

class InstrumentType:
1494class InstrumentType:
1495    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1496    _key = {32:12}
1497    def __get__(self, obj, objtype=None):
1498        pdtn = obj.section4[1]
1499        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1500    def __set__(self, obj, value):
1501        pass

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

class ScaleFactorOfCentralWaveNumber:
1503class ScaleFactorOfCentralWaveNumber:
1504    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1505    _key = {32:13}
1506    def __get__(self, obj, objtype=None):
1507        pdtn = obj.section4[1]
1508        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1509    def __set__(self, obj, value):
1510        pass

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

class ScaledValueOfCentralWaveNumber:
1512class ScaledValueOfCentralWaveNumber:
1513    """Scaled Value Of Central WaveNumber of band NB"""
1514    _key = {32:14}
1515    def __get__(self, obj, objtype=None):
1516        pdtn = obj.section4[1]
1517        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1518    def __set__(self, obj, value):
1519        pass

Scaled Value Of Central WaveNumber of band NB

class TypeOfAerosol:
1521class TypeOfAerosol:
1522    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1523    _key = {48:2}
1524    def __get__(self, obj, objtype=None):
1525        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1526    def __set__(self, obj, value):
1527        obj.section4[self._key[obj.pdtn]+2] = value
class TypeOfIntervalForAerosolSize:
1529class TypeOfIntervalForAerosolSize:
1530    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1531    _key = {48:3}
1532    def __get__(self, obj, objtype=None):
1533        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1534    def __set__(self, obj, value):
1535        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstSize:
1537class ScaleFactorOfFirstSize:
1538    """Scale Factor of First Size"""
1539    _key = {48:4}
1540    def __get__(self, obj, objtype=None):
1541        return obj.section4[self._key[obj.pdtn]+2]
1542    def __set__(self, obj, value):
1543        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Size

class ScaledValueOfFirstSize:
1545class ScaledValueOfFirstSize:
1546    """Scaled Value of First Size"""
1547    _key = {48:5}
1548    def __get__(self, obj, objtype=None):
1549        return obj.section4[self._key[obj.pdtn]+2]
1550    def __set__(self, obj, value):
1551        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Size

class ScaleFactorOfSecondSize:
1553class ScaleFactorOfSecondSize:
1554    """Scale Factor of Second Size"""
1555    _key = {48:6}
1556    def __get__(self, obj, objtype=None):
1557        return obj.section4[self._key[obj.pdtn]+2]
1558    def __set__(self, obj, value):
1559        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Size

class ScaledValueOfSecondSize:
1561class ScaledValueOfSecondSize:
1562    """Scaled Value of Second Size"""
1563    _key = {48:7}
1564    def __get__(self, obj, objtype=None):
1565        return obj.section4[self._key[obj.pdtn]+2]
1566    def __set__(self, obj, value):
1567        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Size

class TypeOfIntervalForAerosolWavelength:
1569class TypeOfIntervalForAerosolWavelength:
1570    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1571    _key = {48:8}
1572    def __get__(self, obj, objtype=None):
1573        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1574    def __set__(self, obj, value):
1575        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstWavelength:
1577class ScaleFactorOfFirstWavelength:
1578    """Scale Factor of First Wavelength"""
1579    _key = {48:9}
1580    def __get__(self, obj, objtype=None):
1581        return obj.section4[self._key[obj.pdtn]+2]
1582    def __set__(self, obj, value):
1583        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Wavelength

class ScaledValueOfFirstWavelength:
1585class ScaledValueOfFirstWavelength:
1586    """Scaled Value of First Wavelength"""
1587    _key = {48:10}
1588    def __get__(self, obj, objtype=None):
1589        return obj.section4[self._key[obj.pdtn]+2]
1590    def __set__(self, obj, value):
1591        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Wavelength

class ScaleFactorOfSecondWavelength:
1593class ScaleFactorOfSecondWavelength:
1594    """Scale Factor of Second Wavelength"""
1595    _key = {48:11}
1596    def __get__(self, obj, objtype=None):
1597        return obj.section4[self._key[obj.pdtn]+2]
1598    def __set__(self, obj, value):
1599        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Wavelength

class ScaledValueOfSecondWavelength:
1601class ScaledValueOfSecondWavelength:
1602    """Scaled Value of Second Wavelength"""
1603    _key = {48:12}
1604    def __get__(self, obj, objtype=None):
1605        return obj.section4[self._key[obj.pdtn]+2]
1606    def __set__(self, obj, value):
1607        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplateBase:
1613@dataclass(init=False)
1614class ProductDefinitionTemplateBase:
1615    """Base attributes for Product Definition Templates"""
1616    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1617    fullName: str = field(init=False, repr=False, default=FullName())
1618    units: str = field(init=False, repr=False, default=Units())
1619    shortName: str = field(init=False, repr=False, default=ShortName())
1620    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1621    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1622    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1623    level: str = field(init=False, repr=False, default=Level())
1624    # Begin template here...
1625    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1626    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1627    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1628    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1629    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1630    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1631    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1632    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1633    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1634    @classmethod
1635    @property
1636    def _attrs(cls):
1637        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]

Base attributes for Product Definition Templates

fullName: str

Full name of the Variable.

units: str

Units of the Variable.

shortName: str

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

leadTime: datetime.timedelta

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

duration: datetime.timedelta

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

validDate: datetime.datetime

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

level: str

Level (same as provided by wgrib2)

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

Background Generating Process Identifier

hoursAfterDataCutoff: int

Hours of observational data cutoff after reference time.

minutesAfterDataCutoff: int

Minutes of observational data cutoff after reference time.

valueOfForecastTime: int

Value of forecast time in units defined by UnitofForecastTime.

@dataclass(init=False)
class ProductDefinitionTemplateSurface:
1639@dataclass(init=False)
1640class ProductDefinitionTemplateSurface:
1641    """Surface attributes for Product Definition Templates"""
1642    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
1643    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
1644    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1645    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1646    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1647    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1648    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1649    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1650    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
1651    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
1652    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
1653    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
1654    @classmethod
1655    @property
1656    def _attrs(cls):
1657        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]

Surface attributes for Product Definition Templates

typeOfFirstFixedSurface: Grib2Metadata
scaleFactorOfFirstFixedSurface: int

Scale Factor of First Fixed Surface

scaledValueOfFirstFixedSurface: int

Scaled Value Of First Fixed Surface

typeOfSecondFixedSurface: Grib2Metadata
scaleFactorOfSecondFixedSurface: int

Scale Factor of Second Fixed Surface

scaledValueOfSecondFixedSurface: int

Scaled Value Of Second Fixed Surface

unitOfFirstFixedSurface: str

Units of First Fixed Surface

valueOfFirstFixedSurface: int

Value of First Fixed Surface

unitOfSecondFixedSurface: str

Units of Second Fixed Surface

valueOfSecondFixedSurface: int

Value of Second Fixed Surface

@dataclass(init=False)
class ProductDefinitionTemplate0(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1659@dataclass(init=False)
1660class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1661    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
1662    _len = 15
1663    _num = 0
1664    @classmethod
1665    @property
1666    def _attrs(cls):
1667        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
@dataclass(init=False)
class ProductDefinitionTemplate1(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1669@dataclass(init=False)
1670class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1671    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
1672    _len = 18
1673    _num = 1
1674    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1675    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1676    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1677    @classmethod
1678    @property
1679    def _attrs(cls):
1680        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate2(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1682@dataclass(init=False)
1683class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1684    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
1685    _len = 17
1686    _num = 2
1687    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1688    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1689    @classmethod
1690    @property
1691    def _attrs(cls):
1692        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfDerivedForecast: Grib2Metadata
numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate5(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1694@dataclass(init=False)
1695class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1696    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
1697    _len = 22
1698    _num = 5
1699    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1700    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1701    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1702    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1703    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1704    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1705    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1706    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1707    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1708    threshold: str = field(init=False, repr=False, default=Threshold())
1709    @classmethod
1710    @property
1711    def _attrs(cls):
1712        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
forecastProbabilityNumber: int

Forecast Probability Number

totalNumberOfForecastProbabilities: int

Total Number of Forecast Probabilities

typeOfProbability: Grib2Metadata
scaleFactorOfThresholdLowerLimit: float

Scale Factor of Threshold Lower Limit

scaledValueOfThresholdLowerLimit: float

Scaled Value of Threshold Lower Limit

scaleFactorOfThresholdUpperLimit: float

Scale Factor of Threshold Upper Limit

scaledValueOfThresholdUpperLimit: float

Scaled Value of Threshold Upper Limit

thresholdLowerLimit: float

Threshold Lower Limit

thresholdUpperLimit: float

Threshold Upper Limit

threshold: str

Threshold string (same as wgrib2)

@dataclass(init=False)
class ProductDefinitionTemplate6(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1714@dataclass(init=False)
1715class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1716    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
1717    _len = 16
1718    _num = 6
1719    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1720    @classmethod
1721    @property
1722    def _attrs(cls):
1723        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
percentileValue: int

Percentile Value

@dataclass(init=False)
class ProductDefinitionTemplate8(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1725@dataclass(init=False)
1726class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1727    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
1728    _len = 29
1729    _num = 8
1730    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1731    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1732    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1733    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1734    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1735    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1736    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1737    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1738    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1739    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1740    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1741    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1742    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1743    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1744    @classmethod
1745    @property
1746    def _attrs(cls):
1747        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

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

numberOfMissingValues: int

Total number of data values missing in statistical process

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

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate9(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1749@dataclass(init=False)
1750class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1751    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
1752    _len = 36
1753    _num = 9
1754    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1755    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1756    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1757    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1758    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1759    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1760    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1761    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1762    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1763    threshold: str = field(init=False, repr=False, default=Threshold())
1764    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1765    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1766    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1767    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1768    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1769    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1770    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1771    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1772    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1773    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1774    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1775    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1776    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1777    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1778    @classmethod
1779    @property
1780    def _attrs(cls):
1781        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
forecastProbabilityNumber: int

Forecast Probability Number

totalNumberOfForecastProbabilities: int

Total Number of Forecast Probabilities

typeOfProbability: Grib2Metadata
scaleFactorOfThresholdLowerLimit: float

Scale Factor of Threshold Lower Limit

scaledValueOfThresholdLowerLimit: float

Scaled Value of Threshold Lower Limit

scaleFactorOfThresholdUpperLimit: float

Scale Factor of Threshold Upper Limit

scaledValueOfThresholdUpperLimit: float

Scaled Value of Threshold Upper Limit

thresholdLowerLimit: float

Threshold Lower Limit

thresholdUpperLimit: float

Threshold Upper Limit

threshold: str

Threshold string (same as wgrib2)

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

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

numberOfMissingValues: int

Total number of data values missing in statistical process

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

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

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

Percentile Value

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

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

numberOfMissingValues: int

Total number of data values missing in statistical process

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

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate11(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1808@dataclass(init=False)
1809class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1810    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
1811    _len = 32
1812    _num = 11
1813    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1814    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1815    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1816    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
1817    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
1818    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
1819    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
1820    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
1821    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
1822    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
1823    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
1824    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1825    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
1826    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
1827    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
1828    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
1829    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
1830    @classmethod
1831    @property
1832    def _attrs(cls):
1833        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

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

numberOfMissingValues: int

Total number of data values missing in statistical process

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

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

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

Total Number of Ensemble Forecasts

yearOfEndOfTimePeriod: int

Year of End of Forecast Time Period

monthOfEndOfTimePeriod: int

Month Year of End of Forecast Time Period

dayOfEndOfTimePeriod: int

Day Year of End of Forecast Time Period

hourOfEndOfTimePeriod: int

Hour Year of End of Forecast Time Period

minuteOfEndOfTimePeriod: int

Minute Year of End of Forecast Time Period

secondOfEndOfTimePeriod: int

Second Year of End of Forecast Time Period

numberOfTimeRanges: int

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

numberOfMissingValues: int

Total number of data values missing in statistical process

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

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate15(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1861@dataclass(init=False)
1862class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1863    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
1864    _len = 18
1865    _num = 15
1866    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
1867    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
1868    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
1869    @classmethod
1870    @property
1871    def _attrs(cls):
1872        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
statisticalProcess: Grib2Metadata
typeOfStatisticalProcessing: Grib2Metadata
numberOfDataPointsForSpatialProcessing: int

Number of Data Points for Spatial Processing

@dataclass(init=False)
class ProductDefinitionTemplate31:
1874@dataclass(init=False)
1875class ProductDefinitionTemplate31:
1876    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
1877    _len = 5
1878    _num = 31
1879    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1880    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1881    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1882    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1883    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1884    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1885    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1886    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1887    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1888    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1889    @classmethod
1890    @property
1891    def _attrs(cls):
1892        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
parameterCategory: int
parameterNumber: int
typeOfGeneratingProcess: Grib2Metadata
generatingProcess: Grib2Metadata
numberOfContributingSpectralBands: int

Number of Contributing Spectral Bands (NB)

satelliteSeries: list

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

satelliteNumber: list

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

instrumentType: list

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

scaleFactorOfCentralWaveNumber: list

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

scaledValueOfCentralWaveNumber: list

Scaled Value Of Central WaveNumber of band NB

@dataclass(init=False)
class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
1894@dataclass(init=False)
1895class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
1896    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
1897    _len = 10
1898    _num = 32
1899    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
1900    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
1901    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
1902    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
1903    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
1904    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
1905    @classmethod
1906    @property
1907    def _attrs(cls):
1908        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
numberOfContributingSpectralBands: int

Number of Contributing Spectral Bands (NB)

satelliteSeries: list

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

satelliteNumber: list

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

instrumentType: list

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

scaleFactorOfCentralWaveNumber: list

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

scaledValueOfCentralWaveNumber: list

Scaled Value Of Central WaveNumber of band NB

@dataclass(init=False)
class ProductDefinitionTemplate48(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1910@dataclass(init=False)
1911class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1912    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
1913    _len = 26
1914    _num = 48
1915    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
1916    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
1917    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
1918    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
1919    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
1920    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
1921    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
1922    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
1923    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
1924    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
1925    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
1926    @classmethod
1927    @property
1928    def _attrs(cls):
1929        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

def pdt_class_by_pdtn(pdtn: int):
1948def pdt_class_by_pdtn(pdtn: int):
1949    """
1950    Provide a Product Definition Template class via the template number.
1951
1952    Parameters
1953    ----------
1954    pdtn
1955        Product definition template number.
1956
1957    Returns
1958    -------
1959    pdt_class_by_pdtn
1960        Product definition template class object (not an instance).
1961    """
1962    return _pdt_by_pdtn[pdtn]

Provide a Product Definition Template class via the template number.

Parameters
  • pdtn: Product definition template number.
Returns
  • pdt_class_by_pdtn: Product definition template class object (not an instance).
class NumberOfPackedValues:
1967class NumberOfPackedValues:
1968    """Number of Packed Values"""
1969    def __get__(self, obj, objtype=None):
1970        return obj.section5[0]
1971    def __set__(self, obj, value):
1972        pass

Number of Packed Values

class DataRepresentationTemplateNumber:
1974class DataRepresentationTemplateNumber:
1975    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
1976    def __get__(self, obj, objtype=None):
1977        return Grib2Metadata(obj.section5[1],table='5.0')
1978    def __set__(self, obj, value):
1979        pass
class DataRepresentationTemplate:
1981class DataRepresentationTemplate:
1982    """Data Representation Template"""
1983    def __get__(self, obj, objtype=None):
1984        return obj.section5[2:]
1985    def __set__(self, obj, value):
1986        raise NotImplementedError

Data Representation Template

class RefValue:
1988class RefValue:
1989    """Reference Value (represented as an IEEE 32-bit floating point value)"""
1990    def __get__(self, obj, objtype=None):
1991        return utils.ieee_int_to_float(obj.section5[0+2])
1992    def __set__(self, obj, value):
1993        pass

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

class BinScaleFactor:
1995class BinScaleFactor:
1996    """Binary Scale Factor"""
1997    def __get__(self, obj, objtype=None):
1998        return obj.section5[1+2]
1999    def __set__(self, obj, value):
2000        obj.section5[1+2] = value

Binary Scale Factor

class DecScaleFactor:
2002class DecScaleFactor:
2003    """Decimal Scale Factor"""
2004    def __get__(self, obj, objtype=None):
2005        return obj.section5[2+2]
2006    def __set__(self, obj, value):
2007        obj.section5[2+2] = value

Decimal Scale Factor

class NBitsPacking:
2009class NBitsPacking:
2010    """Minimum number of bits for packing"""
2011    def __get__(self, obj, objtype=None):
2012        return obj.section5[3+2]
2013    def __set__(self, obj, value):
2014        obj.section5[3+2] = value

Minimum number of bits for packing

class TypeOfValues:
2016class TypeOfValues:
2017    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2018    def __get__(self, obj, objtype=None):
2019        return Grib2Metadata(obj.section5[4+2],table='5.1')
2020    def __set__(self, obj, value):
2021        obj.section5[4+2] = value
class GroupSplittingMethod:
2023class GroupSplittingMethod:
2024    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2025    def __get__(self, obj, objtype=None):
2026        return Grib2Metadata(obj.section5[5+2],table='5.4')
2027    def __set__(self, obj, value):
2028        obj.section5[5+2] = value
class TypeOfMissingValueManagement:
2030class TypeOfMissingValueManagement:
2031    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2032    def __get__(self, obj, objtype=None):
2033        return Grib2Metadata(obj.section5[6+2],table='5.5')
2034    def __set__(self, obj, value):
2035        obj.section5[6+2] = value
class PriMissingValue:
2037class PriMissingValue:
2038    """Primary Missing Value"""
2039    def __get__(self, obj, objtype=None):
2040        if obj.typeOfValues == 0:
2041            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
2042        elif obj.typeOfValues == 1:
2043            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2044    def __set__(self, obj, value):
2045        if obj.typeOfValues == 0:
2046            obj.section5[7+2] = utils.ieee_float_to_int(value)
2047        elif self.typeOfValues == 1:
2048            obj.section5[7+2] = int(value)
2049        obj.section5[6+2] = 1

Primary Missing Value

class SecMissingValue:
2051class SecMissingValue:
2052    """Secondary Missing Value"""
2053    def __get__(self, obj, objtype=None):
2054        if obj.typeOfValues == 0:
2055            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
2056        elif obj.typeOfValues == 1:
2057            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2058    def __set__(self, obj, value):
2059        if obj.typeOfValues == 0:
2060            obj.section5[8+2] = utils.ieee_float_to_int(value)
2061        elif self.typeOfValues == 1:
2062            obj.section5[8+2] = int(value)
2063        obj.section5[6+2] = 2

Secondary Missing Value

class NGroups:
2065class NGroups:
2066    """Number of Groups"""
2067    def __get__(self, obj, objtype=None):
2068        return obj.section5[9+2]
2069    def __set__(self, obj, value):
2070        pass

Number of Groups

class RefGroupWidth:
2072class RefGroupWidth:
2073    """Reference Group Width"""
2074    def __get__(self, obj, objtype=None):
2075        return obj.section5[10+2]
2076    def __set__(self, obj, value):
2077        pass

Reference Group Width

class NBitsGroupWidth:
2079class NBitsGroupWidth:
2080    """Number of bits for Group Width"""
2081    def __get__(self, obj, objtype=None):
2082        return obj.section5[11+2]
2083    def __set__(self, obj, value):
2084        pass

Number of bits for Group Width

class RefGroupLength:
2086class RefGroupLength:
2087    """Reference Group Length"""
2088    def __get__(self, obj, objtype=None):
2089        return obj.section5[12+2]
2090    def __set__(self, obj, value):
2091        pass

Reference Group Length

class GroupLengthIncrement:
2093class GroupLengthIncrement:
2094    """Group Length Increment"""
2095    def __get__(self, obj, objtype=None):
2096        return obj.section5[13+2]
2097    def __set__(self, obj, value):
2098        pass

Group Length Increment

class LengthOfLastGroup:
2100class LengthOfLastGroup:
2101    """Length of Last Group"""
2102    def __get__(self, obj, objtype=None):
2103        return obj.section5[14+2]
2104    def __set__(self, obj, value):
2105        pass

Length of Last Group

class NBitsScaledGroupLength:
2107class NBitsScaledGroupLength:
2108    """Number of bits of Scaled Group Length"""
2109    def __get__(self, obj, objtype=None):
2110        return obj.section5[15+2]
2111    def __set__(self, obj, value):
2112        pass

Number of bits of Scaled Group Length

class SpatialDifferenceOrder:
2114class SpatialDifferenceOrder:
2115    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2116    def __get__(self, obj, objtype=None):
2117        return Grib2Metadata(obj.section5[16+2],table='5.6')
2118    def __set__(self, obj, value):
2119        obj.section5[16+2] = value
class NBytesSpatialDifference:
2121class NBytesSpatialDifference:
2122    """Number of bytes for Spatial Differencing"""
2123    def __get__(self, obj, objtype=None):
2124        return obj.section5[17+2]
2125    def __set__(self, obj, value):
2126        pass

Number of bytes for Spatial Differencing

class Precision:
2128class Precision:
2129    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2130    def __get__(self, obj, objtype=None):
2131        return Grib2Metadata(obj.section5[0+2],table='5.7')
2132    def __set__(self, obj, value):
2133        obj.section5[0+2] = value
class TypeOfCompression:
2135class TypeOfCompression:
2136    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2137    def __get__(self, obj, objtype=None):
2138        return Grib2Metadata(obj.section5[5+2],table='5.40')
2139    def __set__(self, obj, value):
2140        obj.section5[5+2] = value
class TargetCompressionRatio:
2142class TargetCompressionRatio:
2143    """Target Compression Ratio"""
2144    def __get__(self, obj, objtype=None):
2145        return obj.section5[6+2]
2146    def __set__(self, obj, value):
2147        pass

Target Compression Ratio

class RealOfCoefficient:
2149class RealOfCoefficient:
2150    """Real of Coefficient"""
2151    def __get__(self, obj, objtype=None):
2152        return utils.ieee_int_to_float(obj.section5[4+2])
2153    def __set__(self, obj, value):
2154        obj.section5[4+2] = utils.ieee_float_to_int(float(value))

Real of Coefficient

class CompressionOptionsMask:
2156class CompressionOptionsMask:
2157    """Compression Options Mask for AEC/CCSDS"""
2158    def __get__(self, obj, objtype=None):
2159        return obj.section5[5+2]
2160    def __set__(self, obj, value):
2161        obj.section5[5+2] = value

Compression Options Mask for AEC/CCSDS

class BlockSize:
2163class BlockSize:
2164    """Block Size for AEC/CCSDS"""
2165    def __get__(self, obj, objtype=None):
2166        return obj.section5[6+2]
2167    def __set__(self, obj, value):
2168        obj.section5[6+2] = value

Block Size for AEC/CCSDS

class RefSampleInterval:
2170class RefSampleInterval:
2171    """Reference Sample Interval for AEC/CCSDS"""
2172    def __get__(self, obj, objtype=None):
2173        return obj.section5[7+2]
2174    def __set__(self, obj, value):
2175        obj.section5[7+2] = value

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate0:
2177@dataclass(init=False)
2178class DataRepresentationTemplate0:
2179    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
2180    _len = 5
2181    _num = 0
2182    _packingScheme = 'simple'
2183    refValue: float = field(init=False, repr=False, default=RefValue())
2184    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2185    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2186    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2187    @classmethod
2188    @property
2189    def _attrs(cls):
2190        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

@dataclass(init=False)
class DataRepresentationTemplate2:
2192@dataclass(init=False)
2193class DataRepresentationTemplate2:
2194    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
2195    _len = 16
2196    _num = 2
2197    _packingScheme = 'complex'
2198    refValue: float = field(init=False, repr=False, default=RefValue())
2199    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2200    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2201    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2202    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2203    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2204    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2205    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2206    nGroups: int = field(init=False, repr=False, default=NGroups())
2207    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2208    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2209    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2210    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2211    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2212    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2213    @classmethod
2214    @property
2215    def _attrs(cls):
2216        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

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

Primary Missing Value

secMissingValue: Union[float, int]

Secondary Missing Value

nGroups: int

Number of Groups

refGroupWidth: int

Reference Group Width

nBitsGroupWidth: int

Number of bits for Group Width

refGroupLength: int

Reference Group Length

groupLengthIncrement: int

Group Length Increment

lengthOfLastGroup: int

Length of Last Group

nBitsScaledGroupLength: int

Number of bits of Scaled Group Length

@dataclass(init=False)
class DataRepresentationTemplate3:
2218@dataclass(init=False)
2219class DataRepresentationTemplate3:
2220    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
2221    _len = 18
2222    _num = 3
2223    _packingScheme = 'complex-spdiff'
2224    refValue: float = field(init=False, repr=False, default=RefValue())
2225    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2226    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2227    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2228    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2229    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2230    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2231    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2232    nGroups: int = field(init=False, repr=False, default=NGroups())
2233    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2234    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2235    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2236    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2237    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2238    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2239    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
2240    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
2241    @classmethod
2242    @property
2243    def _attrs(cls):
2244        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

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

Primary Missing Value

secMissingValue: Union[float, int]

Secondary Missing Value

nGroups: int

Number of Groups

refGroupWidth: int

Reference Group Width

nBitsGroupWidth: int

Number of bits for Group Width

refGroupLength: int

Reference Group Length

groupLengthIncrement: int

Group Length Increment

lengthOfLastGroup: int

Length of Last Group

nBitsScaledGroupLength: int

Number of bits of Scaled Group Length

spatialDifferenceOrder: Grib2Metadata
nBytesSpatialDifference: int

Number of bytes for Spatial Differencing

@dataclass(init=False)
class DataRepresentationTemplate4:
2246@dataclass(init=False)
2247class DataRepresentationTemplate4:
2248    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
2249    _len = 1
2250    _num = 4
2251    _packingScheme = 'ieee-float'
2252    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
2253    @classmethod
2254    @property
2255    def _attrs(cls):
2256        return list(cls.__dataclass_fields__.keys())
@dataclass(init=False)
class DataRepresentationTemplate40:
2258@dataclass(init=False)
2259class DataRepresentationTemplate40:
2260    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
2261    _len = 7
2262    _num = 40
2263    _packingScheme = 'jpeg'
2264    refValue: float = field(init=False, repr=False, default=RefValue())
2265    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2266    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2267    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2268    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
2269    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
2270    @classmethod
2271    @property
2272    def _attrs(cls):
2273        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

typeOfCompression: Grib2Metadata
targetCompressionRatio: int

Target Compression Ratio

@dataclass(init=False)
class DataRepresentationTemplate41:
2275@dataclass(init=False)
2276class DataRepresentationTemplate41:
2277    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
2278    _len = 5
2279    _num = 41
2280    _packingScheme = 'png'
2281    refValue: float = field(init=False, repr=False, default=RefValue())
2282    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2283    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2284    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2285    @classmethod
2286    @property
2287    def _attrs(cls):
2288        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

@dataclass(init=False)
class DataRepresentationTemplate42:
2290@dataclass(init=False)
2291class DataRepresentationTemplate42:
2292    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
2293    _len = 8
2294    _num = 42
2295    _packingScheme = 'aec'
2296    refValue: float = field(init=False, repr=False, default=RefValue())
2297    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2298    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2299    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2300    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
2301    blockSize: int = field(init=False, repr=False, default=BlockSize())
2302    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
2303    @classmethod
2304    @property
2305    def _attrs(cls):
2306        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

compressionOptionsMask: int

Compression Options Mask for AEC/CCSDS

blockSize: int

Block Size for AEC/CCSDS

refSampleInterval: int

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate50:
2308@dataclass(init=False)
2309class DataRepresentationTemplate50:
2310    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
2311    _len = 5
2312    _num = 0
2313    _packingScheme = 'spectral-simple'
2314    refValue: float = field(init=False, repr=False, default=RefValue())
2315    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2316    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2317    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2318    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
2319    @classmethod
2320    @property
2321    def _attrs(cls):
2322        return list(cls.__dataclass_fields__.keys())
refValue: float

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

binScaleFactor: int

Binary Scale Factor

decScaleFactor: int

Decimal Scale Factor

nBitsPacking: int

Minimum number of bits for packing

realOfCoefficient: float

Real of Coefficient

def drt_class_by_drtn(drtn: int):
2335def drt_class_by_drtn(drtn: int):
2336    """
2337    Provide a Data Representation Template class via the template number.
2338
2339    Parameters
2340    ----------
2341    drtn
2342        Data Representation template number.
2343
2344    Returns
2345    -------
2346    drt_class_by_drtn
2347        Data Representation template class object (not an instance).
2348    """
2349    return _drt_by_drtn[drtn]

Provide a Data Representation Template class via the template number.

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