Example #1
0
 def test_as_cartopy_crs(self):
     cs = GeogCS(6543210, 6500000)
     res = cs.as_cartopy_crs()
     globe = ccrs.Globe(semimajor_axis=6543210.0,
                        semiminor_axis=6500000.0, ellipse=None)
     expected = ccrs.Geodetic(globe)
     self.assertEqual(res, expected)
    def test_float_tolerant_equality(self):
        # Ensure that floating point numbers are treated appropriately when
        # introducing precision difference from wrap_around.
        source = Cube([[1]])
        cs = GeogCS(6371229)

        bounds = np.array([[-91, 0]], dtype="float")
        points = bounds.mean(axis=1)
        lon_coord = DimCoord(
            points,
            bounds=bounds,
            standard_name="longitude",
            units="degrees",
            coord_system=cs,
        )
        source.add_aux_coord(lon_coord, 1)

        bounds = np.array([[-90, 90]], dtype="float")
        points = bounds.mean(axis=1)
        lat_coord = DimCoord(
            points,
            bounds=bounds,
            standard_name="latitude",
            units="degrees",
            coord_system=cs,
        )
        source.add_aux_coord(lat_coord, 0)

        grid = Cube([[0]])
        bounds = np.array([[270, 360]], dtype="float")
        points = bounds.mean(axis=1)
        lon_coord = DimCoord(
            points,
            bounds=bounds,
            standard_name="longitude",
            units="degrees",
            coord_system=cs,
        )
        grid.add_aux_coord(lon_coord, 1)
        grid.add_aux_coord(lat_coord, 0)

        res = regrid(source, grid)
        # The result should be equal to the source data and NOT be masked.
        self.assertArrayEqual(res.data, np.array([1.0]))
Example #3
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
Example #4
0
def lat_lon_cube():
    """
    Returns a cube with a latitude and longitude suitable for testing
    saving to PP/NetCDF etc.

    """
    cube = Cube(np.arange(12, dtype=np.int32).reshape((3, 4)))
    cs = GeogCS(6371229)
    coord = DimCoord(points=np.array([-1, 0, 1], dtype=np.int32),
                     standard_name='latitude',
                     units='degrees',
                     coord_system=cs)
    cube.add_dim_coord(coord, 0)
    coord = DimCoord(points=np.array([-1, 0, 1, 2], dtype=np.int32),
                     standard_name='longitude',
                     units='degrees',
                     coord_system=cs)
    cube.add_dim_coord(coord, 1)
    return cube
Example #5
0
 def test_laea_cs(self):
     coord_system = LambertAzimuthalEqualArea(
         latitude_of_projection_origin=52,
         longitude_of_projection_origin=10,
         false_easting=100,
         false_northing=200,
         ellipsoid=GeogCS(6377563.396, 6356256.909),
     )
     expected = {
         "grid_mapping_name": b"lambert_azimuthal_equal_area",
         "latitude_of_projection_origin": 52,
         "longitude_of_projection_origin": 10,
         "false_easting": 100,
         "false_northing": 200,
         "semi_major_axis": 6377563.396,
         "semi_minor_axis": 6356256.909,
         "longitude_of_prime_meridian": 0,
     }
     self._test(coord_system, expected)
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
Example #7
0
 def test_sphere(self):
     cube = self._cube(GeogCS(6377000))
     with self.temp_filename(".tif") as temp_filename:
         export_geotiff(cube, temp_filename)
         dataset = gdal.Open(temp_filename, gdal.GA_ReadOnly)
         projection_string = dataset.GetProjection()
         # String has embedded floating point values,
         # Test with values to N decimal places, using a regular expression.
         re_pattern = (
             r'GEOGCS\["unknown",DATUM\["unknown",'
             r'SPHEROID\["unknown",637....,0\]\],PRIMEM\["Greenwich",0\],'
             r'UNIT\["degree",0.01745[0-9]*,AUTHORITY\["EPSG","9122"\]\],'
             r'AXIS\["Latitude",NORTH\],AXIS\["Longitude",EAST\]\]')
         re_exp = re.compile(re_pattern)
         self.assertIsNotNone(
             re_exp.match(projection_string),
             "projection string {!r} does not match {!r}".format(
                 projection_string, re_pattern),
         )
Example #8
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)
Example #9
0
    def test_extra_kwargs(self):
        longitude_of_projection_origin = 90.0
        true_scale_lat = 14.0
        ellipsoid = GeogCS(semi_major_axis=6377563.396,
                           semi_minor_axis=6356256.909)

        merc_cs = Mercator(
            longitude_of_projection_origin,
            ellipsoid=ellipsoid,
            standard_parallel=true_scale_lat)

        expected = ccrs.Mercator(
            central_longitude=longitude_of_projection_origin,
            globe=ccrs.Globe(semimajor_axis=6377563.396,
                             semiminor_axis=6356256.909, ellipse=None),
            latitude_true_scale=true_scale_lat)

        res = merc_cs.as_cartopy_projection()
        self.assertEqual(res, expected)
Example #10
0
 def setUp(self):
     path = tests.get_data_path(
         ('NIMROD', 'uk2km', 'WO0000000003452',
          '201007020900_u1096_ng_ey00_visibility0180_screen_2km'))
     self.src = iris.load_cube(path)[0]
     # Cast up to float64, to work around numpy<=1.8 bug with means of
     # arrays of 32bit floats.
     self.src.data = self.src.data.astype(np.float64)
     self.grid = Cube(np.empty((73, 96)))
     cs = GeogCS(6370000)
     lat = DimCoord(np.linspace(46, 65, 73),
                    'latitude',
                    units='degrees',
                    coord_system=cs)
     lon = DimCoord(np.linspace(-14, 8, 96),
                    'longitude',
                    units='degrees',
                    coord_system=cs)
     self.grid.add_dim_coord(lat, 0)
     self.grid.add_dim_coord(lon, 1)
Example #11
0
 def test_lambert_conformal(self):
     coord_system = LambertConformal(
         central_lat=44,
         central_lon=2,
         false_easting=-2,
         false_northing=-5,
         secant_latitudes=(38, 50),
         ellipsoid=GeogCS(6371000),
     )
     expected = {
         "grid_mapping_name": b"lambert_conformal_conic",
         "latitude_of_projection_origin": 44,
         "longitude_of_central_meridian": 2,
         "false_easting": -2,
         "false_northing": -5,
         "standard_parallel": (38, 50),
         "earth_radius": 6371000,
         "longitude_of_prime_meridian": 0,
     }
     self._test(coord_system, expected)
 def setUp(self):
     # A (3, 2, 4) cube with a masked element.
     cube = Cube(np.ma.arange(24, dtype=np.int32).reshape((3, 2, 4)))
     cs = GeogCS(6371229)
     coord = DimCoord(points=np.array([-1, 0, 1], dtype=np.int32),
                      standard_name='latitude',
                      units='degrees',
                      coord_system=cs)
     cube.add_dim_coord(coord, 0)
     coord = DimCoord(points=np.array([-1, 0, 1, 2], dtype=np.int32),
                      standard_name='longitude',
                      units='degrees',
                      coord_system=cs)
     cube.add_dim_coord(coord, 2)
     cube.coord('latitude').guess_bounds()
     cube.coord('longitude').guess_bounds()
     cube.data[1, 1, 2] = ma.masked
     self.src_cube = cube
     # Create (7, 2, 9) grid cube.
     self.grid_cube = _resampled_grid(cube, 2.3, 2.4)
Example #13
0
 def test_aea_cs(self):
     coord_system = AlbersEqualArea(latitude_of_projection_origin=52,
                                    longitude_of_central_meridian=10,
                                    false_easting=100,
                                    false_northing=200,
                                    standard_parallels=(38, 50),
                                    ellipsoid=GeogCS(
                                        6377563.396, 6356256.909))
     expected = {
         'grid_mapping_name': b'albers_conical_equal_area',
         'latitude_of_projection_origin': 52,
         'longitude_of_central_meridian': 10,
         'false_easting': 100,
         'false_northing': 200,
         'standard_parallel': (38, 50),
         'semi_major_axis': 6377563.396,
         'semi_minor_axis': 6356256.909,
         'longitude_of_prime_meridian': 0,
     }
     self._test(coord_system, expected)
Example #14
0
 def test_aea_cs(self):
     coord_system = AlbersEqualArea(
         latitude_of_projection_origin=52,
         longitude_of_central_meridian=10,
         false_easting=100,
         false_northing=200,
         standard_parallels=(38, 50),
         ellipsoid=GeogCS(6377563.396, 6356256.909),
     )
     expected = {
         "grid_mapping_name": b"albers_conical_equal_area",
         "latitude_of_projection_origin": 52,
         "longitude_of_central_meridian": 10,
         "false_easting": 100,
         "false_northing": 200,
         "standard_parallel": (38, 50),
         "semi_major_axis": 6377563.396,
         "semi_minor_axis": 6356256.909,
         "longitude_of_prime_meridian": 0,
     }
     self._test(coord_system, expected)
Example #15
0
    def setUp(self):
        cube = iris.cube.Cube(np.arange(36, dtype=np.int32).reshape((3, 3, 4)))
        cs = GeogCS(6371229)

        coord = iris.coords.DimCoord(
            points=np.array([1, 2, 3], dtype=np.int32), long_name='time')
        cube.add_dim_coord(coord, 0)

        coord = iris.coords.DimCoord(
            points=np.array([-1, 0, 1], dtype=np.int32),
            standard_name='latitude',
            units='degrees',
            coord_system=cs)
        cube.add_dim_coord(coord, 1)
        coord = iris.coords.DimCoord(
            points=np.array([-1, 0, 1, 2], dtype=np.int32),
            standard_name='longitude',
            units='degrees',
            coord_system=cs)
        cube.add_dim_coord(coord, 2)
        self.cube = cube
Example #16
0
    def test_extra_kwargs(self):
        # Check that a projection with non-default values is correctly
        # converted to a cartopy CRS.
        longitude_of_projection_origin = 90.0
        true_scale_lat = 14.0
        ellipsoid = GeogCS(semi_major_axis=6377563.396,
                           semi_minor_axis=6356256.909)

        merc_cs = Mercator(
            longitude_of_projection_origin,
            ellipsoid=ellipsoid,
            standard_parallel=true_scale_lat)

        expected = ccrs.Mercator(
            central_longitude=longitude_of_projection_origin,
            globe=ccrs.Globe(semimajor_axis=6377563.396,
                             semiminor_axis=6356256.909, ellipse=None),
            latitude_true_scale=true_scale_lat)

        res = merc_cs.as_cartopy_crs()
        self.assertEqual(res, expected)
 def test_osgb_to_latlon(self):
     path = tests.get_data_path(
         ('NIMROD', 'uk2km', 'WO0000000003452',
          '201007020900_u1096_ng_ey00_visibility0180_screen_2km'))
     src = iris.load_cube(path)[0]
     src.data = src.data.astype(np.float32)
     grid = Cube(np.empty((73, 96)))
     cs = GeogCS(6370000)
     lat = DimCoord(np.linspace(46, 65, 73),
                    'latitude',
                    units='degrees',
                    coord_system=cs)
     lon = DimCoord(np.linspace(-14, 8, 96),
                    'longitude',
                    units='degrees',
                    coord_system=cs)
     grid.add_dim_coord(lat, 0)
     grid.add_dim_coord(lon, 1)
     result = regrid(src, grid)
     qplt.pcolor(result, antialiased=False)
     qplt.plt.gca().coastlines()
     self.check_graphic()
Example #18
0
def realistic_4d_w_missing_data():
    data_path = tests.get_data_path(('stock', 'stock_mdi_arrays.npz'))
    if not os.path.isfile(data_path):
        raise IOError('Test data is not available at {}.'.format(data_path))
    data_archive = np.load(data_path)
    data = ma.masked_array(data_archive['arr_0'], mask=data_archive['arr_1'])

    # sort the arrays based on the order they were originally given.
    # The names given are of the form 'arr_1' or 'arr_10'

    ll_cs = GeogCS(6371229)

    lat = DimCoord(np.arange(20, dtype=np.float32),
                   standard_name='grid_latitude',
                   units='degrees',
                   coord_system=ll_cs)
    lon = DimCoord(np.arange(20, dtype=np.float32),
                   standard_name='grid_longitude',
                   units='degrees',
                   coord_system=ll_cs)
    time = DimCoord([1000., 1003., 1006.],
                    standard_name='time',
                    units='hours since 1970-01-01 00:00:00')
    forecast_period = DimCoord([0.0, 3.0, 6.0],
                               standard_name='forecast_period',
                               units='hours')
    pressure = DimCoord(np.array([800., 900., 1000.], dtype=np.float32),
                        long_name='pressure',
                        units='hPa')

    cube = iris.cube.Cube(data,
                          long_name='missing data test data',
                          units='K',
                          dim_coords_and_dims=[(time, 0), (pressure, 1),
                                               (lat, 2), (lon, 3)],
                          aux_coords_and_dims=[(forecast_period, 0)],
                          attributes={'source': 'Iris test case'})
    return cube
Example #19
0
    def test_as_cartopy_projection(self):
        latitude_of_projection_origin = -90.0
        longitude_of_projection_origin = -45.0
        false_easting = 100.0
        false_northing = 200.0
        ellipsoid = GeogCS(6377563.396, 6356256.909)

        st = Stereographic(central_lat=latitude_of_projection_origin,
                           central_lon=longitude_of_projection_origin,
                           false_easting=false_easting,
                           false_northing=false_northing,
                           ellipsoid=ellipsoid)
        expected = ccrs.Stereographic(
            central_latitude=latitude_of_projection_origin,
            central_longitude=longitude_of_projection_origin,
            false_easting=false_easting,
            false_northing=false_northing,
            globe=ccrs.Globe(semimajor_axis=6377563.396,
                             semiminor_axis=6356256.909,
                             ellipse=None))

        res = st.as_cartopy_projection()
        self.assertEqual(res, expected)
Example #20
0
    def setUp(self):
        self.cs = GeogCS(6371229)

        # Source cube candidate for regridding.
        cube = Cube(np.arange(12, dtype=np.float32).reshape(3, 4), long_name='unknown')
        cube.units = '1'
        cube.add_dim_coord(DimCoord(np.array([1, 2, 3]), 'latitude', units='degrees', coord_system=self.cs), 0)
        cube.add_dim_coord(DimCoord(np.array([1, 2, 3, 4]), 'longitude', units='degrees', coord_system=self.cs), 1)
        self.source = cube

        # Cube with a smaller grid in latitude and longitude than the source grid by taking the coordinate mid-points.
        cube = Cube(np.arange(6, dtype=np.float).reshape(2, 3))
        cube.units = '1'
        cube.add_dim_coord(DimCoord(np.array([1.5, 2.5]), 'latitude', units='degrees', coord_system=self.cs), 0)
        cube.add_dim_coord(DimCoord(np.array([1.5, 2.5, 3.5]), 'longitude', units='degrees', coord_system=self.cs), 1)
        self.smaller = cube

        # Cube with a larger grid in latitude and longitude than the source grid by taking the coordinate mid-points and extrapolating at extremes.
        cube = Cube(np.arange(20, dtype=np.float).reshape(4, 5))
        cube.units = '1'
        cube.add_dim_coord(DimCoord(np.array([0.5, 1.5, 2.5, 3.5]), 'latitude', units='degrees', coord_system=self.cs), 0)
        cube.add_dim_coord(DimCoord(np.array([0.5, 1.5, 2.5, 3.5, 4.5]), 'longitude', units='degrees', coord_system=self.cs), 1)
        self.larger = cube
Example #21
0
    def setUp(self):
        # Set everything to non-default values.
        self.latitude_of_projection_origin = 0  # For now, Cartopy needs =0.
        self.longitude_of_projection_origin = 123.0
        self.perspective_point_height = 9999.0
        self.sweep_angle_axis = "x"
        self.false_easting = 100.0
        self.false_northing = -200.0

        self.semi_major_axis = 4000.0
        self.semi_minor_axis = 3900.0
        self.ellipsoid = GeogCS(self.semi_major_axis, self.semi_minor_axis)
        self.globe = ccrs.Globe(
            semimajor_axis=self.semi_major_axis,
            semiminor_axis=self.semi_minor_axis,
            ellipse=None,
        )

        # Actual and expected coord system can be re-used for
        # Geostationary.test_crs_creation and test_projection_creation.
        self.expected = ccrs.Geostationary(
            central_longitude=self.longitude_of_projection_origin,
            satellite_height=self.perspective_point_height,
            false_easting=self.false_easting,
            false_northing=self.false_northing,
            globe=self.globe,
            sweep_axis=self.sweep_angle_axis,
        )
        self.geo_cs = Geostationary(
            self.latitude_of_projection_origin,
            self.longitude_of_projection_origin,
            self.perspective_point_height,
            self.sweep_angle_axis,
            self.false_easting,
            self.false_northing,
            self.ellipsoid,
        )
Example #22
0
    def setUp(self):
        self.latitude_of_projection_origin = 0.0
        self.longitude_of_projection_origin = 0.0
        self.perspective_point_height = 35785831.0
        self.sweep_angle_axis = "y"
        self.false_easting = 0.0
        self.false_northing = 0.0

        self.semi_major_axis = 6377563.396
        self.semi_minor_axis = 6356256.909
        self.ellipsoid = GeogCS(self.semi_major_axis, self.semi_minor_axis)
        self.globe = ccrs.Globe(
            semimajor_axis=self.semi_major_axis,
            semiminor_axis=self.semi_minor_axis,
            ellipse=None,
        )

        # Actual and expected coord system can be re-used for
        # Geostationary.test_crs_creation and test_projection_creation.
        self.expected = ccrs.Geostationary(
            central_longitude=self.longitude_of_projection_origin,
            satellite_height=self.perspective_point_height,
            false_easting=self.false_easting,
            false_northing=self.false_northing,
            globe=self.globe,
            sweep_axis=self.sweep_angle_axis,
        )
        self.geo_cs = Geostationary(
            self.latitude_of_projection_origin,
            self.longitude_of_projection_origin,
            self.perspective_point_height,
            self.sweep_angle_axis,
            self.false_easting,
            self.false_northing,
            self.ellipsoid,
        )
Example #23
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
Example #24
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)
Example #25
0
 def test_grid_inconsistent_cs(self):
     ok, bad = self.ok_bad(GeogCS(6370000), GeogCS(6371000))
     with self.assertRaises(ValueError):
         Regridder(ok, bad, *self.args)
Example #26
0
 def test_grid_one_cs(self):
     ok, bad = self.ok_bad(None, GeogCS(6371000))
     with self.assertRaises(ValueError):
         Regridder(ok, bad, *self.args)
Example #27
0
 def setUp(self):
     self.cs1 = iris.coord_systems.GeogCS(6371229)
     self.cs2 = iris.coord_systems.GeogCS(6371229)
     self.cs3 = iris.coord_systems.RotatedGeogCS(30,
                                                 30,
                                                 ellipsoid=GeogCS(6371229))
Example #28
0
 def test_as_cartopy_globe(self):
     cs = GeogCS(6543210, 6500000)
     # Can't check equality directly, so use the proj4 params instead.
     res = cs.as_cartopy_globe().to_proj4_params()
     expected = {"a": 6543210, "b": 6500000}
     self.assertEqual(res, expected)
Example #29
0
 def test_str(self):
     cs = GeogCS(6543210, 6500000)
     expected = (
         "GeogCS(semi_major_axis=6543210.0, semi_minor_axis=6500000.0)")
     self.assertEqual(expected, str(cs))
Example #30
0
from typing import Tuple

import numpy as np
from iris.analysis import Linear
from iris.analysis.cartography import rotate_winds
from iris.coord_systems import GeogCS
from iris.coords import DimCoord
from iris.cube import Cube
from numpy import ndarray

from improver import BasePlugin
from improver.utilities.cube_manipulation import compare_coords

# Global coordinate reference system used in StaGE (GRS80)
GLOBAL_CRS = GeogCS(semi_major_axis=6378137.0, inverse_flattening=298.257222101)


class ResolveWindComponents(BasePlugin):
    """
    Plugin to resolve wind components along an input cube's projection axes,
    given directions with respect to true North
    """

    def __repr__(self) -> str:
        """Represent the plugin instance as a string"""
        return "<ResolveWindComponents>"

    @staticmethod
    def calc_true_north_offset(reference_cube: Cube) -> ndarray:
        """
Example #31
0
         0.97636177, 0.97944502, 0.98458376, 0.99177801
     ],
     [
         0.99486125, 0.98766701, 0.98252826, 0.97944502, 0.97841727,
         0.97944502, 0.98252826, 0.98766701, 0.99486125
     ],
     [
         1.0, 0.99280576, 0.98766701, 0.98458376, 0.98355601, 0.98458376,
         0.98766701, 0.99280576, 1.0
     ],
     [
         1.0, 1.0, 0.99486125, 0.99177801, 0.99075026, 0.99177801, 0.99486125,
         1.0, 1.0
     ]])

ELLIPSOID = GeogCS(semi_major_axis=6378137.0,
                   semi_minor_axis=6356752.314140356)
STANDARD_GRID_CCRS = LambertAzimuthalEqualArea(
    latitude_of_projection_origin=54.9,
    longitude_of_projection_origin=-2.5,
    false_easting=0.0,
    false_northing=0.0,
    ellipsoid=ELLIPSOID)


def set_up_cube(zero_point_indices=((0, 0, 7, 7), ),
                num_time_points=1,
                num_grid_points=16,
                num_realization_points=1):
    """Set up a cube with equal intervals along the x and y axis."""

    zero_point_indices = list(zero_point_indices)
Example #32
0
 def test_as_cartopy_globe(self):
     cs = GeogCS(6543210, 6500000)
     # Can't check equality directly, so use the proj4 params instead.
     res = cs.as_cartopy_globe().to_proj4_params()
     expected = {'a': 6543210, 'b': 6500000}
     self.assertEqual(res, expected)