def test(self):
     metadata = deepcopy(self.metadata)
     angleOfRotation = mock.sentinel.angleOfRotation
     shapeOfTheEarth = mock.sentinel.shapeOfTheEarth
     section = {'latitudeOfSouthernPole': 45000000,
                'longitudeOfSouthernPole': 90000000,
                'angleOfRotation': angleOfRotation,
                'shapeOfTheEarth': shapeOfTheEarth}
     # The called being tested.
     grid_definition_template_5(section, metadata)
     from iris_grib._load_convert import \
         ellipsoid_geometry, \
         ellipsoid, \
         grid_definition_template_4_and_5 as gdt_4_5
     self.assertEqual(ellipsoid_geometry.call_count, 1)
     ellipsoid.assert_called_once_with(shapeOfTheEarth, self.major,
                                       self.minor, self.radius)
     from iris.coord_systems import RotatedGeogCS
     RotatedGeogCS.assert_called_once_with(-45.0, 270.0, angleOfRotation,
                                           self.ellipsoid)
     gdt_4_5.assert_called_once_with(section, metadata, 'grid_latitude',
                                     'grid_longitude', self.cs)
     expected = deepcopy(self.metadata)
     expected['dim_coords_and_dims'].append((self.coord, self.dim))
     self.assertEqual(metadata, expected)
Пример #2
0
 def test(self):
     metadata = deepcopy(self.metadata)
     angleOfRotation = mock.sentinel.angleOfRotation
     shapeOfTheEarth = mock.sentinel.shapeOfTheEarth
     section = {'latitudeOfSouthernPole': 45000000,
                'longitudeOfSouthernPole': 90000000,
                'angleOfRotation': angleOfRotation,
                'shapeOfTheEarth': shapeOfTheEarth}
     # The called being tested.
     grid_definition_template_5(section, metadata)
     from iris.fileformats.grib._load_convert import \
         ellipsoid_geometry, \
         ellipsoid, \
         grid_definition_template_4_and_5 as gdt_4_5
     self.assertEqual(ellipsoid_geometry.call_count, 1)
     ellipsoid.assert_called_once_with(shapeOfTheEarth, self.major,
                                       self.minor, self.radius)
     from iris.coord_systems import RotatedGeogCS
     RotatedGeogCS.assert_called_once_with(-45.0, 270.0, angleOfRotation,
                                           self.ellipsoid)
     gdt_4_5.assert_called_once_with(section, metadata, 'grid_latitude',
                                     'grid_longitude', self.cs)
     expected = deepcopy(self.metadata)
     expected['dim_coords_and_dims'].append((self.coord, self.dim))
     self.assertEqual(metadata, expected)
Пример #3
0
class Test_init(tests.IrisTest):
    def setUp(self):
        self.pole_lon = 171.77
        self.pole_lat = 49.55
        self.rotation_about_new_pole = 180.0
        self.rp_crs = RotatedGeogCS(self.pole_lat, self.pole_lon,
                                    self.rotation_about_new_pole)

    def test_crs_creation(self):
        self.assertEqual(self.pole_lon, self.rp_crs.grid_north_pole_longitude)
        self.assertEqual(self.pole_lat, self.rp_crs.grid_north_pole_latitude)
        self.assertEqual(self.rotation_about_new_pole,
                         self.rp_crs.north_pole_grid_longitude)

    def test_as_cartopy_crs(self):
        if cartopy.__version__ < "0.12":
            with mock.patch("warnings.warn") as warn:
                accrs = self.rp_crs.as_cartopy_crs()
                self.assertEqual(warn.call_count, 1)
        else:
            accrs = self.rp_crs.as_cartopy_crs()
            expected = ccrs.RotatedGeodetic(self.pole_lon, self.pole_lat,
                                            self.rotation_about_new_pole)
            self.assertEqual(
                sorted(accrs.proj4_init.split(" +")),
                sorted(expected.proj4_init.split(" +")),
            )

    def test_as_cartopy_projection(self):
        if cartopy.__version__ < "0.12":
            with mock.patch("warnings.warn") as warn:
                _ = self.rp_crs.as_cartopy_projection()
                self.assertEqual(warn.call_count, 1)
        else:
            accrsp = self.rp_crs.as_cartopy_projection()
            expected = ccrs.RotatedPole(self.pole_lon, self.pole_lat,
                                        self.rotation_about_new_pole)
            self.assertEqual(
                sorted(accrsp.proj4_init.split(" +")),
                sorted(expected.proj4_init.split(" +")),
            )

    def _check_crs_default(self, crs):
        # Check for property defaults when no kwargs options are set.
        # NOTE: except ellipsoid, which is done elsewhere.
        self.assertEqualAndKind(crs.north_pole_grid_longitude, 0.0)

    def test_optional_args_missing(self):
        # Check that unused 'north_pole_grid_longitude' defaults to 0.0.
        crs = RotatedGeogCS(self.pole_lon, self.pole_lat)
        self._check_crs_default(crs)

    def test_optional_args_None(self):
        # Check that 'north_pole_grid_longitude=None' defaults to 0.0.
        crs = RotatedGeogCS(self.pole_lon,
                            self.pole_lat,
                            north_pole_grid_longitude=None)
        self._check_crs_default(crs)
Пример #4
0
    def test_init(self):
        rcs = RotatedGeogCS(30,
                            40,
                            north_pole_grid_longitude=50,
                            ellipsoid=GeogCS(6371229))
        self.assertXMLElement(rcs, ("coord_systems", "RotatedGeogCS_init.xml"))

        rcs = RotatedGeogCS(30, 40, north_pole_grid_longitude=50)
        self.assertXMLElement(rcs,
                              ("coord_systems", "RotatedGeogCS_init_a.xml"))

        rcs = RotatedGeogCS(30, 40)
        self.assertXMLElement(rcs,
                              ("coord_systems", "RotatedGeogCS_init_b.xml"))
 def setup(self, type):
     lon_bounds = (-180, 180)
     lat_bounds = (-90, 90)
     n_lons_src = 20
     n_lats_src = 40
     n_lons_tgt = 20
     n_lats_tgt = 40
     h = 100
     if type == "large source":
         n_lons_src = 100
         n_lats_src = 200
     if type == "large target":
         n_lons_tgt = 100
         n_lats_tgt = 200
     if type == "mixed":
         coord_system_src = RotatedGeogCS(0, 90, 90)
     else:
         coord_system_src = None
     grid = _grid_cube(
         n_lons_src,
         n_lats_src,
         lon_bounds,
         lat_bounds,
         coord_system=coord_system_src,
     )
     tgt = _grid_cube(n_lons_tgt, n_lats_tgt, lon_bounds, lat_bounds)
     src_data = np.arange(n_lats_src * n_lons_src * h).reshape(
         [n_lats_src, n_lons_src, h])
     src = Cube(src_data)
     src.add_dim_coord(grid.coord("latitude"), 0)
     src.add_dim_coord(grid.coord("longitude"), 1)
     self.regridder = ESMFAreaWeightedRegridder(src, tgt)
     self.src = src
Пример #6
0
def realistic_3d():
    """
    Returns a realistic 3d cube.

    >>> print(repr(realistic_3d()))
    <iris 'Cube' of air_potential_temperature (time: 7; grid_latitude: 9;
    grid_longitude: 11)>

    """
    data = np.arange(7*9*11).reshape((7,9,11))
    lat_pts = np.linspace(-4, 4, 9)
    lon_pts = np.linspace(-5, 5, 11)
    time_pts = np.linspace(394200, 394236, 7)
    forecast_period_pts = np.linspace(0, 36, 7)
    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))

    lat = icoords.DimCoord(lat_pts, standard_name='grid_latitude',
                           units='degrees', coord_system=ll_cs)
    lon = icoords.DimCoord(lon_pts, standard_name='grid_longitude',
                           units='degrees', coord_system=ll_cs)
    time = icoords.DimCoord(time_pts, standard_name='time',
                            units='hours since 1970-01-01 00:00:00')
    forecast_period = icoords.DimCoord(forecast_period_pts,
                                       standard_name='forecast_period',
                                       units='hours')
    height = icoords.DimCoord(1000.0, standard_name='air_pressure',
                              units='Pa')
    cube = iris.cube.Cube(data, standard_name='air_potential_temperature',
                          units='K',
                          dim_coords_and_dims=[(time, 0), (lat, 1), (lon, 2)],
                          aux_coords_and_dims=[(forecast_period, 0),
                                               (height, None)],
                          attributes={'source': 'Iris test case'})
    return cube
Пример #7
0
    def test_str(self):
        rcs = RotatedGeogCS(30,
                            40,
                            north_pole_grid_longitude=50,
                            ellipsoid=GeogCS(6371229))
        expected = "RotatedGeogCS(30.0, 40.0, "\
                    "north_pole_grid_longitude=50.0, ellipsoid=GeogCS(6371229.0))"
        self.assertEqual(expected, str(rcs))

        rcs = RotatedGeogCS(30, 40, north_pole_grid_longitude=50)
        expected = "RotatedGeogCS(30.0, 40.0, north_pole_grid_longitude=50.0)"
        self.assertEqual(expected, str(rcs))

        rcs = RotatedGeogCS(30, 40)
        expected = "RotatedGeogCS(30.0, 40.0)"
        self.assertEqual(expected, str(rcs))
 def _default_coord_system(self):
     # Define an alternate, rotated coordinate system to test."
     self.default_ellipsoid = GeogCS(PP_DEFAULT_EARTH_RADIUS)
     cs = RotatedGeogCS(grid_north_pole_latitude=90.0,
                        grid_north_pole_longitude=0.0,
                        ellipsoid=self.default_ellipsoid)
     return cs
 def test__shape_of_earth_spherical(self):
     cs = RotatedGeogCS(grid_north_pole_latitude=90.0,
                        grid_north_pole_longitude=0.0,
                        ellipsoid=GeogCS(52431.0))
     test_cube = self._make_test_cube(cs=cs)
     grid_definition_template_5(test_cube, self.mock_grib)
     self._check_key('shapeOfTheEarth', 1)
     self._check_key('scaleFactorOfRadiusOfSphericalEarth', 0)
     self._check_key('scaledValueOfRadiusOfSphericalEarth', 52431.0)
 def test__rotated_pole(self):
     cs = RotatedGeogCS(grid_north_pole_latitude=75.3,
                        grid_north_pole_longitude=54.321,
                        ellipsoid=self.default_ellipsoid)
     test_cube = self._make_test_cube(cs=cs)
     grid_definition_template_5(test_cube, self.mock_grib)
     self._check_key("latitudeOfSouthernPole", -75300000)
     self._check_key("longitudeOfSouthernPole", 234321000)
     self._check_key("angleOfRotation", 0)
Пример #11
0
 def test_grid_definition_template_5(self):
     # Irregular (variable resolution) rotated lat/lon grid.
     x_points = np.array([0, 2, 7])
     y_points = np.array([1, 3, 6])
     coord_units = '1'
     cs = RotatedGeogCS(34.0, 117.0, ellipsoid=self.ellipsoid)
     test_cube = self._make_test_cube(cs, x_points, y_points, coord_units)
     grid_definition_section(test_cube, self.mock_grib)
     self._check_key('gridDefinitionTemplateNumber', 5)
Пример #12
0
 def test_grid_definition_template_1(self):
     # Rotated lat/lon (Plate Carree).
     x_points = np.arange(3)
     y_points = np.arange(3)
     coord_units = 'degrees'
     cs = RotatedGeogCS(34.0, 117.0, ellipsoid=self.ellipsoid)
     test_cube = self._make_test_cube(cs, x_points, y_points, coord_units)
     grid_definition_section(test_cube, self.mock_grib)
     self._check_key('gridDefinitionTemplateNumber', 1)
Пример #13
0
 def test_alternative_cs(self):
     # Check the result is just the same in a different coordinate system.
     cs = RotatedGeogCS(grid_north_pole_latitude=75.3,
                        grid_north_pole_longitude=102.5,
                        ellipsoid=GeogCS(100.0))
     for cube in (self.src_cube, self.grid_cube):
         for coord_name in ('longitude', 'latitude'):
             cube.coord(coord_name).coord_system = cs
     self._check_expected()
 def test__fail_rotated_pole_nonstandard_meridian(self):
     cs = RotatedGeogCS(grid_north_pole_latitude=90.0,
                        grid_north_pole_longitude=0.0,
                        north_pole_grid_longitude=22.5,
                        ellipsoid=self.default_ellipsoid)
     test_cube = self._make_test_cube(cs=cs)
     with self.assertRaisesRegexp(
             TranslationError,
             'not yet support .* rotated prime meridian.'):
         grid_definition_template_5(test_cube, self.mock_grib)
Пример #15
0
 def test_rotated_geog_cs(self):
     coord_system = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))
     expected = {'grid_mapping_name': b'rotated_latitude_longitude',
                 'north_pole_grid_longitude': 0.0,
                 'grid_north_pole_longitude': 177.5,
                 'grid_north_pole_latitude': 37.5,
                 'longitude_of_prime_meridian': 0.0,
                 'earth_radius': 6371229.0,
                 }
     self._test(coord_system, expected)
Пример #16
0
 def test_rotated_geog_cs(self):
     coord_system = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))
     expected = {
         "grid_mapping_name": b"rotated_latitude_longitude",
         "north_pole_grid_longitude": 0.0,
         "grid_north_pole_longitude": 177.5,
         "grid_north_pole_latitude": 37.5,
         "longitude_of_prime_meridian": 0.0,
         "earth_radius": 6371229.0,
     }
     self._test(coord_system, expected)
Пример #17
0
class Test_init(tests.IrisTest):
    def setUp(self):
        self.pole_lon = 171.77
        self.pole_lat = 49.55
        self.rotation_about_new_pole = 180.0
        self.rp_crs = RotatedGeogCS(self.pole_lat, self.pole_lon,
                                    self.rotation_about_new_pole)

    def test_crs_creation(self):
        self.assertEqual(self.pole_lon, self.rp_crs.grid_north_pole_longitude)
        self.assertEqual(self.pole_lat, self.rp_crs.grid_north_pole_latitude)
        self.assertEqual(self.rotation_about_new_pole,
                         self.rp_crs.north_pole_grid_longitude)

    def test_as_cartopy_crs(self):
        if cartopy.__version__ < "0.12":
            with mock.patch("warnings.warn") as warn:
                accrs = self.rp_crs.as_cartopy_crs()
                self.assertEqual(warn.call_count, 1)
        else:
            accrs = self.rp_crs.as_cartopy_crs()
            expected = ccrs.RotatedGeodetic(self.pole_lon, self.pole_lat,
                                            self.rotation_about_new_pole)
            self.assertEqual(
                sorted(accrs.proj4_init.split(" +")),
                sorted(expected.proj4_init.split(" +")),
            )

    def test_as_cartopy_projection(self):
        if cartopy.__version__ < "0.12":
            with mock.patch("warnings.warn") as warn:
                _ = self.rp_crs.as_cartopy_projection()
                self.assertEqual(warn.call_count, 1)
        else:
            accrsp = self.rp_crs.as_cartopy_projection()
            expected = ccrs.RotatedPole(self.pole_lon, self.pole_lat,
                                        self.rotation_about_new_pole)
            self.assertEqual(
                sorted(accrsp.proj4_init.split(" +")),
                sorted(expected.proj4_init.split(" +")),
            )
def test_rotated_regridding():
    """
    Test for :func:`esmf_regrid.schemes.regrid_rectilinear_to_rectilinear`.

    Test the regriding of a rotated pole coordinate system. The test is
    designed to that it should be possible to verify the result by
    inspection.
    """
    src_coord_system = RotatedGeogCS(0, 90, 90)
    tgt_coord_system = None

    n_lons = 4
    n_lats = 4
    lon_bounds = (-180, 180)
    lat_bounds = (-90, 90)

    src = _grid_cube(
        n_lons,
        n_lats,
        lon_bounds,
        lat_bounds,
        circular=True,
        coord_system=src_coord_system,
    )
    tgt = _grid_cube(
        n_lons,
        n_lats,
        lon_bounds,
        lat_bounds,
        circular=True,
        coord_system=tgt_coord_system,
    )
    src_data = np.arange(n_lons * n_lats).reshape([n_lats, n_lons])
    # src_mask = np.empty([n_lats, n_lons])
    # src_mask[:] = np.array([1, 0, 0, 1])[:, np.newaxis]
    src_mask = np.array([[1, 1, 1, 1], [0, 0, 0, 0], [0, 0, 0, 0],
                         [1, 1, 1, 1]])
    src_data = ma.array(src_data, mask=src_mask)
    src.data = src_data

    no_mdtol_result = regrid_rectilinear_to_rectilinear(src, tgt)

    full_mdtol_result = regrid_rectilinear_to_rectilinear(src, tgt, mdtol=1)

    expected_data = np.array([[5, 4, 8, 9], [5, 4, 8, 9], [6, 7, 11, 10],
                              [6, 7, 11, 10]])
    expected_mask = np.array([[0, 0, 0, 0], [1, 1, 1, 1], [1, 1, 1, 1],
                              [0, 0, 0, 0]])
    no_mdtol_expected_data = ma.array(expected_data, mask=expected_mask)

    # Lenient check for data.
    assert np.allclose(no_mdtol_expected_data, no_mdtol_result.data)
    assert np.allclose(expected_data, full_mdtol_result.data)
 def test__shape_of_earth_flattened(self):
     ellipsoid = GeogCS(semi_major_axis=1456.0, semi_minor_axis=1123.0)
     cs = RotatedGeogCS(grid_north_pole_latitude=90.0,
                        grid_north_pole_longitude=0.0,
                        ellipsoid=ellipsoid)
     test_cube = self._make_test_cube(cs=cs)
     grid_definition_template_5(test_cube, self.mock_grib)
     self._check_key('shapeOfTheEarth', 7)
     self._check_key('scaleFactorOfEarthMajorAxis', 0)
     self._check_key('scaledValueOfEarthMajorAxis', 1456.0)
     self._check_key('scaleFactorOfEarthMinorAxis', 0)
     self._check_key('scaledValueOfEarthMinorAxis', 1123.0)
Пример #20
0
class Test_init(tests.IrisTest):
    def setUp(self):
        self.pole_lon = 171.77
        self.pole_lat = 49.55
        self.rotation_about_new_pole = 180.0
        self.rp_crs = RotatedGeogCS(self.pole_lat, self.pole_lon,
                                    self.rotation_about_new_pole)

    def test_crs_creation(self):
        self.assertEqual(self.pole_lon, self.rp_crs.grid_north_pole_longitude)
        self.assertEqual(self.pole_lat, self.rp_crs.grid_north_pole_latitude)
        self.assertEqual(self.rotation_about_new_pole,
                         self.rp_crs.north_pole_grid_longitude)

    def test_as_cartopy_crs(self):
        if cartopy.__version__ < '0.12':
            with mock.patch('warnings.warn') as warn:
                accrs = self.rp_crs.as_cartopy_crs()
                self.assertEqual(warn.call_count, 1)
        else:
            accrs = self.rp_crs.as_cartopy_crs()
            expected = ccrs.RotatedGeodetic(self.pole_lon, self.pole_lat,
                                            self.rotation_about_new_pole)
            self.assertEqual(sorted(accrs.proj4_init.split(' +')),
                             sorted(expected.proj4_init.split(' +')))

    def test_as_cartopy_projection(self):
        if cartopy.__version__ < '0.12':
            with mock.patch('warnings.warn') as warn:
                accrs = self.rp_crs.as_cartopy_projection()
                self.assertEqual(warn.call_count, 1)
        else:
            accrsp = self.rp_crs.as_cartopy_projection()
            expected = ccrs.RotatedPole(self.pole_lon, self.pole_lat,
                                        self.rotation_about_new_pole)
            self.assertEqual(sorted(accrsp.proj4_init.split(' +')),
                             sorted(expected.proj4_init.split(' +')))
Пример #21
0
    def test_rotated_geog_cs(self):
        coord_system = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))
        cube = self.cube_with_cs(coord_system)
        expected = {'grid_mapping_name': 'rotated_latitude_longitude',
                    'north_pole_grid_longitude': 0.0,
                    'grid_north_pole_longitude': 177.5,
                    'grid_north_pole_latitude': 37.5,
                    'longitude_of_prime_meridian': 0.0,
                    'earth_radius': 6371229.0,
                    }

        grid_variable = self.construct_cf_grid_mapping_variable(cube)
        actual = self.variable_attributes(grid_variable)

        # To see obvious differences, check that they keys are the same.
        self.assertEqual(sorted(actual.keys()), sorted(expected.keys()))
        # Now check that the values are equivalent.
        self.assertEqual(actual, expected)
Пример #22
0
def _generate_extended_cube():
    cube_list = iris.cube.CubeList()
    lower_bound = 0
    upper_bound = 70
    period = 70
    data = np.arange(70 * 9 * 11).reshape((70, 9, 11))
    lat_pts = np.linspace(-4, 4, 9)
    lon_pts = np.linspace(-5, 5, 11)
    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))
    for i in range(0, 100):
        time_pts = np.linspace(lower_bound, upper_bound - 1, 70)
        lat = icoords.DimCoord(
            lat_pts,
            standard_name="grid_latitude",
            units="degrees",
            coord_system=ll_cs,
        )
        lon = icoords.DimCoord(
            lon_pts,
            standard_name="grid_longitude",
            units="degrees",
            coord_system=ll_cs,
        )
        time = icoords.DimCoord(
            time_pts,
            standard_name="time",
            units="days since 1970-01-01 00:00:00"
        )
        cube = iris.cube.Cube(
            data,
            standard_name="air_potential_temperature",
            units="K",
            dim_coords_and_dims=[(time, 0),
                                 (lat, 1),
                                 (lon, 2)],
            attributes={"source": "Iris test case"},
        )
        lower_bound = lower_bound + 70
        upper_bound = upper_bound + 70
        period = period + 70
        cube_list.append(cube)
    cube = cube_list.concatenate_cube()
    return cube
Пример #23
0
    def external(*args, **kwargs):
        """
        Prep and call _grid_cube, saving to a NetCDF file.

        Saving to a file allows the original python executable to pick back up.

        Remember that all arguments must work as strings, hence the fresh
        construction of a ``coord_system`` within the function.

        """
        from iris import save
        from iris.coord_systems import RotatedGeogCS

        from esmf_regrid.tests.unit.schemes.test__cube_to_GridInfo import (
            _grid_cube as original,
        )

        save_path = kwargs.pop("save_path")

        if kwargs.pop("alt_coord_system"):
            kwargs["coord_system"] = RotatedGeogCS(0, 90, 90)

        cube = original(*args, **kwargs)
        save(cube, save_path)
def realistic_3d():
    data = np.arange(7 * 9 * 11).reshape((7, 9, 11))
    lat_pts = np.linspace(-4, 4, 9)
    lon_pts = np.linspace(-5, 5, 11)
    time_pts = np.linspace(394200, 394236, 7)
    forecast_period_pts = np.linspace(0, 36, 7)
    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))

    lat = icoords.DimCoord(
        lat_pts,
        standard_name="grid_latitude",
        units="degrees",
        coord_system=ll_cs,
    )
    lon = icoords.DimCoord(
        lon_pts,
        standard_name="grid_longitude",
        units="degrees",
        coord_system=ll_cs,
    )
    time = icoords.DimCoord(time_pts,
                            standard_name="time",
                            units="hours since 1970-01-01 00:00:00")
    forecast_period = icoords.DimCoord(forecast_period_pts,
                                       standard_name="forecast_period",
                                       units="hours")
    height = icoords.DimCoord(1000.0, standard_name="air_pressure", units="Pa")
    cube = iris.cube.Cube(
        data,
        standard_name="air_potential_temperature",
        units="K",
        dim_coords_and_dims=[(time, 0), (lat, 1), (lon, 2)],
        aux_coords_and_dims=[(forecast_period, 0), (height, None)],
        attributes={"source": "Iris test case"},
    )
    return cube
Пример #25
0
 def test_optional_args_None(self):
     # Check that 'north_pole_grid_longitude=None' defaults to 0.0.
     crs = RotatedGeogCS(self.pole_lon,
                         self.pole_lat,
                         north_pole_grid_longitude=None)
     self._check_crs_default(crs)
Пример #26
0
 def setUp(self):
     self.pole_lon = 171.77
     self.pole_lat = 49.55
     self.rotation_about_new_pole = 180.0
     self.rp_crs = RotatedGeogCS(self.pole_lat, self.pole_lon,
                                 self.rotation_about_new_pole)
Пример #27
0
def realistic_4d():
    """
    Returns a realistic 4d cube.

    >>> print(repr(realistic_4d()))
    <iris 'Cube' of air_potential_temperature (time: 6; model_level_number: 70;
    grid_latitude: 100; grid_longitude: 100)>

    """
    data_path = tests.get_data_path(('stock', 'stock_arrays.npz'))
    if not os.path.isfile(data_path):
        raise IOError('Test data is not available at {}.'.format(data_path))
    r = np.load(data_path)
    # sort the arrays based on the order they were originally given.
    # The names given are of the form 'arr_1' or 'arr_10'
    _, arrays = zip(*sorted(r.items(), key=lambda item: int(item[0][4:])))

    lat_pts, lat_bnds, lon_pts, lon_bnds, level_height_pts, \
        level_height_bnds, model_level_pts, sigma_pts, sigma_bnds, time_pts, \
        _source_pts, forecast_period_pts, data, orography = arrays

    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))

    lat = icoords.DimCoord(lat_pts,
                           standard_name='grid_latitude',
                           units='degrees',
                           bounds=lat_bnds,
                           coord_system=ll_cs)
    lon = icoords.DimCoord(lon_pts,
                           standard_name='grid_longitude',
                           units='degrees',
                           bounds=lon_bnds,
                           coord_system=ll_cs)
    level_height = icoords.DimCoord(level_height_pts,
                                    long_name='level_height',
                                    units='m',
                                    bounds=level_height_bnds,
                                    attributes={'positive': 'up'})
    model_level = icoords.DimCoord(model_level_pts,
                                   standard_name='model_level_number',
                                   units='1',
                                   attributes={'positive': 'up'})
    sigma = icoords.AuxCoord(sigma_pts,
                             long_name='sigma',
                             units='1',
                             bounds=sigma_bnds)
    orography = icoords.AuxCoord(orography,
                                 standard_name='surface_altitude',
                                 units='m')
    time = icoords.DimCoord(time_pts,
                            standard_name='time',
                            units='hours since 1970-01-01 00:00:00')
    forecast_period = icoords.DimCoord(forecast_period_pts,
                                       standard_name='forecast_period',
                                       units='hours')

    hybrid_height = iris.aux_factory.HybridHeightFactory(
        level_height, sigma, orography)

    cube = iris.cube.Cube(data,
                          standard_name='air_potential_temperature',
                          units='K',
                          dim_coords_and_dims=[(time, 0), (model_level, 1),
                                               (lat, 2), (lon, 3)],
                          aux_coords_and_dims=[(orography, (2, 3)),
                                               (level_height, 1), (sigma, 1),
                                               (forecast_period, None)],
                          attributes={'source': 'Iris test case'},
                          aux_factories=[hybrid_height])
    return cube
Пример #28
0
 def setUp(self):
     self.pole_lon = 171.77
     self.pole_lat = 49.55
     self.rotation_about_new_pole = 180.0
     self.rp_crs = RotatedGeogCS(self.pole_lat, self.pole_lon,
                                 self.rotation_about_new_pole)
Пример #29
0
def sample_2d_latlons(regional=False, rotated=False, transformed=False):
    """
    Construct small 2d cubes with 2d X and Y coordinates.

    This makes cubes with 'expanded' coordinates (4 bounds per cell), analagous
    to ORCA data.
    The coordinates are always geographical, so either it has a coord system
    or they are "true" lats + lons.
    ( At present, they are always latitudes and longitudes, but maybe in a
    rotated system. )
    The results always have fully contiguous bounds.

    Kwargs:
    * regional (bool):
        If False (default), results cover the whole globe, and there is
        implicit connectivity between rhs + lhs of the array.
        If True, coverage is regional and edges do not connect.
    * rotated (bool):
        If False, X and Y coordinates are true-latitudes and longitudes, with
        an implicit coordinate system (i.e. None).
        If True, the X and Y coordinates are lats+lons in a selected
        rotated-latlon coordinate system.
    * transformed (bool):
        Build coords from rotated coords as for 'rotated', but then replace
        their values with the equivalent "true" lats + lons, and no
        coord-system (defaults to true-latlon).
        In this case, the X and Y coords are no longer 'meshgrid' style,
        i.e. the points + bounds values vary in *both* dimensions.

    .. note::

        'transformed' is an alternative to 'rotated' :  when 'transformed' is
        set, then 'rotated' has no effect.

    .. Some sample results printouts ::

        >>> print(sample_2d_latlons())
        test_data / (unknown)               (-- : 5; -- : 6)
             Auxiliary coordinates:
                  latitude                      x       x
                  longitude                     x       x
        >>>
        >>> print(sample_2d_latlons().coord(axis='x')[0, :2])
        AuxCoord(array([ 37.5 ,  93.75]),
                 bounds=array([[   0.   ,   65.625,   65.625,    0.   ],
                               [  65.625,  121.875,  121.875,   65.625]]),
                 standard_name='longitude', units=Unit('degrees'))
        >>> print(np.round(sample_2d_latlons().coord(axis='x').points, 3))
        [[  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]]
        >>> print(np.round(sample_2d_latlons().coord(axis='y').points, 3))
        [[-85.  -85.  -85.  -85.  -85.  -85. ]
         [-47.5 -47.5 -47.5 -47.5 -47.5 -47.5]
         [-10.  -10.  -10.  -10.  -10.  -10. ]
         [ 27.5  27.5  27.5  27.5  27.5  27.5]
         [ 65.   65.   65.   65.   65.   65. ]]


        >>> print(np.round(
            sample_2d_latlons(rotated=True).coord(axis='x').points, 3))
        [[  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]
         [  37.5    93.75  150.    206.25  262.5   318.75]]
        >>> print(sample_2d_latlons(rotated=True).coord(axis='y').coord_system)
        RotatedGeogCS(75.0, 120.0)


        >>> print(
            sample_2d_latlons(transformed=True).coord(axis='y').coord_system)
        None
        >>> print(np.round(
            sample_2d_latlons(transformed=True).coord(axis='x').points, 3))
        [[ -50.718  -40.983  -46.74   -71.938  -79.293  -70.146]
         [ -29.867   17.606   77.936  157.145 -141.037  -93.172]
         [ -23.139   31.007   87.699  148.322 -154.639 -100.505]
         [ -16.054   41.218   92.761  143.837 -164.738 -108.105]
         [  10.86    61.78   100.236  137.285  175.511 -135.446]]
        >>> print(np.round(
            sample_2d_latlons(transformed=True).coord(axis='y').points, 3))
        [[-70.796 -74.52  -79.048 -79.26  -74.839 -70.96 ]
         [-34.99  -46.352 -59.721 -60.34  -47.305 -35.499]
         [  1.976 -10.626 -22.859 -23.349 -11.595   1.37 ]
         [ 38.914  25.531  14.312  13.893  24.585  38.215]
         [ 74.197  60.258  51.325  51.016  59.446  73.268]]
        >>>

    """
    def sample_cube(xargs, yargs):
        # Make a test cube with given latitude + longitude coordinates.
        # xargs/yargs are args for np.linspace (start, stop, N), to make the X
        # and Y coordinate points.
        x0, x1, nx = xargs
        y0, y1, ny = yargs
        # Data has cycling values, staggered a bit in successive rows.
        data = np.zeros((ny, nx))
        data.flat[:] = np.arange(ny * nx) % (nx + 2)
        # Build a 2d cube with longitude + latitude coordinates.
        cube = Cube(data, long_name="test_data")
        x_pts = np.linspace(x0, x1, nx, endpoint=True)
        y_pts = np.linspace(y0, y1, ny, endpoint=True)
        co_x = DimCoord(x_pts, standard_name="longitude", units="degrees")
        co_y = DimCoord(y_pts, standard_name="latitude", units="degrees")
        cube.add_dim_coord(co_y, 0)
        cube.add_dim_coord(co_x, 1)
        return cube

    # Start by making a "normal" cube with separate 1-D X and Y coords.
    if regional:
        # Make a small regional cube.
        cube = sample_cube(xargs=(150.0, 243.75, 6), yargs=(-10.0, 40.0, 5))

        # Add contiguous bounds.
        for ax in ("x", "y"):
            cube.coord(axis=ax).guess_bounds()
    else:
        # Global data, but at a drastically reduced resolution.
        cube = sample_cube(xargs=(37.5, 318.75, 6), yargs=(-85.0, 65.0, 5))

        # Make contiguous bounds and adjust outer edges to ensure it is global.
        for name in ("longitude", "latitude"):
            coord = cube.coord(name)
            coord.guess_bounds()
            bds = coord.bounds.copy()
            # Make bounds global, by fixing lowest and uppermost values.
            if name == "longitude":
                bds[0, 0] = 0.0
                bds[-1, 1] = 360.0
            else:
                bds[0, 0] = -90.0
                bds[-1, 1] = 90.0
            coord.bounds = bds

    # Now convert the 1-d coords to 2-d equivalents.
    # Get original 1-d coords.
    co_1d_x, co_1d_y = [cube.coord(axis=ax).copy() for ax in ("x", "y")]

    # Calculate 2-d equivalents.
    co_2d_x, co_2d_y = grid_coords_2d_from_1d(co_1d_x, co_1d_y)

    # Remove the old grid coords.
    for coord in (co_1d_x, co_1d_y):
        cube.remove_coord(coord)

    # Add the new grid coords.
    for coord in (co_2d_x, co_2d_y):
        cube.add_aux_coord(coord, (0, 1))

    if transformed or rotated:
        # Put the cube locations into a rotated coord system.
        pole_lat, pole_lon = 75.0, 120.0
        if transformed:
            # Reproject coordinate values from rotated to true lat-lons.
            co_x, co_y = [cube.coord(axis=ax) for ax in ("x", "y")]
            # Unrotate points.
            lons, lats = co_x.points, co_y.points
            lons, lats = unrotate_pole(lons, lats, pole_lon, pole_lat)
            co_x.points, co_y.points = lons, lats
            # Unrotate bounds.
            lons, lats = co_x.bounds, co_y.bounds
            # Note: save the shape, flatten + then re-apply the shape, because
            # "unrotate_pole" uses "cartopy.crs.CRS.transform_points", which
            # only works on arrays of 1 or 2 dimensions.
            shape = lons.shape
            lons, lats = unrotate_pole(lons.flatten(), lats.flatten(),
                                       pole_lon, pole_lat)
            co_x.bounds, co_y.bounds = lons.reshape(shape), lats.reshape(shape)
        else:
            # "Just" rotate operation : add a coord-system to each coord.
            cs = RotatedGeogCS(pole_lat, pole_lon)
            for coord in cube.coords():
                coord.coord_system = cs

    return cube
Пример #30
0
def realistic_4d():
    """
    Returns a realistic 4d cube.

    >>> print(repr(realistic_4d()))
    <iris 'Cube' of air_potential_temperature (time: 6; model_level_number: 70;
    grid_latitude: 100; grid_longitude: 100)>

    """
    data_path = tests.get_data_path(("stock", "stock_arrays.npz"))
    if not os.path.isfile(data_path):
        raise IOError("Test data is not available at {}.".format(data_path))
    r = np.load(data_path)
    # sort the arrays based on the order they were originally given.
    # The names given are of the form 'arr_1' or 'arr_10'
    _, arrays = zip(*sorted(r.items(), key=lambda item: int(item[0][4:])))

    (
        lat_pts,
        lat_bnds,
        lon_pts,
        lon_bnds,
        level_height_pts,
        level_height_bnds,
        model_level_pts,
        sigma_pts,
        sigma_bnds,
        time_pts,
        _source_pts,
        forecast_period_pts,
        data,
        orography,
    ) = arrays

    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))

    lat = icoords.DimCoord(
        lat_pts,
        standard_name="grid_latitude",
        units="degrees",
        bounds=lat_bnds,
        coord_system=ll_cs,
    )
    lon = icoords.DimCoord(
        lon_pts,
        standard_name="grid_longitude",
        units="degrees",
        bounds=lon_bnds,
        coord_system=ll_cs,
    )
    level_height = icoords.DimCoord(
        level_height_pts,
        long_name="level_height",
        units="m",
        bounds=level_height_bnds,
        attributes={"positive": "up"},
    )
    model_level = icoords.DimCoord(
        model_level_pts,
        standard_name="model_level_number",
        units="1",
        attributes={"positive": "up"},
    )
    sigma = icoords.AuxCoord(sigma_pts,
                             long_name="sigma",
                             units="1",
                             bounds=sigma_bnds)
    orography = icoords.AuxCoord(orography,
                                 standard_name="surface_altitude",
                                 units="m")
    time = icoords.DimCoord(time_pts,
                            standard_name="time",
                            units="hours since 1970-01-01 00:00:00")
    forecast_period = icoords.DimCoord(forecast_period_pts,
                                       standard_name="forecast_period",
                                       units="hours")

    hybrid_height = iris.aux_factory.HybridHeightFactory(
        level_height, sigma, orography)

    cube = iris.cube.Cube(
        data,
        standard_name="air_potential_temperature",
        units="K",
        dim_coords_and_dims=[(time, 0), (model_level, 1), (lat, 2), (lon, 3)],
        aux_coords_and_dims=[
            (orography, (2, 3)),
            (level_height, 1),
            (sigma, 1),
            (forecast_period, None),
        ],
        attributes={"source": "Iris test case"},
        aux_factories=[hybrid_height],
    )
    return cube
Пример #31
0
def realistic_4d():
    """
    Returns a realistic 4d cube.

    >>> print repr(realistic_4d())
    <iris 'Cube' of air_potential_temperature (time: 6; model_level_number: 70; grid_latitude: 100; grid_longitude: 100)>

    """
    # the stock arrays were created in Iris 0.8 with:
    #    >>> fname = iris.sample_data_path('PP', 'COLPEX', 'theta_and_orog_subset.pp')
    #    >>> theta = iris.load_cube(fname, 'air_potential_temperature')
    #    >>> for coord in theta.coords():
    #    ...  print coord.name, coord.has_points(), coord.has_bounds(), coord.units
    #    ...
    #    grid_latitude True True degrees
    #    grid_longitude True True degrees
    #    level_height True True m
    #    model_level True False 1
    #    sigma True True 1
    #    time True False hours since 1970-01-01 00:00:00
    #    source True False no_unit
    #    forecast_period True False hours
    #    >>> arrays = []
    #    >>> for coord in theta.coords():
    #    ...  if coord.has_points(): arrays.append(coord.points)
    #    ...  if coord.has_bounds(): arrays.append(coord.bounds)
    #    >>> arrays.append(theta.data)
    #    >>> arrays.append(theta.coord('sigma').coord_system.orography.data)
    #    >>> np.savez('stock_arrays.npz', *arrays)

    data_path = os.path.join(os.path.dirname(__file__), 'stock_arrays.npz')
    r = np.load(data_path)
    # sort the arrays based on the order they were originally given. The names given are of the form 'arr_1' or 'arr_10'
    _, arrays = zip(*sorted(r.iteritems(), key=lambda item: int(item[0][4:])))

    lat_pts, lat_bnds, lon_pts, lon_bnds, level_height_pts, \
    level_height_bnds, model_level_pts, sigma_pts, sigma_bnds, time_pts, \
    _source_pts, forecast_period_pts, data, orography = arrays

    ll_cs = RotatedGeogCS(37.5, 177.5, ellipsoid=GeogCS(6371229.0))

    lat = icoords.DimCoord(lat_pts,
                           standard_name='grid_latitude',
                           units='degrees',
                           bounds=lat_bnds,
                           coord_system=ll_cs)
    lon = icoords.DimCoord(lon_pts,
                           standard_name='grid_longitude',
                           units='degrees',
                           bounds=lon_bnds,
                           coord_system=ll_cs)
    level_height = icoords.DimCoord(level_height_pts,
                                    long_name='level_height',
                                    units='m',
                                    bounds=level_height_bnds,
                                    attributes={'positive': 'up'})
    model_level = icoords.DimCoord(model_level_pts,
                                   standard_name='model_level_number',
                                   units='1',
                                   attributes={'positive': 'up'})
    sigma = icoords.AuxCoord(sigma_pts,
                             long_name='sigma',
                             units='1',
                             bounds=sigma_bnds)
    orography = icoords.AuxCoord(orography,
                                 standard_name='surface_altitude',
                                 units='m')
    time = icoords.DimCoord(time_pts,
                            standard_name='time',
                            units='hours since 1970-01-01 00:00:00')
    forecast_period = icoords.DimCoord(forecast_period_pts,
                                       standard_name='forecast_period',
                                       units='hours')

    hybrid_height = iris.aux_factory.HybridHeightFactory(
        level_height, sigma, orography)

    cube = iris.cube.Cube(data,
                          standard_name='air_potential_temperature',
                          units='K',
                          dim_coords_and_dims=[(time, 0), (model_level, 1),
                                               (lat, 2), (lon, 3)],
                          aux_coords_and_dims=[(orography, (2, 3)),
                                               (level_height, 1), (sigma, 1),
                                               (forecast_period, None)],
                          attributes={'source': 'Iris test case'},
                          aux_factories=[hybrid_height])
    return cube
Пример #32
0
    def test_multidim(self):
        # Testing with >2D data to demonstrate correct operation over
        # additional non-XY dimensions (including data masking), which is
        # handled by the PointInCell wrapper class.

        # Define a simple target grid first, in plain latlon coordinates.
        plain_latlon_cs = GeogCS(EARTH_RADIUS)
        grid_x_coord = DimCoord(points=[15.0, 25.0, 35.0],
                                bounds=[[10.0, 20.0], [20.0, 30.0],
                                        [30.0, 40.0]],
                                standard_name='longitude',
                                units='degrees',
                                coord_system=plain_latlon_cs)
        grid_y_coord = DimCoord(points=[-30.0, -50.0],
                                bounds=[[-20.0, -40.0], [-40.0, -60.0]],
                                standard_name='latitude',
                                units='degrees',
                                coord_system=plain_latlon_cs)
        grid_cube = Cube(np.zeros((2, 3)))
        grid_cube.add_dim_coord(grid_y_coord, 0)
        grid_cube.add_dim_coord(grid_x_coord, 1)

        # Define some key points in true-lat/lon thta have known positions
        # First 3x2 points in the centre of each output cell.
        x_centres, y_centres = np.meshgrid(grid_x_coord.points,
                                           grid_y_coord.points)
        # An extra point also falling in cell 1, 1
        x_in11, y_in11 = 26.3, -48.2
        # An extra point completely outside the target grid
        x_out, y_out = 70.0, -40.0

        # Define a rotated coord system for the source data
        pole_lon, pole_lat = -125.3, 53.4
        src_cs = RotatedGeogCS(grid_north_pole_latitude=pole_lat,
                               grid_north_pole_longitude=pole_lon,
                               ellipsoid=plain_latlon_cs)

        # Concatenate all the testpoints in a flat array, and find the rotated
        # equivalents.
        xx = list(x_centres.flat[:]) + [x_in11, x_out]
        yy = list(y_centres.flat[:]) + [y_in11, y_out]
        xx, yy = rotate_pole(lons=np.array(xx),
                             lats=np.array(yy),
                             pole_lon=pole_lon,
                             pole_lat=pole_lat)
        # Define handy index numbers for all these.
        i00, i01, i02, i10, i11, i12, i_in, i_out = range(8)

        # Build test data in the shape Z,YX = (3, 8)
        data = [[1, 2, 3, 11, 12, 13, 7, 99], [1, 2, 3, 11, 12, 13, 7, 99],
                [7, 6, 5, 51, 52, 53, 12, 1]]
        mask = [[0, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 1, 0],
                [0, 0, 0, 0, 0, 0, 0, 0]]
        src_data = np.ma.array(data, mask=mask, dtype=float)

        # Make the source cube.
        src_cube = Cube(src_data)
        src_x = AuxCoord(xx,
                         standard_name='grid_longitude',
                         units='degrees',
                         coord_system=src_cs)
        src_y = AuxCoord(yy,
                         standard_name='grid_latitude',
                         units='degrees',
                         coord_system=src_cs)
        src_z = DimCoord(np.arange(3), long_name='z')
        src_cube.add_dim_coord(src_z, 0)
        src_cube.add_aux_coord(src_x, 1)
        src_cube.add_aux_coord(src_y, 1)
        # Add in some extra metadata, to ensure it gets copied over.
        src_cube.add_aux_coord(DimCoord([0], long_name='extra_scalar_coord'))
        src_cube.attributes['extra_attr'] = 12.3

        # Define what the expected answers should be, shaped (3, 2, 3).
        expected_result = [
            [[1.0, 2.0, 3.0], [11.0, 0.5 * (12 + 7), 13.0]],
            [[1.0, -999, 3.0], [11.0, 12.0, 13.0]],
            [[7.0, 6.0, 5.0], [51.0, 0.5 * (52 + 12), 53.0]],
        ]
        expected_result = np.ma.masked_less(expected_result, 0)

        # Perform the calculation with the regridder.
        regridder = Regridder(src_cube, grid_cube)

        # Check all is as expected.
        result = regridder(src_cube)
        self.assertEqual(result.coord('z'), src_cube.coord('z'))
        self.assertEqual(result.coord('extra_scalar_coord'),
                         src_cube.coord('extra_scalar_coord'))
        self.assertEqual(result.coord('longitude'),
                         grid_cube.coord('longitude'))
        self.assertEqual(result.coord('latitude'), grid_cube.coord('latitude'))
        self.assertMaskedArrayAlmostEqual(result.data, expected_result)
Пример #33
0
 def test_rotated(self):
     cs = RotatedGeogCS(30, 40, ellipsoid=GeogCS(6371229))
     self.assertXMLElement(cs,
                           ("coord_systems", "CoordSystem_xml_element.xml"))