Beispiel #1
0
    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
Beispiel #2
0
    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)
Beispiel #3
0
    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
Beispiel #4
0
    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
Beispiel #5
0
 def time_settings(self):
     return util.filter_dataclass(self, _VarlistTimeSettings)
Beispiel #6
0
 def global_settings(self):
     return util.filter_dataclass(self, _VarlistGlobalSettings)