diff --git a/Changelog.rst b/Changelog.rst index cfb32e6c..b195f0fc 100644 --- a/Changelog.rst +++ b/Changelog.rst @@ -3,6 +3,7 @@ Version ?.?.? **2026-??-??** +* Add ``__orthogonal_indexing__`` flag by `David Hassell `_ in https://github.com/NCAS-CMS/pyfive/issue/171 * Allow negative slices when indexing chunked data by `David Hassell `_ in https://github.com/NCAS-CMS/pyfive/pull/170 Version 1.0.1 diff --git a/pyfive/high_level.py b/pyfive/high_level.py index eddfac3b..1ab5e906 100644 --- a/pyfive/high_level.py +++ b/pyfive/high_level.py @@ -16,6 +16,7 @@ from pyfive.dataobjects import DataObjects, DatasetID from pyfive.misc_low_level import SuperBlock from pyfive.h5py import Datatype +from pyfive.p5t import P5VlenStringType, P5ReferenceType, P5SequenceType class Group(Mapping): @@ -502,6 +503,37 @@ def attrs(self): """attrs attribute.""" return self.id._meta.attributes + @property + def __orthogonal_indexing__(self): + """Flag to indicate whether indexing is orthogonal. + + In general, the flag will be `True` if: + + * The data is chunked. + * The data is contiguous and memory mapped access is not + available. + + """ + if self.id.chunks is not None: + # Chunked data indexed with + # `DatasetID._get_selection_via_chunks` + return True + + if ( + not ( + isinstance( + self.id._ptype, (P5ReferenceType, P5VlenStringType, P5SequenceType) + ) + ) + and not self.id.posix + ): + # Contiguous data indexed with + # `DatasetID._get_direct_from_contiguous` + return True + + # All other cases + return False + class DimensionManager(Sequence): """Represents a collection of dimensions associated with a dataset.""" diff --git a/tests/test_dataset_indexing.py b/tests/test_dataset_indexing.py index 970e75ac..63e4c73a 100644 --- a/tests/test_dataset_indexing.py +++ b/tests/test_dataset_indexing.py @@ -10,6 +10,7 @@ DIRNAME = os.path.dirname(__file__) DATASET_CHUNKED_FILE = os.path.join(DIRNAME, "data/chunked.hdf5") +DATASET_CONTIGUOUS_FILE = os.path.join(DIRNAME, "data/dataset_multidim.hdf5") # Define a fixture that opens the chunked file once @@ -19,6 +20,13 @@ def chunked_file(): yield hfile +# Define a fixture that opens the contiguous file once +@pytest.fixture(scope="module") +def contiguous_file(): + with pyfive.File(DATASET_CONTIGUOUS_FILE) as hfile: + yield hfile + + @pytest.mark.parametrize( "index", [ @@ -65,3 +73,8 @@ def test_dataset_indexing_replace_negative_slices(): # Can't pass in in Ellipsis with pytest.raises(ValueError) as error: func((0, slice(6, 0, -2), ...), (7, 8, 9)) + + +def test_dataset_orthogonal_indexing(chunked_file, contiguous_file): + assert chunked_file["dataset1"].__orthogonal_indexing__ is True + assert contiguous_file["d"].__orthogonal_indexing__ is False