This repository was archived by the owner on Jul 8, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
Ucubes summaries #27
Merged
Merged
Ucubes summaries #27
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
d2f7b5f
Load unstructured cubes as a new UCube subclass.
pp-mo b28fa58
UCubes provide extended cube summaries.
pp-mo a5b9b6d
Tidy mesh lines in ucube summary.
pp-mo fe514e3
Add test for ucube._repr_html_.
pp-mo e2690de
Codestyle fixes.
pp-mo 199c391
Codestyle fix.
pp-mo eccd444
Blackify.
trexfeathers 5e7f4a6
Clearer boolean statement for UCube checking that self.ugrid exists.
trexfeathers 5b0d1bd
Split UCube summary indent variable into _number and _string variables.
trexfeathers dc3665e
Clearer docstring and comment for UGridCFReader.cube_completion_adjus…
trexfeathers 8cf8e94
More logical import for test_UCube.py.
trexfeathers 33b8fc7
Include None in UGridCFReader.cube_completion_adjust Returns docstring.
trexfeathers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| # Copyright Iris-ugrid contributors | ||
| # | ||
| # This file is part of Iris and is released under the LGPL license. | ||
| # See COPYING and COPYING.LESSER in the root of the repository for full | ||
| # licensing details. | ||
| """ | ||
| Test basic :class:`iris_ugrid.ucube.Ucube` object. | ||
| """ | ||
| import iris.tests as tests | ||
|
|
||
| import re | ||
|
|
||
| from iris import Constraint | ||
| from iris.cube import CubeList | ||
|
|
||
| from iris_ugrid.ugrid_cf_reader import load_cubes | ||
|
|
||
|
|
||
| class Test_cube_representations(tests.IrisTest): | ||
| def setUp(self): | ||
| file_path = tests.get_data_path( | ||
| ("NetCDF", "unstructured_grid", "theta_nodal_xios.nc") | ||
| ) | ||
| loaded_cubes = CubeList(load_cubes(file_path)) | ||
| (cube,) = loaded_cubes.extract(Constraint("theta")) | ||
| # Prune the attributes, just because there are a lot. | ||
| keep_attrs = ["timeStamp", "Conventions"] | ||
| cube.attributes = { | ||
| key: value | ||
| for key, value in cube.attributes.items() | ||
| if key in keep_attrs | ||
| } | ||
| self.ucube = cube | ||
|
|
||
| def test_summary_short(self): | ||
| # Check the short-form of a UCube summary. | ||
| # This the same as what will appear in a CubeList string repr. | ||
| result = self.ucube.summary(shorten=True) | ||
| expected = ( | ||
| "Potential Temperature / (K) " | ||
| "(time: 1; levels: 6; *-- : 866)" | ||
| ) | ||
| self.assertEqual(result, expected) | ||
|
|
||
| def test_summary_long(self): | ||
| result = str(self.ucube) | ||
| expected = """\ | ||
| Potential Temperature / (K) (time: 1; levels: 6; *-- : 866) | ||
| Dimension coordinates: | ||
| time x - - | ||
| levels - x - | ||
| Auxiliary coordinates: | ||
| time x - - | ||
| Unstructured mesh: | ||
| Mesh0.node - - x | ||
| topology_dimension "2" : | ||
| node_coordinates "latitude longitude" : | ||
| <unprintable mesh> | ||
| Attributes: | ||
| Conventions: UGRID | ||
| timeStamp: 2016-Oct-24 15:16:48 BST | ||
| Cell methods: | ||
| point: time\ | ||
| """ | ||
| self.assertEqual(result, expected) | ||
|
|
||
| def test__repr_html_(self): | ||
| result = self.ucube._repr_html_() | ||
| # Check for some key pieces of html, which indicate that it includes | ||
| # a summary of the unstructured dimension, and mesh details. | ||
| str_dim = '<th class="iris iris-word-cell">*--</th>' | ||
| self.assertIn(str_dim, result) | ||
| str_section = ( | ||
| '<td class="iris-title iris-word-cell">Unstructured mesh</td>' | ||
| ) | ||
| self.assertIn(str_section, result) | ||
| re_mesh = ( | ||
| r'<td class="iris-word-cell iris-subheading-cell">' | ||
| r"\s*Mesh0\s*</td>" | ||
| r'\s*<td class="iris-inclusion-cell">node</td>' | ||
| ) | ||
| self.assertIsNotNone(re.search(re_mesh, result)) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| tests.main() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| # Copyright Iris contributors | ||
| # | ||
| # This file is part of Iris and is released under the LGPL license. | ||
| # See COPYING and COPYING.LESSER in the root of the repository for full | ||
| # licensing details. | ||
| """ | ||
| Defines the UCube : a cube which has an unstructured mesh dimension. | ||
|
|
||
| """ | ||
| from iris.cube import Cube | ||
|
|
||
|
|
||
| class UCube(Cube): | ||
| # Derived 'unstructured' Cube subtype, with a '.ugrid' property. | ||
| def __init__(self, *args, ugrid=None, **kwargs): | ||
| super().__init__(*args, **kwargs) | ||
| self.ugrid = ugrid | ||
|
|
||
| def _summary_dim_name(self, dim): | ||
| """ | ||
| Add an identifying "*" prefix to the mesh dimension. | ||
|
|
||
| This specialises the labelling of dims in cube summaries. | ||
|
|
||
| """ | ||
| name = super()._summary_dim_name(dim) | ||
| if self.ugrid is not None and dim == self.ugrid.cube_dim: | ||
| name = "*" + name | ||
| return name | ||
|
|
||
| def _summary_vector_sections_info(self): | ||
| """ | ||
| Build the "vector summary sections" list. This has the standard form, | ||
| plus one extra section to contain the mesh. | ||
|
|
||
| This extends cube summaries with a row showing the mesh as for a | ||
| coordinate, showing which cube dims it maps to. | ||
|
|
||
| """ | ||
| specs = super()._summary_vector_sections_info() | ||
| if self.ugrid: | ||
| Spec = Cube._VectorSectionSpec | ||
| specs.append( | ||
| Spec( | ||
| title="Unstructured mesh", | ||
| elements=[self.ugrid], | ||
| add_extra_lines=True, | ||
| ) | ||
| ) | ||
| return specs | ||
|
|
||
| def summary(self, shorten=False, *args, **kwargs): | ||
| """ | ||
| Provide cube summaries, extended to include mesh information. | ||
|
|
||
| """ | ||
| summary = super().summary(shorten=shorten, *args, **kwargs) | ||
| if self.ugrid and not shorten: | ||
| # Get a mesh description : as it prints itself. | ||
| detail_lines = str(self.ugrid).split("\n") | ||
| # Use only certain parts: which happens to be the last N lines. | ||
| (i_wanted_line,) = [ | ||
| i | ||
| for i, line in enumerate(detail_lines) | ||
| if "topology_dimension" in line | ||
| ] | ||
| # Cut out end portion, strip lines and discard blank ones. | ||
| detail_lines = detail_lines[i_wanted_line:] | ||
| detail_lines = [line.strip() for line in detail_lines] | ||
| detail_lines = [line for line in detail_lines if line] | ||
|
|
||
| # Find the section that shows the grid info. | ||
| summary_lines = summary.split("\n") | ||
| ugrid_section_title = "Unstructured mesh" | ||
| (i_ugrid_line,) = [ | ||
| i | ||
| for i, line in enumerate(summary_lines) | ||
| if line.strip().startswith(ugrid_section_title) | ||
| ] | ||
|
|
||
| # Get the indent of the line below (the grid variable dims). | ||
| next_line = summary_lines[i_ugrid_line + 1] | ||
| indent_number = [ | ||
| ind for ind, char in enumerate(next_line) if char != " " | ||
| ][0] | ||
|
|
||
| # Indent the mesh details 4 spaces more than that. | ||
| indent_string = " " * (indent_number + 4) | ||
| detail_lines = [indent_string + line for line in detail_lines] | ||
|
|
||
| # Splice in the detail lines after that, indenting to match. | ||
| i_next_section = i_ugrid_line + 2 | ||
| summary_lines[i_next_section:i_next_section] = detail_lines | ||
|
|
||
| summary = "\n".join(summary_lines) | ||
|
|
||
| return summary |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to say somewhere that this actually returns a
UCube.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dc3665e