Example #1
0
def sample_mesh(n_nodes=None, n_faces=None, n_edges=None):
    """
    Make a test mesh.

    Mesh has faces edges, face-coords and edge-coords, numbers of which can be controlled.

    """
    if n_nodes is None:
        n_nodes = _TEST_N_NODES
    if n_faces is None:
        n_faces = _TEST_N_FACES
    if n_edges is None:
        n_edges = _TEST_N_EDGES
    node_x = AuxCoord(
        1100 + np.arange(n_nodes),
        standard_name="longitude",
        units="degrees_east",
        long_name="long-name",
        var_name="var-name",
        attributes={"a": 1, "b": "c"},
    )
    node_y = AuxCoord(1200 + np.arange(n_nodes), standard_name="latitude")

    # Define a rather arbitrary edge-nodes connectivity.
    # Some nodes are left out, because n_edges*2 < n_nodes.
    conns = np.arange(n_edges * 2, dtype=int)
    # Missing nodes include #0-5, because we add 5.
    conns = ((conns + 5) % n_nodes).reshape((n_edges, 2))
    edge_nodes = Connectivity(conns, cf_role="edge_node_connectivity")
    conns = np.arange(n_edges * 2, dtype=int)

    # Some numbers for the edge coordinates.
    edge_x = AuxCoord(2100 + np.arange(n_edges), standard_name="longitude")
    edge_y = AuxCoord(2200 + np.arange(n_edges), standard_name="latitude")

    # Define a rather arbitrary face-nodes connectivity.
    # Some nodes are left out, because n_faces*n_bounds < n_nodes.
    conns = np.arange(n_faces * _TEST_N_BOUNDS, dtype=int)
    conns = (conns % n_nodes).reshape((n_faces, _TEST_N_BOUNDS))
    face_nodes = Connectivity(conns, cf_role="face_node_connectivity")

    # Some numbers for the edge coordinates.
    face_x = AuxCoord(3100 + np.arange(n_faces), standard_name="longitude")
    face_y = AuxCoord(3200 + np.arange(n_faces), standard_name="latitude")

    mesh = Mesh(
        topology_dimension=2,
        node_coords_and_axes=[(node_x, "x"), (node_y, "y")],
        connectivities=[face_nodes, edge_nodes],
        edge_coords_and_axes=[(edge_x, "x"), (edge_y, "y")],
        face_coords_and_axes=[(face_x, "x"), (face_y, "y")],
    )
    return mesh
Example #2
0
 def setUp(self):
     # Crete an instance, with non-default arguments to allow testing of
     # correct property setting.
     self.kwargs = {
         "indices": np.linspace(1, 9, 9, dtype=int).reshape((3, -1)),
         "cf_role": "face_node_connectivity",
         "long_name": "my_face_nodes",
         "var_name": "face_nodes",
         "attributes": {"notes": "this is a test"},
         "start_index": 1,
         "src_dim": 1,
     }
     self.connectivity = Connectivity(**self.kwargs)
 def test_connectivity__location_axis(self):
     # Check we can print a Connectivity
     # Like a Coord, but always print : cf_role, location_axis, start_index
     data = self.sample_data(shape=(3, 2), datatype=int)
     conn = Connectivity(
         data.transpose(),
         location_axis=1,
         cf_role="edge_node_connectivity",
         long_name="enc",
         units="1",
     )
     result = self.repr_str_strings(conn)
     expected = [
         "<Connectivity: enc / (1)  [[0, 2, 4], [1, 3, 5]]  shape(2, 3)>",
         "Connectivity :  enc / (1)",
         "    data: [",
         "        [0, 2, 4],",
         "        [1, 3, 5]]",
         "    shape: (2, 3)",
         "    dtype: int64",
         "    long_name: 'enc'",
         "    cf_role: 'edge_node_connectivity'",
         "    start_index: 0",
         "    location_axis: 1",
     ]
     self.assertLines(expected, result)
Example #4
0
    def test_connectivity_start_index(self):
        """Test a mesh where some connectivities have start_index = 1."""
        # Make a mesh with both faces *and* some edges
        mesh = make_mesh(n_edges=7)
        # Get the face-node and edge-node connectivities
        face_nodes_conn = mesh.face_node_connectivity
        edge_nodes_conn = mesh.edge_node_connectivity
        edge_nodes_conn2 = Connectivity(
            indices=edge_nodes_conn.indices + 1,
            cf_role=edge_nodes_conn.cf_role,
            var_name="edges_x_2",
            start_index=1,
        )
        # Make a new mesh with altered connectivities.
        mesh2 = Mesh(
            topology_dimension=mesh.topology_dimension,
            node_coords_and_axes=zip(mesh.node_coords, XY_LOCS),
            face_coords_and_axes=zip(mesh.face_coords, XY_LOCS),
            connectivities=[face_nodes_conn, edge_nodes_conn2],
        )

        # Save and snapshot the result
        tempfile_path = self.check_save_mesh(mesh2)
        dims, vars = scan_dataset(tempfile_path)

        # Check shape and dimensions of the associated connectivity variables.
        (mesh_name,) = vars_meshnames(vars)
        mesh_props = vars[mesh_name]
        faceconn_name = mesh_props["face_node_connectivity"]
        edgeconn_name = mesh_props["edge_node_connectivity"]
        faceconn_props = vars[faceconn_name]
        edgeconn_props = vars[edgeconn_name]
        self.assertEqual(faceconn_props["start_index"], 0)
        self.assertEqual(edgeconn_props["start_index"], 1)
Example #5
0
 def test___eq__(self):
     equivalent_kwargs = self.kwargs
     equivalent_kwargs["indices"] = self.kwargs["indices"].transpose()
     equivalent_kwargs["location_axis"] = 1 - self.kwargs["location_axis"]
     equivalent = Connectivity(**equivalent_kwargs)
     self.assertFalse(
         np.array_equal(equivalent.indices, self.connectivity.indices))
     self.assertEqual(equivalent, self.connectivity)
Example #6
0
 def test___eq__(self):
     equivalent_kwargs = self.kwargs
     equivalent_kwargs["indices"] = self.kwargs["indices"].transpose()
     equivalent_kwargs["src_dim"] = 1 - self.kwargs["src_dim"]
     equivalent = Connectivity(**equivalent_kwargs)
     self.assertFalse(
         (equivalent.indices == self.connectivity.indices).all()
     )
     self.assertEqual(equivalent, self.connectivity)
Example #7
0
    def test_nonuniform_connectivity(self):
        # Check handling of connectivities with missing points.
        n_faces = 7
        mesh = make_mesh(n_faces=n_faces)

        # In this case, add on a partial face-face connectivity.
        # construct a vaguely plausible face-face index array
        indices = np.ma.arange(n_faces * 4).reshape((7, 4))
        indices = indices % 7
        # make some missing points -- i.e. not all faces have 4 neighbours
        indices[(2, (2, 3))] = np.ma.masked
        indices[(3, (0, 2))] = np.ma.masked
        indices[6, :] = np.ma.masked

        conn = Connectivity(
            indices,
            cf_role="face_face_connectivity",
        )
        mesh.add_connectivities(conn)

        # Save and snapshot the result
        tempfile_path = self.check_save_mesh(mesh)
        dims, vars = scan_dataset(tempfile_path)

        # Check that the mesh saved with the additional connectivity
        (mesh_name,) = vars_meshnames(vars)
        mesh_props = vars[mesh_name]
        self.assertIn("face_face_connectivity", mesh_props)
        ff_conn_name = mesh_props["face_face_connectivity"]

        # check that the connectivity has the corrects dims and fill-property
        ff_props = vars[ff_conn_name]
        self.assertEqual(
            ff_props[_VAR_DIMS], ["Mesh2d_faces", "Mesh2d_face_N_faces"]
        )
        self.assertIn("_FillValue", ff_props)
        self.assertEqual(ff_props["_FillValue"], -1)

        # Check that a 'normal' connectivity does *not* have a _FillValue
        fn_conn_name = mesh_props["face_node_connectivity"]
        fn_props = vars[fn_conn_name]
        self.assertNotIn("_FillValue", fn_props)

        # For what it's worth, *also* check the actual data array in the file
        ds = nc.Dataset(tempfile_path)
        conn_var = ds.variables[ff_conn_name]
        data = conn_var[:]
        ds.close()
        self.assertIsInstance(data, np.ma.MaskedArray)
        self.assertEqual(data.fill_value, -1)
        # Compare raw values stored to indices, but with -1 at missing points
        raw_data = data.data
        filled_indices = indices.filled(-1)
        self.assertArrayEqual(raw_data, filled_indices)
Example #8
0
 def test_indices_locations_masked(self):
     mask = ([0, 0, 0] * 2) + [0, 0, 1]
     data = np.linspace(1, 9, 9, dtype=int).reshape((3, -1))
     kwargs = {
         "indices": ma.array(data=data, mask=mask),
         "cf_role": "face_node_connectivity",
     }
     # Validation of individual location sizes (denoted by masks) only
     # available through explicit call of Connectivity.validate_indices().
     connectivity = Connectivity(**kwargs)
     self.assertRaisesRegex(
         ValueError,
         "Not all src_locations meet requirement: len>=3",
         connectivity.validate_indices,
     )
Example #9
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
Example #10
0
def sample_mesh(n_nodes=None, n_faces=None, n_edges=None, lazy_values=False):
    """
    Make a test mesh.

    Mesh has nodes, plus faces and/or edges, with face-coords and edge-coords,
    numbers of which can be controlled.

    Args:
    * n_nodes (int or None):
        Number of nodes in mesh. Default is 15.  Cannot be 0.
    * n_edges (int or None):
        Number of edges in mesh. Default is 5.
        If not 0, edge coords and an 'edge_node_connectivity' are included.
    * n_faces (int or None):
        Number of faces in mesh. Default is 3.
        If not 0, face coords and a 'face_node_connectivity' are included.
    * lazy_values (bool):
        If True, all content values of coords and connectivities are lazy.

    """
    if lazy_values:
        import dask.array as da

        arr = da
    else:
        arr = np

    if n_nodes is None:
        n_nodes = _TEST_N_NODES
    if n_faces is None:
        n_faces = _TEST_N_FACES
    if n_edges is None:
        n_edges = _TEST_N_EDGES
    node_x = AuxCoord(
        1100 + arr.arange(n_nodes),
        standard_name="longitude",
        units="degrees_east",
        long_name="long-name",
        var_name="var-name",
        attributes={
            "a": 1,
            "b": "c"
        },
    )
    node_y = AuxCoord(1200 + arr.arange(n_nodes), standard_name="latitude")

    connectivities = []
    if n_edges == 0:
        edge_coords_and_axes = None
    else:
        # Define a rather arbitrary edge-nodes connectivity.
        # Some nodes are left out, because n_edges*2 < n_nodes.
        conns = arr.arange(n_edges * 2, dtype=int)
        # Missing nodes include #0-5, because we add 5.
        conns = ((conns + 5) % n_nodes).reshape((n_edges, 2))
        edge_nodes = Connectivity(conns, cf_role="edge_node_connectivity")
        connectivities.append(edge_nodes)

        edge_x = AuxCoord(2100 + arr.arange(n_edges),
                          standard_name="longitude")
        edge_y = AuxCoord(2200 + arr.arange(n_edges), standard_name="latitude")
        edge_coords_and_axes = [(edge_x, "x"), (edge_y, "y")]

    if n_faces == 0:
        face_coords_and_axes = None
    else:
        # Define a rather arbitrary face-nodes connectivity.
        # Some nodes are left out, because n_faces*n_bounds < n_nodes.
        conns = arr.arange(n_faces * _TEST_N_BOUNDS, dtype=int)
        conns = (conns % n_nodes).reshape((n_faces, _TEST_N_BOUNDS))
        face_nodes = Connectivity(conns, cf_role="face_node_connectivity")
        connectivities.append(face_nodes)

        # Some numbers for the edge coordinates.
        face_x = AuxCoord(3100 + arr.arange(n_faces),
                          standard_name="longitude")
        face_y = AuxCoord(3200 + arr.arange(n_faces), standard_name="latitude")
        face_coords_and_axes = [(face_x, "x"), (face_y, "y")]

    mesh = Mesh(
        topology_dimension=2,
        node_coords_and_axes=[(node_x, "x"), (node_y, "y")],
        connectivities=connectivities,
        edge_coords_and_axes=edge_coords_and_axes,
        face_coords_and_axes=face_coords_and_axes,
    )
    return mesh
Example #11
0
class TestStandard(tests.IrisTest):
    def setUp(self):
        # Crete an instance, with non-default arguments to allow testing of
        # correct property setting.
        self.kwargs = {
            "indices": np.linspace(1, 9, 9, dtype=int).reshape((3, -1)),
            "cf_role": "face_node_connectivity",
            "long_name": "my_face_nodes",
            "var_name": "face_nodes",
            "attributes": {"notes": "this is a test"},
            "start_index": 1,
            "src_dim": 1,
        }
        self.connectivity = Connectivity(**self.kwargs)

    def test_cf_role(self):
        self.assertEqual(self.kwargs["cf_role"], self.connectivity.cf_role)

    def test_src_location(self):
        expected = self.kwargs["cf_role"].split("_")[0]
        self.assertEqual(expected, self.connectivity.src_location)

    def test_tgt_location(self):
        expected = self.kwargs["cf_role"].split("_")[1]
        self.assertEqual(expected, self.connectivity.tgt_location)

    def test_start_index(self):
        self.assertEqual(
            self.kwargs["start_index"], self.connectivity.start_index
        )

    def test_src_dim(self):
        self.assertEqual(self.kwargs["src_dim"], self.connectivity.src_dim)

    def test_indices(self):
        self.assertArrayEqual(
            self.kwargs["indices"], self.connectivity.indices
        )

    def test_read_only(self):
        attributes = ("indices", "cf_role", "start_index", "src_dim")
        for attribute in attributes:
            self.assertRaisesRegex(
                AttributeError,
                "can't set attribute",
                setattr,
                self.connectivity,
                attribute,
                1,
            )

    def test_transpose(self):
        expected_dim = 1 - self.kwargs["src_dim"]
        expected_indices = self.kwargs["indices"].transpose()
        new_connectivity = self.connectivity.transpose()
        self.assertEqual(expected_dim, new_connectivity.src_dim)
        self.assertArrayEqual(expected_indices, new_connectivity.indices)

    def test_lazy_indices(self):
        self.assertTrue(is_lazy_data(self.connectivity.lazy_indices()))

    def test_core_indices(self):
        self.assertArrayEqual(
            self.kwargs["indices"], self.connectivity.core_indices()
        )

    def test_has_lazy_indices(self):
        self.assertFalse(self.connectivity.has_lazy_indices())

    def test_lazy_src_lengths(self):
        self.assertTrue(is_lazy_data(self.connectivity.lazy_src_lengths()))

    def test_src_lengths(self):
        expected = [3, 3, 3]
        self.assertArrayEqual(expected, self.connectivity.src_lengths())

    def test___str__(self):
        expected = (
            "Connectivity(cf_role='face_node_connectivity', start_index=1)"
        )
        self.assertEqual(expected, self.connectivity.__str__())

    def test___repr__(self):
        expected = (
            "Connectivity(array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), "
            "cf_role='face_node_connectivity', long_name='my_face_nodes', "
            "var_name='face_nodes', attributes={'notes': 'this is a test'}, "
            "start_index=1, src_dim=1)"
        )
        self.assertEqual(expected, self.connectivity.__repr__())

    def test_xml_element(self):
        doc = minidom.Document()
        connectivity_element = self.connectivity.xml_element(doc)
        self.assertEqual(connectivity_element.tagName, "connectivity")
        for attribute in ("cf_role", "start_index", "src_dim"):
            self.assertIn(attribute, connectivity_element.attributes)

    def test___eq__(self):
        equivalent_kwargs = self.kwargs
        equivalent_kwargs["indices"] = self.kwargs["indices"].transpose()
        equivalent_kwargs["src_dim"] = 1 - self.kwargs["src_dim"]
        equivalent = Connectivity(**equivalent_kwargs)
        self.assertFalse(
            (equivalent.indices == self.connectivity.indices).all()
        )
        self.assertEqual(equivalent, self.connectivity)

    def test_different(self):
        different_kwargs = self.kwargs
        different_kwargs["indices"] = self.kwargs["indices"].transpose()
        different = Connectivity(**different_kwargs)
        self.assertNotEqual(different, self.connectivity)

    def test_no_cube_dims(self):
        self.assertRaises(NotImplementedError, self.connectivity.cube_dims, 1)

    def test_shape(self):
        self.assertEqual(self.kwargs["indices"].shape, self.connectivity.shape)

    def test_ndim(self):
        self.assertEqual(self.kwargs["indices"].ndim, self.connectivity.ndim)

    def test___getitem_(self):
        subset = self.connectivity[:, 0:1]
        self.assertArrayEqual(self.kwargs["indices"][:, 0:1], subset.indices)

    def test_copy(self):
        new_indices = np.linspace(11, 16, 6, dtype=int).reshape((3, -1))
        copy_connectivity = self.connectivity.copy(new_indices)
        self.assertArrayEqual(new_indices, copy_connectivity.indices)

    def test_indices_by_src(self):
        expected = self.kwargs["indices"].transpose()
        self.assertArrayEqual(expected, self.connectivity.indices_by_src())

    def test_indices_by_src_input(self):
        expected = as_lazy_data(self.kwargs["indices"].transpose())
        by_src = self.connectivity.indices_by_src(
            self.connectivity.lazy_indices()
        )
        self.assertArrayEqual(expected, by_src)
Example #12
0
 def test_has_lazy_indices(self):
     connectivity = Connectivity(
         indices=self.lazy_indices, cf_role="face_node_connectivity"
     )
     self.assertTrue(connectivity.has_lazy_indices())
Example #13
0
 def common(self, indices):
     connectivity = Connectivity(
         indices=indices, cf_role="face_node_connectivity"
     )
     self.assertArrayEqual(indices, connectivity.indices)
Example #14
0
 def test_different(self):
     different_kwargs = self.kwargs
     different_kwargs["indices"] = self.kwargs["indices"].transpose()
     different = Connectivity(**different_kwargs)
     self.assertNotEqual(different, self.connectivity)
Example #15
0
def build_mesh(
    n_nodes=2,
    n_faces=0,
    n_edges=0,
    nodecoord_xyargs=None,
    edgecoord_xyargs=None,
    facecoord_xyargs=None,
    conn_role_kwargs=None,  # mapping {connectivity-role: connectivity-kwargs}
    mesh_kwargs=None,
):
    """
    Make a test mesh.

    Mesh has faces edges, face-coords and edge-coords, numbers of which can be
    controlled.

    Args:

    * n_nodes, n_faces, n_edges (int):
        Basic dimensions of mesh components.  Zero means no such location.
    * nodecoord_xyargs, edgecoord_xyargs, facecoord_xyargs (pair of dict):
        Pairs (x,y) of settings kwargs, applied after initial creation the
        relevant location coordinates.
    * conn_role_kwargs (dict of string:dict):
        Mapping from cf_role name to settings kwargs for connectivities,
        applied after initially creating them.
    * mesh_kwargs (dict):
        Dictionary of key settings to apply to the Mesh, after creating it.

    """

    def applyargs(coord, kwargs):
        if kwargs:
            for key, val in kwargs.items():
                # kwargs is a dict
                setattr(coord, key, val)

    def apply_xyargs(coords, xyargs):
        if xyargs:
            for coord, kwargs in zip(coords, xyargs):
                # coords and xyargs both iterables : implicitly=(x,y)
                applyargs(coord, kwargs)

    node_coords = [
        AuxCoord(np.arange(n_nodes), standard_name=name) for name in XY_NAMES
    ]
    apply_xyargs(node_coords, nodecoord_xyargs)

    connectivities = {}
    edge_coords = []
    face_coords = []
    topology_dimension = 0
    if n_edges:
        topology_dimension = 1
        connectivities["edge_node_connectivity"] = Connectivity(
            np.zeros((n_edges, 2), np.int32), cf_role="edge_node_connectivity"
        )
        edge_coords = [
            AuxCoord(np.arange(n_edges), standard_name=name)
            for name in XY_NAMES
        ]
        apply_xyargs(edge_coords, edgecoord_xyargs)

    if n_faces:
        topology_dimension = 2
        connectivities["face_node_connectivity"] = Connectivity(
            np.zeros((n_faces, 4), np.int32), cf_role="face_node_connectivity"
        )
        face_coords = [
            AuxCoord(np.arange(n_faces), standard_name=name)
            for name in XY_NAMES
        ]
        apply_xyargs(face_coords, facecoord_xyargs)

    mesh_dims = {"node": n_nodes, "edge": n_edges, "face": n_faces}

    if conn_role_kwargs:
        for role, kwargs in conn_role_kwargs.items():
            if role in connectivities:
                conn = connectivities[role]
            else:
                loc_from, loc_to, _ = role.split("_")
                dims = [mesh_dims[loc] for loc in (loc_from, loc_to)]
                conn = Connectivity(
                    np.zeros(dims, dtype=np.int32), cf_role=role
                )
                connectivities[role] = conn
            applyargs(conn, kwargs)

    mesh = Mesh(
        topology_dimension=topology_dimension,
        node_coords_and_axes=zip(node_coords, XY_LOCS),
        edge_coords_and_axes=zip(edge_coords, XY_LOCS),
        face_coords_and_axes=zip(face_coords, XY_LOCS),
        connectivities=connectivities.values(),
    )
    applyargs(mesh, mesh_kwargs)

    return mesh
Example #16
0
class TestStandard(tests.IrisTest):
    def setUp(self):
        # Crete an instance, with non-default arguments to allow testing of
        # correct property setting.
        self.kwargs = {
            "indices": np.linspace(1, 12, 12, dtype=int).reshape((4, -1)),
            "cf_role": "face_node_connectivity",
            "long_name": "my_face_nodes",
            "var_name": "face_nodes",
            "attributes": {
                "notes": "this is a test"
            },
            "start_index": 1,
            "location_axis": 1,
        }
        self.connectivity = Connectivity(**self.kwargs)

    def test_cf_role(self):
        self.assertEqual(self.kwargs["cf_role"], self.connectivity.cf_role)

    def test_location(self):
        expected = self.kwargs["cf_role"].split("_")[0]
        self.assertEqual(expected, self.connectivity.location)

    def test_connected(self):
        expected = self.kwargs["cf_role"].split("_")[1]
        self.assertEqual(expected, self.connectivity.connected)

    def test_start_index(self):
        self.assertEqual(self.kwargs["start_index"],
                         self.connectivity.start_index)

    def test_location_axis(self):
        self.assertEqual(self.kwargs["location_axis"],
                         self.connectivity.location_axis)

    def test_indices(self):
        self.assertArrayEqual(self.kwargs["indices"],
                              self.connectivity.indices)

    def test_read_only(self):
        attributes = ("indices", "cf_role", "start_index", "location_axis")
        for attribute in attributes:
            self.assertRaisesRegex(
                AttributeError,
                "can't set attribute",
                setattr,
                self.connectivity,
                attribute,
                1,
            )

    def test_transpose(self):
        expected_dim = 1 - self.kwargs["location_axis"]
        expected_indices = self.kwargs["indices"].transpose()
        new_connectivity = self.connectivity.transpose()
        self.assertEqual(expected_dim, new_connectivity.location_axis)
        self.assertArrayEqual(expected_indices, new_connectivity.indices)

    def test_lazy_indices(self):
        self.assertTrue(is_lazy_data(self.connectivity.lazy_indices()))

    def test_core_indices(self):
        self.assertArrayEqual(self.kwargs["indices"],
                              self.connectivity.core_indices())

    def test_has_lazy_indices(self):
        self.assertFalse(self.connectivity.has_lazy_indices())

    def test_lazy_location_lengths(self):
        self.assertTrue(is_lazy_data(
            self.connectivity.lazy_location_lengths()))

    def test_location_lengths(self):
        expected = [4, 4, 4]
        self.assertArrayEqual(expected, self.connectivity.location_lengths())

    def test___str__(self):
        expected = "\n".join([
            "Connectivity :  my_face_nodes / (unknown)",
            "    data: [",
            "        [ 1,  2,  3],",
            "        [ 4,  5,  6],",
            "        [ 7,  8,  9],",
            "        [10, 11, 12]]",
            "    shape: (4, 3)",
            "    dtype: int64",
            "    long_name: 'my_face_nodes'",
            "    var_name: 'face_nodes'",
            "    attributes:",
            "        notes  'this is a test'",
            "    cf_role: 'face_node_connectivity'",
            "    start_index: 1",
            "    location_axis: 1",
        ])
        self.assertEqual(expected, self.connectivity.__str__())

    def test___repr__(self):
        expected = "<Connectivity: my_face_nodes / (unknown)  [[1, 2, 3], ...]  shape(4, 3)>"
        self.assertEqual(expected, self.connectivity.__repr__())

    def test_xml_element(self):
        doc = minidom.Document()
        connectivity_element = self.connectivity.xml_element(doc)
        self.assertEqual(connectivity_element.tagName, "connectivity")
        for attribute in ("cf_role", "start_index", "location_axis"):
            self.assertIn(attribute, connectivity_element.attributes)

    def test___eq__(self):
        equivalent_kwargs = self.kwargs
        equivalent_kwargs["indices"] = self.kwargs["indices"].transpose()
        equivalent_kwargs["location_axis"] = 1 - self.kwargs["location_axis"]
        equivalent = Connectivity(**equivalent_kwargs)
        self.assertFalse(
            np.array_equal(equivalent.indices, self.connectivity.indices))
        self.assertEqual(equivalent, self.connectivity)

    def test_different(self):
        different_kwargs = self.kwargs
        different_kwargs["indices"] = self.kwargs["indices"].transpose()
        different = Connectivity(**different_kwargs)
        self.assertNotEqual(different, self.connectivity)

    def test_no_cube_dims(self):
        self.assertRaises(NotImplementedError, self.connectivity.cube_dims, 1)

    def test_shape(self):
        self.assertEqual(self.kwargs["indices"].shape, self.connectivity.shape)

    def test_ndim(self):
        self.assertEqual(self.kwargs["indices"].ndim, self.connectivity.ndim)

    def test___getitem_(self):
        subset = self.connectivity[:, 0:1]
        self.assertArrayEqual(self.kwargs["indices"][:, 0:1], subset.indices)

    def test_copy(self):
        new_indices = np.linspace(11, 16, 6, dtype=int).reshape((3, -1))
        copy_connectivity = self.connectivity.copy(new_indices)
        self.assertArrayEqual(new_indices, copy_connectivity.indices)

    def test_indices_by_location(self):
        expected = self.kwargs["indices"].transpose()
        self.assertArrayEqual(expected,
                              self.connectivity.indices_by_location())

    def test_indices_by_location_input(self):
        expected = as_lazy_data(self.kwargs["indices"].transpose())
        by_location = self.connectivity.indices_by_location(
            self.connectivity.lazy_indices())
        self.assertArrayEqual(expected, by_location)