You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: paper.md
+40-6Lines changed: 40 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -70,7 +70,7 @@ Hydra [@Yadan2019] provides hierarchical *composition* but not runtime *resoluti
70
70
71
71
## Beyond Dataclasses: Callable Support
72
72
73
-
ObjectState handles callables (functions, methods) the same way as dataclasses. When given a callable, it extracts parameters from the function signature:
73
+
ObjectState handles callables (functions, methods) the same way as dataclasses. When given a callable, it extracts parameters from the function signature using Python's `inspect` module:
The `None` sentinel works identically for function kwargs—unset parameters inherit from the context hierarchy. This enables pipeline steps where function parameters participate in the same dual-axis inheritance as dataclass fields.
85
85
86
+
**Practical Impact**: In OpenHCS, users can register arbitrary Python functions (from scikit-image, CuPy, PyTorch, etc.) as pipeline steps. ObjectState automatically extracts their parameters and makes them configurable through the same hierarchical inheritance system as dataclass fields. A user can set a global default for `sigma`, override it per-pipeline, and override it again per-step—all without modifying the function itself.
87
+
88
+
## Provenance Tracking
89
+
90
+
Every parameter value is tagged with its source:
91
+
92
+
```python
93
+
state.get_parameter_with_provenance("sigma")
94
+
# Returns: (2.0, "step_config")
95
+
```
96
+
97
+
This enables:
98
+
-**UI Feedback**: Show users where a value came from (e.g., "inherited from pipeline config")
99
+
-**Debugging**: Trace why a parameter has a particular value
100
+
-**Dirty Tracking**: Distinguish between user-set and inherited values
101
+
102
+
The provenance system is the foundation for the GUI's visual feedback—empty fields show inherited values in gray, while user-set values appear in bold.
103
+
104
+
**Implementation Details**: Provenance is tracked via a parallel dictionary structure that mirrors the parameter structure. When a parameter is resolved through the inheritance chain, the resolution function records which scope level provided the final value. This allows the UI to display not just the value, but also its source, enabling users to understand the configuration hierarchy at a glance.
105
+
106
+
**Example**: A user sees `sigma = 2.0 (from pipeline config)` in the UI. They can click to see that the step config has no override, the plate config has no override, but the pipeline config sets it to 2.0. This transparency is critical for debugging configuration issues in complex pipelines.
107
+
86
108
## Example
87
109
88
110
```python
@@ -124,13 +146,25 @@ The user's mental model ("empty = inherit") maps directly to resolution semantic
124
146
125
147
# Research Application
126
148
127
-
ObjectState was developed for OpenHCS (Open High-Content Screening) to manage imaging pipeline configurations with hundreds of parameters across processing stages. The framework handles:
149
+
ObjectState was developed for OpenHCS (Open High-Content Screening), an open-source platform for automated microscopy image analysis. OpenHCS pipelines process thousands of images per experiment, each requiring configuration across multiple scopes:
150
+
151
+
**Global Scope**: Default parameters for all plates (e.g., `num_workers=8`, `output_dir="/results"`)
152
+
153
+
**Plate Scope**: Per-plate overrides (e.g., `num_workers=4` for a specific plate with memory constraints)
154
+
155
+
**Pipeline Scope**: Per-pipeline overrides (e.g., `compression="gzip"` for Zarr output on this pipeline only)
156
+
157
+
**Step Scope**: Per-processing-step overrides (e.g., `sigma=2.0` for Gaussian filtering in this step)
158
+
159
+
Without ObjectState, each scope level would require explicit parameter passing through 20+ function calls. With ObjectState, configuration resolves automatically: a step's `sigma` parameter first checks the step config, then the pipeline config, then the plate config, then global defaults—all transparently.
160
+
161
+
**Interactive Parameter Tuning**: The GUI allows users to edit parameters in real-time. When a user clears a field (sets it to `None`), the UI immediately shows the inherited value via provenance tracking. When they type a value, it overrides the inheritance chain. This unifies the user's mental model ("empty = inherit") with the data model.
162
+
163
+
**Experiment Branching**: ObjectState's git-like undo/redo with branching timelines enables users to compare configuration strategies. A user can configure a pipeline, save it, then time-travel back and try a different configuration, creating a branching history. This is more powerful than traditional undo/redo for exploratory parameter tuning.
128
164
129
-
- Interactive parameter tuning with immediate feedback
130
-
- Experiment branching for comparing configuration strategies
131
-
- Hierarchical override patterns (step inherits from pipeline inherits from global)
165
+
**Dirty Tracking**: The framework maintains both saved and live state. When a user edits a parameter, it's marked dirty. The UI shows visual feedback (flash animations) for modified fields. Users can save changes (updating the baseline) or restore to the last saved state without losing the history.
132
166
133
-
The zero-dependency design ensures easy integration into scientific software stacks.
167
+
The zero-dependency design ensures easy integration into scientific software stacks without adding heavyweight dependencies.
0 commit comments