- 
                Notifications
    You must be signed in to change notification settings 
- Fork 297
Merge dataless #6741
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
    
  
     Merged
                    Merge dataless #6741
Changes from 11 commits
      Commits
    
    
            Show all changes
          
          
            18 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      c8fa1b4
              
                Initial WIP for dataless merges -- cannot yet merge datafull+dataless.
              
              
                pp-mo c4165a9
              
                Starting tests.
              
              
                pp-mo 4715ad5
              
                Functioning backstop: merge can pass-through dataless, but not actual…
              
              
                pp-mo 222acb5
              
                Dataless merge, combine dataless with/without dataful.
              
              
                pp-mo b1be959
              
                Tidy awkward layout in test.
              
              
                pp-mo 37fc7f5
              
                Ensure that cube.shape can only be a tuple (or None).
              
              
                pp-mo 6b0087c
              
                Make test_merge check against dataless input in all its tests.
              
              
                pp-mo 46ccc67
              
                Improve tests, and test for lazy merge result.
              
              
                pp-mo 1c4f14c
              
                Fix typo.
              
              
                pp-mo e3eec6f
              
                Expand documentation.
              
              
                pp-mo e0c2cd8
              
                Fix broken ref + tweak whatsnew.
              
              
                pp-mo 4f9da22
              
                Merge branch 'main' into merge_dataless
              
              
                pp-mo c2bfca5
              
                Merge branch 'main' into merge_dataless
              
              
                pp-mo 1cb44e7
              
                Fixes following implementation of dataless save-and-load (#6739).
              
              
                pp-mo f2c1f30
              
                Remove redundant checks.
              
              
                pp-mo 43d02ef
              
                Make make_gridcube() dataless, and improve documentation cross-refs.
              
              
                pp-mo feba264
              
                Review changes: small fixes to docs.
              
              
                pp-mo 58aca88
              
                Use the intended dtype for data of all-masked arrays.
              
              
                pp-mo 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
    
  
  
    
              
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| .. _dataless-cubes: | ||
|  | ||
| ============== | ||
| Dataless Cubes | ||
| ============== | ||
| It is possible for a cube to exist without a data payload. | ||
| In this case ``cube.data`` is ``None``, instead of containing an array (real or lazy) as | ||
| usual. | ||
|  | ||
| This can be useful when the cube is used purely as a placeholder for metadata, e.g. to | ||
| represent a combination of coordinates. | ||
|  | ||
| Most notably, dataless cubes can be used as the target "grid cube" for most regridding | ||
| schemes, since in that case the cube's coordinates are all that the method uses. | ||
| See also :meth:`iris.util.make_gridcube`. | ||
|  | ||
|  | ||
| Properties of dataless cubes | ||
| ---------------------------- | ||
|  | ||
| * ``cube.shape`` is unchanged | ||
| * ``cube.data`` == ``None`` | ||
| * ``cube.dtype`` == ``None`` | ||
| * ``cube.core_data()`` == ``cube.lazy_data()`` == ``None`` | ||
| * ``cube.is_dataless()`` == ``True`` | ||
| * ``cube.has_lazy_data()`` == ``False`` | ||
|  | ||
|  | ||
| Cube creation | ||
| ------------- | ||
| You can create a dataless cube with the :meth:`~iris.cube.Cube` constructor | ||
| (i.e. ``__init__`` call), by specifying the ``shape`` keyword in place of ``data``. | ||
| If both are specified, an error is raised (even if data and shape are compatible). | ||
|  | ||
|  | ||
| Data assignment | ||
| --------------- | ||
| You can make an existing cube dataless, by setting ``cube.data = None``. | ||
| The data array is simply discarded. | ||
|  | ||
|  | ||
| Cube copy | ||
| --------- | ||
| The syntax that allows you to replace data on copying, | ||
| e.g. ``cube2 = cube.copy(new_data)``, has now extended to accept the special value | ||
| :data:`iris.DATALESS`. | ||
|  | ||
| So, ``cube2 = cube.copy(iris.DATALESS)`` makes ``cube2`` a | ||
| dataless copy of ``cube``. | ||
| This is equivalent to ``cube2 = cube.copy(); cube2.data = None``. | ||
|  | ||
|  | ||
| Save and Load | ||
| ------------- | ||
| The netcdf file interface can save and re-load dataless cubes correctly. | ||
| TODO: link to ref e.g. "netcdf_dataless" in netcdf docs, | ||
| when #6339 "Dataless netcdf save+load" is in place. | ||
|  | ||
|  | ||
| .. _dataless_merge: | ||
|  | ||
| Merging | ||
| ------- | ||
| Merging is fully supported for dataless cubes, including combining them with "normal" | ||
| cubes. | ||
|  | ||
| * in all cases, the result has the same shape and metadata as if the same cubes had | ||
| data. | ||
| * Merging multiple dataless cubes produces a dataless result. | ||
| * Merging dataless and non-dataless cubes results in a partially 'missing' data array, | ||
| i.e. the relevant sections are filled with masked data. | ||
| * Laziness is also preserved. | ||
|  | ||
|  | ||
| Operations NOT supported | ||
| ------------------------- | ||
| Dataless cubes are relatively new, and only partly integrated with Iris cube operations | ||
| generally. | ||
|  | ||
| The following are some of the notable features which do *not* support dataless cubes, | ||
| at least as yet : | ||
|  | ||
| * plotting | ||
|  | ||
| * cube arithmetic | ||
|  | ||
| * statistics | ||
|  | ||
| * concatenation | ||
|         
                  ukmo-ccbunney marked this conversation as resolved.
              Show resolved
            Hide resolved | ||
|  | ||
| * :meth:`iris.cube.CubeList.realise_data` | ||
|  | ||
| * various :class:`~iris.cube.Cube` methods, including at least: | ||
|  | ||
| * :meth:`~iris.cube.Cube.convert_units` | ||
|  | ||
| * :meth:`~iris.cube.Cube.subset` | ||
|  | ||
| * :meth:`~iris.cube.Cube.intersection` | ||
|  | ||
| * :meth:`~iris.cube.Cube.slices` | ||
|  | ||
| * :meth:`~iris.cube.Cube.interpolate` | ||
|  | ||
| * :meth:`~iris.cube.Cube.regrid` | ||
| Note: in this case the target ``grid`` can be dataless, but not the source | ||
| (``self``) cube. | ||
  
    
      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
    
  
  
    
              
  
    
      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
    
  
  
    
              
  
    
      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,65 @@ | ||
| # Copyright Iris contributors | ||
| # | ||
| # This file is part of Iris and is released under the BSD license. | ||
| # See LICENSE in the root of the repository for full licensing details. | ||
| """Integration tests for merging with dataless cubes.""" | ||
|  | ||
| import dask.array as da | ||
| import numpy as np | ||
|  | ||
| from iris.coords import AuxCoord, DimCoord | ||
| from iris.cube import Cube, CubeList | ||
|  | ||
|  | ||
| class TestMergeDataless: | ||
| def _testcube(self, z=1, name="this", dataless=False, lazy=False): | ||
| # Create a testcube with a scalar Z coord, for merge testing. | ||
| data = da.arange(3) if lazy else np.arange(3) | ||
| cube = Cube( | ||
| data, | ||
| long_name=name, | ||
| dim_coords_and_dims=[(DimCoord([0.0, 1.0, 2], long_name="x"), 0)], | ||
| aux_coords_and_dims=[(AuxCoord([z], long_name="z"), ())], | ||
| ) | ||
| if dataless: | ||
| cube.data = None | ||
| return cube | ||
|  | ||
| def test_mixed_passthrough(self): | ||
| # Check that normal merge can handle dataless alongside dataful cubes. | ||
| cube_normal = self._testcube(name="this", dataless=False) | ||
| cube_dataless = self._testcube(name="that", dataless=True) | ||
| cubes = CubeList([cube_normal, cube_dataless]) | ||
|  | ||
| result = cubes.merge() | ||
|  | ||
| assert len(result) == 2 | ||
| cube1, cube2 = [result.extract_cube(name) for name in ("this", "that")] | ||
| assert not cube1.is_dataless() | ||
| assert cube2.is_dataless() | ||
|  | ||
| def test_dataless_merge(self): | ||
| # Check that dataless cubes can be merged. | ||
| cube_1 = self._testcube(z=1, dataless=True) | ||
| cube_2 = self._testcube(z=2, dataless=True) | ||
| cubes = CubeList([cube_1, cube_2]) | ||
|  | ||
| cube = cubes.merge_cube() | ||
|  | ||
| assert cube.is_dataless() | ||
| assert np.all(cube.coord("z").points == [1, 2]) | ||
|  | ||
| def test_dataless_dataful_merge(self): | ||
| # Check that dataless cubes can merge **with** regular ones. | ||
| # Include checking that laziness is preserved. | ||
| cube_normal = self._testcube(z=1, dataless=False, lazy=True) | ||
| cube_dataless = self._testcube(z=2, dataless=True) | ||
| cubes = CubeList([cube_normal, cube_dataless]) | ||
|  | ||
| cube = cubes.merge_cube() | ||
|  | ||
| assert not cube.is_dataless() | ||
| assert cube.has_lazy_data() | ||
| data_z1, data_z2 = cube[0].data, cube[1].data | ||
| assert np.all(data_z1 == [0, 1, 2]) | ||
| assert np.all(np.ma.getmaskarray(data_z2) == True) # noqa: E712 | 
      
      Oops, something went wrong.
        
    
  
      
      Oops, something went wrong.
        
    
  
  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.
  
    
  
    
Uh oh!
There was an error while loading. Please reload this page.