@@ -338,27 +338,21 @@ def _get_measure_variable(
338
338
339
339
def _get_measure (obj : Union [DataArray , Dataset ], key : str ) -> List [str ]:
340
340
"""
341
- Translate from cell measures ("area" or "volume") to appropriate variable name.
341
+ Translate from cell measures to appropriate variable name.
342
342
This function interprets the ``cell_measures`` attribute on DataArrays.
343
343
344
344
Parameters
345
345
----------
346
346
obj: DataArray, Dataset
347
347
DataArray belonging to the coordinate to be checked
348
- key: str, ["area", "volume"]
348
+ key: str
349
349
key to check for.
350
350
351
351
Returns
352
352
-------
353
353
List[str], Variable name(s) in parent xarray object that matches axis or coordinate `key`
354
354
"""
355
355
356
- valid_keys = _CELL_MEASURES
357
- if key not in valid_keys :
358
- raise KeyError (
359
- f"cf_xarray did not understand key { key !r} . Expected one of { valid_keys !r} "
360
- )
361
-
362
356
if isinstance (obj , DataArray ):
363
357
obj = obj ._to_temp_dataset ()
364
358
@@ -438,7 +432,7 @@ def _build_docstring(func):
438
432
mapper_docstrings = {
439
433
_get_axis_coord : f"One or more of { (_AXIS_NAMES + _COORD_NAMES )!r} " ,
440
434
_get_axis_coord_single : f"One of { (_AXIS_NAMES + _COORD_NAMES )!r} " ,
441
- _get_measure_variable : f"One of { _CELL_MEASURES !r} " ,
435
+ # _get_measure_variable: f"One of {_CELL_MEASURES!r}",
442
436
}
443
437
444
438
sig = inspect .signature (func )
@@ -653,6 +647,9 @@ class CFAccessor:
653
647
654
648
def __init__ (self , da ):
655
649
self ._obj = da
650
+ self ._defined_cell_measures = tuple (
651
+ set (_CELL_MEASURES + tuple (self .cell_measures ))
652
+ )
656
653
657
654
def _process_signature (
658
655
self ,
@@ -833,7 +830,7 @@ def describe(self):
833
830
834
831
text += "\n Cell Measures:\n "
835
832
measures = self .cell_measures
836
- for key in _CELL_MEASURES :
833
+ for key in sorted ( self . _defined_cell_measures ) :
837
834
text += f"\t { key } : { measures [key ] if key in measures else []} \n "
838
835
839
836
text += "\n Standard Names:\n "
@@ -930,15 +927,33 @@ def cell_measures(self) -> Dict[str, List[str]]:
930
927
Returns
931
928
-------
932
929
Dictionary of valid cell measure names that can be used with __getitem__ or .cf[key].
933
- Will be ("area", "volume") or a subset thereof.
934
930
"""
935
931
936
- measures = {
937
- key : apply_mapper (_get_measure , self ._obj , key , error = False )
938
- for key in _CELL_MEASURES
939
- }
932
+ obj = self ._obj
933
+ all_attrs = [
934
+ da .attrs .get ("cell_measures" )
935
+ for da in obj .coords .values ()
936
+ if da .attrs .get ("cell_measures" )
937
+ ]
938
+ if isinstance (obj , DataArray ):
939
+ all_attrs += (
940
+ [obj .attrs .get ("cell_measures" )]
941
+ if obj .attrs .get ("cell_measures" )
942
+ else []
943
+ )
944
+ elif isinstance (obj , Dataset ):
945
+ all_attrs += [
946
+ da .attrs .get ("cell_measures" )
947
+ for da in obj .data_vars .values ()
948
+ if da .attrs .get ("cell_measures" )
949
+ ]
950
+
951
+ measures : Dict [str , List [str ]] = dict ()
952
+ for attr in all_attrs :
953
+ for key , value in parse_cell_methods_attr (attr ).items ():
954
+ measures [key ] = measures .setdefault (key , []) + [value ]
940
955
941
- return {k : sorted (v ) for k , v in measures .items () if v }
956
+ return {k : sorted (set ( v ) ) for k , v in measures .items () if v }
942
957
943
958
def get_standard_names (self ) -> List [str ]:
944
959
@@ -1069,7 +1084,7 @@ def check_results(names, k):
1069
1084
check_results (names , k )
1070
1085
successful [k ] = bool (names )
1071
1086
coords .extend (names )
1072
- elif k in _CELL_MEASURES :
1087
+ elif k in self . _defined_cell_measures :
1073
1088
measure = _get_measure (self ._obj , k )
1074
1089
check_results (measure , k )
1075
1090
successful [k ] = bool (measure )
0 commit comments