def get_iter(self): ref_value,ref_bounds = self._get_iter_value_bounds_() if ref_bounds is None: has_bounds = False else: has_bounds = True ref_uid = self.uid ref_name_value = self.name_value assert_raise(self.name_value != None,logger='interface.dimension.base', exc=ValueError('The "name_value" attribute is required for iteration.')) ref_name_uid = self.name_uid ref_name_bounds_lower = '{0}_lower'.format(self.name_bounds) ref_name_bounds_upper = '{0}_upper'.format(self.name_bounds) for ii in range(self.value.shape[0]): yld = {ref_name_value:ref_value[ii],ref_name_uid:ref_uid[ii]} if has_bounds: yld.update({ref_name_bounds_lower:ref_bounds[ii,0], ref_name_bounds_upper:ref_bounds[ii,1]}) else: yld.update({ref_name_bounds_lower:None, ref_name_bounds_upper:None}) yield(ii,yld)
def variables(self,value): if isinstance(value,Variable): value = VariableCollection(variables=[value]) assert_raise(isinstance(value,VariableCollection),exc=ValueError('The "variables" keyword must be a Variable object.')) self._variables = value for v in value.itervalues(): v._field = self if v._value is not None: assert(v._value.shape == self.shape)
def get(self,format_time=True): def _get_temporal_adds_(ref_attrs): ## calendar should default to standard if it is not present. calendar = ref_attrs.get('calendar',None) or self.t_calendar return({'units':self.t_units or ref_attrs['units'], 'calendar':calendar, 'format_time':format_time}) ## parameters for the loading loop to_load = {'temporal':{'cls':NcTemporalDimension,'adds':_get_temporal_adds_,'axis':'T','name_uid':'tid','name_value':'time'}, 'level':{'cls':NcVectorDimension,'adds':None,'axis':'Z','name_uid':'lid','name_value':'level'}, 'row':{'cls':NcVectorDimension,'adds':None,'axis':'Y','name_uid':'row_id','name_value':'row'}, 'col':{'cls':NcVectorDimension,'adds':None,'axis':'X','name_uid':'col_id','name_value':'col'}, 'realization':{'cls':NcVectorDimension,'adds':None,'axis':'R','name_uid':'rlz_id','name_value':'rlz'}} loaded = {} for k,v in to_load.iteritems(): ## this is the string axis representation axis_value = v['axis'] or v['cls']._axis ## pull the axis information out of the dimension map ref_axis = self._source_metadata['dim_map'].get(axis_value) ## if the axis is not represented, fill it with none. this happens ## when a dataset does not have a vertical level or projection axis ## for example. if ref_axis is None: fill = None else: ref_variable = self._source_metadata['variables'].get(ref_axis['variable']) ## for data with a projection/realization axis there may be no ## associated variable. try: ref_variable['axis'] = ref_axis except TypeError: if axis_value == 'R' and ref_variable is None: ref_variable = {'axis':ref_axis,'name':ref_axis['dimension'],'attrs':{}} ## extract the data length to use when creating the source index ## arrays. length = self._source_metadata['dimensions'][ref_axis['dimension']]['len'] src_idx = np.arange(0,length) ## assemble parameters for creating the dimension class then initialize ## the class. kwds = dict(name_uid=v['name_uid'],name_value=v['name_value'],src_idx=src_idx, data=self,meta=ref_variable,axis=axis_value,name=ref_variable.get('name')) if v['adds'] is not None: kwds.update(v['adds'](ref_variable['attrs'])) kwds.update({'name':ref_variable.get('name')}) fill = v['cls'](**kwds) loaded[k] = fill assert_raise(set(('temporal','row','col')).issubset(set([k for k,v in loaded.iteritems() if v != None])), logger='request',exc=ValueError('Target variable must at least have temporal, row, and column dimensions.')) grid = SpatialGridDimension(row=loaded['row'],col=loaded['col']) crs = None if self.s_crs is not None: crs = self.s_crs else: crs = self._get_crs_() if crs is None: ocgis_lh('No "grid_mapping" attribute available assuming WGS84: {0}'.format(self.uri), 'request',logging.WARN) crs = CFWGS84() ## rotated pole coordinate systems require transforming the coordinates to ## WGS84 before they may be loaded. if isinstance(crs,CFRotatedPole): msg = 'CFRotatedPole projection found. Transforming coordinates to WGS84 and replacing the CRS with CFWGS84' ocgis_lh(msg=msg,logger='request.nc',level=logging.WARN) grid = get_rotated_pole_spatial_grid_dimension(crs,grid) crs = CFWGS84() spatial = SpatialDimension(name_uid='gid',grid=grid,crs=crs,abstraction=self.s_abstraction) variable_meta = self._source_metadata['variables'][self.variable] variable_units = variable_meta['attrs'].get('units') variable = Variable(self.variable,self.alias,variable_units,meta=variable_meta, data=self) vc = VariableCollection(variables=[variable]) ret = NcField(variables=vc,spatial=spatial,temporal=loaded['temporal'],level=loaded['level'], realization=loaded['realization'],meta=self._source_metadata,uid=self.did) ## apply any subset parameters after the field is loaded if self.time_range is not None: ret = ret.get_between('temporal',min(self.time_range),max(self.time_range)) if self.time_region is not None: ret = ret.get_time_region(self.time_region) if self.level_range is not None: ret = ret.get_between('level',min(self.level_range),max(self.level_range)) return(ret)
def get_field(self, format_time=True, interpolate_spatial_bounds=False): """ :param bool format_time: :param bool interpolate_spatial_bounds: :raises ValueError: """ 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}) ## this dictionary contains additional keyword arguments for the row ## and column dimensions. adds_row_col = {'interpolate_bounds': interpolate_spatial_bounds} ## parameters for the loading loop to_load = {'temporal': {'cls': NcTemporalDimension, 'adds': _get_temporal_adds_, 'axis': 'T', 'name_uid': 'tid', 'name_value': 'time'}, 'level': {'cls': NcVectorDimension, 'adds': None, 'axis': 'Z', 'name_uid': 'lid', 'name_value': 'level'}, 'row': {'cls': NcVectorDimension, 'adds': adds_row_col, 'axis': 'Y', 'name_uid': 'row_id', 'name_value': 'row'}, 'col': {'cls': NcVectorDimension, 'adds': adds_row_col, 'axis': 'X', 'name_uid': 'col_id', 'name_value': 'col'}, 'realization': {'cls': NcVectorDimension, 'adds': None, 'axis': 'R', 'name_uid': 'rlz_id', 'name_value': 'rlz'}} loaded = {} for k, v in to_load.iteritems(): ## this is the string axis representation axis_value = v['axis'] or v['cls']._axis ## pull the axis information out of the dimension map ref_axis = self.rd.source_metadata['dim_map'].get(axis_value) ref_axis = self.rd.source_metadata['dim_map'].get(axis_value) ## if the axis is not represented, fill it with none. this happens ## when a dataset does not have a vertical level or projection axis ## for example. if ref_axis is None: fill = None else: ref_variable = self.rd.source_metadata['variables'].get(ref_axis['variable']) ## for data with a projection/realization axis there may be no ## associated variable. try: ref_variable['axis'] = ref_axis except TypeError: if axis_value == 'R' and ref_variable is None: ref_variable = {'axis': ref_axis, 'name': ref_axis['dimension'], 'attrs': {}} ## extract the data length to use when creating the source index ## arrays. length = self.rd.source_metadata['dimensions'][ref_axis['dimension']]['len'] src_idx = np.arange(0, length, dtype=constants.np_int) ## get the target data type for the dimension try: dtype = np.dtype(ref_variable['dtype']) ## the realization dimension may not be a associated with a variable except KeyError: if k == 'realization' and ref_variable['axis']['variable'] is None: dtype = None else: raise ## assemble parameters for creating the dimension class then initialize ## the class. kwds = dict(name_uid=v['name_uid'], name_value=v['name_value'], src_idx=src_idx, data=self.rd, meta=ref_variable, axis=axis_value, name=ref_variable.get('name'), dtype=dtype) ## there may be additional parameters for each dimension. if v['adds'] is not None: try: kwds.update(v['adds'](ref_variable['attrs'])) ## adds may not be a callable object. assume they are a ## dictionary. except TypeError: kwds.update(v['adds']) kwds.update({'name': ref_variable.get('name')}) fill = v['cls'](**kwds) loaded[k] = fill assert_raise(set(('temporal', 'row', 'col')).issubset(set([k for k, v in loaded.iteritems() if v != None])), logger='request', exc=ValueError('Target variable must at least have temporal, row, and column dimensions.')) grid = SpatialGridDimension(row=loaded['row'], col=loaded['col']) # crs = None # if rd.crs is not None: # crs = rd.crs # else: # crs = rd._get_crs_(rd._variable[0]) # if crs is None: # ocgis_lh('No "grid_mapping" attribute available assuming WGS84: {0}'.format(rd.uri), # 'request', logging.WARN) # crs = CFWGS84() 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(self.rd._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) vc.add_variable(variable) ret = NcField(variables=vc, spatial=spatial, temporal=loaded['temporal'], level=loaded['level'], realization=loaded['realization'], meta=deepcopy(self.rd._source_metadata), uid=self.rd.did, name=self.rd.name) ## 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.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 == None: msg = ("A level subset was requested but the target dataset does not have a level dimension. The " "dataset's alias is: {0}".format(self.rd.alias)) raise (ValueError(msg)) else: raise return ret