Пример #1
0
def climatology_3d():
    def jan_offset(day, year):
        dt = (datetime(year, 1, day) - datetime(1970, 1, 1))
        return dt.total_seconds() / (24. * 3600)

    days = range(10, 15)
    years = [[year, year + 10] for year in [2001] * 4]
    days_since = [[jan_offset(day, yr1),
                   jan_offset(day, yr2)]
                  for (day, [yr1, yr2]) in zip(days, years)]
    time_bounds = np.array(days_since)
    time_points = time_bounds[..., 0]

    lon = np.linspace(-25, 25, 5)
    lat = np.linspace(0, 60, 3)

    time_dim = DimCoord(time_points,
                        standard_name='time',
                        bounds=time_bounds,
                        units='days since 1970-01-01 00:00:00-00',
                        climatological=True)
    lon_dim = DimCoord(lon, standard_name='longitude')
    lat_dim = DimCoord(lat, standard_name='latitude')

    data_shape = (len(time_points), len(lat), len(lon))
    values = np.zeros(shape=data_shape, dtype=np.int8)
    cube = Cube(values)
    cube.add_dim_coord(time_dim, 0)
    cube.add_dim_coord(lat_dim, 1)
    cube.add_dim_coord(lon_dim, 2)
    cube.rename('climatology test')
    cube.units = 'Kelvin'
    cube.add_cell_method(CellMethod('mean over years', coords='time'))

    return cube
Пример #2
0
 def test_unknown_method(self):
     cube = Cube([1, 2], long_name="odd_phenomenon")
     cube.add_cell_method(CellMethod(method="oddity", coords=("x",)))
     temp_dirpath = tempfile.mkdtemp()
     try:
         temp_filepath = os.path.join(temp_dirpath, "tmp.nc")
         iris.save(cube, temp_filepath)
         with warnings.catch_warnings(record=True) as warning_records:
             iris.load(temp_filepath)
         # Filter to get the warning we are interested in.
         warning_messages = [record.message for record in warning_records]
         warning_messages = [
             warn
             for warn in warning_messages
             if isinstance(warn, UnknownCellMethodWarning)
         ]
         self.assertEqual(len(warning_messages), 1)
         message = warning_messages[0].args[0]
         msg = (
             "NetCDF variable 'odd_phenomenon' contains unknown cell "
             "method 'oddity'"
         )
         self.assertIn(msg, message)
     finally:
         shutil.rmtree(temp_dirpath)
Пример #3
0
 def test_climatological_mean_single_year(self):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(AuxCoord(standard_name="forecast_period", units="hours", points=36, bounds=[24, 4 * 24]))
     cube.add_aux_coord(
         AuxCoord(standard_name="time", units="hours since epoch", points=240 + 36, bounds=[240 + 24, 240 + 4 * 24])
     )
     cube.add_aux_coord(AuxCoord(long_name="clim_season", points="DUMMY"))
     cube.add_cell_method(CellMethod("DUMMY", "clim_season"))
     field = self.convert_cube_to_field(cube)
     self.assertEqual(field.lbft, 4 * 24)
Пример #4
0
    def create_difference_cube(cube, coord_name, diff_along_axis):
        """
        Put the difference array into a cube with the appropriate
        metadata.

        Parameters
        ----------
        cube : Iris.cube.Cube
            Cube from which the differences have been calculated.
        coord_name : String
            The name of the coordinate over which the difference
            have been calculated.
        diff_along_axis : numpy array
            Array containing the differences.

        Returns
        -------
        diff_cube : Iris.cube.Cube
            Cube containing the differences calculated along the
            specified axis.
        """
        points = cube.coord(coord_name).points
        mean_points = (points[1:] + points[:-1]) / 2

        # Copy cube metadata and coordinates into a new cube.
        # Create a new coordinate for the coordinate along which the
        # difference has been calculated.
        metadata_dict = copy.deepcopy(cube.metadata._asdict())
        diff_cube = Cube(diff_along_axis, **metadata_dict)

        for coord in cube.dim_coords:
            dims = cube.coord_dims(coord)
            if coord.name() in [coord_name]:
                coord = coord.copy(points=mean_points)
            diff_cube.add_dim_coord(coord.copy(), dims)
        for coord in cube.aux_coords:
            dims = cube.coord_dims(coord)
            diff_cube.add_aux_coord(coord.copy(), dims)
        for coord in cube.derived_coords:
            dims = cube.coord_dims(coord)
            diff_cube.add_aux_coord(coord.copy(), dims)

        # Add metadata to indicate that a difference has been calculated.
        # TODO: update this metadata when proper conventions have been
        #       agreed upon.
        cell_method = CellMethod("difference",
                                 coords=[coord_name],
                                 intervals='1 grid length')
        diff_cube.add_cell_method(cell_method)
        diff_cube.attributes["form_of_difference"] = ("forward_difference")
        diff_cube.rename('difference_of_' + cube.name())
        return diff_cube
Пример #5
0
 def test_climatological_mean_single_year(self):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(AuxCoord(standard_name='forecast_period',
                                 units='hours',
                                 points=36, bounds=[24, 4 * 24]))
     cube.add_aux_coord(AuxCoord(standard_name='time',
                                 units='hours since epoch',
                                 points=240 + 36, bounds=[240 + 24,
                                                          240 + 4 * 24]))
     cube.add_aux_coord(AuxCoord(long_name='clim_season', points='DUMMY'))
     cube.add_cell_method(CellMethod('DUMMY', 'clim_season'))
     field = self.convert_cube_to_field(cube)
     self.assertEqual(field.lbft, 4 * 24)
Пример #6
0
 def test_climatological_mean_single_year(self):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(AuxCoord(standard_name='forecast_period',
                                 units='hours',
                                 points=36, bounds=[24, 4 * 24]))
     cube.add_aux_coord(AuxCoord(standard_name='time',
                                 units='hours since epoch',
                                 points=240 + 36, bounds=[240 + 24,
                                                          240 + 4 * 24]))
     cube.add_aux_coord(AuxCoord(long_name='clim_season', points='DUMMY'))
     cube.add_cell_method(CellMethod('DUMMY', 'clim_season'))
     field = self.convert_cube_to_field(cube)
     self.assertEqual(field.lbft, 4 * 24)
Пример #7
0
    def create_difference_cube(self, cube, coord_name, diff_along_axis):
        """
        Put the difference array into a cube with the appropriate
        metadata.

        Args:
            cube (iris.cube.Cube):
                Cube from which the differences have been calculated.
            coord_name (str):
                The name of the coordinate over which the difference
                have been calculated.
            diff_along_axis (numpy.ndarray):
                Array containing the differences.

        Returns:
            iris.cube.Cube:
                Cube containing the differences calculated along the
                specified axis.
        """
        points = cube.coord(coord_name).points
        mean_points = (points[1:] + points[:-1]) / 2

        # Copy cube metadata and coordinates into a new cube.
        # Create a new coordinate for the coordinate along which the
        # difference has been calculated.
        metadata_dict = copy.deepcopy(cube.metadata._asdict())
        diff_cube = Cube(diff_along_axis, **metadata_dict)

        for coord in cube.dim_coords:
            dims = cube.coord_dims(coord)
            if coord.name() in [coord_name]:
                coord = coord.copy(points=mean_points)
            diff_cube.add_dim_coord(coord.copy(), dims)
        for coord in cube.aux_coords:
            dims = cube.coord_dims(coord)
            diff_cube.add_aux_coord(coord.copy(), dims)
        for coord in cube.derived_coords:
            dims = cube.coord_dims(coord)
            diff_cube.add_aux_coord(coord.copy(), dims)

        # Add metadata to indicate that a difference has been calculated.
        # TODO: update metadata for difference and add metadata for gradient
        #       when proper conventions have been agreed upon.
        if not self.is_gradient:
            cell_method = CellMethod("difference",
                                     coords=[coord_name],
                                     intervals="1 grid length")
            diff_cube.add_cell_method(cell_method)
            diff_cube.attributes["form_of_difference"] = "forward_difference"
        diff_cube.rename("difference_of_" + cube.name())
        return diff_cube
Пример #8
0
 def create_cube(self, fp_min, fp_mid, fp_max, ref_offset, season=None):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(AuxCoord(standard_name='forecast_period',
                                 units='hours',
                                 points=fp_mid, bounds=[fp_min, fp_max]))
     cube.add_aux_coord(AuxCoord(standard_name='time',
                                 units='hours since epoch',
                                 points=ref_offset + fp_mid,
                                 bounds=[ref_offset + fp_min,
                                         ref_offset + fp_max]))
     if season:
         cube.add_aux_coord(AuxCoord(long_name='clim_season',
                                     points=season))
         cube.add_cell_method(CellMethod('DUMMY', 'clim_season'))
     return cube
Пример #9
0
 def create_cube(self, fp_min, fp_mid, fp_max, ref_offset, season=None):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(AuxCoord(standard_name='forecast_period',
                                 units='hours',
                                 points=fp_mid, bounds=[fp_min, fp_max]))
     cube.add_aux_coord(AuxCoord(standard_name='time',
                                 units='hours since epoch',
                                 points=ref_offset + fp_mid,
                                 bounds=[ref_offset + fp_min,
                                         ref_offset + fp_max]))
     if season:
         cube.add_aux_coord(AuxCoord(long_name='clim_season',
                                     points=season))
         cube.add_cell_method(CellMethod('DUMMY', 'clim_season'))
     return cube
Пример #10
0
 def create_cube(self, fp_min, fp_mid, fp_max, ref_offset, season=None):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(
         AuxCoord(standard_name="forecast_period", units="hours", points=fp_mid, bounds=[fp_min, fp_max])
     )
     cube.add_aux_coord(
         AuxCoord(
             standard_name="time",
             units="hours since epoch",
             points=ref_offset + fp_mid,
             bounds=[ref_offset + fp_min, ref_offset + fp_max],
         )
     )
     if season:
         cube.add_aux_coord(AuxCoord(long_name="clim_season", points=season))
         cube.add_cell_method(CellMethod("DUMMY", "clim_season"))
     return cube
Пример #11
0
    def _update_metadata(diff_cube: Cube, coord_name: str, cube_name: str) -> None:
        """Rename cube, add attribute and cell method to describe difference.

        Args:
            diff_cube
            coord_name
            cube_name
        """
        # Add metadata to indicate that a difference has been calculated.
        # TODO: update metadata for difference when
        #  proper conventions have been agreed upon.
        cell_method = CellMethod(
            "difference", coords=[coord_name], intervals="1 grid length"
        )
        diff_cube.add_cell_method(cell_method)
        diff_cube.attributes["form_of_difference"] = "forward_difference"
        diff_cube.rename("difference_of_" + cube_name)
Пример #12
0
 def test_section_cell_methods(self):
     cube = Cube([0], long_name="name", units=1)
     cube.add_cell_method(CellMethod("stdev", "area"))
     cube.add_cell_method(
         CellMethod(
             method="mean",
             coords=["y", "time"],
             intervals=["10m", "3min"],
             comments=["vertical", "=duration"],
         ))
     rep = cube_replines(cube)
     # Note: not alphabetical -- provided order is significant
     expected = [
         "name / (1)                          (-- : 1)",
         "    Cell methods:",
         "        stdev                       area",
         "        mean                        y (10m, vertical), time (3min, =duration)",
     ]
     self.assertEqual(rep, expected)
Пример #13
0
 def test_unknown_method(self):
     cube = Cube([1, 2], long_name='odd_phenomenon')
     cube.add_cell_method(CellMethod(method='oddity', coords=('x',)))
     temp_dirpath = tempfile.mkdtemp()
     try:
         temp_filepath = os.path.join(temp_dirpath, 'tmp.nc')
         iris.save(cube, temp_filepath)
         with warnings.catch_warnings(record=True) as warning_records:
             iris.load(temp_filepath)
         # Filter to get the warning we are interested in.
         warning_messages = [record.message for record in warning_records]
         warning_messages = [warn for warn in warning_messages
                             if isinstance(warn, UnknownCellMethodWarning)]
         self.assertEqual(len(warning_messages), 1)
         message = warning_messages[0].args[0]
         msg = ("NetCDF variable 'odd_phenomenon' contains unknown cell "
                "method 'oddity'")
         self.assertIn(msg, message)
     finally:
         shutil.rmtree(temp_dirpath)
Пример #14
0
 def test_climatological_mean_single_year(self):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(
         AuxCoord(
             standard_name="forecast_period",
             units="hours",
             points=36,
             bounds=[24, 4 * 24],
         ))
     cube.add_aux_coord(
         AuxCoord(
             standard_name="time",
             units="hours since epoch",
             points=240 + 36,
             bounds=[240 + 24, 240 + 4 * 24],
         ))
     cube.add_aux_coord(AuxCoord(long_name="clim_season", points="DUMMY"))
     cube.add_cell_method(CellMethod("DUMMY", "clim_season"))
     field = self.convert_cube_to_field(cube)
     self.assertEqual(field.lbft, 4 * 24)
Пример #15
0
 def create_cube(self, fp_min, fp_mid, fp_max, ref_offset, season=None):
     cube = Cube(np.zeros((3, 4)))
     cube.add_aux_coord(
         AuxCoord(
             standard_name="forecast_period",
             units="hours",
             points=fp_mid,
             bounds=[fp_min, fp_max],
         ))
     cube.add_aux_coord(
         AuxCoord(
             standard_name="time",
             units="hours since epoch",
             points=ref_offset + fp_mid,
             bounds=[ref_offset + fp_min, ref_offset + fp_max],
         ))
     if season:
         cube.add_aux_coord(AuxCoord(long_name="clim_season",
                                     points=season))
         cube.add_cell_method(CellMethod("DUMMY", "clim_season"))
     return cube