예제 #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_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)
예제 #3
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)
예제 #4
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)
예제 #5
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)
예제 #6
0
 def test_init(self):
     expr = 'es=6.1078*exp(17.08085*(tas-273.16)/(234.175+(tas-273.16)))'
     ef = EvalFunction(expr=expr)
     self.assertEqual(ef.expr, expr)
예제 #7
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