reader-workbench 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- reader_workbench/__init__.py +22 -0
- reader_workbench/__main__.py +4 -0
- reader_workbench/_version.py +17 -0
- reader_workbench/api/__init__.py +74 -0
- reader_workbench/api/_record_reads.py +75 -0
- reader_workbench/api/artifacts.py +79 -0
- reader_workbench/api/facade.py +538 -0
- reader_workbench/api/models.py +285 -0
- reader_workbench/api/notebooks.py +63 -0
- reader_workbench/contracts/__init__.py +18 -0
- reader_workbench/contracts/builtins/__init__.py +36 -0
- reader_workbench/contracts/builtins/cytometry.py +140 -0
- reader_workbench/contracts/builtins/four_state_event_window.py +214 -0
- reader_workbench/contracts/builtins/generic.py +21 -0
- reader_workbench/contracts/builtins/logic.py +149 -0
- reader_workbench/contracts/builtins/plate_reader.py +47 -0
- reader_workbench/contracts/catalog.py +257 -0
- reader_workbench/contracts/model.py +109 -0
- reader_workbench/domains/__init__.py +1 -0
- reader_workbench/domains/cytometry/__init__.py +3 -0
- reader_workbench/domains/cytometry/analysis/__init__.py +29 -0
- reader_workbench/domains/cytometry/analysis/events.py +182 -0
- reader_workbench/domains/cytometry/analysis/gating.py +175 -0
- reader_workbench/domains/cytometry/analysis/workflow.py +248 -0
- reader_workbench/domains/cytometry/io/__init__.py +3 -0
- reader_workbench/domains/cytometry/io/fcs.py +135 -0
- reader_workbench/domains/cytometry/plots/__init__.py +5 -0
- reader_workbench/domains/cytometry/plots/diagnostic.py +155 -0
- reader_workbench/domains/logic/__init__.py +3 -0
- reader_workbench/domains/logic/crosstalk/__init__.py +3 -0
- reader_workbench/domains/logic/crosstalk/pairs.py +661 -0
- reader_workbench/domains/logic/four_state_vector/__init__.py +7 -0
- reader_workbench/domains/logic/four_state_vector/builder.py +321 -0
- reader_workbench/domains/logic/four_state_vector/collection/__init__.py +20 -0
- reader_workbench/domains/logic/four_state_vector/collection/checks.py +49 -0
- reader_workbench/domains/logic/four_state_vector/collection/constants.py +29 -0
- reader_workbench/domains/logic/four_state_vector/collection/model.py +19 -0
- reader_workbench/domains/logic/four_state_vector/collection/render.py +383 -0
- reader_workbench/domains/logic/four_state_vector/collection/sources.py +185 -0
- reader_workbench/domains/logic/four_state_vector/config.py +214 -0
- reader_workbench/domains/logic/four_state_vector/diagnostic.py +361 -0
- reader_workbench/domains/logic/four_state_vector/heatmap.py +86 -0
- reader_workbench/domains/logic/four_state_vector/math.py +191 -0
- reader_workbench/domains/logic/four_state_vector/reference.py +85 -0
- reader_workbench/domains/logic/four_state_vector/selection.py +228 -0
- reader_workbench/domains/logic/four_state_vector/treatment_semantics.py +51 -0
- reader_workbench/domains/logic/four_state_vector/validation.py +19 -0
- reader_workbench/domains/logic/logic_symmetry/__init__.py +3 -0
- reader_workbench/domains/logic/logic_symmetry/encodings.py +93 -0
- reader_workbench/domains/logic/logic_symmetry/extract_corners.py +192 -0
- reader_workbench/domains/logic/logic_symmetry/main.py +236 -0
- reader_workbench/domains/logic/logic_symmetry/metrics.py +96 -0
- reader_workbench/domains/logic/logic_symmetry/overlay.py +129 -0
- reader_workbench/domains/logic/logic_symmetry/prep.py +138 -0
- reader_workbench/domains/logic/logic_symmetry/render.py +356 -0
- reader_workbench/domains/logic/treatment_columns.py +42 -0
- reader_workbench/domains/plate_reader/__init__.py +1 -0
- reader_workbench/domains/plate_reader/analysis/__init__.py +14 -0
- reader_workbench/domains/plate_reader/analysis/fold_change.py +474 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/__init__.py +21 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/aggregation.py +191 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/contract_fields.py +50 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/contracts.py +320 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/design_dispositions.py +54 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/disposition_records.py +140 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/event_sensitivity.py +27 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/materialize.py +274 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/observation_resampling.py +97 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/reduction.py +62 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/seeds.py +15 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/sources.py +308 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/well_exclusion_validation.py +94 -0
- reader_workbench/domains/plate_reader/analysis/four_state_event_window/well_exclusions.py +54 -0
- reader_workbench/domains/plate_reader/analysis/timepoints.py +76 -0
- reader_workbench/domains/plate_reader/io/__init__.py +6 -0
- reader_workbench/domains/plate_reader/io/sample_map.py +65 -0
- reader_workbench/domains/plate_reader/io/synergy_h1/__init__.py +6 -0
- reader_workbench/domains/plate_reader/io/synergy_h1/_kinetic.py +141 -0
- reader_workbench/domains/plate_reader/io/synergy_h1/_parser.py +295 -0
- reader_workbench/domains/plate_reader/io/synergy_h1/_shared.py +195 -0
- reader_workbench/domains/plate_reader/io/synergy_h1/_snapshot.py +130 -0
- reader_workbench/domains/plate_reader/ordering.py +59 -0
- reader_workbench/domains/plate_reader/plots/__init__.py +15 -0
- reader_workbench/domains/plate_reader/plots/_data.py +29 -0
- reader_workbench/domains/plate_reader/plots/common.py +346 -0
- reader_workbench/domains/plate_reader/plots/distributions.py +324 -0
- reader_workbench/domains/plate_reader/plots/dual_reporter_triptych.py +525 -0
- reader_workbench/domains/plate_reader/plots/dual_reporter_triptych_render.py +195 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/__init__.py +26 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/diagnostic.py +295 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/diagnostic_components.py +149 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/diagnostic_render.py +308 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/diagnostic_style.py +51 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/schema.py +8 -0
- reader_workbench/domains/plate_reader/plots/four_state_event_window/summary.py +140 -0
- reader_workbench/domains/plate_reader/plots/grouping.py +53 -0
- reader_workbench/domains/plate_reader/plots/panels/__init__.py +12 -0
- reader_workbench/domains/plate_reader/plots/panels/snapshot.py +161 -0
- reader_workbench/domains/plate_reader/plots/panels/snapshot_data.py +91 -0
- reader_workbench/domains/plate_reader/plots/panels/time_series.py +296 -0
- reader_workbench/domains/plate_reader/plots/single_reporter_diagnostic.py +435 -0
- reader_workbench/domains/plate_reader/plots/single_reporter_diagnostic_render.py +300 -0
- reader_workbench/domains/plate_reader/plots/snapshot_barplot/__init__.py +315 -0
- reader_workbench/domains/plate_reader/plots/snapshot_barplot/planning.py +168 -0
- reader_workbench/domains/plate_reader/plots/snapshot_heatmap/__init__.py +205 -0
- reader_workbench/domains/plate_reader/plots/snapshot_heatmap/inputs.py +103 -0
- reader_workbench/domains/plate_reader/plots/time_series.py +317 -0
- reader_workbench/domains/plate_reader/plots/ts_and_snap/__init__.py +479 -0
- reader_workbench/domains/plate_reader/plots/ts_and_snap/planning.py +283 -0
- reader_workbench/domains/time_series/__init__.py +29 -0
- reader_workbench/domains/time_series/aggregation.py +60 -0
- reader_workbench/domains/time_series/contracts.py +368 -0
- reader_workbench/domains/time_series/reduction.py +395 -0
- reader_workbench/errors.py +55 -0
- reader_workbench/maintenance/__init__.py +6 -0
- reader_workbench/maintenance/docs.py +335 -0
- reader_workbench/maintenance/model.py +28 -0
- reader_workbench/maintenance/release.py +39 -0
- reader_workbench/maintenance/skills.py +124 -0
- reader_workbench/plotting/__init__.py +20 -0
- reader_workbench/plotting/mpl.py +56 -0
- reader_workbench/plotting/sinks.py +69 -0
- reader_workbench/plotting/style.py +175 -0
- reader_workbench/plotting/utils.py +27 -0
- reader_workbench/plugins/__init__.py +1 -0
- reader_workbench/plugins/catalog.py +33 -0
- reader_workbench/plugins/export/__init__.py +0 -0
- reader_workbench/plugins/export/_paths.py +21 -0
- reader_workbench/plugins/export/csv.py +41 -0
- reader_workbench/plugins/export/xlsx.py +44 -0
- reader_workbench/plugins/ingest/__init__.py +0 -0
- reader_workbench/plugins/ingest/_discovery.py +58 -0
- reader_workbench/plugins/ingest/discovery_policy.py +66 -0
- reader_workbench/plugins/ingest/flow_cytometer.py +139 -0
- reader_workbench/plugins/ingest/synergy_h1.py +234 -0
- reader_workbench/plugins/manifests/__init__.py +1 -0
- reader_workbench/plugins/manifests/export.py +29 -0
- reader_workbench/plugins/manifests/ingest.py +29 -0
- reader_workbench/plugins/manifests/plot.py +161 -0
- reader_workbench/plugins/manifests/transform.py +172 -0
- reader_workbench/plugins/manifests/validator.py +18 -0
- reader_workbench/plugins/plot/__init__.py +0 -0
- reader_workbench/plugins/plot/_shared.py +55 -0
- reader_workbench/plugins/plot/cytometry_diagnostic.py +54 -0
- reader_workbench/plugins/plot/distributions.py +58 -0
- reader_workbench/plugins/plot/dual_reporter_triptych.py +224 -0
- reader_workbench/plugins/plot/four_state_event_window_diagnostic.py +133 -0
- reader_workbench/plugins/plot/four_state_event_window_summary.py +53 -0
- reader_workbench/plugins/plot/four_state_vector_collection.py +45 -0
- reader_workbench/plugins/plot/four_state_vector_diagnostic.py +105 -0
- reader_workbench/plugins/plot/four_state_vector_heatmap.py +63 -0
- reader_workbench/plugins/plot/logic_symmetry.py +56 -0
- reader_workbench/plugins/plot/single_reporter_diagnostic.py +279 -0
- reader_workbench/plugins/plot/snapshot_barplot.py +65 -0
- reader_workbench/plugins/plot/snapshot_heatmap.py +104 -0
- reader_workbench/plugins/plot/time_series.py +114 -0
- reader_workbench/plugins/plot/ts_and_snap.py +210 -0
- reader_workbench/plugins/transform/__init__.py +0 -0
- reader_workbench/plugins/transform/_four_state_vector.py +204 -0
- reader_workbench/plugins/transform/_labeling.py +109 -0
- reader_workbench/plugins/transform/alias.py +70 -0
- reader_workbench/plugins/transform/assay_labels.py +62 -0
- reader_workbench/plugins/transform/blank.py +79 -0
- reader_workbench/plugins/transform/crosstalk_pairs.py +180 -0
- reader_workbench/plugins/transform/cytometry_gating.py +120 -0
- reader_workbench/plugins/transform/fold_change.py +79 -0
- reader_workbench/plugins/transform/four_state_event_window.py +93 -0
- reader_workbench/plugins/transform/four_state_vector.py +62 -0
- reader_workbench/plugins/transform/four_state_vector_collection.py +41 -0
- reader_workbench/plugins/transform/logic_symmetry.py +67 -0
- reader_workbench/plugins/transform/outlier_filter.py +60 -0
- reader_workbench/plugins/transform/overflow.py +197 -0
- reader_workbench/plugins/transform/ratio.py +237 -0
- reader_workbench/plugins/transform/sample_map.py +170 -0
- reader_workbench/plugins/transform/sample_metadata.py +94 -0
- reader_workbench/plugins/validator/__init__.py +1 -0
- reader_workbench/plugins/validator/to_tidy_plus_map.py +155 -0
- reader_workbench/protocols/__init__.py +80 -0
- reader_workbench/protocols/_builtins_plate_reader_growth.py +179 -0
- reader_workbench/protocols/_builtins_plate_reader_variants.py +274 -0
- reader_workbench/protocols/builtins.py +1656 -0
- reader_workbench/protocols/compiler.py +22 -0
- reader_workbench/protocols/compilers/__init__.py +1 -0
- reader_workbench/protocols/compilers/common.py +100 -0
- reader_workbench/protocols/compilers/cytometry.py +87 -0
- reader_workbench/protocols/compilers/generic.py +14 -0
- reader_workbench/protocols/compilers/logic.py +245 -0
- reader_workbench/protocols/compilers/plate_reader.py +937 -0
- reader_workbench/protocols/compilers/plate_reader_pipeline.py +197 -0
- reader_workbench/protocols/model.py +1486 -0
- reader_workbench/protocols/semantic_coverage.py +234 -0
- reader_workbench/runtime/__init__.py +12 -0
- reader_workbench/runtime/builtin.py +23 -0
- reader_workbench/runtime/model.py +42 -0
- reader_workbench/workbench/__init__.py +60 -0
- reader_workbench/workbench/assets/__init__.py +22 -0
- reader_workbench/workbench/assets/types.py +118 -0
- reader_workbench/workbench/audit/__init__.py +5 -0
- reader_workbench/workbench/audit/experiments.py +307 -0
- reader_workbench/workbench/audit/staging.py +187 -0
- reader_workbench/workbench/cli/__init__.py +51 -0
- reader_workbench/workbench/cli/_lazy.py +9 -0
- reader_workbench/workbench/cli/_records_view.py +150 -0
- reader_workbench/workbench/cli/_surface_execution.py +443 -0
- reader_workbench/workbench/cli/audit.py +95 -0
- reader_workbench/workbench/cli/automation.py +229 -0
- reader_workbench/workbench/cli/demo.py +46 -0
- reader_workbench/workbench/cli/dop.py +91 -0
- reader_workbench/workbench/cli/experiments.py +635 -0
- reader_workbench/workbench/cli/helpers.py +232 -0
- reader_workbench/workbench/cli/main.py +59 -0
- reader_workbench/workbench/cli/maintenance.py +82 -0
- reader_workbench/workbench/cli/notebooks.py +260 -0
- reader_workbench/workbench/cli/pagination.py +117 -0
- reader_workbench/workbench/cli/protocols.py +336 -0
- reader_workbench/workbench/cli/shared.py +309 -0
- reader_workbench/workbench/cli/surfaces.py +534 -0
- reader_workbench/workbench/cli/verification.py +128 -0
- reader_workbench/workbench/commands.py +10 -0
- reader_workbench/workbench/config/__init__.py +47 -0
- reader_workbench/workbench/config/identity.py +13 -0
- reader_workbench/workbench/config/load.py +405 -0
- reader_workbench/workbench/config/model.py +274 -0
- reader_workbench/workbench/context.py +26 -0
- reader_workbench/workbench/decl/__init__.py +31 -0
- reader_workbench/workbench/decl/build.py +190 -0
- reader_workbench/workbench/decl/model.py +81 -0
- reader_workbench/workbench/dop/__init__.py +12 -0
- reader_workbench/workbench/dop/builtins.py +261 -0
- reader_workbench/workbench/dop/model.py +209 -0
- reader_workbench/workbench/engine/__init__.py +42 -0
- reader_workbench/workbench/engine/_shared.py +76 -0
- reader_workbench/workbench/engine/contracts.py +283 -0
- reader_workbench/workbench/engine/execution.py +326 -0
- reader_workbench/workbench/engine/file_outputs.py +260 -0
- reader_workbench/workbench/engine/inputs.py +161 -0
- reader_workbench/workbench/engine/invocations.py +507 -0
- reader_workbench/workbench/engine/planning.py +72 -0
- reader_workbench/workbench/engine/runtime.py +464 -0
- reader_workbench/workbench/engine/setup.py +149 -0
- reader_workbench/workbench/engine/validation.py +684 -0
- reader_workbench/workbench/experiment/__init__.py +47 -0
- reader_workbench/workbench/experiment/model.py +381 -0
- reader_workbench/workbench/experiments.py +133 -0
- reader_workbench/workbench/graph/__init__.py +47 -0
- reader_workbench/workbench/graph/nodes.py +102 -0
- reader_workbench/workbench/graph/normalize.py +177 -0
- reader_workbench/workbench/graph/refs.py +148 -0
- reader_workbench/workbench/input_discovery.py +19 -0
- reader_workbench/workbench/inspection/__init__.py +3 -0
- reader_workbench/workbench/inspection/catalogs.py +128 -0
- reader_workbench/workbench/inspection/common.py +92 -0
- reader_workbench/workbench/inspection/dop.py +64 -0
- reader_workbench/workbench/inspection/experiments.py +449 -0
- reader_workbench/workbench/inspection/inventory.py +68 -0
- reader_workbench/workbench/inspection/protocols.py +368 -0
- reader_workbench/workbench/inspection/readiness.py +333 -0
- reader_workbench/workbench/inspection/reports.py +367 -0
- reader_workbench/workbench/inspection/results.py +166 -0
- reader_workbench/workbench/inspection/runtime.py +287 -0
- reader_workbench/workbench/inspection/semantics.py +192 -0
- reader_workbench/workbench/inspection/validation.py +30 -0
- reader_workbench/workbench/notebooks/__init__.py +17 -0
- reader_workbench/workbench/notebooks/_launch_registry.py +112 -0
- reader_workbench/workbench/notebooks/_launch_runtime.py +104 -0
- reader_workbench/workbench/notebooks/components/__init__.py +21 -0
- reader_workbench/workbench/notebooks/components/deliverables.py +403 -0
- reader_workbench/workbench/notebooks/components/overview.py +119 -0
- reader_workbench/workbench/notebooks/eda.marimo.py.txt +153 -0
- reader_workbench/workbench/notebooks/launch.py +274 -0
- reader_workbench/workbench/notebooks/presentation.py +136 -0
- reader_workbench/workbench/notebooks/scaffold.py +60 -0
- reader_workbench/workbench/ontology.py +78 -0
- reader_workbench/workbench/paths.py +44 -0
- reader_workbench/workbench/ports/__init__.py +31 -0
- reader_workbench/workbench/ports/model.py +168 -0
- reader_workbench/workbench/records/__init__.py +44 -0
- reader_workbench/workbench/records/epoch.py +329 -0
- reader_workbench/workbench/records/evidence.py +247 -0
- reader_workbench/workbench/records/identity.py +87 -0
- reader_workbench/workbench/records/locking.py +185 -0
- reader_workbench/workbench/records/model.py +711 -0
- reader_workbench/workbench/records/sources.py +73 -0
- reader_workbench/workbench/records/store.py +1022 -0
- reader_workbench/workbench/records/verification.py +998 -0
- reader_workbench/workbench/registry.py +333 -0
- reader_workbench/workbench/spec_overrides.py +215 -0
- reader_workbench-1.0.0.dist-info/METADATA +91 -0
- reader_workbench-1.0.0.dist-info/RECORD +293 -0
- reader_workbench-1.0.0.dist-info/WHEEL +5 -0
- reader_workbench-1.0.0.dist-info/entry_points.txt +2 -0
- reader_workbench-1.0.0.dist-info/licenses/LICENSE +21 -0
- reader_workbench-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Mapping, Sequence
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Literal, Self
|
|
6
|
+
|
|
7
|
+
import pandas as pd
|
|
8
|
+
from pydantic import Field, field_validator, model_validator
|
|
9
|
+
|
|
10
|
+
from reader_workbench.domains.plate_reader.io.synergy_h1 import (
|
|
11
|
+
parse_kinetic_only,
|
|
12
|
+
parse_snapshot_and_timeseries,
|
|
13
|
+
probe_synergy_workbook,
|
|
14
|
+
)
|
|
15
|
+
from reader_workbench.errors import ParseError
|
|
16
|
+
from reader_workbench.plugins.ingest._discovery import discover_auto_input_files
|
|
17
|
+
from reader_workbench.plugins.ingest.discovery_policy import DEFAULT_EXCLUDE, DEFAULT_INCLUDE
|
|
18
|
+
from reader_workbench.workbench.ports import dataframe_output, file_path_input
|
|
19
|
+
from reader_workbench.workbench.registry import Plugin, PluginConfig, PreflightIssue
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class SynergyH1UnifiedCfg(PluginConfig):
|
|
23
|
+
# What kind of ingest are we doing?
|
|
24
|
+
mode: Literal["snapshot_only", "kinetic_only", "mixed"] = "mixed"
|
|
25
|
+
|
|
26
|
+
# parsing knobs
|
|
27
|
+
channels: list[str] | None = None
|
|
28
|
+
channel_map: Mapping[str, str] | None = None
|
|
29
|
+
sheet_names: Sequence[str] | None = None
|
|
30
|
+
|
|
31
|
+
# time normalization
|
|
32
|
+
time_round_decimals: int | None = 12
|
|
33
|
+
time_step_h: float | None = None
|
|
34
|
+
time_offset_h: float = Field(
|
|
35
|
+
default=0.0,
|
|
36
|
+
ge=0.0,
|
|
37
|
+
allow_inf_nan=False,
|
|
38
|
+
description="Hours added to parsed measurement times when assay age is known outside the workbook.",
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# auto-discovery knobs
|
|
42
|
+
auto_roots: list[str] | None = None
|
|
43
|
+
auto_include: list[str] = Field(default_factory=lambda: list(DEFAULT_INCLUDE))
|
|
44
|
+
auto_exclude: list[str] = Field(default_factory=lambda: list(DEFAULT_EXCLUDE))
|
|
45
|
+
auto_pick: Literal["single", "latest"] = "single"
|
|
46
|
+
auto_recursive: bool = False
|
|
47
|
+
|
|
48
|
+
# logging
|
|
49
|
+
print_summary: bool = True
|
|
50
|
+
|
|
51
|
+
@field_validator("time_offset_h", mode="before")
|
|
52
|
+
@classmethod
|
|
53
|
+
def reject_boolean_time_offset(cls, value: object) -> object:
|
|
54
|
+
if isinstance(value, bool):
|
|
55
|
+
raise ValueError("time_offset_h must be a non-negative finite number, not a boolean")
|
|
56
|
+
return value
|
|
57
|
+
|
|
58
|
+
@model_validator(mode="after")
|
|
59
|
+
def require_channel_contract(self) -> Self:
|
|
60
|
+
if self.mode in {"snapshot_only", "mixed"} and not self.channel_map:
|
|
61
|
+
raise ValueError(f"Synergy H1 mode {self.mode!r} requires an explicit channel_map")
|
|
62
|
+
if not self.channels and not self.channel_map:
|
|
63
|
+
raise ValueError("Synergy H1 ingest requires channels or channel_map")
|
|
64
|
+
return self
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class SynergyH1(Plugin):
|
|
68
|
+
"""Unified Synergy H1 ingest (snapshot-only, kinetic-only, or mixed)."""
|
|
69
|
+
|
|
70
|
+
ConfigModel = SynergyH1UnifiedCfg
|
|
71
|
+
|
|
72
|
+
@classmethod
|
|
73
|
+
def input_ports(cls):
|
|
74
|
+
return {"raw": file_path_input("raw", optional=True)}
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def output_ports(cls):
|
|
78
|
+
return {"df": dataframe_output("df", "tidy.v1")}
|
|
79
|
+
|
|
80
|
+
@classmethod
|
|
81
|
+
def _selected_workbooks(
|
|
82
|
+
cls,
|
|
83
|
+
*,
|
|
84
|
+
exp_dir: Path,
|
|
85
|
+
cfg: SynergyH1UnifiedCfg,
|
|
86
|
+
inputs: Mapping[str, object],
|
|
87
|
+
) -> list[Path]:
|
|
88
|
+
if "raw" in inputs:
|
|
89
|
+
raw_value = inputs["raw"]
|
|
90
|
+
raw_path = raw_value if isinstance(raw_value, Path) else getattr(raw_value, "path", None)
|
|
91
|
+
if raw_path is None:
|
|
92
|
+
raise ParseError("Synergy H1 raw input must select a workbook file")
|
|
93
|
+
path = Path(raw_path)
|
|
94
|
+
return [path if path.is_absolute() else exp_dir / path]
|
|
95
|
+
return discover_auto_input_files(
|
|
96
|
+
exp_dir=exp_dir,
|
|
97
|
+
auto_roots=cfg.auto_roots,
|
|
98
|
+
auto_include=cfg.auto_include,
|
|
99
|
+
auto_exclude=cfg.auto_exclude,
|
|
100
|
+
auto_recursive=cfg.auto_recursive,
|
|
101
|
+
auto_pick=cfg.auto_pick,
|
|
102
|
+
discovery_label="raw .xlsx files",
|
|
103
|
+
singular_label="workbook",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
@classmethod
|
|
107
|
+
def resolve_missing_file_inputs(cls, *, exp_dir, cfg: SynergyH1UnifiedCfg, inputs):
|
|
108
|
+
if "raw" in inputs:
|
|
109
|
+
return {}
|
|
110
|
+
selected = cls._selected_workbooks(exp_dir=exp_dir, cfg=cfg, inputs=inputs)
|
|
111
|
+
return {"raw": selected[0]}
|
|
112
|
+
|
|
113
|
+
@classmethod
|
|
114
|
+
def preflight_readiness(cls, *, exp_dir, cfg: SynergyH1UnifiedCfg, reads):
|
|
115
|
+
try:
|
|
116
|
+
selected = cls._selected_workbooks(exp_dir=exp_dir, cfg=cfg, inputs=reads)
|
|
117
|
+
except ParseError as err:
|
|
118
|
+
return (PreflightIssue(kind="file", message=str(err)),)
|
|
119
|
+
|
|
120
|
+
issues: list[PreflightIssue] = []
|
|
121
|
+
for path in selected:
|
|
122
|
+
try:
|
|
123
|
+
probe_synergy_workbook(path)
|
|
124
|
+
except Exception as err:
|
|
125
|
+
issues.append(
|
|
126
|
+
PreflightIssue(
|
|
127
|
+
kind="file",
|
|
128
|
+
message=f"Synergy H1 workbook {path} could not be opened: {err}",
|
|
129
|
+
)
|
|
130
|
+
)
|
|
131
|
+
return tuple(issues)
|
|
132
|
+
|
|
133
|
+
def _log_df_summary(self, ctx, df: pd.DataFrame, files_count: int, mode: str):
|
|
134
|
+
try:
|
|
135
|
+
n_rows = len(df)
|
|
136
|
+
n_pos = df["position"].nunique()
|
|
137
|
+
chans = sorted(df["channel"].astype(str).unique().tolist())
|
|
138
|
+
tmin = float(pd.to_numeric(df["time"]).min()) if n_rows else 0.0
|
|
139
|
+
tmax = float(pd.to_numeric(df["time"]).max()) if n_rows else 0.0
|
|
140
|
+
src_counts = df["source"].value_counts().to_dict() if "source" in df.columns else {}
|
|
141
|
+
sheets = int(df["sheet_name"].nunique()) if "sheet_name" in df.columns else 0
|
|
142
|
+
ctx.logger.info(
|
|
143
|
+
"Synergy H1 ingest • files=%d • mode=[bold]%s[/bold] • rows=%d • positions=%d • channels=%d "
|
|
144
|
+
"• time=[%.2f, %.2f] h • sheets=%d • parts=%s",
|
|
145
|
+
files_count,
|
|
146
|
+
mode,
|
|
147
|
+
n_rows,
|
|
148
|
+
n_pos,
|
|
149
|
+
len(chans),
|
|
150
|
+
tmin,
|
|
151
|
+
tmax,
|
|
152
|
+
sheets,
|
|
153
|
+
src_counts or "{}",
|
|
154
|
+
)
|
|
155
|
+
if chans:
|
|
156
|
+
preview = ", ".join(chans[:8]) + (" …" if len(chans) > 8 else "")
|
|
157
|
+
ctx.logger.debug("channels: %s", preview)
|
|
158
|
+
|
|
159
|
+
# Block presence line (unambiguous snapshot/kinetic summary)
|
|
160
|
+
snap_n = int(src_counts.get("snapshot", 0))
|
|
161
|
+
kin_n = int(src_counts.get("kinetic", 0))
|
|
162
|
+
snap_flag = "YES" if snap_n > 0 else "NO"
|
|
163
|
+
kin_flag = "YES" if kin_n > 0 else "NO"
|
|
164
|
+
ctx.logger.debug(
|
|
165
|
+
"parsed blocks • snapshot=%s (%d rows) • kinetic=%s (%d rows)", snap_flag, snap_n, kin_flag, kin_n
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
except Exception:
|
|
169
|
+
# Logging should never break the pipeline
|
|
170
|
+
pass
|
|
171
|
+
|
|
172
|
+
# ---------- run ----------
|
|
173
|
+
|
|
174
|
+
def run(self, ctx, inputs, cfg: SynergyH1UnifiedCfg):
|
|
175
|
+
effective_mode = cfg.mode
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
raw_path = inputs.get("raw")
|
|
179
|
+
if not isinstance(raw_path, Path):
|
|
180
|
+
raise ParseError("Synergy H1 runtime requires one resolved raw workbook path")
|
|
181
|
+
|
|
182
|
+
if cfg.print_summary:
|
|
183
|
+
ctx.logger.info(
|
|
184
|
+
"[muted]Synergy H1 ingest • workbook selected[/muted] • %s",
|
|
185
|
+
raw_path.name,
|
|
186
|
+
)
|
|
187
|
+
if effective_mode == "kinetic_only":
|
|
188
|
+
out = parse_kinetic_only(
|
|
189
|
+
raw_path,
|
|
190
|
+
channels=cfg.channels,
|
|
191
|
+
channel_map=cfg.channel_map,
|
|
192
|
+
sheet_names=cfg.sheet_names,
|
|
193
|
+
time_round_decimals=cfg.time_round_decimals,
|
|
194
|
+
time_step_h=cfg.time_step_h,
|
|
195
|
+
time_offset_h=cfg.time_offset_h,
|
|
196
|
+
)
|
|
197
|
+
elif effective_mode == "snapshot_only":
|
|
198
|
+
out = parse_snapshot_and_timeseries(
|
|
199
|
+
raw_path,
|
|
200
|
+
channels=cfg.channels,
|
|
201
|
+
channel_map=cfg.channel_map,
|
|
202
|
+
sheet_names=cfg.sheet_names,
|
|
203
|
+
time_round_decimals=cfg.time_round_decimals,
|
|
204
|
+
time_step_h=cfg.time_step_h,
|
|
205
|
+
time_offset_h=cfg.time_offset_h,
|
|
206
|
+
include_snapshot=True,
|
|
207
|
+
include_kinetic=False,
|
|
208
|
+
)
|
|
209
|
+
elif effective_mode == "mixed":
|
|
210
|
+
out = parse_snapshot_and_timeseries(
|
|
211
|
+
raw_path,
|
|
212
|
+
channels=cfg.channels,
|
|
213
|
+
channel_map=cfg.channel_map,
|
|
214
|
+
sheet_names=cfg.sheet_names,
|
|
215
|
+
time_round_decimals=cfg.time_round_decimals,
|
|
216
|
+
time_step_h=cfg.time_step_h,
|
|
217
|
+
time_offset_h=cfg.time_offset_h,
|
|
218
|
+
include_snapshot=True,
|
|
219
|
+
include_kinetic=True,
|
|
220
|
+
)
|
|
221
|
+
else:
|
|
222
|
+
raise ParseError(
|
|
223
|
+
f"Unsupported Synergy H1 mode {effective_mode!r}; expected snapshot_only, kinetic_only, or mixed"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if cfg.print_summary:
|
|
227
|
+
self._log_df_summary(ctx, out, files_count=1, mode=effective_mode)
|
|
228
|
+
|
|
229
|
+
except ParseError:
|
|
230
|
+
raise
|
|
231
|
+
except Exception as e:
|
|
232
|
+
raise ParseError(f"Synergy H1 ingest failed: {e}") from e
|
|
233
|
+
|
|
234
|
+
return {"df": out}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Category-owned manifests for Reader's built-in plugins."""
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from reader_workbench.plugins.export.csv import ExportCsv
|
|
4
|
+
from reader_workbench.plugins.export.xlsx import ExportXlsx
|
|
5
|
+
from reader_workbench.workbench.assets import AssetDescriptor, build_plugin_asset
|
|
6
|
+
from reader_workbench.workbench.ontology import PluginSemantics
|
|
7
|
+
|
|
8
|
+
BUILTIN_PLUGIN_DESCRIPTORS: tuple[AssetDescriptor, ...] = (
|
|
9
|
+
build_plugin_asset(
|
|
10
|
+
plugin_id="export/csv",
|
|
11
|
+
semantics=PluginSemantics(
|
|
12
|
+
domain="generic",
|
|
13
|
+
family="table_export",
|
|
14
|
+
summary="Write dataframe records to CSV files.",
|
|
15
|
+
tags=("csv", "files"),
|
|
16
|
+
),
|
|
17
|
+
plugin_cls=ExportCsv,
|
|
18
|
+
),
|
|
19
|
+
build_plugin_asset(
|
|
20
|
+
plugin_id="export/xlsx",
|
|
21
|
+
semantics=PluginSemantics(
|
|
22
|
+
domain="generic",
|
|
23
|
+
family="table_export",
|
|
24
|
+
summary="Write dataframe records to XLSX workbooks.",
|
|
25
|
+
tags=("xlsx", "files"),
|
|
26
|
+
),
|
|
27
|
+
plugin_cls=ExportXlsx,
|
|
28
|
+
),
|
|
29
|
+
)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from reader_workbench.plugins.ingest.flow_cytometer import FlowCytometerIngest
|
|
4
|
+
from reader_workbench.plugins.ingest.synergy_h1 import SynergyH1
|
|
5
|
+
from reader_workbench.workbench.assets import AssetDescriptor, build_plugin_asset
|
|
6
|
+
from reader_workbench.workbench.ontology import PluginSemantics
|
|
7
|
+
|
|
8
|
+
BUILTIN_PLUGIN_DESCRIPTORS: tuple[AssetDescriptor, ...] = (
|
|
9
|
+
build_plugin_asset(
|
|
10
|
+
plugin_id="ingest/flow_cytometer",
|
|
11
|
+
semantics=PluginSemantics(
|
|
12
|
+
domain="cytometry",
|
|
13
|
+
family="fcs_ingest",
|
|
14
|
+
summary="Parse FCS cytometry files into tidy event tables and channel metadata.",
|
|
15
|
+
tags=("fcs", "events", "channels"),
|
|
16
|
+
),
|
|
17
|
+
plugin_cls=FlowCytometerIngest,
|
|
18
|
+
),
|
|
19
|
+
build_plugin_asset(
|
|
20
|
+
plugin_id="ingest/synergy_h1",
|
|
21
|
+
semantics=PluginSemantics(
|
|
22
|
+
domain="plate_reader",
|
|
23
|
+
family="workbook_ingest",
|
|
24
|
+
summary="Parse Synergy H1 workbooks into tidy plate-reader traces.",
|
|
25
|
+
tags=("xlsx", "kinetic", "snapshot"),
|
|
26
|
+
),
|
|
27
|
+
plugin_cls=SynergyH1,
|
|
28
|
+
),
|
|
29
|
+
)
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from reader_workbench.plugins.plot.cytometry_diagnostic import CytometryDiagnosticPlot
|
|
4
|
+
from reader_workbench.plugins.plot.distributions import DistributionsPlot
|
|
5
|
+
from reader_workbench.plugins.plot.dual_reporter_triptych import DualReporterTriptychPlot
|
|
6
|
+
from reader_workbench.plugins.plot.four_state_event_window_diagnostic import FourStateEventWindowDiagnosticPlot
|
|
7
|
+
from reader_workbench.plugins.plot.four_state_event_window_summary import FourStateEventWindowSummaryPlot
|
|
8
|
+
from reader_workbench.plugins.plot.four_state_vector_collection import FourStateVectorCollectionHeatmapPlot
|
|
9
|
+
from reader_workbench.plugins.plot.four_state_vector_diagnostic import FourStateVectorDiagnosticPlot
|
|
10
|
+
from reader_workbench.plugins.plot.four_state_vector_heatmap import FourStateVectorHeatmapPlot
|
|
11
|
+
from reader_workbench.plugins.plot.logic_symmetry import LogicSymmetryPlot
|
|
12
|
+
from reader_workbench.plugins.plot.single_reporter_diagnostic import SingleReporterDiagnosticPlot
|
|
13
|
+
from reader_workbench.plugins.plot.snapshot_barplot import SnapshotBarplot
|
|
14
|
+
from reader_workbench.plugins.plot.snapshot_heatmap import SnapshotHeatmapPlot
|
|
15
|
+
from reader_workbench.plugins.plot.time_series import TimeSeriesPlot
|
|
16
|
+
from reader_workbench.plugins.plot.ts_and_snap import TSAndSnapPlot
|
|
17
|
+
from reader_workbench.workbench.assets import AssetDescriptor, build_plugin_asset
|
|
18
|
+
from reader_workbench.workbench.ontology import PluginSemantics
|
|
19
|
+
|
|
20
|
+
BUILTIN_PLUGIN_DESCRIPTORS: tuple[AssetDescriptor, ...] = (
|
|
21
|
+
build_plugin_asset(
|
|
22
|
+
plugin_id="plot/cytometry_diagnostic",
|
|
23
|
+
semantics=PluginSemantics(
|
|
24
|
+
domain="cytometry",
|
|
25
|
+
family="gating_diagnostic",
|
|
26
|
+
summary="Render configured cells, singlets, fluorescence, and retention diagnostics.",
|
|
27
|
+
tags=("gating", "fluorescence", "qc", "records"),
|
|
28
|
+
),
|
|
29
|
+
plugin_cls=CytometryDiagnosticPlot,
|
|
30
|
+
),
|
|
31
|
+
build_plugin_asset(
|
|
32
|
+
plugin_id="plot/dual_reporter_triptych",
|
|
33
|
+
semantics=PluginSemantics(
|
|
34
|
+
domain="plate_reader",
|
|
35
|
+
family="composite_plot",
|
|
36
|
+
summary="Render per-design growth, reporter-ratio, and endpoint panels.",
|
|
37
|
+
tags=("dual_reporter", "kinetics", "snapshot"),
|
|
38
|
+
),
|
|
39
|
+
plugin_cls=DualReporterTriptychPlot,
|
|
40
|
+
),
|
|
41
|
+
build_plugin_asset(
|
|
42
|
+
plugin_id="plot/single_reporter_diagnostic",
|
|
43
|
+
semantics=PluginSemantics(
|
|
44
|
+
domain="plate_reader",
|
|
45
|
+
family="composite_plot",
|
|
46
|
+
summary="Render single-reporter kinetics, an explicit reduction, and normalizer QC in one row.",
|
|
47
|
+
tags=("single_reporter", "kinetics", "reduction", "qc"),
|
|
48
|
+
),
|
|
49
|
+
plugin_cls=SingleReporterDiagnosticPlot,
|
|
50
|
+
),
|
|
51
|
+
build_plugin_asset(
|
|
52
|
+
plugin_id="plot/four_state_event_window_diagnostic",
|
|
53
|
+
semantics=PluginSemantics(
|
|
54
|
+
domain="plate_reader",
|
|
55
|
+
family="event_relative_diagnostic",
|
|
56
|
+
summary="Render trajectories and reduced components for one explicitly identified source design.",
|
|
57
|
+
tags=("event", "window", "diagnostic", "reduction"),
|
|
58
|
+
),
|
|
59
|
+
plugin_cls=FourStateEventWindowDiagnosticPlot,
|
|
60
|
+
),
|
|
61
|
+
build_plugin_asset(
|
|
62
|
+
plugin_id="plot/four_state_event_window_summary",
|
|
63
|
+
semantics=PluginSemantics(
|
|
64
|
+
domain="plate_reader",
|
|
65
|
+
family="event_relative_summary",
|
|
66
|
+
summary="Render primary event-relative components across source records.",
|
|
67
|
+
tags=("event", "window", "aggregate", "summary"),
|
|
68
|
+
),
|
|
69
|
+
plugin_cls=FourStateEventWindowSummaryPlot,
|
|
70
|
+
),
|
|
71
|
+
build_plugin_asset(
|
|
72
|
+
plugin_id="plot/logic_symmetry",
|
|
73
|
+
semantics=PluginSemantics(
|
|
74
|
+
domain="logic",
|
|
75
|
+
family="geometry_plot",
|
|
76
|
+
summary="Render logic symmetry geometry from a persisted summary record.",
|
|
77
|
+
tags=("logic", "geometry"),
|
|
78
|
+
),
|
|
79
|
+
plugin_cls=LogicSymmetryPlot,
|
|
80
|
+
),
|
|
81
|
+
build_plugin_asset(
|
|
82
|
+
plugin_id="plot/four_state_vector_diagnostic",
|
|
83
|
+
semantics=PluginSemantics(
|
|
84
|
+
domain="logic",
|
|
85
|
+
family="four_state_vector_diagnostic",
|
|
86
|
+
summary="Render per-design trajectories beside persisted four-state vector components.",
|
|
87
|
+
tags=("logic", "four_state_vector", "diagnostic", "records"),
|
|
88
|
+
),
|
|
89
|
+
plugin_cls=FourStateVectorDiagnosticPlot,
|
|
90
|
+
),
|
|
91
|
+
build_plugin_asset(
|
|
92
|
+
plugin_id="plot/four_state_vector_heatmap",
|
|
93
|
+
semantics=PluginSemantics(
|
|
94
|
+
domain="logic",
|
|
95
|
+
family="four_state_vector_heatmap",
|
|
96
|
+
summary="Render a heatmap over one experiment's four-state vector logic-shape and reference-normalized intensity channels.",
|
|
97
|
+
tags=("logic", "four_state_vector", "vector", "heatmap"),
|
|
98
|
+
),
|
|
99
|
+
plugin_cls=FourStateVectorHeatmapPlot,
|
|
100
|
+
),
|
|
101
|
+
build_plugin_asset(
|
|
102
|
+
plugin_id="plot/four_state_vector_collection",
|
|
103
|
+
semantics=PluginSemantics(
|
|
104
|
+
domain="logic",
|
|
105
|
+
family="four_state_vector_heatmap",
|
|
106
|
+
summary="Render a four-state vector heatmap over a provenance-bound record collection.",
|
|
107
|
+
tags=("logic", "four_state_vector", "collection", "heatmap"),
|
|
108
|
+
),
|
|
109
|
+
plugin_cls=FourStateVectorCollectionHeatmapPlot,
|
|
110
|
+
),
|
|
111
|
+
build_plugin_asset(
|
|
112
|
+
plugin_id="plot/ts_and_snap",
|
|
113
|
+
semantics=PluginSemantics(
|
|
114
|
+
domain="plate_reader",
|
|
115
|
+
family="composite_plot",
|
|
116
|
+
summary="Render paired time-series and snapshot summary panels.",
|
|
117
|
+
tags=("time_series", "snapshot"),
|
|
118
|
+
),
|
|
119
|
+
plugin_cls=TSAndSnapPlot,
|
|
120
|
+
),
|
|
121
|
+
build_plugin_asset(
|
|
122
|
+
plugin_id="plot/distributions",
|
|
123
|
+
semantics=PluginSemantics(
|
|
124
|
+
domain="plate_reader",
|
|
125
|
+
family="distribution",
|
|
126
|
+
summary="Render channel-wise distribution plots from tidy measurements.",
|
|
127
|
+
tags=("density", "qc"),
|
|
128
|
+
),
|
|
129
|
+
plugin_cls=DistributionsPlot,
|
|
130
|
+
),
|
|
131
|
+
build_plugin_asset(
|
|
132
|
+
plugin_id="plot/snapshot_barplot",
|
|
133
|
+
semantics=PluginSemantics(
|
|
134
|
+
domain="plate_reader",
|
|
135
|
+
family="snapshot_bar",
|
|
136
|
+
summary="Render grouped snapshot barplots at a selected timepoint.",
|
|
137
|
+
tags=("snapshot", "bars"),
|
|
138
|
+
),
|
|
139
|
+
plugin_cls=SnapshotBarplot,
|
|
140
|
+
),
|
|
141
|
+
build_plugin_asset(
|
|
142
|
+
plugin_id="plot/snapshot_heatmap",
|
|
143
|
+
semantics=PluginSemantics(
|
|
144
|
+
domain="plate_reader",
|
|
145
|
+
family="snapshot_heatmap",
|
|
146
|
+
summary="Render heatmaps for snapshot or fold-change plate-reader summaries.",
|
|
147
|
+
tags=("snapshot", "heatmap"),
|
|
148
|
+
),
|
|
149
|
+
plugin_cls=SnapshotHeatmapPlot,
|
|
150
|
+
),
|
|
151
|
+
build_plugin_asset(
|
|
152
|
+
plugin_id="plot/time_series",
|
|
153
|
+
semantics=PluginSemantics(
|
|
154
|
+
domain="plate_reader",
|
|
155
|
+
family="time_series",
|
|
156
|
+
summary="Render grouped time-series plots from tidy plate-reader traces.",
|
|
157
|
+
tags=("kinetics", "channels"),
|
|
158
|
+
),
|
|
159
|
+
plugin_cls=TimeSeriesPlot,
|
|
160
|
+
),
|
|
161
|
+
)
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from reader_workbench.plugins.transform.alias import AliasTransform
|
|
4
|
+
from reader_workbench.plugins.transform.assay_labels import AnnotationLabelsTransform
|
|
5
|
+
from reader_workbench.plugins.transform.blank import BlankCorrection
|
|
6
|
+
from reader_workbench.plugins.transform.crosstalk_pairs import CrosstalkPairs
|
|
7
|
+
from reader_workbench.plugins.transform.cytometry_gating import CytometryGatingTransform
|
|
8
|
+
from reader_workbench.plugins.transform.fold_change import FoldChange
|
|
9
|
+
from reader_workbench.plugins.transform.four_state_event_window import FourStateEventWindowTransform
|
|
10
|
+
from reader_workbench.plugins.transform.four_state_vector import FourStateVectorTransform
|
|
11
|
+
from reader_workbench.plugins.transform.four_state_vector_collection import FourStateVectorCollectionTransform
|
|
12
|
+
from reader_workbench.plugins.transform.logic_symmetry import LogicSymmetryTransform
|
|
13
|
+
from reader_workbench.plugins.transform.outlier_filter import OutlierFilter
|
|
14
|
+
from reader_workbench.plugins.transform.overflow import OverflowHandling
|
|
15
|
+
from reader_workbench.plugins.transform.ratio import RatioTransform
|
|
16
|
+
from reader_workbench.plugins.transform.sample_map import SampleMapMerge
|
|
17
|
+
from reader_workbench.plugins.transform.sample_metadata import SampleMetadataMerge
|
|
18
|
+
from reader_workbench.workbench.assets import AssetDescriptor, build_plugin_asset
|
|
19
|
+
from reader_workbench.workbench.ontology import PluginSemantics
|
|
20
|
+
|
|
21
|
+
BUILTIN_PLUGIN_DESCRIPTORS: tuple[AssetDescriptor, ...] = (
|
|
22
|
+
build_plugin_asset(
|
|
23
|
+
plugin_id="transform/alias",
|
|
24
|
+
semantics=PluginSemantics(
|
|
25
|
+
domain="generic",
|
|
26
|
+
family="label_enrichment",
|
|
27
|
+
summary="Add alias columns for configured categorical metadata.",
|
|
28
|
+
tags=("aliases", "annotation"),
|
|
29
|
+
),
|
|
30
|
+
plugin_cls=AliasTransform,
|
|
31
|
+
),
|
|
32
|
+
build_plugin_asset(
|
|
33
|
+
plugin_id="transform/assay_labels",
|
|
34
|
+
semantics=PluginSemantics(
|
|
35
|
+
domain="generic",
|
|
36
|
+
family="label_enrichment",
|
|
37
|
+
summary="Materialize configured annotations.labels into dataframe columns.",
|
|
38
|
+
tags=("annotations", "labels", "annotation"),
|
|
39
|
+
),
|
|
40
|
+
plugin_cls=AnnotationLabelsTransform,
|
|
41
|
+
),
|
|
42
|
+
build_plugin_asset(
|
|
43
|
+
plugin_id="transform/outlier_filter",
|
|
44
|
+
semantics=PluginSemantics(
|
|
45
|
+
domain="generic",
|
|
46
|
+
family="quality_filter",
|
|
47
|
+
summary="Drop outlier tidy rows using per-channel and per-time z-scores.",
|
|
48
|
+
tags=("qc", "filtering"),
|
|
49
|
+
),
|
|
50
|
+
plugin_cls=OutlierFilter,
|
|
51
|
+
),
|
|
52
|
+
build_plugin_asset(
|
|
53
|
+
plugin_id="transform/crosstalk_pairs",
|
|
54
|
+
semantics=PluginSemantics(
|
|
55
|
+
domain="logic",
|
|
56
|
+
family="summary_transform",
|
|
57
|
+
summary="Derive pairwise logic crosstalk rankings from fold-change tables.",
|
|
58
|
+
tags=("logic", "pairs", "summary"),
|
|
59
|
+
),
|
|
60
|
+
plugin_cls=CrosstalkPairs,
|
|
61
|
+
),
|
|
62
|
+
build_plugin_asset(
|
|
63
|
+
plugin_id="transform/cytometry_gating",
|
|
64
|
+
semantics=PluginSemantics(
|
|
65
|
+
domain="cytometry",
|
|
66
|
+
family="gating",
|
|
67
|
+
summary="Apply an explicit cytometry gating, threshold, grouping, and QC policy.",
|
|
68
|
+
tags=("gating", "threshold", "qc"),
|
|
69
|
+
),
|
|
70
|
+
plugin_cls=CytometryGatingTransform,
|
|
71
|
+
),
|
|
72
|
+
build_plugin_asset(
|
|
73
|
+
plugin_id="transform/logic_symmetry",
|
|
74
|
+
semantics=PluginSemantics(
|
|
75
|
+
domain="logic",
|
|
76
|
+
family="summary_transform",
|
|
77
|
+
summary="Compute logic-symmetry metrics over an explicit four-state mapping.",
|
|
78
|
+
tags=("logic", "geometry", "summary"),
|
|
79
|
+
),
|
|
80
|
+
plugin_cls=LogicSymmetryTransform,
|
|
81
|
+
),
|
|
82
|
+
build_plugin_asset(
|
|
83
|
+
plugin_id="transform/four_state_vector",
|
|
84
|
+
semantics=PluginSemantics(
|
|
85
|
+
domain="logic",
|
|
86
|
+
family="summary_transform",
|
|
87
|
+
summary="Compute four-state vector logic summaries from annotated plate-reader traces.",
|
|
88
|
+
tags=("logic", "summary", "four_state_vector"),
|
|
89
|
+
),
|
|
90
|
+
plugin_cls=FourStateVectorTransform,
|
|
91
|
+
),
|
|
92
|
+
build_plugin_asset(
|
|
93
|
+
plugin_id="transform/four_state_vector_collection",
|
|
94
|
+
semantics=PluginSemantics(
|
|
95
|
+
domain="logic",
|
|
96
|
+
family="record_collection",
|
|
97
|
+
summary="Collect exact four-state vector record revisions from multiple Reader experiments.",
|
|
98
|
+
tags=("logic", "collection", "provenance"),
|
|
99
|
+
),
|
|
100
|
+
plugin_cls=FourStateVectorCollectionTransform,
|
|
101
|
+
),
|
|
102
|
+
build_plugin_asset(
|
|
103
|
+
plugin_id="transform/ratio",
|
|
104
|
+
semantics=PluginSemantics(
|
|
105
|
+
domain="plate_reader",
|
|
106
|
+
family="derived_channel",
|
|
107
|
+
summary="Create derived ratio channels from aligned tidy measurements.",
|
|
108
|
+
tags=("ratios", "derived_signal"),
|
|
109
|
+
),
|
|
110
|
+
plugin_cls=RatioTransform,
|
|
111
|
+
),
|
|
112
|
+
build_plugin_asset(
|
|
113
|
+
plugin_id="transform/four_state_event_window",
|
|
114
|
+
semantics=PluginSemantics(
|
|
115
|
+
domain="plate_reader",
|
|
116
|
+
family="event_relative_summary",
|
|
117
|
+
summary="Materialize event-relative summaries from provenance-bound source records.",
|
|
118
|
+
tags=("event", "window", "aggregate", "provenance"),
|
|
119
|
+
),
|
|
120
|
+
plugin_cls=FourStateEventWindowTransform,
|
|
121
|
+
),
|
|
122
|
+
build_plugin_asset(
|
|
123
|
+
plugin_id="transform/sample_map",
|
|
124
|
+
semantics=PluginSemantics(
|
|
125
|
+
domain="plate_reader",
|
|
126
|
+
family="metadata_merge",
|
|
127
|
+
summary="Attach well-position sample maps to tidy plate-reader traces.",
|
|
128
|
+
tags=("well_map", "annotation"),
|
|
129
|
+
),
|
|
130
|
+
plugin_cls=SampleMapMerge,
|
|
131
|
+
),
|
|
132
|
+
build_plugin_asset(
|
|
133
|
+
plugin_id="transform/sample_metadata",
|
|
134
|
+
semantics=PluginSemantics(
|
|
135
|
+
domain="generic",
|
|
136
|
+
family="metadata_merge",
|
|
137
|
+
summary="Attach sample-keyed metadata tables to tidy measurement rows.",
|
|
138
|
+
tags=("annotation", "table_join"),
|
|
139
|
+
),
|
|
140
|
+
plugin_cls=SampleMetadataMerge,
|
|
141
|
+
),
|
|
142
|
+
build_plugin_asset(
|
|
143
|
+
plugin_id="transform/overflow_handling",
|
|
144
|
+
semantics=PluginSemantics(
|
|
145
|
+
domain="plate_reader",
|
|
146
|
+
family="quality_filter",
|
|
147
|
+
summary="Mask, drop, or cap overflowed plate-reader measurements.",
|
|
148
|
+
tags=("overflow", "qc"),
|
|
149
|
+
),
|
|
150
|
+
plugin_cls=OverflowHandling,
|
|
151
|
+
),
|
|
152
|
+
build_plugin_asset(
|
|
153
|
+
plugin_id="transform/blank_correction",
|
|
154
|
+
semantics=PluginSemantics(
|
|
155
|
+
domain="plate_reader",
|
|
156
|
+
family="signal_correction",
|
|
157
|
+
summary="Detect and optionally subtract blank control wells.",
|
|
158
|
+
tags=("blanks", "normalization"),
|
|
159
|
+
),
|
|
160
|
+
plugin_cls=BlankCorrection,
|
|
161
|
+
),
|
|
162
|
+
build_plugin_asset(
|
|
163
|
+
plugin_id="transform/fold_change",
|
|
164
|
+
semantics=PluginSemantics(
|
|
165
|
+
domain="plate_reader",
|
|
166
|
+
family="summary_transform",
|
|
167
|
+
summary="Summarize nearest-time fold-change tables from tidy signals.",
|
|
168
|
+
tags=("fold_change", "snapshot_summary"),
|
|
169
|
+
),
|
|
170
|
+
plugin_cls=FoldChange,
|
|
171
|
+
),
|
|
172
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from reader_workbench.plugins.validator.to_tidy_plus_map import PromoteToTidyPlusMap
|
|
4
|
+
from reader_workbench.workbench.assets import AssetDescriptor, build_plugin_asset
|
|
5
|
+
from reader_workbench.workbench.ontology import PluginSemantics
|
|
6
|
+
|
|
7
|
+
BUILTIN_PLUGIN_DESCRIPTORS: tuple[AssetDescriptor, ...] = (
|
|
8
|
+
build_plugin_asset(
|
|
9
|
+
plugin_id="validator/to_tidy_plus_map",
|
|
10
|
+
semantics=PluginSemantics(
|
|
11
|
+
domain="plate_reader",
|
|
12
|
+
family="contract_promotion",
|
|
13
|
+
summary="Promote tidy tables to annotated plate-reader contracts when metadata is present.",
|
|
14
|
+
tags=("contract", "annotation"),
|
|
15
|
+
),
|
|
16
|
+
plugin_cls=PromoteToTidyPlusMap,
|
|
17
|
+
),
|
|
18
|
+
)
|
|
File without changes
|