iris icon indicating copy to clipboard operation
iris copied to clipboard

Netcdf load should workaround unexpected names in 'coordinates'

Open pp-mo opened this issue 6 years ago • 1 comments

We encountered a file where loading fails due to a variable referencing as 'coordinates' a dimension that it doesn't actually use.

Simplified example CDL :

netcdf minimal_failcase {
dimensions:
                length_scale = 1 ;
                lat = 3 ;
variables:
                float lat(lat) ;
                                lat:standard_name = "latitude" ;
                                lat:units = "degrees_north" ;
                short lst_unc_sys(length_scale) ;
                                lst_unc_sys:long_name = "uncertainty from large-scale systematic errors" ;
                                lst_unc_sys:units = "kelvin" ;
                                lst_unc_sys:coordinates = "lat" ;

data:
  lat = 0, 1, 2;
}

LOADING FAILS with message"ValueError: Missing data dimensions for multi-valued DimCoord 'latitude'"

Proposal Strictly, this is not good CF. Cf-checker confirms this, saying "INFO: attribute coordinates is being used in a non-standard way". However, we should probable be capable of gracefully working around this type of problem, as we do for invalid 'unit' and 'standard_name'.

pp-mo avatar Jan 21 '20 21:01 pp-mo

Actual testcode + error :

(old version with Pyke ...)
>>> os.system('ncgen -o minimal_failcase.nc minimal_failcase.cdl')
>>> print(iris.load('minimal_failcase.nc'))
Traceback (most recent call last):
  File "/home/h05/itpp/Support/periods/period_20200106_iris2x4/Surgery/RobKing_jasmin_loadfail/test_failcase.py", line 6, in <module>
    print(iris.load('minimal_failcase.nc'))
  File "...lib/iris/__init__.py", line 304, in load
    return _load_collection(uris, constraints, callback).merged().cubes()
  File "...lib/iris/__init__.py", line 271, in _load_collection
    result = iris.cube._CubeFilterCollection.from_cubes(cubes, constraints)
  File "...lib/iris/cube.py", line 144, in from_cubes
    for cube in cubes:
  File "...lib/iris/__init__.py", line 258, in _generate_cubes
    for cube in iris.io.load_files(part_names, callback, constraints):
  File "...lib/iris/io/__init__.py", line 207, in load_files
    for cube in handling_format_spec.handler(fnames, callback):
  File "...lib/iris/fileformats/netcdf.py", line 788, in load_cubes
    cube = _load_cube(engine, cf, cf_var, filename)
  File "...lib/iris/fileformats/netcdf.py", line 598, in _load_cube
    engine.activate(_PYKE_RULE_BASE)
  File "/tmp/persistent/miniconda3/envs/iristest_py3/lib/python3.6/site-packages/pyke/knowledge_engine.py", line 297, in activate
    for rb_name in rb_names: self.get_rb(rb_name).activate()
  File "/tmp/persistent/miniconda3/envs/iristest_py3/lib/python3.6/site-packages/pyke/rule_base.py", line 159, in activate
    self.run_fc_rules(current_rb)
  File "/tmp/persistent/miniconda3/envs/iristest_py3/lib/python3.6/site-packages/pyke/rule_base.py", line 147, in run_fc_rules
    for fc_rule in rb.fc_rules: fc_rule.run()
  File "/tmp/persistent/miniconda3/envs/iristest_py3/lib/python3.6/site-packages/pyke/fc_rule.py", line 90, in run
    self.rule_fn(self)
  File "...lib/iris/fileformats/_pyke_rules/compiled_krb/fc_rules_cf_fc.py", line 633, in fc_build_coordinate_latitude_nocs
    coord_system=None)
  File "...lib/iris/fileformats/_pyke_rules/compiled_krb/fc_rules_cf_fc.py", line 2337, in build_dimension_coordinate
    cube.add_aux_coord(coord, data_dims)
  File "...lib/iris/cube.py", line 1061, in add_aux_coord
    self._add_unique_aux_coord(coord, data_dims)
  File "...lib/iris/cube.py", line 1104, in _add_unique_aux_coord
    data_dims = self._check_multi_dim_metadata(coord, data_dims)
  File "...lib/iris/cube.py", line 1100, in _check_multi_dim_metadata
    raise ValueError(msg)
ValueError: Missing data dimensions for multi-valued DimCoord 'latitude'

Stacktrace

itpp@vld321 $ python -c "import iris; print(iris.load('sample.nc'))"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/__init__.py", line 314, in load
    return _load_collection(uris, constraints, callback).merged().cubes()
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/__init__.py", line 280, in _load_collection
    result = _CubeFilterCollection.from_cubes(cubes, constraints)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/cube.py", line 104, in from_cubes
    for cube in cubes:
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/__init__.py", line 265, in _generate_cubes
    for cube in iris.io.load_files(part_names, callback, constraints):
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/io/__init__.py", line 218, in load_files
    for cube in handling_format_spec.handler(
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/netcdf/loader.py", line 574, in load_cubes
    cube = _load_cube(engine, cf, cf_var, filename)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/netcdf/loader.py", line 287, in _load_cube
    engine.activate()
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/_nc_load_rules/engine.py", line 97, in activate
    run_actions(self)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/_nc_load_rules/actions.py", line 542, in run_actions
    action_build_dimension_coordinate(engine, providescoord_fact)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/_nc_load_rules/actions.py", line 74, in inner
    rule_name = func(engine, *args, **kwargs)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/_nc_load_rules/actions.py", line 347, in action_build_dimension_coordinate
    hh.build_dimension_coordinate(
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/fileformats/_nc_load_rules/helpers.py", line 895, in build_dimension_coordinate
    cube.add_aux_coord(coord, data_dims)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/cube.py", line 1162, in add_aux_coord
    self._add_unique_aux_coord(coord, data_dims)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/cube.py", line 1205, in _add_unique_aux_coord
    data_dims = self._check_multi_dim_metadata(coord, data_dims)
  File "/home/h05/itpp/git/iris/iris_main/lib/iris/cube.py", line 1201, in _check_multi_dim_metadata
    raise ValueError(msg)
ValueError: Missing data dimensions for multi-valued DimCoord 'latitude'

/home/h05/itpp/Support/periods/period_20220905_gendev/dev/meshcoord_update/bad_aux_coords
itpp@vld321 $ 

pp-mo avatar Jan 21 '20 21:01 pp-mo