Esempio n. 1
0
 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)
Esempio n. 2
0
 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)
Esempio n. 3
0
 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)
Esempio n. 4
0
    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