def test_scalar_coord(self):
     """Test it works if blend coordinate is scalar. """
     self.cube.add_aux_coord(AuxCoord(1, long_name="scalar_coord", units="no_unit"))
     coord = self.cube.coord("scalar_coord")
     plugin = NonLinearWeights(0.85)
     result = plugin.process(self.cube, coord)
     self.assertArrayAlmostEqual(result.data, np.array([1.0]))
Example #2
0
 def test_fails_input_not_a_cube(self):
     """Test it raises a Value Error if not supplied with a cube. """
     plugin = NonLinearWeights(0.85)
     notacube = 0.0
     msg = "The first argument must be an instance of " "iris.cube.Cube"
     with self.assertRaisesRegex(TypeError, msg):
         plugin.process(notacube, self.coord_name)
 def test_fails_coord_not_in_cube(self):
     """Test it raises a Value Error if coord not in the cube. """
     coord = "notset"
     plugin = NonLinearWeights()
     msg = ('The coord for this plugin must be '
            'an existing coordinate in the input cube')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(self.cube, coord)
 def test_works_if_scalar_coord(self):
     """Test it works if scalar coordinate. """
     self.cube.add_aux_coord(
         AuxCoord(1, long_name='scalar_coord', units='no_unit'))
     coord = self.cube.coord("scalar_coord")
     plugin = NonLinearWeights()
     result = plugin.process(self.cube, coord)
     self.assertArrayAlmostEqual(result.data, np.array([1.0]))
 def test_larger_num(self):
     """Test it works with larger num_of_vals. """
     plugin = NonLinearWeights(cval=0.5)
     cubenew = add_coordinate(self.cube, np.arange(6), "realization", dtype=np.int32)
     coord_name = "realization"
     result = plugin.process(cubenew, coord_name)
     expected_result = np.array(
         [0.50793651, 0.25396825, 0.12698413, 0.06349206, 0.03174603, 0.01587302]
     )
     self.assertArrayAlmostEqual(result.data, expected_result)
 def test_works_with_missing_coord(self):
     """Test it works with missing coord """
     plugin = NonLinearWeights(cval=0.6)
     cubenew = add_realizations(self.cube, 6)
     coord_vals = '0, 1, 2, 3, 4, 5, 6'
     coord_name = 'realization'
     result = plugin.process(cubenew, coord_name, coord_vals)
     expected_result = np.array(
         [0.41472, 0.250112, 0.151347, 0.092088, 0.056533, 0.0352])
     self.assertArrayAlmostEqual(result, expected_result)
 def test_works_with_larger_num(self):
     """Test it works with larger num_of_vals. """
     plugin = NonLinearWeights(cval=0.5)
     cubenew = add_realizations(self.cube, 6)
     coord_name = 'realization'
     coord_vals = ','.join(
         [str(x) for x in cubenew.coord('realization').points])
     result = plugin.process(cubenew, coord_name, coord_vals)
     expected_result = np.array([
         0.50793651, 0.25396825, 0.12698413, 0.06349206, 0.03174603,
         0.01587302
     ])
     self.assertArrayAlmostEqual(result, expected_result)
    def _calculate_blending_weights(self, cube):
        """
        Wrapper for plugins to calculate blending weights by the appropriate
        method.

        Args:
            cube (iris.cube.Cube):
                Cube of input data to be blended

        Returns:
            iris.cube.Cube:
                Cube containing 1D array of weights for blending
        """
        if self.wts_calc_method == "dict":
            if "model" in self.blend_coord:
                config_coord = "model_configuration"
            else:
                config_coord = self.blend_coord

            weights = ChooseWeightsLinear(self.weighting_coord,
                                          self.wts_dict,
                                          config_coord_name=config_coord)(cube)

        elif self.wts_calc_method == "linear":
            weights = ChooseDefaultWeightsLinear(y0val=self.y0val,
                                                 ynval=self.ynval)(
                                                     cube, self.blend_coord)

        elif self.wts_calc_method == "nonlinear":
            weights = ChooseDefaultWeightsNonLinear(self.cval)(
                cube, self.blend_coord, inverse_ordering=self.inverse_ordering)

        return weights
Example #9
0
 def test_values_inverse_ordering(self):
     """Test inverting the order of the input cube produces inverted weights
     order, with the cube and weights cube still matching in dimensions. """
     reference_cube = self.cube.copy()
     plugin = NonLinearWeights(cval=0.85)
     result = plugin.process(
         self.cube, self.coord_name, inverse_ordering=True)
     expected_result = np.array([0.45945946, 0.54054054])
     self.assertArrayAlmostEqual(result.data, expected_result)
     # check input cube blend coordinate order is unchanged
     self.assertArrayEqual(
         self.cube.coord(self.coord_name).points,
         reference_cube.coord(self.coord_name).points)
     # check weights cube and input cube blend coordinate orders match
     self.assertArrayEqual(
         result.coord(self.coord_name).points,
         reference_cube.coord(self.coord_name).points)
 def test_fails_if_cval_not_valid(self):
     """Test it raises a Value Error if cval is not in range,
         cval must be greater than 0.0 and less
         than or equal to 1.0
     """
     plugin = NonLinearWeights(cval=-1.0)
     msg = ('cval must be greater than 0.0 and less '
            'than or equal to 1.0')
     with self.assertRaisesRegexp(ValueError, msg):
         plugin.process(self.cube, self.coord_name, self.coord_vals)
     plugin2 = NonLinearWeights(cval=1.1)
     with self.assertRaisesRegexp(ValueError, msg):
         plugin2.process(self.cube, self.coord_name, self.coord_vals)
Example #11
0
def calculate_blending_weights(cube,
                               blend_coord,
                               method,
                               wts_dict=None,
                               weighting_coord=None,
                               coord_unit=None,
                               y0val=None,
                               ynval=None,
                               cval=None,
                               dict_coord=None):
    """
    Wrapper for plugins to calculate blending weights using the command line
    options specified.

    Args:
        cube (iris.cube.Cube):
            Cube of input data to be blended
        blend_coord (str):
            Coordinate over which blending will be performed (eg "model" for
            grid blending)
        method (str):
            Weights calculation method ("linear", "nonlinear", "dict" or
            "mask")

    Kwargs:
        wts_dict (str):
            File path to json file with parameters for linear weights
            calculation
        weighting_coord (str):
            Coordinate over which linear weights should be calculated from dict
        coord_unit (str or cf_units.Unit):
            Unit of blending coordinate (for default weights plugins)
        y0val (float):
            Intercept parameter for default linear weights plugin
        ynval (float):
            Gradient parameter for default linear weights plugin
        cval (float):
            Parameter for default non-linear weights plugin
        dict_coord (str):
            The coordinate that will be used when accessing the weights from
            the weights dictionary.

    Returns:
        weights (np.ndarray):
            1D array of weights corresponding to slices in ascending order
            of blending coordinate.  (Note: ChooseLinearWeights has the
            option to create a 3D array of spatially-varying weights with the
            "mask" option, however this is not currently supported by the
            blending plugin.)
    """
    # sort input cube by blending coordinate
    cube = sort_coord_in_cube(cube, blend_coord, order="ascending")

    # calculate blending weights
    if method == "dict":
        # calculate linear weights from a dictionary
        with open(wts_dict, 'r') as wts:
            weights_dict = json.load(wts)
        weights_cube = ChooseWeightsLinear(
            weighting_coord, weights_dict,
            config_coord_name=dict_coord).process(cube)

        # sort weights cube by blending coordinate
        weights = sort_coord_in_cube(weights_cube,
                                     blend_coord,
                                     order="ascending")

    elif method == "linear":
        weights = ChooseDefaultWeightsLinear(y0val=y0val, ynval=ynval).process(
            cube, blend_coord, coord_unit=coord_unit)

    elif method == "nonlinear":
        # this is set here rather than in the CLI arguments in order to check
        # for invalid argument combinations
        cvalue = cval if cval else 0.85
        weights = ChooseDefaultWeightsNonLinear(cvalue).process(
            cube, blend_coord, coord_unit=coord_unit)

    return weights
Example #12
0
 def test_cval_equal_one(self):
     """Test it works with cval = 1.0, i.e. equal weights. """
     plugin = NonLinearWeights(cval=1.0)
     result = plugin.process(self.cube, self.coord_name)
     expected_result = np.array([0.5, 0.5])
     self.assertArrayAlmostEqual(result.data, expected_result)
Example #13
0
 def test_values(self):
     """Test weights values. """
     plugin = NonLinearWeights(cval=0.85)
     result = plugin.process(self.cube, self.coord_name)
     expected_result = np.array([0.54054054, 0.45945946])
     self.assertArrayAlmostEqual(result.data, expected_result)
Example #14
0
 def test_array_sum_equals_one(self):
     """Test that the resulting weights add up to one. """
     plugin = NonLinearWeights(0.85)
     result = plugin.process(self.cube, self.coord_name)
     self.assertAlmostEqual(result.data.sum(), 1.0)
Example #15
0
 def test_basic(self):
     """Test that the plugin returns an array of weights. """
     plugin = NonLinearWeights(0.85)
     result = plugin.process(self.cube, self.coord_name)
     self.assertIsInstance(result, iris.cube.Cube)
 def test_basic(self):
     """Test that the plugin returns an array of weights. """
     plugin = NonLinearWeights()
     result = plugin.process(self.cube, self.coord_name, self.coord_vals)
     self.assertIsInstance(result, np.ndarray)
 def test_works_with_default_cval(self):
     """Test it works with default cval. """
     plugin = NonLinearWeights()
     result = plugin.process(self.cube, self.coord_name, self.coord_vals)
     expected_result = np.array([0.54054054, 0.45945946])
     self.assertArrayAlmostEqual(result, expected_result)
 def test_works_if_scalar_coord(self):
     """Test it works if scalar coordinate. """
     coord = self.cube.coord("scalar_coord")
     plugin = NonLinearWeights()
     result = plugin.process(self.cube, coord)
     self.assertArrayAlmostEqual(result, np.array([1.0]))