Skip to content

Commit dda23fc

Browse files
committed
Extended grid_mapping integration tests to test multi coord systems
1 parent 9f3fb48 commit dda23fc

File tree

1 file changed

+121
-1
lines changed

1 file changed

+121
-1
lines changed

lib/iris/tests/integration/netcdf/test_coord_systems.py

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import tempfile
1414
import warnings
1515

16+
import numpy as np
1617
import pytest
1718

1819
import iris
@@ -93,7 +94,7 @@ def test_load_laea_grid(self):
9394
float data(y, x) ;
9495
data :standard_name = "toa_brightness_temperature" ;
9596
data :units = "K" ;
96-
data :grid_mapping = "mercator" ;
97+
data :grid_mapping = "mercator: x y" ;
9798
int mercator ;
9899
mercator:grid_mapping_name = "mercator" ;
99100
mercator:longitude_of_prime_meridian = 0. ;
@@ -131,6 +132,55 @@ def test_load_laea_grid(self):
131132
}
132133
"""
133134

135+
multi_cs_osgb_wkt = """
136+
netcdf osgb {
137+
dimensions:
138+
y = 5 ;
139+
x = 4 ;
140+
variables:
141+
double x(x) ;
142+
x:standard_name = "projection_x_coordinate" ;
143+
x:long_name = "Easting" ;
144+
x:units = "m" ;
145+
double y(y) ;
146+
y:standard_name = "projection_y_coordinate" ;
147+
y:long_name = "Northing" ;
148+
y:units = "m" ;
149+
double lat(y, x) ;
150+
lat:standard_name = "latitude" ;
151+
lat:units = "degrees_north" ;
152+
double lon(y, x) ;
153+
lon:standard_name = "longitude" ;
154+
lon:units = "degrees_east" ;
155+
float temp(y, x) ;
156+
temp:standard_name = "air_temperature" ;
157+
temp:units = "K" ;
158+
temp:coordinates = "lat lon" ;
159+
temp:grid_mapping = "crsOSGB: x y crsWGS84: lat lon" ;
160+
int crsOSGB ;
161+
crsOSGB:grid_mapping_name = "transverse_mercator" ;
162+
crsOSGB:semi_major_axis = 6377563.396 ;
163+
crsOSGB:inverse_flattening = 299.3249646 ;
164+
crsOSGB:longitude_of_prime_meridian = 0. ;
165+
crsOSGB:latitude_of_projection_origin = 49. ;
166+
crsOSGB:longitude_of_central_meridian = -2. ;
167+
crsOSGB:scale_factor_at_central_meridian = 0.9996012717 ;
168+
crsOSGB:false_easting = 400000. ;
169+
crsOSGB:false_northing = -100000. ;
170+
crsOSGB:unit = "metre" ;
171+
crsOSGB:crs_wkt = "PROJCRS[\\"unknown\\",BASEGEOGCRS[\\"unknown\\",DATUM[\\"Unknown based on Airy 1830 ellipsoid\\",ELLIPSOID[\\"Airy 1830\\",6377563.396,299.324964600004,LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]]],PRIMEM[\\"Greenwich\\",0,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8901]]],CONVERSION[\\"unknown\\",METHOD[\\"Transverse Mercator\\",ID[\\"EPSG\\",9807]],PARAMETER[\\"Latitude of natural origin\\",49,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8801]],PARAMETER[\\"Longitude of natural origin\\",-2,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8802]],PARAMETER[\\"Scale factor at natural origin\\",0.9996012717,SCALEUNIT[\\"unity\\",1],ID[\\"EPSG\\",8805]],PARAMETER[\\"False easting\\",400000,LENGTHUNIT[\\"metre\\",1],ID[\\"EPSG\\",8806]],PARAMETER[\\"False northing\\",-100000,LENGTHUNIT[\\"metre\\",1],ID[\\"EPSG\\",8807]]],CS[Cartesian,2],AXIS[\\"(E)\\",east,ORDER[1],LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]],AXIS[\\"(N)\\",north,ORDER[2],LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]]]" ;
172+
int crsWGS84 ;
173+
crsWGS84:grid_mapping_name = "latitude_longitude" ;
174+
crsWGS84:longitude_of_prime_meridian = 0. ;
175+
crsWGS84:semi_major_axis = 6378137. ;
176+
crsWGS84:inverse_flattening = 298.257223563 ;
177+
crsWGS84: crs_wkt = "GEOGCRS[\\"unknown\\",DATUM[\\"Unknown based on WGS 84 ellipsoid\\",ELLIPSOID[\\"WGS 84\\",6378137,298.257223562997,LENGTHUNIT[\\"metre\\",1,ID[\\"EPSG\\",9001]]]],PRIMEM[\\"Greenwich\\",0,ANGLEUNIT[\\"degree\\",0.0174532925199433],ID[\\"EPSG\\",8901]],CS[ellipsoidal,2],AXIS[\\"longitude\\",east,ORDER[1],ANGLEUNIT[\\"degree\\",0.0174532925199433,ID[\\"EPSG\\",9122]]],AXIS[\\"latitude\\",north,ORDER[2],ANGLEUNIT[\\"degree\\",0.0174532925199433,ID[\\"EPSG\\",9122]]]]" ;
178+
data:
179+
x = 1,2,3,4,5 ;
180+
y = 1,2,3,4 ;
181+
}
182+
"""
183+
134184
def test_load_datum_wkt(self):
135185
expected = "OSGB 1936"
136186
nc_path = tlc.cdl_to_nc(self.datum_wkt_cdl)
@@ -175,6 +225,22 @@ def test_no_load_datum_cf_var(self):
175225
actual = str(test_crs.as_cartopy_crs().datum)
176226
assert actual == "unknown"
177227

228+
def test_load_multi_cs_wkt(self):
229+
nc_path = tlc.cdl_to_nc(self.multi_cs_osgb_wkt)
230+
with iris.FUTURE.context(datum_support=True):
231+
cube = iris.load_cube(nc_path)
232+
233+
assert len(cube.coord_systems()) == 2
234+
for name in ["projection_y_coordinate", "projection_y_coordinate"]:
235+
assert (
236+
cube.coord(name).coord_system.grid_mapping_name == "transverse_mercator"
237+
)
238+
for name in ["latitude", "longitude"]:
239+
assert (
240+
cube.coord(name).coord_system.grid_mapping_name == "latitude_longitude"
241+
)
242+
assert cube.extended_grid_mapping is True
243+
178244
def test_save_datum(self):
179245
expected = "OSGB 1936"
180246
saved_crs = iris.coord_systems.Mercator(
@@ -214,6 +280,60 @@ def test_save_datum(self):
214280
actual = str(test_crs.as_cartopy_crs().datum)
215281
assert actual == expected
216282

283+
def test_save_multi_cs_wkt(self):
284+
crsOSGB = iris.coord_systems.OSGB()
285+
crsLatLon = iris.coord_systems.GeogCS(6e6)
286+
287+
dimx_coord = iris.coords.DimCoord(
288+
np.arange(4), "projection_x_coordinate", coord_system=crsOSGB
289+
)
290+
dimy_coord = iris.coords.DimCoord(
291+
np.arange(5), "projection_y_coordinate", coord_system=crsOSGB
292+
)
293+
294+
auxlon_coord = iris.coords.AuxCoord(
295+
np.arange(20).reshape((5, 4)),
296+
standard_name="longitude",
297+
coord_system=crsLatLon,
298+
)
299+
auxlat_coord = iris.coords.AuxCoord(
300+
np.arange(20).reshape((5, 4)),
301+
standard_name="latitude",
302+
coord_system=crsLatLon,
303+
)
304+
305+
test_cube = Cube(
306+
np.ones(20).reshape((5, 4)),
307+
standard_name="air_pressure",
308+
units="Pa",
309+
dim_coords_and_dims=(
310+
(dimy_coord, 0),
311+
(dimx_coord, 1),
312+
),
313+
aux_coords_and_dims=(
314+
(auxlat_coord, (0, 1)),
315+
(auxlon_coord, (0, 1)),
316+
),
317+
)
318+
319+
test_cube.extended_grid_mapping = True
320+
321+
with self.temp_filename(suffix=".nc") as filename:
322+
iris.save(test_cube, filename)
323+
with iris.FUTURE.context(datum_support=True):
324+
cube = iris.load_cube(filename)
325+
326+
assert len(cube.coord_systems()) == 2
327+
for name in ["projection_y_coordinate", "projection_y_coordinate"]:
328+
assert (
329+
cube.coord(name).coord_system.grid_mapping_name == "transverse_mercator"
330+
)
331+
for name in ["latitude", "longitude"]:
332+
assert (
333+
cube.coord(name).coord_system.grid_mapping_name == "latitude_longitude"
334+
)
335+
assert cube.extended_grid_mapping is True
336+
217337

218338
class TestLoadMinimalGeostationary(tests.IrisTest):
219339
"""Check we can load data with a geostationary grid-mapping, even when the

0 commit comments

Comments
 (0)