Hi all.
TLDR; Does anyone know what the iris cube attribute grid_staggering (which appears to have integer values) refers to? I came across an error related to this attribute which caused some dramas. I thought I’d share it in case it pops up again.
Details :
I’m building a regional ancillary suite for a coupled model. This is mostly the same as the RNS ancillary suite, except that we pass it a target land-sea mask (created in regional MOM6) and enforce the ancillaries to respect this land-sea definition.
I came across a strange ‘feature’ which I thought I’d share.
The task ancil_soil_albedo runs in two steps:
- Run
ancil_soil_albedo.py - Run a second script
append.pywhich combines various soil cubes into a single ancillary file.
The ‘append’ step failed with:
RuntimeError: Cubes provided are defined with different grid staggering: ([6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6])
Which was a weird error. The script append.py is very simple
#!/usr/bin/env python
"""
The CAP reads specifically 10 fields from the input file when generating the
snow ancillaries (ancilSmcsnow). There is more than 10 fields present in the
soils ancillary which means that ancilSmcsnow is dependent on field order...
We move those fields it doesn't need to the end of the file to avoid a
segmentation fault.
"""
import warnings
import ants
import ants.io.save as save
def main(filenames, output):
cubes = ants.load(filenames)
# Sort by the following stash items (lbuser4).
items = [40, 41, 43, 207, 47, 44, 46, 48, 220, 223, 8, 418, 419, 420]
end = len(items) + 1
def sortme(cube):
stash = cube.attributes['STASH']
try:
order = items.index(stash.item)
except ValueError:
warnings.warn('Was this stash expected?? {}'.format(stash))
return order
cubes = sorted(cubes, key=sortme)
save.ancil(cubes, output)
if __name__ == '__main__':
parser = ants.AntsArgParser()
args = parser.parse_args()
main(args.sources, args.output)
The comments of this function suggests the RAS suite is using it for a task it wasn’t designed for (what could go wrong, eh?).
Here are the offending cubes:
In [160]: cubes
Out[160]:
[<iris 'Cube' of volume_fraction_of_condensed_water_in_soil_at_wilting_point / (1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of volume_fraction_of_condensed_water_in_soil_at_critical_point / (1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_porosity / (1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of m01s00i207 / (unknown) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_thermal_conductivity / (W m-1 K-1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_hydraulic_conductivity_at_saturation / (m s-1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_thermal_capacity / (J kg-1 K-1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_suction_at_saturation / (Pa) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_albedo / (1) (latitude: 50; longitude: 50)>,
<iris 'Cube' of soil_carbon_content / (kg m-2) (latitude: 50; longitude: 50)>,
<iris 'Cube' of m01s00i008 / (unknown) (latitude: 50; longitude: 50)>,
<iris 'Cube' of volume_fraction_of_clay_in_soil / (m3 m-3) (latitude: 50; longitude: 50)>,
<iris 'Cube' of volume_fraction_of_silt_in_soil / (m3 m-3) (latitude: 50; longitude: 50)>,
<iris 'Cube' of volume_fraction_of_sand_in_soil / (m3 m-3) (latitude: 50; longitude: 50)>]
And their attributes
In [159]: [ cube.attributes for cube in cubes]
Out[159]:
[CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=40), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=41), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=43), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=207), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=47), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=44), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=46), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=48), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'source': 'Data from Met Office Unified Model', 'um_version': '6.4', 'STASH': STASH(model=1, section=0, item=220), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=223), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=8), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=418), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=419), 'grid_staggering': 6}),
CubeAttrsDict(globals={}, locals={'STASH': STASH(model=1, section=0, item=420), 'grid_staggering': 6})]
I have no idea what this attribute refers to. I inserted some logic into a local copy of append.py to search for the most common value, and then enforce this value throughout the cube list.
So I got the ancil to generate, but I’m absolutely stumped as to what’s going on here, and I hope it doesn’t come back to bite me at some point in the future.