Promote CellProfiler parity and accelerated backends#60
Draft
trissim wants to merge 986 commits into
Draft
Conversation
Learn moreAll Green is an AI agent that automatically: ✅ Addresses code review comments ✅ Fixes failing CI checks ✅ Resolves merge conflicts |
Refactor benchmark adapters around the same declared runtime contracts used by OpenHCS execution. The OpenHCS adapter no longer carries benchmark-only execution branches for pipeline semantics; it delegates through generated pipeline/source schema surfaces and records visible source information for inspection. Clean the converter stack by removing stale contract inference and recategorization paths, tightening the compatibility matrix and absorber prompts, and moving generated callable metadata toward registry-backed declarations. This keeps benchmark conversion aligned with the module declaration model used in production. Add planning/audit documents and a runtime-profile summarizer that capture the artifact lineage and measurement semantic authority work behind the current parity checkpoint. Generated benchmark outputs remain untracked because they are large run artifacts, not source.
Update agent function DTOs, catalog lookup, knowledge-base context, execution-session handling, and LLM context assembly for the refactored callable and CellProfiler declaration model. The catalog now reflects the backend registry and declaration surfaces used by runtime execution. Adjust PyQt source-binding and live-measurement widgets for the updated runtime/source state shapes without introducing separate UI-only semantic mirrors.
Refresh unit and integration coverage for nominal artifact types, source bindings, runtime values, path planning, pycodify output, function-step transport, materialization flags, and runtime equivalence under the refactored core model. Expand CellProfiler module/runtime tests around declared module semantics, generated pipeline execution, source schema ingestion, symbol table output, processing contracts, object measurement policies, runtime adapter behavior, backend public API, and parity-sensitive module implementations. Adjust PyQt, agent, visible-source, debug, and benchmark comparison tests so they verify the same declaration-backed runtime surfaces rather than stale converter-era or UI-local assumptions.
Advance ObjectState to the registry-backed subfield semantics and current coverage-badge commit required by the refactored UI/runtime ObjectState paths. Advance PolyStore to the pushed memory backend lookup optimization used by OpenHCS memory-backed artifact hot paths. Advance metaclass-registry after merging remote coverage-badge churn into the local registry cache-key checkpoint, and advance pyqt-reactive to the inline dataclass reset, ObjectState flash, listener lifecycle, and metric sampler updates used by the current GUI stack.
Merge origin/benchmark-platform into the local benchmark-platform checkpoint after the CellProfiler semantic parity work. Resolve the ObjectState submodule pointer by keeping the local 70f2a7b checkout, which already contains the remote UI-state work. Resolve the plate-manager test conflict around GlobalPipelineConfig context setup, and update the source-bindings table editor so choice cells can be backed by registered ArtifactType declarations as well as Python Enum values. Verification: pytest tests/unit/pyqt_gui/test_plate_manager_widget.py tests/unit/pyqt_gui/test_source_bindings_editor.py tests/unit/pyqt_gui/test_debug_toolbar.py tests/unit/test_unified_registry_runtime_payloads.py -q
Move FunctionStep transport normalization into PlatePipelineRequest.submission(), the shared lowering boundary used by compile, normal run, and debug submissions. This prevents compile artifacts from being created from one serialized pipeline source and then reused with a differently serialized run request. Remove the compile-only normalized request copy so compile goes through the same submission path as run instead of maintaining a parallel transport path. Add a regression test covering the CellProfiler module-object case that previously produced different compile/run pipeline hashes and request signatures. Verified with: pytest tests/unit/pyqt_gui/test_batch_workflow_compile_engine.py -q; pytest tests/unit/test_function_step_transport.py -q; pytest tests/unit/test_zmq_compilation.py -q; ruff check openhcs/pyqt_gui/widgets/shared/services/compile_workflow_service.py tests/unit/pyqt_gui/test_batch_workflow_compile_engine.py
FunctionStep transport normalization was replacing CellProfiler runtime callables with their raw catalog functions. That discarded the module artifact contract and runtime adapter before compilation, so runtime tuple outputs were treated as anonymous image slices instead of declared artifact outputs. Keep callables that already declare a module artifact contract or runtime adapter intact during normalization. This lets the compiler consume the authoritative callable declaration from the FunctionStep instead of relying on UI-specific rebinding. Remove the plate compile request builder's CellProfiler rebinding pass so compile submission sends normalized steps directly. Add regression coverage proving runtime callables survive transport normalization with their artifact contract and adapter. Tests: pytest -q tests/unit/test_function_step_transport.py tests/unit/pyqt_gui/test_batch_workflow_compile_engine.py
Store generated CellProfiler module settings in a typed compile-time kwarg carrier so editable pipeline source stays raw while the compiler can reconstruct module artifact contracts. Keep the carrier out of runtime callable kwargs and ObjectState child parameter editors, but preserve it when UI state reconstructs FunctionStep patterns for execution. Remove source-level cellprofiler_module_callable/ModuleArtifactContract wrapping from generated pipeline transport and derive invocation contracts through the compile-time kwarg registry. Tests: focused function-pattern stripping, CellProfiler contract derivation, generated pipeline source transport, and ObjectState reconstruction regression. Focused ExampleColocalization benchmark runs without the output-slice identity crash.
…enHCS into benchmark-platform
Move CellProfiler runtime contract derivation out of hidden function kwargs and into declaration-owned compile-time providers. Public pipeline/codegen output now keeps plain backend callables plus explicit public settings, while the compiler reconstructs module contracts from callable/module declarations, source bindings, and generated pipeline metadata. Publish resolved callable annotations for CellProfiler runtime/public wrappers so ObjectState and the function pane render enum parameters as typed controls. Update pyqt-reactive submodule to preserve callable authority when editable function-pattern kwargs extend a signature. Expand module declarations for public CP artifact settings, repeated settings, nominal enum coercion, and generated pipeline binding validation. Update tests for nominal enum literals and stricter measurement/source-binding contracts. Validation: git diff --check; pyqt-reactive diff --check; pytest tests/unit/test_cellprofiler_runtime_callable_introspection.py tests/unit/test_cellprofiler_symbol_table.py tests/unit/test_settings_binder.py tests/unit/test_cellprofiler_generated_pipeline_execution.py tests/unit/test_function_patterns.py tests/unit/test_cppipe_corpus.py -q; pyqt-reactive focused widget enum tests.
Add source-stack lineage relation support and preserve source artifact component identity for source-binding-derived artifacts. Tighten channel-last image role detection so source roles own accepted channel counts instead of treating every rank-3/4 array as a channel-last image. Preserve sparse object-label representations through payload construction/replacement and support singleton stack unstacking for source slices. Use measurement payload identity when assigning repeated artifact plane identities so distinct object/relationship/measurement subjects are not collapsed together. Adjust measurement row projection/equivalence handling for grouped duplicate image-feature rows and source-qualified tables. Covered by runtime value, runtime value store, image stack layout, and runtime equivalence unit tests.
Introduce typed FunctionStepInvocationContracts keyed by normalized function-pattern invocation keys and snapshot them during compilation. Preserve invocation contracts across ZMQ/pycodify transport while keeping clean pipeline source free of internal contract fields. Preserve nominal Pipeline identity through transport and ObjectState replacement without using CellProfiler-specific pipeline metadata. Collapse Textual onto the shared PatternDataManager and keep RuntimeInvocationOptions out of editable function kwargs. Covered by FunctionStep transport, compilation session, pattern data manager, and PyQt pipeline state tests.
Make compile-time CellProfiler contract resolution consume CompilationSession snapshots and FunctionStep invocation contracts instead of Pipeline.metadata side channels. Move missing CellProfiler setting reconstruction onto module declarations via CellProfilerCompileTimeSettingsRequest so compiler code asks module-owned declarations for required settings. Emit grouped FunctionStep dict patterns for adjacent generated modules with matching callable, processing semantics, and source-binding shape; group keys come from source-binding component identity. Attach generated runtime artifact contracts back onto FunctionStep.invocation_contracts and rebind raw generated callables through the typed invocation-contract provider. Keep generated contract sidecars as import-module attributes only; clean user-facing pipeline source does not expose compile-time kwargs, module wrappers, or ModuleArtifactContract literals. Covered by generated pipeline execution, module processing component, runtime callable introspection, source schema, and symbol table tests.
Bind runtime object/image/measurement inputs from declared artifact contracts and invocation options instead of keeping backend-only object/image names in public kwargs. Add runtime-bound parameters for modules whose row identity depends on declared artifacts, including MeasureImageAreaOccupied, TrackObjects, CalculateMath, FilterObjects, and UntangleWorms. Preserve source-stack lineage for Align outputs, treat CorrectIlluminationApply as pure 2D pairwise semantics, and allow aligned multi-image execution to run non-3D callables safely. Preserve sparse object-label representations and dense-domain row completion through CellProfiler runtime adapter and object-measurement row policies. Move shape/Zernike feature-array domain ownership into the Zernike authority and remove stale grid-specific invocation literal overrides now covered by generic runtime invocation option serialization. Covered by CellProfiler module execution, runtime adapter, and settings binder tests.
Derive generated CellProfiler runtime artifact contracts from the selected .cppipe during compilation so clean public FunctionStep source does not need hidden invocation metadata. Bind PURE_3D object-label special inputs as whole-stack values and reject runtime-slice aligned kwargs for true stack callables. Mark Tile as FLEXIBLE so multi-image aligned stacks are tiled by runtime slice instead of collapsed as a true 3D operation. Apply callable default kwargs before CellProfiler execution-mode policy evaluation, which keeps clean code allowed to omit default structuring-element values while preserving morphology stack/plane dispatch.
Submit OpenHCS benchmark executions through the same ZMQ compiler/orchestrator path used by UI/headless execution instead of direct in-process orchestration. Export server-side runtime observations for benchmark validation and cache manifests, and validate those observations against converted .cppipe expectations. Record separate SUBMIT_OPENHCS, WAIT_OPENHCS, COMPILE_OPENHCS, and EXECUTE_OPENHCS phases so benchmark timing distinguishes client wait time from server compile and execution progress.
CellProfiler UI initialization previously prepared source-schema execution directly in the raw plate folder when no explicit workspace root was provided. The benchmark path prepared a separate source workspace, so the same generated FunctionSteps could reach the ZMQ server with a different execution_plate_id and produce different runtime behavior. Derive the default CellProfiler source workspace from the plate root and cppipe path under .openhcs_cellprofiler, force source-schema materialization for this path, and update workspace tests to assert the hidden deterministic execution root. This keeps the server/orchestrator path deterministic instead of depending on GUI process state.
Remove the generated artifact contract sidecar and stop transporting FunctionStep invocation contracts through ZMQ source. Generated CellProfiler import modules now attach invocation contracts through GeneratedPipelineRuntimeBindings, while clean benchmark/UI submissions rely on the compiler's selected-cppipe contract provider. Add AST-backed tests that benchmark and PyQt submissions emit identical clean pipeline source without hidden contract metadata, and update generated pipeline execution tests to compile through invocation-contract providers. Verified with focused unit tests and a fresh forced official30 parity run: 30/30 equivalent, 0 OpenHCS cache hits.
Keep CellProfiler-generated FunctionStep kwargs public/API-facing by removing generated slice_by_slice semantic controls and deriving execution-mode defaults inside the runtime invocation path. Project source-bound current payloads through the active runtime plane when a module resolves image inputs, so UI/ZMQ execution sees the same grouped component slice as canonical benchmark execution. Fix step-output manifest anchor selection to prefer the declared main STEP_OUTPUT dependency over auxiliary runtime artifact inputs, preventing downstream steps from anchoring on unrelated producer artifacts. Batch ImageMath PURE_2D slice execution when slice kwargs can be stacked losslessly, while preserving source-plane stacks as single image operands from provenance metadata. Add focused regressions for manifest anchor selection, source-bound runtime projection, public generated kwargs, and ImageMath batching/source-plane behavior. Verification: official30 canonical ZMQ/OpenHCS run at /home/ts/.cache/openhcs/benchmark_runs/official30_post_imagemath_20260707_1150 produced 30/30 equivalent observations; generated-code AST scan found 303 FunctionStep calls and 0 slice_by_slice literal leaks; pytest focused regression suite passed 148 tests.
Add typed source-binding declaration helpers shared by editable and compiled plans, including group and artifact-key projections. Resolve step source bindings against pipeline source-binding and step-source defaults so generated and UI-loaded pipelines inherit the same SOURCE_BINDINGS microscope semantics. Preserve source component identity and explicit virtual-workspace metadata through source-schema projection, and validate path spelling drift before runtime. Add compiler, path-planner, source-schema, and source-bound runtime tests for inherited defaults, grouped source scoping, and payload source-plane semantics.
Keep generated FunctionStep callables public while attaching CellProfiler artifact contracts through typed invocation_contracts, including grouped contract payloads for module declarations that require explicit per-group runtime selection. Carry generated PipelineConfig with generated Pipeline objects and transport normalization so UI, headless, and ZMQ compilation resolve the same source-binding and processing defaults. Move module-specific behavior to declarations and backend functions: grouped CorrectIlluminationApply emission, Watershed function variants, mask/reference-image semantics, and declared module compatibility semantics. Fix runtime payload preservation, output identity, measurement/object-location parity, and grouped-output cleanup so CP modules execute through generic OpenHCS runtime semantics. Add regression coverage for generated public callable preservation, grouped invocation contracts, UI/ZMQ generated pipeline config inheritance, CP module function resolution, and official generated pipeline execution.
Use generated pipeline configs directly in benchmark and throughput paths so benchmark execution follows the same compiler/orchestrator defaults as UI and headless runs. Record OpenHCS execution timing when progress streams lack axis events by bounding execution with observed completion time, and keep headless native CellProfiler from blocking on Pause modules. Classify compatibility coverage through declared CellProfiler module semantics instead of a parallel role table, including infrastructure filtering and absorbed processing counts. Add benchmark adapter and compatibility matrix tests for strict parity tolerance, ZMQ timing fallback, and nominal module coverage classification.
Update the official ExampleFly ZMQ integration to prepare the CellProfiler source-schema workspace through the same ingestion service used by UI/headless benchmark execution. Submit the source root, execution workspace, and selected .cppipe path together so the server recompiles contracts and source provenance through the canonical compiler-orchestrator boundary instead of a hand-materialized test shortcut. Verification: CELLPROFILER_EXAMPLES_ROOT=/home/ts/.cache/openhcs/cellprofiler_examples pytest tests/unit/test_openhcs_adapter.py::test_benchmark_transport_matches_pyqt_submission_source tests/unit/test_openhcs_adapter.py::test_openhcs_progress_timing_uses_completion_bound_without_axis_events tests/unit/test_cellprofiler_generated_pipeline_execution.py::test_generated_runtime_binding_resolves_inherited_source_bindings tests/unit/test_cellprofiler_generated_pipeline_execution.py::test_generated_runtime_contract_attachment_preserves_backend_callable_identity tests/unit/test_cellprofiler_generated_pipeline_execution.py::test_generated_runtime_binding_groups_native_default_invocation_contracts tests/unit/test_cellprofiler_symbol_table.py::test_compiler_derives_cellprofiler_contracts_from_selected_cppipe tests/integration/test_cellprofiler_generated_pipeline.py::test_official_examplefly_cppipe_executes_through_zmq_server -q -rs
Cache normalized source-image provenance identity tuples on construction and rebuild them lazily for older pickled runtime observations. This removes repeated per-plane identity recomputation in source-aligned payload paths without changing the nominal provenance model. Preserve indexed scalar source-plane provenance when unstacking payloads so single volumetric stack payloads keep their full-stack metadata while ordinary per-plane unstacking expands scalar provenance correctly. Verification: pytest tests/unit/test_runtime_values.py tests/unit/test_step_result_artifacts.py::test_unstack_payload_context_expands_indexed_scalar_source_for_preserved_stack tests/unit/test_step_result_artifacts.py::test_unstack_payload_context_preserves_volumetric_source_slice_identity -q
Retire Pipeline's list-subclass behavior so it is an explicit UI/ObjectState carrier with a private step list. Public execution boundaries now use list[FunctionStep] plus PipelineConfig, and transport/code-document boundaries normalize submitted pipelines to plain step sequences. Update the PyQt code-document workflow, ZMQ transport, benchmark adapter, and CellProfiler generated-pipeline helpers to submit explicit step sequences rather than UI carrier objects. Keep legacy Pipeline values accepted only at compatibility boundaries, where they are immediately projected to lists. Preserve CellProfiler source rendering by carrying hidden runtime parameter exclusions from wrapped processing callables through registry wrappers, and avoid rebinding already-bound CellProfiler runtime callables. Expose imported CellProfiler steps through a pipeline_steps projection for UI consumers. Add a deterministic MCP thesis demo smoke script and checklist using durable mcp_outputs paths, list-only pipeline source, ZMQ execution, and optional pinned UI bridge checks. Validation: - pytest tests/unit/test_pipeline_definition.py tests/unit/test_function_step_transport.py tests/unit/test_pycodify_formatters.py tests/unit/test_openhcs_adapter.py tests/unit/test_cellprofiler_interop_import_records.py tests/unit/test_cellprofiler_source_schema_ingestion.py tests/unit/test_cellprofiler_plate_workspace.py tests/unit/test_cppipe_corpus.py tests/unit/pyqt_gui/test_plate_manager_widget.py tests/unit/pyqt_gui/test_pipeline_editor_widget.py tests/unit/pyqt_gui/test_ui_agent_bridge.py tests/unit/agent/test_mcp_server.py tests/unit/agent/test_ui_bridge_service.py tests/unit/pyqt_gui/test_ui_bridge_lifecycle_config.py -q - python -m py_compile on changed Python files - scripts/mcp_thesis_demo_smoke.sh - scripts/mcp_thesis_demo_smoke.sh --ui-descriptor mcp_outputs/thesis_demo/ui_bridge/ui_bridge_ui-85b00ab1-7adf-4333-8c1e-bd748f196ff4.json
Add a no-fallback live rehearsal driver for the MCP thesis demo. The script starts the real ZMQ execution server and PyQt UI bridge, verifies the UI bridge through the generic ZMQ runtime scan, edits/applies the plate manager orchestrator code document, runs init/compile/execute through the selected-plate workflow, validates Napari payloads and provenance context, and captures UI/viewer snapshots. Update the thesis demo checklist to make scripts/mcp_thesis_demo_live.py the authoritative path and remove fallback/headless substitutions. The verified evidence is mcp_outputs/thesis_demo/live/rehearsals/20260708_020400: three consecutive runs passed at 78.71s, 64.83s, and 65.55s. Also route the floating ZMQ server manager through OpenHCSMainWindow.zmq_server_manager_ports_to_scan() so the UI bridge appears in the same server surface as the embedded manager, and temporarily hide the unfinished pipeline debug toolbar for the seminar UI.
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.