예제 #1
0
 def test_calculation_file_only_one_variable(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     field = field.get_field_slice({'time': slice(0, 10)})
     expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr, field=field, file_only=True)
     ret = ef.execute()
     self.assertEqual(ret['es']._value, None)
예제 #2
0
 def test_calculation_file_only_one_variable(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     field = field.get_field_slice({'time': slice(0, 10)})
     expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr, field=field, file_only=True)
     ret = ef.execute()
     self.assertEqual(ret['es']._value, None)
예제 #3
0
 def test_calculation_one_variable_exp_and_log(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     field = field[:,0:10,:,:,:]
     expr = 'es=6.1078*exp(log(17.08085)*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr,field=field)
     ret = ef.execute()
     var = field.variables['tas']
     actual_value = 6.1078*np.exp(np.log(17.08085)*(var.value-273.16)/(234.175+(var.value-273.16)))
     self.assertNumpyAll(ret['es'].value,actual_value)
예제 #4
0
 def test_calculation_file_only_one_variable(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     field = field[:,0:10,:,:,:]
     expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr,field=field,file_only=True)
     ret = ef.execute()
     self.assertEqual(ret['es']._value,None)
     self.assertEqual(ret['es'].dtype,field.variables['tas'].dtype)
     self.assertEqual(ret['es'].fill_value,field.variables['tas'].fill_value)
예제 #5
0
 def test_calculation_file_only_two_variables(self):
     rd = self.test_data.get_rd('cancm4_tas')
     rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
     field = rd.get()
     field2 = rd2.get()
     field.variables.add_variable(field2.variables['tasmax'],assign_new_uid=True)
     field = field[:,0:10,:,:,:]
     expr = 'foo=log(1000*(tasmax-tas))/3'
     ef = EvalFunction(expr=expr,field=field,file_only=True)
     ret = ef.execute()
     self.assertEqual(ret['foo']._value,None)
예제 #6
0
 def test_calculation_one_variable_exp_and_log(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     # field = field[:, 0:10, :, :, :]
     field = field.get_field_slice({'time': slice(0, 10)})
     expr = 'es=6.1078*exp(log(17.08085)*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr, field=field)
     ret = ef.execute()
     var = field['tas']
     actual_value = 6.1078 * np.exp(
         np.log(17.08085) * (var.get_value() - 273.16) /
         (234.175 + (var.get_value() - 273.16)))
     self.assertNumpyAll(ret['es'].get_value(), actual_value)
예제 #7
0
    def test_calculation_file_only_two_variables(self):
        rd = self.test_data.get_rd('cancm4_tas')
        rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
        field = rd.get()
        field2 = rd2.get()

        with orphaned(field2['tasmax']):
            field.add_variable(field2['tasmax'], is_data=True)
        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'foo=log(1000*(tasmax-tas))/3'
        ef = EvalFunction(expr=expr, field=field, file_only=True)
        ret = ef.execute()
        self.assertEqual(ret['foo']._value, None)
예제 #8
0
    def test_calculation_file_only_two_variables(self):
        rd = self.test_data.get_rd('cancm4_tas')
        rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
        field = rd.get()
        field2 = rd2.get()

        with orphaned(field2['tasmax']):
            field.add_variable(field2['tasmax'], is_data=True)
        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'foo=log(1000*(tasmax-tas))/3'
        ef = EvalFunction(expr=expr, field=field, file_only=True)
        ret = ef.execute()
        self.assertEqual(ret['foo']._value, None)
예제 #9
0
    def test_calculation_one_variable_exp_only(self):
        rd = self.test_data.get_rd('cancm4_tas')
        field = rd.get()
        # field = field[:, 0:10, :, :, :]
        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
        ef = EvalFunction(expr=expr, field=field)
        ret = ef.execute()
        self.assertEqual(list(ret.keys()), ['es'])
        self.assertEqual(ret['es'].units, None)
        self.assertEqual(ret['es'].name, 'es')

        var = field['tas']
        actual_value = 6.1078 * np.exp(17.08085 * (var.get_value() - 273.16) / (234.175 + (var.get_value() - 273.16)))
        self.assertNumpyAll(ret['es'].get_value(), actual_value)
예제 #10
0
    def test_calculation_one_variable_exp_only(self):
        rd = self.test_data.get_rd('cancm4_tas')
        field = rd.get()
        # field = field[:, 0:10, :, :, :]
        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
        ef = EvalFunction(expr=expr, field=field)
        ret = ef.execute()
        self.assertEqual(list(ret.keys()), ['es'])
        self.assertEqual(ret['es'].units, None)
        self.assertEqual(ret['es'].name, 'es')

        var = field['tas']
        actual_value = 6.1078 * np.exp(17.08085 * (var.get_value() - 273.16) /
                                       (234.175 + (var.get_value() - 273.16)))
        self.assertNumpyAll(ret['es'].get_value(), actual_value)
예제 #11
0
 def test_calculation_one_variable_exp_only(self):
     rd = self.test_data.get_rd('cancm4_tas')
     field = rd.get()
     field = field[:,0:10,:,:,:]
     expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr,field=field)
     ret = ef.execute()
     self.assertEqual(ret.keys(),['es'])
     self.assertEqual(ret['es'].units,None)
     self.assertEqual(ret['es'].alias,'es')
     self.assertEqual(ret['es'].name,'es')
     self.assertEqual(ret['es'].parents.keys(),['tas'])
     
     var = field.variables['tas']
     actual_value = 6.1078*np.exp(17.08085*(var.value-273.16)/(234.175+(var.value-273.16)))
     self.assertNumpyAll(ret['es'].value,actual_value)
예제 #12
0
 def test_calculation_two_variables_exp_only(self):
     rd = self.test_data.get_rd('cancm4_tas')
     rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
     field = rd.get()
     field2 = rd2.get()
     field.variables.add_variable(field2.variables['tasmax'],assign_new_uid=True)
     field = field[:,0:10,:,:,:]
     expr = 'foo=log(1000*(tasmax-tas))/3'
     ef = EvalFunction(expr=expr,field=field)
     ret = ef.execute()
     self.assertEqual(ret.keys(),['foo'])
     self.assertEqual(set(ret['foo'].parents.keys()),set(['tas','tasmax']))
     
     tas = field.variables['tas']
     tasmax = field.variables['tasmax']
     actual_value = np.log(1000*(tasmax.value-tas.value))/3
     self.assertNumpyAll(ret['foo'].value,actual_value)
예제 #13
0
    def test_calculation_two_variables_exp_only(self):
        rd = self.test_data.get_rd('cancm4_tas')
        rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
        field = rd.get()
        field2 = rd2.get()

        with orphaned(field2['tasmax']):
            field.add_variable(field2['tasmax'], is_data=True)

        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'foo=log(1000*(tasmax-tas))/3'
        ef = EvalFunction(expr=expr, field=field)
        ret = ef.execute()
        self.assertEqual(list(ret.keys()), ['foo'])

        tas = field['tas']
        tasmax = field['tasmax']
        actual_value = np.log(1000 * (tasmax.get_value() - tas.get_value())) / 3
        self.assertNumpyAll(ret['foo'].get_value(), actual_value)
예제 #14
0
    def test_calculation_two_variables_exp_only(self):
        rd = self.test_data.get_rd('cancm4_tas')
        rd2 = self.test_data.get_rd('cancm4_tasmax_2001')
        field = rd.get()
        field2 = rd2.get()

        with orphaned(field2['tasmax']):
            field.add_variable(field2['tasmax'], is_data=True)

        field = field.get_field_slice({'time': slice(0, 10)})
        expr = 'foo=log(1000*(tasmax-tas))/3'
        ef = EvalFunction(expr=expr, field=field)
        ret = ef.execute()
        self.assertEqual(list(ret.keys()), ['foo'])

        tas = field['tas']
        tasmax = field['tasmax']
        actual_value = np.log(1000 *
                              (tasmax.get_value() - tas.get_value())) / 3
        self.assertNumpyAll(ret['foo'].get_value(), actual_value)
예제 #15
0
파일: engine.py 프로젝트: tatarinova/ocgis
    def execute(self,coll,file_only=False,tgds=None):
        '''
        :param :class:~`ocgis.SpatialCollection` coll:
        :param bool file_only:
        :param dict tgds: {'field_alias': :class:`ocgis.interface.base.dimension.temporal.TemporalGroupDimension`,...}
        '''
        
        ## switch field type based on the types of calculations present
        if self._check_calculation_members_(self.funcs,AbstractMultivariateFunction):
            klass = DerivedMultivariateField
        elif self._check_calculation_members_(self.funcs,EvalFunction):
            ## if the input field has more than one variable, assumed this is a 
            ## multivariate calculation
            klass = DerivedField
            for field_container in coll.itervalues():
                for field in field_container.itervalues():
                    if len(field.variables.keys()) > 1:
                        klass = DerivedMultivariateField
                        break
        else:
            klass = DerivedField
        
        ## select which dictionary will hold the temporal group dimensions
        if tgds == None:
            tgds_to_use = self._tgds
            tgds_overloaded = False
        else:
            tgds_to_use = tgds
            tgds_overloaded = True
                                    
        ## group the variables. if grouping is None, calculations are performed
        ## on each element. array computations are taken advantage of.
        if self.grouping is not None:
            ocgis_lh('Setting temporal groups: {0}'.format(self.grouping),'calc.engine')
            for v in coll.itervalues():
                for k2,v2 in v.iteritems():
                    if tgds_overloaded:
                        assert(k2 in tgds_to_use)
                    else:
                        if k2 not in tgds_to_use:
                            tgds_to_use[k2] = v2.temporal.get_grouping(self.grouping)

        ## iterate over functions
        for ugid,dct in coll.iteritems():
            for alias_field,field in dct.iteritems():
                ## choose a representative data type based on the first variable
                dtype = field.variables.values()[0].dtype
                
                new_temporal = tgds_to_use.get(alias_field)
                ## if the engine has a grouping, ensure it is equivalent to the
                ## new temporal dimension.
                if self.grouping is not None:
                    try:
                        compare = set(new_temporal.grouping) == set(self.grouping)
                    ## types may be unhashable, compare directly
                    except TypeError:
                        compare = new_temporal.grouping == self.grouping
                    if compare == False:
                        msg = ('Engine temporal grouping and field temporal grouping '
                               'are not equivalent. Perhaps optimizations are incorrect?')
                        ocgis_lh(logger='calc.engine',exc=ValueError(msg))
                
                out_vc = VariableCollection()
                for f in self.funcs:
                    
                    try:
                        ocgis_lh('Calculating: {0}'.format(f['func']),logger='calc.engine')
                        
                        ## initialize the function
                        function = f['ref'](alias=f['name'],dtype=dtype,field=field,file_only=file_only,vc=out_vc,
                             parms=f['kwds'],tgd=new_temporal,use_raw_values=self.use_raw_values,
                             calc_sample_size=self.calc_sample_size)
                    except KeyError:
                        ## likely an eval function which does not have the name
                        ## key
                        function = EvalFunction(field=field,file_only=file_only,vc=out_vc,
                                                expr=self.funcs[0]['func'])
                        
                    ocgis_lh('calculation initialized',logger='calc.engine',level=logging.DEBUG)
                    
                    ## return the variable collection from the calculations
                    out_vc = function.execute()
                    
                    for dv in out_vc.itervalues():
                        ## any outgoing variables from a calculation must have a 
                        ## data type associated with it
                        try:
                            assert(dv.dtype != None)
                        except AssertionError:
                            assert(isinstance(dv.dtype,np.dtype))
                        ## if this is a file only operation, then there should
                        ## be no values.
                        if file_only:
                            assert(dv._value == None)
                    
                    ocgis_lh('calculation finished',logger='calc.engine',level=logging.DEBUG)
                    
                    ## try to mark progress
                    try:
                        self._progress.mark()
                    except AttributeError:
                        pass
                    
                new_temporal = new_temporal or field.temporal
                new_field = klass(variables=out_vc,temporal=new_temporal,spatial=field.spatial,
                                  level=field.level,realization=field.realization,meta=field.meta,
                                  uid=field.uid,name=field.name)
                coll[ugid][alias_field] = new_field
        return(coll)
예제 #16
0
파일: engine.py 프로젝트: NCPP/ocgis
    def execute(self, coll, file_only=False, tgds=None):
        """
        :param :class:~`ocgis.SpatialCollection` coll:
        :param bool file_only:
        :param dict tgds: {'field_alias': :class:`ocgis.interface.base.dimension.temporal.TemporalGroupDimension`,...}
        """
        from ocgis import VariableCollection

        # Select which dictionary will hold the temporal group dimensions.
        if tgds is None:
            tgds_to_use = self._tgds
            tgds_overloaded = False
        else:
            tgds_to_use = tgds
            tgds_overloaded = True

        # Group the variables. If grouping is None, calculations are performed on each element.
        if self.grouping is not None:
            ocgis_lh('Setting temporal groups: {0}'.format(self.grouping), 'calc.engine')
            for field in coll.iter_fields():
                if tgds_overloaded:
                    assert field.name in tgds_to_use
                else:
                    if field.name not in tgds_to_use:
                        tgds_to_use[field.name] = field.time.get_grouping(self.grouping)

        # Iterate over functions.
        for ugid, container in list(coll.children.items()):
            for field_name, field in list(container.children.items()):
                new_temporal = tgds_to_use.get(field_name)
                if new_temporal is not None:
                    new_temporal = new_temporal.copy()
                # If the engine has a grouping, ensure it is equivalent to the new temporal dimension.
                if self.grouping is not None:
                    try:
                        compare = set(new_temporal.grouping) == set(self.grouping)
                    # Types may be unhashable, compare directly.
                    except TypeError:
                        compare = new_temporal.grouping == self.grouping
                    if not compare:
                        msg = 'Engine temporal grouping and field temporal grouping are not equivalent. Perhaps ' \
                              'optimizations are incorrect?'
                        ocgis_lh(logger='calc.engine', exc=ValueError(msg))

                out_vc = VariableCollection()

                for f in self.funcs:
                    try:
                        ocgis_lh('Calculating: {0}'.format(f['func']), logger='calc.engine')
                        # Initialize the function.
                        function = f['ref'](alias=f['name'], dtype=None, field=field, file_only=file_only, vc=out_vc,
                                            parms=f['kwds'], tgd=new_temporal, calc_sample_size=self.calc_sample_size,
                                            meta_attrs=f.get('meta_attrs'),
                                            spatial_aggregation=self.spatial_aggregation)
                        # Allow a calculation to create a temporal aggregation after initialization.
                        if new_temporal is None and function.tgd is not None:
                            new_temporal = function.tgd.extract()
                    except KeyError:
                        # Likely an eval function which does not have the name key.
                        function = EvalFunction(field=field, file_only=file_only, vc=out_vc, expr=self.funcs[0]['func'],
                                                meta_attrs=self.funcs[0].get('meta_attrs'))

                    ocgis_lh('calculation initialized', logger='calc.engine', level=logging.DEBUG)

                    # Return the variable collection from the calculations.
                    out_vc = function.execute()

                    for dv in out_vc.values():
                        # Any outgoing variables from a calculation must have an associated data type.
                        try:
                            assert dv.dtype is not None
                        except AssertionError:
                            assert isinstance(dv.dtype, np.dtype)
                        # If this is a file only operation, there should be no computed values.
                        if file_only:
                            assert dv._value is None

                    ocgis_lh('calculation finished', logger='calc.engine', level=logging.DEBUG)

                    # Try to mark progress. Okay if it is not there.
                    try:
                        self._progress.mark()
                    except AttributeError:
                        pass

                out_field = function.field.copy()
                function_tag = function.tag

                # Format the returned field. Doing things like removing original data variables and modifying the
                # time dimension if necessary. Field functions handle all field modifications on their own, so bypass
                # in that case.
                if new_temporal is not None:
                    new_temporal = new_temporal.extract()
                format_return_field(function_tag, out_field, new_temporal=new_temporal)

                # Add the calculation variables.
                for variable in list(out_vc.values()):
                    variable = variable.extract()
                    out_field.add_variable(variable)

                # Tag the calculation data as data variables.
                out_field.append_to_tags(function_tag, list(out_vc.keys()))

                # Update the field if there is a CRS. This will ensure accurate tagging of data variables.
                if out_field.crs is not None:
                    # print 'here'
                    out_field.crs.format_spatial_object(out_field)

                coll.children[ugid].children[field_name] = out_field
        return coll
예제 #17
0
파일: engine.py 프로젝트: wk1984/ocgis
    def execute(self, coll, file_only=False, tgds=None):
        """
        :param :class:~`ocgis.SpatialCollection` coll:
        :param bool file_only:
        :param dict tgds: {'field_alias': :class:`ocgis.interface.base.dimension.temporal.TemporalGroupDimension`,...}
        """
        from ocgis import VariableCollection

        # Select which dictionary will hold the temporal group dimensions.
        if tgds is None:
            tgds_to_use = self._tgds
            tgds_overloaded = False
        else:
            tgds_to_use = tgds
            tgds_overloaded = True

        # Group the variables. If grouping is None, calculations are performed on each element.
        if self.grouping is not None:
            ocgis_lh('Setting temporal groups: {0}'.format(self.grouping),
                     'calc.engine')
            for field in coll.iter_fields():
                if tgds_overloaded:
                    assert field.name in tgds_to_use
                else:
                    if field.name not in tgds_to_use:
                        tgds_to_use[field.name] = field.time.get_grouping(
                            self.grouping)

        # Iterate over functions.
        for ugid, container in list(coll.children.items()):
            for field_name, field in list(container.children.items()):
                new_temporal = tgds_to_use.get(field_name)
                if new_temporal is not None:
                    new_temporal = new_temporal.copy()
                # If the engine has a grouping, ensure it is equivalent to the new temporal dimension.
                if self.grouping is not None:
                    try:
                        compare = set(new_temporal.grouping) == set(
                            self.grouping)
                    # Types may be unhashable, compare directly.
                    except TypeError:
                        compare = new_temporal.grouping == self.grouping
                    if not compare:
                        msg = 'Engine temporal grouping and field temporal grouping are not equivalent. Perhaps ' \
                              'optimizations are incorrect?'
                        ocgis_lh(logger='calc.engine', exc=ValueError(msg))

                out_vc = VariableCollection()

                for f in self.funcs:
                    try:
                        ocgis_lh('Calculating: {0}'.format(f['func']),
                                 logger='calc.engine')
                        # Initialize the function.
                        function = f['ref'](
                            alias=f['name'],
                            dtype=None,
                            field=field,
                            file_only=file_only,
                            vc=out_vc,
                            parms=f['kwds'],
                            tgd=new_temporal,
                            calc_sample_size=self.calc_sample_size,
                            meta_attrs=f.get('meta_attrs'),
                            spatial_aggregation=self.spatial_aggregation)
                        # Allow a calculation to create a temporal aggregation after initialization.
                        if new_temporal is None and function.tgd is not None:
                            new_temporal = function.tgd.extract()
                    except KeyError:
                        # Likely an eval function which does not have the name key.
                        function = EvalFunction(
                            field=field,
                            file_only=file_only,
                            vc=out_vc,
                            expr=self.funcs[0]['func'],
                            meta_attrs=self.funcs[0].get('meta_attrs'))

                    ocgis_lh('calculation initialized',
                             logger='calc.engine',
                             level=logging.DEBUG)

                    # Return the variable collection from the calculations.
                    out_vc = function.execute()

                    for dv in out_vc.values():
                        # Any outgoing variables from a calculation must have an associated data type.
                        try:
                            assert dv.dtype is not None
                        except AssertionError:
                            assert isinstance(dv.dtype, np.dtype)
                        # If this is a file only operation, there should be no computed values.
                        if file_only:
                            assert dv._value is None

                    ocgis_lh('calculation finished',
                             logger='calc.engine',
                             level=logging.DEBUG)

                    # Try to mark progress. Okay if it is not there.
                    try:
                        self._progress.mark()
                    except AttributeError:
                        pass

                out_field = function.field.copy()
                function_tag = function.tag

                # Format the returned field. Doing things like removing original data variables and modifying the
                # time dimension if necessary. Field functions handle all field modifications on their own, so bypass
                # in that case.
                if new_temporal is not None:
                    new_temporal = new_temporal.extract()
                format_return_field(function_tag,
                                    out_field,
                                    new_temporal=new_temporal)

                # Add the calculation variables.
                for variable in list(out_vc.values()):
                    variable = variable.extract()
                    out_field.add_variable(variable)

                # Tag the calculation data as data variables.
                out_field.append_to_tags(function_tag, list(out_vc.keys()))

                # Update the field if there is a CRS. This will ensure accurate tagging of data variables.
                if out_field.crs is not None:
                    # print 'here'
                    out_field.crs.format_spatial_object(out_field)

                coll.children[ugid].children[field_name] = out_field
        return coll