Ejemplo n.º 1
0
    def _get_field_(self, format_time=True):
        """
        :param bool format_time:
        :raises ValueError:
        """

        # reference the request dataset's source metadata
        source_metadata = self.rd.source_metadata

        def _get_temporal_adds_(ref_attrs):
            # calendar should default to standard if it is not present and the t_calendar overload is not used.
            calendar = self.rd.t_calendar or ref_attrs.get("calendar", None) or "standard"

            return {
                "units": self.rd.t_units or ref_attrs["units"],
                "calendar": calendar,
                "format_time": format_time,
                "conform_units_to": self.rd.t_conform_units_to,
            }

        # parameters for the loading loop
        to_load = {
            "temporal": {
                "cls": NcTemporalDimension,
                "adds": _get_temporal_adds_,
                "axis": "T",
                "name_uid": "tid",
                "name": "time",
            },
            "level": {"cls": NcVectorDimension, "adds": None, "axis": "Z", "name_uid": "lid", "name": "level"},
            "row": {"cls": NcVectorDimension, "adds": None, "axis": "Y", "name_uid": "yc_id", "name": "yc"},
            "col": {"cls": NcVectorDimension, "adds": None, "axis": "X", "name_uid": "xc_id", "name": "xc"},
            "realization": {
                "cls": NcVectorDimension,
                "adds": None,
                "axis": "R",
                "name_uid": "rlz_id",
                "name_value": "rlz",
            },
        }

        loaded = {}
        kwds_grid = {}
        has_row_column = True
        for k, v in to_load.iteritems():
            fill = self._get_vector_dimension_(k, v, source_metadata)
            if k != "realization" and not isinstance(fill, NcVectorDimension) and fill is not None:
                assert k in ("row", "col")
                has_row_column = False
                kwds_grid[k] = fill
            loaded[k] = fill

        loaded_keys = set([k for k, v in loaded.iteritems() if v is not None])
        if has_row_column:
            if not {"temporal", "row", "col"}.issubset(loaded_keys):
                raise ValueError("Target variable must at least have temporal, row, and column dimensions.")
            kwds_grid = {"row": loaded["row"], "col": loaded["col"]}
        else:
            shape_src_idx = [source_metadata["dimensions"][xx]["len"] for xx in kwds_grid["row"]["dimensions"]]
            src_idx = {
                "row": np.arange(0, shape_src_idx[0], dtype=np.int32),
                "col": np.arange(0, shape_src_idx[1], dtype=np.int32),
            }
            name_row = kwds_grid["row"]["name"]
            name_col = kwds_grid["col"]["name"]
            kwds_grid = {"name_row": name_row, "name_col": name_col, "data": self.rd, "src_idx": src_idx}

        grid = NcSpatialGridDimension(**kwds_grid)

        spatial = SpatialDimension(name_uid="gid", grid=grid, crs=self.rd.crs, abstraction=self.rd.s_abstraction)

        vc = VariableCollection()
        for vdict in self.rd:
            variable_meta = deepcopy(source_metadata["variables"][vdict["variable"]])
            variable_units = vdict["units"] or variable_meta["attrs"].get("units")
            dtype = np.dtype(variable_meta["dtype"])
            fill_value = variable_meta["fill_value"]
            variable = Variable(
                vdict["variable"],
                vdict["alias"],
                units=variable_units,
                meta=variable_meta,
                data=self.rd,
                conform_units_to=vdict["conform_units_to"],
                dtype=dtype,
                fill_value=fill_value,
                attrs=variable_meta["attrs"].copy(),
            )
            vc.add_variable(variable)

        ret = NcField(
            variables=vc,
            spatial=spatial,
            temporal=loaded["temporal"],
            level=loaded["level"],
            realization=loaded["realization"],
            meta=source_metadata.copy(),
            uid=self.rd.did,
            name=self.rd.name,
            attrs=source_metadata["dataset"].copy(),
        )

        # Apply any subset parameters after the field is loaded.
        if self.rd.time_range is not None:
            ret = ret.get_between("temporal", min(self.rd.time_range), max(self.rd.time_range))
        if self.rd.time_region is not None:
            ret = ret.get_time_region(self.rd.time_region)
        if self.rd.time_subset_func is not None:
            ret = ret.get_time_subset_by_function(self.rd.time_subset_func)
        if self.rd.level_range is not None:
            try:
                ret = ret.get_between("level", min(self.rd.level_range), max(self.rd.level_range))
            except AttributeError:
                # there may be no level dimension
                if ret.level is None:
                    msg = messages.M4.format(self.rd.alias)
                    raise ValueError(msg)
                else:
                    raise

        return ret
Ejemplo n.º 2
0
    def _get_field_(self, format_time=True):
        """
        :param bool format_time:
        :raises ValueError:
        """

        # reference the request dataset's source metadata
        source_metadata = self.rd.source_metadata

        def _get_temporal_adds_(ref_attrs):
            # calendar should default to standard if it is not present and the t_calendar overload is not used.
            calendar = self.rd.t_calendar or ref_attrs.get('calendar', None) or 'standard'

            return {'units': self.rd.t_units or ref_attrs['units'], 'calendar': calendar, 'format_time': format_time,
                    'conform_units_to': self.rd.t_conform_units_to}

        # parameters for the loading loop
        to_load = {'temporal': {'cls': NcTemporalDimension, 'adds': _get_temporal_adds_, 'axis': 'T', 'name_uid': 'tid',
                                'name': 'time'},
                   'level': {'cls': NcVectorDimension, 'adds': None, 'axis': 'Z', 'name_uid': 'lid', 'name': 'level'},
                   'row': {'cls': NcVectorDimension, 'adds': None, 'axis': 'Y', 'name_uid': 'yc_id', 'name': 'yc'},
                   'col': {'cls': NcVectorDimension, 'adds': None, 'axis': 'X', 'name_uid': 'xc_id', 'name': 'xc'},
                   'realization': {'cls': NcVectorDimension, 'adds': None, 'axis': 'R', 'name_uid': 'rlz_id',
                                   'name_value': 'rlz'}}

        loaded = {}
        kwds_grid = {}
        has_row_column = True
        for k, v in to_load.iteritems():
            fill = self._get_vector_dimension_(k, v, source_metadata)
            if k != 'realization' and not isinstance(fill, NcVectorDimension) and fill is not None:
                assert k in ('row', 'col')
                has_row_column = False
                kwds_grid[k] = fill
            loaded[k] = fill

        loaded_keys = set([k for k, v in loaded.iteritems() if v is not None])
        if has_row_column:
            if not {'temporal', 'row', 'col'}.issubset(loaded_keys):
                raise ValueError('Target variable must at least have temporal, row, and column dimensions.')
            kwds_grid = {'row': loaded['row'], 'col': loaded['col']}
        else:
            shape_src_idx = [source_metadata['dimensions'][xx]['len'] for xx in kwds_grid['row']['dimensions']]
            src_idx = {'row': np.arange(0, shape_src_idx[0], dtype=np.int32),
                       'col': np.arange(0, shape_src_idx[1], dtype=np.int32)}
            name_row = kwds_grid['row']['name']
            name_col = kwds_grid['col']['name']
            kwds_grid = {'name_row': name_row, 'name_col': name_col, 'request_dataset': self.rd, 'src_idx': src_idx}

        grid = NcSpatialGridDimension(**kwds_grid)

        spatial = SpatialDimension(name_uid='gid', grid=grid, crs=self.rd.crs, abstraction=self.rd.s_abstraction)

        vc = VariableCollection()
        for vdict in self.rd:
            variable_meta = deepcopy(source_metadata['variables'][vdict['variable']])
            variable_units = vdict['units'] or variable_meta['attrs'].get('units')
            attrs = variable_meta['attrs'].copy()
            if variable_meta['dtype_packed'] is None:
                dtype = np.dtype(variable_meta['dtype'])
                fill_value = variable_meta['fill_value']
            else:
                dtype = np.dtype(variable_meta['dtype_packed'])
                fill_value = variable_meta['fill_value_packed']
                # Remove scale factors and offsets from the metadata.
                attrs.pop('scale_factor')
                attrs.pop('add_offset', None)
                attrs.pop('missing_value', None)
                attrs.pop('_Fill_Value', None)
            variable = Variable(vdict['variable'], vdict['alias'], units=variable_units, meta=variable_meta,
                                request_dataset=self.rd, conform_units_to=vdict['conform_units_to'], dtype=dtype,
                                fill_value=fill_value, attrs=attrs)
            vc.add_variable(variable)

        ret = NcField(variables=vc, spatial=spatial, temporal=loaded['temporal'], level=loaded['level'],
                      realization=loaded['realization'], meta=source_metadata.copy(), uid=self.rd.did,
                      name=self.rd.name, attrs=source_metadata['dataset'].copy())

        # Apply any subset parameters after the field is loaded.
        if self.rd.time_range is not None:
            ret = ret.get_between('temporal', min(self.rd.time_range), max(self.rd.time_range))
        if self.rd.time_region is not None:
            ret = ret.get_time_region(self.rd.time_region)
        if self.rd.time_subset_func is not None:
            ret = ret.get_time_subset_by_function(self.rd.time_subset_func)
        if self.rd.level_range is not None:
            try:
                ret = ret.get_between('level', min(self.rd.level_range), max(self.rd.level_range))
            except AttributeError:
                # there may be no level dimension
                if ret.level is None:
                    msg = messages.M4.format(self.rd.alias)
                    raise ValueError(msg)
                else:
                    raise

        return ret