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
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