Beispiel #1
0
def cl_cubes():
    """Cubes for ``cl.``."""
    b_coord = AuxCoord(
        [1.0],
        var_name='b',
        long_name='vertical coordinate formula term: b(k)',
        attributes={'a': 1, 'b': '2'},
    )
    cl_cube = Cube(
        [0.0],
        var_name='cl',
        standard_name='cloud_area_fraction_in_atmosphere_layer',
        aux_coords_and_dims=[(b_coord.copy(), 0)],
    )
    x_cube = Cube([0.0],
                  long_name='x',
                  aux_coords_and_dims=[(b_coord.copy(), 0)])
    cubes = CubeList([cl_cube, x_cube])
    return cubes
Beispiel #2
0
    def test_attributes_subtle_differences(self):
        cube = Cube([0])

        # Add a pair that differ only in having a list instead of an array.
        co1a = DimCoord(
            [0],
            long_name="co1_list_or_array",
            attributes=dict(x=1, arr1=np.array(2), arr2=np.array([1, 2])),
        )
        co1b = co1a.copy()
        co1b.attributes.update(dict(arr2=[1, 2]))
        for co in (co1a, co1b):
            cube.add_aux_coord(co)

        # Add a pair that differ only in an attribute array dtype.
        co2a = AuxCoord(
            [0],
            long_name="co2_dtype",
            attributes=dict(x=1, arr1=np.array(2), arr2=np.array([3, 4])),
        )
        co2b = co2a.copy()
        co2b.attributes.update(dict(arr2=np.array([3.0, 4.0])))
        assert co2b != co2a
        for co in (co2a, co2b):
            cube.add_aux_coord(co)

        # Add a pair that differ only in an attribute array shape.
        co3a = DimCoord(
            [0],
            long_name="co3_shape",
            attributes=dict(x=1, arr1=np.array([5, 6]), arr2=np.array([3, 4])),
        )
        co3b = co3a.copy()
        co3b.attributes.update(dict(arr1=np.array([[5], [6]])))
        for co in (co3a, co3b):
            cube.add_aux_coord(co)

        rep = iris._representation.CubeSummary(cube)
        co_summs = rep.scalar_sections["Scalar coordinates:"].contents
        co1a_summ, co1b_summ = co_summs[0:2]
        self.assertEqual(co1a_summ.extra, "arr2=array([1, 2])")
        self.assertEqual(co1b_summ.extra, "arr2=[1, 2]")
        co2a_summ, co2b_summ = co_summs[2:4]
        self.assertEqual(co2a_summ.extra, "arr2=array([3, 4])")
        self.assertEqual(co2b_summ.extra, "arr2=array([3., 4.])")
        co3a_summ, co3b_summ = co_summs[4:6]
        self.assertEqual(co3a_summ.extra, "arr1=array([5, 6])")
        self.assertEqual(co3b_summ.extra, "arr1=array([[5], [6]])")
Beispiel #3
0
    def test_xy_dimensionality(self):
        u, v = uv_cubes()
        # Replace 1d lat with 2d lat.
        x = u.coord('grid_longitude').points
        y = u.coord('grid_latitude').points
        x2d, y2d = np.meshgrid(x, y)
        lat_2d = AuxCoord(y2d, 'grid_latitude', units='degrees',
                          coord_system=u.coord('grid_latitude').coord_system)
        for cube in (u, v):
            cube.remove_coord('grid_latitude')
            cube.add_aux_coord(lat_2d.copy(), (0, 1))

        with self.assertRaisesRegexp(
                ValueError,
                'x and y coordinates must have the same number of dimensions'):
            rotate_winds(u, v, iris.coord_systems.OSGB())
Beispiel #4
0
    def test_xy_dimensionality(self):
        u, v = uv_cubes()
        # Replace 1d lat with 2d lat.
        x = u.coord('grid_longitude').points
        y = u.coord('grid_latitude').points
        x2d, y2d = np.meshgrid(x, y)
        lat_2d = AuxCoord(y2d, 'grid_latitude', units='degrees',
                          coord_system=u.coord('grid_latitude').coord_system)
        for cube in (u, v):
            cube.remove_coord('grid_latitude')
            cube.add_aux_coord(lat_2d.copy(), (0, 1))

        with self.assertRaisesRegex(
                ValueError,
                'x and y coordinates must have the same number of dimensions'):
            rotate_winds(u, v, iris.coord_systems.OSGB())
Beispiel #5
0
class Test_is_compatible(tests.IrisTest):
    def setUp(self):
        self.test_coord = AuxCoord([1.])
        self.other_coord = self.test_coord.copy()

    def test_noncommon_array_attrs_compatible(self):
        # Non-common array attributes should be ok.
        self.test_coord.attributes['array_test'] = np.array([1.0, 2, 3])
        self.assertTrue(self.test_coord.is_compatible(self.other_coord))

    def test_matching_array_attrs_compatible(self):
        # Matching array attributes should be ok.
        self.test_coord.attributes['array_test'] = np.array([1.0, 2, 3])
        self.other_coord.attributes['array_test'] = np.array([1.0, 2, 3])
        self.assertTrue(self.test_coord.is_compatible(self.other_coord))

    def test_different_array_attrs_incompatible(self):
        # Differing array attributes should make coords incompatible.
        self.test_coord.attributes['array_test'] = np.array([1.0, 2, 3])
        self.other_coord.attributes['array_test'] = np.array([1.0, 2, 777.7])
        self.assertFalse(self.test_coord.is_compatible(self.other_coord))
Beispiel #6
0
class Test_is_compatible(tests.IrisTest):
    def setUp(self):
        self.test_coord = AuxCoord([1.0])
        self.other_coord = self.test_coord.copy()

    def test_noncommon_array_attrs_compatible(self):
        # Non-common array attributes should be ok.
        self.test_coord.attributes["array_test"] = np.array([1.0, 2, 3])
        self.assertTrue(self.test_coord.is_compatible(self.other_coord))

    def test_matching_array_attrs_compatible(self):
        # Matching array attributes should be ok.
        self.test_coord.attributes["array_test"] = np.array([1.0, 2, 3])
        self.other_coord.attributes["array_test"] = np.array([1.0, 2, 3])
        self.assertTrue(self.test_coord.is_compatible(self.other_coord))

    def test_different_array_attrs_incompatible(self):
        # Differing array attributes should make coords incompatible.
        self.test_coord.attributes["array_test"] = np.array([1.0, 2, 3])
        self.other_coord.attributes["array_test"] = np.array([1.0, 2, 777.7])
        self.assertFalse(self.test_coord.is_compatible(self.other_coord))
Beispiel #7
0
 def test_nanpoints_eq_copy(self):
     co1 = AuxCoord([1., np.nan, 2.])
     co2 = co1.copy()
     self.assertEqual(co1, co2)
Beispiel #8
0
    def _make_test_meshcoord(
        self,
        lazy_sources=False,
        location="face",
        inds_start_index=0,
        inds_location_axis=0,
        facenodes_changes=None,
    ):
        # Construct a miniature face-nodes mesh for testing.
        # NOTE: we will make our connectivity arrays with standard
        # start_index=0 and location_axis=0 :  We only adjust that (if required) when
        # creating the actual connectivities.
        face_nodes_array = np.array(
            [
                [0, 2, 1, 3],
                [1, 3, 10, 13],
                [2, 7, 9, 19],
                [
                    3,
                    4,
                    7,
                    -1,
                ],  # This one has a "missing" point (it's a triangle)
                [8, 1, 7, 2],
            ]
        )
        # Connectivity uses *masked* for missing points.
        face_nodes_array = np.ma.masked_less(face_nodes_array, 0)
        if facenodes_changes:
            facenodes_changes = facenodes_changes.copy()
            facenodes_changes.pop("n_extra_bad_points")
            for indices, value in facenodes_changes.items():
                face_nodes_array[indices] = value

        # Construct a miniature edge-nodes mesh for testing.
        edge_nodes_array = np.array([[0, 2], [1, 3], [1, 4], [3, 7]])
        # Connectivity uses *masked* for missing points.
        edge_nodes_array = np.ma.masked_less(edge_nodes_array, 0)

        n_faces = face_nodes_array.shape[0]
        n_edges = edge_nodes_array.shape[0]
        n_nodes = int(face_nodes_array.max() + 1)
        self.NODECOORDS_BASENUM = 1100.0
        self.EDGECOORDS_BASENUM = 1200.0
        self.FACECOORDS_BASENUM = 1300.0
        node_xs = self.NODECOORDS_BASENUM + np.arange(n_nodes)
        edge_xs = self.EDGECOORDS_BASENUM + np.arange(n_edges)
        face_xs = self.FACECOORDS_BASENUM + np.arange(n_faces)

        # Record all these for re-use in tests
        self.n_faces = n_faces
        self.n_nodes = n_nodes
        self.face_xs = face_xs
        self.node_xs = node_xs
        self.edge_xs = edge_xs
        self.face_nodes_array = face_nodes_array
        self.edge_nodes_array = edge_nodes_array

        # convert source data to Dask arrays if asked.
        if lazy_sources:

            def lazify(arr):
                return da.from_array(arr, chunks=-1, meta=np.ndarray)

            node_xs = lazify(node_xs)
            face_xs = lazify(face_xs)
            edge_xs = lazify(edge_xs)
            face_nodes_array = lazify(face_nodes_array)
            edge_nodes_array = lazify(edge_nodes_array)

        # Build a mesh with this info stored in it.
        co_nodex = AuxCoord(
            node_xs, standard_name="longitude", long_name="node_x", units=1
        )
        co_facex = AuxCoord(
            face_xs, standard_name="longitude", long_name="face_x", units=1
        )
        co_edgex = AuxCoord(
            edge_xs, standard_name="longitude", long_name="edge_x", units=1
        )
        # N.B. the Mesh requires 'Y's as well.
        co_nodey = co_nodex.copy()
        co_nodey.rename("latitude")
        co_nodey.long_name = "node_y"
        co_facey = co_facex.copy()
        co_facey.rename("latitude")
        co_facey.long_name = "face_y"
        co_edgey = co_edgex.copy()
        co_edgey.rename("edge_y")
        co_edgey.long_name = "edge_y"

        face_node_conn = Connectivity(
            inds_start_index
            + (
                face_nodes_array.transpose()
                if inds_location_axis == 1
                else face_nodes_array
            ),
            cf_role="face_node_connectivity",
            long_name="face_nodes",
            start_index=inds_start_index,
            location_axis=inds_location_axis,
        )

        edge_node_conn = Connectivity(
            inds_start_index
            + (
                edge_nodes_array.transpose()
                if inds_location_axis == 1
                else edge_nodes_array
            ),
            cf_role="edge_node_connectivity",
            long_name="edge_nodes",
            start_index=inds_start_index,
            location_axis=inds_location_axis,
        )

        self.mesh = Mesh(
            topology_dimension=2,
            node_coords_and_axes=[(co_nodex, "x"), (co_nodey, "y")],
            connectivities=[face_node_conn, edge_node_conn],
            face_coords_and_axes=[(co_facex, "x"), (co_facey, "y")],
            edge_coords_and_axes=[(co_edgex, "x"), (co_edgey, "y")],
        )

        # Construct a test meshcoord.
        meshcoord = MeshCoord(mesh=self.mesh, location=location, axis="x")
        self.meshcoord = meshcoord
        return meshcoord
class Test1Dim(tests.IrisTest):
    def setUp(self):
        self.lon = DimCoord(
            points=[0.5, 1.5, 2.5],
            bounds=[[0, 1], [1, 2], [2, 3]],
            standard_name="longitude",
            long_name="edge longitudes",
            var_name="lon",
            units="degrees",
            attributes={"test": 1},
        )
        # Should be fine with either a DimCoord or an AuxCoord.
        self.lat = AuxCoord(
            points=[0.5, 2.5, 1.5],
            bounds=[[0, 1], [2, 3], [1, 2]],
            standard_name="latitude",
            long_name="edge_latitudes",
            var_name="lat",
            units="degrees",
            attributes={"test": 1},
        )

    def create(self):
        return Mesh.from_coords(self.lon, self.lat)

    def test_dimensionality(self):
        mesh = self.create()
        self.assertEqual(1, mesh.topology_dimension)

        self.assertArrayEqual([0, 1, 1, 2, 2, 3],
                              mesh.node_coords.node_x.points)
        self.assertArrayEqual([0, 1, 2, 3, 1, 2],
                              mesh.node_coords.node_y.points)
        self.assertArrayEqual([0.5, 1.5, 2.5], mesh.edge_coords.edge_x.points)
        self.assertArrayEqual([0.5, 2.5, 1.5], mesh.edge_coords.edge_y.points)
        self.assertIsNone(getattr(mesh, "face_coords", None))

        for conn_name in Connectivity.UGRID_CF_ROLES:
            conn = getattr(mesh, conn_name, None)
            if conn_name == "edge_node_connectivity":
                self.assertArrayEqual([[0, 1], [2, 3], [4, 5]], conn.indices)
            else:
                self.assertIsNone(conn)

    def test_node_metadata(self):
        mesh = self.create()
        pairs = [
            (self.lon, mesh.node_coords.node_x),
            (self.lat, mesh.node_coords.node_y),
        ]
        for expected_coord, actual_coord in pairs:
            for attr in ("standard_name", "long_name", "units", "attributes"):
                expected = getattr(expected_coord, attr)
                actual = getattr(actual_coord, attr)
                self.assertEqual(expected, actual)
            self.assertIsNone(actual_coord.var_name)

    def test_centre_metadata(self):
        mesh = self.create()
        pairs = [
            (self.lon, mesh.edge_coords.edge_x),
            (self.lat, mesh.edge_coords.edge_y),
        ]
        for expected_coord, actual_coord in pairs:
            for attr in ("standard_name", "long_name", "units", "attributes"):
                expected = getattr(expected_coord, attr)
                actual = getattr(actual_coord, attr)
                self.assertEqual(expected, actual)
            self.assertIsNone(actual_coord.var_name)

    def test_mesh_metadata(self):
        # Inappropriate to guess these values from the input coords.
        mesh = self.create()
        for attr in (
                "standard_name",
                "long_name",
                "var_name",
        ):
            self.assertIsNone(getattr(mesh, attr))
        self.assertTrue(mesh.units.is_unknown())
        self.assertDictEqual({}, mesh.attributes)

    def test_lazy(self):
        self.lon = AuxCoord.from_coord(self.lon)
        self.lon = self.lon.copy(self.lon.lazy_points(),
                                 self.lon.lazy_bounds())
        self.lat = self.lat.copy(self.lat.lazy_points(),
                                 self.lat.lazy_bounds())

        mesh = self.create()
        for coord in list(mesh.all_coords):
            if coord is not None:
                self.assertTrue(coord.has_lazy_points())
        for conn in list(mesh.all_connectivities):
            if conn is not None:
                self.assertTrue(conn.has_lazy_indices())

    def test_coord_shape_mismatch(self):
        lat_orig = self.lat.copy(self.lat.points, self.lat.bounds)
        self.lat = lat_orig.copy(points=lat_orig.points,
                                 bounds=np.tile(lat_orig.bounds, 2))
        with self.assertRaisesRegex(ValueError,
                                    "bounds shapes are not identical"):
            _ = self.create()

        self.lat = lat_orig.copy(points=lat_orig.points[-1],
                                 bounds=lat_orig.bounds[-1])
        with self.assertRaisesRegex(ValueError,
                                    "points shapes are not identical"):
            _ = self.create()

    def test_reorder(self):
        # Swap the coords.
        self.lat, self.lon = self.lon, self.lat
        mesh = self.create()
        # Confirm that the coords have been swapped back to the 'correct' order.
        self.assertEqual("longitude", mesh.node_coords.node_x.standard_name)
        self.assertEqual("latitude", mesh.node_coords.node_y.standard_name)

    def test_non_xy(self):
        for coord in self.lon, self.lat:
            coord.standard_name = None
        lon_name, lat_name = [
            coord.long_name for coord in (self.lon, self.lat)
        ]
        # Swap the coords.
        self.lat, self.lon = self.lon, self.lat
        with self.assertLogs(logger, "INFO", "Unable to find 'X' and 'Y'"):
            mesh = self.create()
        # Confirm that the coords have not been swapped back.
        self.assertEqual(lat_name, mesh.node_coords.node_x.long_name)
        self.assertEqual(lon_name, mesh.node_coords.node_y.long_name)