Metadata

[1]:
import earthkit.data as ekd

Metadata of the various data formats are represented by Metadata objects, which are:

  • immutable

  • behave like a dict

  • can be updated with the override() method creating a new object

  • derived from the abstract Metadata base class

RawMetadata

The simplest metadata type is RawMetadata, which we can create in the same way as a dict:

[2]:
from earthkit.data.core.metadata import RawMetadata

# from dict
md = RawMetadata({"shortName": "2t", "perturbationNumber": 5})

# from list of key/value pairs
md = RawMetadata([("shortName", "2t"), ("perturbationNumber", 5)])

# from keyword arguments
md = RawMetadata(shortName="2t", perturbationNumber=5)
[3]:
md
[3]:
RawMetadata({'shortName': '2t', 'perturbationNumber': 5})

Value access

We can get the value for a key using [] and get() just like for a dict:

[4]:
print(md["shortName"])
print(md.get("shortName"))
2t
2t

When a key is not available [] raises a KeyError.

[5]:
try:
    md["nonExistentKey"]
except KeyError as e:
    print(f"KeyError: {e}")
KeyError: 'nonExistentKey'

get() can take a default value as a second argument. When the key is not available the default value is returned. If default is not given, it defaults to None, so that this method never raises a KeyError.

[6]:
print(md.get("nonExistentKey"))
print(md.get("nonExistentKey", 12))
None
12

Iteration

[7]:
list(md.keys())
[7]:
['shortName', 'perturbationNumber']
[8]:
for k,v in md.items():
    print(f"{k}: {v}")
shortName: 2t
perturbationNumber: 5

Override

The metadata object is immutable but we can use override() to create a new object with a modified content:

[9]:
md1 = md.override({"shortName": "2d", "step": 6})
[10]:
md1
[10]:
RawMetadata({'shortName': '2d', 'perturbationNumber': 5, 'step': 6})

The original metadata object did not change:

[11]:
md
[11]:
RawMetadata({'shortName': '2t', 'perturbationNumber': 5})

GribMetadata

For this exercise we read a GRIB file containing 4 messages:

[12]:
ekd.download_example_file("test4.grib")
ds = ekd.from_source("file", "test4.grib")
ds.ls()
[12]:
centre shortName typeOfLevel level dataDate dataTime stepRange dataType number gridType
0 ecmf t isobaricInhPa 500 20070101 1200 0 an 0 regular_ll
1 ecmf z isobaricInhPa 500 20070101 1200 0 an 0 regular_ll
2 ecmf t isobaricInhPa 850 20070101 1200 0 an 0 regular_ll
3 ecmf z isobaricInhPa 850 20070101 1200 0 an 0 regular_ll

We cannot create GRIB metadata object from a dict or RawMetadata, but can get it from a GRIB field. The resulting GribMetadata instance will store a reference to the ecCodes handle of its parent field.

[13]:
md = ds[0].metadata()

GribMetadata works like a dict:

[14]:
print(md["shortName"])
print(md.get("shortName"))
print(md.get("nonExistentKey"))
print(md.get("nonExistentKey", 12))
t
t
None
12

However, it is also aware of the ecCodes namespaces, when we use as_namespace() or dump().

[15]:
md.as_namespace("vertical")
[15]:
{'typeOfLevel': 'isobaricInhPa', 'level': 500}
[16]:
md.dump()
[16]:
GribFieldMetadata
globalDomaing
GRIBEditionNumber1
eps0
offsetSection00
section0Length8
totalLength130428
editionNumber1
WMO0
productionStatusOfProcessedData0
section1Length52
wrongPadding0
table2Version128
centreecmf
centreDescriptionEuropean Centre for Medium-Range Weather Forecasts
generatingProcessIdentifier145
gridDefinition255
indicatorOfParameter130
parameterNameTemperature
parameterUnitsK
indicatorOfTypeOfLevelpl
pressureUnitshPa
typeOfLevelECMFisobaricInhPa
typeOfLevelisobaricInhPa
level500
yearOfCentury7
month1
day1
hour12
minute0
second0
unitOfTimeRange1
P10
P20
timeRangeIndicator0
numberIncludedInAverage0
numberMissingFromAveragesOrAccumulations0
centuryOfReferenceTimeOfData21
subCentre0
paramIdECMF130
paramId130
cfNameECMFair_temperature
cfNameair_temperature
unitsECMFK
unitsK
nameECMFTemperature
nameTemperature
decimalScaleFactor0
setLocalDefinition0
optimizeScaleFactor0
dataDate20070101
year2007
dataTime1200
julianDay2454102.0
stepUnits1
stepTypeinstant
stepRange0
startStep0
endStep0
marsParam130.128
validityDate20070101
validityTime1200
validityDateTime2454101.5083333333
deleteLocalDefinition0
localUsePresent1
reservedNeedNotBePresent['']
localDefinitionNumber1
GRIBEXSection1Problem0
marsClassea
marsTypean
marsStreamoper
experimentVersionNumber0001
perturbationNumber0
numberOfForecastsInEnsemble0
padding_local1_100
grib2LocalSectionNumber1
localExtensionPadding
_xNone
section1Padding
shortNameECMFt
shortNamet
cfVarNameECMFt
cfVarNamet
ifsParam130
stepTypeForConversionunknown
md5Section1e4c6d9f0d01b01247d9c57dad662ee30
md5Producted3159ec68703fb0415e15e859b4eb02
paramIdForConversion0
gridDescriptionSectionPresent1
bitmapPresent0
angleSubdivisions1000
section2Length32
radius6367470
numberOfVerticalCoordinateValues0
neitherPresent255
pvlLocation255
dataRepresentationType0
gridDefinitionDescriptionLatitude/Longitude Grid
gridDefinitionTemplateNumber0
Ni360
Nj181
latitudeOfFirstGridPoint90000
latitudeOfFirstGridPointInDegrees90.0
longitudeOfFirstGridPoint0
longitudeOfFirstGridPointInDegrees0.0
resolutionAndComponentFlags128
ijDirectionIncrementGiven1
earthIsOblate0
resolutionAndComponentFlags30
resolutionAndComponentFlags40
uvRelativeToGrid0
resolutionAndComponentFlags60
resolutionAndComponentFlags70
resolutionAndComponentFlags80
latitudeOfLastGridPoint-90000
latitudeOfLastGridPointInDegrees-90.0
longitudeOfLastGridPoint359000
longitudeOfLastGridPointInDegrees359.0
iDirectionIncrement1000
jDirectionIncrement1000
isGridded1
scanningMode0
iScansNegatively0
jScansPositively0
jPointsAreConsecutive0
alternativeRowScanning0
iScansPositively1
jScansNegatively1
scanningMode40
scanningMode50
scanningMode60
scanningMode70
scanningMode80
swapScanningAlternativeRows0
jDirectionIncrementInDegrees1.0
iDirectionIncrementInDegrees1.0
numberOfDataPoints65160
numberOfValues65160
zeros
PVPresent0
padding_sec2_2
PLPresent0
padding_sec2_1
deletePV1
padding_sec2_3
md5Section2d0ccb07e4b36a8911817cc07539cf859
isSpectral0
lengthOfHeaders85
md5Headersb2ff552cc12a4ea08bfbd989ed20c0fb
missingValue9999
tableReference0
section4Length130332
halfByte8
dataFlag8
binaryScaleFactor-10
referenceValue224.05772399902344
referenceValueError1.52587890625e-05
sphericalHarmonics0
complexPacking0
integerPointValues0
additionalFlagPresent0
orderOfSPD2
boustrophedonic0
hideThis0
packingTypegrid_simple
bitsPerValue16
constantFieldHalfByte8
bitMapIndicator255
numberOfCodedValues65160
packingError0.00049591064453125
unpackedError1.52587890625e-05
maximum273.33799743652344
minimum224.05772399902344
average252.5098487718183
standardDeviation13.372886915179645
skewness-0.2209591997514728
kurtosis-1.2738579926507174
isConstant0.0
numberOfMissing0
dataLength16290
changeDecimalPrecision0
decimalPrecision0
bitsPerValueAndRepack16
setPackingTypegrid_simple
scaleValuesBy1.0
offsetValuesBy0.0
gridTyperegular_ll
getNumberOfValues65160
padding_sec4_1
md5Section473097e43c94a4e2947a55799222424c2
section5Length4
77777777
edition1
centreecmf
typeOfLevelisobaricInhPa
level500
dataDate20070101
stepRange0
dataTypean
shortNamet
packingTypegrid_simple
gridTyperegular_ll
bitmapPresent0
Ni360
Nj181
latitudeOfFirstGridPointInDegrees90.0
longitudeOfFirstGridPointInDegrees0.0
latitudeOfLastGridPointInDegrees-90.0
longitudeOfLastGridPointInDegrees359.0
iScansNegatively0
jScansPositively0
jPointsAreConsecutive0
jDirectionIncrementInDegrees1.0
iDirectionIncrementInDegrees1.0
gridTyperegular_ll
domaing
levtypepl
levelist500
date20070101
time1200
step0
paramt
classea
typean
streamoper
expver0001
centreecmf
paramId130
unitsK
nameTemperature
shortNamet
max273.33799743652344
min224.05772399902344
avg252.5098487718183
sd13.372886915179645
skew-0.2209591997514728
kurt-1.2738579926507174
const0.0
dataDate20070101
dataTime1200
stepUnits1
stepTypeinstant
stepRange0
startStep0
endStep0
validityDate20070101
validityTime1200
typeOfLevelisobaricInhPa
level500