grib2io.templates

GRIB2 section templates classes and metadata descriptor classes.

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

Provide the definition of the numeric metadata.

def show_table(self):
107    def show_table(self):
108        """Provide the table related to this metadata."""
109        return tables.get_table(self.table)

Provide the table related to this metadata.

class IndicatorSection:
114class IndicatorSection:
115    """
116    [GRIB2 Indicator Section (0)](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect0.shtml)
117    """
118    def __get__(self, obj, objtype=None):
119        return obj.section0
120    def __set__(self, obj, value):
121        obj.section0 = value
class Discipline:
123class Discipline:
124    """[Discipline](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table0-0.shtml)"""
125    def __get__(self, obj, objtype=None):
126        return Grib2Metadata(obj.indicatorSection[2],table='0.0')
127    def __set__(self, obj, value):
128        obj.section0[2] = value
class IdentificationSection:
134class IdentificationSection:
135    """
136    GRIB2 Section 1, [Identification Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect1.shtml)
137    """
138    def __get__(self, obj, objtype=None):
139        return obj.section1
140    def __set__(self, obj, value):
141        obj.section1 = value

GRIB2 Section 1, Identification Section

class OriginatingCenter:
143class OriginatingCenter:
144    """[Originating Center](https://www.nco.ncep.noaa.gov/pmb/docs/on388/table0.html)"""
145    def __get__(self, obj, objtype=None):
146        return Grib2Metadata(obj.section1[0],table='originating_centers')
147    def __set__(self, obj, value):
148        obj.section1[0] = value
class OriginatingSubCenter:
150class OriginatingSubCenter:
151    """[Originating SubCenter](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablec.html)"""
152    def __get__(self, obj, objtype=None):
153        return Grib2Metadata(obj.section1[1],table='originating_subcenters')
154    def __set__(self, obj, value):
155        obj.section1[1] = value
class MasterTableInfo:
157class MasterTableInfo:
158    """[GRIB2 Master Table Version](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-0.shtml)"""
159    def __get__(self, obj, objtype=None):
160        return Grib2Metadata(obj.section1[2],table='1.0')
161    def __set__(self, obj, value):
162        obj.section1[2] = value
class LocalTableInfo:
164class LocalTableInfo:
165    """[GRIB2 Local Tables Version Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-1.shtml)"""
166    def __get__(self, obj, objtype=None):
167        return Grib2Metadata(obj.section1[3],table='1.1')
168    def __set__(self, obj, value):
169        obj.section1[3] = value
class SignificanceOfReferenceTime:
171class SignificanceOfReferenceTime:
172    """[Significance of Reference Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-2.shtml)"""
173    def __get__(self, obj, objtype=None):
174        return Grib2Metadata(obj.section1[4],table='1.2')
175    def __set__(self, obj, value):
176        obj.section1[4] = value
class Year:
178class Year:
179    """Year of reference time"""
180    def __get__(self, obj, objtype=None):
181        return obj.section1[5]
182    def __set__(self, obj, value):
183        rd = copy.copy(obj.section1[5:11])
184        rd[0] = value
185        # Test validity of datetime values
186        _ = datetime.datetime(*rd)
187        obj.section1[5] = value

Year of reference time

class Month:
189class Month:
190    """Month of reference time"""
191    def __get__(self, obj, objtype=None):
192        return obj.section1[6]
193    def __set__(self, obj, value):
194        rd = copy.copy(obj.section1[5:11])
195        rd[1] = value
196        # Test validity of datetime values
197        _ = datetime.datetime(*rd)
198        obj.section1[6] = value

Month of reference time

class Day:
200class Day:
201    """Day of reference time"""
202    def __get__(self, obj, objtype=None):
203        return obj.section1[7]
204    def __set__(self, obj, value):
205        rd = copy.copy(obj.section1[5:11])
206        rd[2] = value
207        # Test validity of datetime values
208        _ = datetime.datetime(*rd)
209        #obj.section1[7] = value

Day of reference time

class Hour:
211class Hour:
212    """Hour of reference time"""
213    def __get__(self, obj, objtype=None):
214        return obj.section1[8]
215    def __set__(self, obj, value):
216        rd = copy.copy(obj.section1[5:11])
217        rd[3] = value
218        # Test validity of datetime values
219        _ = datetime.datetime(*rd)
220        obj.section1[8] = value

Hour of reference time

class Minute:
222class Minute:
223    """Minute of reference time"""
224    def __get__(self, obj, objtype=None):
225        return obj.section1[9]
226    def __set__(self, obj, value):
227        rd = copy.copy(obj.section1[5:11])
228        rd[4] = value
229        # Test validity of datetime values
230        _ = datetime.datetime(*rd)
231        obj.section1[9] = value

Minute of reference time

class Second:
233class Second:
234    """Second of reference time"""
235    def __get__(self, obj, objtype=None):
236        return obj.section1[10]
237    def __set__(self, obj, value):
238        rd = copy.copy(obj.section1[5:11])
239        rd[5] = value
240        # Test validity of datetime values
241        _ = datetime.datetime(*rd)
242        obj.section1[10] = value

Second of reference time

class RefDate:
244class RefDate:
245    """Reference Date. NOTE: This is a `datetime.datetime` object."""
246    def __get__(self, obj, objtype=None):
247        return datetime.datetime(*obj.section1[5:11])
248    def __set__(self, obj, value):
249        if isinstance(value, np.datetime64):
250            timestamp = (value - np.datetime64("1970-01-01T00:00:00")) / np.timedelta64(
251                1, "s"
252            )
253            try:
254                # Python >= 3.10
255                value = datetime.datetime.fromtimestamp(timestamp, datetime.UTC)
256            except(AttributeError):
257                # Python < 3.10
258                value = datetime.datetime.utcfromtimestamp(timestamp)
259        if isinstance(value, datetime.datetime):
260            obj.section1[5] = value.year
261            obj.section1[6] = value.month
262            obj.section1[7] = value.day
263            obj.section1[8] = value.hour
264            obj.section1[9] = value.minute
265            obj.section1[10] = value.second
266            # IMPORTANT: Update validDate components when message is time interval
267            if obj.pdtn in _timeinterval_pdtns:
268                vd = value + obj.leadTime + obj.duration
269                obj.yearOfEndOfTimePeriod = vd.year
270                obj.monthOfEndOfTimePeriod = vd.month
271                obj.dayOfEndOfTimePeriod = vd.day
272                obj.hourOfEndOfTimePeriod = vd.hour
273                obj.minuteOfEndOfTimePeriod = vd.minute
274                obj.secondOfEndOfTimePeriod = vd.second
275        else:
276            msg = "Reference date must be a datetime.datetime or np.datetime64 object."
277            raise TypeError(msg)

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

class ProductionStatus:
279class ProductionStatus:
280    """[Production Status of Processed Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-3.shtml)"""
281    def __get__(self, obj, objtype=None):
282        return Grib2Metadata(obj.section1[11],table='1.3')
283    def __set__(self, obj, value):
284        obj.section1[11] = value
class TypeOfData:
286class TypeOfData:
287    """[Type of Processed Data in this GRIB message](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table1-4.shtml)"""
288    def __get__(self, obj, objtype=None):
289        return Grib2Metadata(obj.section1[12],table='1.4')
290    def __set__(self, obj, value):
291        obj.section1[12] = value
class GridDefinitionSection:
300class GridDefinitionSection:
301    """
302    GRIB2 Section 3, [Grid Definition Section](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_sect3.shtml)
303    """
304    def __get__(self, obj, objtype=None):
305        return obj.section3[0:5]
306    def __set__(self, obj, value):
307        raise RuntimeError

GRIB2 Section 3, Grid Definition Section

class SourceOfGridDefinition:
309class SourceOfGridDefinition:
310    """[Source of Grid Definition](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-0.shtml)"""
311    def __get__(self, obj, objtype=None):
312        return Grib2Metadata(obj.section3[0],table='3.0')
313    def __set__(self, obj, value):
314        raise RuntimeError
class NumberOfDataPoints:
316class NumberOfDataPoints:
317    """Number of Data Points"""
318    def __get__(self, obj, objtype=None):
319        return obj.section3[1]
320    def __set__(self, obj, value):
321        raise RuntimeError

Number of Data Points

class InterpretationOfListOfNumbers:
323class InterpretationOfListOfNumbers:
324    """Interpretation of List of Numbers"""
325    def __get__(self, obj, objtype=None):
326        return Grib2Metadata(obj.section3[3],table='3.11')
327    def __set__(self, obj, value):
328        raise RuntimeError

Interpretation of List of Numbers

class GridDefinitionTemplateNumber:
330class GridDefinitionTemplateNumber:
331    """[Grid Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-1.shtml)"""
332    def __get__(self, obj, objtype=None):
333        return Grib2Metadata(obj.section3[4],table='3.1')
334    def __set__(self, obj, value):
335        raise RuntimeError
class GridDefinitionTemplate:
337class GridDefinitionTemplate:
338    """Grid definition template"""
339    def __get__(self, obj, objtype=None):
340        return obj.section3[5:]
341    def __set__(self, obj, value):
342        raise RuntimeError

Grid definition template

class EarthParams:
344class EarthParams:
345    """Metadata about the shape of the Earth"""
346    def __get__(self, obj, objtype=None):
347        if obj.section3[5] in {50,51,52,1200}:
348            return None
349        return tables.get_table('earth_params')[str(obj.section3[5])]
350    def __set__(self, obj, value):
351        raise RuntimeError

Metadata about the shape of the Earth

class DxSign:
353class DxSign:
354    """Sign of Grid Length in X-Direction"""
355    def __get__(self, obj, objtype=None):
356        if obj.section3[4] in {0,1,203,205,32768,32769} and \
357        obj.section3[17] > obj.section3[20]:
358            return -1.0
359        return 1.0
360    def __set__(self, obj, value):
361        raise RuntimeError

Sign of Grid Length in X-Direction

class DySign:
363class DySign:
364    """Sign of Grid Length in Y-Direction"""
365    def __get__(self, obj, objtype=None):
366        if obj.section3[4] in {0,1,203,205,32768,32769} and \
367        obj.section3[16] > obj.section3[19]:
368            return -1.0
369        return 1.0
370    def __set__(self, obj, value):
371        raise RuntimeError

Sign of Grid Length in Y-Direction

class LLScaleFactor:
373class LLScaleFactor:
374    """Scale Factor for Lats/Lons"""
375    def __get__(self, obj, objtype=None):
376        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
377            llscalefactor = float(obj.section3[14])
378            if llscalefactor == 0:
379                return 1
380            return llscalefactor
381        return 1
382    def __set__(self, obj, value):
383        raise RuntimeError

Scale Factor for Lats/Lons

class LLDivisor:
385class LLDivisor:
386    """Divisor Value for scaling Lats/Lons"""
387    def __get__(self, obj, objtype=None):
388        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
389            lldivisor = float(obj.section3[15])
390            if lldivisor <= 0:
391                return 1.e6
392            return lldivisor
393        return 1.e6
394    def __set__(self, obj, value):
395        raise RuntimeError

Divisor Value for scaling Lats/Lons

class XYDivisor:
397class XYDivisor:
398    """Divisor Value for scaling grid lengths"""
399    def __get__(self, obj, objtype=None):
400        if obj.section3[4] in {0,1,40,41,203,205,32768,32769}:
401            return obj._lldivisor
402        return 1.e3
403    def __set__(self, obj, value):
404        raise RuntimeError

Divisor Value for scaling grid lengths

class ShapeOfEarth:
406class ShapeOfEarth:
407    """[Shape of the Reference System](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-2.shtml)"""
408    def __get__(self, obj, objtype=None):
409        return Grib2Metadata(obj.section3[5],table='3.2')
410    def __set__(self, obj, value):
411        obj.section3[5] = value
class EarthShape:
413class EarthShape:
414    """Description of the shape of the Earth"""
415    def __get__(self, obj, objtype=None):
416        return obj._earthparams['shape']
417    def __set__(self, obj, value):
418        raise RuntimeError

Description of the shape of the Earth

class EarthRadius:
420class EarthRadius:
421    """Radius of the Earth (Assumes "spherical")"""
422    def __get__(self, obj, objtype=None):
423        ep = obj._earthparams
424        if ep['shape'] == 'spherical':
425            if ep['radius'] is None:
426                return obj.section3[7]/(10.**obj.section3[6])
427            else:
428                return ep['radius']
429        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
430            return None
431    def __set__(self, obj, value):
432        raise RuntimeError

Radius of the Earth (Assumes "spherical")

class EarthMajorAxis:
434class EarthMajorAxis:
435    """Major Axis of the Earth (Assumes "oblate spheroid" or "ellipsoid")"""
436    def __get__(self, obj, objtype=None):
437        ep = obj._earthparams
438        if ep['shape'] == 'spherical':
439            return None
440        elif ep['shape'] in {'ellipsoid','oblateSpheriod'}:
441            if ep['major_axis'] is None and ep['minor_axis'] is None:
442                return obj.section3[9]/(10.**obj.section3[8])
443            else:
444                return ep['major_axis']
445    def __set__(self, obj, value):
446        raise RuntimeError

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

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

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

class Nx:
462class Nx:
463    """Number of grid points in the X-direction (generally East-West)"""
464    def __get__(self, obj, objtype=None):
465        return obj.section3[12]
466    def __set__(self, obj, value):
467        obj.section3[12] = value
468        obj.section3[1] = value * obj.section3[13]

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

class Ny:
470class Ny:
471    """Number of grid points in the Y-direction (generally North-South)"""
472    def __get__(self, obj, objtype=None):
473        return obj.section3[13]
474    def __set__(self, obj, value):
475        obj.section3[13] = value
476        obj.section3[1] = value * obj.section3[12]

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

class ScanModeFlags:
478class ScanModeFlags:
479    """[Scanning Mode](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-4.shtml)"""
480    _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}
481    def __get__(self, obj, objtype=None):
482        if obj.gdtn == 50:
483            return [None, None, None, None]
484        else:
485            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0:8]
486    def __set__(self, obj, value):
487        obj.section3[self._key[obj.gdtn]+5] = value
class ResolutionAndComponentFlags:
489class ResolutionAndComponentFlags:
490    """[Resolution and Component Flags](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-3.shtml)"""
491    _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}
492    def __get__(self, obj, objtype=None):
493        if obj.gdtn == 50:
494            return [None for i in range(8)]
495        else:
496            return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)
497    def __set__(self, obj, value):
498        obj.section3[self._key[obj.gdtn]+5] = value
class LatitudeFirstGridpoint:
500class LatitudeFirstGridpoint:
501    """Latitude of first gridpoint"""
502    _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}
503    def __get__(self, obj, objtype=None):
504        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
505    def __set__(self, obj, value):
506        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Latitude of first gridpoint

class LongitudeFirstGridpoint:
508class LongitudeFirstGridpoint:
509    """Longitude of first gridpoint"""
510    _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}
511    def __get__(self, obj, objtype=None):
512        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
513    def __set__(self, obj, value):
514        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude of first gridpoint

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

class LongitudeLastGridpoint:
524class LongitudeLastGridpoint:
525    """Longitude of last gridpoint"""
526    _key = {0:15, 1:15, 10:14, 40:15, 41:15, 203:15, 204:15, 205:15, 32768:15, 32769:20}
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 last gridpoint

class LatitudeCenterGridpoint:
532class LatitudeCenterGridpoint:
533    """Latitude of center gridpoint"""
534    _key = {32768:14, 32769:14}
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 center gridpoint

class LongitudeCenterGridpoint:
540class LongitudeCenterGridpoint:
541    """Longitude of center gridpoint"""
542    _key = {32768:15, 32769:15}
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 center gridpoint

class GridlengthXDirection:
548class GridlengthXDirection:
549    """Grid lenth in the X-Direction"""
550    _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}
551    def __get__(self, obj, objtype=None):
552        return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dxsign
553    def __set__(self, obj, value):
554        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the X-Direction

class GridlengthYDirection:
556class GridlengthYDirection:
557    """Grid lenth in the Y-Direction"""
558    _key = {0:17, 1:17, 10:18, 20:15, 30:15, 31:15, 203:17, 204:17, 205:17, 32768:17, 32769:17}
559    def __get__(self, obj, objtype=None):
560        if obj.gdtn in {40, 41}:
561            return obj.gridlengthXDirection
562        else:
563            return (obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._xydivisor)*obj._dysign
564    def __set__(self, obj, value):
565        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._xydivisor/obj._llscalefactor)

Grid lenth in the Y-Direction

class NumberOfParallels:
567class NumberOfParallels:
568    """Number of parallels between a pole and the equator"""
569    _key = {40:17, 41:17}
570    def __get__(self, obj, objtype=None):
571        return obj.section3[self._key[obj.gdtn]+5]
572    def __set__(self, obj, value):
573        raise RuntimeError

Number of parallels between a pole and the equator

class LatitudeSouthernPole:
575class LatitudeSouthernPole:
576    """Latitude of the Southern Pole for a Rotated Lat/Lon Grid"""
577    _key = {1:19, 30:20, 31:20, 41:19}
578    def __get__(self, obj, objtype=None):
579        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
580    def __set__(self, obj, value):
581        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class LongitudeSouthernPole:
583class LongitudeSouthernPole:
584    """Longitude of the Southern Pole for a Rotated Lat/Lon Grid"""
585    _key = {1:20, 30:21, 31:21, 41:20}
586    def __get__(self, obj, objtype=None):
587        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
588    def __set__(self, obj, value):
589        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

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

class AnglePoleRotation:
591class AnglePoleRotation:
592    """Angle of Pole Rotation for a Rotated Lat/Lon Grid"""
593    _key = {1:21, 41:21}
594    def __get__(self, obj, objtype=None):
595        return obj.section3[self._key[obj.gdtn]+5]
596    def __set__(self, obj, value):
597        obj.section3[self._key[obj.gdtn]+5] = int(value)

Angle of Pole Rotation for a Rotated Lat/Lon Grid

class LatitudeTrueScale:
599class LatitudeTrueScale:
600    """Latitude at which grid lengths are specified"""
601    _key = {10:12, 20:12, 30:12, 31:12}
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)

Latitude at which grid lengths are specified

class GridOrientation:
607class GridOrientation:
608    """Longitude at which the grid is oriented"""
609    _key = {10:16, 20:13, 30:13, 31:13}
610    def __get__(self, obj, objtype=None):
611        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
612    def __set__(self, obj, value):
613        if obj.gdtn == 10 and (value < 0 or value > 90):
614            raise ValueError("Grid orientation is limited to range of 0 to 90 degrees.")
615        obj.section3[self._key[obj.gdtn]+5] = int(value*obj._lldivisor/obj._llscalefactor)

Longitude at which the grid is oriented

class ProjectionCenterFlag:
617class ProjectionCenterFlag:
618    """[Projection Center](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table3-5.shtml)"""
619    _key = {20:16, 30:16, 31:16}
620    def __get__(self, obj, objtype=None):
621        return utils.int2bin(obj.section3[self._key[obj.gdtn]+5],output=list)[0]
622    def __set__(self, obj, value):
623        obj.section3[self._key[obj.gdtn]+5] = value
class StandardLatitude1:
625class StandardLatitude1:
626    """First Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
627    _key = {30:18, 31:18}
628    def __get__(self, obj, objtype=None):
629        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
630    def __set__(self, obj, value):
631        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:
633class StandardLatitude2:
634    """Second Standard Latitude (from the pole at which the secant cone cuts the sphere)"""
635    _key = {30:19, 31:19}
636    def __get__(self, obj, objtype=None):
637        return obj._llscalefactor*obj.section3[self._key[obj.gdtn]+5]/obj._lldivisor
638    def __set__(self, obj, value):
639        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:
641class SpectralFunctionParameters:
642    """Spectral Function Parameters"""
643    def __get__(self, obj, objtype=None):
644        return obj.section3[0:3]
645    def __set__(self, obj, value):
646        obj.section3[0:3] = value[0:3]

Spectral Function Parameters

class ProjParameters:
648class ProjParameters:
649    """PROJ Parameters to define the reference system"""
650    def __get__(self, obj, objtype=None):
651        projparams = {}
652        projparams['a'] = 1.0
653        projparams['b'] = 1.0
654        if obj.earthRadius is not None:
655            projparams['a'] = obj.earthRadius
656            projparams['b'] = obj.earthRadius
657        else:
658            if obj.earthMajorAxis is not None: projparams['a'] = obj.earthMajorAxis
659            if obj.earthMajorAxis is not None: projparams['b'] = obj.earthMinorAxis
660        if obj.gdtn == 0:
661            projparams['proj'] = 'longlat'
662        elif obj.gdtn == 1:
663            projparams['o_proj'] = 'longlat'
664            projparams['proj'] = 'ob_tran'
665            projparams['o_lat_p'] = -1.0*obj.latitudeSouthernPole
666            projparams['o_lon_p'] = obj.anglePoleRotation
667            projparams['lon_0'] = obj.longitudeSouthernPole
668        elif obj.gdtn == 10:
669            projparams['proj'] = 'merc'
670            projparams['lat_ts'] = obj.latitudeTrueScale
671            projparams['lon_0'] = 0.5*(obj.longitudeFirstGridpoint+obj.longitudeLastGridpoint)
672        elif obj.gdtn == 20:
673            if obj.projectionCenterFlag == 0:
674                lat0 = 90.0
675            elif obj.projectionCenterFlag == 1:
676                lat0 = -90.0
677            projparams['proj'] = 'stere'
678            projparams['lat_ts'] = obj.latitudeTrueScale
679            projparams['lat_0'] = lat0
680            projparams['lon_0'] = obj.gridOrientation
681        elif obj.gdtn == 30:
682            projparams['proj'] = 'lcc'
683            projparams['lat_1'] = obj.standardLatitude1
684            projparams['lat_2'] = obj.standardLatitude2
685            projparams['lat_0'] = obj.latitudeTrueScale
686            projparams['lon_0'] = obj.gridOrientation
687        elif obj.gdtn == 31:
688            projparams['proj'] = 'aea'
689            projparams['lat_1'] = obj.standardLatitude1
690            projparams['lat_2'] = obj.standardLatitude2
691            projparams['lat_0'] = obj.latitudeTrueScale
692            projparams['lon_0'] = obj.gridOrientation
693        elif obj.gdtn == 40:
694            projparams['proj'] = 'eqc'
695        elif obj.gdtn == 32769:
696            projparams['proj'] = 'aeqd'
697            projparams['lon_0'] = obj.longitudeCenterGridpoint
698            projparams['lat_0'] = obj.latitudeCenterGridpoint
699        return projparams
700    def __set__(self, obj, value):
701        raise RuntimeError

PROJ Parameters to define the reference system

@dataclass(init=False)
class GridDefinitionTemplate0:
703@dataclass(init=False)
704class GridDefinitionTemplate0:
705    """[Grid Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-0.shtml)"""
706    _len = 19
707    _num = 0
708    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
709    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
710    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
711    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
712    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
713    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
714
715    @classmethod
716    def _attrs(cls):
717        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:
719@dataclass(init=False)
720class GridDefinitionTemplate1:
721    """[Grid Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-1.shtml)"""
722    _len = 22
723    _num = 1
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    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
731    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
732    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
733    @classmethod
734    def _attrs(cls):
735        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:
737@dataclass(init=False)
738class GridDefinitionTemplate10:
739    """[Grid Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-10.shtml)"""
740    _len = 19
741    _num = 10
742    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
743    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
744    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
745    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
746    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
747    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
748    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
749    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
750    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
751    @classmethod
752    def _attrs(cls):
753        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:
755@dataclass(init=False)
756class GridDefinitionTemplate20:
757    """[Grid Definition Template 20](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-20.shtml)"""
758    _len = 18
759    _num = 20
760    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
761    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
762    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
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    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
767    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
768    @classmethod
769    def _attrs(cls):
770        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:
772@dataclass(init=False)
773class GridDefinitionTemplate30:
774    """[Grid Definition Template 30](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-30.shtml)"""
775    _len = 22
776    _num = 30
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    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
785    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
786    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
787    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
788    projParameters: dict = field(init=False, repr=False, default=ProjParameters())
789    @classmethod
790    def _attrs(cls):
791        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:
793@dataclass(init=False)
794class GridDefinitionTemplate31:
795    """[Grid Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-31.shtml)"""
796    _len = 22
797    _num = 31
798    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
799    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
800    latitudeTrueScale: float = field(init=False, repr=False, default=LatitudeTrueScale())
801    gridOrientation: float = field(init=False, repr=False, default=GridOrientation())
802    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
803    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
804    projectionCenterFlag: list = field(init=False, repr=False, default=ProjectionCenterFlag())
805    standardLatitude1: float = field(init=False, repr=False, default=StandardLatitude1())
806    standardLatitude2: float = field(init=False, repr=False, default=StandardLatitude2())
807    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
808    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
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

@dataclass(init=False)
class GridDefinitionTemplate40:
813@dataclass(init=False)
814class GridDefinitionTemplate40:
815    """[Grid Definition Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-40.shtml)"""
816    _len = 19
817    _num = 40
818    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
819    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
820    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
821    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
822    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
823    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
824    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
825    @classmethod
826    def _attrs(cls):
827        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:
829@dataclass(init=False)
830class GridDefinitionTemplate41:
831    """[Grid Definition Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-41.shtml)"""
832    _len = 22
833    _num = 41
834    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
835    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
836    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
837    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
838    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
839    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
840    numberOfParallels: int = field(init=False, repr=False, default=NumberOfParallels())
841    latitudeSouthernPole: float = field(init=False, repr=False, default=LatitudeSouthernPole())
842    longitudeSouthernPole: float = field(init=False, repr=False, default=LongitudeSouthernPole())
843    anglePoleRotation: float = field(init=False, repr=False, default=AnglePoleRotation())
844    @classmethod
845    def _attrs(cls):
846        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:
848@dataclass(init=False)
849class GridDefinitionTemplate50:
850    """[Grid Definition Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-50.shtml)"""
851    _len = 5
852    _num = 50
853    spectralFunctionParameters: list = field(init=False, repr=False, default=SpectralFunctionParameters())
854    @classmethod
855    def _attrs(cls):
856        return list(cls.__dataclass_fields__.keys())
spectralFunctionParameters: list

Spectral Function Parameters

@dataclass(init=False)
class GridDefinitionTemplate32768:
858@dataclass(init=False)
859class GridDefinitionTemplate32768:
860    """[Grid Definition Template 32768](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32768.shtml)"""
861    _len = 19
862    _num = 32768
863    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
864    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
865    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
866    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
867    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
868    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
869    @classmethod
870    def _attrs(cls):
871        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:
873@dataclass(init=False)
874class GridDefinitionTemplate32769:
875    """[Grid Definition Template 32769](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp3-32769.shtml)"""
876    _len = 19
877    _num = 32769
878    latitudeFirstGridpoint: float = field(init=False, repr=False, default=LatitudeFirstGridpoint())
879    longitudeFirstGridpoint: float = field(init=False, repr=False, default=LongitudeFirstGridpoint())
880    latitudeCenterGridpoint: float = field(init=False, repr=False, default=LatitudeCenterGridpoint())
881    longitudeCenterGridpoint: float = field(init=False, repr=False, default=LongitudeCenterGridpoint())
882    gridlengthXDirection: float = field(init=False, repr=False, default=GridlengthXDirection())
883    gridlengthYDirection: float = field(init=False, repr=False, default=GridlengthYDirection())
884    latitudeLastGridpoint: float = field(init=False, repr=False, default=LatitudeLastGridpoint())
885    longitudeLastGridpoint: float = field(init=False, repr=False, default=LongitudeLastGridpoint())
886    @classmethod
887    def _attrs(cls):
888        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):
903def gdt_class_by_gdtn(gdtn: int):
904    """
905    Provides a Grid Definition Template class via the template number
906
907    Parameters
908    ----------
909    gdtn
910        Grid definition template number.
911
912    Returns
913    -------
914    gdt_class_by_gdtn
915        Grid definition template class object (not an instance).
916    """
917    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:
922class ProductDefinitionTemplateNumber:
923    """[Product Definition Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-0.shtml)"""
924    def __get__(self, obj, objtype=None):
925        return Grib2Metadata(obj.section4[1],table='4.0')
926    def __set__(self, obj, value):
927        raise RuntimeError
class ProductDefinitionTemplate:
930class ProductDefinitionTemplate:
931    """Product Definition Template"""
932    def __get__(self, obj, objtype=None):
933        return obj.section4[2:]
934    def __set__(self, obj, value):
935        raise RuntimeError

Product Definition Template

class ParameterCategory:
937class ParameterCategory:
938    """[Parameter Category](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-1.shtml)"""
939    _key = defaultdict(lambda: 0)
940    def __get__(self, obj, objtype=None):
941        return obj.section4[0+2]
942    def __set__(self, obj, value):
943        obj.section4[self._key[obj.pdtn]+2] = value
class ParameterNumber:
945class ParameterNumber:
946    """[Parameter Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-2.shtml)"""
947    _key = defaultdict(lambda: 1)
948    def __get__(self, obj, objtype=None):
949        return obj.section4[1+2]
950    def __set__(self, obj, value):
951        obj.section4[self._key[obj.pdtn]+2] = value
class VarInfo:
953class VarInfo:
954    """
955    Variable Information.
956
957    These are the metadata returned for a specific variable according to
958    discipline, parameter category, and parameter number.
959    """
960    def __get__(self, obj, objtype=None):
961        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)
962    def __set__(self, obj, value):
963        raise RuntimeError

Variable Information.

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

class FullName:
 965class FullName:
 966    """Full name of the Variable."""
 967    def __get__(self, obj, objtype=None):
 968        full_name = []
 969
 970        # Get aerosol type from table 4.233
 971        if not hasattr(obj, 'typeOfAerosol'):
 972            return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[0]
 973        elif obj.typeOfAerosol is not None:
 974            aero_type = str(obj.typeOfAerosol.value)
 975            if aero_type in tables.table_4_233:
 976                full_name.append(tables.table_4_233[aero_type][0])
 977
 978            # Get base name from GRIB2 table
 979            base_name = tables.get_varinfo_from_table(
 980                obj.section0[2],
 981                *obj.section4[2:4],
 982                isNDFD=obj._isNDFD
 983            )[0]
 984            full_name.append(base_name)
 985
 986            # Add optical properties with wavelengths if present
 987            if hasattr(obj, 'scaledValueOfFirstWavelength'):
 988                optical_type = str(obj.parameterNumber)
 989                first_wl = obj.scaledValueOfFirstWavelength
 990                second_wl = getattr(obj, 'scaledValueOfSecondWavelength', None)
 991
 992                # Special case for AE between 440-870nm
 993                if optical_type == '111' and first_wl == 440 and second_wl == 870:
 994                    full_name.append("at 440-870nm")
 995
 996                # Handle wavelength-specific optical properties
 997                elif optical_type in ['102', '103', '104', '105', '106']:
 998                    wavelength = f"{first_wl}nm"
 999                    if second_wl:
1000                        wavelength = f"{first_wl}-{second_wl}nm"
1001                    full_name.append(f"at {wavelength}")
1002
1003            final = " ".join(full_name)
1004
1005            return final.replace('Aerosol Aerosol', 'Aerosol')
1006
1007    def __set__(self, obj, value):
1008        raise RuntimeError(
1009            "Cannot set the fullName of the message. Instead set shortName OR set the appropriate discipline, "
1010            "parameterCategory, and parameterNumber. The fullName will be set automatically from these other attributes."
1011        )

Full name of the Variable.

class Units:
1013class Units:
1014    """Units of the Variable."""
1015    def __get__(self, obj, objtype=None):
1016        return tables.get_varinfo_from_table(obj.section0[2],*obj.section4[2:4],isNDFD=obj._isNDFD)[1]
1017    def __set__(self, obj, value):
1018        raise RuntimeError(
1019            "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."
1020        )

Units of the Variable.

class ShortName:
1022class ShortName:
1023    """Short name of the variable (i.e. the variable abbreviation)."""
1024    def __get__(self, obj, objtype=None):
1025        if hasattr(obj, 'typeOfAerosol'):
1026            return tables._build_aerosol_shortname(obj)
1027        else:
1028            return tables.get_varinfo_from_table(obj.section0[2], *obj.section4[2:4], isNDFD=obj._isNDFD)[2]
1029    def __set__(self, obj, value):
1030        metadata = tables.get_metadata_from_shortname(value)
1031        if len(metadata) > 1:
1032            raise ValueError(
1033                f"shortName={value} is ambiguous within the GRIB2 standard and you have to set instead with discipline, parameterCategory, and parameterNumber.\n{metadata}"
1034            )
1035        for attr, val in metadata[0].items():
1036            if attr in ["fullName", "units"]:
1037                continue
1038            setattr(obj, attr, val)

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

class TypeOfGeneratingProcess:
1040class TypeOfGeneratingProcess:
1041    """[Type of Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-3.shtml)"""
1042    _key = defaultdict(lambda: 2, {48:13})
1043    #_key = {0:2, 1:2, 2:2, 5:2, 6:2, 8:2, 9:2, 10:2, 11:2, 12:2, 15:2, 48:13}
1044    def __get__(self, obj, objtype=None):
1045        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.3')
1046    def __set__(self, obj, value):
1047        obj.section4[self._key[obj.pdtn]+2] = value
class BackgroundGeneratingProcessIdentifier:
1049class BackgroundGeneratingProcessIdentifier:
1050    """Background Generating Process Identifier"""
1051    _key = defaultdict(lambda: 3, {48:14})
1052    #_key = {0:3, 1:3, 2:3, 5:3, 6:3, 8:3, 9:3, 10:3, 11:3, 12:3, 15:3, 48:14}
1053    def __get__(self, obj, objtype=None):
1054        return obj.section4[self._key[obj.pdtn]+2]
1055    def __set__(self, obj, value):
1056        obj.section4[self._key[obj.pdtn]+2] = value

Background Generating Process Identifier

class GeneratingProcess:
1058class GeneratingProcess:
1059    """[Generating Process](https://www.nco.ncep.noaa.gov/pmb/docs/on388/tablea.html)"""
1060    _key = defaultdict(lambda: 4, {48:15})
1061    #_key = {0:4, 1:4, 2:4, 5:4, 6:4, 8:4, 9:4, 10:4, 11:4, 12:4, 15:4, 48:15}
1062    def __get__(self, obj, objtype=None):
1063        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='generating_process')
1064    def __set__(self, obj, value):
1065        obj.section4[self._key[obj.pdtn]+2] = value
class HoursAfterDataCutoff:
1067class HoursAfterDataCutoff:
1068    """Hours of observational data cutoff after reference time."""
1069    _key = defaultdict(lambda: 5, {48:16})
1070    def __get__(self, obj, objtype=None):
1071        return obj.section4[self._key[obj.pdtn]+2]
1072    def __set__(self, obj, value):
1073        obj.section4[self._key[obj.pdtn]+2] = value

Hours of observational data cutoff after reference time.

class MinutesAfterDataCutoff:
1075class MinutesAfterDataCutoff:
1076    """Minutes of observational data cutoff after reference time."""
1077    _key = defaultdict(lambda: 6, {48:17})
1078    def __get__(self, obj, objtype=None):
1079        return obj.section4[self._key[obj.pdtn]+2]
1080    def __set__(self, obj, value):
1081        obj.section4[self._key[obj.pdtn]+2] = value

Minutes of observational data cutoff after reference time.

class UnitOfForecastTime:
1083class UnitOfForecastTime:
1084    """[Units of Forecast Time](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1085    _key = defaultdict(lambda: 7, {48:18})
1086    #_key = {0:7, 1:7, 2:7, 5:7, 6:7, 8:7, 9:7, 10:7, 11:7, 12:7, 15:7, 48:18}
1087    def __get__(self, obj, objtype=None):
1088        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.4')
1089    def __set__(self, obj, value):
1090        obj.section4[self._key[obj.pdtn]+2] = value
class ValueOfForecastTime:
1092class ValueOfForecastTime:
1093    """Value of forecast time in units defined by `UnitofForecastTime`."""
1094    _key = defaultdict(lambda: 8, {48:19})
1095    def __get__(self, obj, objtype=None):
1096        return obj.section4[self._key[obj.pdtn]+2]
1097    def __set__(self, obj, value):
1098        obj.section4[self._key[obj.pdtn]+2] = value

Value of forecast time in units defined by UnitofForecastTime.

class LeadTime:
1100class LeadTime:
1101    """Forecast Lead Time. NOTE: This is a `datetime.timedelta` object."""
1102    _key = ValueOfForecastTime._key
1103    def __get__(self, obj, objtype=None):
1104        return utils.get_leadtime(obj.section4[1], obj.section4[2:]) + obj.duration
1105    def __set__(self, obj, value):
1106        if isinstance(value, np.timedelta64):
1107            # Allows setting from xarray
1108            value = datetime.timedelta(
1109                seconds=int(value/np.timedelta64(1, 's')))
1110        # First update validDate if necessary.
1111        # IMPORTANT: Update validDate components when message is time interval
1112        if obj.pdtn in _timeinterval_pdtns:
1113            vd = obj.refDate + value 
1114            obj.yearOfEndOfTimePeriod = vd.year
1115            obj.monthOfEndOfTimePeriod = vd.month
1116            obj.dayOfEndOfTimePeriod = vd.day
1117            obj.hourOfEndOfTimePeriod = vd.hour
1118            obj.minuteOfEndOfTimePeriod = vd.minute
1119            obj.secondOfEndOfTimePeriod = vd.second
1120        # Update leadTime component in section4
1121        value -= obj.duration
1122        obj.section4[self._key[obj.pdtn]+2] = int(value.total_seconds()/3600)

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

class FixedSfc1Info:
1124class FixedSfc1Info:
1125    """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)"""
1126    _key = defaultdict(lambda: 9, {48:20})
1127    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1128    def __get__(self, obj, objtype=None):
1129        if obj.section4[self._key[obj.pdtn]+2] == 255:
1130            return [None, None]
1131        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1132    def __set__(self, obj, value):
1133        raise NotImplementedError

Information of the first fixed surface via table 4.5

class FixedSfc2Info:
1135class FixedSfc2Info:
1136    """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)"""
1137    _key = defaultdict(lambda: 12, {48:23})
1138    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1139    def __get__(self, obj, objtype=None):
1140        if obj.section4[self._key[obj.pdtn]+2] == 255:
1141            return [None, None]
1142        return tables.get_value_from_table(obj.section4[self._key[obj.pdtn]+2],'4.5')
1143    def __set__(self, obj, value):
1144        raise NotImplementedError

Information of the second fixed surface via table 4.5

class TypeOfFirstFixedSurface:
1146class TypeOfFirstFixedSurface:
1147    """[Type of First Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1148    _key = defaultdict(lambda: 9, {48:20})
1149    #_key = {0:9, 1:9, 2:9, 5:9, 6:9, 8:9, 9:9, 10:9, 11:9, 12:9, 15:9, 48:20}
1150    def __get__(self, obj, objtype=None):
1151        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1152    def __set__(self, obj, value):
1153        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstFixedSurface:
1155class ScaleFactorOfFirstFixedSurface:
1156    """Scale Factor of First Fixed Surface"""
1157    _key = defaultdict(lambda: 10, {48:21})
1158    #_key = {0:10, 1:10, 2:10, 5:10, 6:10, 8:10, 9:10, 10:10, 11:10, 12:10, 15:10, 48:21}
1159    def __get__(self, obj, objtype=None):
1160        return obj.section4[self._key[obj.pdtn]+2]
1161    def __set__(self, obj, value):
1162        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Fixed Surface

class ScaledValueOfFirstFixedSurface:
1164class ScaledValueOfFirstFixedSurface:
1165    """Scaled Value Of First Fixed Surface"""
1166    _key = defaultdict(lambda: 11, {48:22})
1167    #_key = {0:11, 1:11, 2:11, 5:11, 6:11, 8:11, 9:11, 10:11, 11:11, 12:11, 15:11, 48:22}
1168    def __get__(self, obj, objtype=None):
1169        return obj.section4[self._key[obj.pdtn]+2]
1170    def __set__(self, obj, value):
1171        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of First Fixed Surface

class UnitOfFirstFixedSurface:
1173class UnitOfFirstFixedSurface:
1174    """Units of First Fixed Surface"""
1175    def __get__(self, obj, objtype=None):
1176        return obj._fixedsfc1info[1]
1177    def __set__(self, obj, value):
1178        pass

Units of First Fixed Surface

class ValueOfFirstFixedSurface:
1180class ValueOfFirstFixedSurface:
1181    """Value of First Fixed Surface"""
1182    def __get__(self, obj, objtype=None):
1183        scale_factor = getattr(obj, "scaleFactorOfFirstFixedSurface")
1184        scaled_value = getattr(obj, "scaledValueOfFirstFixedSurface")
1185        return scaled_value / (10.**scale_factor)
1186    def __set__(self, obj, value):
1187        scale = _calculate_scale_factor(value)
1188        setattr(obj, "scaleFactorOfFirstFixedSurface", scale)
1189        setattr(obj, "scaledValueOfFirstFixedSurface", value * 10**scale)

Value of First Fixed Surface

class TypeOfSecondFixedSurface:
1191class TypeOfSecondFixedSurface:
1192    """[Type of Second Fixed Surface](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-5.shtml)"""
1193    _key = defaultdict(lambda: 12, {48:23})
1194    #_key = {0:12, 1:12, 2:12, 5:12, 6:12, 8:12, 9:12, 10:12, 11:12, 12:12, 15:12, 48:23}
1195    def __get__(self, obj, objtype=None):
1196        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.5')
1197    def __set__(self, obj, value):
1198        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfSecondFixedSurface:
1200class ScaleFactorOfSecondFixedSurface:
1201    """Scale Factor of Second Fixed Surface"""
1202    _key = defaultdict(lambda: 13, {48:24})
1203    #_key = {0:13, 1:13, 2:13, 5:13, 6:13, 8:13, 9:13, 10:13, 11:13, 12:13, 15:13, 48:24}
1204    def __get__(self, obj, objtype=None):
1205        return obj.section4[self._key[obj.pdtn]+2]
1206    def __set__(self, obj, value):
1207        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Fixed Surface

class ScaledValueOfSecondFixedSurface:
1209class ScaledValueOfSecondFixedSurface:
1210    """Scaled Value Of Second Fixed Surface"""
1211    _key = defaultdict(lambda: 14, {48:25})
1212    #_key = {0:14, 1:14, 2:14, 5:14, 6:14, 8:14, 9:14, 10:14, 11:14, 12:14, 15:14, 48:25}
1213    def __get__(self, obj, objtype=None):
1214        return obj.section4[self._key[obj.pdtn]+2]
1215    def __set__(self, obj, value):
1216        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value Of Second Fixed Surface

class UnitOfSecondFixedSurface:
1218class UnitOfSecondFixedSurface:
1219    """Units of Second Fixed Surface"""
1220    def __get__(self, obj, objtype=None):
1221        return obj._fixedsfc2info[1]
1222    def __set__(self, obj, value):
1223        pass

Units of Second Fixed Surface

class ValueOfSecondFixedSurface:
1225class ValueOfSecondFixedSurface:
1226    """Value of Second Fixed Surface"""
1227    def __get__(self, obj, objtype=None):
1228        scale_factor = getattr(obj, "scaleFactorOfSecondFixedSurface")
1229        scaled_value = getattr(obj, "scaledValueOfSecondFixedSurface")
1230        return scaled_value / (10.**scale_factor)
1231    def __set__(self, obj, value):
1232        scale = _calculate_scale_factor(value)
1233        setattr(obj, "scaleFactorOfSecondFixedSurface", scale)
1234        setattr(obj, "scaledValueOfSecondFixedSurface", value * 10**scale)

Value of Second Fixed Surface

class Level:
1236class Level:
1237    """Level (same as provided by [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Level.c))"""
1238    def __get__(self, obj, objtype=None):
1239        return tables.get_wgrib2_level_string(obj.pdtn,obj.section4[2:])
1240    def __set__(self, obj, value):
1241        pass

Level (same as provided by wgrib2)

class TypeOfEnsembleForecast:
1243class TypeOfEnsembleForecast:
1244    """[Type of Ensemble Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-6.shtml)"""
1245    _key = {1:15, 11:15}
1246    def __get__(self, obj, objtype=None):
1247        pdtn = obj.section4[1]
1248        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.6')
1249    def __set__(self, obj, value):
1250        pdtn = obj.section4[1]
1251        obj.section4[self._key[pdtn]+2] = value
class PerturbationNumber:
1253class PerturbationNumber:
1254    """Ensemble Perturbation Number"""
1255    _key = {1:16, 11:16}
1256    def __get__(self, obj, objtype=None):
1257        pdtn = obj.section4[1]
1258        return obj.section4[self._key[pdtn]+2]
1259    def __set__(self, obj, value):
1260        pdtn = obj.section4[1]
1261        obj.section4[self._key[pdtn]+2] = value

Ensemble Perturbation Number

class NumberOfEnsembleForecasts:
1263class NumberOfEnsembleForecasts:
1264    """Total Number of Ensemble Forecasts"""
1265    _key = {1:17, 2:16, 11:17, 12:16}
1266    def __get__(self, obj, objtype=None):
1267        pdtn = obj.section4[1]
1268        return obj.section4[self._key[pdtn]+2]
1269    def __set__(self, obj, value):
1270        pdtn = obj.section4[1]
1271        obj.section4[self._key[pdtn]+2] = value

Total Number of Ensemble Forecasts

class TypeOfDerivedForecast:
1273class TypeOfDerivedForecast:
1274    """[Type of Derived Forecast](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-7.shtml)"""
1275    _key = {2:15, 12:15}
1276    def __get__(self, obj, objtype=None):
1277        pdtn = obj.section4[1]
1278        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.7')
1279    def __set__(self, obj, value):
1280        pdtn = obj.section4[1]
1281        obj.section4[self._key[pdtn]+2] = value
class ForecastProbabilityNumber:
1283class ForecastProbabilityNumber:
1284    """Forecast Probability Number"""
1285    _key = {5:15, 9:15}
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

Forecast Probability Number

class TotalNumberOfForecastProbabilities:
1293class TotalNumberOfForecastProbabilities:
1294    """Total Number of Forecast Probabilities"""
1295    _key = {5:16, 9:16}
1296    def __get__(self, obj, objtype=None):
1297        pdtn = obj.section4[1]
1298        return obj.section4[self._key[pdtn]+2]
1299    def __set__(self, obj, value):
1300        pdtn = obj.section4[1]
1301        obj.section4[self._key[pdtn]+2] = value

Total Number of Forecast Probabilities

class TypeOfProbability:
1303class TypeOfProbability:
1304    """[Type of Probability](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-9.shtml)"""
1305    _key = {5:17, 9:17}
1306    def __get__(self, obj, objtype=None):
1307        pdtn = obj.section4[1]
1308        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.9')
1309    def __set__(self, obj, value):
1310        pdtn = obj.section4[1]
1311        obj.section4[self._key[pdtn]+2] = value
class ScaleFactorOfThresholdLowerLimit:
1313class ScaleFactorOfThresholdLowerLimit:
1314    """Scale Factor of Threshold Lower Limit"""
1315    _key = {5:18, 9:18}
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

Scale Factor of Threshold Lower Limit

class ScaledValueOfThresholdLowerLimit:
1323class ScaledValueOfThresholdLowerLimit:
1324    """Scaled Value of Threshold Lower Limit"""
1325    _key = {5:19, 9:19}
1326    def __get__(self, obj, objtype=None):
1327        pdtn = obj.section4[1]
1328        return obj.section4[self._key[pdtn]+2]
1329    def __set__(self, obj, value):
1330        pdtn = obj.section4[1]
1331        obj.section4[self._key[pdtn]+2] = value

Scaled Value of Threshold Lower Limit

class ScaleFactorOfThresholdUpperLimit:
1333class ScaleFactorOfThresholdUpperLimit:
1334    """Scale Factor of Threshold Upper Limit"""
1335    _key = {5:20, 9:20}
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 Upper Limit

class ScaledValueOfThresholdUpperLimit:
1343class ScaledValueOfThresholdUpperLimit:
1344    """Scaled Value of Threshold Upper Limit"""
1345    _key = {5:21, 9:21}
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 Upper Limit

class ThresholdLowerLimit:
1353class ThresholdLowerLimit:
1354    """Threshold Lower Limit"""
1355    def __get__(self, obj, objtype=None):
1356        scale_factor = getattr(obj, "scaleFactorOfThresholdLowerLimit")
1357        scaled_value = getattr(obj, "scaledValueOfThresholdLowerLimit")
1358        if scale_factor == -127 and scaled_value == 255:
1359            return 0.0
1360        return scaled_value / (10.**scale_factor)
1361    def __set__(self, obj, value):
1362        scale = _calculate_scale_factor(value)
1363        setattr(obj, "scaleFactorOfThresholdLowerLimit", scale)
1364        setattr(obj, "scaledValueOfThresholdLowerLimit", value * 10**scale)

Threshold Lower Limit

class ThresholdUpperLimit:
1366class ThresholdUpperLimit:
1367    """Threshold Upper Limit"""
1368    def __get__(self, obj, objtype=None):
1369        scale_factor = getattr(obj, "scaleFactorOfThresholdUpperLimit")
1370        scaled_value = getattr(obj, "scaledValueOfThresholdUpperLimit")
1371        if scale_factor == -127 and scaled_value == 255:
1372            return 0.0
1373        return scaled_value / (10.**scale_factor)
1374    def __set__(self, obj, value):
1375        scale = _calculate_scale_factor(value)
1376        setattr(obj, "scaleFactorOfThresholdUpperLimit", scale)
1377        setattr(obj, "scaledValueOfThresholdUpperLimit", value * 10**scale)

Threshold Upper Limit

class Threshold:
1379class Threshold:
1380    """Threshold string (same as [wgrib2](https://github.com/NOAA-EMC/NCEPLIBS-wgrib2/blob/develop/wgrib2/Prob.c))"""
1381    def __get__(self, obj, objtype=None):
1382        return utils.get_wgrib2_prob_string(*obj.section4[17+2:22+2])
1383    def __set__(self, obj, value):
1384        pass

Threshold string (same as wgrib2)

class PercentileValue:
1386class PercentileValue:
1387    """Percentile Value"""
1388    _key = {6:15, 10:15}
1389    def __get__(self, obj, objtype=None):
1390        pdtn = obj.section4[1]
1391        return obj.section4[self._key[pdtn]+2]
1392    def __set__(self, obj, value):
1393        pdtn = obj.section4[1]
1394        obj.section4[self._key[pdtn]+2] = value

Percentile Value

class YearOfEndOfTimePeriod:
1396class YearOfEndOfTimePeriod:
1397    """Year of End of Forecast Time Period"""
1398    _key = {8:15, 9:22, 10:16, 11:18, 12:17}
1399    def __get__(self, obj, objtype=None):
1400        pdtn = obj.section4[1]
1401        return obj.section4[self._key[pdtn]+2]
1402    def __set__(self, obj, value):
1403        pdtn = obj.section4[1]
1404        obj.section4[self._key[pdtn]+2] = value

Year of End of Forecast Time Period

class MonthOfEndOfTimePeriod:
1406class MonthOfEndOfTimePeriod:
1407    """Month Year of End of Forecast Time Period"""
1408    _key = {8:16, 9:23, 10:17, 11:19, 12:18}
1409    def __get__(self, obj, objtype=None):
1410        pdtn = obj.section4[1]
1411        return obj.section4[self._key[pdtn]+2]
1412    def __set__(self, obj, value):
1413        pdtn = obj.section4[1]
1414        obj.section4[self._key[pdtn]+2] = value

Month Year of End of Forecast Time Period

class DayOfEndOfTimePeriod:
1416class DayOfEndOfTimePeriod:
1417    """Day Year of End of Forecast Time Period"""
1418    _key = {8:17, 9:24, 10:18, 11:20, 12:19}
1419    def __get__(self, obj, objtype=None):
1420        pdtn = obj.section4[1]
1421        return obj.section4[self._key[pdtn]+2]
1422    def __set__(self, obj, value):
1423        pdtn = obj.section4[1]
1424        obj.section4[self._key[pdtn]+2] = value

Day Year of End of Forecast Time Period

class HourOfEndOfTimePeriod:
1426class HourOfEndOfTimePeriod:
1427    """Hour Year of End of Forecast Time Period"""
1428    _key = {8:18, 9:25, 10:19, 11:21, 12:20}
1429    def __get__(self, obj, objtype=None):
1430        pdtn = obj.section4[1]
1431        return obj.section4[self._key[pdtn]+2]
1432    def __set__(self, obj, value):
1433        pdtn = obj.section4[1]
1434        obj.section4[self._key[pdtn]+2] = value

Hour Year of End of Forecast Time Period

class MinuteOfEndOfTimePeriod:
1436class MinuteOfEndOfTimePeriod:
1437    """Minute Year of End of Forecast Time Period"""
1438    _key = {8:19, 9:26, 10:20, 11:22, 12:21}
1439    def __get__(self, obj, objtype=None):
1440        pdtn = obj.section4[1]
1441        return obj.section4[self._key[pdtn]+2]
1442    def __set__(self, obj, value):
1443        pdtn = obj.section4[1]
1444        obj.section4[self._key[pdtn]+2] = value

Minute Year of End of Forecast Time Period

class SecondOfEndOfTimePeriod:
1446class SecondOfEndOfTimePeriod:
1447    """Second Year of End of Forecast Time Period"""
1448    _key = {8:20, 9:27, 10:21, 11:23, 12:22}
1449    def __get__(self, obj, objtype=None):
1450        pdtn = obj.section4[1]
1451        return obj.section4[self._key[pdtn]+2]
1452    def __set__(self, obj, value):
1453        pdtn = obj.section4[1]
1454        obj.section4[self._key[pdtn]+2] = value

Second Year of End of Forecast Time Period

class Duration:
1456class Duration:
1457    """Duration of time period. NOTE: This is a `datetime.timedelta` object."""
1458    def __get__(self, obj, objtype=None):
1459        return utils.get_duration(obj.section4[1],obj.section4[2:])
1460    def __set__(self, obj, value):
1461        if obj.pdtn in _continuous_pdtns:
1462            pass
1463        elif obj.pdtn in _timeinterval_pdtns:
1464            lt_orig = obj.leadTime
1465            _key = TimeRangeOfStatisticalProcess._key
1466            if isinstance(value, np.timedelta64):
1467                # Allows setting from xarray
1468                value = datetime.timedelta(
1469                    seconds=int(value/np.timedelta64(1, 's')))
1470            obj.section4[_key[obj.pdtn]+2] = int(value.total_seconds()/3600)
1471            obj.leadTime = lt_orig
1472            # IMPORTANT: Update validDate components when message is time interval
1473            #if obj.pdtn in _timeinterval_pdtns:
1474            #    print(obj.refDate, value, obj.leadTime)
1475            #    vd = obj.refDate + value + obj.leadTime
1476            #    obj.yearOfEndOfTimePeriod = vd.year
1477            #    obj.monthOfEndOfTimePeriod = vd.month
1478            #    obj.dayOfEndOfTimePeriod = vd.day
1479            #    obj.hourOfEndOfTimePeriod = vd.hour
1480            #    obj.minuteOfEndOfTimePeriod = vd.minute
1481            #    obj.secondOfEndOfTimePeriod = vd.second

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

class ValidDate:
1483class ValidDate:
1484    """Valid Date of the forecast. NOTE: This is a `datetime.datetime` object."""
1485    _key = {8:slice(15,21), 9:slice(22,28), 10:slice(16,22), 11:slice(18,24), 12:slice(17,23)}
1486    def __get__(self, obj, objtype=None):
1487        pdtn = obj.section4[1]
1488        try:
1489            s = slice(self._key[pdtn].start+2,self._key[pdtn].stop+2)
1490            return datetime.datetime(*obj.section4[s])
1491        except(KeyError):
1492            return obj.refDate + obj.leadTime
1493    def __set__(self, obj, value):
1494        warnings.warn(f"validDate attribute is read-only.")

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

class NumberOfTimeRanges:
1496class NumberOfTimeRanges:
1497    """Number of time ranges specifications describing the time intervals used to calculate the statistically-processed field"""
1498    _key = {8:21, 9:28, 10:22, 11:24, 12:23, 46:27}
1499    def __get__(self, obj, objtype=None):
1500        pdtn = obj.section4[1]
1501        return obj.section4[self._key[pdtn]+2]
1502    def __set__(self, obj, value):
1503        pdtn = obj.section4[1]
1504        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:
1506class NumberOfMissingValues:
1507    """Total number of data values missing in statistical process"""
1508    _key = {8:22, 9:29, 10:23, 11:25, 12:24, 46:28}
1509    def __get__(self, obj, objtype=None):
1510        pdtn = obj.section4[1]
1511        return obj.section4[self._key[pdtn]+2]
1512    def __set__(self, obj, value):
1513        pdtn = obj.section4[1]
1514        obj.section4[self._key[pdtn]+2] = value

Total number of data values missing in statistical process

class StatisticalProcess:
1516class StatisticalProcess:
1517    """[Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-10.shtml)"""
1518    _key = {
1519        8: 23,
1520        9: 30,
1521        10: 24,
1522        11: 26,
1523        12: 25,
1524        15: 15,
1525        46: 30,
1526        47: 30,
1527        49: 30,
1528        80: 30,
1529        81: 30,
1530        82: 30,
1531        83: 30,
1532        84: 30,
1533        85: 30
1534    }
1535
1536    def __get__(self, obj, objtype=None):
1537        pdtn = obj.section4[1]
1538        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.10')
1539
1540    def __set__(self, obj, value):
1541        pdtn = obj.section4[1]
1542        obj.section4[self._key[pdtn]+2] = value
class TypeOfTimeIncrementOfStatisticalProcess:
1544class TypeOfTimeIncrementOfStatisticalProcess:
1545    """[Type of Time Increment of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1546    _key = {
1547        4: 31,
1548        8: 24,
1549        9: 31,
1550        10: 25,
1551        11: 27,
1552        12: 26,
1553        46: 31,
1554        47: 31,
1555        49: 31,
1556        80: 31,
1557        81: 31,
1558        82: 31,
1559        83: 31,
1560        84: 31,
1561        85: 31
1562    }
1563
1564    def __get__(self, obj, objtype=None):
1565        pdtn = obj.section4[1]
1566        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.11')
1567
1568    def __set__(self, obj, value):
1569        pdtn = obj.section4[1]
1570        obj.section4[self._key[pdtn]+2] = value
class UnitOfTimeRangeOfStatisticalProcess:
1571class UnitOfTimeRangeOfStatisticalProcess:
1572    """[Unit of Time Range of Statistical Process](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-11.shtml)"""
1573    _key = {
1574        4: 32,
1575        8: 25,
1576        9: 32,
1577        10: 26,
1578        11: 28,
1579        12: 27,
1580        46: 32,
1581        47: 32,
1582        49: 32,
1583        80: 32,
1584        81: 32,
1585        82: 32,
1586        83: 32,
1587        84: 32,
1588        85: 32
1589    }
1590
1591    def __get__(self, obj, objtype=None):
1592        pdtn = obj.section4[1]
1593        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1594
1595    def __set__(self, obj, value):
1596        pdtn = obj.section4[1]
1597        obj.section4[self._key[pdtn]+2] = value
class TimeRangeOfStatisticalProcess:
1599class TimeRangeOfStatisticalProcess:
1600    """Time Range of Statistical Process"""
1601    _key = {
1602        4: 33,
1603        8: 26,
1604        9: 33,
1605        10: 27,
1606        11: 29,
1607        12: 28,
1608        46: 33,
1609        47: 33,
1610        49: 33,
1611        80: 33,
1612        81: 33,
1613        82: 33,
1614        83: 33,
1615        84: 33,
1616        85: 33
1617    }
1618
1619    def __get__(self, obj, objtype=None):
1620        pdtn = obj.section4[1]
1621        return obj.section4[self._key[pdtn]+2]
1622
1623    def __set__(self, obj, value):
1624        pdtn = obj.section4[1]
1625        obj.section4[self._key[pdtn]+2] = value

Time Range of Statistical Process

class UnitOfTimeRangeOfSuccessiveFields:
1627class UnitOfTimeRangeOfSuccessiveFields:
1628    """[Unit of Time Range of Successive Fields](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-4.shtml)"""
1629    _key = {
1630        4: 34,
1631        8: 27,
1632        9: 34,
1633        10: 28,
1634        11: 30,
1635        12: 29,
1636        46: 34,
1637        47: 34,
1638        49: 34,
1639        80: 34,
1640        81: 34,
1641        82: 34,
1642        83: 34,
1643        84: 34,
1644        85: 34
1645    }
1646
1647    def __get__(self, obj, objtype=None):
1648        pdtn = obj.section4[1]
1649        return Grib2Metadata(obj.section4[self._key[pdtn]+2], table='4.4')
1650
1651    def __set__(self, obj, value):
1652        pdtn = obj.section4[1]
1653        obj.section4[self._key[pdtn]+2] = value
class TimeIncrementOfSuccessiveFields:
1655class TimeIncrementOfSuccessiveFields:
1656    """Time Increment of Successive Fields"""
1657    _key = {
1658        4: 35,
1659        8: 28,
1660        9: 35,
1661        10: 29,
1662        11: 31,
1663        12: 30,
1664        46: 67,
1665        47: 67,
1666        49: 67,
1667        80: 35,
1668        81: 35,
1669        82: 35,
1670        83: 35,
1671        84: 35,
1672        85: 35
1673    }
1674
1675    def __get__(self, obj, objtype=None):
1676        pdtn = obj.section4[1]
1677        return obj.section4[self._key[pdtn]+2]
1678
1679    def __set__(self, obj, value):
1680        pdtn = obj.section4[1]
1681        obj.section4[self._key[pdtn]+2] = value

Time Increment of Successive Fields

class TypeOfStatisticalProcessing:
1682class TypeOfStatisticalProcessing:
1683    """[Type of Statistical Processing](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-15.shtml)"""
1684    _key = {15:16}
1685    def __get__(self, obj, objtype=None):
1686        pdtn = obj.section4[1]
1687        return Grib2Metadata(obj.section4[self._key[pdtn]+2],table='4.15')
1688    def __set__(self, obj, value):
1689        pdtn = obj.section4[1]
1690        obj.section4[self._key[pdtn]+2] = value
class NumberOfDataPointsForSpatialProcessing:
1692class NumberOfDataPointsForSpatialProcessing:
1693    """Number of Data Points for Spatial Processing"""
1694    _key = {15:17}
1695    def __get__(self, obj, objtype=None):
1696        pdtn = obj.section4[1]
1697        return obj.section4[self._key[pdtn]+2]
1698    def __set__(self, obj, value):
1699        pdtn = obj.section4[1]
1700        obj.section4[self._key[pdtn]+2] = value

Number of Data Points for Spatial Processing

class NumberOfContributingSpectralBands:
1702class NumberOfContributingSpectralBands:
1703    """Number of Contributing Spectral Bands (NB)"""
1704    _key = {32:9}
1705    def __get__(self, obj, objtype=None):
1706        pdtn = obj.section4[1]
1707        return obj.section4[self._key[pdtn]+2]
1708    def __set__(self, obj, value):
1709        pdtn = obj.section4[1]
1710        obj.section4[self._key[pdtn]+2] = value

Number of Contributing Spectral Bands

class SatelliteSeries:
1712class SatelliteSeries:
1713    """Satellte Series of band nb, where nb=1,NB if NB > 0"""
1714    _key = {32:10}
1715    def __get__(self, obj, objtype=None):
1716        pdtn = obj.section4[1]
1717        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1718    def __set__(self, obj, value):
1719        pass

Satellite Series

class SatelliteNumber:
1721class SatelliteNumber:
1722    """Satellte Number of band nb, where nb=1,NB if NB > 0"""
1723    _key = {32:11}
1724    def __get__(self, obj, objtype=None):
1725        pdtn = obj.section4[1]
1726        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1727    def __set__(self, obj, value):
1728        pass

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

class InstrumentType:
1730class InstrumentType:
1731    """Instrument Type of band nb, where nb=1,NB if NB > 0"""
1732    _key = {32:12}
1733    def __get__(self, obj, objtype=None):
1734        pdtn = obj.section4[1]
1735        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1736    def __set__(self, obj, value):
1737        pass

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

class ScaleFactorOfCentralWaveNumber:
1739class ScaleFactorOfCentralWaveNumber:
1740    """Scale Factor Of Central WaveNumber of band nb, where nb=1,NB if NB > 0"""
1741    _key = {32:13}
1742    def __get__(self, obj, objtype=None):
1743        pdtn = obj.section4[1]
1744        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1745    def __set__(self, obj, value):
1746        pass

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

class ScaledValueOfCentralWaveNumber:
1748class ScaledValueOfCentralWaveNumber:
1749    """Scaled Value Of Central WaveNumber of band NB"""
1750    _key = {32:14}
1751    def __get__(self, obj, objtype=None):
1752        pdtn = obj.section4[1]
1753        return obj.section4[self._key[pdtn]+2::5][:obj.section4[9+2]]
1754    def __set__(self, obj, value):
1755        pass

Scaled Value Of Central WaveNumber of band NB

class TypeOfAerosol:
1757class TypeOfAerosol:
1758    """[Type of Aerosol](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-233.shtml)"""
1759    _key = {46:2, 48:2}
1760    def __get__(self, obj, objtype=None):
1761        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.233')
1762    def __set__(self, obj, value):
1763        obj.section4[self._key[obj.pdtn]+2] = value
class TypeOfIntervalForAerosolSize:
1765class TypeOfIntervalForAerosolSize:
1766    """[Type of Interval for Aerosol Size](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1767    _key = {46:3, 48:3}
1768    def __get__(self, obj, objtype=None):
1769        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1770    def __set__(self, obj, value):
1771        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstSize:
1773class ScaleFactorOfFirstSize:
1774    """Scale Factor of First Size"""
1775    _key = {46:4, 48:4}
1776    def __get__(self, obj, objtype=None):
1777        return obj.section4[self._key[obj.pdtn]+2]
1778    def __set__(self, obj, value):
1779        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of First Size

class ScaledValueOfFirstSize:
1781class ScaledValueOfFirstSize:
1782    """Scaled Value of First Size"""
1783    _key = {46:5, 48:5}
1784    def __get__(self, obj, objtype=None):
1785        return obj.section4[self._key[obj.pdtn]+2]
1786    def __set__(self, obj, value):
1787        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Size

class ScaleFactorOfSecondSize:
1789class ScaleFactorOfSecondSize:
1790    """Scale Factor of Second Size"""
1791    _key = {46:6, 48:6}
1792    def __get__(self, obj, objtype=None):
1793        return obj.section4[self._key[obj.pdtn]+2]
1794    def __set__(self, obj, value):
1795        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Size

class ScaledValueOfSecondSize:
1797class ScaledValueOfSecondSize:
1798    """Scaled Value of Second Size"""
1799    _key = {46:6, 48:7}
1800    def __get__(self, obj, objtype=None):
1801        return obj.section4[self._key[obj.pdtn]+2]
1802    def __set__(self, obj, value):
1803        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Size

class TypeOfIntervalForAerosolWavelength:
1805class TypeOfIntervalForAerosolWavelength:
1806    """[Type of Interval for Aerosol Wavelength](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-91.shtml)"""
1807    _key = {48:8}
1808    def __get__(self, obj, objtype=None):
1809        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2],table='4.91')
1810    def __set__(self, obj, value):
1811        obj.section4[self._key[obj.pdtn]+2] = value
class ScaleFactorOfFirstWavelength:
1813class ScaleFactorOfFirstWavelength:
1814    """Scale Factor of First Wavelength"""
1815    _key = {48:9}
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

Scale Factor of First Wavelength

class ScaledValueOfFirstWavelength:
1821class ScaledValueOfFirstWavelength:
1822    """Scaled Value of First Wavelength"""
1823    _key = {48:10}
1824    def __get__(self, obj, objtype=None):
1825        return obj.section4[self._key[obj.pdtn]+2]
1826    def __set__(self, obj, value):
1827        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of First Wavelength

class ScaleFactorOfSecondWavelength:
1829class ScaleFactorOfSecondWavelength:
1830    """Scale Factor of Second Wavelength"""
1831    _key = {48:11}
1832    def __get__(self, obj, objtype=None):
1833        return obj.section4[self._key[obj.pdtn]+2]
1834    def __set__(self, obj, value):
1835        obj.section4[self._key[obj.pdtn]+2] = value

Scale Factor of Second Wavelength

class ScaledValueOfSecondWavelength:
1837class ScaledValueOfSecondWavelength:
1838    """Scaled Value of Second Wavelength"""
1839    _key = {48:12}
1840    def __get__(self, obj, objtype=None):
1841        return obj.section4[self._key[obj.pdtn]+2]
1842    def __set__(self, obj, value):
1843        obj.section4[self._key[obj.pdtn]+2] = value

Scaled Value of Second Wavelength

class SourceSinkIndicator:
1845class SourceSinkIndicator:
1846    """[Source/Sink Indicator](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-238.shtml)"""
1847    _key = {80:3, 81:3, 82:3, 83:3, 84:3, 85:3}
1848    def __get__(self, obj, objtype=None):
1849        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.238')
1850    def __set__(self, obj, value):
1851        obj.section4[self._key[obj.pdtn]+2] = value
class ConstituentType:
1860class ConstituentType:
1861    """[Constituent Type](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table4-230.shtml)"""
1862    _key = defaultdict(lambda: 10)
1863    def __get__(self, obj, objtype=None):
1864        return Grib2Metadata(obj.section4[self._key[obj.pdtn]+2], table='4.230')
1865    def __set__(self, obj, value):
1866        obj.section4[self._key[obj.pdtn]+2] = value
@dataclass(init=False)
class ProductDefinitionTemplateBase:
1896@dataclass(init=False)
1897class ProductDefinitionTemplateBase:
1898    """Base attributes for Product Definition Templates"""
1899    _varinfo: list = field(init=False, repr=False, default=VarInfo())
1900    fullName: str = field(init=False, repr=False, default=FullName())
1901    units: str = field(init=False, repr=False, default=Units())
1902    shortName: str = field(init=False, repr=False, default=ShortName())
1903    leadTime: datetime.timedelta = field(init=False,repr=False,default=LeadTime())
1904    duration: datetime.timedelta = field(init=False,repr=False,default=Duration())
1905    validDate: datetime.datetime = field(init=False,repr=False,default=ValidDate())
1906    level: str = field(init=False, repr=False, default=Level())
1907    # Begin template here...
1908    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
1909    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
1910    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
1911    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
1912    backgroundGeneratingProcessIdentifier: int = field(init=False,repr=False,default=BackgroundGeneratingProcessIdentifier())
1913    hoursAfterDataCutoff: int = field(init=False,repr=False,default=HoursAfterDataCutoff())
1914    minutesAfterDataCutoff: int = field(init=False,repr=False,default=MinutesAfterDataCutoff())
1915    unitOfForecastTime: Grib2Metadata = field(init=False,repr=False,default=UnitOfForecastTime())
1916    valueOfForecastTime: int = field(init=False,repr=False,default=ValueOfForecastTime())
1917    @classmethod
1918    def _attrs(cls):
1919        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:
1921@dataclass(init=False)
1922class ProductDefinitionTemplateSurface:
1923    """Surface attributes for Product Definition Templates"""
1924    _fixedsfc1info: list = field(init=False, repr=False, default=FixedSfc1Info())
1925    _fixedsfc2info: list = field(init=False, repr=False, default=FixedSfc2Info())
1926    typeOfFirstFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfFirstFixedSurface())
1927    scaleFactorOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfFirstFixedSurface())
1928    scaledValueOfFirstFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfFirstFixedSurface())
1929    typeOfSecondFixedSurface: Grib2Metadata = field(init=False,repr=False,default=TypeOfSecondFixedSurface())
1930    scaleFactorOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaleFactorOfSecondFixedSurface())
1931    scaledValueOfSecondFixedSurface: int = field(init=False,repr=False,default=ScaledValueOfSecondFixedSurface())
1932    unitOfFirstFixedSurface: str = field(init=False,repr=False,default=UnitOfFirstFixedSurface())
1933    valueOfFirstFixedSurface: int = field(init=False,repr=False,default=ValueOfFirstFixedSurface())
1934    unitOfSecondFixedSurface: str = field(init=False,repr=False,default=UnitOfSecondFixedSurface())
1935    valueOfSecondFixedSurface: int = field(init=False,repr=False,default=ValueOfSecondFixedSurface())
1936    @classmethod
1937    def _attrs(cls):
1938        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):
1940@dataclass(init=False)
1941class ProductDefinitionTemplate0(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1942    """[Product Definition Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-0.shtml)"""
1943    _len = 15
1944    _num = 0
1945    @classmethod
1946    def _attrs(cls):
1947        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
@dataclass(init=False)
class ProductDefinitionTemplate1(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
1949@dataclass(init=False)
1950class ProductDefinitionTemplate1(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1951    """[Product Definition Template 1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-1.shtml)"""
1952    _len = 18
1953    _num = 1
1954    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
1955    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
1956    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1957    @classmethod
1958    def _attrs(cls):
1959        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):
1961@dataclass(init=False)
1962class ProductDefinitionTemplate2(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1963    """[Product Definition Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-2.shtml)"""
1964    _len = 17
1965    _num = 2
1966    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
1967    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
1968    @classmethod
1969    def _attrs(cls):
1970        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):
1972@dataclass(init=False)
1973class ProductDefinitionTemplate5(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1974    """[Product Definition Template 5](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-5.shtml)"""
1975    _len = 22
1976    _num = 5
1977    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
1978    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
1979    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
1980    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
1981    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
1982    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
1983    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
1984    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
1985    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
1986    threshold: str = field(init=False, repr=False, default=Threshold())
1987    @classmethod
1988    def _attrs(cls):
1989        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):
1991@dataclass(init=False)
1992class ProductDefinitionTemplate6(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
1993    """[Product Definition Template 6](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-6.shtml)"""
1994    _len = 16
1995    _num = 6
1996    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
1997    @classmethod
1998    def _attrs(cls):
1999        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
percentileValue: int

Percentile Value

@dataclass(init=False)
class ProductDefinitionTemplate8(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2001@dataclass(init=False)
2002class ProductDefinitionTemplate8(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2003    """[Product Definition Template 8](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-8.shtml)"""
2004    _len = 29
2005    _num = 8
2006    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2007    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2008    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2009    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2010    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2011    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2012    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2013    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2014    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2015    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2016    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2017    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2018    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2019    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2020    @classmethod
2021    def _attrs(cls):
2022        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):
2024@dataclass(init=False)
2025class ProductDefinitionTemplate9(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2026    """[Product Definition Template 9](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-9.shtml)"""
2027    _len = 36
2028    _num = 9
2029    forecastProbabilityNumber: int = field(init=False, repr=False, default=ForecastProbabilityNumber())
2030    totalNumberOfForecastProbabilities: int = field(init=False, repr=False, default=TotalNumberOfForecastProbabilities())
2031    typeOfProbability: Grib2Metadata = field(init=False, repr=False, default=TypeOfProbability())
2032    scaleFactorOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdLowerLimit())
2033    scaledValueOfThresholdLowerLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdLowerLimit())
2034    scaleFactorOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaleFactorOfThresholdUpperLimit())
2035    scaledValueOfThresholdUpperLimit: float = field(init=False, repr=False, default=ScaledValueOfThresholdUpperLimit())
2036    thresholdLowerLimit: float = field(init=False, repr=False, default=ThresholdLowerLimit())
2037    thresholdUpperLimit: float = field(init=False, repr=False, default=ThresholdUpperLimit())
2038    threshold: str = field(init=False, repr=False, default=Threshold())
2039    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2040    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2041    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2042    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2043    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2044    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2045    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2046    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2047    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2048    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2049    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2050    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2051    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2052    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2053    @classmethod
2054    def _attrs(cls):
2055        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):
2057@dataclass(init=False)
2058class ProductDefinitionTemplate10(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2059    """[Product Definition Template 10](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-10.shtml)"""
2060    _len = 30
2061    _num = 10
2062    percentileValue: int = field(init=False, repr=False, default=PercentileValue())
2063    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2064    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2065    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2066    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2067    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2068    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2069    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2070    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2071    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2072    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2073    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2074    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2075    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2076    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2077    @classmethod
2078    def _attrs(cls):
2079        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):
2081@dataclass(init=False)
2082class ProductDefinitionTemplate11(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2083    """[Product Definition Template 11](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-11.shtml)"""
2084    _len = 32
2085    _num = 11
2086    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2087    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2088    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
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    @classmethod
2104    def _attrs(cls):
2105        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):
2107@dataclass(init=False)
2108class ProductDefinitionTemplate12(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2109    """[Product Definition Template 12](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-12.shtml)"""
2110    _len = 31
2111    _num = 12
2112    typeOfDerivedForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfDerivedForecast())
2113    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2114    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2115    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2116    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2117    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2118    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2119    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2120    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2121    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2122    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2123    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2124    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2125    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2126    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2127    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2128    @classmethod
2129    def _attrs(cls):
2130        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):
2132@dataclass(init=False)
2133class ProductDefinitionTemplate13(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2134    """[Product Definition Template 13](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-13.shtml)"""
2135    _len = 18
2136    _num = 13
2137    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2138    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2139    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2140    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2141    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2142    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2143    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2144    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2145    @classmethod
2146    def _attrs(cls):
2147        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):
2149@dataclass(init=False)
2150class ProductDefinitionTemplate14(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2151    """[Product Definition Template 14](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-14.shtml)"""
2152    _len = 18
2153    _num = 14
2154    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2155    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2156    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
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    @classmethod
2163    def _attrs(cls):
2164        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):
2166@dataclass(init=False)
2167class ProductDefinitionTemplate15(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2168    """[Product Definition Template 15](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-15.shtml)"""
2169    _len = 18
2170    _num = 15
2171    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2172    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2173    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2174    @classmethod
2175    def _attrs(cls):
2176        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:
2194@dataclass(init=False)
2195class ProductDefinitionTemplate31:
2196    """[Product Definition Template 31](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-31.shtml)"""
2197    _len = 5
2198    _num = 31
2199    parameterCategory: int = field(init=False,repr=False,default=ParameterCategory())
2200    parameterNumber: int = field(init=False,repr=False,default=ParameterNumber())
2201    typeOfGeneratingProcess: Grib2Metadata = field(init=False,repr=False,default=TypeOfGeneratingProcess())
2202    generatingProcess: Grib2Metadata = field(init=False, repr=False, default=GeneratingProcess())
2203    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2204    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2205    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2206    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2207    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2208    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2209    @classmethod
2210    def _attrs(cls):
2211        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):
2213@dataclass(init=False)
2214class ProductDefinitionTemplate32(ProductDefinitionTemplateBase):
2215    """[Product Definition Template 32](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-32.shtml)"""
2216    _len = 10
2217    _num = 32
2218    numberOfContributingSpectralBands: int = field(init=False,repr=False,default=NumberOfContributingSpectralBands())
2219    satelliteSeries: list = field(init=False,repr=False,default=SatelliteSeries())
2220    satelliteNumber: list = field(init=False,repr=False,default=SatelliteNumber())
2221    instrumentType: list = field(init=False,repr=False,default=InstrumentType())
2222    scaleFactorOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaleFactorOfCentralWaveNumber())
2223    scaledValueOfCentralWaveNumber: list = field(init=False,repr=False,default=ScaledValueOfCentralWaveNumber())
2224    @classmethod
2225    def _attrs(cls):
2226        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 ProductDefinitionTemplate48(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2305@dataclass(init=False)
2306class ProductDefinitionTemplate48(ProductDefinitionTemplateBase,ProductDefinitionTemplateSurface):
2307    """[Product Definition Template 48](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-48.shtml)"""
2308    _len = 26
2309    _num = 48
2310    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2311    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2312    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2313    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2314    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2315    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2316    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2317    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2318    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2319    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2320    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2321    @classmethod
2322    def _attrs(cls):
2323        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplate46(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2325@dataclass(init=False)
2326class ProductDefinitionTemplate46(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2327    """[Product Definition Template 4.46](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-46.shtml)"""
2328    _len = 38  # Total number of octets
2329    _num = 46
2330
2331    # Aerosol-specific parameters
2332    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2333    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2334    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2335    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2336    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2337    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2338    # Time interval parameters
2339    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2340    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2341    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2342    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2343    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2344    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2345    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2346    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2347    # Statistical processing parameters
2348    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2349    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2350    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2351    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2352    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2353    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2354    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2355    @classmethod
2356    def _attrs(cls):
2357        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

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):
2361@dataclass(init=False)
2362class ProductDefinitionTemplate47(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2363    """[Product Definition Template 4.47](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-47.shtml)"""
2364    _len = 41  # Total number of octets for base template
2365    _num = 47
2366
2367    # Aerosol parameters
2368    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2369    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2370    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2371    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2372    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2373    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2374
2375    # Ensemble parameters
2376    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2377    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2378    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2379
2380    # Time interval parameters
2381    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2382    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2383    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2384    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2385    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2386    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2387    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2388    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2389    # Statistical processing parameters
2390    typeOfStatisticalProcessing: Grib2Metadata = field(init=False, repr=False, default=TypeOfStatisticalProcessing())
2391    numberOfDataPointsForSpatialProcessing: int = field(init=False, repr=False, default=NumberOfDataPointsForSpatialProcessing())
2392    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2393    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2394    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2395    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2396    timeIncrementOfSuccessiveFields: int = field(init=False, repr=False, default=TimeIncrementOfSuccessiveFields())
2397    @classmethod
2398    def _attrs(cls):
2399        return [key for key in cls.__dataclass_fields__.keys() if not key.startswith('_')]
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

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 ProductDefinitionTemplate49(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2401@dataclass(init=False)
2402class ProductDefinitionTemplate49(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2403    """[Product Definition Template 4.49](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-49.shtml)"""
2404    _len = 28
2405    _num = 49
2406
2407    # Aerosol parameters
2408    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2409    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2410    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2411    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2412    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2413    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2414
2415    # Wavelength parameters
2416    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2417    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2418    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2419    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2420    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2421
2422    # Ensemble parameters
2423    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2424    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2425    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate80(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2427@dataclass(init=False)
2428class ProductDefinitionTemplate80(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2429    """[Product Definition Template 4.80](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-80.shtml)"""
2430    _len = 26
2431    _num = 80
2432
2433    # Aerosol parameters
2434    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2435    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2436    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2437    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2438    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2439    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2440    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2441
2442    # Wavelength parameters
2443    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2444    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2445    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2446    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2447    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
sourceSinkIndicator: Grib2Metadata
typeOfIntervalForAerosolSize: Grib2Metadata
scaleFactorOfFirstSize: int

Scale Factor of First Size

scaledValueOfFirstSize: int

Scaled Value of First Size

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

@dataclass(init=False)
class ProductDefinitionTemplate81(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2449@dataclass(init=False)
2450class ProductDefinitionTemplate81(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2451    """[Product Definition Template 4.81](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-81.shtml)"""
2452    _len = 31
2453    _num = 81
2454
2455    # Aerosol parameters
2456    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2457    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2458    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2459    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2460    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2461    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2462    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2463
2464    # Wavelength parameters
2465    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2466    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2467    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2468    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2469    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2470
2471    # Ensemble parameters
2472    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2473    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2474    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

@dataclass(init=False)
class ProductDefinitionTemplate82(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2476@dataclass(init=False)
2477class ProductDefinitionTemplate82(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2478    """[Product Definition Template 4.82](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-82.shtml)"""
2479    _len = 41
2480    _num = 82
2481
2482    # Aerosol parameters
2483    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2484    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2485    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2486    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2487    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2488    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2489    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2490
2491    # Wavelength parameters
2492    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2493    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2494    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2495    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2496    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2497
2498   # Time interval parameters
2499    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2500    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2501    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2502    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2503    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2504    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2505    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2506    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2507
2508    # Statistical processing parameters
2509    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2510    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2511    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2512    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2513    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2514    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2515    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2516    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

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):
2518@dataclass(init=False)
2519class ProductDefinitionTemplate83(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2520    """[Product Definition Template 4.83](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-83.shtml)"""
2521    _len = 44
2522    _num = 83
2523
2524    # Aerosol parameters
2525    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2526    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2527    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2528    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2529    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2530    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2531    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2532
2533    # Wavelength parameters
2534    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2535    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2536    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2537    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2538    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2539
2540    # Ensemble parameters
2541    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2542    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2543    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2544
2545    # Time interval parameters
2546    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2547    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2548    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2549    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2550    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2551    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2552    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2553    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

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):
2555@dataclass(init=False)
2556class ProductDefinitionTemplate84(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2557    """[Product Definition Template 4.84](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-84.shtml)"""
2558    _len = 44
2559    _num = 84
2560
2561    # Aerosol parameters
2562    typeOfAerosol: Grib2Metadata = field(init=False, repr=False, default=TypeOfAerosol())
2563    sourceSinkIndicator: Grib2Metadata = field(init=False, repr=False, default=SourceSinkIndicator())
2564    typeOfIntervalForAerosolSize: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolSize())
2565    scaleFactorOfFirstSize: int = field(init=False, repr=False, default=ScaleFactorOfFirstSize())
2566    scaledValueOfFirstSize: int = field(init=False, repr=False, default=ScaledValueOfFirstSize())
2567    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2568    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2569
2570    # Wavelength parameters
2571    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2572    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2573    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2574    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2575    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2576
2577    # Ensemble parameters
2578    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2579    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2580    numberOfEnsembleForecasts: int = field(init=False, repr=False, default=NumberOfEnsembleForecasts())
2581
2582    # Time interval parameters
2583    yearOfEndOfTimePeriod: int = field(init=False, repr=False, default=YearOfEndOfTimePeriod())
2584    monthOfEndOfTimePeriod: int = field(init=False, repr=False, default=MonthOfEndOfTimePeriod())
2585    dayOfEndOfTimePeriod: int = field(init=False, repr=False, default=DayOfEndOfTimePeriod())
2586    hourOfEndOfTimePeriod: int = field(init=False, repr=False, default=HourOfEndOfTimePeriod())
2587    minuteOfEndOfTimePeriod: int = field(init=False, repr=False, default=MinuteOfEndOfTimePeriod())
2588    secondOfEndOfTimePeriod: int = field(init=False, repr=False, default=SecondOfEndOfTimePeriod())
2589
2590    # Statistical processing parameters
2591    numberOfTimeRanges: int = field(init=False, repr=False, default=NumberOfTimeRanges())
2592    numberOfMissingValues: int = field(init=False, repr=False, default=NumberOfMissingValues())
2593    statisticalProcess: Grib2Metadata = field(init=False, repr=False, default=StatisticalProcess())
2594    typeOfTimeIncrementOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=TypeOfTimeIncrementOfStatisticalProcess())
2595    unitOfTimeRangeOfStatisticalProcess: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfStatisticalProcess())
2596    timeRangeOfStatisticalProcess: int = field(init=False, repr=False, default=TimeRangeOfStatisticalProcess())
2597    unitOfTimeRangeOfSuccessiveFields: Grib2Metadata = field(init=False, repr=False, default=UnitOfTimeRangeOfSuccessiveFields())
2598    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

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):
2600@dataclass(init=False)
2601class ProductDefinitionTemplate85(ProductDefinitionTemplateBase, ProductDefinitionTemplateSurface):
2602    """[Product Definition Template 4.85](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp4-85.shtml)"""
2603    _len = 33
2604    _num = 85
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    scaleFactorOfSecondSize: int = field(init=False, repr=False, default=ScaleFactorOfSecondSize())
2613    scaledValueOfSecondSize: int = field(init=False, repr=False, default=ScaledValueOfSecondSize())
2614
2615    # Wavelength parameters
2616    typeOfIntervalForAerosolWavelength: Grib2Metadata = field(init=False, repr=False, default=TypeOfIntervalForAerosolWavelength())
2617    scaleFactorOfFirstWavelength: int = field(init=False, repr=False, default=ScaleFactorOfFirstWavelength())
2618    scaledValueOfFirstWavelength: int = field(init=False, repr=False, default=ScaledValueOfFirstWavelength())
2619    scaleFactorOfSecondWavelength: int = field(init=False, repr=False, default=ScaleFactorOfSecondWavelength())
2620    scaledValueOfSecondWavelength: int = field(init=False, repr=False, default=ScaledValueOfSecondWavelength())
2621
2622    # Ensemble parameters
2623    typeOfEnsembleForecast: Grib2Metadata = field(init=False, repr=False, default=TypeOfEnsembleForecast())
2624    perturbationNumber: int = field(init=False, repr=False, default=PerturbationNumber())
2625    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

scaleFactorOfSecondSize: int

Scale Factor of Second Size

scaledValueOfSecondSize: int

Scaled Value of Second Size

typeOfIntervalForAerosolWavelength: Grib2Metadata
scaleFactorOfFirstWavelength: int

Scale Factor of First Wavelength

scaledValueOfFirstWavelength: int

Scaled Value of First Wavelength

scaleFactorOfSecondWavelength: int

Scale Factor of Second Wavelength

scaledValueOfSecondWavelength: int

Scaled Value of Second Wavelength

typeOfEnsembleForecast: Grib2Metadata
perturbationNumber: int

Ensemble Perturbation Number

numberOfEnsembleForecasts: int

Total Number of Ensemble Forecasts

def pdt_class_by_pdtn(pdtn: int):
2653def pdt_class_by_pdtn(pdtn: int):
2654    """
2655    Provide a Product Definition Template class via the template number.
2656
2657    Parameters
2658    ----------
2659    pdtn
2660        Product definition template number.
2661
2662    Returns
2663    -------
2664    pdt_class_by_pdtn
2665        Product definition template class object (not an instance).
2666    """
2667    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:
2672class NumberOfPackedValues:
2673    """Number of Packed Values"""
2674    def __get__(self, obj, objtype=None):
2675        return obj.section5[0]
2676    def __set__(self, obj, value):
2677        pass

Number of Packed Values

class DataRepresentationTemplateNumber:
2679class DataRepresentationTemplateNumber:
2680    """[Data Representation Template Number](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-0.shtml)"""
2681    def __get__(self, obj, objtype=None):
2682        return Grib2Metadata(obj.section5[1],table='5.0')
2683    def __set__(self, obj, value):
2684        pass
class DataRepresentationTemplate:
2686class DataRepresentationTemplate:
2687    """Data Representation Template"""
2688    def __get__(self, obj, objtype=None):
2689        return obj.section5[2:]
2690    def __set__(self, obj, value):
2691        raise NotImplementedError

Data Representation Template

class RefValue:
2693class RefValue:
2694    """Reference Value (represented as an IEEE 32-bit floating point value)"""
2695    def __get__(self, obj, objtype=None):
2696        return utils.ieee_int_to_float(obj.section5[0+2])
2697    def __set__(self, obj, value):
2698        pass

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

class BinScaleFactor:
2700class BinScaleFactor:
2701    """Binary Scale Factor"""
2702    def __get__(self, obj, objtype=None):
2703        return obj.section5[1+2]
2704    def __set__(self, obj, value):
2705        obj.section5[1+2] = value

Binary Scale Factor

class DecScaleFactor:
2707class DecScaleFactor:
2708    """Decimal Scale Factor"""
2709    def __get__(self, obj, objtype=None):
2710        return obj.section5[2+2]
2711    def __set__(self, obj, value):
2712        obj.section5[2+2] = value

Decimal Scale Factor

class NBitsPacking:
2714class NBitsPacking:
2715    """Minimum number of bits for packing"""
2716    def __get__(self, obj, objtype=None):
2717        return obj.section5[3+2]
2718    def __set__(self, obj, value):
2719        obj.section5[3+2] = value

Minimum number of bits for packing

class TypeOfValues:
2721class TypeOfValues:
2722    """[Type of Original Field Values](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)"""
2723    def __get__(self, obj, objtype=None):
2724        return Grib2Metadata(obj.section5[4+2],table='5.1')
2725    def __set__(self, obj, value):
2726        obj.section5[4+2] = value
class GroupSplittingMethod:
2728class GroupSplittingMethod:
2729    """[Group Splitting Method](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-4.shtml)"""
2730    def __get__(self, obj, objtype=None):
2731        return Grib2Metadata(obj.section5[5+2],table='5.4')
2732    def __set__(self, obj, value):
2733        obj.section5[5+2] = value
class TypeOfMissingValueManagement:
2735class TypeOfMissingValueManagement:
2736    """[Type of Missing Value Management](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-5.shtml)"""
2737    def __get__(self, obj, objtype=None):
2738        return Grib2Metadata(obj.section5[6+2],table='5.5')
2739    def __set__(self, obj, value):
2740        obj.section5[6+2] = value
class PriMissingValue:
2742class PriMissingValue:
2743    """Primary Missing Value"""
2744    def __get__(self, obj, objtype=None):
2745        if obj.typeOfValues == 0:
2746            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
2747        elif obj.typeOfValues == 1:
2748            return obj.section5[7+2] if obj.section5[6+2] in [1,2] else None
2749    def __set__(self, obj, value):
2750        if obj.typeOfValues == 0:
2751            obj.section5[7+2] = utils.ieee_float_to_int(value)
2752        elif self.typeOfValues == 1:
2753            obj.section5[7+2] = int(value)
2754        obj.section5[6+2] = 1

Primary Missing Value

class SecMissingValue:
2756class SecMissingValue:
2757    """Secondary Missing Value"""
2758    def __get__(self, obj, objtype=None):
2759        if obj.typeOfValues == 0:
2760            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
2761        elif obj.typeOfValues == 1:
2762            return obj.section5[8+2] if obj.section5[6+2] in {1,2} else None
2763    def __set__(self, obj, value):
2764        if obj.typeOfValues == 0:
2765            obj.section5[8+2] = utils.ieee_float_to_int(value)
2766        elif self.typeOfValues == 1:
2767            obj.section5[8+2] = int(value)
2768        obj.section5[6+2] = 2

Secondary Missing Value

class NGroups:
2770class NGroups:
2771    """Number of Groups"""
2772    def __get__(self, obj, objtype=None):
2773        return obj.section5[9+2]
2774    def __set__(self, obj, value):
2775        pass

Number of Groups

class RefGroupWidth:
2777class RefGroupWidth:
2778    """Reference Group Width"""
2779    def __get__(self, obj, objtype=None):
2780        return obj.section5[10+2]
2781    def __set__(self, obj, value):
2782        pass

Reference Group Width

class NBitsGroupWidth:
2784class NBitsGroupWidth:
2785    """Number of bits for Group Width"""
2786    def __get__(self, obj, objtype=None):
2787        return obj.section5[11+2]
2788    def __set__(self, obj, value):
2789        pass

Number of bits for Group Width

class RefGroupLength:
2791class RefGroupLength:
2792    """Reference Group Length"""
2793    def __get__(self, obj, objtype=None):
2794        return obj.section5[12+2]
2795    def __set__(self, obj, value):
2796        pass

Reference Group Length

class GroupLengthIncrement:
2798class GroupLengthIncrement:
2799    """Group Length Increment"""
2800    def __get__(self, obj, objtype=None):
2801        return obj.section5[13+2]
2802    def __set__(self, obj, value):
2803        pass

Group Length Increment

class LengthOfLastGroup:
2805class LengthOfLastGroup:
2806    """Length of Last Group"""
2807    def __get__(self, obj, objtype=None):
2808        return obj.section5[14+2]
2809    def __set__(self, obj, value):
2810        pass

Length of Last Group

class NBitsScaledGroupLength:
2812class NBitsScaledGroupLength:
2813    """Number of bits of Scaled Group Length"""
2814    def __get__(self, obj, objtype=None):
2815        return obj.section5[15+2]
2816    def __set__(self, obj, value):
2817        pass

Number of bits of Scaled Group Length

class SpatialDifferenceOrder:
2819class SpatialDifferenceOrder:
2820    """[Spatial Difference Order](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-6.shtml)"""
2821    def __get__(self, obj, objtype=None):
2822        return Grib2Metadata(obj.section5[16+2],table='5.6')
2823    def __set__(self, obj, value):
2824        obj.section5[16+2] = value
class NBytesSpatialDifference:
2826class NBytesSpatialDifference:
2827    """Number of bytes for Spatial Differencing"""
2828    def __get__(self, obj, objtype=None):
2829        return obj.section5[17+2]
2830    def __set__(self, obj, value):
2831        pass

Number of bytes for Spatial Differencing

class Precision:
2833class Precision:
2834    """[Precision for IEEE Floating Point Data](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-7.shtml)"""
2835    def __get__(self, obj, objtype=None):
2836        return Grib2Metadata(obj.section5[0+2],table='5.7')
2837    def __set__(self, obj, value):
2838        obj.section5[0+2] = value
class TypeOfCompression:
2840class TypeOfCompression:
2841    """[Type of Compression](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)"""
2842    def __get__(self, obj, objtype=None):
2843        return Grib2Metadata(obj.section5[5+2],table='5.40')
2844    def __set__(self, obj, value):
2845        obj.section5[5+2] = value
class TargetCompressionRatio:
2847class TargetCompressionRatio:
2848    """Target Compression Ratio"""
2849    def __get__(self, obj, objtype=None):
2850        return obj.section5[6+2]
2851    def __set__(self, obj, value):
2852        pass

Target Compression Ratio

class RealOfCoefficient:
2854class RealOfCoefficient:
2855    """Real of Coefficient"""
2856    def __get__(self, obj, objtype=None):
2857        return utils.ieee_int_to_float(obj.section5[4+2])
2858    def __set__(self, obj, value):
2859        obj.section5[4+2] = utils.ieee_float_to_int(float(value))

Real of Coefficient

class CompressionOptionsMask:
2861class CompressionOptionsMask:
2862    """Compression Options Mask for AEC/CCSDS"""
2863    def __get__(self, obj, objtype=None):
2864        return obj.section5[5+2]
2865    def __set__(self, obj, value):
2866        obj.section5[5+2] = value

Compression Options Mask for AEC/CCSDS

class BlockSize:
2868class BlockSize:
2869    """Block Size for AEC/CCSDS"""
2870    def __get__(self, obj, objtype=None):
2871        return obj.section5[6+2]
2872    def __set__(self, obj, value):
2873        obj.section5[6+2] = value

Block Size for AEC/CCSDS

class RefSampleInterval:
2875class RefSampleInterval:
2876    """Reference Sample Interval for AEC/CCSDS"""
2877    def __get__(self, obj, objtype=None):
2878        return obj.section5[7+2]
2879    def __set__(self, obj, value):
2880        obj.section5[7+2] = value

Reference Sample Interval for AEC/CCSDS

@dataclass(init=False)
class DataRepresentationTemplate0:
2882@dataclass(init=False)
2883class DataRepresentationTemplate0:
2884    """[Data Representation Template 0](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)"""
2885    _len = 5
2886    _num = 0
2887    _packingScheme = 'simple'
2888    refValue: float = field(init=False, repr=False, default=RefValue())
2889    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2890    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2891    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2892    @classmethod
2893    def _attrs(cls):
2894        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:
2896@dataclass(init=False)
2897class DataRepresentationTemplate2:
2898    """[Data Representation Template 2](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)"""
2899    _len = 16
2900    _num = 2
2901    _packingScheme = 'complex'
2902    refValue: float = field(init=False, repr=False, default=RefValue())
2903    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2904    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2905    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2906    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2907    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2908    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2909    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2910    nGroups: int = field(init=False, repr=False, default=NGroups())
2911    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2912    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2913    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2914    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2915    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2916    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2917    @classmethod
2918    def _attrs(cls):
2919        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:
2921@dataclass(init=False)
2922class DataRepresentationTemplate3:
2923    """[Data Representation Template 3](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)"""
2924    _len = 18
2925    _num = 3
2926    _packingScheme = 'complex-spdiff'
2927    refValue: float = field(init=False, repr=False, default=RefValue())
2928    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2929    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2930    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2931    groupSplittingMethod: Grib2Metadata = field(init=False, repr=False, default=GroupSplittingMethod())
2932    typeOfMissingValueManagement: Grib2Metadata = field(init=False, repr=False, default=TypeOfMissingValueManagement())
2933    priMissingValue: Union[float, int] = field(init=False, repr=False, default=PriMissingValue())
2934    secMissingValue: Union[float, int] = field(init=False, repr=False, default=SecMissingValue())
2935    nGroups: int = field(init=False, repr=False, default=NGroups())
2936    refGroupWidth: int = field(init=False, repr=False, default=RefGroupWidth())
2937    nBitsGroupWidth: int = field(init=False, repr=False, default=NBitsGroupWidth())
2938    refGroupLength: int = field(init=False, repr=False, default=RefGroupLength())
2939    groupLengthIncrement: int = field(init=False, repr=False, default=GroupLengthIncrement())
2940    lengthOfLastGroup: int = field(init=False, repr=False, default=LengthOfLastGroup())
2941    nBitsScaledGroupLength: int = field(init=False, repr=False, default=NBitsScaledGroupLength())
2942    spatialDifferenceOrder: Grib2Metadata = field(init=False, repr=False, default=SpatialDifferenceOrder())
2943    nBytesSpatialDifference: int = field(init=False, repr=False, default=NBytesSpatialDifference())
2944    @classmethod
2945    def _attrs(cls):
2946        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:
2948@dataclass(init=False)
2949class DataRepresentationTemplate4:
2950    """[Data Representation Template 4](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-4.shtml)"""
2951    _len = 1
2952    _num = 4
2953    _packingScheme = 'ieee-float'
2954    precision: Grib2Metadata = field(init=False, repr=False, default=Precision())
2955    @classmethod
2956    def _attrs(cls):
2957        return list(cls.__dataclass_fields__.keys())
@dataclass(init=False)
class DataRepresentationTemplate40:
2959@dataclass(init=False)
2960class DataRepresentationTemplate40:
2961    """[Data Representation Template 40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)"""
2962    _len = 7
2963    _num = 40
2964    _packingScheme = 'jpeg'
2965    refValue: float = field(init=False, repr=False, default=RefValue())
2966    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2967    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2968    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2969    typeOfCompression: Grib2Metadata = field(init=False, repr=False, default=TypeOfCompression())
2970    targetCompressionRatio: int = field(init=False, repr=False, default=TargetCompressionRatio())
2971    @classmethod
2972    def _attrs(cls):
2973        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:
2975@dataclass(init=False)
2976class DataRepresentationTemplate41:
2977    """[Data Representation Template 41](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-41.shtml)"""
2978    _len = 5
2979    _num = 41
2980    _packingScheme = 'png'
2981    refValue: float = field(init=False, repr=False, default=RefValue())
2982    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2983    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2984    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2985    @classmethod
2986    def _attrs(cls):
2987        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:
2989@dataclass(init=False)
2990class DataRepresentationTemplate42:
2991    """[Data Representation Template 42](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-42.shtml)"""
2992    _len = 8
2993    _num = 42
2994    _packingScheme = 'aec'
2995    refValue: float = field(init=False, repr=False, default=RefValue())
2996    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
2997    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
2998    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
2999    compressionOptionsMask: int = field(init=False, repr=False, default=CompressionOptionsMask())
3000    blockSize: int = field(init=False, repr=False, default=BlockSize())
3001    refSampleInterval: int = field(init=False, repr=False, default=RefSampleInterval())
3002    @classmethod
3003    def _attrs(cls):
3004        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:
3006@dataclass(init=False)
3007class DataRepresentationTemplate50:
3008    """[Data Representation Template 50](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)"""
3009    _len = 5
3010    _num = 0
3011    _packingScheme = 'spectral-simple'
3012    refValue: float = field(init=False, repr=False, default=RefValue())
3013    binScaleFactor: int = field(init=False, repr=False, default=BinScaleFactor())
3014    decScaleFactor: int = field(init=False, repr=False, default=DecScaleFactor())
3015    nBitsPacking: int = field(init=False, repr=False, default=NBitsPacking())
3016    realOfCoefficient: float = field(init=False, repr=False, default=RealOfCoefficient())
3017    @classmethod
3018    def _attrs(cls):
3019        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):
3032def drt_class_by_drtn(drtn: int):
3033    """
3034    Provide a Data Representation Template class via the template number.
3035
3036    Parameters
3037    ----------
3038    drtn
3039        Data Representation template number.
3040
3041    Returns
3042    -------
3043    drt_class_by_drtn
3044        Data Representation template class object (not an instance).
3045    """
3046    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).