def test_check_exception_is_raised(self):
     """
     Test that the expected results are returned for the bounds_pairing.
     """
     cube_name = "nonsense"
     cube_units = Unit("degreesC")
     msg = "The bounds_pairing_key"
     with self.assertRaisesRegex(KeyError, msg):
         get_bounds_of_distribution(cube_name, cube_units)
 def test_check_data(self):
     """
     Test that the expected results are returned for the bounds_pairing.
     """
     cube_name = "air_temperature"
     cube_units = Unit("degreesC")
     bounds_pairing = (-40, 50)
     result = (get_bounds_of_distribution(cube_name, cube_units))
     self.assertArrayAlmostEqual(result, bounds_pairing)
Esempio n. 3
0
    def process(self, forecast_at_percentiles, no_of_percentiles=None,
                sampling="quantile"):
        """
        1. Concatenates cubes with a percentile coordinate.
        2. Creates a list of percentiles.
        3. Accesses the lower and upper bound pair of the forecast values,
           in order to specify lower and upper bounds for the percentiles.
        4. Interpolate the percentile coordinate into an alternative
           set of percentiles using linear interpolation.

        Args:
            forecast_at_percentiles (Iris CubeList or Iris Cube):
                Cube or CubeList expected to contain a percentile coordinate.
            no_of_percentiles (Integer or None):
                Number of percentiles
                If None, the number of percentiles within the input
                forecast_at_percentiles cube is used as the
                number of percentiles.
            sampling (String):
                Type of sampling of the distribution to produce a set of
                percentiles e.g. quantile or random.

                Accepted options for sampling are:

                * Quantile: A regular set of equally-spaced percentiles aimed
                     at dividing a Cumulative Distribution Function into
                     blocks of equal probability.
                * Random: A random set of ordered percentiles.

        Returns:
            forecast_at_percentiles (iris.cube.Cube):
                Cube with forecast values at the desired set of percentiles.
                The percentile coordinate is always the zeroth dimension.

        """
        forecast_at_percentiles = concatenate_cubes(forecast_at_percentiles)

        percentile_coord = (
            find_percentile_coordinate(forecast_at_percentiles).name())

        if no_of_percentiles is None:
            no_of_percentiles = (
                len(forecast_at_percentiles.coord(
                    percentile_coord).points))

        percentiles = choose_set_of_percentiles(
            no_of_percentiles, sampling=sampling)

        cube_units = forecast_at_percentiles.units
        bounds_pairing = (
            get_bounds_of_distribution(
                forecast_at_percentiles.name(), cube_units))

        forecast_at_percentiles = self._interpolate_percentiles(
            forecast_at_percentiles, percentiles, bounds_pairing,
            percentile_coord)
        return forecast_at_percentiles
Esempio n. 4
0
    def process(self,
                forecast_probabilities,
                no_of_percentiles=None,
                sampling="quantile"):
        """
        1. Concatenates cubes with a threshold coordinate.
        2. Creates a list of percentiles.
        3. Accesses the lower and upper bound pair to find the ends of the
           cumulative distribution function.
        4. Convert the threshold coordinate into
           values at a set of percentiles using linear interpolation,
           see Figure 1 from Flowerdew, 2014.

        Parameters
        ----------
        forecast_probabilities : Iris CubeList or Iris Cube
            Cube or CubeList expected to contain a threshold coordinate.
        no_of_percentiles : Integer or None
            Number of percentiles
            If None, the number of thresholds within the input
            forecast_probabilities cube is used as the number of percentiles.
        sampling : String
            Type of sampling of the distribution to produce a set of
            percentiles e.g. quantile or random.
            Accepted options for sampling are:
            Quantile: A regular set of equally-spaced percentiles aimed
                      at dividing a Cumulative Distribution Function into
                      blocks of equal probability.
            Random: A random set of ordered percentiles.

        Returns
        -------
        forecast_at_percentiles : Iris cube
            Cube with forecast values at the desired set of percentiles.
            The threshold coordinate is always the zeroth dimension.

        """
        forecast_probabilities = concatenate_cubes(forecast_probabilities)
        threshold_coord = forecast_probabilities.coord("threshold")
        phenom_name = (forecast_probabilities.name().replace(
            "probability_of_", ""))

        if no_of_percentiles is None:
            no_of_percentiles = (len(
                forecast_probabilities.coord(threshold_coord.name()).points))

        percentiles = choose_set_of_percentiles(no_of_percentiles,
                                                sampling=sampling)

        cube_units = (forecast_probabilities.coord(
            threshold_coord.name()).units)
        bounds_pairing = (get_bounds_of_distribution(phenom_name, cube_units))

        forecast_at_percentiles = self._probabilities_to_percentiles(
            forecast_probabilities, percentiles, bounds_pairing)
        return forecast_at_percentiles
 def test_check_unit_conversion(self):
     """
     Test that the expected results are returned for the bounds_pairing,
     if the units of the bounds_pairings need to be converted to match
     the units of the forecast.
     """
     cube_name = "air_temperature"
     cube_units = Unit("fahrenheit")
     bounds_pairing = (-40, 122)  # In fahrenheit
     result = (get_bounds_of_distribution(cube_name, cube_units))
     self.assertArrayAlmostEqual(result, bounds_pairing)
Esempio n. 6
0
    def process(self,
                forecast_probabilities,
                no_of_percentiles=None,
                percentiles=None,
                sampling="quantile"):
        """
        1. Concatenates cubes with a threshold coordinate.
        2. Creates a list of percentiles.
        3. Accesses the lower and upper bound pair to find the ends of the
           cumulative distribution function.
        4. Convert the threshold coordinate into
           values at a set of percentiles using linear interpolation,
           see Figure 1 from Flowerdew, 2014.

        Args:
            forecast_probabilities (Iris CubeList or Iris Cube):
                Cube or CubeList expected to contain a threshold coordinate.
            no_of_percentiles (Integer or None):
                Number of percentiles. If None and percentiles is not set,
                the number of thresholds within the input
                forecast_probabilities cube is used as the number of
                percentiles. This argument is mutually exclusive with
                percentiles.
            percentiles (list of floats):
                The desired percentile values in the interval [0, 100].
                This argument is mutually exclusive with no_of_percentiles.
            sampling (String):
                Type of sampling of the distribution to produce a set of
                percentiles e.g. quantile or random.

                Accepted options for sampling are:

                * Quantile: A regular set of equally-spaced percentiles aimed
                          at dividing a Cumulative Distribution Function into
                          blocks of equal probability.
                * Random: A random set of ordered percentiles.

        Returns:
            forecast_at_percentiles (Iris cube):
                Cube with forecast values at the desired set of percentiles.
                The threshold coordinate is always the zeroth dimension.

        """
        if no_of_percentiles is not None and percentiles is not None:
            raise ValueError(
                "Cannot specify both no_of_percentiles and percentiles to "
                "GeneratePercentilesFromProbabilities")

        forecast_probabilities = concatenate_cubes(
            forecast_probabilities,
            coords_to_slice_over="threshold",
            coordinates_for_association=[])

        threshold_coord = forecast_probabilities.coord("threshold")
        phenom_name = (forecast_probabilities.name().replace(
            "probability_of_", ""))

        if no_of_percentiles is None:
            no_of_percentiles = (len(
                forecast_probabilities.coord(threshold_coord.name()).points))

        if percentiles is None:
            percentiles = choose_set_of_percentiles(no_of_percentiles,
                                                    sampling=sampling)
        elif not isinstance(percentiles, (tuple, list)):
            percentiles = [percentiles]
        percentiles = np.array(percentiles, dtype=np.float32)

        cube_units = (forecast_probabilities.coord(
            threshold_coord.name()).units)
        bounds_pairing = (get_bounds_of_distribution(phenom_name, cube_units))

        # If a cube still has multiple realizations, slice over these to reduce
        # the memory requirements into manageable chunks.
        try:
            slices_over_realization = forecast_probabilities.slices_over(
                "realization")
        except CoordinateNotFoundError:
            slices_over_realization = [forecast_probabilities]

        cubelist = iris.cube.CubeList([])
        for cube_realization in slices_over_realization:
            cubelist.append(
                self._probabilities_to_percentiles(cube_realization,
                                                   percentiles,
                                                   bounds_pairing))

        forecast_at_percentiles = cubelist.merge_cube()
        return forecast_at_percentiles
 def test_basic(self):
     """Test that the result is a numpy array."""
     cube_name = "air_temperature"
     cube_units = Unit("degreesC")
     result = get_bounds_of_distribution(cube_name, cube_units)
     self.assertIsInstance(result, np.ndarray)