brainhops.io.base.hdf5
Shared plumbing for formats stored in HDF5 files.
Several transformation formats are HDF5 containers -- ITK's binary
transforms (.h5) and BIDS X5 (.x5) among them -- and they cannot be
told apart by their container: both are HDF5 files, and both even keep
their transforms under a root group named TransformGroup. What
differs is their content, so each format only says how to recognise
and decode an open [h5py.File][], and the mixins here deal
with everything else: paths, open binary streams, bytes held in memory,
and lazily read datasets.
Hdf5Parserturns every input thatbrainhopsaccepts into an openh5py.File, and hands it to the format'ssniff_h5andfrom_h5.Hdf5ParserWriterdoes the same for writing, through the format'sto_h5.DelayedH5Arrayis a dataset that can still be read after its file was closed, by reopening it on demand.
h5py is an optional dependency, so this module is imported only by
the formats that need it, and only when it is installed.
Attributes
H5Like
module-attribute
Anything an HDF5 format can be read from or written to.
Classes
Hdf5Parser
Bases: BinaryFileParser
Reads a format stored in an HDF5 file.
A concrete format implements two class methods, both of which take an
open h5py.File:
sniff_h5(h5file, error=False) -> floatfrom_h5(h5file, keep_open=False, load=True, **kwargs) -> Self
and this mixin routes paths, streams and bytes to them. A path is
handed to h5py by name rather than as a stream, so that a dataset
read lazily (load=False) can reopen the file long after it was
parsed.
Attributes
EXTENSIONS
class-attribute
EXTENSIONS: tuple[str, ...] = ()
File extensions handled by this parser, e.g. (".nii", ".nii.gz").
Used as a first, cheap dispatch pass. When several parsers match,
the longest matching extension wins, so a parser declaring
".nii.gz" takes precedence over one declaring ".gz".
PREFIXES
class-attribute
PREFIXES: tuple[str, ...] = ()
Filename prefixes required by this parser, e.g. ("y_", "iy_").
An empty tuple means "no constraint". A parser that constrains the prefix is more specific than one that does not, and wins ties.
Declaring EXTENSIONS and PREFIXES separately states the
cross-product implicitly, which is how these conventions actually
work: SPM's four names are {y_, iy_} x {.nii, .nii.gz}.
PRIORITY
class-attribute
PRIORITY: int = 0
Explicit tie-breaker, consulted only when specificity cannot decide.
Higher wins. Leave at 0 unless two parsers genuinely collide.
Methods:
sniff_h5
classmethod
Score how confident the format is that an open HDF5 file is one of its files.
sniff_file
classmethod
Score a path, open HDF5 file, or binary stream.
sniff_filename
classmethod
sniff_filename(
filename: str | PathLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Score the HDF5 file found at a path.
sniff_fileobj
classmethod
Score an open, seekable binary stream.
sniff_bytes
classmethod
Score the bytes of an HDF5 file.
from_file
classmethod
Build an object from a file (path, file-like object, or HDF5 file).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
str | PathLike | IO | File
|
Input file. |
required |
keep_open
|
bool
|
If True, keep the HDF5 file open after loading.
If False, close the file after loading.
If |
False
|
load
|
bool
|
If True, read large datasets into memory. If False, keep them on disk. |
True
|
from_filename
classmethod
from_filename(
filename: str | PathLike,
keep_open: bool = False,
load: bool = True,
**kwargs,
) -> Self
Build an object from the HDF5 file found at a path.
from_fileobj
classmethod
Build an object from an open, seekable binary stream.
sniff
classmethod
sniff(
file: FileOrContentLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Determine if the given file is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
FileOrContentLike
|
The file to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the file cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the file is of this type, in |
sniff_content
classmethod
sniff_content(
content: ContentLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Determine if the given content is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
ContentLike
|
The content to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the content is of this type, in |
sniff_text
classmethod
Determine if the given text is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the text is of this type, in |
sniff_lines
classmethod
Determine if the given lines are of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lines
|
Iterable[str]
|
The lines to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the lines is of this type, in |
sniff_line
classmethod
Determine if the given line is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line
|
str
|
The line to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the line is of this type, in |
load
classmethod
load(other: FileOrContentLike, **kwargs) -> Self
Build an object from a file (path, file-like object or iterable of lines).
This is the generic front door to the from_* family: it looks
at what it was handed and calls the right one.
A str is always a path, whether or not the file exists, so a
missing file raises FileNotFoundError whichever way its path
was spelled. Text held in memory is read with from_text or
from_content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
FileOrContentLike
|
Input file, or its content. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
Raises:
| Type | Description |
|---|---|
ParserExistsError
|
If |
from_spec
classmethod
from_spec(spec: SourceSpec, **kwargs) -> Self
Build an object from an unqualified structured source.
from_content
classmethod
from_content(content: ContentLike, **kwargs) -> Self
Build an object from a file content (bytes, str, or iterable of lines).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
ContentLike
|
The content to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
from_bytes
classmethod
from_bytes(content: BinaryContentLike, **kwargs) -> Self
Build an object from a binary representation of a file.
If the class implements from_fileobj itself, the bytes are
wrapped in an io.BytesIO stream and handed to from_fileobj.
Otherwise, this raises ParserNotImplementedError: the default
from_fileobj delegates to from_bytes, so falling back to it
would recurse. A from_fileobj override that only forwards to
super().from_fileobj should be decorated with
_passthrough_from_fileobj; if it is not, the loop is still
detected when from_bytes is re-entered for the same class, and
ParserNotImplementedError is raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
BinaryContentLike
|
The content to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
Raises:
| Type | Description |
|---|---|
ParserNotImplementedError
|
If neither |
from_text
classmethod
Build an object from a text representation of a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
from_lines
classmethod
Hdf5ParserWriter
Bases: Hdf5Parser, BinaryFileParserWriter
Reads and writes a format stored in an HDF5 file.
On top of what Hdf5Parser asks for, a concrete format
implements to_h5(self, h5file, **kwargs), which fills a new, empty
HDF5 file open for writing.
Attributes
EXTENSIONS
class-attribute
EXTENSIONS: tuple[str, ...] = ()
File extensions handled by this parser, e.g. (".nii", ".nii.gz").
Used as a first, cheap dispatch pass. When several parsers match,
the longest matching extension wins, so a parser declaring
".nii.gz" takes precedence over one declaring ".gz".
PREFIXES
class-attribute
PREFIXES: tuple[str, ...] = ()
Filename prefixes required by this parser, e.g. ("y_", "iy_").
An empty tuple means "no constraint". A parser that constrains the prefix is more specific than one that does not, and wins ties.
Declaring EXTENSIONS and PREFIXES separately states the
cross-product implicitly, which is how these conventions actually
work: SPM's four names are {y_, iy_} x {.nii, .nii.gz}.
PRIORITY
class-attribute
PRIORITY: int = 0
Explicit tie-breaker, consulted only when specificity cannot decide.
Higher wins. Leave at 0 unless two parsers genuinely collide.
Methods:
to_h5
Write this object into an empty HDF5 file open for writing.
to_file
to_file(file: H5Like, **kwargs) -> None
Write to a path, an open binary stream, or an HDF5 file.
to_filename
Write to the file found at a path, replacing it.
sniff
classmethod
sniff(
file: FileOrContentLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Determine if the given file is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
FileOrContentLike
|
The file to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the file cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the file is of this type, in |
sniff_file
classmethod
Score a path, open HDF5 file, or binary stream.
sniff_filename
classmethod
sniff_filename(
filename: str | PathLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Score the HDF5 file found at a path.
sniff_fileobj
classmethod
Score an open, seekable binary stream.
sniff_content
classmethod
sniff_content(
content: ContentLike,
error: bool | Type[Exception] = False,
**kwargs,
) -> float
Determine if the given content is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
ContentLike
|
The content to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the content is of this type, in |
sniff_bytes
classmethod
Score the bytes of an HDF5 file.
sniff_text
classmethod
Determine if the given text is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the text is of this type, in |
sniff_lines
classmethod
Determine if the given lines are of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lines
|
Iterable[str]
|
The lines to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the lines is of this type, in |
sniff_line
classmethod
Determine if the given line is of the type that this parser can handle.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line
|
str
|
The line to sniff. |
required |
error
|
bool | type[Exception]
|
If not False, raise an error if the content cannot be sniffed. |
False
|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
float
|
Confidence that the line is of this type, in |
load
classmethod
load(other: FileOrContentLike, **kwargs) -> Self
Build an object from a file (path, file-like object or iterable of lines).
This is the generic front door to the from_* family: it looks
at what it was handed and calls the right one.
A str is always a path, whether or not the file exists, so a
missing file raises FileNotFoundError whichever way its path
was spelled. Text held in memory is read with from_text or
from_content.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
other
|
FileOrContentLike
|
Input file, or its content. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
Raises:
| Type | Description |
|---|---|
ParserExistsError
|
If |
from_spec
classmethod
from_spec(spec: SourceSpec, **kwargs) -> Self
Build an object from an unqualified structured source.
from_file
classmethod
Build an object from a file (path, file-like object, or HDF5 file).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
str | PathLike | IO | File
|
Input file. |
required |
keep_open
|
bool
|
If True, keep the HDF5 file open after loading.
If False, close the file after loading.
If |
False
|
load
|
bool
|
If True, read large datasets into memory. If False, keep them on disk. |
True
|
from_filename
classmethod
from_filename(
filename: str | PathLike,
keep_open: bool = False,
load: bool = True,
**kwargs,
) -> Self
Build an object from the HDF5 file found at a path.
from_fileobj
classmethod
Build an object from an open, seekable binary stream.
from_content
classmethod
from_content(content: ContentLike, **kwargs) -> Self
Build an object from a file content (bytes, str, or iterable of lines).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
ContentLike
|
The content to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
from_bytes
classmethod
from_bytes(content: BinaryContentLike, **kwargs) -> Self
Build an object from a binary representation of a file.
If the class implements from_fileobj itself, the bytes are
wrapped in an io.BytesIO stream and handed to from_fileobj.
Otherwise, this raises ParserNotImplementedError: the default
from_fileobj delegates to from_bytes, so falling back to it
would recurse. A from_fileobj override that only forwards to
super().from_fileobj should be decorated with
_passthrough_from_fileobj; if it is not, the loop is still
detected when from_bytes is re-entered for the same class, and
ParserNotImplementedError is raised.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
content
|
BinaryContentLike
|
The content to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
Raises:
| Type | Description |
|---|---|
ParserNotImplementedError
|
If neither |
from_text
classmethod
Build an object from a text representation of a file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
from_lines
classmethod
from_line
classmethod
Build an object from a single line of text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
line
|
str
|
The line to parse. |
required |
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
obj
|
The parsed object. |
save
save(file: FileLike, **kwargs) -> None
Write the object to a file (path or file-like object).
This is the generic front door to the to_* family. It is named
save rather than to because to already means something else
on the data models these parsers are mixed into: Transformation.to
converts an object to another type. A writer's to was shadowed
by it on every writable transformation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file
|
FileLike
|
The file to write to. |
required |
**kwargs
|
Parser-specific options. |
{}
|
to_text
to_text(**kwargs) -> str
Return a text version of the file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
A text version of the file. |
to_lines
Return a text version of the file as an iterable of lines.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
Iterator[str]
|
An iterable of lines representing the object. |
to_line
to_line(**kwargs) -> str
Return a line representing the object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Parser-specific options. |
{}
|
Returns:
| Type | Description |
|---|---|
str
|
A line representing the object. |
sniff_h5
classmethod
Score how confident the format is that an open HDF5 file is one of its files.
DelayedH5Array
An HDF5 dataset that can be read even after its file was closed, by reopening the file when needed.
Attributes
Methods:
to_dataset
Return the underlying h5py.Dataset, opening the file if
needed.
to_dask
to_dask(
*, keep_open: bool = False, **kwargs
) -> ArrayProtocol
Wrap the dataset as a dask array that reads chunks lazily.
__getitem__
Read the indexed chunk of the dataset, opening the file if needed.
__array__
__array__(dtype: dtype = None, copy: Any = None) -> ndarray
Read the whole dataset into a numpy array.
Functions:
read_string
Decode a string stored in HDF5, whatever its storage.
HDF5 strings come back from h5py as str (variable-length UTF-8
attributes), as bytes (fixed-length or ASCII ones), as numpy
scalars, or wrapped in a one-element array or dataset.
delayed_dataset
delayed_dataset(
h5file: File, key: str, keep_open: bool
) -> DelayedH5Array | ArrayProtocol
A dataset of an open file, to be read later rather than now.
With keep_open, the open file is held; otherwise the file is
reopened by name when the data is read. The result is wrapped in a
dask array when dask is installed.