def common_test_setup(self, shape_3d=(0, 2), data_chunks=None): # Construct a basic testcase with all-lazy mesh_cube and submesh_cubes # full-mesh cube shape is 'shape_3d' # data_chunks sets chunking of source cube, (else all-1-chunk) n_outer, n_z = shape_3d n_mesh = 20 mesh = sample_mesh(n_nodes=20, n_edges=0, n_faces=n_mesh) mesh_cube = sample_mesh_cube(n_z=n_z, mesh=mesh) # Fix index-coord name to the expected default for recombine_submeshes. mesh_cube.coord("i_mesh_face").rename("i_mesh_index") if n_outer: # Crudely merge a set of copies to build an outer dimension. mesh_cube.add_aux_coord(AuxCoord([0], long_name="outer")) meshcubes_2d = [] for i_outer in range(n_outer): cube = mesh_cube.copy() cube.coord("outer").points = np.array([i_outer]) meshcubes_2d.append(cube) mesh_cube = CubeList(meshcubes_2d).merge_cube() if not data_chunks: data_chunks = mesh_cube.shape[:-1] + (-1, ) mesh_cube.data = da.zeros(mesh_cube.shape, chunks=data_chunks) n_regions = 4 # it doesn't divide neatly region_len = n_mesh // n_regions i_points = np.arange(n_mesh) region_inds = [ np.where((i_points // region_len) == i_region) for i_region in range(n_regions) ] # Disturb slightly to ensure some gaps + some overlaps region_inds = [list(indarr[0]) for indarr in region_inds] region_inds[2] = region_inds[2][:-2] # missing points region_inds[3] += region_inds[1][:2] # duplicates self.mesh_cube = mesh_cube self.region_inds = region_inds self.region_cubes = [mesh_cube[..., inds] for inds in region_inds] for i_cube, cube in enumerate(self.region_cubes): for i_z in range(n_z): # Set data='z' ; don't vary over other dimensions. cube.data[..., i_z, :] = i_cube + 1000 * i_z + 1 cube.data = cube.lazy_data() # Also construct an array to match the expected result (2d cases only). # basic layer showing region allocation (large -ve values for missing) expected = np.array([1.0, 1, 1, 1, 1] + [4, 4] # points in #1 overlapped by #3 + [2, 2, 2] + [3, 3, 3] + [-99999, -99999] # missing points + [4, 4, 4, 4, 4]) # second layer should be same but +1000. # NOTE: only correct if shape_3d=None; no current need to generalise this. expected = np.stack([expected, expected + 1000]) # convert to masked array with missing points. expected = np.ma.masked_less(expected, 0) self.expected_result = expected
def test_unstructured_cube(self): cube = sample_mesh_cube() rep = CubeSummary(cube) # Just check that coordinates appear in the expected sections dim_section = rep.vector_sections["Dimension coordinates:"] mesh_section = rep.vector_sections["Mesh coordinates:"] aux_section = rep.vector_sections["Auxiliary coordinates:"] self.assertEqual(len(dim_section.contents), 2) self.assertEqual(len(mesh_section.contents), 2) self.assertEqual(len(aux_section.contents), 1)
def generate_cube_like_2d_cubesphere(n_cube: int, with_mesh: bool, output_path: str): """ Construct and save to file an LFRIc cubesphere-like cube for a given cubesphere size, *or* a simpler structured (UM-like) cube of equivalent size. NOTE: this function is *NEVER* called from within this actual package. Instead, it is to be called via benchmarks.remote_data_generation, so that it can use up-to-date facilities, independent of the ASV controlled environment which contains the "Iris commit under test". This means: * it must be completely self-contained : i.e. it includes all its own imports, and saves results to an output file. """ from iris import save from iris.tests.stock.mesh import sample_mesh, sample_mesh_cube n_face_nodes = n_cube * n_cube n_faces = 6 * n_face_nodes # Set n_nodes=n_faces and n_edges=2*n_faces # : Not exact, but similar to a 'real' cubesphere. n_nodes = n_faces n_edges = 2 * n_faces if with_mesh: mesh = sample_mesh(n_nodes=n_nodes, n_faces=n_faces, n_edges=n_edges, lazy_values=True) cube = sample_mesh_cube(mesh=mesh, n_z=1) else: cube = sample_mesh_cube(nomesh_faces=n_faces, n_z=1) # Strip off the 'extra' aux-coord mapping the mesh, which sample-cube adds # but which we don't want. cube.remove_coord("mesh_face_aux") # Save the result to a named file. save(cube, output_path)
def test_unstructured_cube(self): # Check a sample mesh-cube against the expected result. cube = sample_mesh_cube() rep = cube_replines(cube) expected = [ "mesh_phenom / (unknown) (level: 2; i_mesh_face: 3)", " Dimension coordinates:", " level x -", " i_mesh_face - x", " Mesh coordinates:", " latitude - x", " longitude - x", " Auxiliary coordinates:", " mesh_face_aux - x", ] self.assertEqual(rep, expected)