def translate_coord(self, coord, log=_log): """Given a :class:`~data_model.DMCoordinate`, look up the corresponding translated :class:`~data_model.DMCoordinate` in this convention. """ ax = coord.axis if ax not in self.axes_lut: raise KeyError( f"Axis {ax} not defined in convention '{self.name}'.") lut1 = self.axes_lut[ax] # abbreviate if not hasattr(coord, 'standard_name'): coords = tuple(lut1.values()) if len(coords) > 1: raise ValueError( (f"Coordinate dimension in convention '{self.name}' " f"not uniquely determined by coordinate {coord.name}.")) new_coord = coords[0] else: if coord.standard_name not in lut1: raise KeyError(( f"Coordinate {coord.name} with standard name " f"'{coord.standard_name}' not defined in convention '{self.name}'." )) new_coord = lut1[coord.standard_name] if hasattr(coord, 'is_scalar') and coord.is_scalar: new_coord = copy.deepcopy(new_coord) new_coord.value = units.convert_scalar_coord(coord, new_coord.units, log=log) else: new_coord = dc.replace(coord, **(util.filter_dataclass(new_coord, coord))) return new_coord
def from_struct(cls, dims_d, name, **kwargs): # if we only have ndim, map to axes names if 'dimensions' not in kwargs and 'ndim' in kwargs: kwargs['dimensions'] = cls._ndim_to_axes_set[kwargs.pop('ndim')] # map dimension names to coordinate objects kwargs['coords'] = [] if 'dimensions' not in kwargs or not kwargs['dimensions']: raise ValueError( f"No dimensions specified for fieldlist entry {name}.") for d_name in kwargs.pop('dimensions'): if d_name in cls._placeholder_class_dict: coord_cls = cls._placeholder_class_dict[d_name] kwargs['coords'].append(coord_cls()) elif d_name not in dims_d: raise ValueError( (f"Unknown dimension name {d_name} in fieldlist " f"entry for {name}.")) else: kwargs['coords'].append(dims_d[d_name]) for d_name in kwargs.get('scalar_coord_templates', dict()): if d_name not in dims_d: raise ValueError( (f"Unknown dimension name {d_name} in scalar " f"coord definition for fieldlist entry for {name}.")) filter_kw = util.filter_dataclass(kwargs, cls, init=True) assert filter_kw['coords'] return cls(name=name, **filter_kw)
def change_coord(self, ax_name, new_class=None, **kwargs): """Replace attributes on a given coordinate, but also optionally cast them to new classes. Kind of hacky. """ # TODO: lookup by non-axis name old_coord = getattr(self, ax_name, None) if not old_coord: raise KeyError(f"{self.name} has no {ax_name} axis") if isinstance(new_class, dict): new_coord_class = new_class.pop('self', None) else: new_coord_class = new_class if new_coord_class is None and not isinstance(new_class, dict): # keep all classes new_coord = dc.replace(old_coord, **kwargs) else: if new_coord_class is None: new_coord_class = old_coord.__class__ new_kwargs = dc.asdict(old_coord) else: new_kwargs = util.filter_dataclass(old_coord, new_coord_class) new_kwargs.update(kwargs) if isinstance(new_class, dict): for k, cls_ in new_class.items(): if k in new_kwargs and not isinstance(new_kwargs[k], cls_): new_kwargs[k] = cls_(new_kwargs[k]) new_coord = new_coord_class(**new_kwargs) self.dims[self.dims.index(old_coord)] = new_coord self.__post_init__(None) # rebuild axes dicts
def from_struct(cls, global_settings_d, dims_d, name, parent, **kwargs): """Instantiate from a struct in the varlist section of a POD's settings.jsonc. """ new_kw = global_settings_d.copy() new_kw['coords'] = [] if 'dimensions' not in kwargs: raise ValueError( f"No dimensions specified for varlist entry {name}.") # validate: check for duplicate coord names scalars = kwargs.get('scalar_coordinates', dict()) seen = set() dupe_names = set(x for x \ in itertools.chain(kwargs['dimensions'], scalars.keys()) \ if x in seen or seen.add(x)) if dupe_names: raise ValueError( (f"Repeated coordinate names {list(dupe_names)} in " f"varlist entry for {name}.")) # add dimensions for d_name in kwargs.pop('dimensions'): if d_name not in dims_d: raise ValueError( (f"Unknown dimension name {d_name} in varlist " f"entry for {name}.")) new_kw['coords'].append(dims_d[d_name]) # add scalar coords if 'scalar_coordinates' in kwargs: for d_name, scalar_val in kwargs.pop('scalar_coordinates').items(): if d_name not in dims_d: raise ValueError( (f"Unknown dimension name {d_name} in varlist " f"entry for {name}.")) new_kw['coords'].append(dims_d[d_name].make_scalar(scalar_val)) filter_kw = util.filter_dataclass(kwargs, cls, init=True) obj = cls(name=name, _parent=parent, **new_kw, **filter_kw) # specialize time coord time_kw = util.filter_dataclass(kwargs, _VarlistTimeSettings) if time_kw: obj.change_coord('T', None, **time_kw) return obj
def time_settings(self): return util.filter_dataclass(self, _VarlistTimeSettings)
def global_settings(self): return util.filter_dataclass(self, _VarlistGlobalSettings)