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 decimal import Decimal
   4from collections import defaultdict
   5from typing import Union
   6import copy
   7import datetime
   8import numpy as np
   9import warnings
  10
  11from . import tables
  12from . import utils
  13
  14# This dict is used by grib2io.Grib2Message.attrs_by_section() method
  15# to get attr names that defined in the Grib2Message base class.
  16_section_attrs = {0:['discipline'],
  17                  1:['originatingCenter', 'originatingSubCenter', 'masterTableInfo', 'localTableInfo',
  18                     'significanceOfReferenceTime', 'year', 'month', 'day', 'hour', 'minute', 'second',
  19                     'refDate', 'productionStatus', 'typeOfData'],
  20                  2:[],
  21                  3:['sourceOfGridDefinition', 'numberOfDataPoints', 'interpretationOfListOfNumbers',
  22                     'gridDefinitionTemplateNumber', 'shapeOfEarth', 'earthRadius', 'earthMajorAxis',
  23                     'earthMinorAxis', 'resolutionAndComponentFlags', 'ny', 'nx', 'scanModeFlags'],
  24                  4:[],
  25                  5:['dataRepresentationTemplateNumber','numberOfPackedValues','typeOfValues'],
  26                  6:['bitMapFlag'],
  27                  7:[],
  28                  8:[],}
  29
  30_continuous_pdtns = [
  31    int(k) for k, v in tables.get_table("4.0").items() if "a point in time" in v
  32]
  33_timeinterval_pdtns = [
  34    int(k)
  35    for k, v in tables.get_table("4.0").items()
  36    if "continuous or non-continuous time interval" in v
  37]
  38
  39
  40def _calculate_scale_factor(value: float):
  41    """
  42    Calculate the scale factor for a given value.
  43
  44    Parameters
  45    ----------
  46    value : float
  47        Value for which to calculate the scale factor.
  48
  49    Returns
  50    -------
  51    int
  52        Scale factor for the value.
  53    """
  54    return len(f"{value}".split(".")[1].rstrip("0"))
  55
  56
  57class Grib2Metadata:
  58    """
  59    Class to hold GRIB2 metadata.
  60
  61    Stores both numeric code value as stored in GRIB2 and its plain language
  62    definition.
  63
  64    Attributes
  65    ----------
  66    value : int
  67        GRIB2 metadata integer code value.
  68    table : str, optional
  69        GRIB2 table to lookup the `value`. Default is None.
  70    definition : str
  71        Plain language description of numeric metadata.
  72    """
  73    __slots__ = ('value','table')
  74
  75    def __init__(self, value, table=None):
  76        self.value = int(value)
  77        self.table = table
  78
  79    def __call__(self):
  80        return self.value
  81
  82    def __hash__(self):
  83        # AS- added hash() to self.value as pandas was raising error about some
  84        # non integer returns from hash method
  85        return hash(self.value)
  86
  87    def __repr__(self):
  88        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
  89
  90    def __str__(self):
  91        return f'{self.value} - {self.definition}'
  92
  93    def __eq__(self,other):
  94        return self.value == other or self.definition[0] == other
  95
  96    def __gt__(self,other):
  97        return self.value > other
  98
  99    def __ge__(self,other):
 100        return self.value >= other
 101
 102    def __lt__(self,other):
 103        return self.value < other
 104
 105    def __le__(self,other):
 106        return self.value <= other
 107
 108    def __contains__(self,other):
 109        return other in self.definition
 110
 111    def __hash__(self):
 112        return hash(self.value)
 113
 114    def __index__(self):
 115        return int(self.value)
 116
 117    @property
 118    def definition(self):
 119        """Provide the definition of the numeric metadata."""
 120        return tables.get_value_from_table(self.value,self.table)
 121
 122    def show_table(self):
 123        """Provide the table related to this metadata."""
 124        return tables.get_table(self.table)
 125
 126# ----------------------------------------------------------------------------------------
 127# Descriptor Classes for Section 0 metadata.
 128# ----------------------------------------------------------------------------------------
 129class IndicatorSection:
 130    """
 131    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
 132    """
 133    def __get__(self, obj, objtype=None):
 134        return obj.section0
 135    def __set__(self, obj, value):
 136        obj.section0 = value
 137
 138class Discipline:
 139    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
 140    def __get__(self, obj, objtype=None):
 141        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
 142    def __set__(self, obj, value):
 143        obj.section0[2] = value
 144
 145
 146# ----------------------------------------------------------------------------------------
 147# Descriptor Classes for Section 1 metadata.
 148# ----------------------------------------------------------------------------------------
 149class IdentificationSection:
 150    """
 151    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
 152    """
 153    def __get__(self, obj, objtype=None):
 154        return obj.section1
 155    def __set__(self, obj, value):
 156        obj.section1 = value
 157
 158class OriginatingCenter:
 159    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
 160    def __get__(self, obj, objtype=None):
 161        return Grib2Metadata(obj.section1[0],table='originating_centers')
 162    def __set__(self, obj, value):
 163        obj.section1[0] = value
 164
 165class OriginatingSubCenter:
 166    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
 167    def __get__(self, obj, objtype=None):
 168        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
 169    def __set__(self, obj, value):
 170        obj.section1[1] = value
 171
 172class MasterTableInfo:
 173    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
 174    def __get__(self, obj, objtype=None):
 175        return Grib2Metadata(obj.section1[2],table='1.0')
 176    def __set__(self, obj, value):
 177        obj.section1[2] = value
 178
 179class LocalTableInfo:
 180    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
 181    def __get__(self, obj, objtype=None):
 182        return Grib2Metadata(obj.section1[3],table='1.1')
 183    def __set__(self, obj, value):
 184        obj.section1[3] = value
 185
 186class SignificanceOfReferenceTime:
 187    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
 188    def __get__(self, obj, objtype=None):
 189        return Grib2Metadata(obj.section1[4],table='1.2')
 190    def __set__(self, obj, value):
 191        obj.section1[4] = value
 192
 193class Year:
 194    """Year of reference time"""
 195    def __get__(self, obj, objtype=None):
 196        return obj.section1[5]
 197    def __set__(self, obj, value):
 198        rd = copy.copy(obj.section1[5:11])
 199        rd[0] = value
 200        # Test validity of datetime values
 201        _ = datetime.datetime(*rd)
 202        obj.section1[5] = value
 203
 204class Month:
 205    """Month of reference time"""
 206    def __get__(self, obj, objtype=None):
 207        return obj.section1[6]
 208    def __set__(self, obj, value):
 209        rd = copy.copy(obj.section1[5:11])
 210        rd[1] = value
 211        # Test validity of datetime values
 212        _ = datetime.datetime(*rd)
 213        obj.section1[6] = value
 214
 215class Day:
 216    """Day of reference time"""
 217    def __get__(self, obj, objtype=None):
 218        return obj.section1[7]
 219    def __set__(self, obj, value):
 220        rd = copy.copy(obj.section1[5:11])
 221        rd[2] = value
 222        # Test validity of datetime values
 223        _ = datetime.datetime(*rd)
 224        obj.section1[7] = value
 225
 226class Hour:
 227    """Hour of reference time"""
 228    def __get__(self, obj, objtype=None):
 229        return obj.section1[8]
 230    def __set__(self, obj, value):
 231        rd = copy.copy(obj.section1[5:11])
 232        rd[3] = value
 233        # Test validity of datetime values
 234        _ = datetime.datetime(*rd)
 235        obj.section1[8] = value
 236
 237class Minute:
 238    """Minute of reference time"""
 239    def __get__(self, obj, objtype=None):
 240        return obj.section1[9]
 241    def __set__(self, obj, value):
 242        rd = copy.copy(obj.section1[5:11])
 243        rd[4] = value
 244        # Test validity of datetime values
 245        _ = datetime.datetime(*rd)
 246        obj.section1[9] = value
 247
 248class Second:
 249    """Second of reference time"""
 250    def __get__(self, obj, objtype=None):
 251        return obj.section1[10]
 252    def __set__(self, obj, value):
 253        rd = copy.copy(obj.section1[5:11])
 254        rd[5] = value
 255        # Test validity of datetime values
 256        _ = datetime.datetime(*rd)
 257        obj.section1[10] = value
 258
 259class RefDate:
 260    """Reference Date. NOTE: This is a `datetime.datetime` object."""
 261    def __get__(self, obj, objtype=None):
 262        return datetime.datetime(*obj.section1[5:11])
 263    def __set__(self, obj, value):
 264        if isinstance(value, np.datetime64):
 265            timestamp = (value - np.datetime64("1970-01-01T00:00:00")) / np.timedelta64(
 266                1, "s"
 267            )
 268            try:
 269                # Python >= 3.10
 270                value = datetime.datetime.fromtimestamp(timestamp, datetime.UTC)
 271            except(AttributeError):
 272                # Python < 3.10
 273                value = datetime.datetime.utcfromtimestamp(timestamp)
 274        if isinstance(value, datetime.datetime):
 275            obj.section1[5] = value.year
 276            obj.section1[6] = value.month
 277            obj.section1[7] = value.day
 278            obj.section1[8] = value.hour
 279            obj.section1[9] = value.minute
 280            obj.section1[10] = value.second
 281            # IMPORTANT: Update validDate components when message is time interval
 282            if obj.pdtn in _timeinterval_pdtns:
 283                vd = value + obj.leadTime + obj.duration
 284                obj.yearOfEndOfTimePeriod = vd.year
 285                obj.monthOfEndOfTimePeriod = vd.month
 286                obj.dayOfEndOfTimePeriod = vd.day
 287                obj.hourOfEndOfTimePeriod = vd.hour
 288                obj.minuteOfEndOfTimePeriod = vd.minute
 289                obj.secondOfEndOfTimePeriod = vd.second
 290        else:
 291            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
 292            raise TypeError(msg)
 293
 294class ProductionStatus:
 295    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
 296    def __get__(self, obj, objtype=None):
 297        return Grib2Metadata(obj.section1[11],table='1.3')
 298    def __set__(self, obj, value):
 299        obj.section1[11] = value
 300
 301class TypeOfData:
 302    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
 303    def __get__(self, obj, objtype=None):
 304        return Grib2Metadata(obj.section1[12],table='1.4')
 305    def __set__(self, obj, value):
 306        obj.section1[12] = value
 307
 308# ----------------------------------------------------------------------------------------
 309# Descriptor Classes for Section 2 metadata.
 310# ----------------------------------------------------------------------------------------
 311
 312# ----------------------------------------------------------------------------------------
 313# Descriptor Classes for Section 3 metadata.
 314# ----------------------------------------------------------------------------------------
 315class GridDefinitionSection:
 316    """
 317    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
 318    """
 319    def __get__(self, obj, objtype=None):
 320        return obj.section3[0:5]
 321    def __set__(self, obj, value):
 322        raise RuntimeError
 323
 324class SourceOfGridDefinition:
 325    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
 326    def __get__(self, obj, objtype=None):
 327        return Grib2Metadata(obj.section3[0],table='3.0')
 328    def __set__(self, obj, value):
 329        raise RuntimeError
 330
 331class NumberOfDataPoints:
 332    """Number of Data Points"""
 333    def __get__(self, obj, objtype=None):
 334        return obj.section3[1]
 335    def __set__(self, obj, value):
 336        raise RuntimeError
 337
 338class InterpretationOfListOfNumbers:
 339    """Interpretation of List of Numbers"""
 340    def __get__(self, obj, objtype=None):
 341        return Grib2Metadata(obj.section3[3],table='3.11')
 342    def __set__(self, obj, value):
 343        raise RuntimeError
 344
 345class GridDefinitionTemplateNumber:
 346    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
 347    def __get__(self, obj, objtype=None):
 348        return Grib2Metadata(obj.section3[4],table='3.1')
 349    def __set__(self, obj, value):
 350        raise RuntimeError
 351
 352class GridDefinitionTemplate:
 353    """Grid definition template"""
 354    def __get__(self, obj, objtype=None):
 355        return obj.section3[5:]
 356    def __set__(self, obj, value):
 357        raise RuntimeError
 358
 359class EarthParams:
 360    """Metadata about the shape of the Earth"""
 361    def __get__(self, obj, objtype=None):
 362        if obj.section3[5] in {50,51,52,1200}:
 363            return None
 364        return tables.get_table('earth_params')[str(obj.section3[5])]
 365    def __set__(self, obj, value):
 366        raise RuntimeError
 367
 368class DxSign:
 369    """Sign of Grid Length in X-Direction"""
 370    def __get__(self, obj, objtype=None):
 371        if obj.section3[4] in {0, 1, 203, 205, 32768, 32769} and \
 372        obj.section3[17] > obj.section3[20]:
 373            return -1.0
 374        return 1.0
 375    def __set__(self, obj, value):
 376        raise RuntimeError
 377
 378class DySign:
 379    """Sign of Grid Length in Y-Direction"""
 380    def __get__(self, obj, objtype=None):
 381        if obj.section3[4] in {0, 1, 203, 205, 32768, 32769} and \
 382        obj.section3[16] > obj.section3[19]:
 383            return -1.0
 384        return 1.0
 385    def __set__(self, obj, value):
 386        raise RuntimeError
 387
 388class LLScaleFactor:
 389    """Scale Factor for Lats/Lons"""
 390    def __get__(self, obj, objtype=None):
 391        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
 392            llscalefactor = float(obj.section3[14])
 393            if llscalefactor == 0:
 394                return 1
 395            return llscalefactor
 396        return 1
 397    def __set__(self, obj, value):
 398        raise RuntimeError
 399
 400class LLDivisor:
 401    """Divisor Value for scaling Lats/Lons"""
 402    def __get__(self, obj, objtype=None):
 403        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
 404            lldivisor = float(obj.section3[15])
 405            if lldivisor <= 0:
 406                return 1.e6
 407            return lldivisor
 408        return 1.e6
 409    def __set__(self, obj, value):
 410        raise RuntimeError
 411
 412class XYDivisor:
 413    """Divisor Value for scaling grid lengths"""
 414    def __get__(self, obj, objtype=None):
 415        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
 416            return obj._lldivisor
 417        return 1.e3
 418    def __set__(self, obj, value):
 419        raise RuntimeError
 420
 421class ShapeOfEarth:
 422    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
 423    def __get__(self, obj, objtype=None):
 424        return Grib2Metadata(obj.section3[5],table='3.2')
 425    def __set__(self, obj, value):
 426        obj.section3[5] = value
 427
 428class EarthShape:
 429    """Description of the shape of the Earth"""
 430    def __get__(self, obj, objtype=None):
 431        return obj._earthparams['shape']
 432    def __set__(self, obj, value):
 433        raise RuntimeError
 434
 435class EarthRadius:
 436    """Radius of the Earth (Assumes "spherical")"""
 437    def __get__(self, obj, objtype=None):
 438        ep = obj._earthparams
 439        if ep['shape'] == 'spherical':
 440            if ep['radius'] is None:
 441                return obj.section3[7]/(10.**obj.section3[6])
 442            else:
 443                return ep['radius']
 444        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 445            return None
 446    def __set__(self, obj, value):
 447        raise RuntimeError
 448
 449class EarthMajorAxis:
 450    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
 451    def __get__(self, obj, objtype=None):
 452        ep = obj._earthparams
 453        if ep['shape'] == 'spherical':
 454            return None
 455        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 456            if ep['major_axis'] is None and ep['minor_axis'] is None:
 457                return obj.section3[9]/(10.**obj.section3[8])
 458            else:
 459                return ep['major_axis']
 460    def __set__(self, obj, value):
 461        raise RuntimeError
 462
 463class EarthMinorAxis:
 464    """Minor Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
 465    def __get__(self, obj, objtype=None):
 466        ep = obj._earthparams
 467        if ep['shape'] == 'spherical':
 468            return None
 469        if ep['shape'] in {'ellipsoid','oblateSpheriod'}:
 470            if ep['major_axis'] is None and ep['minor_axis'] is None:
 471                return obj.section3[11]/(10.**section3[10])
 472            else:
 473                return ep['minor_axis']
 474    def __set__(self, obj, value):
 475        raise RuntimeError
 476
 477class Nx:
 478    """Number of grid points in the X-direction (generally East-West)"""
 479    def __get__(self, obj, objtype=None):
 480        return obj.section3[12]
 481    def __set__(self, obj, value):
 482        obj.section3[12] = value
 483        obj.section3[1] = value * obj.section3[13]
 484
 485class Ny:
 486    """Number of grid points in the Y-direction (generally North-South)"""
 487    def __get__(self, obj, objtype=None):
 488        return obj.section3[13]
 489    def __set__(self, obj, value):
 490        obj.section3[13] = value
 491        obj.section3[1] = value * obj.section3[12]
 492
 493class ScanModeFlags:
 494    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
 495    _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}
 496    def __get__(self, obj, objtype=None):
 497        if obj.gdtn == 50:
 498            return [None, None, None, None]
 499        else:
 500            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
 501    def __set__(self, obj, value):
 502        obj.section3[self._key[obj.gdtn]+5] = value
 503
 504class ResolutionAndComponentFlags:
 505    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
 506    _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}
 507    def __get__(self, obj, objtype=None):
 508        if obj.gdtn == 50:
 509            return [None for i in range(8)]
 510        else:
 511            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
 512    def __set__(self, obj, value):
 513        obj.section3[self._key[obj.gdtn]+5] = value
 514
 515class LatitudeFirstGridpoint:
 516    """Latitude of first gridpoint"""
 517    _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}
 518    def __get__(self, obj, objtype=None):
 519        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 520    def __set__(self, obj, value):
 521        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 522
 523class LongitudeFirstGridpoint:
 524    """Longitude of first gridpoint"""
 525    _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}
 526    def __get__(self, obj, objtype=None):
 527        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 528    def __set__(self, obj, value):
 529        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 530
 531class LatitudeLastGridpoint:
 532    """Latitude of last gridpoint"""
 533    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:19}
 534    def __get__(self, obj, objtype=None):
 535        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 536    def __set__(self, obj, value):
 537        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 538
 539class LongitudeLastGridpoint:
 540    """Longitude of last gridpoint"""
 541    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:20}
 542    def __get__(self, obj, objtype=None):
 543        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 544    def __set__(self, obj, value):
 545        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 546
 547class LatitudeCenterGridpoint:
 548    """Latitude of center gridpoint"""
 549    _key = {32768:14, 32769:14}
 550    def __get__(self, obj, objtype=None):
 551        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 552    def __set__(self, obj, value):
 553        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 554
 555class LongitudeCenterGridpoint:
 556    """Longitude of center gridpoint"""
 557    _key = {32768:15, 32769:15}
 558    def __get__(self, obj, objtype=None):
 559        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 560    def __set__(self, obj, value):
 561        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 562
 563class GridlengthXDirection:
 564    """Grid lenth in the X-Direction"""
 565    _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}
 566    def __get__(self, obj, objtype=None):
 567        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
 568    def __set__(self, obj, value):
 569        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 570
 571class GridlengthYDirection:
 572    """Grid lenth in the Y-Direction"""
 573    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
 574    def __get__(self, obj, objtype=None):
 575        if obj.gdtn in {40, 41}:
 576            return obj.gridlengthXDirection
 577        else:
 578            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
 579    def __set__(self, obj, value):
 580        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)
 581
 582class NumberOfParallels:
 583    """Number of parallels between a pole and the equator"""
 584    _key = {40:17, 41:17}
 585    def __get__(self, obj, objtype=None):
 586        return obj.section3[self._key[obj.gdtn]+5]
 587    def __set__(self, obj, value):
 588        raise RuntimeError
 589
 590class LatitudeSouthernPole:
 591    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
 592    _key = {1:19, 30:20, 31:20, 41:19}
 593    def __get__(self, obj, objtype=None):
 594        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 595    def __set__(self, obj, value):
 596        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 597
 598class LongitudeSouthernPole:
 599    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
 600    _key = {1:20, 30:21, 31:21, 41:20}
 601    def __get__(self, obj, objtype=None):
 602        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 603    def __set__(self, obj, value):
 604        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 605
 606class AnglePoleRotation:
 607    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
 608    _key = {1:21, 41:21}
 609    def __get__(self, obj, objtype=None):
 610        return obj.section3[self._key[obj.gdtn]+5]
 611    def __set__(self, obj, value):
 612        obj.section3[self._key[obj.gdtn]+5] = int(value)
 613
 614class LatitudeTrueScale:
 615    """Latitude at which grid lengths are specified"""
 616    _key = {10:12, 20:12, 30:12, 31:12}
 617    def __get__(self, obj, objtype=None):
 618        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 619    def __set__(self, obj, value):
 620        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 621
 622class GridOrientation:
 623    """Longitude at which the grid is oriented"""
 624    _key = {10:16, 20:13, 30:13, 31:13}
 625    def __get__(self, obj, objtype=None):
 626        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 627    def __set__(self, obj, value):
 628        if obj.gdtn == 10 and (value < 0 or value > 90):
 629            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
 630        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 631
 632class ProjectionCenterFlag:
 633    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
 634    _key = {20:16, 30:16, 31:16}
 635    def __get__(self, obj, objtype=None):
 636        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
 637    def __set__(self, obj, value):
 638        obj.section3[self._key[obj.gdtn]+5] = value
 639
 640class StandardLatitude1:
 641    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
 642    _key = {30:18, 31:18}
 643    def __get__(self, obj, objtype=None):
 644        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 645    def __set__(self, obj, value):
 646        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 647
 648class StandardLatitude2:
 649    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
 650    _key = {30:19, 31:19}
 651    def __get__(self, obj, objtype=None):
 652        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
 653    def __set__(self, obj, value):
 654        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)
 655
 656class SpectralFunctionParameters:
 657    """Spectral Function Parameters"""
 658    def __get__(self, obj, objtype=None):
 659        return obj.section3[0:3]
 660    def __set__(self, obj, value):
 661        obj.section3[0:3] = value[0:3]
 662
 663class ProjParameters:
 664    """PROJ Parameters to define the reference system"""
 665    def __get__(self, obj, objtype=None):
 666        projparams = {}
 667        projparams['a'] = 1.0
 668        projparams['b'] = 1.0
 669        if obj.earthRadius is not None:
 670            projparams['a'] = float(obj.earthRadius)
 671            projparams['b'] = float(obj.earthRadius)
 672        else:
 673            if obj.earthMajorAxis is not None: projparams['a'] = float(obj.earthMajorAxis)
 674            if obj.earthMajorAxis is not None: projparams['b'] = float(obj.earthMinorAxis)
 675        if obj.gdtn == 0:
 676            projparams['proj'] = 'longlat'
 677        elif obj.gdtn == 1:
 678            projparams['o_proj'] = 'longlat'
 679            projparams['proj'] = 'ob_tran'
 680            projparams['o_lat_p'] = float(-1.0*obj.latitudeSouthernPole)
 681            projparams['o_lon_p'] = float(obj.anglePoleRotation)
 682            projparams['lon_0'] = float(obj.longitudeSouthernPole)
 683        elif obj.gdtn == 10:
 684            projparams['proj'] = 'merc'
 685            projparams['lat_ts'] = float(obj.latitudeTrueScale)
 686            projparams['lon_0'] = float(0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint))
 687        elif obj.gdtn == 20:
 688            if obj.projectionCenterFlag == 0:
 689                lat0 = 90.0
 690            elif obj.projectionCenterFlag == 1:
 691                lat0 = -90.0
 692            projparams['proj'] = 'stere'
 693            projparams['lat_ts'] = float(obj.latitudeTrueScale)
 694            projparams['lat_0'] = lat0
 695            projparams['lon_0'] = float(obj.gridOrientation)
 696        elif obj.gdtn == 30:
 697            projparams['proj'] = 'lcc'
 698            projparams['lat_1'] = float(obj.standardLatitude1)
 699            projparams['lat_2'] = float(obj.standardLatitude2)
 700            projparams['lat_0'] = float(obj.latitudeTrueScale)
 701            projparams['lon_0'] = float(obj.gridOrientation)
 702        elif obj.gdtn == 31:
 703            projparams['proj'] = 'aea'
 704            projparams['lat_1'] = float(obj.standardLatitude1)
 705            projparams['lat_2'] = float(obj.standardLatitude2)
 706            projparams['lat_0'] = float(obj.latitudeTrueScale)
 707            projparams['lon_0'] = float(obj.gridOrientation)
 708        elif obj.gdtn == 40:
 709            projparams['proj'] = 'eqc'
 710        elif obj.gdtn == 32769:
 711            projparams['proj'] = 'aeqd'
 712            projparams['lon_0'] = float(obj.longitudeCenterGridpoint)
 713            projparams['lat_0'] = float(obj.latitudeCenterGridpoint)
 714        return projparams
 715    def __set__(self, obj, value):
 716        raise RuntimeError
 717
 718@dataclass(init=False)
 719class GridDefinitionTemplate0:
 720    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
 721    _len = 19
 722    _num = 0
 723    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 724    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 725    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 726    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 727    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 728    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 729
 730    @classmethod
 731    def _attrs(cls):
 732        return list(cls.__dataclass_fields__.keys())
 733
 734@dataclass(init=False)
 735class GridDefinitionTemplate1:
 736    """[Grid Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-1.shtml)"""
 737    _len = 22
 738    _num = 1
 739    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 740    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 741    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 742    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 743    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 744    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 745    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 746    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 747    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 748
 749    @classmethod
 750    def _attrs(cls):
 751        return list(cls.__dataclass_fields__.keys())
 752
 753@dataclass(init=False)
 754class GridDefinitionTemplate10:
 755    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
 756    _len = 19
 757    _num = 10
 758    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 759    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 760    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 761    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 762    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 763    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 764    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 765    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 766    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 767
 768    @classmethod
 769    def _attrs(cls):
 770        return list(cls.__dataclass_fields__.keys())
 771
 772@dataclass(init=False)
 773class GridDefinitionTemplate20:
 774    """[Grid Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-20.shtml)"""
 775    _len = 18
 776    _num = 20
 777    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 778    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 779    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 780    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 781    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 782    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 783    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 784    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 785
 786    @classmethod
 787    def _attrs(cls):
 788        return list(cls.__dataclass_fields__.keys())
 789
 790@dataclass(init=False)
 791class GridDefinitionTemplate30:
 792    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
 793    _len = 22
 794    _num = 30
 795    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 796    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 797    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 798    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 799    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 800    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 801    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 802    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 803    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 804    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 805    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 806    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
 807
 808    @classmethod
 809    def _attrs(cls):
 810        return list(cls.__dataclass_fields__.keys())
 811
 812@dataclass(init=False)
 813class GridDefinitionTemplate31:
 814    """[Grid Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-31.shtml)"""
 815    _len = 22
 816    _num = 31
 817    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 818    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 819    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
 820    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
 821    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 822    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 823    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
 824    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
 825    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
 826    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 827    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 828
 829    @classmethod
 830    def _attrs(cls):
 831        return list(cls.__dataclass_fields__.keys())
 832
 833@dataclass(init=False)
 834class GridDefinitionTemplate40:
 835    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
 836    _len = 19
 837    _num = 40
 838    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 839    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 840    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 841    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 842    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 843    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 844    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
 845
 846    @classmethod
 847    def _attrs(cls):
 848        return list(cls.__dataclass_fields__.keys())
 849
 850@dataclass(init=False)
 851class GridDefinitionTemplate41:
 852    """[Grid Definition Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-41.shtml)"""
 853    _len = 22
 854    _num = 41
 855    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 856    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 857    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 858    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 859    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 860    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 861    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
 862    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
 863    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
 864    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
 865
 866    @classmethod
 867    def _attrs(cls):
 868        return list(cls.__dataclass_fields__.keys())
 869
 870@dataclass(init=False)
 871class GridDefinitionTemplate50:
 872    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
 873    _len = 5
 874    _num = 50
 875    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
 876
 877    @classmethod
 878    def _attrs(cls):
 879        return list(cls.__dataclass_fields__.keys())
 880
 881@dataclass(init=False)
 882class GridDefinitionTemplate32768:
 883    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
 884    _len = 19
 885    _num = 32768
 886    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 887    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 888    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
 889    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
 890    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 891    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 892
 893    @classmethod
 894    def _attrs(cls):
 895        return list(cls.__dataclass_fields__.keys())
 896
 897@dataclass(init=False)
 898class GridDefinitionTemplate32769:
 899    """[Grid Definition Template 32769](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32769.shtml)"""
 900    _len = 19
 901    _num = 32769
 902    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
 903    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
 904    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
 905    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
 906    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
 907    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
 908    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
 909    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
 910
 911    @classmethod
 912    def _attrs(cls):
 913        return list(cls.__dataclass_fields__.keys())
 914
 915_gdt_by_gdtn = {0: GridDefinitionTemplate0,
 916    1: GridDefinitionTemplate1,
 917    10: GridDefinitionTemplate10,
 918    20: GridDefinitionTemplate20,
 919    30: GridDefinitionTemplate30,
 920    31: GridDefinitionTemplate31,
 921    40: GridDefinitionTemplate40,
 922    41: GridDefinitionTemplate41,
 923    50: GridDefinitionTemplate50,
 924    32768: GridDefinitionTemplate32768,
 925    32769: GridDefinitionTemplate32769,
 926    }
 927
 928def gdt_class_by_gdtn(gdtn: int):
 929    """
 930    Provides a Grid Definition Template class via the template number
 931
 932    Parameters
 933    ----------
 934    gdtn
 935        Grid definition template number.
 936
 937    Returns
 938    -------
 939    gdt_class_by_gdtn
 940        Grid definition template class object (not an instance).
 941    """
 942    return _gdt_by_gdtn[gdtn]
 943
 944# ----------------------------------------------------------------------------------------
 945# Descriptor Classes for Section 4 metadata.
 946# ----------------------------------------------------------------------------------------
 947class ProductDefinitionTemplateNumber:
 948    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
 949    def __get__(self, obj, objtype=None):
 950        return Grib2Metadata(obj.section4[1],table='4.0')
 951    def __set__(self, obj, value):
 952        raise RuntimeError
 953
 954#  since PDT begins at position 2 of section4, code written with +2 for added readability with grib2 documentation
 955class ProductDefinitionTemplate:
 956    """Product Definition Template"""
 957    def __get__(self, obj, objtype=None):
 958        return obj.section4[2:]
 959    def __set__(self, obj, value):
 960        raise RuntimeError
 961
 962class ParameterCategory:
 963    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
 964    _key = defaultdict(lambda: 0)
 965    def __get__(self, obj, objtype=None):
 966        return obj.section4[0+2]
 967    def __set__(self, obj, value):
 968        obj.section4[self._key[obj.pdtn]+2] = value
 969
 970class ParameterNumber:
 971    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
 972    _key = defaultdict(lambda: 1)
 973    def __get__(self, obj, objtype=None):
 974        return obj.section4[1+2]
 975    def __set__(self, obj, value):
 976        obj.section4[self._key[obj.pdtn]+2] = value
 977
 978class VarInfo:
 979    """
 980    Variable Information.
 981
 982    These are the metadata returned for a specific variable according to
 983    discipline, parameter category, and parameter number.
 984    """
 985    def __get__(self, obj, objtype=None):
 986        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
 987    def __set__(self, obj, value):
 988        raise RuntimeError
 989
 990class FullName:
 991    """Full name of the Variable."""
 992    def __get__(self, obj, objtype=None):
 993        full_name = []
 994
 995        # Get aerosol type from table 4.233
 996        if not hasattr(obj, 'typeOfAerosol'):
 997            return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
 998        elif obj.typeOfAerosol is not None:
 999            aero_type = str(obj.typeOfAerosol.value)
1000            if aero_type in tables.table_4_233:
1001                full_name.append(tables.table_4_233[aero_type][0])
1002
1003            # Get base name from GRIB2 table
1004            base_name = tables.get_varinfo_from_table(
1005                obj.section0[2],
1006                *obj.section4[2:4],
1007                isNDFD=obj._isNDFD
1008            )[0]
1009            full_name.append(base_name)
1010
1011            # Add optical properties with wavelengths if present
1012            if hasattr(obj, 'scaledValueOfFirstWavelength'):
1013                optical_type = str(obj.parameterNumber)
1014                first_wl = obj.scaledValueOfFirstWavelength
1015                second_wl = getattr(obj, 'scaledValueOfSecondWavelength', None)
1016
1017                # Special case for AE between 440-870nm
1018                if optical_type == '111' and first_wl == 440 and second_wl == 870:
1019                    full_name.append("at 440-870nm")
1020
1021                # Handle wavelength-specific optical properties
1022                elif optical_type in ['102', '103', '104', '105', '106']:
1023                    wavelength = f"{first_wl}nm"
1024                    if second_wl:
1025                        wavelength = f"{first_wl}-{second_wl}nm"
1026                    full_name.append(f"at {wavelength}")
1027
1028            final = " ".join(full_name)
1029
1030            return final.replace('Aerosol Aerosol', 'Aerosol')
1031
1032    def __set__(self, obj, value):
1033        raise RuntimeError(
1034            "Cannot set the fullName of the message. Instead set shortName OR set the appropriate discipline, "
1035            "parameterCategory, and parameterNumber. The fullName will be set automatically from these other attributes."
1036        )
1037
1038class Units:
1039    """Units of the Variable."""
1040    def __get__(self, obj, objtype=None):
1041        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
1042    def __set__(self, obj, value):
1043        raise RuntimeError(
1044            "Cannot set the units of the message.  Instead set shortName OR set the appropriate discipline, parameterCategory, and parameterNumber.  The units will be set automatically from these other attributes."
1045        )
1046
1047class ShortName:
1048    """Short name of the variable (i.e. the variable abbreviation)."""
1049    def __get__(self, obj, objtype=None):
1050        if hasattr(obj, 'typeOfAerosol'):
1051            return tables._build_aerosol_shortname(obj)
1052        else:
1053            return tables.get_varinfo_from_table(obj.section0[2], *obj.section4[2:4], isNDFD=obj._isNDFD)[2]
1054    def __set__(self, obj, value):
1055        metadata = tables.get_metadata_from_shortname(value)
1056        if len(metadata) > 1:
1057            raise ValueError(
1058                f"shortName={value} is ambiguous within the GRIB2 standard and you have to set instead with discipline, parameterCategory, and parameterNumber.\n{metadata}"
1059            )
1060        for attr, val in metadata[0].items():
1061            if attr in ["fullName", "units"]:
1062                continue
1063            setattr(obj, attr, val)
1064
1065class TypeOfGeneratingProcess:
1066    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
1067    _key = defaultdict(lambda: 2, {48:13})
1068    def __get__(self, obj, objtype=None):
1069        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
1070    def __set__(self, obj, value):
1071        obj.section4[self._key[obj.pdtn]+2] = value
1072
1073class BackgroundGeneratingProcessIdentifier:
1074    """Background Generating Process Identifier"""
1075    _key = defaultdict(lambda: 3, {48:14})
1076    def __get__(self, obj, objtype=None):
1077        return obj.section4[self._key[obj.pdtn]+2]
1078    def __set__(self, obj, value):
1079        obj.section4[self._key[obj.pdtn]+2] = value
1080
1081class GeneratingProcess:
1082    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
1083    _key = defaultdict(lambda: 4, {48:15})
1084    def __get__(self, obj, objtype=None):
1085        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
1086    def __set__(self, obj, value):
1087        obj.section4[self._key[obj.pdtn]+2] = value
1088
1089class HoursAfterDataCutoff:
1090    """Hours of observational data cutoff after reference time."""
1091    _key = defaultdict(lambda: 5, {48:16})
1092    def __get__(self, obj, objtype=None):
1093        return obj.section4[self._key[obj.pdtn]+2]
1094    def __set__(self, obj, value):
1095        obj.section4[self._key[obj.pdtn]+2] = value
1096
1097class MinutesAfterDataCutoff:
1098    """Minutes of observational data cutoff after reference time."""
1099    _key = defaultdict(lambda: 6, {48:17})
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 UnitOfForecastTime:
1106    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1107    _key = defaultdict(lambda: 7, {48:18})
1108    def __get__(self, obj, objtype=None):
1109        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
1110    def __set__(self, obj, value):
1111        obj.section4[self._key[obj.pdtn]+2] = value
1112
1113class ValueOfForecastTime:
1114    """Value of forecast time in units defined by `UnitofForecastTime`."""
1115    _key = defaultdict(lambda: 8, {48:19})
1116    def __get__(self, obj, objtype=None):
1117        return obj.section4[self._key[obj.pdtn]+2]
1118    def __set__(self, obj, value):
1119        obj.section4[self._key[obj.pdtn]+2] = value
1120
1121class LeadTime:
1122    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
1123    _key = ValueOfForecastTime._key
1124    def __get__(self, obj, objtype=None):
1125        return utils.get_leadtime(obj.section4[1], obj.section4[2:]) + obj.duration
1126    def __set__(self, obj, value):
1127        if isinstance(value, np.timedelta64):
1128            # Allows setting from xarray
1129            value = datetime.timedelta(
1130                seconds=int(value/np.timedelta64(1, 's')))
1131        # First update validDate if necessary.
1132        # IMPORTANT: Update validDate components when message is time interval
1133        if obj.pdtn in _timeinterval_pdtns:
1134            vd = obj.refDate + value 
1135            obj.yearOfEndOfTimePeriod = vd.year
1136            obj.monthOfEndOfTimePeriod = vd.month
1137            obj.dayOfEndOfTimePeriod = vd.day
1138            obj.hourOfEndOfTimePeriod = vd.hour
1139            obj.minuteOfEndOfTimePeriod = vd.minute
1140            obj.secondOfEndOfTimePeriod = vd.second
1141        # Update leadTime component in section4
1142        value -= obj.duration
1143        obj.section4[self._key[obj.pdtn]+2] = int(value.total_seconds()/3600)
1144
1145class FixedSfc1Info:
1146    """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)"""
1147    _key = defaultdict(lambda: 9, {48:20})
1148    def __get__(self, obj, objtype=None):
1149        if obj.section4[self._key[obj.pdtn]+2] == 255:
1150            return [None, None]
1151        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1152    def __set__(self, obj, value):
1153        raise NotImplementedError
1154
1155class FixedSfc2Info:
1156    """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)"""
1157    _key = defaultdict(lambda: 12, {48:23})
1158    def __get__(self, obj, objtype=None):
1159        if obj.section4[self._key[obj.pdtn]+2] == 255:
1160            return [None, None]
1161        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1162    def __set__(self, obj, value):
1163        raise NotImplementedError
1164
1165class TypeOfFirstFixedSurface:
1166    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1167    _key = defaultdict(lambda: 9, {48:20})
1168    def __get__(self, obj, objtype=None):
1169        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1170    def __set__(self, obj, value):
1171        obj.section4[self._key[obj.pdtn]+2] = value
1172
1173class ScaleFactorOfFirstFixedSurface:
1174    """Scale Factor of First Fixed Surface"""
1175    _key = defaultdict(lambda: 10, {48:21})
1176    def __get__(self, obj, objtype=None):
1177        return obj.section4[self._key[obj.pdtn]+2]
1178    def __set__(self, obj, value):
1179        obj.section4[self._key[obj.pdtn]+2] = value
1180
1181class ScaledValueOfFirstFixedSurface:
1182    """Scaled Value Of First Fixed Surface"""
1183    _key = defaultdict(lambda: 11, {48:22})
1184    def __get__(self, obj, objtype=None):
1185        return obj.section4[self._key[obj.pdtn]+2]
1186    def __set__(self, obj, value):
1187        obj.section4[self._key[obj.pdtn]+2] = value
1188
1189class UnitOfFirstFixedSurface:
1190    """Units of First Fixed Surface"""
1191    def __get__(self, obj, objtype=None):
1192        return obj._fixedsfc1info[1]
1193    def __set__(self, obj, value):
1194        pass
1195
1196class ValueOfFirstFixedSurface:
1197    """Value of First Fixed Surface"""
1198    def __get__(self, obj, objtype=None):
1199        scale_factor = getattr(obj, "scaleFactorOfFirstFixedSurface")
1200        scaled_value = getattr(obj, "scaledValueOfFirstFixedSurface")
1201        if scale_factor < 0:
1202            return 0.0
1203        else:
1204            return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1205    def __set__(self, obj, value):
1206        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1207        setattr(obj, "scaleFactorOfFirstFixedSurface", scale_factor)
1208        setattr(obj, "scaledValueOfFirstFixedSurface", scaled_value)
1209
1210class TypeOfSecondFixedSurface:
1211    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1212    _key = defaultdict(lambda: 12, {48:23})
1213    def __get__(self, obj, objtype=None):
1214        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1215    def __set__(self, obj, value):
1216        obj.section4[self._key[obj.pdtn]+2] = value
1217
1218class ScaleFactorOfSecondFixedSurface:
1219    """Scale Factor of Second Fixed Surface"""
1220    _key = defaultdict(lambda: 13, {48:24})
1221    def __get__(self, obj, objtype=None):
1222        return obj.section4[self._key[obj.pdtn]+2]
1223    def __set__(self, obj, value):
1224        obj.section4[self._key[obj.pdtn]+2] = value
1225
1226class ScaledValueOfSecondFixedSurface:
1227    """Scaled Value Of Second Fixed Surface"""
1228    _key = defaultdict(lambda: 14, {48:25})
1229    def __get__(self, obj, objtype=None):
1230        return obj.section4[self._key[obj.pdtn]+2]
1231    def __set__(self, obj, value):
1232        obj.section4[self._key[obj.pdtn]+2] = value
1233
1234class UnitOfSecondFixedSurface:
1235    """Units of Second Fixed Surface"""
1236    def __get__(self, obj, objtype=None):
1237        return obj._fixedsfc2info[1]
1238    def __set__(self, obj, value):
1239        pass
1240
1241class ValueOfSecondFixedSurface:
1242    """Value of Second Fixed Surface"""
1243    def __get__(self, obj, objtype=None):
1244        scale_factor = getattr(obj, "scaleFactorOfSecondFixedSurface")
1245        scaled_value = getattr(obj, "scaledValueOfSecondFixedSurface")
1246        if scale_factor < 0:
1247            return 0.0
1248        else:
1249            return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1250    def __set__(self, obj, value):
1251        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1252        setattr(obj, "scaleFactorOfSecondFixedSurface", scale_factor)
1253        setattr(obj, "scaledValueOfSecondFixedSurface", scaled_value)
1254
1255class Level:
1256    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1257    def __get__(self, obj, objtype=None):
1258        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1259    def __set__(self, obj, value):
1260        pass
1261
1262class TypeOfEnsembleForecast:
1263    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1264    _key = {1:15, 11:15}
1265    def __get__(self, obj, objtype=None):
1266        pdtn = obj.section4[1]
1267        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1268    def __set__(self, obj, value):
1269        pdtn = obj.section4[1]
1270        obj.section4[self._key[pdtn]+2] = value
1271
1272class PerturbationNumber:
1273    """Ensemble Perturbation Number"""
1274    _key = {1:16, 11:16}
1275    def __get__(self, obj, objtype=None):
1276        pdtn = obj.section4[1]
1277        return obj.section4[self._key[pdtn]+2]
1278    def __set__(self, obj, value):
1279        pdtn = obj.section4[1]
1280        obj.section4[self._key[pdtn]+2] = value
1281
1282class NumberOfEnsembleForecasts:
1283    """Total Number of Ensemble Forecasts"""
1284    _key = {1:17, 2:16, 11:17, 12:16}
1285    def __get__(self, obj, objtype=None):
1286        pdtn = obj.section4[1]
1287        return obj.section4[self._key[pdtn]+2]
1288    def __set__(self, obj, value):
1289        pdtn = obj.section4[1]
1290        obj.section4[self._key[pdtn]+2] = value
1291
1292class TypeOfDerivedForecast:
1293    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1294    _key = {2:15, 12:15}
1295    def __get__(self, obj, objtype=None):
1296        pdtn = obj.section4[1]
1297        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1298    def __set__(self, obj, value):
1299        pdtn = obj.section4[1]
1300        obj.section4[self._key[pdtn]+2] = value
1301
1302class ForecastProbabilityNumber:
1303    """Forecast Probability Number"""
1304    _key = {5:15, 9:15}
1305    def __get__(self, obj, objtype=None):
1306        pdtn = obj.section4[1]
1307        return obj.section4[self._key[pdtn]+2]
1308    def __set__(self, obj, value):
1309        pdtn = obj.section4[1]
1310        obj.section4[self._key[pdtn]+2] = value
1311
1312class TotalNumberOfForecastProbabilities:
1313    """Total Number of Forecast Probabilities"""
1314    _key = {5:16, 9:16}
1315    def __get__(self, obj, objtype=None):
1316        pdtn = obj.section4[1]
1317        return obj.section4[self._key[pdtn]+2]
1318    def __set__(self, obj, value):
1319        pdtn = obj.section4[1]
1320        obj.section4[self._key[pdtn]+2] = value
1321
1322class TypeOfProbability:
1323    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1324    _key = {5:17, 9:17}
1325    def __get__(self, obj, objtype=None):
1326        pdtn = obj.section4[1]
1327        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1328    def __set__(self, obj, value):
1329        pdtn = obj.section4[1]
1330        obj.section4[self._key[pdtn]+2] = value
1331
1332class ScaleFactorOfThresholdLowerLimit:
1333    """Scale Factor of Threshold Lower Limit"""
1334    _key = {5:18, 9:18}
1335    def __get__(self, obj, objtype=None):
1336        pdtn = obj.section4[1]
1337        return obj.section4[self._key[pdtn]+2]
1338    def __set__(self, obj, value):
1339        pdtn = obj.section4[1]
1340        obj.section4[self._key[pdtn]+2] = value
1341
1342class ScaledValueOfThresholdLowerLimit:
1343    """Scaled Value of Threshold Lower Limit"""
1344    _key = {5:19, 9:19}
1345    def __get__(self, obj, objtype=None):
1346        pdtn = obj.section4[1]
1347        return obj.section4[self._key[pdtn]+2]
1348    def __set__(self, obj, value):
1349        pdtn = obj.section4[1]
1350        obj.section4[self._key[pdtn]+2] = value
1351
1352class ScaleFactorOfThresholdUpperLimit:
1353    """Scale Factor of Threshold Upper Limit"""
1354    _key = {5:20, 9:20}
1355    def __get__(self, obj, objtype=None):
1356        pdtn = obj.section4[1]
1357        return obj.section4[self._key[pdtn]+2]
1358    def __set__(self, obj, value):
1359        pdtn = obj.section4[1]
1360        obj.section4[self._key[pdtn]+2] = value
1361
1362class ScaledValueOfThresholdUpperLimit:
1363    """Scaled Value of Threshold Upper Limit"""
1364    _key = {5:21, 9:21}
1365    def __get__(self, obj, objtype=None):
1366        pdtn = obj.section4[1]
1367        return obj.section4[self._key[pdtn]+2]
1368    def __set__(self, obj, value):
1369        pdtn = obj.section4[1]
1370        obj.section4[self._key[pdtn]+2] = value
1371
1372class ThresholdLowerLimit:
1373    """Threshold Lower Limit"""
1374    def __get__(self, obj, objtype=None):
1375        scale_factor = getattr(obj, "scaleFactorOfThresholdLowerLimit")
1376        scaled_value = getattr(obj, "scaledValueOfThresholdLowerLimit")
1377        if scale_factor in {-2147483647,-127} or scaled_value in {-2147483647,255}:
1378            return 0.0
1379        value = float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1380        return value
1381    def __set__(self, obj, value):
1382        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1383        setattr(obj, "scaleFactorOfThresholdLowerLimit", scale_factor)
1384        setattr(obj, "scaledValueOfThresholdLowerLimit", scaled_value)
1385
1386class ThresholdUpperLimit:
1387    """Threshold Upper Limit"""
1388    def __get__(self, obj, objtype=None):
1389        scale_factor = getattr(obj, "scaleFactorOfThresholdUpperLimit")
1390        scaled_value = getattr(obj, "scaledValueOfThresholdUpperLimit")
1391        if scale_factor in {-2147483647,-127} or scaled_value in {-2147483647,255}:
1392            return 0.0
1393        value = float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1394        return value
1395    def __set__(self, obj, value):
1396        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1397        setattr(obj, "scaleFactorOfThresholdUpperLimit", scale_factor)
1398        setattr(obj, "scaledValueOfThresholdUpperLimit", scaled_value)
1399
1400class Threshold:
1401    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1402    def __get__(self, obj, objtype=None):
1403        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1404    def __set__(self, obj, value):
1405        pass
1406
1407class PercentileValue:
1408    """Percentile Value"""
1409    _key = {6:15, 10:15}
1410    def __get__(self, obj, objtype=None):
1411        pdtn = obj.section4[1]
1412        return obj.section4[self._key[pdtn]+2]
1413    def __set__(self, obj, value):
1414        pdtn = obj.section4[1]
1415        obj.section4[self._key[pdtn]+2] = value
1416
1417class YearOfEndOfTimePeriod:
1418    """Year of End of Forecast Time Period"""
1419    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1420    def __get__(self, obj, objtype=None):
1421        pdtn = obj.section4[1]
1422        return obj.section4[self._key[pdtn]+2]
1423    def __set__(self, obj, value):
1424        pdtn = obj.section4[1]
1425        obj.section4[self._key[pdtn]+2] = value
1426
1427class MonthOfEndOfTimePeriod:
1428    """Month Year of End of Forecast Time Period"""
1429    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1430    def __get__(self, obj, objtype=None):
1431        pdtn = obj.section4[1]
1432        return obj.section4[self._key[pdtn]+2]
1433    def __set__(self, obj, value):
1434        pdtn = obj.section4[1]
1435        obj.section4[self._key[pdtn]+2] = value
1436
1437class DayOfEndOfTimePeriod:
1438    """Day Year of End of Forecast Time Period"""
1439    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1440    def __get__(self, obj, objtype=None):
1441        pdtn = obj.section4[1]
1442        return obj.section4[self._key[pdtn]+2]
1443    def __set__(self, obj, value):
1444        pdtn = obj.section4[1]
1445        obj.section4[self._key[pdtn]+2] = value
1446
1447class HourOfEndOfTimePeriod:
1448    """Hour Year of End of Forecast Time Period"""
1449    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1450    def __get__(self, obj, objtype=None):
1451        pdtn = obj.section4[1]
1452        return obj.section4[self._key[pdtn]+2]
1453    def __set__(self, obj, value):
1454        pdtn = obj.section4[1]
1455        obj.section4[self._key[pdtn]+2] = value
1456
1457class MinuteOfEndOfTimePeriod:
1458    """Minute Year of End of Forecast Time Period"""
1459    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1460    def __get__(self, obj, objtype=None):
1461        pdtn = obj.section4[1]
1462        return obj.section4[self._key[pdtn]+2]
1463    def __set__(self, obj, value):
1464        pdtn = obj.section4[1]
1465        obj.section4[self._key[pdtn]+2] = value
1466
1467class SecondOfEndOfTimePeriod:
1468    """Second Year of End of Forecast Time Period"""
1469    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1470    def __get__(self, obj, objtype=None):
1471        pdtn = obj.section4[1]
1472        return obj.section4[self._key[pdtn]+2]
1473    def __set__(self, obj, value):
1474        pdtn = obj.section4[1]
1475        obj.section4[self._key[pdtn]+2] = value
1476
1477class Duration:
1478    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1479    def __get__(self, obj, objtype=None):
1480        return utils.get_duration(obj.section4[1],obj.section4[2:])
1481    def __set__(self, obj, value):
1482        if obj.pdtn in _continuous_pdtns:
1483            pass
1484        elif obj.pdtn in _timeinterval_pdtns:
1485            lt_orig = obj.leadTime
1486            _key = TimeRangeOfStatisticalProcess._key
1487            if isinstance(value, np.timedelta64):
1488                # Allows setting from xarray
1489                value = datetime.timedelta(
1490                    seconds=int(value/np.timedelta64(1, 's')))
1491            obj.section4[_key[obj.pdtn]+2] = int(value.total_seconds()/3600)
1492            obj.leadTime = lt_orig
1493            # IMPORTANT: Update validDate components when message is time interval
1494            #if obj.pdtn in _timeinterval_pdtns:
1495            #    print(obj.refDate, value, obj.leadTime)
1496            #    vd = obj.refDate + value + obj.leadTime
1497            #    obj.yearOfEndOfTimePeriod = vd.year
1498            #    obj.monthOfEndOfTimePeriod = vd.month
1499            #    obj.dayOfEndOfTimePeriod = vd.day
1500            #    obj.hourOfEndOfTimePeriod = vd.hour
1501            #    obj.minuteOfEndOfTimePeriod = vd.minute
1502            #    obj.secondOfEndOfTimePeriod = vd.second
1503
1504class ValidDate:
1505    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1506    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1507    def __get__(self, obj, objtype=None):
1508        pdtn = obj.section4[1]
1509        try:
1510            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1511            return datetime.datetime(*obj.section4[s])
1512        except(KeyError):
1513            return obj.refDate + obj.leadTime
1514    def __set__(self, obj, value):
1515        warnings.warn(f"validDate attribute is read-only.")
1516
1517class NumberOfTimeRanges:
1518    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1519    _key = {8:21, 9:28, 10:22, 11:24, 12:23, 46:27}
1520    def __get__(self, obj, objtype=None):
1521        pdtn = obj.section4[1]
1522        return obj.section4[self._key[pdtn]+2]
1523    def __set__(self, obj, value):
1524        pdtn = obj.section4[1]
1525        obj.section4[self._key[pdtn]+2] = value
1526
1527class NumberOfMissingValues:
1528    """Total number of data values missing in statistical process"""
1529    _key = {8:22, 9:29, 10:23, 11:25, 12:24, 46:28}
1530    def __get__(self, obj, objtype=None):
1531        pdtn = obj.section4[1]
1532        return obj.section4[self._key[pdtn]+2]
1533    def __set__(self, obj, value):
1534        pdtn = obj.section4[1]
1535        obj.section4[self._key[pdtn]+2] = value
1536
1537class StatisticalProcess:
1538    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1539    _key = {
1540        8: 23,
1541        9: 30,
1542        10: 24,
1543        11: 26,
1544        12: 25,
1545        15: 15,
1546        46: 30,
1547        47: 30,
1548        49: 30,
1549        80: 30,
1550        81: 30,
1551        82: 30,
1552        83: 30,
1553        84: 30,
1554        85: 30
1555    }
1556
1557    def __get__(self, obj, objtype=None):
1558        pdtn = obj.section4[1]
1559        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.10')
1560
1561    def __set__(self, obj, value):
1562        pdtn = obj.section4[1]
1563        obj.section4[self._key[pdtn]+2] = value
1564
1565class TypeOfTimeIncrementOfStatisticalProcess:
1566    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1567    _key = {
1568        4: 31,
1569        8: 24,
1570        9: 31,
1571        10: 25,
1572        11: 27,
1573        12: 26,
1574        46: 31,
1575        47: 31,
1576        49: 31,
1577        80: 31,
1578        81: 31,
1579        82: 31,
1580        83: 31,
1581        84: 31,
1582        85: 31
1583    }
1584
1585    def __get__(self, obj, objtype=None):
1586        pdtn = obj.section4[1]
1587        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.11')
1588
1589    def __set__(self, obj, value):
1590        pdtn = obj.section4[1]
1591        obj.section4[self._key[pdtn]+2] = value
1592class UnitOfTimeRangeOfStatisticalProcess:
1593    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1594    _key = {
1595        4: 32,
1596        8: 25,
1597        9: 32,
1598        10: 26,
1599        11: 28,
1600        12: 27,
1601        46: 32,
1602        47: 32,
1603        49: 32,
1604        80: 32,
1605        81: 32,
1606        82: 32,
1607        83: 32,
1608        84: 32,
1609        85: 32
1610    }
1611
1612    def __get__(self, obj, objtype=None):
1613        pdtn = obj.section4[1]
1614        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1615
1616    def __set__(self, obj, value):
1617        pdtn = obj.section4[1]
1618        obj.section4[self._key[pdtn]+2] = value
1619
1620class TimeRangeOfStatisticalProcess:
1621    """Time Range of Statistical Process"""
1622    _key = {
1623        4: 33,
1624        8: 26,
1625        9: 33,
1626        10: 27,
1627        11: 29,
1628        12: 28,
1629        46: 33,
1630        47: 33,
1631        49: 33,
1632        80: 33,
1633        81: 33,
1634        82: 33,
1635        83: 33,
1636        84: 33,
1637        85: 33
1638    }
1639
1640    def __get__(self, obj, objtype=None):
1641        pdtn = obj.section4[1]
1642        return obj.section4[self._key[pdtn]+2]
1643
1644    def __set__(self, obj, value):
1645        pdtn = obj.section4[1]
1646        obj.section4[self._key[pdtn]+2] = value
1647
1648class UnitOfTimeRangeOfSuccessiveFields:
1649    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1650    _key = {
1651        4: 34,
1652        8: 27,
1653        9: 34,
1654        10: 28,
1655        11: 30,
1656        12: 29,
1657        46: 34,
1658        47: 34,
1659        49: 34,
1660        80: 34,
1661        81: 34,
1662        82: 34,
1663        83: 34,
1664        84: 34,
1665        85: 34
1666    }
1667
1668    def __get__(self, obj, objtype=None):
1669        pdtn = obj.section4[1]
1670        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1671
1672    def __set__(self, obj, value):
1673        pdtn = obj.section4[1]
1674        obj.section4[self._key[pdtn]+2] = value
1675
1676class TimeIncrementOfSuccessiveFields:
1677    """Time Increment of Successive Fields"""
1678    _key = {
1679        4: 35,
1680        8: 28,
1681        9: 35,
1682        10: 29,
1683        11: 31,
1684        12: 30,
1685        46: 67,
1686        47: 67,
1687        49: 67,
1688        80: 35,
1689        81: 35,
1690        82: 35,
1691        83: 35,
1692        84: 35,
1693        85: 35
1694    }
1695
1696    def __get__(self, obj, objtype=None):
1697        pdtn = obj.section4[1]
1698        return obj.section4[self._key[pdtn]+2]
1699
1700    def __set__(self, obj, value):
1701        pdtn = obj.section4[1]
1702        obj.section4[self._key[pdtn]+2] = value
1703class TypeOfStatisticalProcessing:
1704    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1705    _key = {15:16}
1706    def __get__(self, obj, objtype=None):
1707        pdtn = obj.section4[1]
1708        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1709    def __set__(self, obj, value):
1710        pdtn = obj.section4[1]
1711        obj.section4[self._key[pdtn]+2] = value
1712
1713class NumberOfDataPointsForSpatialProcessing:
1714    """Number of Data Points for Spatial Processing"""
1715    _key = {15:17}
1716    def __get__(self, obj, objtype=None):
1717        pdtn = obj.section4[1]
1718        return obj.section4[self._key[pdtn]+2]
1719    def __set__(self, obj, value):
1720        pdtn = obj.section4[1]
1721        obj.section4[self._key[pdtn]+2] = value
1722
1723class NumberOfContributingSpectralBands:
1724    """Number of Contributing Spectral Bands (NB)"""
1725    _key = {32:9}
1726    def __get__(self, obj, objtype=None):
1727        pdtn = obj.section4[1]
1728        return obj.section4[self._key[pdtn]+2]
1729    def __set__(self, obj, value):
1730        pdtn = obj.section4[1]
1731        obj.section4[self._key[pdtn]+2] = value
1732
1733class SatelliteSeries:
1734    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1735    _key = {32:10}
1736    def __get__(self, obj, objtype=None):
1737        pdtn = obj.section4[1]
1738        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1739    def __set__(self, obj, value):
1740        pass
1741
1742class SatelliteNumber:
1743    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1744    _key = {32:11}
1745    def __get__(self, obj, objtype=None):
1746        pdtn = obj.section4[1]
1747        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1748    def __set__(self, obj, value):
1749        pass
1750
1751class InstrumentType:
1752    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1753    _key = {32:12}
1754    def __get__(self, obj, objtype=None):
1755        pdtn = obj.section4[1]
1756        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1757    def __set__(self, obj, value):
1758        pass
1759
1760class ScaleFactorOfCentralWaveNumber:
1761    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1762    _key = {32:13}
1763    def __get__(self, obj, objtype=None):
1764        pdtn = obj.section4[1]
1765        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1766    def __set__(self, obj, value):
1767        pass
1768
1769class ScaledValueOfCentralWaveNumber:
1770    """Scaled Value Of Central WaveNumber of band NB"""
1771    _key = {32:14}
1772    def __get__(self, obj, objtype=None):
1773        pdtn = obj.section4[1]
1774        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1775    def __set__(self, obj, value):
1776        pass
1777
1778class CetralWaveNumber:
1779    """Central WaveNumber of band NB"""
1780    def __get__(self, obj, objtype=None):
1781        scale_factor = getattr(obj, "scaleFactorOfCentralWaveNumber")
1782        scaled_value = getattr(obj, "scaledValueOfCentralWaveNumber")
1783        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1784    def __set__(self, obj, value):
1785        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1786        setattr(obj, "scaleFactorOfCentralWaveNumber", scale_factor)
1787        setattr(obj, "scaledValueOfCentralWaveNumber", scaled_value)
1788
1789class TypeOfAerosol:
1790    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1791    _key = {46:2, 48:2}
1792    def __get__(self, obj, objtype=None):
1793        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1794    def __set__(self, obj, value):
1795        obj.section4[self._key[obj.pdtn]+2] = value
1796
1797class TypeOfIntervalForAerosolSize:
1798    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1799    _key = {46:3, 48:3}
1800    def __get__(self, obj, objtype=None):
1801        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1802    def __set__(self, obj, value):
1803        obj.section4[self._key[obj.pdtn]+2] = value
1804
1805class ScaleFactorOfFirstSize:
1806    """Scale Factor of First Size"""
1807    _key = {46:4, 48:4}
1808    def __get__(self, obj, objtype=None):
1809        return obj.section4[self._key[obj.pdtn]+2]
1810    def __set__(self, obj, value):
1811        obj.section4[self._key[obj.pdtn]+2] = value
1812
1813class ScaledValueOfFirstSize:
1814    """Scaled Value of First Size"""
1815    _key = {46:5, 48:5}
1816    def __get__(self, obj, objtype=None):
1817        return obj.section4[self._key[obj.pdtn]+2]
1818    def __set__(self, obj, value):
1819        obj.section4[self._key[obj.pdtn]+2] = value
1820
1821class FirstSizeOfAerosol:
1822    """First size of Aerosol"""
1823    def __get__(self, obj, objtype=None):
1824        scale_factor = getattr(obj, "scaleFactorOfFirstSize")
1825        scaled_value = getattr(obj, "scaledValueOfFirstSize")
1826        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1827    def __set__(self, obj, value):
1828        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1829        setattr(obj, "scaleFactorOfFirstSize", scale_factor)
1830        setattr(obj, "scaledValueOfFirstSize", scaled_value)
1831
1832class ScaleFactorOfSecondSize:
1833    """Scale Factor of Second Size"""
1834    _key = {46:6, 48:6}
1835    def __get__(self, obj, objtype=None):
1836        return obj.section4[self._key[obj.pdtn]+2]
1837    def __set__(self, obj, value):
1838        obj.section4[self._key[obj.pdtn]+2] = value
1839
1840class ScaledValueOfSecondSize:
1841    """Scaled Value of Second Size"""
1842    _key = {46:6, 48:7}
1843    def __get__(self, obj, objtype=None):
1844        return obj.section4[self._key[obj.pdtn]+2]
1845    def __set__(self, obj, value):
1846        obj.section4[self._key[obj.pdtn]+2] = value
1847
1848class SecondSizeOfAerosol:
1849    """Second size of Aerosol"""
1850    def __get__(self, obj, objtype=None):
1851        scale_factor = getattr(obj, "scaleFactorOfSecondSize")
1852        scaled_value = getattr(obj, "scaledValueOfSecondSize")
1853        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1854    def __set__(self, obj, value):
1855        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1856        setattr(obj, "scaleFactorOfSecondSize", scale_factor)
1857        setattr(obj, "scaledValueOfSecondSize", scaled_value)
1858
1859class TypeOfIntervalForAerosolWavelength:
1860    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1861    _key = {48:8}
1862    def __get__(self, obj, objtype=None):
1863        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1864    def __set__(self, obj, value):
1865        obj.section4[self._key[obj.pdtn]+2] = value
1866
1867class ScaleFactorOfFirstWavelength:
1868    """Scale Factor of First Wavelength"""
1869    _key = {48:9}
1870    def __get__(self, obj, objtype=None):
1871        return obj.section4[self._key[obj.pdtn]+2]
1872    def __set__(self, obj, value):
1873        obj.section4[self._key[obj.pdtn]+2] = value
1874
1875class ScaledValueOfFirstWavelength:
1876    """Scaled Value of First Wavelength"""
1877    _key = {48:10}
1878    def __get__(self, obj, objtype=None):
1879        return obj.section4[self._key[obj.pdtn]+2]
1880    def __set__(self, obj, value):
1881        obj.section4[self._key[obj.pdtn]+2] = value
1882
1883class FirstWavelength:
1884    """First Wavelength"""
1885    def __get__(self, obj, objtype=None):
1886        scale_factor = getattr(obj, "scaleFactorOfFirstWavelength")
1887        scaled_value = getattr(obj, "scaledValueOfFirstWavelength")
1888        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1889    def __set__(self, obj, value):
1890        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1891        setattr(obj, "scaleFactorOfFirstWavelength", scale_factor)
1892        setattr(obj, "scaledValueOfFirstWavelength", scaled_value)
1893
1894class ScaleFactorOfSecondWavelength:
1895    """Scale Factor of Second Wavelength"""
1896    _key = {48:11}
1897    def __get__(self, obj, objtype=None):
1898        return obj.section4[self._key[obj.pdtn]+2]
1899    def __set__(self, obj, value):
1900        obj.section4[self._key[obj.pdtn]+2] = value
1901
1902class ScaledValueOfSecondWavelength:
1903    """Scaled Value of Second Wavelength"""
1904    _key = {48:12}
1905    def __get__(self, obj, objtype=None):
1906        return obj.section4[self._key[obj.pdtn]+2]
1907    def __set__(self, obj, value):
1908        obj.section4[self._key[obj.pdtn]+2] = value
1909
1910class SecondWavelength:
1911    """Second Wavelength"""
1912    def __get__(self, obj, objtype=None):
1913        scale_factor = getattr(obj, "scaleFactorOfSecondWavelength")
1914        scaled_value = getattr(obj, "scaledValueOfSecondWavelength")
1915        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1916    def __set__(self, obj, value):
1917        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1918        setattr(obj, "scaleFactorOfSecondWavelength", scale_factor)
1919        setattr(obj, "scaledValueOfSecondWavelength", scaled_value)
1920
1921class SourceSinkIndicator:
1922    """[Source/Sink Indicator](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-238.shtml)"""
1923    _key = {80:3, 81:3, 82:3, 83:3, 84:3, 85:3}
1924    def __get__(self, obj, objtype=None):
1925        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.238')
1926    def __set__(self, obj, value):
1927        obj.section4[self._key[obj.pdtn]+2] = value
1928
1929class NumberOfContributingSpectralBands:
1930    """Number of contributing spectral bands (NB)"""
1931    def __get__(self, obj, objtype=None):
1932        return obj.section4[9]
1933    def __set__(self, obj, value):
1934        obj.section4[9] = value
1935
1936class ConstituentType:
1937    """[Constituent Type](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-230.shtml)"""
1938    _key = defaultdict(lambda: 10)
1939    def __get__(self, obj, objtype=None):
1940        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.230')
1941    def __set__(self, obj, value):
1942        obj.section4[self._key[obj.pdtn]+2] = value
1943
1944class NumberOfContributingSpectralBands:
1945    """Number of Contributing Spectral Bands"""
1946    _key = defaultdict(lambda: 9)
1947    def __get__(self, obj, objtype=None):
1948        return obj.section4[self._key[obj.pdtn]+2]
1949    def __set__(self, obj, value):
1950        obj.section4[self._key[obj.pdtn]+2] = value
1951
1952class SatelliteSeries:
1953    """Satellite Series"""
1954    def __get__(self, obj, objtype=None):
1955        nb = obj.section4[9]  # Get number of bands
1956        values = []
1957        for i in range(nb):
1958            offset = 11 * i
1959            values.append(obj.section4[11 + offset])
1960        return values
1961    def __set__(self, obj, value):
1962        nb = obj.section4[9]
1963        for i in range(nb):
1964            offset = 11 * i
1965            obj.section4[11 + offset] = value[i]
1966
1967
1968"""
1969GRIB2 Section 4, Product Definition Template Classes
1970"""
1971
1972@dataclass(init=False)
1973class ProductDefinitionTemplateBase:
1974    """Base attributes for Product Definition Templates"""
1975    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1976    fullName: str = field(init=False, repr=False, default=FullName())
1977    units: str = field(init=False, repr=False, default=Units())
1978    shortName: str = field(init=False, repr=False, default=ShortName())
1979    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1980    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1981    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1982    level: str = field(init=False, repr=False, default=Level())
1983    # Begin template here...
1984    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1985    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1986    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1987    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1988    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1989    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1990    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1991    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1992    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1993
1994    @classmethod
1995    def _attrs(cls):
1996        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
1997
1998@dataclass(init=False)
1999class ProductDefinitionTemplateSurface:
2000    """Surface attributes for Product Definition Templates"""
2001    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
2002    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
2003    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
2004    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
2005    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
2006    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
2007    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
2008    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
2009    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
2010    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
2011    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
2012    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
2013
2014    @classmethod
2015    def _attrs(cls):
2016        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2017
2018@dataclass(init=False)
2019class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2020    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
2021    _len = 15
2022    _num = 0
2023
2024    @classmethod
2025    def _attrs(cls):
2026        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2027
2028@dataclass(init=False)
2029class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2030    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
2031    _len = 18
2032    _num = 1
2033    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2034    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2035    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2036
2037    @classmethod
2038    def _attrs(cls):
2039        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2040
2041@dataclass(init=False)
2042class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2043    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
2044    _len = 17
2045    _num = 2
2046    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
2047    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2048
2049    @classmethod
2050    def _attrs(cls):
2051        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2052
2053@dataclass(init=False)
2054class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2055    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
2056    _len = 22
2057    _num = 5
2058    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
2059    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
2060    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
2061    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
2062    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
2063    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
2064    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
2065    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
2066    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
2067    threshold: str = field(init=False, repr=False, default=Threshold())
2068
2069    @classmethod
2070    def _attrs(cls):
2071        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2072
2073@dataclass(init=False)
2074class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2075    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
2076    _len = 16
2077    _num = 6
2078    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
2079
2080    @classmethod
2081    def _attrs(cls):
2082        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2083
2084@dataclass(init=False)
2085class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2086    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
2087    _len = 29
2088    _num = 8
2089    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2090    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2091    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2092    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2093    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2094    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2095    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2096    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2097    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2098    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2099    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2100    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2101    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2102    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2103
2104    @classmethod
2105    def _attrs(cls):
2106        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2107
2108@dataclass(init=False)
2109class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2110    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
2111    _len = 36
2112    _num = 9
2113    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
2114    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
2115    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
2116    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
2117    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
2118    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
2119    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
2120    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
2121    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
2122    threshold: str = field(init=False, repr=False, default=Threshold())
2123    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2124    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2125    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2126    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2127    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2128    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2129    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2130    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2131    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2132    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2133    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2134    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2135    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2136    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2137
2138    @classmethod
2139    def _attrs(cls):
2140        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2141
2142@dataclass(init=False)
2143class ProductDefinitionTemplate10(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2144    """[Product Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-10.shtml)"""
2145    _len = 30
2146    _num = 10
2147    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
2148    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2149    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2150    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2151    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2152    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2153    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2154    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2155    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2156    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2157    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2158    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2159    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2160    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2161    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2162
2163    @classmethod
2164    def _attrs(cls):
2165        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2166
2167@dataclass(init=False)
2168class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2169    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
2170    _len = 32
2171    _num = 11
2172    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2173    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2174    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2175    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2176    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2177    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2178    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2179    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2180    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2181    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2182    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2183    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2184    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2185    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2186    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2187    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2188    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2189
2190    @classmethod
2191    def _attrs(cls):
2192        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2193
2194@dataclass(init=False)
2195class ProductDefinitionTemplate12(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2196    """[Product Definition Template 12](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-12.shtml)"""
2197    _len = 31
2198    _num = 12
2199    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
2200    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2201    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2202    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2203    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2204    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2205    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2206    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2207    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2208    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2209    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2210    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2211    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2212    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2213    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2214    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2215
2216    @classmethod
2217    def _attrs(cls):
2218        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2219
2220@dataclass(init=False)
2221class ProductDefinitionTemplate13(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2222    """[Product Definition Template 13](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-13.shtml)"""
2223    _len = 18
2224    _num = 13
2225    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2226    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2227    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2228    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2229    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2230    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2231    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2232    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2233
2234    @classmethod
2235    def _attrs(cls):
2236        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2237
2238@dataclass(init=False)
2239class ProductDefinitionTemplate14(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2240    """[Product Definition Template 14](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-14.shtml)"""
2241    _len = 18
2242    _num = 14
2243    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2244    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2245    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2246    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2247    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2248    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2249    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2250    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2251
2252    @classmethod
2253    def _attrs(cls):
2254        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2255
2256@dataclass(init=False)
2257class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2258    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
2259    _len = 18
2260    _num = 15
2261    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2262    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2263    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2264
2265    @classmethod
2266    def _attrs(cls):
2267        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2268
2269# @dataclass(init=False)
2270# class ProductDefinitionTemplate20(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2271#     """[Product Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-20.shtml)"""
2272#     __slots__ = ('section4',)
2273#     _len = 19
2274#     _num = 20
2275
2276#     typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2277#     unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2278#     timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2279#     unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2280#     timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2281#     statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2282#     spatialProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfSpatialProcessing())
2283#     numberOfPointsUsed: int = field(init=False, repr=False, default=NumberOfPointsUsed())
2284
2285@dataclass(init=False)
2286class ProductDefinitionTemplate31:
2287    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
2288    _len = 5
2289    _num = 31
2290    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
2291    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
2292    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
2293    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
2294    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2295    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2296    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2297    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2298    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2299    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2300
2301    @classmethod
2302    def _attrs(cls):
2303        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2304
2305@dataclass(init=False)
2306class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
2307    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
2308    _len = 10
2309    _num = 32
2310    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2311    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2312    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2313    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2314    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2315    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2316
2317    @classmethod
2318    def _attrs(cls):
2319        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2320
2321# @dataclass(init=False)
2322# class ProductDefinitionTemplate33(ProductDefinitionTemplateBase):
2323#     """[Product Definition Template 33] - Individual ensemble forecast, control and perturbed at intervals"""
2324#     _len = None  # Length depends on number of spectral bands
2325#     _num = 33
2326#     # Note: parameterCategory through valueOfForecastTime inherited from base class
2327#     numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2328#     # Spectral band fields - these will need special handling since they repeat
2329#     satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2330#     satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2331#     instrumentTypes: list = field(init=False,repr=False,default=InstrumentTypes())
2332#     scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2333#     scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2334#     # Continue with remaining fields
2335#     typeOfEnsembleForecast: Grib2Metadata = field(init=False,repr=False,default=TypeOfEnsembleForecast())
2336#     perturbationNumber: int = field(init=False,repr=False,default=PerturbationNumber())
2337#     numberOfForecastsInEnsemble: int = field(init=False,repr=False,default=NumberOfForecastsInEnsemble())
2338#     yearOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=YearOfEndOfOverallTimeInterval())
2339#     monthOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MonthOfEndOfOverallTimeInterval())
2340#     dayOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=DayOfEndOfOverallTimeInterval())
2341#     hourOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=HourOfEndOfOverallTimeInterval())
2342#     minuteOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MinuteOfEndOfOverallTimeInterval())
2343#     secondOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=SecondOfEndOfOverallTimeInterval())
2344#     numberOfTimeRange: int = field(init=False,repr=False,default=NumberOfTimeRange())
2345#     numberOfMissingInStatisticalProcess: int = field(init=False,repr=False,default=NumberOfMissingInStatisticalProcess())
2346# @dataclass(init=False)
2347# class ProductDefinitionTemplate34(ProductDefinitionTemplateBase):
2348#     """[Product Definition Template 34] - Individual ensemble forecast, control and perturbed at intervals - chemical"""
2349#     _len = None  # Length depends on number of spectral bands
2350#     _num = 34
2351#     constituentType: int = field(init=False,repr=False,default=ConstituentType())
2352#     numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2353#     # For each band nb=1 to NB:
2354#     satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2355#     satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2356#     instrumentTypes: list = field(init=False,repr=False,default=InstrumentTypes())
2357#     scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2358#     scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2359#     # After spectral bands:
2360#     typeOfEnsembleForecast: int = field(init=False,repr=False,default=TypeOfEnsembleForecast())
2361#     perturbationNumber: int = field(init=False,repr=False,default=PerturbationNumber())
2362#     numberOfForecastsInEnsemble: int = field(init=False,repr=False,default=NumberOfForecastsInEnsemble())
2363#     yearOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=YearOfEndOfOverallTimeInterval())
2364#     monthOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MonthOfEndOfOverallTimeInterval())
2365#     dayOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=DayOfEndOfOverallTimeInterval())
2366#     hourOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=HourOfEndOfOverallTimeInterval())
2367#     minuteOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MinuteOfEndOfOverallTimeInterval())
2368#     secondOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=SecondOfEndOfOverallTimeInterval())
2369#     numberOfTimeRange: int = field(init=False,repr=False,default=NumberOfTimeRange())
2370#     numberOfMissingInStatisticalProcess: int = field(init=False,repr=False,default=NumberOfMissingInStatisticalProcess())
2371
2372# @dataclass(init=False)
2373# class ProductDefinitionTemplate35(ProductDefinitionTemplateBase):
2374#     """[Product Definition Template 35] - Individual ensemble forecast, control and perturbed at intervals - aerosol"""
2375#     _len = None  # Length depends on number of spectral bands
2376#     _num = 35
2377#     aerosolType: int = field(init=False,repr=False,default=AerosolType())
2378#     numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2379#     # For each band nb=1 to NB:
2380#     satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2381#     satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2382#     instrumentTypes: list = field(init=False,repr=False,default=InstrumentTypes())
2383#     scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2384#     scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2385#     # After spectral bands:
2386#     typeOfEnsembleForecast: int = field(init=False,repr=False,default=TypeOfEnsembleForecast())
2387#     perturbationNumber: int = field(init=False,repr=False,default=PerturbationNumber())
2388#     numberOfForecastsInEnsemble: int = field(init=False,repr=False,default=NumberOfForecastsInEnsemble())
2389#     yearOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=YearOfEndOfOverallTimeInterval())
2390#     monthOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MonthOfEndOfOverallTimeInterval())
2391#     dayOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=DayOfEndOfOverallTimeInterval())
2392#     hourOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=HourOfEndOfOverallTimeInterval())
2393#     minuteOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=MinuteOfEndOfOverallTimeInterval())
2394#     secondOfEndOfOverallTimeInterval: int = field(init=False,repr=False,default=SecondOfEndOfOverallTimeInterval())
2395#     numberOfTimeRange: int = field(init=False,repr=False,default=NumberOfTimeRange())
2396#     numberOfMissingInStatisticalProcess: int = field(init=False,repr=False,default=NumberOfMissingInStatisticalProcess())@dataclass(init=False)
2397
2398
2399@dataclass(init=False)
2400class ProductDefinitionTemplate46(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2401    """[Product Definition Template 4.46](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-46.shtml)"""
2402    _len = 38  # Total number of octets
2403    _num = 46
2404
2405    # Aerosol-specific parameters
2406    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2407    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2408    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2409    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2410    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2411    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2412    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2413    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2414
2415    # Time interval parameters
2416    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2417    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2418    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2419    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2420    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2421    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2422    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2423    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2424
2425    # Statistical processing parameters
2426    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2427    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2428    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2429    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2430    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2431    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2432    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2433
2434    @classmethod
2435    def _attrs(cls):
2436        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2437
2438
2439@dataclass(init=False)
2440class ProductDefinitionTemplate47(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2441    """[Product Definition Template 4.47](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-47.shtml)"""
2442    _len = 41  # Total number of octets for base template
2443    _num = 47
2444
2445    # Aerosol parameters
2446    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2447    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2448    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2449    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2450    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2451    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2452    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2453    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2454
2455    # Ensemble parameters
2456    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2457    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2458    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2459
2460    # Time interval parameters
2461    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2462    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2463    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2464    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2465    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2466    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2467    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2468    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2469
2470    # Statistical processing parameters
2471    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2472    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2473    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2474    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2475    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2476    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2477    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2478
2479    @classmethod
2480    def _attrs(cls):
2481        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2482
2483
2484@dataclass(init=False)
2485class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2486    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
2487    _len = 26
2488    _num = 48
2489    # Aerosol parameters
2490    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2491    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2492    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2493    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2494    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2495    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2496    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2497    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2498
2499    # Wavelength parameters
2500    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2501    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2502    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2503    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2504    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2505    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2506    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2507
2508    @classmethod
2509    def _attrs(cls):
2510        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
2511
2512
2513@dataclass(init=False)
2514class ProductDefinitionTemplate49(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2515    """[Product Definition Template 4.49](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-49.shtml)"""
2516    _len = 28
2517    _num = 49
2518
2519    # Aerosol parameters
2520    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2521    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2522    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2523    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2524    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2525    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2526    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2527    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2528
2529    # Wavelength parameters
2530    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2531    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2532    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2533    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2534    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2535    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2536    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2537
2538    # Ensemble parameters
2539    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2540    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2541    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2542
2543@dataclass(init=False)
2544class ProductDefinitionTemplate80(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2545    """[Product Definition Template 4.80](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-80.shtml)"""
2546    _len = 26
2547    _num = 80
2548
2549    # Aerosol parameters
2550    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2551    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2552    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2553    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2554    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2555    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2556    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2557    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2558    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2559
2560    # Wavelength parameters
2561    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2562    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2563    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2564    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2565    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2566    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2567    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2568
2569@dataclass(init=False)
2570class ProductDefinitionTemplate81(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2571    """[Product Definition Template 4.81](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-81.shtml)"""
2572    _len = 31
2573    _num = 81
2574
2575    # Aerosol parameters
2576    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2577    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2578    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2579    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2580    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2581    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2582    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2583    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2584    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2585
2586    # Wavelength parameters
2587    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2588    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2589    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2590    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2591    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2592    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2593    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2594
2595    # Ensemble parameters
2596    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2597    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2598    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2599
2600@dataclass(init=False)
2601class ProductDefinitionTemplate82(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2602    """[Product Definition Template 4.82](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-82.shtml)"""
2603    _len = 41
2604    _num = 82
2605
2606    # Aerosol parameters
2607    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2608    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2609    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2610    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2611    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2612    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2613    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2614    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2615    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2616
2617    # Wavelength parameters
2618    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2619    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2620    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2621    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2622    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2623    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2624    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2625
2626   # Time interval parameters
2627    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2628    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2629    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2630    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2631    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2632    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2633    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2634    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2635
2636    # Statistical processing parameters
2637    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2638    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2639    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2640    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2641    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2642    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2643    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2644    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2645
2646@dataclass(init=False)
2647class ProductDefinitionTemplate83(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2648    """[Product Definition Template 4.83](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-83.shtml)"""
2649    _len = 44
2650    _num = 83
2651
2652    # Aerosol parameters
2653    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2654    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2655    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2656    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2657    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2658    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2659    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2660    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2661    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2662
2663    # Wavelength parameters
2664    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2665    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2666    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2667    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2668    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2669    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2670    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2671
2672    # Ensemble parameters
2673    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2674    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2675    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2676
2677    # Time interval parameters
2678    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2679    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2680    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2681    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2682    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2683    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2684    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2685    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2686
2687@dataclass(init=False)
2688class ProductDefinitionTemplate84(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2689    """[Product Definition Template 4.84](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-84.shtml)"""
2690    _len = 44
2691    _num = 84
2692
2693    # Aerosol parameters
2694    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2695    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2696    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2697    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2698    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2699    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2700    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2701    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2702    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2703
2704    # Wavelength parameters
2705    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2706    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2707    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2708    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2709    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2710    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2711    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2712
2713    # Ensemble parameters
2714    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2715    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2716    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2717
2718    # Time interval parameters
2719    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2720    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2721    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2722    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2723    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2724    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2725
2726    # Statistical processing parameters
2727    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2728    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2729    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2730    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2731    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2732    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2733    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2734    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2735
2736@dataclass(init=False)
2737class ProductDefinitionTemplate85(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2738    """[Product Definition Template 4.85](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-85.shtml)"""
2739    _len = 33
2740    _num = 85
2741
2742    # Aerosol parameters
2743    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2744    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2745    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2746    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2747    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2748    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2749    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2750    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2751    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2752
2753    # Wavelength parameters
2754    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2755    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2756    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2757    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2758    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2759    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2760    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2761
2762    # Ensemble parameters
2763    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2764    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2765    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2766
2767_pdt_by_pdtn = {
2768    0: ProductDefinitionTemplate0,
2769    1: ProductDefinitionTemplate1,
2770    2: ProductDefinitionTemplate2,
2771    5: ProductDefinitionTemplate5,
2772    6: ProductDefinitionTemplate6,
2773    8: ProductDefinitionTemplate8,
2774    9: ProductDefinitionTemplate9,
2775    10: ProductDefinitionTemplate10,
2776    11: ProductDefinitionTemplate11,
2777    12: ProductDefinitionTemplate12,
2778    15: ProductDefinitionTemplate15,
2779    31: ProductDefinitionTemplate31,
2780    32: ProductDefinitionTemplate32,
2781    46: ProductDefinitionTemplate46,
2782    47: ProductDefinitionTemplate47,
2783    48: ProductDefinitionTemplate48,
2784    49: ProductDefinitionTemplate49,
2785    80: ProductDefinitionTemplate80,
2786    81: ProductDefinitionTemplate81,
2787    82: ProductDefinitionTemplate82,
2788    83: ProductDefinitionTemplate83,
2789    84: ProductDefinitionTemplate84,
2790    85: ProductDefinitionTemplate85,
2791    }
2792
2793def pdt_class_by_pdtn(pdtn: int):
2794    """
2795    Provide a Product Definition Template class via the template number.
2796
2797    Parameters
2798    ----------
2799    pdtn
2800        Product definition template number.
2801
2802    Returns
2803    -------
2804    pdt_class_by_pdtn
2805        Product definition template class object (not an instance).
2806    """
2807    return _pdt_by_pdtn[pdtn]
2808
2809# ----------------------------------------------------------------------------------------
2810# Descriptor Classes for Section 5 metadata.
2811# ----------------------------------------------------------------------------------------
2812class NumberOfPackedValues:
2813    """Number of Packed Values"""
2814    def __get__(self, obj, objtype=None):
2815        return obj.section5[0]
2816    def __set__(self, obj, value):
2817        pass
2818
2819class DataRepresentationTemplateNumber:
2820    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
2821    def __get__(self, obj, objtype=None):
2822        return Grib2Metadata(obj.section5[1],table='5.0')
2823    def __set__(self, obj, value):
2824        pass
2825
2826class DataRepresentationTemplate:
2827    """Data Representation Template"""
2828    def __get__(self, obj, objtype=None):
2829        return obj.section5[2:]
2830    def __set__(self, obj, value):
2831        raise NotImplementedError
2832
2833class RefValue:
2834    """Reference Value (represented as an IEEE 32-bit floating point value)"""
2835    def __get__(self, obj, objtype=None):
2836        return utils.ieee_int_to_float(obj.section5[0+2])
2837    def __set__(self, obj, value):
2838        pass
2839
2840class BinScaleFactor:
2841    """Binary Scale Factor"""
2842    def __get__(self, obj, objtype=None):
2843        return obj.section5[1+2]
2844    def __set__(self, obj, value):
2845        obj.section5[1+2] = value
2846
2847class DecScaleFactor:
2848    """Decimal Scale Factor"""
2849    def __get__(self, obj, objtype=None):
2850        return obj.section5[2+2]
2851    def __set__(self, obj, value):
2852        obj.section5[2+2] = value
2853
2854class NBitsPacking:
2855    """Minimum number of bits for packing"""
2856    def __get__(self, obj, objtype=None):
2857        return obj.section5[3+2]
2858    def __set__(self, obj, value):
2859        obj.section5[3+2] = value
2860
2861class TypeOfValues:
2862    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2863    def __get__(self, obj, objtype=None):
2864        return Grib2Metadata(obj.section5[4+2],table='5.1')
2865    def __set__(self, obj, value):
2866        obj.section5[4+2] = value
2867
2868class GroupSplittingMethod:
2869    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2870    def __get__(self, obj, objtype=None):
2871        return Grib2Metadata(obj.section5[5+2],table='5.4')
2872    def __set__(self, obj, value):
2873        obj.section5[5+2] = value
2874
2875class TypeOfMissingValueManagement:
2876    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2877    def __get__(self, obj, objtype=None):
2878        return Grib2Metadata(obj.section5[6+2],table='5.5')
2879    def __set__(self, obj, value):
2880        obj.section5[6+2] = value
2881
2882class PriMissingValue:
2883    """Primary Missing Value"""
2884    def __get__(self, obj, objtype=None):
2885        if obj.typeOfValues == 0:
2886            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
2887        elif obj.typeOfValues == 1:
2888            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2889    def __set__(self, obj, value):
2890        if obj.typeOfValues == 0:
2891            obj.section5[7+2] = utils.ieee_float_to_int(value)
2892        elif self.typeOfValues == 1:
2893            obj.section5[7+2] = int(value)
2894        obj.section5[6+2] = 1
2895
2896class SecMissingValue:
2897    """Secondary Missing Value"""
2898    def __get__(self, obj, objtype=None):
2899        if obj.typeOfValues == 0:
2900            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
2901        elif obj.typeOfValues == 1:
2902            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2903    def __set__(self, obj, value):
2904        if obj.typeOfValues == 0:
2905            obj.section5[8+2] = utils.ieee_float_to_int(value)
2906        elif self.typeOfValues == 1:
2907            obj.section5[8+2] = int(value)
2908        obj.section5[6+2] = 2
2909
2910class NGroups:
2911    """Number of Groups"""
2912    def __get__(self, obj, objtype=None):
2913        return obj.section5[9+2]
2914    def __set__(self, obj, value):
2915        pass
2916
2917class RefGroupWidth:
2918    """Reference Group Width"""
2919    def __get__(self, obj, objtype=None):
2920        return obj.section5[10+2]
2921    def __set__(self, obj, value):
2922        pass
2923
2924class NBitsGroupWidth:
2925    """Number of bits for Group Width"""
2926    def __get__(self, obj, objtype=None):
2927        return obj.section5[11+2]
2928    def __set__(self, obj, value):
2929        pass
2930
2931class RefGroupLength:
2932    """Reference Group Length"""
2933    def __get__(self, obj, objtype=None):
2934        return obj.section5[12+2]
2935    def __set__(self, obj, value):
2936        pass
2937
2938class GroupLengthIncrement:
2939    """Group Length Increment"""
2940    def __get__(self, obj, objtype=None):
2941        return obj.section5[13+2]
2942    def __set__(self, obj, value):
2943        pass
2944
2945class LengthOfLastGroup:
2946    """Length of Last Group"""
2947    def __get__(self, obj, objtype=None):
2948        return obj.section5[14+2]
2949    def __set__(self, obj, value):
2950        pass
2951
2952class NBitsScaledGroupLength:
2953    """Number of bits of Scaled Group Length"""
2954    def __get__(self, obj, objtype=None):
2955        return obj.section5[15+2]
2956    def __set__(self, obj, value):
2957        pass
2958
2959class SpatialDifferenceOrder:
2960    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2961    def __get__(self, obj, objtype=None):
2962        return Grib2Metadata(obj.section5[16+2],table='5.6')
2963    def __set__(self, obj, value):
2964        obj.section5[16+2] = value
2965
2966class NBytesSpatialDifference:
2967    """Number of bytes for Spatial Differencing"""
2968    def __get__(self, obj, objtype=None):
2969        return obj.section5[17+2]
2970    def __set__(self, obj, value):
2971        pass
2972
2973class Precision:
2974    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2975    def __get__(self, obj, objtype=None):
2976        return Grib2Metadata(obj.section5[0+2],table='5.7')
2977    def __set__(self, obj, value):
2978        obj.section5[0+2] = value
2979
2980class TypeOfCompression:
2981    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2982    def __get__(self, obj, objtype=None):
2983        return Grib2Metadata(obj.section5[5+2],table='5.40')
2984    def __set__(self, obj, value):
2985        obj.section5[5+2] = value
2986
2987class TargetCompressionRatio:
2988    """Target Compression Ratio"""
2989    def __get__(self, obj, objtype=None):
2990        return obj.section5[6+2]
2991    def __set__(self, obj, value):
2992        pass
2993
2994class RealOfCoefficient:
2995    """Real of Coefficient"""
2996    def __get__(self, obj, objtype=None):
2997        return utils.ieee_int_to_float(obj.section5[4+2])
2998    def __set__(self, obj, value):
2999        obj.section5[4+2] = utils.ieee_float_to_int(float(value))
3000
3001class CompressionOptionsMask:
3002    """Compression Options Mask for AEC/CCSDS"""
3003    def __get__(self, obj, objtype=None):
3004        return obj.section5[5+2]
3005    def __set__(self, obj, value):
3006        obj.section5[5+2] = value
3007
3008class BlockSize:
3009    """Block Size for AEC/CCSDS"""
3010    def __get__(self, obj, objtype=None):
3011        return obj.section5[6+2]
3012    def __set__(self, obj, value):
3013        obj.section5[6+2] = value
3014
3015class RefSampleInterval:
3016    """Reference Sample Interval for AEC/CCSDS"""
3017    def __get__(self, obj, objtype=None):
3018        return obj.section5[7+2]
3019    def __set__(self, obj, value):
3020        obj.section5[7+2] = value
3021
3022@dataclass(init=False)
3023class DataRepresentationTemplate0:
3024    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
3025    _len = 5
3026    _num = 0
3027    _packingScheme = 'simple'
3028    refValue: float = field(init=False, repr=False, default=RefValue())
3029    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3030    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3031    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3032
3033    @classmethod
3034    def _attrs(cls):
3035        return list(cls.__dataclass_fields__.keys())
3036
3037@dataclass(init=False)
3038class DataRepresentationTemplate2:
3039    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
3040    _len = 16
3041    _num = 2
3042    _packingScheme = 'complex'
3043    refValue: float = field(init=False, repr=False, default=RefValue())
3044    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3045    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3046    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3047    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
3048    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
3049    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
3050    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
3051    nGroups: int = field(init=False, repr=False, default=NGroups())
3052    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
3053    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
3054    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
3055    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
3056    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
3057    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
3058
3059    @classmethod
3060    def _attrs(cls):
3061        return list(cls.__dataclass_fields__.keys())
3062
3063@dataclass(init=False)
3064class DataRepresentationTemplate3:
3065    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
3066    _len = 18
3067    _num = 3
3068    _packingScheme = 'complex-spdiff'
3069    refValue: float = field(init=False, repr=False, default=RefValue())
3070    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3071    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3072    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3073    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
3074    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
3075    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
3076    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
3077    nGroups: int = field(init=False, repr=False, default=NGroups())
3078    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
3079    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
3080    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
3081    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
3082    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
3083    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
3084    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
3085    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
3086
3087    @classmethod
3088    def _attrs(cls):
3089        return list(cls.__dataclass_fields__.keys())
3090
3091@dataclass(init=False)
3092class DataRepresentationTemplate4:
3093    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
3094    _len = 1
3095    _num = 4
3096    _packingScheme = 'ieee-float'
3097    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
3098
3099    @classmethod
3100    def _attrs(cls):
3101        return list(cls.__dataclass_fields__.keys())
3102
3103@dataclass(init=False)
3104class DataRepresentationTemplate40:
3105    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
3106    _len = 7
3107    _num = 40
3108    _packingScheme = 'jpeg'
3109    refValue: float = field(init=False, repr=False, default=RefValue())
3110    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3111    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3112    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3113    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
3114    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
3115
3116    @classmethod
3117    def _attrs(cls):
3118        return list(cls.__dataclass_fields__.keys())
3119
3120@dataclass(init=False)
3121class DataRepresentationTemplate41:
3122    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
3123    _len = 5
3124    _num = 41
3125    _packingScheme = 'png'
3126    refValue: float = field(init=False, repr=False, default=RefValue())
3127    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3128    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3129    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3130
3131    @classmethod
3132    def _attrs(cls):
3133        return list(cls.__dataclass_fields__.keys())
3134
3135@dataclass(init=False)
3136class DataRepresentationTemplate42:
3137    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
3138    _len = 8
3139    _num = 42
3140    _packingScheme = 'aec'
3141    refValue: float = field(init=False, repr=False, default=RefValue())
3142    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3143    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3144    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3145    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
3146    blockSize: int = field(init=False, repr=False, default=BlockSize())
3147    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
3148
3149    @classmethod
3150    def _attrs(cls):
3151        return list(cls.__dataclass_fields__.keys())
3152
3153@dataclass(init=False)
3154class DataRepresentationTemplate50:
3155    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
3156    _len = 5
3157    _num = 0
3158    _packingScheme = 'spectral-simple'
3159    refValue: float = field(init=False, repr=False, default=RefValue())
3160    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3161    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3162    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3163    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
3164
3165    @classmethod
3166    def _attrs(cls):
3167        return list(cls.__dataclass_fields__.keys())
3168
3169_drt_by_drtn = {
3170    0: DataRepresentationTemplate0,
3171    2: DataRepresentationTemplate2,
3172    3: DataRepresentationTemplate3,
3173    4: DataRepresentationTemplate4,
3174    40: DataRepresentationTemplate40,
3175    41: DataRepresentationTemplate41,
3176    42: DataRepresentationTemplate42,
3177    50: DataRepresentationTemplate50,
3178    }
3179
3180def drt_class_by_drtn(drtn: int):
3181    """
3182    Provide a Data Representation Template class via the template number.
3183
3184    Parameters
3185    ----------
3186    drtn
3187        Data Representation template number.
3188
3189    Returns
3190    -------
3191    drt_class_by_drtn
3192        Data Representation template class object (not an instance).
3193    """
3194    return _drt_by_drtn[drtn]
class Grib2Metadata:
 58class Grib2Metadata:
 59    """
 60    Class to hold GRIB2 metadata.
 61
 62    Stores both numeric code value as stored in GRIB2 and its plain language
 63    definition.
 64
 65    Attributes
 66    ----------
 67    value : int
 68        GRIB2 metadata integer code value.
 69    table : str, optional
 70        GRIB2 table to lookup the `value`. Default is None.
 71    definition : str
 72        Plain language description of numeric metadata.
 73    """
 74    __slots__ = ('value','table')
 75
 76    def __init__(self, value, table=None):
 77        self.value = int(value)
 78        self.table = table
 79
 80    def __call__(self):
 81        return self.value
 82
 83    def __hash__(self):
 84        # AS- added hash() to self.value as pandas was raising error about some
 85        # non integer returns from hash method
 86        return hash(self.value)
 87
 88    def __repr__(self):
 89        return f"{self.__class__.__name__}({self.value}, table = '{self.table}')"
 90
 91    def __str__(self):
 92        return f'{self.value} - {self.definition}'
 93
 94    def __eq__(self,other):
 95        return self.value == other or self.definition[0] == other
 96
 97    def __gt__(self,other):
 98        return self.value > other
 99
100    def __ge__(self,other):
101        return self.value >= other
102
103    def __lt__(self,other):
104        return self.value < other
105
106    def __le__(self,other):
107        return self.value <= other
108
109    def __contains__(self,other):
110        return other in self.definition
111
112    def __hash__(self):
113        return hash(self.value)
114
115    def __index__(self):
116        return int(self.value)
117
118    @property
119    def definition(self):
120        """Provide the definition of the numeric metadata."""
121        return tables.get_value_from_table(self.value,self.table)
122
123    def show_table(self):
124        """Provide the table related to this metadata."""
125        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)
76    def __init__(self, value, table=None):
77        self.value = int(value)
78        self.table = table
value
table
definition
118    @property
119    def definition(self):
120        """Provide the definition of the numeric metadata."""
121        return tables.get_value_from_table(self.value,self.table)

Provide the definition of the numeric metadata.

def show_table(self):
123    def show_table(self):
124        """Provide the table related to this metadata."""
125        return tables.get_table(self.table)

Provide the table related to this metadata.

class IndicatorSection:
130class IndicatorSection:
131    """
132    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
133    """
134    def __get__(self, obj, objtype=None):
135        return obj.section0
136    def __set__(self, obj, value):
137        obj.section0 = value
class Discipline:
139class Discipline:
140    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
141    def __get__(self, obj, objtype=None):
142        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
143    def __set__(self, obj, value):
144        obj.section0[2] = value
class IdentificationSection:
150class IdentificationSection:
151    """
152    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
153    """
154    def __get__(self, obj, objtype=None):
155        return obj.section1
156    def __set__(self, obj, value):
157        obj.section1 = value

GRIB2 Section 1, Identification Section

class OriginatingCenter:
159class OriginatingCenter:
160    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
161    def __get__(self, obj, objtype=None):
162        return Grib2Metadata(obj.section1[0],table='originating_centers')
163    def __set__(self, obj, value):
164        obj.section1[0] = value
class OriginatingSubCenter:
166class OriginatingSubCenter:
167    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
168    def __get__(self, obj, objtype=None):
169        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
170    def __set__(self, obj, value):
171        obj.section1[1] = value
class MasterTableInfo:
173class MasterTableInfo:
174    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
175    def __get__(self, obj, objtype=None):
176        return Grib2Metadata(obj.section1[2],table='1.0')
177    def __set__(self, obj, value):
178        obj.section1[2] = value
class LocalTableInfo:
180class LocalTableInfo:
181    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
182    def __get__(self, obj, objtype=None):
183        return Grib2Metadata(obj.section1[3],table='1.1')
184    def __set__(self, obj, value):
185        obj.section1[3] = value
class SignificanceOfReferenceTime:
187class SignificanceOfReferenceTime:
188    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
189    def __get__(self, obj, objtype=None):
190        return Grib2Metadata(obj.section1[4],table='1.2')
191    def __set__(self, obj, value):
192        obj.section1[4] = value
class Year:
194class Year:
195    """Year of reference time"""
196    def __get__(self, obj, objtype=None):
197        return obj.section1[5]
198    def __set__(self, obj, value):
199        rd = copy.copy(obj.section1[5:11])
200        rd[0] = value
201        # Test validity of datetime values
202        _ = datetime.datetime(*rd)
203        obj.section1[5] = value

Year of reference time

class Month:
205class Month:
206    """Month of reference time"""
207    def __get__(self, obj, objtype=None):
208        return obj.section1[6]
209    def __set__(self, obj, value):
210        rd = copy.copy(obj.section1[5:11])
211        rd[1] = value
212        # Test validity of datetime values
213        _ = datetime.datetime(*rd)
214        obj.section1[6] = value

Month of reference time

class Day:
216class Day:
217    """Day of reference time"""
218    def __get__(self, obj, objtype=None):
219        return obj.section1[7]
220    def __set__(self, obj, value):
221        rd = copy.copy(obj.section1[5:11])
222        rd[2] = value
223        # Test validity of datetime values
224        _ = datetime.datetime(*rd)
225        obj.section1[7] = value

Day of reference time

class Hour:
227class Hour:
228    """Hour of reference time"""
229    def __get__(self, obj, objtype=None):
230        return obj.section1[8]
231    def __set__(self, obj, value):
232        rd = copy.copy(obj.section1[5:11])
233        rd[3] = value
234        # Test validity of datetime values
235        _ = datetime.datetime(*rd)
236        obj.section1[8] = value

Hour of reference time

class Minute:
238class Minute:
239    """Minute of reference time"""
240    def __get__(self, obj, objtype=None):
241        return obj.section1[9]
242    def __set__(self, obj, value):
243        rd = copy.copy(obj.section1[5:11])
244        rd[4] = value
245        # Test validity of datetime values
246        _ = datetime.datetime(*rd)
247        obj.section1[9] = value

Minute of reference time

class Second:
249class Second:
250    """Second of reference time"""
251    def __get__(self, obj, objtype=None):
252        return obj.section1[10]
253    def __set__(self, obj, value):
254        rd = copy.copy(obj.section1[5:11])
255        rd[5] = value
256        # Test validity of datetime values
257        _ = datetime.datetime(*rd)
258        obj.section1[10] = value

Second of reference time

class RefDate:
260class RefDate:
261    """Reference Date. NOTE: This is a `datetime.datetime` object."""
262    def __get__(self, obj, objtype=None):
263        return datetime.datetime(*obj.section1[5:11])
264    def __set__(self, obj, value):
265        if isinstance(value, np.datetime64):
266            timestamp = (value - np.datetime64("1970-01-01T00:00:00")) / np.timedelta64(
267                1, "s"
268            )
269            try:
270                # Python >= 3.10
271                value = datetime.datetime.fromtimestamp(timestamp, datetime.UTC)
272            except(AttributeError):
273                # Python < 3.10
274                value = datetime.datetime.utcfromtimestamp(timestamp)
275        if isinstance(value, datetime.datetime):
276            obj.section1[5] = value.year
277            obj.section1[6] = value.month
278            obj.section1[7] = value.day
279            obj.section1[8] = value.hour
280            obj.section1[9] = value.minute
281            obj.section1[10] = value.second
282            # IMPORTANT: Update validDate components when message is time interval
283            if obj.pdtn in _timeinterval_pdtns:
284                vd = value + obj.leadTime + obj.duration
285                obj.yearOfEndOfTimePeriod = vd.year
286                obj.monthOfEndOfTimePeriod = vd.month
287                obj.dayOfEndOfTimePeriod = vd.day
288                obj.hourOfEndOfTimePeriod = vd.hour
289                obj.minuteOfEndOfTimePeriod = vd.minute
290                obj.secondOfEndOfTimePeriod = vd.second
291        else:
292            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
293            raise TypeError(msg)

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

class ProductionStatus:
295class ProductionStatus:
296    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
297    def __get__(self, obj, objtype=None):
298        return Grib2Metadata(obj.section1[11],table='1.3')
299    def __set__(self, obj, value):
300        obj.section1[11] = value
class TypeOfData:
302class TypeOfData:
303    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
304    def __get__(self, obj, objtype=None):
305        return Grib2Metadata(obj.section1[12],table='1.4')
306    def __set__(self, obj, value):
307        obj.section1[12] = value
class GridDefinitionSection:
316class GridDefinitionSection:
317    """
318    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
319    """
320    def __get__(self, obj, objtype=None):
321        return obj.section3[0:5]
322    def __set__(self, obj, value):
323        raise RuntimeError

GRIB2 Section 3, Grid Definition Section

class SourceOfGridDefinition:
325class SourceOfGridDefinition:
326    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
327    def __get__(self, obj, objtype=None):
328        return Grib2Metadata(obj.section3[0],table='3.0')
329    def __set__(self, obj, value):
330        raise RuntimeError
class NumberOfDataPoints:
332class NumberOfDataPoints:
333    """Number of Data Points"""
334    def __get__(self, obj, objtype=None):
335        return obj.section3[1]
336    def __set__(self, obj, value):
337        raise RuntimeError

Number of Data Points

class InterpretationOfListOfNumbers:
339class InterpretationOfListOfNumbers:
340    """Interpretation of List of Numbers"""
341    def __get__(self, obj, objtype=None):
342        return Grib2Metadata(obj.section3[3],table='3.11')
343    def __set__(self, obj, value):
344        raise RuntimeError

Interpretation of List of Numbers

class GridDefinitionTemplateNumber:
346class GridDefinitionTemplateNumber:
347    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
348    def __get__(self, obj, objtype=None):
349        return Grib2Metadata(obj.section3[4],table='3.1')
350    def __set__(self, obj, value):
351        raise RuntimeError
class GridDefinitionTemplate:
353class GridDefinitionTemplate:
354    """Grid definition template"""
355    def __get__(self, obj, objtype=None):
356        return obj.section3[5:]
357    def __set__(self, obj, value):
358        raise RuntimeError

Grid definition template

class EarthParams:
360class EarthParams:
361    """Metadata about the shape of the Earth"""
362    def __get__(self, obj, objtype=None):
363        if obj.section3[5] in {50,51,52,1200}:
364            return None
365        return tables.get_table('earth_params')[str(obj.section3[5])]
366    def __set__(self, obj, value):
367        raise RuntimeError

Metadata about the shape of the Earth

class DxSign:
369class DxSign:
370    """Sign of Grid Length in X-Direction"""
371    def __get__(self, obj, objtype=None):
372        if obj.section3[4] in {0, 1, 203, 205, 32768, 32769} and \
373        obj.section3[17] > obj.section3[20]:
374            return -1.0
375        return 1.0
376    def __set__(self, obj, value):
377        raise RuntimeError

Sign of Grid Length in X-Direction

class DySign:
379class DySign:
380    """Sign of Grid Length in Y-Direction"""
381    def __get__(self, obj, objtype=None):
382        if obj.section3[4] in {0, 1, 203, 205, 32768, 32769} and \
383        obj.section3[16] > obj.section3[19]:
384            return -1.0
385        return 1.0
386    def __set__(self, obj, value):
387        raise RuntimeError

Sign of Grid Length in Y-Direction

class LLScaleFactor:
389class LLScaleFactor:
390    """Scale Factor for Lats/Lons"""
391    def __get__(self, obj, objtype=None):
392        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
393            llscalefactor = float(obj.section3[14])
394            if llscalefactor == 0:
395                return 1
396            return llscalefactor
397        return 1
398    def __set__(self, obj, value):
399        raise RuntimeError

Scale Factor for Lats/Lons

class LLDivisor:
401class LLDivisor:
402    """Divisor Value for scaling Lats/Lons"""
403    def __get__(self, obj, objtype=None):
404        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
405            lldivisor = float(obj.section3[15])
406            if lldivisor <= 0:
407                return 1.e6
408            return lldivisor
409        return 1.e6
410    def __set__(self, obj, value):
411        raise RuntimeError

Divisor Value for scaling Lats/Lons

class XYDivisor:
413class XYDivisor:
414    """Divisor Value for scaling grid lengths"""
415    def __get__(self, obj, objtype=None):
416        if obj.section3[4] in {0, 1, 40, 41, 203, 205, 32768, 32769}:
417            return obj._lldivisor
418        return 1.e3
419    def __set__(self, obj, value):
420        raise RuntimeError

Divisor Value for scaling grid lengths

class ShapeOfEarth:
422class ShapeOfEarth:
423    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
424    def __get__(self, obj, objtype=None):
425        return Grib2Metadata(obj.section3[5],table='3.2')
426    def __set__(self, obj, value):
427        obj.section3[5] = value
class EarthShape:
429class EarthShape:
430    """Description of the shape of the Earth"""
431    def __get__(self, obj, objtype=None):
432        return obj._earthparams['shape']
433    def __set__(self, obj, value):
434        raise RuntimeError

Description of the shape of the Earth

class EarthRadius:
436class EarthRadius:
437    """Radius of the Earth (Assumes "spherical")"""
438    def __get__(self, obj, objtype=None):
439        ep = obj._earthparams
440        if ep['shape'] == 'spherical':
441            if ep['radius'] is None:
442                return obj.section3[7]/(10.**obj.section3[6])
443            else:
444                return ep['radius']
445        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
446            return None
447    def __set__(self, obj, value):
448        raise RuntimeError

Radius of the Earth (Assumes "spherical")

class EarthMajorAxis:
450class EarthMajorAxis:
451    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
452    def __get__(self, obj, objtype=None):
453        ep = obj._earthparams
454        if ep['shape'] == 'spherical':
455            return None
456        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
457            if ep['major_axis'] is None and ep['minor_axis'] is None:
458                return obj.section3[9]/(10.**obj.section3[8])
459            else:
460                return ep['major_axis']
461    def __set__(self, obj, value):
462        raise RuntimeError

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

class EarthMinorAxis:
464class EarthMinorAxis:
465    """Minor Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
466    def __get__(self, obj, objtype=None):
467        ep = obj._earthparams
468        if ep['shape'] == 'spherical':
469            return None
470        if ep['shape'] in {'ellipsoid','oblateSpheriod'}:
471            if ep['major_axis'] is None and ep['minor_axis'] is None:
472                return obj.section3[11]/(10.**section3[10])
473            else:
474                return ep['minor_axis']
475    def __set__(self, obj, value):
476        raise RuntimeError

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

class Nx:
478class Nx:
479    """Number of grid points in the X-direction (generally East-West)"""
480    def __get__(self, obj, objtype=None):
481        return obj.section3[12]
482    def __set__(self, obj, value):
483        obj.section3[12] = value
484        obj.section3[1] = value * obj.section3[13]

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

class Ny:
486class Ny:
487    """Number of grid points in the Y-direction (generally North-South)"""
488    def __get__(self, obj, objtype=None):
489        return obj.section3[13]
490    def __set__(self, obj, value):
491        obj.section3[13] = value
492        obj.section3[1] = value * obj.section3[12]

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

class ScanModeFlags:
494class ScanModeFlags:
495    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
496    _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}
497    def __get__(self, obj, objtype=None):
498        if obj.gdtn == 50:
499            return [None, None, None, None]
500        else:
501            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
502    def __set__(self, obj, value):
503        obj.section3[self._key[obj.gdtn]+5] = value
class ResolutionAndComponentFlags:
505class ResolutionAndComponentFlags:
506    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
507    _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}
508    def __get__(self, obj, objtype=None):
509        if obj.gdtn == 50:
510            return [None for i in range(8)]
511        else:
512            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
513    def __set__(self, obj, value):
514        obj.section3[self._key[obj.gdtn]+5] = value
class LatitudeFirstGridpoint:
516class LatitudeFirstGridpoint:
517    """Latitude of first gridpoint"""
518    _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}
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)

Latitude of first gridpoint

class LongitudeFirstGridpoint:
524class LongitudeFirstGridpoint:
525    """Longitude of first gridpoint"""
526    _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}
527    def __get__(self, obj, objtype=None):
528        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
529    def __set__(self, obj, value):
530        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of first gridpoint

class LatitudeLastGridpoint:
532class LatitudeLastGridpoint:
533    """Latitude of last gridpoint"""
534    _key = {0:14, 1:14, 10:13, 40:14, 41:14, 203:14, 204:14, 205:14, 32768:14, 32769:19}
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)

Latitude of last gridpoint

class LongitudeLastGridpoint:
540class LongitudeLastGridpoint:
541    """Longitude of last gridpoint"""
542    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:20}
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        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of last gridpoint

class LatitudeCenterGridpoint:
548class LatitudeCenterGridpoint:
549    """Latitude of center gridpoint"""
550    _key = {32768:14, 32769:14}
551    def __get__(self, obj, objtype=None):
552        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
553    def __set__(self, obj, value):
554        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of center gridpoint

class LongitudeCenterGridpoint:
556class LongitudeCenterGridpoint:
557    """Longitude of center gridpoint"""
558    _key = {32768:15, 32769:15}
559    def __get__(self, obj, objtype=None):
560        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
561    def __set__(self, obj, value):
562        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of center gridpoint

class GridlengthXDirection:
564class GridlengthXDirection:
565    """Grid lenth in the X-Direction"""
566    _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}
567    def __get__(self, obj, objtype=None):
568        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
569    def __set__(self, obj, value):
570        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the X-Direction

class GridlengthYDirection:
572class GridlengthYDirection:
573    """Grid lenth in the Y-Direction"""
574    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
575    def __get__(self, obj, objtype=None):
576        if obj.gdtn in {40, 41}:
577            return obj.gridlengthXDirection
578        else:
579            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
580    def __set__(self, obj, value):
581        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the Y-Direction

class NumberOfParallels:
583class NumberOfParallels:
584    """Number of parallels between a pole and the equator"""
585    _key = {40:17, 41:17}
586    def __get__(self, obj, objtype=None):
587        return obj.section3[self._key[obj.gdtn]+5]
588    def __set__(self, obj, value):
589        raise RuntimeError

Number of parallels between a pole and the equator

class LatitudeSouthernPole:
591class LatitudeSouthernPole:
592    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
593    _key = {1:19, 30:20, 31:20, 41:19}
594    def __get__(self, obj, objtype=None):
595        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
596    def __set__(self, obj, value):
597        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:
599class LongitudeSouthernPole:
600    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
601    _key = {1:20, 30:21, 31:21, 41:20}
602    def __get__(self, obj, objtype=None):
603        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
604    def __set__(self, obj, value):
605        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:
607class AnglePoleRotation:
608    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
609    _key = {1:21, 41:21}
610    def __get__(self, obj, objtype=None):
611        return obj.section3[self._key[obj.gdtn]+5]
612    def __set__(self, obj, value):
613        obj.section3[self._key[obj.gdtn]+5] = int(value)

Angle of Pole Rotation for a Rotated Lat/Lon Grid

class LatitudeTrueScale:
615class LatitudeTrueScale:
616    """Latitude at which grid lengths are specified"""
617    _key = {10:12, 20:12, 30:12, 31:12}
618    def __get__(self, obj, objtype=None):
619        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
620    def __set__(self, obj, value):
621        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude at which grid lengths are specified

class GridOrientation:
623class GridOrientation:
624    """Longitude at which the grid is oriented"""
625    _key = {10:16, 20:13, 30:13, 31:13}
626    def __get__(self, obj, objtype=None):
627        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
628    def __set__(self, obj, value):
629        if obj.gdtn == 10 and (value < 0 or value > 90):
630            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
631        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude at which the grid is oriented

class ProjectionCenterFlag:
633class ProjectionCenterFlag:
634    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
635    _key = {20:16, 30:16, 31:16}
636    def __get__(self, obj, objtype=None):
637        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
638    def __set__(self, obj, value):
639        obj.section3[self._key[obj.gdtn]+5] = value
class StandardLatitude1:
641class StandardLatitude1:
642    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
643    _key = {30:18, 31:18}
644    def __get__(self, obj, objtype=None):
645        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
646    def __set__(self, obj, value):
647        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:
649class StandardLatitude2:
650    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
651    _key = {30:19, 31:19}
652    def __get__(self, obj, objtype=None):
653        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
654    def __set__(self, obj, value):
655        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:
657class SpectralFunctionParameters:
658    """Spectral Function Parameters"""
659    def __get__(self, obj, objtype=None):
660        return obj.section3[0:3]
661    def __set__(self, obj, value):
662        obj.section3[0:3] = value[0:3]

Spectral Function Parameters

class ProjParameters:
664class ProjParameters:
665    """PROJ Parameters to define the reference system"""
666    def __get__(self, obj, objtype=None):
667        projparams = {}
668        projparams['a'] = 1.0
669        projparams['b'] = 1.0
670        if obj.earthRadius is not None:
671            projparams['a'] = float(obj.earthRadius)
672            projparams['b'] = float(obj.earthRadius)
673        else:
674            if obj.earthMajorAxis is not None: projparams['a'] = float(obj.earthMajorAxis)
675            if obj.earthMajorAxis is not None: projparams['b'] = float(obj.earthMinorAxis)
676        if obj.gdtn == 0:
677            projparams['proj'] = 'longlat'
678        elif obj.gdtn == 1:
679            projparams['o_proj'] = 'longlat'
680            projparams['proj'] = 'ob_tran'
681            projparams['o_lat_p'] = float(-1.0*obj.latitudeSouthernPole)
682            projparams['o_lon_p'] = float(obj.anglePoleRotation)
683            projparams['lon_0'] = float(obj.longitudeSouthernPole)
684        elif obj.gdtn == 10:
685            projparams['proj'] = 'merc'
686            projparams['lat_ts'] = float(obj.latitudeTrueScale)
687            projparams['lon_0'] = float(0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint))
688        elif obj.gdtn == 20:
689            if obj.projectionCenterFlag == 0:
690                lat0 = 90.0
691            elif obj.projectionCenterFlag == 1:
692                lat0 = -90.0
693            projparams['proj'] = 'stere'
694            projparams['lat_ts'] = float(obj.latitudeTrueScale)
695            projparams['lat_0'] = lat0
696            projparams['lon_0'] = float(obj.gridOrientation)
697        elif obj.gdtn == 30:
698            projparams['proj'] = 'lcc'
699            projparams['lat_1'] = float(obj.standardLatitude1)
700            projparams['lat_2'] = float(obj.standardLatitude2)
701            projparams['lat_0'] = float(obj.latitudeTrueScale)
702            projparams['lon_0'] = float(obj.gridOrientation)
703        elif obj.gdtn == 31:
704            projparams['proj'] = 'aea'
705            projparams['lat_1'] = float(obj.standardLatitude1)
706            projparams['lat_2'] = float(obj.standardLatitude2)
707            projparams['lat_0'] = float(obj.latitudeTrueScale)
708            projparams['lon_0'] = float(obj.gridOrientation)
709        elif obj.gdtn == 40:
710            projparams['proj'] = 'eqc'
711        elif obj.gdtn == 32769:
712            projparams['proj'] = 'aeqd'
713            projparams['lon_0'] = float(obj.longitudeCenterGridpoint)
714            projparams['lat_0'] = float(obj.latitudeCenterGridpoint)
715        return projparams
716    def __set__(self, obj, value):
717        raise RuntimeError

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate0:
719@dataclass(init=False)
720class GridDefinitionTemplate0:
721    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
722    _len = 19
723    _num = 0
724    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
725    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
726    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
727    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
728    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
729    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
730
731    @classmethod
732    def _attrs(cls):
733        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:
735@dataclass(init=False)
736class GridDefinitionTemplate1:
737    """[Grid Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-1.shtml)"""
738    _len = 22
739    _num = 1
740    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
741    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
742    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
743    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
744    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
745    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
746    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
747    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
748    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
749
750    @classmethod
751    def _attrs(cls):
752        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:
754@dataclass(init=False)
755class GridDefinitionTemplate10:
756    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
757    _len = 19
758    _num = 10
759    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
760    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
761    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
762    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
763    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
764    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
765    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
766    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
767    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
768
769    @classmethod
770    def _attrs(cls):
771        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:
773@dataclass(init=False)
774class GridDefinitionTemplate20:
775    """[Grid Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-20.shtml)"""
776    _len = 18
777    _num = 20
778    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
779    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
780    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
781    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
782    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
783    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
784    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
785    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
786
787    @classmethod
788    def _attrs(cls):
789        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:
791@dataclass(init=False)
792class GridDefinitionTemplate30:
793    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
794    _len = 22
795    _num = 30
796    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
797    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
798    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
799    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
800    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
801    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
802    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
803    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
804    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
805    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
806    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
807    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
808
809    @classmethod
810    def _attrs(cls):
811        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:
813@dataclass(init=False)
814class GridDefinitionTemplate31:
815    """[Grid Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-31.shtml)"""
816    _len = 22
817    _num = 31
818    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
819    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
820    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
821    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
822    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
823    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
824    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
825    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
826    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
827    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
828    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
829
830    @classmethod
831    def _attrs(cls):
832        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:
834@dataclass(init=False)
835class GridDefinitionTemplate40:
836    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
837    _len = 19
838    _num = 40
839    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
840    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
841    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
842    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
843    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
844    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
845    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
846
847    @classmethod
848    def _attrs(cls):
849        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:
851@dataclass(init=False)
852class GridDefinitionTemplate41:
853    """[Grid Definition Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-41.shtml)"""
854    _len = 22
855    _num = 41
856    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
857    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
858    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
859    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
860    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
861    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
862    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
863    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
864    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
865    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
866
867    @classmethod
868    def _attrs(cls):
869        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:
871@dataclass(init=False)
872class GridDefinitionTemplate50:
873    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
874    _len = 5
875    _num = 50
876    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
877
878    @classmethod
879    def _attrs(cls):
880        return list(cls.__dataclass_fields__.keys())
spectralFunctionParameters: list

Spectral Function Parameters

@dataclass(init=False)
class GridDefinitionTemplate32768:
882@dataclass(init=False)
883class GridDefinitionTemplate32768:
884    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
885    _len = 19
886    _num = 32768
887    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
888    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
889    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
890    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
891    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
892    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
893
894    @classmethod
895    def _attrs(cls):
896        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:
898@dataclass(init=False)
899class GridDefinitionTemplate32769:
900    """[Grid Definition Template 32769](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32769.shtml)"""
901    _len = 19
902    _num = 32769
903    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
904    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
905    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
906    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
907    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
908    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
909    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
910    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
911
912    @classmethod
913    def _attrs(cls):
914        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):
929def gdt_class_by_gdtn(gdtn: int):
930    """
931    Provides a Grid Definition Template class via the template number
932
933    Parameters
934    ----------
935    gdtn
936        Grid definition template number.
937
938    Returns
939    -------
940    gdt_class_by_gdtn
941        Grid definition template class object (not an instance).
942    """
943    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:
948class ProductDefinitionTemplateNumber:
949    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
950    def __get__(self, obj, objtype=None):
951        return Grib2Metadata(obj.section4[1],table='4.0')
952    def __set__(self, obj, value):
953        raise RuntimeError
class ProductDefinitionTemplate:
956class ProductDefinitionTemplate:
957    """Product Definition Template"""
958    def __get__(self, obj, objtype=None):
959        return obj.section4[2:]
960    def __set__(self, obj, value):
961        raise RuntimeError

Product Definition Template

class ParameterCategory:
963class ParameterCategory:
964    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
965    _key = defaultdict(lambda: 0)
966    def __get__(self, obj, objtype=None):
967        return obj.section4[0+2]
968    def __set__(self, obj, value):
969        obj.section4[self._key[obj.pdtn]+2] = value
class ParameterNumber:
971class ParameterNumber:
972    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
973    _key = defaultdict(lambda: 1)
974    def __get__(self, obj, objtype=None):
975        return obj.section4[1+2]
976    def __set__(self, obj, value):
977        obj.section4[self._key[obj.pdtn]+2] = value
class VarInfo:
979class VarInfo:
980    """
981    Variable Information.
982
983    These are the metadata returned for a specific variable according to
984    discipline, parameter category, and parameter number.
985    """
986    def __get__(self, obj, objtype=None):
987        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
988    def __set__(self, obj, value):
989        raise RuntimeError

Variable Information.

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

class FullName:
 991class FullName:
 992    """Full name of the Variable."""
 993    def __get__(self, obj, objtype=None):
 994        full_name = []
 995
 996        # Get aerosol type from table 4.233
 997        if not hasattr(obj, 'typeOfAerosol'):
 998            return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
 999        elif obj.typeOfAerosol is not None:
1000            aero_type = str(obj.typeOfAerosol.value)
1001            if aero_type in tables.table_4_233:
1002                full_name.append(tables.table_4_233[aero_type][0])
1003
1004            # Get base name from GRIB2 table
1005            base_name = tables.get_varinfo_from_table(
1006                obj.section0[2],
1007                *obj.section4[2:4],
1008                isNDFD=obj._isNDFD
1009            )[0]
1010            full_name.append(base_name)
1011
1012            # Add optical properties with wavelengths if present
1013            if hasattr(obj, 'scaledValueOfFirstWavelength'):
1014                optical_type = str(obj.parameterNumber)
1015                first_wl = obj.scaledValueOfFirstWavelength
1016                second_wl = getattr(obj, 'scaledValueOfSecondWavelength', None)
1017
1018                # Special case for AE between 440-870nm
1019                if optical_type == '111' and first_wl == 440 and second_wl == 870:
1020                    full_name.append("at 440-870nm")
1021
1022                # Handle wavelength-specific optical properties
1023                elif optical_type in ['102', '103', '104', '105', '106']:
1024                    wavelength = f"{first_wl}nm"
1025                    if second_wl:
1026                        wavelength = f"{first_wl}-{second_wl}nm"
1027                    full_name.append(f"at {wavelength}")
1028
1029            final = " ".join(full_name)
1030
1031            return final.replace('Aerosol Aerosol', 'Aerosol')
1032
1033    def __set__(self, obj, value):
1034        raise RuntimeError(
1035            "Cannot set the fullName of the message. Instead set shortName OR set the appropriate discipline, "
1036            "parameterCategory, and parameterNumber. The fullName will be set automatically from these other attributes."
1037        )

Full name of the Variable.

class Units:
1039class Units:
1040    """Units of the Variable."""
1041    def __get__(self, obj, objtype=None):
1042        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
1043    def __set__(self, obj, value):
1044        raise RuntimeError(
1045            "Cannot set the units of the message.  Instead set shortName OR set the appropriate discipline, parameterCategory, and parameterNumber.  The units will be set automatically from these other attributes."
1046        )

Units of the Variable.

class ShortName:
1048class ShortName:
1049    """Short name of the variable (i.e. the variable abbreviation)."""
1050    def __get__(self, obj, objtype=None):
1051        if hasattr(obj, 'typeOfAerosol'):
1052            return tables._build_aerosol_shortname(obj)
1053        else:
1054            return tables.get_varinfo_from_table(obj.section0[2], *obj.section4[2:4], isNDFD=obj._isNDFD)[2]
1055    def __set__(self, obj, value):
1056        metadata = tables.get_metadata_from_shortname(value)
1057        if len(metadata) > 1:
1058            raise ValueError(
1059                f"shortName={value} is ambiguous within the GRIB2 standard and you have to set instead with discipline, parameterCategory, and parameterNumber.\n{metadata}"
1060            )
1061        for attr, val in metadata[0].items():
1062            if attr in ["fullName", "units"]:
1063                continue
1064            setattr(obj, attr, val)

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

class TypeOfGeneratingProcess:
1066class TypeOfGeneratingProcess:
1067    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
1068    _key = defaultdict(lambda: 2, {48:13})
1069    def __get__(self, obj, objtype=None):
1070        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
1071    def __set__(self, obj, value):
1072        obj.section4[self._key[obj.pdtn]+2] = value
class BackgroundGeneratingProcessIdentifier:
1074class BackgroundGeneratingProcessIdentifier:
1075    """Background Generating Process Identifier"""
1076    _key = defaultdict(lambda: 3, {48:14})
1077    def __get__(self, obj, objtype=None):
1078        return obj.section4[self._key[obj.pdtn]+2]
1079    def __set__(self, obj, value):
1080        obj.section4[self._key[obj.pdtn]+2] = value

Background Generating Process Identifier

class GeneratingProcess:
1082class GeneratingProcess:
1083    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
1084    _key = defaultdict(lambda: 4, {48:15})
1085    def __get__(self, obj, objtype=None):
1086        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
1087    def __set__(self, obj, value):
1088        obj.section4[self._key[obj.pdtn]+2] = value
class HoursAfterDataCutoff:
1090class HoursAfterDataCutoff:
1091    """Hours of observational data cutoff after reference time."""
1092    _key = defaultdict(lambda: 5, {48:16})
1093    def __get__(self, obj, objtype=None):
1094        return obj.section4[self._key[obj.pdtn]+2]
1095    def __set__(self, obj, value):
1096        obj.section4[self._key[obj.pdtn]+2] = value

Hours of observational data cutoff after reference time.

class MinutesAfterDataCutoff:
1098class MinutesAfterDataCutoff:
1099    """Minutes of observational data cutoff after reference time."""
1100    _key = defaultdict(lambda: 6, {48:17})
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

Minutes of observational data cutoff after reference time.

class UnitOfForecastTime:
1106class UnitOfForecastTime:
1107    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1108    _key = defaultdict(lambda: 7, {48:18})
1109    def __get__(self, obj, objtype=None):
1110        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
1111    def __set__(self, obj, value):
1112        obj.section4[self._key[obj.pdtn]+2] = value
class ValueOfForecastTime:
1114class ValueOfForecastTime:
1115    """Value of forecast time in units defined by `UnitofForecastTime`."""
1116    _key = defaultdict(lambda: 8, {48:19})
1117    def __get__(self, obj, objtype=None):
1118        return obj.section4[self._key[obj.pdtn]+2]
1119    def __set__(self, obj, value):
1120        obj.section4[self._key[obj.pdtn]+2] = value

Value of forecast time in units defined by UnitofForecastTime.

class LeadTime:
1122class LeadTime:
1123    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
1124    _key = ValueOfForecastTime._key
1125    def __get__(self, obj, objtype=None):
1126        return utils.get_leadtime(obj.section4[1], obj.section4[2:]) + obj.duration
1127    def __set__(self, obj, value):
1128        if isinstance(value, np.timedelta64):
1129            # Allows setting from xarray
1130            value = datetime.timedelta(
1131                seconds=int(value/np.timedelta64(1, 's')))
1132        # First update validDate if necessary.
1133        # IMPORTANT: Update validDate components when message is time interval
1134        if obj.pdtn in _timeinterval_pdtns:
1135            vd = obj.refDate + value 
1136            obj.yearOfEndOfTimePeriod = vd.year
1137            obj.monthOfEndOfTimePeriod = vd.month
1138            obj.dayOfEndOfTimePeriod = vd.day
1139            obj.hourOfEndOfTimePeriod = vd.hour
1140            obj.minuteOfEndOfTimePeriod = vd.minute
1141            obj.secondOfEndOfTimePeriod = vd.second
1142        # Update leadTime component in section4
1143        value -= obj.duration
1144        obj.section4[self._key[obj.pdtn]+2] = int(value.total_seconds()/3600)

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

class FixedSfc1Info:
1146class FixedSfc1Info:
1147    """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)"""
1148    _key = defaultdict(lambda: 9, {48:20})
1149    def __get__(self, obj, objtype=None):
1150        if obj.section4[self._key[obj.pdtn]+2] == 255:
1151            return [None, None]
1152        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1153    def __set__(self, obj, value):
1154        raise NotImplementedError

Information of the first fixed surface via table 4.5

class FixedSfc2Info:
1156class FixedSfc2Info:
1157    """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)"""
1158    _key = defaultdict(lambda: 12, {48:23})
1159    def __get__(self, obj, objtype=None):
1160        if obj.section4[self._key[obj.pdtn]+2] == 255:
1161            return [None, None]
1162        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1163    def __set__(self, obj, value):
1164        raise NotImplementedError

Information of the second fixed surface via table 4.5

class TypeOfFirstFixedSurface:
1166class TypeOfFirstFixedSurface:
1167    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1168    _key = defaultdict(lambda: 9, {48:20})
1169    def __get__(self, obj, objtype=None):
1170        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1171    def __set__(self, obj, value):
1172        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstFixedSurface:
1174class ScaleFactorOfFirstFixedSurface:
1175    """Scale Factor of First Fixed Surface"""
1176    _key = defaultdict(lambda: 10, {48:21})
1177    def __get__(self, obj, objtype=None):
1178        return obj.section4[self._key[obj.pdtn]+2]
1179    def __set__(self, obj, value):
1180        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Fixed Surface

class ScaledValueOfFirstFixedSurface:
1182class ScaledValueOfFirstFixedSurface:
1183    """Scaled Value Of First Fixed Surface"""
1184    _key = defaultdict(lambda: 11, {48:22})
1185    def __get__(self, obj, objtype=None):
1186        return obj.section4[self._key[obj.pdtn]+2]
1187    def __set__(self, obj, value):
1188        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of First Fixed Surface

class UnitOfFirstFixedSurface:
1190class UnitOfFirstFixedSurface:
1191    """Units of First Fixed Surface"""
1192    def __get__(self, obj, objtype=None):
1193        return obj._fixedsfc1info[1]
1194    def __set__(self, obj, value):
1195        pass

Units of First Fixed Surface

class ValueOfFirstFixedSurface:
1197class ValueOfFirstFixedSurface:
1198    """Value of First Fixed Surface"""
1199    def __get__(self, obj, objtype=None):
1200        scale_factor = getattr(obj, "scaleFactorOfFirstFixedSurface")
1201        scaled_value = getattr(obj, "scaledValueOfFirstFixedSurface")
1202        if scale_factor < 0:
1203            return 0.0
1204        else:
1205            return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1206    def __set__(self, obj, value):
1207        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1208        setattr(obj, "scaleFactorOfFirstFixedSurface", scale_factor)
1209        setattr(obj, "scaledValueOfFirstFixedSurface", scaled_value)

Value of First Fixed Surface

class TypeOfSecondFixedSurface:
1211class TypeOfSecondFixedSurface:
1212    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1213    _key = defaultdict(lambda: 12, {48:23})
1214    def __get__(self, obj, objtype=None):
1215        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1216    def __set__(self, obj, value):
1217        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfSecondFixedSurface:
1219class ScaleFactorOfSecondFixedSurface:
1220    """Scale Factor of Second Fixed Surface"""
1221    _key = defaultdict(lambda: 13, {48:24})
1222    def __get__(self, obj, objtype=None):
1223        return obj.section4[self._key[obj.pdtn]+2]
1224    def __set__(self, obj, value):
1225        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Fixed Surface

class ScaledValueOfSecondFixedSurface:
1227class ScaledValueOfSecondFixedSurface:
1228    """Scaled Value Of Second Fixed Surface"""
1229    _key = defaultdict(lambda: 14, {48:25})
1230    def __get__(self, obj, objtype=None):
1231        return obj.section4[self._key[obj.pdtn]+2]
1232    def __set__(self, obj, value):
1233        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of Second Fixed Surface

class UnitOfSecondFixedSurface:
1235class UnitOfSecondFixedSurface:
1236    """Units of Second Fixed Surface"""
1237    def __get__(self, obj, objtype=None):
1238        return obj._fixedsfc2info[1]
1239    def __set__(self, obj, value):
1240        pass

Units of Second Fixed Surface

class ValueOfSecondFixedSurface:
1242class ValueOfSecondFixedSurface:
1243    """Value of Second Fixed Surface"""
1244    def __get__(self, obj, objtype=None):
1245        scale_factor = getattr(obj, "scaleFactorOfSecondFixedSurface")
1246        scaled_value = getattr(obj, "scaledValueOfSecondFixedSurface")
1247        if scale_factor < 0:
1248            return 0.0
1249        else:
1250            return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1251    def __set__(self, obj, value):
1252        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1253        setattr(obj, "scaleFactorOfSecondFixedSurface", scale_factor)
1254        setattr(obj, "scaledValueOfSecondFixedSurface", scaled_value)

Value of Second Fixed Surface

class Level:
1256class Level:
1257    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1258    def __get__(self, obj, objtype=None):
1259        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1260    def __set__(self, obj, value):
1261        pass

Level (same as provided by wgrib2)

class TypeOfEnsembleForecast:
1263class TypeOfEnsembleForecast:
1264    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1265    _key = {1:15, 11:15}
1266    def __get__(self, obj, objtype=None):
1267        pdtn = obj.section4[1]
1268        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1269    def __set__(self, obj, value):
1270        pdtn = obj.section4[1]
1271        obj.section4[self._key[pdtn]+2] = value
class PerturbationNumber:
1273class PerturbationNumber:
1274    """Ensemble Perturbation Number"""
1275    _key = {1:16, 11:16}
1276    def __get__(self, obj, objtype=None):
1277        pdtn = obj.section4[1]
1278        return obj.section4[self._key[pdtn]+2]
1279    def __set__(self, obj, value):
1280        pdtn = obj.section4[1]
1281        obj.section4[self._key[pdtn]+2] = value

Ensemble Perturbation Number

class NumberOfEnsembleForecasts:
1283class NumberOfEnsembleForecasts:
1284    """Total Number of Ensemble Forecasts"""
1285    _key = {1:17, 2:16, 11:17, 12:16}
1286    def __get__(self, obj, objtype=None):
1287        pdtn = obj.section4[1]
1288        return obj.section4[self._key[pdtn]+2]
1289    def __set__(self, obj, value):
1290        pdtn = obj.section4[1]
1291        obj.section4[self._key[pdtn]+2] = value

Total Number of Ensemble Forecasts

class TypeOfDerivedForecast:
1293class TypeOfDerivedForecast:
1294    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1295    _key = {2:15, 12:15}
1296    def __get__(self, obj, objtype=None):
1297        pdtn = obj.section4[1]
1298        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1299    def __set__(self, obj, value):
1300        pdtn = obj.section4[1]
1301        obj.section4[self._key[pdtn]+2] = value
class ForecastProbabilityNumber:
1303class ForecastProbabilityNumber:
1304    """Forecast Probability Number"""
1305    _key = {5:15, 9:15}
1306    def __get__(self, obj, objtype=None):
1307        pdtn = obj.section4[1]
1308        return obj.section4[self._key[pdtn]+2]
1309    def __set__(self, obj, value):
1310        pdtn = obj.section4[1]
1311        obj.section4[self._key[pdtn]+2] = value

Forecast Probability Number

class TotalNumberOfForecastProbabilities:
1313class TotalNumberOfForecastProbabilities:
1314    """Total Number of Forecast Probabilities"""
1315    _key = {5:16, 9:16}
1316    def __get__(self, obj, objtype=None):
1317        pdtn = obj.section4[1]
1318        return obj.section4[self._key[pdtn]+2]
1319    def __set__(self, obj, value):
1320        pdtn = obj.section4[1]
1321        obj.section4[self._key[pdtn]+2] = value

Total Number of Forecast Probabilities

class TypeOfProbability:
1323class TypeOfProbability:
1324    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1325    _key = {5:17, 9:17}
1326    def __get__(self, obj, objtype=None):
1327        pdtn = obj.section4[1]
1328        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1329    def __set__(self, obj, value):
1330        pdtn = obj.section4[1]
1331        obj.section4[self._key[pdtn]+2] = value
class ScaleFactorOfThresholdLowerLimit:
1333class ScaleFactorOfThresholdLowerLimit:
1334    """Scale Factor of Threshold Lower Limit"""
1335    _key = {5:18, 9:18}
1336    def __get__(self, obj, objtype=None):
1337        pdtn = obj.section4[1]
1338        return obj.section4[self._key[pdtn]+2]
1339    def __set__(self, obj, value):
1340        pdtn = obj.section4[1]
1341        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Lower Limit

class ScaledValueOfThresholdLowerLimit:
1343class ScaledValueOfThresholdLowerLimit:
1344    """Scaled Value of Threshold Lower Limit"""
1345    _key = {5:19, 9:19}
1346    def __get__(self, obj, objtype=None):
1347        pdtn = obj.section4[1]
1348        return obj.section4[self._key[pdtn]+2]
1349    def __set__(self, obj, value):
1350        pdtn = obj.section4[1]
1351        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Lower Limit

class ScaleFactorOfThresholdUpperLimit:
1353class ScaleFactorOfThresholdUpperLimit:
1354    """Scale Factor of Threshold Upper Limit"""
1355    _key = {5:20, 9:20}
1356    def __get__(self, obj, objtype=None):
1357        pdtn = obj.section4[1]
1358        return obj.section4[self._key[pdtn]+2]
1359    def __set__(self, obj, value):
1360        pdtn = obj.section4[1]
1361        obj.section4[self._key[pdtn]+2] = value

Scale Factor of Threshold Upper Limit

class ScaledValueOfThresholdUpperLimit:
1363class ScaledValueOfThresholdUpperLimit:
1364    """Scaled Value of Threshold Upper Limit"""
1365    _key = {5:21, 9:21}
1366    def __get__(self, obj, objtype=None):
1367        pdtn = obj.section4[1]
1368        return obj.section4[self._key[pdtn]+2]
1369    def __set__(self, obj, value):
1370        pdtn = obj.section4[1]
1371        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Upper Limit

class ThresholdLowerLimit:
1373class ThresholdLowerLimit:
1374    """Threshold Lower Limit"""
1375    def __get__(self, obj, objtype=None):
1376        scale_factor = getattr(obj, "scaleFactorOfThresholdLowerLimit")
1377        scaled_value = getattr(obj, "scaledValueOfThresholdLowerLimit")
1378        if scale_factor in {-2147483647,-127} or scaled_value in {-2147483647,255}:
1379            return 0.0
1380        value = float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1381        return value
1382    def __set__(self, obj, value):
1383        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1384        setattr(obj, "scaleFactorOfThresholdLowerLimit", scale_factor)
1385        setattr(obj, "scaledValueOfThresholdLowerLimit", scaled_value)

Threshold Lower Limit

class ThresholdUpperLimit:
1387class ThresholdUpperLimit:
1388    """Threshold Upper Limit"""
1389    def __get__(self, obj, objtype=None):
1390        scale_factor = getattr(obj, "scaleFactorOfThresholdUpperLimit")
1391        scaled_value = getattr(obj, "scaledValueOfThresholdUpperLimit")
1392        if scale_factor in {-2147483647,-127} or scaled_value in {-2147483647,255}:
1393            return 0.0
1394        value = float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1395        return value
1396    def __set__(self, obj, value):
1397        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1398        setattr(obj, "scaleFactorOfThresholdUpperLimit", scale_factor)
1399        setattr(obj, "scaledValueOfThresholdUpperLimit", scaled_value)

Threshold Upper Limit

class Threshold:
1401class Threshold:
1402    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1403    def __get__(self, obj, objtype=None):
1404        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1405    def __set__(self, obj, value):
1406        pass

Threshold string (same as wgrib2)

class PercentileValue:
1408class PercentileValue:
1409    """Percentile Value"""
1410    _key = {6:15, 10:15}
1411    def __get__(self, obj, objtype=None):
1412        pdtn = obj.section4[1]
1413        return obj.section4[self._key[pdtn]+2]
1414    def __set__(self, obj, value):
1415        pdtn = obj.section4[1]
1416        obj.section4[self._key[pdtn]+2] = value

Percentile Value

class YearOfEndOfTimePeriod:
1418class YearOfEndOfTimePeriod:
1419    """Year of End of Forecast Time Period"""
1420    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1421    def __get__(self, obj, objtype=None):
1422        pdtn = obj.section4[1]
1423        return obj.section4[self._key[pdtn]+2]
1424    def __set__(self, obj, value):
1425        pdtn = obj.section4[1]
1426        obj.section4[self._key[pdtn]+2] = value

Year of End of Forecast Time Period

class MonthOfEndOfTimePeriod:
1428class MonthOfEndOfTimePeriod:
1429    """Month Year of End of Forecast Time Period"""
1430    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1431    def __get__(self, obj, objtype=None):
1432        pdtn = obj.section4[1]
1433        return obj.section4[self._key[pdtn]+2]
1434    def __set__(self, obj, value):
1435        pdtn = obj.section4[1]
1436        obj.section4[self._key[pdtn]+2] = value

Month Year of End of Forecast Time Period

class DayOfEndOfTimePeriod:
1438class DayOfEndOfTimePeriod:
1439    """Day Year of End of Forecast Time Period"""
1440    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1441    def __get__(self, obj, objtype=None):
1442        pdtn = obj.section4[1]
1443        return obj.section4[self._key[pdtn]+2]
1444    def __set__(self, obj, value):
1445        pdtn = obj.section4[1]
1446        obj.section4[self._key[pdtn]+2] = value

Day Year of End of Forecast Time Period

class HourOfEndOfTimePeriod:
1448class HourOfEndOfTimePeriod:
1449    """Hour Year of End of Forecast Time Period"""
1450    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1451    def __get__(self, obj, objtype=None):
1452        pdtn = obj.section4[1]
1453        return obj.section4[self._key[pdtn]+2]
1454    def __set__(self, obj, value):
1455        pdtn = obj.section4[1]
1456        obj.section4[self._key[pdtn]+2] = value

Hour Year of End of Forecast Time Period

class MinuteOfEndOfTimePeriod:
1458class MinuteOfEndOfTimePeriod:
1459    """Minute Year of End of Forecast Time Period"""
1460    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1461    def __get__(self, obj, objtype=None):
1462        pdtn = obj.section4[1]
1463        return obj.section4[self._key[pdtn]+2]
1464    def __set__(self, obj, value):
1465        pdtn = obj.section4[1]
1466        obj.section4[self._key[pdtn]+2] = value

Minute Year of End of Forecast Time Period

class SecondOfEndOfTimePeriod:
1468class SecondOfEndOfTimePeriod:
1469    """Second Year of End of Forecast Time Period"""
1470    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1471    def __get__(self, obj, objtype=None):
1472        pdtn = obj.section4[1]
1473        return obj.section4[self._key[pdtn]+2]
1474    def __set__(self, obj, value):
1475        pdtn = obj.section4[1]
1476        obj.section4[self._key[pdtn]+2] = value

Second Year of End of Forecast Time Period

class Duration:
1478class Duration:
1479    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1480    def __get__(self, obj, objtype=None):
1481        return utils.get_duration(obj.section4[1],obj.section4[2:])
1482    def __set__(self, obj, value):
1483        if obj.pdtn in _continuous_pdtns:
1484            pass
1485        elif obj.pdtn in _timeinterval_pdtns:
1486            lt_orig = obj.leadTime
1487            _key = TimeRangeOfStatisticalProcess._key
1488            if isinstance(value, np.timedelta64):
1489                # Allows setting from xarray
1490                value = datetime.timedelta(
1491                    seconds=int(value/np.timedelta64(1, 's')))
1492            obj.section4[_key[obj.pdtn]+2] = int(value.total_seconds()/3600)
1493            obj.leadTime = lt_orig
1494            # IMPORTANT: Update validDate components when message is time interval
1495            #if obj.pdtn in _timeinterval_pdtns:
1496            #    print(obj.refDate, value, obj.leadTime)
1497            #    vd = obj.refDate + value + obj.leadTime
1498            #    obj.yearOfEndOfTimePeriod = vd.year
1499            #    obj.monthOfEndOfTimePeriod = vd.month
1500            #    obj.dayOfEndOfTimePeriod = vd.day
1501            #    obj.hourOfEndOfTimePeriod = vd.hour
1502            #    obj.minuteOfEndOfTimePeriod = vd.minute
1503            #    obj.secondOfEndOfTimePeriod = vd.second

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

class ValidDate:
1505class ValidDate:
1506    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1507    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1508    def __get__(self, obj, objtype=None):
1509        pdtn = obj.section4[1]
1510        try:
1511            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1512            return datetime.datetime(*obj.section4[s])
1513        except(KeyError):
1514            return obj.refDate + obj.leadTime
1515    def __set__(self, obj, value):
1516        warnings.warn(f"validDate attribute is read-only.")

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

class NumberOfTimeRanges:
1518class NumberOfTimeRanges:
1519    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1520    _key = {8:21, 9:28, 10:22, 11:24, 12:23, 46:27}
1521    def __get__(self, obj, objtype=None):
1522        pdtn = obj.section4[1]
1523        return obj.section4[self._key[pdtn]+2]
1524    def __set__(self, obj, value):
1525        pdtn = obj.section4[1]
1526        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:
1528class NumberOfMissingValues:
1529    """Total number of data values missing in statistical process"""
1530    _key = {8:22, 9:29, 10:23, 11:25, 12:24, 46:28}
1531    def __get__(self, obj, objtype=None):
1532        pdtn = obj.section4[1]
1533        return obj.section4[self._key[pdtn]+2]
1534    def __set__(self, obj, value):
1535        pdtn = obj.section4[1]
1536        obj.section4[self._key[pdtn]+2] = value

Total number of data values missing in statistical process

class StatisticalProcess:
1538class StatisticalProcess:
1539    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1540    _key = {
1541        8: 23,
1542        9: 30,
1543        10: 24,
1544        11: 26,
1545        12: 25,
1546        15: 15,
1547        46: 30,
1548        47: 30,
1549        49: 30,
1550        80: 30,
1551        81: 30,
1552        82: 30,
1553        83: 30,
1554        84: 30,
1555        85: 30
1556    }
1557
1558    def __get__(self, obj, objtype=None):
1559        pdtn = obj.section4[1]
1560        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.10')
1561
1562    def __set__(self, obj, value):
1563        pdtn = obj.section4[1]
1564        obj.section4[self._key[pdtn]+2] = value
class TypeOfTimeIncrementOfStatisticalProcess:
1566class TypeOfTimeIncrementOfStatisticalProcess:
1567    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1568    _key = {
1569        4: 31,
1570        8: 24,
1571        9: 31,
1572        10: 25,
1573        11: 27,
1574        12: 26,
1575        46: 31,
1576        47: 31,
1577        49: 31,
1578        80: 31,
1579        81: 31,
1580        82: 31,
1581        83: 31,
1582        84: 31,
1583        85: 31
1584    }
1585
1586    def __get__(self, obj, objtype=None):
1587        pdtn = obj.section4[1]
1588        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.11')
1589
1590    def __set__(self, obj, value):
1591        pdtn = obj.section4[1]
1592        obj.section4[self._key[pdtn]+2] = value
class UnitOfTimeRangeOfStatisticalProcess:
1593class UnitOfTimeRangeOfStatisticalProcess:
1594    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1595    _key = {
1596        4: 32,
1597        8: 25,
1598        9: 32,
1599        10: 26,
1600        11: 28,
1601        12: 27,
1602        46: 32,
1603        47: 32,
1604        49: 32,
1605        80: 32,
1606        81: 32,
1607        82: 32,
1608        83: 32,
1609        84: 32,
1610        85: 32
1611    }
1612
1613    def __get__(self, obj, objtype=None):
1614        pdtn = obj.section4[1]
1615        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1616
1617    def __set__(self, obj, value):
1618        pdtn = obj.section4[1]
1619        obj.section4[self._key[pdtn]+2] = value
class TimeRangeOfStatisticalProcess:
1621class TimeRangeOfStatisticalProcess:
1622    """Time Range of Statistical Process"""
1623    _key = {
1624        4: 33,
1625        8: 26,
1626        9: 33,
1627        10: 27,
1628        11: 29,
1629        12: 28,
1630        46: 33,
1631        47: 33,
1632        49: 33,
1633        80: 33,
1634        81: 33,
1635        82: 33,
1636        83: 33,
1637        84: 33,
1638        85: 33
1639    }
1640
1641    def __get__(self, obj, objtype=None):
1642        pdtn = obj.section4[1]
1643        return obj.section4[self._key[pdtn]+2]
1644
1645    def __set__(self, obj, value):
1646        pdtn = obj.section4[1]
1647        obj.section4[self._key[pdtn]+2] = value

Time Range of Statistical Process

class UnitOfTimeRangeOfSuccessiveFields:
1649class UnitOfTimeRangeOfSuccessiveFields:
1650    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1651    _key = {
1652        4: 34,
1653        8: 27,
1654        9: 34,
1655        10: 28,
1656        11: 30,
1657        12: 29,
1658        46: 34,
1659        47: 34,
1660        49: 34,
1661        80: 34,
1662        81: 34,
1663        82: 34,
1664        83: 34,
1665        84: 34,
1666        85: 34
1667    }
1668
1669    def __get__(self, obj, objtype=None):
1670        pdtn = obj.section4[1]
1671        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1672
1673    def __set__(self, obj, value):
1674        pdtn = obj.section4[1]
1675        obj.section4[self._key[pdtn]+2] = value
class TimeIncrementOfSuccessiveFields:
1677class TimeIncrementOfSuccessiveFields:
1678    """Time Increment of Successive Fields"""
1679    _key = {
1680        4: 35,
1681        8: 28,
1682        9: 35,
1683        10: 29,
1684        11: 31,
1685        12: 30,
1686        46: 67,
1687        47: 67,
1688        49: 67,
1689        80: 35,
1690        81: 35,
1691        82: 35,
1692        83: 35,
1693        84: 35,
1694        85: 35
1695    }
1696
1697    def __get__(self, obj, objtype=None):
1698        pdtn = obj.section4[1]
1699        return obj.section4[self._key[pdtn]+2]
1700
1701    def __set__(self, obj, value):
1702        pdtn = obj.section4[1]
1703        obj.section4[self._key[pdtn]+2] = value

Time Increment of Successive Fields

class TypeOfStatisticalProcessing:
1704class TypeOfStatisticalProcessing:
1705    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1706    _key = {15:16}
1707    def __get__(self, obj, objtype=None):
1708        pdtn = obj.section4[1]
1709        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1710    def __set__(self, obj, value):
1711        pdtn = obj.section4[1]
1712        obj.section4[self._key[pdtn]+2] = value
class NumberOfDataPointsForSpatialProcessing:
1714class NumberOfDataPointsForSpatialProcessing:
1715    """Number of Data Points for Spatial Processing"""
1716    _key = {15:17}
1717    def __get__(self, obj, objtype=None):
1718        pdtn = obj.section4[1]
1719        return obj.section4[self._key[pdtn]+2]
1720    def __set__(self, obj, value):
1721        pdtn = obj.section4[1]
1722        obj.section4[self._key[pdtn]+2] = value

Number of Data Points for Spatial Processing

class NumberOfContributingSpectralBands:
1724class NumberOfContributingSpectralBands:
1725    """Number of Contributing Spectral Bands (NB)"""
1726    _key = {32:9}
1727    def __get__(self, obj, objtype=None):
1728        pdtn = obj.section4[1]
1729        return obj.section4[self._key[pdtn]+2]
1730    def __set__(self, obj, value):
1731        pdtn = obj.section4[1]
1732        obj.section4[self._key[pdtn]+2] = value

Number of Contributing Spectral Bands

class SatelliteSeries:
1734class SatelliteSeries:
1735    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1736    _key = {32:10}
1737    def __get__(self, obj, objtype=None):
1738        pdtn = obj.section4[1]
1739        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1740    def __set__(self, obj, value):
1741        pass

Satellite Series

class SatelliteNumber:
1743class SatelliteNumber:
1744    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1745    _key = {32:11}
1746    def __get__(self, obj, objtype=None):
1747        pdtn = obj.section4[1]
1748        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1749    def __set__(self, obj, value):
1750        pass

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

class InstrumentType:
1752class InstrumentType:
1753    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1754    _key = {32:12}
1755    def __get__(self, obj, objtype=None):
1756        pdtn = obj.section4[1]
1757        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1758    def __set__(self, obj, value):
1759        pass

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

class ScaleFactorOfCentralWaveNumber:
1761class ScaleFactorOfCentralWaveNumber:
1762    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1763    _key = {32:13}
1764    def __get__(self, obj, objtype=None):
1765        pdtn = obj.section4[1]
1766        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1767    def __set__(self, obj, value):
1768        pass

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

class ScaledValueOfCentralWaveNumber:
1770class ScaledValueOfCentralWaveNumber:
1771    """Scaled Value Of Central WaveNumber of band NB"""
1772    _key = {32:14}
1773    def __get__(self, obj, objtype=None):
1774        pdtn = obj.section4[1]
1775        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1776    def __set__(self, obj, value):
1777        pass

Scaled Value Of Central WaveNumber of band NB

class CetralWaveNumber:
1779class CetralWaveNumber:
1780    """Central WaveNumber of band NB"""
1781    def __get__(self, obj, objtype=None):
1782        scale_factor = getattr(obj, "scaleFactorOfCentralWaveNumber")
1783        scaled_value = getattr(obj, "scaledValueOfCentralWaveNumber")
1784        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1785    def __set__(self, obj, value):
1786        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1787        setattr(obj, "scaleFactorOfCentralWaveNumber", scale_factor)
1788        setattr(obj, "scaledValueOfCentralWaveNumber", scaled_value)

Central WaveNumber of band NB

class TypeOfAerosol:
1790class TypeOfAerosol:
1791    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1792    _key = {46:2, 48:2}
1793    def __get__(self, obj, objtype=None):
1794        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1795    def __set__(self, obj, value):
1796        obj.section4[self._key[obj.pdtn]+2] = value
class TypeOfIntervalForAerosolSize:
1798class TypeOfIntervalForAerosolSize:
1799    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1800    _key = {46:3, 48:3}
1801    def __get__(self, obj, objtype=None):
1802        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1803    def __set__(self, obj, value):
1804        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstSize:
1806class ScaleFactorOfFirstSize:
1807    """Scale Factor of First Size"""
1808    _key = {46:4, 48:4}
1809    def __get__(self, obj, objtype=None):
1810        return obj.section4[self._key[obj.pdtn]+2]
1811    def __set__(self, obj, value):
1812        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Size

class ScaledValueOfFirstSize:
1814class ScaledValueOfFirstSize:
1815    """Scaled Value of First Size"""
1816    _key = {46:5, 48:5}
1817    def __get__(self, obj, objtype=None):
1818        return obj.section4[self._key[obj.pdtn]+2]
1819    def __set__(self, obj, value):
1820        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Size

class FirstSizeOfAerosol:
1822class FirstSizeOfAerosol:
1823    """First size of Aerosol"""
1824    def __get__(self, obj, objtype=None):
1825        scale_factor = getattr(obj, "scaleFactorOfFirstSize")
1826        scaled_value = getattr(obj, "scaledValueOfFirstSize")
1827        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1828    def __set__(self, obj, value):
1829        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1830        setattr(obj, "scaleFactorOfFirstSize", scale_factor)
1831        setattr(obj, "scaledValueOfFirstSize", scaled_value)

First size of Aerosol

class ScaleFactorOfSecondSize:
1833class ScaleFactorOfSecondSize:
1834    """Scale Factor of Second Size"""
1835    _key = {46:6, 48:6}
1836    def __get__(self, obj, objtype=None):
1837        return obj.section4[self._key[obj.pdtn]+2]
1838    def __set__(self, obj, value):
1839        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Size

class ScaledValueOfSecondSize:
1841class ScaledValueOfSecondSize:
1842    """Scaled Value of Second Size"""
1843    _key = {46:6, 48:7}
1844    def __get__(self, obj, objtype=None):
1845        return obj.section4[self._key[obj.pdtn]+2]
1846    def __set__(self, obj, value):
1847        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Size

class SecondSizeOfAerosol:
1849class SecondSizeOfAerosol:
1850    """Second size of Aerosol"""
1851    def __get__(self, obj, objtype=None):
1852        scale_factor = getattr(obj, "scaleFactorOfSecondSize")
1853        scaled_value = getattr(obj, "scaledValueOfSecondSize")
1854        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1855    def __set__(self, obj, value):
1856        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1857        setattr(obj, "scaleFactorOfSecondSize", scale_factor)
1858        setattr(obj, "scaledValueOfSecondSize", scaled_value)

Second size of Aerosol

class TypeOfIntervalForAerosolWavelength:
1860class TypeOfIntervalForAerosolWavelength:
1861    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1862    _key = {48:8}
1863    def __get__(self, obj, objtype=None):
1864        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1865    def __set__(self, obj, value):
1866        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstWavelength:
1868class ScaleFactorOfFirstWavelength:
1869    """Scale Factor of First Wavelength"""
1870    _key = {48:9}
1871    def __get__(self, obj, objtype=None):
1872        return obj.section4[self._key[obj.pdtn]+2]
1873    def __set__(self, obj, value):
1874        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Wavelength

class ScaledValueOfFirstWavelength:
1876class ScaledValueOfFirstWavelength:
1877    """Scaled Value of First Wavelength"""
1878    _key = {48:10}
1879    def __get__(self, obj, objtype=None):
1880        return obj.section4[self._key[obj.pdtn]+2]
1881    def __set__(self, obj, value):
1882        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Wavelength

class FirstWavelength:
1884class FirstWavelength:
1885    """First Wavelength"""
1886    def __get__(self, obj, objtype=None):
1887        scale_factor = getattr(obj, "scaleFactorOfFirstWavelength")
1888        scaled_value = getattr(obj, "scaledValueOfFirstWavelength")
1889        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1890    def __set__(self, obj, value):
1891        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1892        setattr(obj, "scaleFactorOfFirstWavelength", scale_factor)
1893        setattr(obj, "scaledValueOfFirstWavelength", scaled_value)

First Wavelength

class ScaleFactorOfSecondWavelength:
1895class ScaleFactorOfSecondWavelength:
1896    """Scale Factor of Second Wavelength"""
1897    _key = {48:11}
1898    def __get__(self, obj, objtype=None):
1899        return obj.section4[self._key[obj.pdtn]+2]
1900    def __set__(self, obj, value):
1901        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Wavelength

class ScaledValueOfSecondWavelength:
1903class ScaledValueOfSecondWavelength:
1904    """Scaled Value of Second Wavelength"""
1905    _key = {48:12}
1906    def __get__(self, obj, objtype=None):
1907        return obj.section4[self._key[obj.pdtn]+2]
1908    def __set__(self, obj, value):
1909        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Wavelength

class SecondWavelength:
1911class SecondWavelength:
1912    """Second Wavelength"""
1913    def __get__(self, obj, objtype=None):
1914        scale_factor = getattr(obj, "scaleFactorOfSecondWavelength")
1915        scaled_value = getattr(obj, "scaledValueOfSecondWavelength")
1916        return float(Decimal(int(scaled_value)) / (10 ** scale_factor))
1917    def __set__(self, obj, value):
1918        scale_factor, scaled_value = utils.decimal_to_scaled_int(value)
1919        setattr(obj, "scaleFactorOfSecondWavelength", scale_factor)
1920        setattr(obj, "scaledValueOfSecondWavelength", scaled_value)

Second Wavelength

class SourceSinkIndicator:
1922class SourceSinkIndicator:
1923    """[Source/Sink Indicator](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-238.shtml)"""
1924    _key = {80:3, 81:3, 82:3, 83:3, 84:3, 85:3}
1925    def __get__(self, obj, objtype=None):
1926        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.238')
1927    def __set__(self, obj, value):
1928        obj.section4[self._key[obj.pdtn]+2] = value
class ConstituentType:
1937class ConstituentType:
1938    """[Constituent Type](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-230.shtml)"""
1939    _key = defaultdict(lambda: 10)
1940    def __get__(self, obj, objtype=None):
1941        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.230')
1942    def __set__(self, obj, value):
1943        obj.section4[self._key[obj.pdtn]+2] = value
@dataclass(init=False)
class ProductDefinitionTemplateBase:
1973@dataclass(init=False)
1974class ProductDefinitionTemplateBase:
1975    """Base attributes for Product Definition Templates"""
1976    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1977    fullName: str = field(init=False, repr=False, default=FullName())
1978    units: str = field(init=False, repr=False, default=Units())
1979    shortName: str = field(init=False, repr=False, default=ShortName())
1980    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1981    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1982    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1983    level: str = field(init=False, repr=False, default=Level())
1984    # Begin template here...
1985    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1986    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1987    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1988    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1989    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1990    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1991    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1992    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1993    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1994
1995    @classmethod
1996    def _attrs(cls):
1997        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:
1999@dataclass(init=False)
2000class ProductDefinitionTemplateSurface:
2001    """Surface attributes for Product Definition Templates"""
2002    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
2003    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
2004    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
2005    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
2006    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
2007    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
2008    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
2009    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
2010    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
2011    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
2012    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
2013    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
2014
2015    @classmethod
2016    def _attrs(cls):
2017        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):
2019@dataclass(init=False)
2020class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2021    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
2022    _len = 15
2023    _num = 0
2024
2025    @classmethod
2026    def _attrs(cls):
2027        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
@dataclass(init=False)
class ProductDefinitionTemplate1(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2029@dataclass(init=False)
2030class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2031    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
2032    _len = 18
2033    _num = 1
2034    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2035    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2036    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2037
2038    @classmethod
2039    def _attrs(cls):
2040        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):
2042@dataclass(init=False)
2043class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2044    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
2045    _len = 17
2046    _num = 2
2047    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
2048    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2049
2050    @classmethod
2051    def _attrs(cls):
2052        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):
2054@dataclass(init=False)
2055class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2056    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
2057    _len = 22
2058    _num = 5
2059    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
2060    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
2061    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
2062    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
2063    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
2064    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
2065    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
2066    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
2067    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
2068    threshold: str = field(init=False, repr=False, default=Threshold())
2069
2070    @classmethod
2071    def _attrs(cls):
2072        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):
2074@dataclass(init=False)
2075class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2076    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
2077    _len = 16
2078    _num = 6
2079    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
2080
2081    @classmethod
2082    def _attrs(cls):
2083        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
percentileValue: int

Percentile Value

@dataclass(init=False)
class ProductDefinitionTemplate8(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2085@dataclass(init=False)
2086class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2087    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
2088    _len = 29
2089    _num = 8
2090    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2091    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2092    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2093    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2094    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2095    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2096    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2097    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2098    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2099    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2100    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2101    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2102    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2103    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2104
2105    @classmethod
2106    def _attrs(cls):
2107        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):
2109@dataclass(init=False)
2110class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2111    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
2112    _len = 36
2113    _num = 9
2114    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
2115    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
2116    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
2117    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
2118    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
2119    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
2120    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
2121    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
2122    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
2123    threshold: str = field(init=False, repr=False, default=Threshold())
2124    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2125    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2126    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2127    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2128    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2129    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2130    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2131    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2132    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2133    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2134    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2135    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2136    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2137    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2138
2139    @classmethod
2140    def _attrs(cls):
2141        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):
2143@dataclass(init=False)
2144class ProductDefinitionTemplate10(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2145    """[Product Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-10.shtml)"""
2146    _len = 30
2147    _num = 10
2148    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
2149    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2150    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2151    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2152    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2153    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2154    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2155    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2156    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2157    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2158    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2159    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2160    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2161    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2162    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2163
2164    @classmethod
2165    def _attrs(cls):
2166        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):
2168@dataclass(init=False)
2169class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2170    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
2171    _len = 32
2172    _num = 11
2173    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2174    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2175    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2176    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2177    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2178    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2179    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2180    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2181    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2182    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2183    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2184    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2185    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2186    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2187    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2188    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2189    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2190
2191    @classmethod
2192    def _attrs(cls):
2193        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):
2195@dataclass(init=False)
2196class ProductDefinitionTemplate12(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2197    """[Product Definition Template 12](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-12.shtml)"""
2198    _len = 31
2199    _num = 12
2200    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
2201    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2202    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2203    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2204    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2205    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2206    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2207    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2208    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2209    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2210    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2211    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2212    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2213    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2214    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2215    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2216
2217    @classmethod
2218    def _attrs(cls):
2219        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 ProductDefinitionTemplate13(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2221@dataclass(init=False)
2222class ProductDefinitionTemplate13(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2223    """[Product Definition Template 13](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-13.shtml)"""
2224    _len = 18
2225    _num = 13
2226    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2227    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2228    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2229    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2230    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2231    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2232    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2233    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2234
2235    @classmethod
2236    def _attrs(cls):
2237        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

typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate14(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2239@dataclass(init=False)
2240class ProductDefinitionTemplate14(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2241    """[Product Definition Template 14](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-14.shtml)"""
2242    _len = 18
2243    _num = 14
2244    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2245    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2246    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2247    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2248    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2249    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2250    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2251    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2252
2253    @classmethod
2254    def _attrs(cls):
2255        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

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):
2257@dataclass(init=False)
2258class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2259    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
2260    _len = 18
2261    _num = 15
2262    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2263    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2264    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2265
2266    @classmethod
2267    def _attrs(cls):
2268        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:
2286@dataclass(init=False)
2287class ProductDefinitionTemplate31:
2288    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
2289    _len = 5
2290    _num = 31
2291    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
2292    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
2293    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
2294    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
2295    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2296    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2297    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2298    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2299    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2300    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2301
2302    @classmethod
2303    def _attrs(cls):
2304        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

satelliteSeries: list

Satellite Series

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):
2306@dataclass(init=False)
2307class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
2308    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
2309    _len = 10
2310    _num = 32
2311    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2312    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2313    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2314    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2315    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2316    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2317
2318    @classmethod
2319    def _attrs(cls):
2320        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
numberOfContributingSpectralBands: int

Number of Contributing Spectral Bands

satelliteSeries: list

Satellite Series

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 ProductDefinitionTemplate46(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2400@dataclass(init=False)
2401class ProductDefinitionTemplate46(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2402    """[Product Definition Template 4.46](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-46.shtml)"""
2403    _len = 38  # Total number of octets
2404    _num = 46
2405
2406    # Aerosol-specific parameters
2407    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2408    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2409    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2410    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2411    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2412    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2413    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2414    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2415
2416    # Time interval parameters
2417    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2418    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2419    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2420    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2421    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2422    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2423    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2424    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2425
2426    # Statistical processing parameters
2427    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2428    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2429    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2430    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2431    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2432    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2433    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2434
2435    @classmethod
2436    def _attrs(cls):
2437        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

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

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

typeOfStatisticalProcessing: Grib2Metadata
numberOfDataPointsForSpatialProcessing: int

Number of Data Points for Spatial Processing

typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate47(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2440@dataclass(init=False)
2441class ProductDefinitionTemplate47(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2442    """[Product Definition Template 4.47](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-47.shtml)"""
2443    _len = 41  # Total number of octets for base template
2444    _num = 47
2445
2446    # Aerosol parameters
2447    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2448    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2449    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2450    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2451    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2452    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2453    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2454    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2455
2456    # Ensemble parameters
2457    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2458    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2459    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2460
2461    # Time interval parameters
2462    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2463    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2464    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2465    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2466    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2467    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2468    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2469    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2470
2471    # Statistical processing parameters
2472    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2473    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2474    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2475    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2476    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2477    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2478    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2479
2480    @classmethod
2481    def _attrs(cls):
2482        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

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

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

typeOfStatisticalProcessing: Grib2Metadata
numberOfDataPointsForSpatialProcessing: int

Number of Data Points for Spatial Processing

typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata
unitOfTimeRangeOfStatisticalProcess: Grib2Metadata
timeRangeOfStatisticalProcess: int

Time Range of Statistical Process

unitOfTimeRangeOfSuccessiveFields: Grib2Metadata
timeIncrementOfSuccessiveFields: int

Time Increment of Successive Fields

@dataclass(init=False)
class ProductDefinitionTemplate48(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2485@dataclass(init=False)
2486class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2487    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
2488    _len = 26
2489    _num = 48
2490    # Aerosol parameters
2491    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2492    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2493    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2494    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2495    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2496    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2497    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2498    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2499
2500    # Wavelength parameters
2501    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2502    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2503    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2504    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2505    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2506    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2507    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2508
2509    @classmethod
2510    def _attrs(cls):
2511        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

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplate49(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2514@dataclass(init=False)
2515class ProductDefinitionTemplate49(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2516    """[Product Definition Template 4.49](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-49.shtml)"""
2517    _len = 28
2518    _num = 49
2519
2520    # Aerosol parameters
2521    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2522    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2523    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2524    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2525    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2526    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2527    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2528    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2529
2530    # Wavelength parameters
2531    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2532    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2533    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2534    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2535    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2536    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2537    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2538
2539    # Ensemble parameters
2540    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2541    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2542    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate80(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2544@dataclass(init=False)
2545class ProductDefinitionTemplate80(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2546    """[Product Definition Template 4.80](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-80.shtml)"""
2547    _len = 26
2548    _num = 80
2549
2550    # Aerosol parameters
2551    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2552    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2553    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2554    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2555    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2556    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2557    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2558    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2559    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2560
2561    # Wavelength parameters
2562    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2563    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2564    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2565    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2566    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2567    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2568    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplate81(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2570@dataclass(init=False)
2571class ProductDefinitionTemplate81(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2572    """[Product Definition Template 4.81](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-81.shtml)"""
2573    _len = 31
2574    _num = 81
2575
2576    # Aerosol parameters
2577    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2578    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2579    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2580    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2581    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2582    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2583    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2584    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2585    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2586
2587    # Wavelength parameters
2588    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2589    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2590    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2591    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2592    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2593    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2594    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2595
2596    # Ensemble parameters
2597    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2598    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2599    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate82(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2601@dataclass(init=False)
2602class ProductDefinitionTemplate82(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2603    """[Product Definition Template 4.82](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-82.shtml)"""
2604    _len = 41
2605    _num = 82
2606
2607    # Aerosol parameters
2608    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2609    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2610    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2611    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2612    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2613    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2614    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2615    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2616    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2617
2618    # Wavelength parameters
2619    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2620    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2621    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2622    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2623    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2624    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2625    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2626
2627   # Time interval parameters
2628    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2629    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2630    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2631    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2632    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2633    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2634    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2635    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2636
2637    # Statistical processing parameters
2638    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2639    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2640    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2641    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2642    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2643    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2644    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2645    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

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 ProductDefinitionTemplate83(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2647@dataclass(init=False)
2648class ProductDefinitionTemplate83(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2649    """[Product Definition Template 4.83](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-83.shtml)"""
2650    _len = 44
2651    _num = 83
2652
2653    # Aerosol parameters
2654    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2655    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2656    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2657    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2658    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2659    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2660    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2661    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2662    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2663
2664    # Wavelength parameters
2665    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2666    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2667    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2668    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2669    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2670    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2671    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2672
2673    # Ensemble parameters
2674    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2675    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2676    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2677
2678    # Time interval parameters
2679    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2680    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2681    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2682    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2683    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2684    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2685    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2686    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

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

@dataclass(init=False)
class ProductDefinitionTemplate84(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2688@dataclass(init=False)
2689class ProductDefinitionTemplate84(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2690    """[Product Definition Template 4.84](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-84.shtml)"""
2691    _len = 44
2692    _num = 84
2693
2694    # Aerosol parameters
2695    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2696    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2697    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2698    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2699    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2700    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2701    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2702    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2703    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2704
2705    # Wavelength parameters
2706    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2707    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2708    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2709    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2710    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2711    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2712    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2713
2714    # Ensemble parameters
2715    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2716    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2717    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2718
2719    # Time interval parameters
2720    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2721    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2722    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2723    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2724    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2725    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2726
2727    # Statistical processing parameters
2728    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2729    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2730    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2731    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2732    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2733    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2734    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2735    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

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 ProductDefinitionTemplate85(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2737@dataclass(init=False)
2738class ProductDefinitionTemplate85(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2739    """[Product Definition Template 4.85](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-85.shtml)"""
2740    _len = 33
2741    _num = 85
2742
2743    # Aerosol parameters
2744    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2745    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2746    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2747    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2748    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2749    firstSizeOfAerosol: float = field(init=False, repr=False, default=FirstSizeOfAerosol())
2750    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2751    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2752    secondSizeOfAerosol: float = field(init=False, repr=False, default=SecondSizeOfAerosol())
2753
2754    # Wavelength parameters
2755    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2756    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2757    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2758    firstWavelength: float = field(init=False, repr=False, default=FirstWavelength())
2759    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2760    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2761    secondWavelength: float = field(init=False, repr=False, default=SecondWavelength())
2762
2763    # Ensemble parameters
2764    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2765    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2766    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

firstSizeOfAerosol: float

First size of Aerosol

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

secondSizeOfAerosol: float

Second size of Aerosol

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

firstWavelength: float

First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

secondWavelength: float

Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

def pdt_class_by_pdtn(pdtn: int):
2794def pdt_class_by_pdtn(pdtn: int):
2795    """
2796    Provide a Product Definition Template class via the template number.
2797
2798    Parameters
2799    ----------
2800    pdtn
2801        Product definition template number.
2802
2803    Returns
2804    -------
2805    pdt_class_by_pdtn
2806        Product definition template class object (not an instance).
2807    """
2808    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:
2813class NumberOfPackedValues:
2814    """Number of Packed Values"""
2815    def __get__(self, obj, objtype=None):
2816        return obj.section5[0]
2817    def __set__(self, obj, value):
2818        pass

Number of Packed Values

class DataRepresentationTemplateNumber:
2820class DataRepresentationTemplateNumber:
2821    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
2822    def __get__(self, obj, objtype=None):
2823        return Grib2Metadata(obj.section5[1],table='5.0')
2824    def __set__(self, obj, value):
2825        pass
class DataRepresentationTemplate:
2827class DataRepresentationTemplate:
2828    """Data Representation Template"""
2829    def __get__(self, obj, objtype=None):
2830        return obj.section5[2:]
2831    def __set__(self, obj, value):
2832        raise NotImplementedError

Data Representation Template

class RefValue:
2834class RefValue:
2835    """Reference Value (represented as an IEEE 32-bit floating point value)"""
2836    def __get__(self, obj, objtype=None):
2837        return utils.ieee_int_to_float(obj.section5[0+2])
2838    def __set__(self, obj, value):
2839        pass

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

class BinScaleFactor:
2841class BinScaleFactor:
2842    """Binary Scale Factor"""
2843    def __get__(self, obj, objtype=None):
2844        return obj.section5[1+2]
2845    def __set__(self, obj, value):
2846        obj.section5[1+2] = value

Binary Scale Factor

class DecScaleFactor:
2848class DecScaleFactor:
2849    """Decimal Scale Factor"""
2850    def __get__(self, obj, objtype=None):
2851        return obj.section5[2+2]
2852    def __set__(self, obj, value):
2853        obj.section5[2+2] = value

Decimal Scale Factor

class NBitsPacking:
2855class NBitsPacking:
2856    """Minimum number of bits for packing"""
2857    def __get__(self, obj, objtype=None):
2858        return obj.section5[3+2]
2859    def __set__(self, obj, value):
2860        obj.section5[3+2] = value

Minimum number of bits for packing

class TypeOfValues:
2862class TypeOfValues:
2863    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2864    def __get__(self, obj, objtype=None):
2865        return Grib2Metadata(obj.section5[4+2],table='5.1')
2866    def __set__(self, obj, value):
2867        obj.section5[4+2] = value
class GroupSplittingMethod:
2869class GroupSplittingMethod:
2870    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2871    def __get__(self, obj, objtype=None):
2872        return Grib2Metadata(obj.section5[5+2],table='5.4')
2873    def __set__(self, obj, value):
2874        obj.section5[5+2] = value
class TypeOfMissingValueManagement:
2876class TypeOfMissingValueManagement:
2877    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2878    def __get__(self, obj, objtype=None):
2879        return Grib2Metadata(obj.section5[6+2],table='5.5')
2880    def __set__(self, obj, value):
2881        obj.section5[6+2] = value
class PriMissingValue:
2883class PriMissingValue:
2884    """Primary Missing Value"""
2885    def __get__(self, obj, objtype=None):
2886        if obj.typeOfValues == 0:
2887            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
2888        elif obj.typeOfValues == 1:
2889            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2890    def __set__(self, obj, value):
2891        if obj.typeOfValues == 0:
2892            obj.section5[7+2] = utils.ieee_float_to_int(value)
2893        elif self.typeOfValues == 1:
2894            obj.section5[7+2] = int(value)
2895        obj.section5[6+2] = 1

Primary Missing Value

class SecMissingValue:
2897class SecMissingValue:
2898    """Secondary Missing Value"""
2899    def __get__(self, obj, objtype=None):
2900        if obj.typeOfValues == 0:
2901            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
2902        elif obj.typeOfValues == 1:
2903            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2904    def __set__(self, obj, value):
2905        if obj.typeOfValues == 0:
2906            obj.section5[8+2] = utils.ieee_float_to_int(value)
2907        elif self.typeOfValues == 1:
2908            obj.section5[8+2] = int(value)
2909        obj.section5[6+2] = 2

Secondary Missing Value

class NGroups:
2911class NGroups:
2912    """Number of Groups"""
2913    def __get__(self, obj, objtype=None):
2914        return obj.section5[9+2]
2915    def __set__(self, obj, value):
2916        pass

Number of Groups

class RefGroupWidth:
2918class RefGroupWidth:
2919    """Reference Group Width"""
2920    def __get__(self, obj, objtype=None):
2921        return obj.section5[10+2]
2922    def __set__(self, obj, value):
2923        pass

Reference Group Width

class NBitsGroupWidth:
2925class NBitsGroupWidth:
2926    """Number of bits for Group Width"""
2927    def __get__(self, obj, objtype=None):
2928        return obj.section5[11+2]
2929    def __set__(self, obj, value):
2930        pass

Number of bits for Group Width

class RefGroupLength:
2932class RefGroupLength:
2933    """Reference Group Length"""
2934    def __get__(self, obj, objtype=None):
2935        return obj.section5[12+2]
2936    def __set__(self, obj, value):
2937        pass

Reference Group Length

class GroupLengthIncrement:
2939class GroupLengthIncrement:
2940    """Group Length Increment"""
2941    def __get__(self, obj, objtype=None):
2942        return obj.section5[13+2]
2943    def __set__(self, obj, value):
2944        pass

Group Length Increment

class LengthOfLastGroup:
2946class LengthOfLastGroup:
2947    """Length of Last Group"""
2948    def __get__(self, obj, objtype=None):
2949        return obj.section5[14+2]
2950    def __set__(self, obj, value):
2951        pass

Length of Last Group

class NBitsScaledGroupLength:
2953class NBitsScaledGroupLength:
2954    """Number of bits of Scaled Group Length"""
2955    def __get__(self, obj, objtype=None):
2956        return obj.section5[15+2]
2957    def __set__(self, obj, value):
2958        pass

Number of bits of Scaled Group Length

class SpatialDifferenceOrder:
2960class SpatialDifferenceOrder:
2961    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2962    def __get__(self, obj, objtype=None):
2963        return Grib2Metadata(obj.section5[16+2],table='5.6')
2964    def __set__(self, obj, value):
2965        obj.section5[16+2] = value
class NBytesSpatialDifference:
2967class NBytesSpatialDifference:
2968    """Number of bytes for Spatial Differencing"""
2969    def __get__(self, obj, objtype=None):
2970        return obj.section5[17+2]
2971    def __set__(self, obj, value):
2972        pass

Number of bytes for Spatial Differencing

class Precision:
2974class Precision:
2975    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2976    def __get__(self, obj, objtype=None):
2977        return Grib2Metadata(obj.section5[0+2],table='5.7')
2978    def __set__(self, obj, value):
2979        obj.section5[0+2] = value
class TypeOfCompression:
2981class TypeOfCompression:
2982    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2983    def __get__(self, obj, objtype=None):
2984        return Grib2Metadata(obj.section5[5+2],table='5.40')
2985    def __set__(self, obj, value):
2986        obj.section5[5+2] = value
class TargetCompressionRatio:
2988class TargetCompressionRatio:
2989    """Target Compression Ratio"""
2990    def __get__(self, obj, objtype=None):
2991        return obj.section5[6+2]
2992    def __set__(self, obj, value):
2993        pass

Target Compression Ratio

class RealOfCoefficient:
2995class RealOfCoefficient:
2996    """Real of Coefficient"""
2997    def __get__(self, obj, objtype=None):
2998        return utils.ieee_int_to_float(obj.section5[4+2])
2999    def __set__(self, obj, value):
3000        obj.section5[4+2] = utils.ieee_float_to_int(float(value))

Real of Coefficient

class CompressionOptionsMask:
3002class CompressionOptionsMask:
3003    """Compression Options Mask for AEC/CCSDS"""
3004    def __get__(self, obj, objtype=None):
3005        return obj.section5[5+2]
3006    def __set__(self, obj, value):
3007        obj.section5[5+2] = value

Compression Options Mask for AEC/CCSDS

class BlockSize:
3009class BlockSize:
3010    """Block Size for AEC/CCSDS"""
3011    def __get__(self, obj, objtype=None):
3012        return obj.section5[6+2]
3013    def __set__(self, obj, value):
3014        obj.section5[6+2] = value

Block Size for AEC/CCSDS

class RefSampleInterval:
3016class RefSampleInterval:
3017    """Reference Sample Interval for AEC/CCSDS"""
3018    def __get__(self, obj, objtype=None):
3019        return obj.section5[7+2]
3020    def __set__(self, obj, value):
3021        obj.section5[7+2] = value

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate0:
3023@dataclass(init=False)
3024class DataRepresentationTemplate0:
3025    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
3026    _len = 5
3027    _num = 0
3028    _packingScheme = 'simple'
3029    refValue: float = field(init=False, repr=False, default=RefValue())
3030    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3031    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3032    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3033
3034    @classmethod
3035    def _attrs(cls):
3036        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:
3038@dataclass(init=False)
3039class DataRepresentationTemplate2:
3040    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
3041    _len = 16
3042    _num = 2
3043    _packingScheme = 'complex'
3044    refValue: float = field(init=False, repr=False, default=RefValue())
3045    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3046    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3047    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3048    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
3049    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
3050    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
3051    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
3052    nGroups: int = field(init=False, repr=False, default=NGroups())
3053    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
3054    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
3055    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
3056    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
3057    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
3058    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
3059
3060    @classmethod
3061    def _attrs(cls):
3062        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:
3064@dataclass(init=False)
3065class DataRepresentationTemplate3:
3066    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
3067    _len = 18
3068    _num = 3
3069    _packingScheme = 'complex-spdiff'
3070    refValue: float = field(init=False, repr=False, default=RefValue())
3071    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3072    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3073    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3074    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
3075    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
3076    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
3077    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
3078    nGroups: int = field(init=False, repr=False, default=NGroups())
3079    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
3080    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
3081    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
3082    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
3083    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
3084    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
3085    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
3086    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
3087
3088    @classmethod
3089    def _attrs(cls):
3090        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:
3092@dataclass(init=False)
3093class DataRepresentationTemplate4:
3094    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
3095    _len = 1
3096    _num = 4
3097    _packingScheme = 'ieee-float'
3098    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
3099
3100    @classmethod
3101    def _attrs(cls):
3102        return list(cls.__dataclass_fields__.keys())
@dataclass(init=False)
class DataRepresentationTemplate40:
3104@dataclass(init=False)
3105class DataRepresentationTemplate40:
3106    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
3107    _len = 7
3108    _num = 40
3109    _packingScheme = 'jpeg'
3110    refValue: float = field(init=False, repr=False, default=RefValue())
3111    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3112    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3113    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3114    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
3115    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
3116
3117    @classmethod
3118    def _attrs(cls):
3119        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:
3121@dataclass(init=False)
3122class DataRepresentationTemplate41:
3123    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
3124    _len = 5
3125    _num = 41
3126    _packingScheme = 'png'
3127    refValue: float = field(init=False, repr=False, default=RefValue())
3128    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3129    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3130    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3131
3132    @classmethod
3133    def _attrs(cls):
3134        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:
3136@dataclass(init=False)
3137class DataRepresentationTemplate42:
3138    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
3139    _len = 8
3140    _num = 42
3141    _packingScheme = 'aec'
3142    refValue: float = field(init=False, repr=False, default=RefValue())
3143    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3144    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3145    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3146    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
3147    blockSize: int = field(init=False, repr=False, default=BlockSize())
3148    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
3149
3150    @classmethod
3151    def _attrs(cls):
3152        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:
3154@dataclass(init=False)
3155class DataRepresentationTemplate50:
3156    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
3157    _len = 5
3158    _num = 0
3159    _packingScheme = 'spectral-simple'
3160    refValue: float = field(init=False, repr=False, default=RefValue())
3161    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3162    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3163    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3164    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
3165
3166    @classmethod
3167    def _attrs(cls):
3168        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):
3181def drt_class_by_drtn(drtn: int):
3182    """
3183    Provide a Data Representation Template class via the template number.
3184
3185    Parameters
3186    ----------
3187    drtn
3188        Data Representation template number.
3189
3190    Returns
3191    -------
3192    drt_class_by_drtn
3193        Data Representation template class object (not an instance).
3194    """
3195    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).