spool_to_xarray

function of dascore.xarray.spool source

spool_to_xarray(
    spool: Spool ,
    dim: str = time,
    group: str | Sequence[str] | None = None,
    tolerance = 1.5,
    conflict: Literal[‘drop’, ‘raise’, ‘keep_first’] = raise,
    block_size: str | int | None[str, int, None] = None,
)

Convert a spool to a lazy, dask-backed xarray DataTree.

Patches are partitioned exactly as chunk partitions them: one tree node per group of related patches, holding one child node per merged output (segment_0 onward, ordered along dim), each with a dask-backed data variable. Node names follow the spool’s own naming rule — the one its repr’s tracks and a coverage plot’s lanes use. Building the tree reads no patch data — every shape, dtype, and coordinate comes from the spool’s metadata — and computing a selection loads only the source patches it touches.

Parameters

Parameter Description
spool The spool to convert.
dim The dimension segments are merged along.
group Attributes which partition patches into unrelated groups, exactly
as chunk uses them. Defaults to the config’s patch_kind_attrs.
tolerance The continuity tolerance deciding when a gap splits segments, as
in chunk (not the sampling-step grouping tolerance).
conflict How attribute conflicts within a segment resolve, as in chunk.
block_size The most a single dask block may hold, as a byte count or a
string dask parses (“256MiB”, “1GB”). This bounds a bulk read:
computing a whole segment asks for one block at a time, so a
source patch bigger than this is read in several windows along
dim rather than whole. It does not affect a selection, which
reads only what it asks for whatever the blocks are. None takes
the configured xarray_block_size (256 MiB by default); zero
makes each source patch one block. A patch whose format cannot
hand back a window (see FiberIO.read_array) stays one block
whatever this says: splitting it would read the file once per
block instead of once.
Note

A selection reads only the samples it names: the arrays are backed by a source spanning each segment, and dask fuses the selection into that source’s own read, which asks each member for its part of the window and no other member at all.

Requires xarray and dask. Coordinates associated with a dimension (rather than defining one) are not carried into the tree, and coordinates are rebuilt from their indexed envelopes, whose numeric values are floats — an integer-valued dimension coordinate comes back as floats.

An evenly sampled datetime/timedelta dimension coordinate is served lazily: its labels are computed from start and step on demand rather than stored, so an arbitrarily long merged time coordinate costs nothing to build. Label selection on it resolves arithmetically — a scalar must land on a sample (or pass method="nearest"), a slice keeps every sample within its inclusive endpoints — and reading .values or asking for the pandas index materializes labels on demand. A merged coordinate which is not one even range (a sub-tolerance seam between differently sampled members) spells its values out, as it must.

A spool with pending value-range selections cannot be converted: the catalog states such bounds as candidacy rather than sample positions, so the arrays cannot be sized without reading. Convert first and select on the tree (e.g. sel(time=...)), or select with samples=True on dimensions, which stays exact. Pending inventory enrichment is likewise refused, since the tree would omit the enriched attributes.