Promote CellProfiler parity and accelerated backends#60
Draft
trissim wants to merge 951 commits into
Draft
Conversation
Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
Move MCP capability and renderer contract ownership away from package-level DTO mirroring and onto direct typed declarations. Add registered authoring-context declarations, knowledge-manifest source tracking, and shared plate-file inventory query types so agent-facing guidance and plate file APIs derive from nominal authorities.
Add a typed debug-toolbar action surface, persistent runtime inspection payloads, shared execution-state vocabulary, and UI bridge action provider coverage for debugger controls. Tighten ZMQ debug client/server handling, progress aggregation, and runtime-value rendering so the debugger can be inspected from both the UI and agent surfaces.
Extract generated CellProfiler pipeline rebinding into a shared service used by compile and run request construction. Keep config-window/source-binding rendering aligned with resolved ObjectState values and add coverage for compile engine rebinding and module execution behavior.
Document the nominal debug-action declaration model, session-state projection, UI bridge surface, and dry-run/search gates for the next debugger UX refactor.
Treat generated runtime function-spec traversal as a class-level operation so nested FunctionStep function patterns can be checked without referencing a nonexistent instance. Add a regression test for list-shaped callable specs, matching the UI compile failure seen while rebinding generated CellProfiler pipelines before submission.
Restore the OpenHCS component configuration default so processing_config.group_by resolves to GroupBy.CHANNEL while variable_components keeps SITE as the default execution axis. Treat GroupBy.NONE as a real enum value instead of letting it compare equal to Python None. ObjectState and lazy dataclass code use None as the inheritance/unset sentinel, so GroupBy.NONE must remain a concrete user override that can be saved, diffed, reset, and round-tripped independently of lazy resolution. Normalize missing variable_components to an empty tuple in FuncStepContractValidator and skip component-key validation for dict patterns when the resolved grouping value is GroupBy.NONE. That avoids querying orchestrator component keys for the explicit no-grouping case while preserving normal validation for concrete axes. Tests cover GroupBy.NONE ObjectState override/reset behavior and prove dict-pattern validation does not call component-key lookup for GroupBy.NONE.
Infer dict-pattern groups for explicit GroupBy.NONE when the source filename metadata contains exactly one fixed component whose values match the dict keys. This keeps concrete no-grouping configs usable for legacy/simple pattern declarations without requiring an orchestrator component lookup. Carry runtime group identity into artifact source metadata when a materialized record has exactly one source component explicitly marked missing. This lets grouped runtime artifacts such as per-channel object labels build coherent output filenames and viewer metadata even when the payload itself was produced with a null component placeholder. Derive stream metadata from emitted source identities, payload provenance, or fallback source identity in that order so Napari streaming gets concrete component values wherever possible. When a streaming request contains aggregate artifacts with incomplete source axes, restrict the viewer display config to the component order that is complete for every streamed item. StreamScopedDisplayConfig delegates the original viewer config API while narrowing COMPONENT_ORDER and component_modes for the request, avoiding viewer payload failures from null component domains. Update the integration visualizer inspection to use the current visualizer-info object contract. Tests cover GroupBy.NONE dict-pattern source-component inference, grouped runtime artifact filename/metadata reconstruction, aggregate stream display-config narrowing, and Napari display payload compatibility through the scoped config wrapper.
Advance ObjectState to the commit that adds deferred live-cache invalidation and pyqt-reactive to the commits that coalesce form/list repaint work and move system monitor probes behind cached samplers. Expose the new monitor controls through OpenHCS PyQt configuration: OpenGL-backed plot rendering, GPU poll refresh cadence, CPU-frequency poll refresh cadence, 10 FPS sample updates, and a 30 FPS legacy render cap. Validate the new positive refresh intervals alongside the existing monitor bounds. Preserve dirty per-plate PipelineConfig ObjectState delegates when saving global config. The plate ObjectState owns the live/saved pipeline draft, so global saves now refresh the global config context and emit the effective config without replacing orchestrator.pipeline_config and rebasing away unsaved per-plate edits. Coalesce ZMQ progress UI redraws by switching the progress timer to single-shot mode and starting it only after registry events mark progress dirty, eliminating the constant idle 100 ms poll. Tests cover deferred invalidation flush/coalescing through ObjectState, delayed dispatcher notifications after debounced form edits, dirty per-plate config preservation across global saves, monitor OpenGL/fallback policy, fixed-axis plot updates, persistent plot buffers, and config-driven monitor restart boundaries.
Replace deprecated remove_small_holes(max_size=...) calls with area_threshold=... in absorbed CellProfiler morphology and skeleton code. scikit-image 0.25 removed the max_size keyword, which caused converted CellProfiler pipelines that fill object or skeleton holes to fail at runtime. The value semantics match the existing maximum-hole-area threshold; only the upstream keyword changed. The compatibility path was validated by rerunning the generated CellProfiler pipeline/schema test suite that exercises the absorbed module registry and converted pipeline materialization.
Introduce core nominal progress/debug projection types so debugger state is built from the same ProgressEvent snapshot as normal runtime aggregation instead of reinterpreting UI state. Add debug command and boundary declarations, a shared debug session projection context, runtime/debug projection builders, runtime tree semantics, live-measurement projection cleanup, and tests for debug records, terminal states, progress channels, ZMQ progress, and compile status projection. Advance the ZMQRuntime submodule to the liveness-aware waiter commit so status timeouts during active progress no longer look like lost connections.
Move the pipeline debugger UI onto declaration-backed actions and shared debug session projections, then expose the same state through UI bridge surfaces and dev-client renderers. Add the live UI overview, compact state-surface rendering, debug runtime frames, terminal summaries, runtime inspector access, server-browser projection reuse, and tests covering toolbar actions, UI bridge payloads, MCP rendering, and live server tree synchronization. The debugger surface now reports current/last frames from the core runtime projection and keeps terminal cursor/snapshot metadata visible after stop/cancel.
Collapse CellProfiler debug-view and module-specific behavior into nominal debug view and module declarations rather than renderer-side lookup tables. Move table projection, empty-state, and artifact/runtime inspection semantics into core debug view declarations, slim the CellProfiler debug view adapter, and update module declarations/tests to keep runtime consumers blind to leaf module names.
Add the source-binding activation plan and move supporting runtime/viewer/config behavior onto typed declarations and reusable protocol objects. Introduce streaming config declarations, viewer control protocol extraction, source-binding runtime cleanup, artifact materialization guardrails, and pycodify formatting coverage without adding MCP-specific handling.
Move benchmark dataset selection and manifest root materialization onto typed declarations instead of parallel catalog-specific code paths. The Bio-Formats HCS validation path now selects DatasetSpec entries by BenchmarkDatasetTag, lets the microscope registry auto-detect BioFormatsHandler, and derives observed wells/sites/channels/z/timepoints/grid dimensions from the metadata handler. That removes the duplicated BioFormatsHcsCatalogRow axis-expectation authority and makes the validation report a projection of the same dataset registry used by normal benchmark cases. Manifest root acquisition is now enum-keyed through AutoRegisterMeta, and ComparisonManifest materializes each root with case-derived root requirements. This keeps root acquisition scoped to the manifest root that declared it instead of having a broad helper inspect every case/root combination at once. The checked-in benchmark manifests are updated to the new root/acquisition shape, and the focused manifest, acquisition, and Bio-Formats validation tests cover the declaration-owned behavior.
Replace benchmark-private OpenHCS axis knobs with the pipeline source-schema image-set selection model used by generated OpenHCS pipelines and native CellProfiler reference runs. OpenHCSAdapter now receives an explicit GlobalPipelineConfig and SourceSchemaImageSetSelection instead of rebuilding worker/start-method/axis policy from ad hoc pipeline_params keys. The selected source-schema wells or first-N image sets become PipelineConfig well_filter_config before execution, so the orchestrator sees the same declaration-owned selection path as normal OpenHCS execution. CellProfilerAdapter uses the same SourceSchemaImageSetSelection when preparing selected native input domains and reference-scope slugs. Cache identity now compares the full current key instead of maintaining legacy OpenHCS-axis compatibility branches, because the semantic input selection is no longer hidden in benchmark-only params. The CLI, comparison loader, runner, converter exports, throughput reporting, and adapter tests are updated around the shared selection contract and the simplified provenance/cache shape.
Make source matching consume a core-owned candidate universe and metadata projection instead of deriving pipeline-start selector candidates from whichever load workspace happened to be active. SourceUniverseRuntimeState and SourceBindingRuntimeContext now carry pipeline_source_candidate_files separately from pipeline_input_files. PipelineStartSourceUniverseRequest builds that selector universe from both virtual workspace projection metadata and the physical pipeline source tree, which lets source artifacts such as sidecar illumination files participate in selector matching without being loadable image planes. Source metadata now has a reserved OpenHCSSourceFilterPaths field. SourceSchema workspace materialization writes source path identities into that field, source matching merges it through the reserved metadata path, and selector matching can target the original source names even after files have been projected into normalized virtual workspace names. VirtualWorkspaceSourceProjection now resolves metadata through physical-source identity, exposes physical pipeline-start candidate files, and has a plate-level authority constructor so the orchestrator can inspect prepared workspace metadata without fabricating a runtime axis. SourceBindingsHandler also keeps AUTO candidate discovery so OpenHCS workspace metadata remains visible after materialization. Source binding compilation now only freezes explicitly enabled source bindings; disabled configs remain inert instead of filtering bindings back in from module artifact contracts. The unit coverage exercises the enabled/inert distinction, match-plan-free selector expansion, axis-filtered virtual projections, and Bio-Formats workspace projection behavior.
Teach the CellProfiler source-schema compiler and runtime to derive source roles from module declarations instead of assuming every LoadImages alias is a grayscale stack image. PipelineImageSchemaBuilder now accepts source-image role refinements keyed by alias. CellProfilerModule exposes source_image_types_by_alias(), and CorrectIlluminationApply declares illumination-function aliases from its settings. LoadImages lowers stack-participating image types to ImageAssignment and non-stack image roles to SourceArtifactAssignment, so .mat illumination functions are modeled as image artifacts rather than forced into the runtime image stack. Pipeline-start source binding resolution now asks SourceBindingRuntimeContext for pipeline_source_candidate_files, matches selector clauses against candidate path identities plus OpenHCSSourceFilterPaths metadata, and inherits current-step component scope only when those components are present in the target candidate set. This fixes source-schema workspaces where normalized virtual filenames need to match original source paths. Generated CellProfiler code emits LazyStepSourceBindingsConfig(enabled=True) for declared source bindings, matching the core rule that disabled source bindings stay inert. Direct generated-pipeline execution now relies on PipelineConfig well_filter_config rather than passing a separate well_filter argument around the orchestrator. The integration coverage exercises generated pipelines, .mat illumination source artifacts, source-schema workspace execution, relationship/measurement output shape updates, and runtime candidate matching across path identity.
Add the debugger IDE workbench plan and update the agent knowledge-base rendering for the new source-schema selection contract. The plan records the debugger architecture decisions from the live UI/MCP audit: runtime debug events are already recorded in core, DebugRuntimeProjection is the projection authority, Qt and MCP must render that projection rather than rebuilding debugger state, and FunctionStep.debug_pause is a step stop point rather than the condition for observability. It also captures the concrete boundary rules for the next implementation slice: route visible debugger Stop through DebugCommandType.STOP, avoid a second breakpoint store, keep command/phase/table semantics on their existing declaration authorities, and expose timeline/frame/stop-point state through the existing UI bridge surface. KnowledgeBaseService now renders default source-schema image-set selection in the official30 recipe document so benchmark guidance matches the selection model introduced in the benchmark execution commits.
36ecb7c to
77f8c8f
Compare
Advance ObjectState and metaclass-registry to their latest main-branch commits after syncing benchmark-platform. Both upstream commits are coverage-badge refreshes, so this keeps the superproject pointers aligned with the current remote submodule state without changing OpenHCS runtime code.
Advance ObjectState to the registry-wide resolved-change notification commit so UI surfaces can subscribe through the ObjectState authority instead of per-row callback wiring. Advance pyqt-reactive to the manager-list flash and managed-form listener cleanup commits, including explicit list-context reset behavior for plate switches and placeholder support for inline dataclass editors.
Remove the production-wide PipelineEditorWidget.cellprofiler_import_result fallback so generated CellProfiler contracts cannot leak from a previously loaded .cppipe plate into a synthetic or unrelated plate. Expose a plate-scoped import-result provider on the pipeline editor and use CellProfilerPipelineRuntimeBindingService from code-mode apply, matching the compile/run request path. Move dual-editor orchestrator-config signal ownership onto the editor window so PipelineEditorWidget does not create untracked cross-window subscriptions. Clean up dual-editor event-bus and orchestrator-config listeners through the managed-window lifecycle, then cover both owned connection setup and cleanup with tests. Add regression coverage proving code-mode apply ignores stale CellProfiler import results associated with other plate scopes.
Construct SnapshotTableBrowser with keyword arguments and an explicit SINGLE selection mode so QMainWindow is not misinterpreted as the table-browser selection-mode argument. Remove the stale datetime import and add a focused PyQt regression test that checks the snapshot browser owns the window parent and keeps single-selection behavior.
Update the ObjectState and pyqt-reactive submodule pointers for structural subfield semantics, inline dataclass chrome, and ObjectState-path flash targets. Teach the SourceBindings editor to expose nominal child identities, granular table-cell semantics, placeholder chrome, reset/provenance targets, and logical/rendered value separation without using display text as authority. Route time-travel and cross-window navigation through concrete ObjectState paths so source-binding tables and nested config editors can scroll and flash the changed structural target. Add focused coverage for SourceBindings table semantics, cross-window placeholder updates, config-window state resolution, and concrete-change time-travel navigation.
Add registered live-overview contributors for operations, windows, and state surfaces so MCP/UI clients receive compact current UI status without hardcoded surface summaries. Route mutation submission through typed operation contracts with accepted receipts, operation IDs, and result-specific outcome projection instead of duplicating status handling per endpoint. Teach window code documents to distinguish ObjectState-backed revision tokens from driver-owned floating editor tokens, keeping stale checks tied to the correct document authority. Update MCP renderers and tests for operation status, code-document behavior, parameter help, system-monitor coalescing, and UI-agent bridge projections.
Project debug cursor and terminal state into pipeline list presentation so active steps have visible markers and badges while preserving the existing workflow/action boundaries. Restore pipeline editor presentation after time travel only when structure changes, and keep plate-manager cancellation/delete workflows aligned with the debug/run button state. Add focused debug-toolbar and pipeline-editor coverage for cursor markers, badge rendering, and workflow state transitions.
Carry runtime payload metadata through unified registry projections so compiler/runtime consumers can read the declared payload contract without re-inferring it from callable details. Add regression coverage for runtime payload metadata round-tripping through the unified registry.
Capture the nominal authorities, non-negotiable boundaries, implemented slice, and remaining extraction path for row/cell dirty, default, inherited, reset, provenance, flash, and time-travel semantics.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
This PR promotes the CellProfiler compatibility path from benchmark-only smoke execution into a broader OpenHCS runtime compatibility layer with explicit runtime semantics, output equivalence, accelerated backends, parity tracking, and expanded generated-pipeline coverage.
Audit
Runtime and equivalence semantics
CellProfiler module compatibility
.cppipeconversion and binding coverage for alignment, color conversion, image math, mask objects, smooth, enhance edges, expand/shrink, filter objects, classify objects, illumination, object measurements, object relationships, and tracking.Explicit accelerated backends
openhcs.processing.backends.cellprofilermodules for alignment, classification, colocalization, illumination, image quality, intensity, intensity distribution, morphology, neighbors, outlines, region properties, relationships, secondary objects, shape, texture, thresholding, tracking, watershed, and Zernike calculations.numbaa required dependency and declares CellProfiler compatibility extras separately.Benchmark tracking and tests
.cppipesuites.Verification
Ran with the sibling OpenHCS virtualenv:
Result:
Follow-up Work
.cppipedialect compiler out of benchmark ownership into a product-facing OpenHCS interop/dialect package so benchmark, CLI, and PyQt consume the same canonical conversion service..cppipeloading alongside.py: compile.cppipeinto a normal OpenHCSPipeline, show generated OpenHCS code/form state, and expose source-schema/provenance mapping instead of a black-box CellProfiler runner.