Data Artifacts

Every named artifact produced and consumed by SleePyPhases phases

Each phase communicates with others through named artifacts registered via registerData and retrieved via getData. Artifacts are cached on disk keyed by a hash of their declared config dependencies. Reading an artifact that is not yet generated triggers the producing phase automatically.

# Producer
self.registerData("my-artifact", value)

# Consumer
value = self.getData("my-artifact", ExpectedType)

Artifacts marked ‘in-memory only’ (i.e. if the phase returns the data and does not use registerData()) are never written to disk and are regenerated each time the program runs. These artifacts are used for data wrapping, for example. If the consumer doesn’t need to persist the data, it can use self.getData("artifact-name"), self.getData("artifact-name", save=False) or self.project.generateData("artifact-name") to generate the data.

Artifacts are stored on disk (or any other persistent storage) via the configured exporter, see Exporter.


Stage 1 — Data Loading

Artifact Python type Produced by Consumed by
allDBRecordIds dict[str, list[str]] LoadData (via record-loader plugin) Setup, Extract, VisualizeConfig

allDBRecordIds — grouped record IDs from the dataset on disk. Keys are group names (usually one key per study); values are lists of record ID strings. The exact shape depends on the loader plugin.


Stage 2 — Setup

Artifact Python type Produced by Consumed by
dataversionmanager DataversionManager (in-memory only) Setup BuildDataset, Eval, EvalReport, ThresholdOptimisation, ExtractEvents, EvalPlotExamples, DataReport, TestRun
removedRecordIds list[str] Extract Setup (via dataversionmanager creation)

dataversionmanager — holds the dataset split assignments for the current configuration (train/val/test record IDs per fold). Never written to disk; re-created from allDBRecordIds and removedRecordIds on every run.

removedRecordIds — record IDs that were excluded during extraction (e.g. recordings that are too short or failed signal quality checks). Read by Setup when building the dataversionmanager.


Stage 3 — Signal Extraction

Artifact Python type Produced by Consumed by
data-processed np.memmap Extract BuildDataset, DataReport, DataAnalysis, TestRun
data-features np.memmap Extract BuildDataset, DataReport, DataAnalysis, TestRun
record-preprocessed list Extract (on-demand) BuildDataset (single-record mode)

data-processed — preprocessed signal windows for all records, stored as a memory-mapped array on disk. Shape is (n_records, n_segments, n_channels, window_length). Backed by MemmapRecordExporter or HDF5RecordExporter depending on project configuration.

data-features — label/feature arrays aligned with data-processed. Shape is (n_records, n_segments, n_features). Typically the last channel dimension holds the ground-truth sleep stage labels.

record-preprocessed — a single preprocessed [signals, labels] pair for one record ID. Generated on-demand when BuildDataset needs to materialise a record that was not yet extracted. Not independently cached.


Stage 4 — Metadata Extraction

Artifact Python type Produced by Consumed by
metadata pd.DataFrame / list ExtractRecordFeatures, ExtractFeatures BuildDataset, Eval, DataReport, ExtractFeatures, TestRun, ExportMetadataToMeticalDB
metadata-channels pd.DataFrame ExtractFeatures ExtractFeatures, ExportMetadataToMeticalDB
metadata-events pd.DataFrame ExtractFeatures ExtractFeatures
features pd.DataFrame ExtractFeatures ExtractFeatures, ExportMetadataToMeticalDB

metadata — per-record metadata table. Columns depend on the record loader; common fields include recordId, age, sex, studySite, and quality flags. Used by BuildDataset to join record-level labels and by Eval to stratify results.

metadata-channels — per-channel metadata (e.g. montage, sample rate, impedance). Produced and consumed within ExtractFeatures.

metadata-events — per-event metadata (e.g. arousal onset, duration, event type). Produced and consumed within ExtractFeatures.

features — numerical feature table extracted from raw signals (e.g. spectral power, HRV metrics). Rows are records; columns are feature names.


Stage 5 — Dataset Building

Artifact Python type Produced by Consumed by
dataset-{split} Manipulator[DatasetXY] BuildDataset (on-demand) Training, Eval, EvalReport, EvalPlotExamples, TestRun
dataset-bySplit Manipulator[DatasetXY] BuildDataset (on-demand) DataReport, EvalReport
record-data Manipulator[DatasetXY] BuildDataset (on-demand) TestRun (single record)

dataset-{split} — iterable dataset for a specific split. {split} is one of train, val, test, or a named fold string (e.g. fold-0). Each item is a (signal, label) pair of tensors after applying all configured segmentManipulation steps. Backed by data-processed and data-features.

dataset-bySplit — full dataset regardless of split, used for reporting across all records.

record-data — single-record dataset for per-record inspection and test runs.


Stage 6 — Training

Artifact Python type Produced by Consumed by
modelState Model Training Eval, Validation, ThresholdOptimisation, EvalReport, Extract (transfer learning)
trainedModel Model (alias of modelState) Training Eval
modelStateConfig dict Training (archived only)

modelState — trained model with weights. Stored as a checkpoint file on disk at modelPath/modelName. Loaded by Model.load() via getData. Also used by Extract when transfer-learning features from a pre-trained encoder.

trainedModel — alias for modelState; resolves to the same cached file.

modelStateConfig — serialised config dependency dict capturing all hashes that contributed to this model. Stored alongside the model checkpoint for reproducibility; not consumed by any downstream phase.


Stage 7 — Threshold Optimisation

Artifact Python type Produced by Consumed by
validationResult tuple[np.ndarray, np.ndarray] ThresholdOptimisation (intermediate) ThresholdOptimisation (second pass)
threshold list[float] ThresholdOptimisation Eval, EvalReport, EvalPlotExamples, Predict

validationResult(predictions, truth) arrays produced by running the model over the validation split. Consumed in a second pass to search for the optimal per-class threshold.

threshold — list of per-class classification thresholds, one value per output class. Applied during evaluation and inference to convert model output probabilities into discrete class labels. Set to fixedThreshold values in the config when threshold optimisation is skipped.


Stage 8 — Evaluation

Artifact Python type Produced by Consumed by
evalResults list Eval EvalReport, EvalPlotExamples
eventResults list Eval EvalReport, EvalPlotExamples

evalResults(per_record_results, aggregate_metrics) pair. per_record_results is a list of per-record score dicts; aggregate_metrics is the overall confusion matrix and Cohen’s kappa / accuracy / F1.

eventResults(event_rows, aggregate_metrics) pair. Contains event-level detection results (onset, duration, TP/FP/FN). Only produced when classification.scorerTypes includes an event scorer.


Stage 9 — Event Extraction

Artifact Python type Produced by Consumed by
events pd.DataFrame ExtractEvents (first pass) ExtractEvents (second pass)
eventDF list ExtractEvents (second pass) ExtractEvents (report)

events — per-record event table produced by the model. Columns include record ID, event type, onset sample, duration.

eventDF — aggregated event dataframe used to build the final event report.


Stage 10 — Data Analysis

Artifact Python type Produced by Consumed by
datasetstats dict DataAnalysis DataReport

datasetstats — per-class segment counts, class distribution, and per-record statistics. Used by DataReport to render dataset composition plots and tables.


Stage 11 — Inference

Artifact Python type Produced by Consumed by
prediction varies Predict (external consumer)

prediction — model output for new / unseen records. The concrete type depends on the scorer configured for the project (e.g. np.ndarray of class probabilities, or a pd.DataFrame of events).


Notes

Cache invalidation

Every artifact is stored under a path that includes a config hash. If any config key listed in the artifact’s data.dependsOn declaration changes, the hash changes and the artifact is treated as missing, triggering regeneration. To see the current hash for an artifact, run:

phases info <artifact-name>

In-memory artifacts

dataversionmanager is the only standard artifact that is never written to disk (save=False). It is cheap to recompute from allDBRecordIds and costs nothing to cache.

Disk-backed arrays

data-processed and data-features can be many gigabytes. The exporter is controlled by the exporter config key:

Value Backend
memmap (default) MemmapRecordExporter — raw NumPy .npy files
hdf5 HDF5RecordExporter — single .h5 file per artifact