scistudio.core.types
Canonical import root: from scistudio.core.types import ...
Self-contained public-API reference — 10 symbols from this module's __all__, with signatures and docstrings inlined (ADR-052 §7). Generated; do not hand-edit.
Array — class
Stability: stable · Since 0.3.1
class Array(DataObject)
Array(*, axes: 'list[str]', shape: 'tuple[int, ...] | None' = None, dtype: 'Any' = None, chunk_shape: 'tuple[int, ...] | None' = None, data: 'Any' = None, **kwargs: 'Any') -> 'None'
N-dimensional array with named axes, optionally chunked on disk.
Use this for any gridded numeric data — a 2D image, a 3D volume, a
time-lapse, a multi-channel stack. Naming the axes makes selections
self-documenting: stack.sel(z=10, c=0) reads one z-plane of one
channel without you tracking which position each axis is in.
A subclass can restrict which axes it accepts through three class
attributes that act as a schema: required_axes,
allowed_axes, and canonical_order. Plain Array
leaves all three permissive, so it accepts any axes you give it.
The axis names used for scientific imaging are t (time), z
(depth), c (discrete channel), lambda (continuous spectral), and
y / x (the two spatial axes). c and lambda are different
axes and may both appear on one array.
Example: >>> from scistudio.core.types import Array >>> stack = Array(axes=["z", "y", "x"], shape=(20, 512, 512)) >>> stack.ndim 3 >>> stack.axes ['z', 'y', 'x']
Members
ndim(self) -> 'int'—stable· Since0.3.1— Number of dimensions (the length ofaxes).sel(self, **kwargs: 'int | slice') -> 'Array'—stable· Since0.3.1— Select a sub-array by naming positions along one or more axes.with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.to_memory(self) -> 'Any'—stable· Since0.3.1— Load the full array into memory and return it.to_numpy(self) -> 'Any'—stable· Since0.3.1— Return the array data as a NumPyndarray.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Rebuild an array's constructor arguments from saved metadata.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return an array's own fields for the saved metadata.
Artifact — class
Stability: stable · Since 0.3.1
class Artifact(DataObject)
Artifact(*, file_path: 'Path | None' = None, mime_type: 'str | None' = None, description: 'str' = '', **kwargs: 'Any') -> 'None'
An opaque file: a PDF, a rendered report, an image, a binary blob.
Use an Artifact when the result of a step is a whole file that
downstream steps should carry along or save rather than inspect. SciStudio
does not parse its contents; it just tracks the file, its MIME type, and
a human-readable description.
Example: >>> from pathlib import Path >>> from scistudio.core.types import Artifact >>> report = Artifact( ... file_path=Path("/tmp/report.pdf"), ... mime_type="application/pdf", ... description="QC report", ... ) >>> report.mime_type 'application/pdf'
Members
with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Rebuild an artifact's constructor arguments from saved metadata.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return an artifact's own fields for the saved metadata.
Collection — class
Stability: stable · Since 0.3.1
class Collection
Collection(items: 'list[DataObject] | None' = None, item_type: 'type | None' = None) -> 'None'
An ordered batch of DataObject items, all of one type.
Blocks use a Collection to pass many items at once — a stack of
images, a set of spectra — while keeping the batch type-checkable at the
boundary between blocks. SciStudio itself never looks inside a
Collection; it only checks the item type for port matching.
Rules it enforces:
- every item must be an instance of the same
DataObjectsubclass; - the item type is fixed once the Collection is created;
- an empty Collection is allowed only if you state
item_typeexplicitly, so an empty batch still has a checkable type.
Example: >>> from scistudio.core.types import Array, Collection >>> imgs = [Array(axes=["y", "x"]), Array(axes=["y", "x"])] >>> batch = Collection(imgs) >>> batch.item_type.name 'Array' >>> len(batch) 2
Members
item_type(self) -> 'type'—stable· Since0.3.1— The element type shared by every item (fixed at creation).length(self) -> 'int'—stable· Since0.3.1— The number of items in the Collection.storage_refs(self) -> 'list[Any]'—stable· Since0.3.1— The storage reference of each item, in order.
CompositeData — class
Stability: stable · Since 0.3.1
class CompositeData(DataObject)
CompositeData(*, slots: 'dict[str, DataObject] | None' = None, **kwargs: 'Any') -> 'None'
A bundle of named DataObject slots.
Holds several data objects together under string keys — think "the image
goes in the image slot, the measurements in the table slot". A
subclass can fix which slots exist and what type each must be by setting
expected_slots; a plain CompositeData accepts any slots.
Example: >>> from scistudio.core.types import CompositeData, Text >>> bundle = CompositeData() >>> bundle.set("notes", Text(content="ok")) >>> bundle.slot_names ['notes'] >>> bundle.get("notes").content 'ok'
Members
get(self, slot_name: 'str') -> 'DataObject'—stable· Since0.3.1— Return the data object stored under slot_name.set(self, slot_name: 'str', data: 'DataObject') -> 'None'—stable· Since0.3.1— Store data under slot_name.slot_types(self) -> 'dict[str, type]'—stable· Since0.3.1— Return this class's expected slot-type mapping.slot_names(self) -> 'list[str]'—stable· Since0.3.1— The names of the currently populated slots.with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.
DataFrame — class
Stability: stable · Since 0.3.1
class DataFrame(DataObject)
DataFrame(*, columns: 'list[str] | None' = None, row_count: 'int | None' = None, schema: 'dict[str, Any] | None' = None, data: 'Any' = None, **kwargs: 'Any') -> 'None'
Columnar table of rows and named columns, backed by Arrow/Parquet.
Use this for any tabular result. The canonical in-memory form is a
pyarrow.Table; to_pandas and to_numpy are convenience
readers for inspection and export. Large tables stay on disk and are read
lazily.
Example: >>> from scistudio.core.types import DataFrame >>> table = DataFrame(columns=["mz", "intensity"], row_count=1024) >>> table.columns ['mz', 'intensity']
Members
with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.to_pandas(self) -> 'Any'—stable· Since0.3.1— Return the table as apandas.DataFrame.to_numpy(self) -> 'Any'—stable· Since0.3.1— Return the table values as a NumPyndarray.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Rebuild a table's constructor arguments from saved metadata.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return a table's own fields for the saved metadata.
DataObject — class
Stability: stable · Since 0.3.1
class DataObject
DataObject(*, framework: 'FrameworkMeta | None' = None, meta: 'BaseModel | None' = None, user: 'dict[str, Any] | None' = None, storage_ref: 'StorageReference | None' = None) -> 'None'
Base class for every first-class data object in SciStudio.
Concrete subclasses represent the kinds of data that blocks exchange:
Array, Series, DataFrame, Text,
Artifact, and CompositeData. You normally work with
those subclasses; this base class defines what they all share —
metadata, lazy access to stored data, and persistence.
Every instance carries three metadata slots:
framework— managed by SciStudio (identity, lineage). Read it, but treat it as read-only.meta— typed, validated metadata for a specific data kind, orNoneon a plainDataObject. A subclass opts in by declaring its own model in theMetaclass attribute.user— a free-formdictfor your own values. It must be JSON-serialisable because it travels between processes.
Example: >>> from scistudio.core.types import Text >>> doc = Text(content="hello", user={"sample_id": "S1"}) >>> doc.user["sample_id"] 'S1'
Members
framework(self) -> 'FrameworkMeta'—stable· Since0.3.1— Framework-managed metadata (identity, lineage, provenance).meta(self) -> 'BaseModel | None'—stable· Since0.3.1— Typed domain metadata (a PydanticBaseModel), orNone.user(self) -> 'dict[str, Any]'—stable· Since0.3.1— Free-form user metadata.with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some of the typedmetafields changed.dtype_info(self) -> 'TypeSignature'—stable· Since0.3.1— TheTypeSignaturedescribing this object's type.storage_ref(self) -> 'StorageReference | None'—stable· Since0.3.1— Where this object's data is persisted, orNone.to_memory(self) -> 'Any'—stable· Since0.3.1— Load the full data from storage into memory and return it.slice(self, *args: 'Any') -> 'Any'—stable· Since0.3.1— Read a sub-selection of the data without loading all of it.iter_chunks(self, chunk_size: 'int') -> 'Iterator[Any]'—stable· Since0.3.1— Yield the data in successive chunks, keeping memory bounded.save(self, path: 'str | Path') -> 'StorageReference'—provisional· Since0.3.1— Persist this object's data to path and remember where it went.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Return the extra constructor arguments needed to rebuild an object.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return the subclass-specific fields to store alongside an object.
Series — class
Stability: stable · Since 0.3.1
class Series(DataObject)
Series(*, index_name: 'str | None' = None, value_name: 'str | None' = None, length: 'int | None' = None, data: 'Any' = None, **kwargs: 'Any') -> 'None'
One-dimensional indexed data: a time series, chromatogram, or spectrum.
A single run of values paired with an index axis (for example intensity
vs. wavenumber). It is persisted as a one-column Arrow/Parquet table, so
to_memory returns a pyarrow.Table even after the series has
crossed a worker subprocess.
Example: >>> from scistudio.core.types import Series >>> spec = Series(index_name="wavenumber", value_name="intensity", length=1024) >>> spec.index_name 'wavenumber'
Members
with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.to_pandas(self) -> 'Any'—stable· Since0.3.1— Return the series as apandas.Series.to_numpy(self) -> 'Any'—stable· Since0.3.1— Return the series values as a NumPyndarray.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Rebuild a series' constructor arguments from saved metadata.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return a series' own fields for the saved metadata.
StorageReference — class
Stability: stable · Since 0.3.1
class StorageReference
StorageReference(backend: 'str', path: 'str', format: 'str | None' = None, metadata: 'dict[str, Any] | None' = None) -> None
Lightweight pointer to a data object stored in a backend.
A StorageReference records where a piece of data lives (which backend
and path) and optionally how it is encoded, without holding the data
itself. Backends accept and return these references when they read, write,
or slice data, so the rest of the runtime can pass data around by reference
instead of by value.
Example: >>> ref = StorageReference(backend="zarr", path="data/image.zarr") >>> ref.backend 'zarr'
Text — class
Stability: stable · Since 0.3.1
class Text(DataObject)
Text(*, content: 'str | None' = None, format: 'str' = 'plain', encoding: 'str' = 'utf-8', **kwargs: 'Any') -> 'None'
Textual data: plain text, Markdown, or JSON.
Use this for any string result — a note, a generated report, JSON output.
The format label records which flavour the text is, and
encoding records its character encoding.
Example: >>> from scistudio.core.types import Text >>> note = Text(content="All samples passed QC.", format="markdown") >>> note.format 'markdown'
Members
with_meta(self, **changes: 'Any') -> 'Self'—stable· Since0.3.1— Return a copy with some typedmetafields changed.reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'—provisional· Since0.3.1— Rebuild a text object's constructor arguments from saved metadata.serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'—provisional· Since0.3.1— Return a text object's own fields for the saved metadata.
TypeSignature — class
Stability: stable · Since 0.3.1
class TypeSignature
TypeSignature(type_chain: 'list[str]', slot_schema: 'dict[str, str] | None' = None, required_axes: 'frozenset[str] | None' = None) -> None
The semantic type of a DataObject, used for port matching.
A signature records the chain of type names from most general to most
specific (for example ["DataObject", "Array"]). SciStudio compares
these signatures to decide whether the output of one block may be fed
into the input port of the next.
You rarely build one by hand: from_type derives it from a class,
and DataObject.dtype_info returns the signature of a live object.
Example: >>> from scistudio.core.types import Array, TypeSignature >>> sig = TypeSignature.from_type(Array) >>> sig.type_chain ['DataObject', 'Array'] >>> sig.matches(TypeSignature(type_chain=["DataObject"])) True
Members
matches(self, other: 'TypeSignature') -> 'bool'—stable· Since0.3.1— Return whether this type can stand in for other.from_type(cls, data_type: 'type') -> 'TypeSignature'—stable· Since0.3.1— Build aTypeSignaturefrom aDataObjectsubclass.