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.

Arrayclass

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 · Since 0.3.1 — Number of dimensions (the length of axes).
  • sel(self, **kwargs: 'int | slice') -> 'Array'stable · Since 0.3.1 — Select a sub-array by naming positions along one or more axes.
  • with_meta(self, **changes: 'Any') -> 'Self'stable · Since 0.3.1 — Return a copy with some typed meta fields changed.
  • to_memory(self) -> 'Any'stable · Since 0.3.1 — Load the full array into memory and return it.
  • to_numpy(self) -> 'Any'stable · Since 0.3.1 — Return the array data as a NumPy ndarray.
  • reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'provisional · Since 0.3.1 — Rebuild an array's constructor arguments from saved metadata.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return an array's own fields for the saved metadata.

Artifactclass

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 · Since 0.3.1 — Return a copy with some typed meta fields changed.
  • reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'provisional · Since 0.3.1 — Rebuild an artifact's constructor arguments from saved metadata.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return an artifact's own fields for the saved metadata.

Collectionclass

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 DataObject subclass;
  • the item type is fixed once the Collection is created;
  • an empty Collection is allowed only if you state item_type explicitly, 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 · Since 0.3.1 — The element type shared by every item (fixed at creation).
  • length(self) -> 'int'stable · Since 0.3.1 — The number of items in the Collection.
  • storage_refs(self) -> 'list[Any]'stable · Since 0.3.1 — The storage reference of each item, in order.

CompositeDataclass

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 · Since 0.3.1 — Return the data object stored under slot_name.
  • set(self, slot_name: 'str', data: 'DataObject') -> 'None'stable · Since 0.3.1 — Store data under slot_name.
  • slot_types(self) -> 'dict[str, type]'stable · Since 0.3.1 — Return this class's expected slot-type mapping.
  • slot_names(self) -> 'list[str]'stable · Since 0.3.1 — The names of the currently populated slots.
  • with_meta(self, **changes: 'Any') -> 'Self'stable · Since 0.3.1 — Return a copy with some typed meta fields changed.

DataFrameclass

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 · Since 0.3.1 — Return a copy with some typed meta fields changed.
  • to_pandas(self) -> 'Any'stable · Since 0.3.1 — Return the table as a pandas.DataFrame.
  • to_numpy(self) -> 'Any'stable · Since 0.3.1 — Return the table values as a NumPy ndarray.
  • reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'provisional · Since 0.3.1 — Rebuild a table's constructor arguments from saved metadata.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return a table's own fields for the saved metadata.

DataObjectclass

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, or None on a plain DataObject. A subclass opts in by declaring its own model in the Meta class attribute.
  • user — a free-form dict for 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 · Since 0.3.1 — Framework-managed metadata (identity, lineage, provenance).
  • meta(self) -> 'BaseModel | None'stable · Since 0.3.1 — Typed domain metadata (a Pydantic BaseModel), or None.
  • user(self) -> 'dict[str, Any]'stable · Since 0.3.1 — Free-form user metadata.
  • with_meta(self, **changes: 'Any') -> 'Self'stable · Since 0.3.1 — Return a copy with some of the typed meta fields changed.
  • dtype_info(self) -> 'TypeSignature'stable · Since 0.3.1 — The TypeSignature describing this object's type.
  • storage_ref(self) -> 'StorageReference | None'stable · Since 0.3.1 — Where this object's data is persisted, or None.
  • to_memory(self) -> 'Any'stable · Since 0.3.1 — Load the full data from storage into memory and return it.
  • slice(self, *args: 'Any') -> 'Any'stable · Since 0.3.1 — Read a sub-selection of the data without loading all of it.
  • iter_chunks(self, chunk_size: 'int') -> 'Iterator[Any]'stable · Since 0.3.1 — Yield the data in successive chunks, keeping memory bounded.
  • save(self, path: 'str | Path') -> 'StorageReference'provisional · Since 0.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 · Since 0.3.1 — Return the extra constructor arguments needed to rebuild an object.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return the subclass-specific fields to store alongside an object.

Seriesclass

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 · Since 0.3.1 — Return a copy with some typed meta fields changed.
  • to_pandas(self) -> 'Any'stable · Since 0.3.1 — Return the series as a pandas.Series.
  • to_numpy(self) -> 'Any'stable · Since 0.3.1 — Return the series values as a NumPy ndarray.
  • reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'provisional · Since 0.3.1 — Rebuild a series' constructor arguments from saved metadata.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return a series' own fields for the saved metadata.

StorageReferenceclass

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'

Textclass

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 · Since 0.3.1 — Return a copy with some typed meta fields changed.
  • reconstruct_extra_kwargs(cls, metadata: 'dict[str, Any]') -> 'dict[str, Any]'provisional · Since 0.3.1 — Rebuild a text object's constructor arguments from saved metadata.
  • serialise_extra_metadata(cls, obj: 'DataObject') -> 'dict[str, Any]'provisional · Since 0.3.1 — Return a text object's own fields for the saved metadata.

TypeSignatureclass

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 · Since 0.3.1 — Return whether this type can stand in for other.
  • from_type(cls, data_type: 'type') -> 'TypeSignature'stable · Since 0.3.1 — Build a TypeSignature from a DataObject subclass.