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]))
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
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
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
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), )
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)
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)
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)
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)
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)
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)
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
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()
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
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)
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
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, )
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, )
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
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)
def test_grid_inconsistent_cs(self): ok, bad = self.ok_bad(GeogCS(6370000), GeogCS(6371000)) with self.assertRaises(ValueError): Regridder(ok, bad, *self.args)
def test_grid_one_cs(self): ok, bad = self.ok_bad(None, GeogCS(6371000)) with self.assertRaises(ValueError): Regridder(ok, bad, *self.args)
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))
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)
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))
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: """
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)
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)