NdfOutputArchive#

class lsst.images.ndf.NdfOutputArchive(file: File, compression_options: Mapping[str, Any] | None = None, opaque_metadata: FitsOpaqueMetadata | None = None, root: Ndf | NdfContainer | None = None, lsst_path: str = '/MORE/LSST', direct_ndf_array_paths: Mapping[str, str] | None = None, wcs_ndf_paths: Sequence[str] = ('/',))#

Bases: OutputArchive[NdfPointerModel]

An OutputArchive implementation that writes HDS-on-HDF5 files compatible with the Starlink NDF data model.

Parameters#

file

An open h5py.File opened in a writable mode. The archive does not close the file; the caller is responsible for that.

compression_options

Optional dict passed through to h5py.Group.create_dataset for image arrays (e.g. {"compression": "gzip", "compression_opts": 4}).

opaque_metadata

Optional FitsOpaqueMetadata; if its primary-HDU header is non-empty its cards will be written to /MORE/FITS by the top-level write function.

Methods Summary

add_array(array, *[, name, update_header])

Add an array to the archive.

add_structured_array(array, *[, name, ...])

Add a table to the archive.

add_table(table, *[, name, update_header])

Add a table to the archive.

add_tree(tree, *[, projection, bbox, unit, ...])

Finalize the file: write WCS, units, JSON tree, and ORIGIN.

iter_frame_sets()

Iterate over the frame sets already serialized to this archive.

open(filename, *[, compression_options, ...])

Open an NDF file for writing and yield an NdfOutputArchive.

serialize_direct(name, serializer)

Use a serializer function to save a nested object.

serialize_frame_set(name, frame_set, ...)

Serialize a frame set and make it available to objects saved later.

serialize_pointer(name, serializer, key)

Use a serializer function to save a nested object that may be referenced in multiple locations in the same archive.

set_array_origin(struct_path, origin)

Overwrite the ORIGIN of an ARRAY structure.

Methods Documentation

add_array(array: ~numpy.ndarray, *, name: str | None = None, update_header: ~collections.abc.Callable[[~astropy.io.fits.header.Header], None] = <function no_header_updates>) ArrayReferenceModel#

Add an array to the archive.

Parameters#

array

Array to save.

name

Name of the array. This should generally be the name of the Pydantic model attribute to which the result will be assigned. It may be left None if there is only one [structured] array or table in a nested object that is being saved.

update_header

A callback that will be given the FITS header for the HDU containing this array in order to add keys to it. This callback may be provided but will not be called if the output format is not FITS.

Returns#

ArrayReferenceModel | InlineArrayModel

A Pydantic model that references or holds the stored array.

add_structured_array(array: ~numpy.ndarray, *, name: str | None = None, units: ~collections.abc.Mapping[str, ~astropy.units.core.Unit] | None = None, descriptions: ~collections.abc.Mapping[str, str] | None = None, update_header: ~collections.abc.Callable[[~astropy.io.fits.header.Header], None] = <function no_header_updates>) TableModel#

Add a table to the archive.

Parameters#

name

Attribute of the paired Pydantic model that will be assigned the result of this call. If it will not be assigned to a direct attribute, it may be a JSON Pointer path (relative to the paired Pydantic model) to the location where it will be added.

array

A structured numpy array.

name

Name of the array. This should generally be the name of the Pydantic model attribute to which the result will be assigned. It may be left None if there is only one [structured] array or table in a nested object that is being saved.

units

A mapping of units for columns. Need not be complete.

descriptions

A mapping of descriptions for columns. Need not be complete.

update_header

A callback that will be given the FITS header for the HDU containing this table in order to add keys to it. This callback may be provided but will not be called if the output format is not FITS.

Returns#

TableModel

A Pydantic model that represents the table.

add_table(table: ~astropy.table.table.Table, *, name: str | None = None, update_header: ~collections.abc.Callable[[~astropy.io.fits.header.Header], None] = <function no_header_updates>) TableModel#

Add a table to the archive.

Parameters#

table

Table to save.

name

Name of the table. This should generally be the name of the Pydantic model attribute to which the result will be assigned. It may be left None if there is only one [structured] array or table in a nested object that is being saved.

update_header

A callback that will be given the FITS header for the HDU containing this table in order to add keys to it. This callback may be provided but will not be called if the output format is not FITS.

Returns#

TableModel

A Pydantic model that represents the table.

add_tree(tree: ArchiveTree, *, projection: Any = None, bbox: Any = None, unit: UnitBase | None = None, root_name: str | None = None) None#

Finalize the file: write WCS, units, JSON tree, and ORIGIN.

Writes the canonical NDF /WCS HDS structure (an AST channel text dump that KAPPA / hdstrace expect) when projection is provided. A native mask sub-NDF at /MORE/LSST/MASK gets a 3D WCS whose first two axes reuse the parent’s sky projection and whose third axis is the mask-byte coordinate. The JSON tree at <lsst_path>/JSON remains the source of truth for symmetric round-trips; /WCS is for Starlink tools. Auto-detect read of /WCS/DATA into a typed Projection is a follow-up.

Parameters#

tree

Pydantic tree returned by the object’s serialize method, with metadata/butler_info already applied.

projection, bbox, unit

Top-level object attributes that drive NDF-canonical writes.

root_name

Value to assign to the root group’s HDS_ROOT_NAME attribute (fixed-length ASCII so KAPPA / hdstrace decode it).

iter_frame_sets() Iterator[tuple[FrameSet, NdfPointerModel]]#

Iterate over the frame sets already serialized to this archive.

Yields#

frame_set

A frame set that has already been written to this archive.

reference

An implementation-specific reference model that points to the frame set.

classmethod open(filename: str | None, *, compression_options: Mapping[str, Any] | None = None, opaque_metadata: FitsOpaqueMetadata | None = None, root: Ndf | NdfContainer | None = None, lsst_path: str = '/MORE/LSST', direct_ndf_array_paths: Mapping[str, str] | None = None, wcs_ndf_paths: Sequence[str] = ('/',)) Iterator[Self]#

Open an NDF file for writing and yield an NdfOutputArchive.

filename=None uses an in-memory HDF5 file; the on-disk artefact is discarded but the archive’s writes still produce a usable returned tree (handy for tests).

serialize_direct(name: str, serializer: Callable[[OutputArchive[NdfPointerModel]], T]) T#

Use a serializer function to save a nested object.

Parameters#

name

Attribute of the paired Pydantic model that will be assigned the result of this call. If it will not be assigned to a direct attribute, it may be a JSON Pointer path (relative to the paired Pydantic model) to the location where it will be added.

serializer

Callable that takes an OutputArchive and returns a Pydantic model. This will be passed a new OutputArchive that automatically prepends {name}/ (and any root path added by this archive) to names passed to it, so the serializer does not need to know where it appears in the overall tree.

Returns#

T

Result of the call to the serializer.

serialize_frame_set(name: str, frame_set: FrameSet, serializer: Callable[[OutputArchive], T], key: Hashable) NdfPointerModel#

Serialize a frame set and make it available to objects saved later.

Parameters#

name

Attribute of the paired Pydantic model that will be assigned the result of this call. If it will not be assigned to a direct attribute, it may be a JSON Pointer path (relative to the paired Pydantic model) to the location where it will be added.

frame_set

The frame set being saved. This will be returned in later calls to iter_frame_sets, along with the returned reference object.

serializer

Callable that takes an OutputArchive and returns a Pydantic model. This will be passed a new OutputArchive that automatically prepends {name}/ (and any root path added by this archive) to names passed to it, so the serializer does not need to know where it appears in the overall tree.

key

A unique identifier for the in-memory object the serializer saves, e.g. a call to the built-in id function.

Returns#

T | P

Either the result of the call to the serializer, or a Pydantic model that can be considered a reference to it and added to a larger model in its place.

serialize_pointer(name: str, serializer: Callable[[OutputArchive[NdfPointerModel]], T], key: Hashable) NdfPointerModel#

Use a serializer function to save a nested object that may be referenced in multiple locations in the same archive.

Parameters#

name

Attribute of the paired Pydantic model that will be assigned the result of this call. If it will not be assigned to a direct attribute, it may be a JSON Pointer path (relative to the paired Pydantic model) to the location where it will be added.

serializer

Callable that takes an OutputArchive and returns a Pydantic model. This will be passed a new OutputArchive that automatically prepends {name}/ (and any root path added by this archive) to names passed to it, so the serializer does not need to know where it appears in the overall tree.

key

A unique identifier for the in-memory object the serializer saves, e.g. a call to the built-in id function.

Returns#

T | P

Either the result of the call to the serializer, or a Pydantic model that can be considered a reference to it and added to a larger model in its place.

set_array_origin(struct_path: str, origin: tuple[int, ...]) None#

Overwrite the ORIGIN of an ARRAY structure.

Parameters#

struct_path

HDF5 path to the ARRAY structure (e.g. "/DATA_ARRAY").

origin

Origin in NDF/Fortran axis order (e.g. (x_min, y_min) for a 2D image with bbox lower bound (x_min, y_min)).