Repository navigation
Stage 3 S3.3: per-unit channel lists, plane_histograms v5 - #288
Merged
Merged
Conversation
…ormalization v0.5.0 - Pin morphobricks-normalization @v0.5.0. - R_HETEROGENEOUS_LAYOUT_NOT_ENABLED only for units of different image types; units with different channel lists are checked per unit. - PlaneRecord channels from each image's unit; table header = declared channel IDs. - Manifest version 5: file entries record channel_ids (part of the row key), narrow ranges by channel ID, channel coverage per repeat. - Intensity checks, group statistics and plots by channel ID; partial presence refused by default with an explicit opt-in. - RunInputs reads the v5 table and checks each row's channels. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…pec P04 lifted, docs - different_channel_counts compares the images of one folder only, so the notebook's axes and Channels steps accept acquisitions with different channels. - Spec conformance P04 (roadmap S3.3): v04/v05/v06/v17 are processed; v29 (RGB beside channel units) stays refused. - Tests: the owner's extra-stain case end to end (table, manifest coverage, fits per repeat, global fit refused unless opted in, resolver), v04 swap per-ID parity, the conformance plan section 4 v5 row on v13/v04/v05/v06/v17 and an ID with '_', a single discrepant FOV refused, the notebook's partial-presence question. - The channel buttons of the intensity panel choose their first ID explicitly. - Docs: contract, user guide, AGENTS, README, conformance, plan question 79, changelog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…swer without calculating Resetting the answer to No while the question was still shown fired the answer's observer, which recalculated the statistics of the newly chosen table unasked. The question is now hidden first. Regression test in test_notebook_extra_stain. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
guijacquemet
marked this pull request as ready for review
November 11, 2026 19:42
guijacquemet
pushed a commit
that referenced
this pull request
Nov 11, 2026
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
guijacquemet
pushed a commit
that referenced
this pull request
Nov 11, 2026
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
guijacquemet
pushed a commit
that referenced
this pull request
Nov 11, 2026
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
guijacquemet
pushed a commit
that referenced
this pull request
Nov 11, 2026
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
This was referenced Nov 11, 2026
Merged
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.
DRAFT, do not merge. This is Spec roadmap Stage 3 S3.3, the preprocessing side. Owner decision of 11 November 2026: enable different channel counts across repeats now. Based on
maindd8e86f.Summary (by module)
morphobricks-normalization @ ...@v0.5.0. The tag is on release merge1291b091fd76e33a33cdc93960aa84d83d6c2cbf, and the pin now uses the tag directly (coordinator, after the owner tagged it).description_layouts,run/description_run,description_run_text:R_HETEROGENEOUS_LAYOUT_NOT_ENABLEDis now raised only for units of different image types (RGB next to channel units,v29). Units whose channel lists differ go to the per-unit physical checks (R_CHANNEL_COUNT_MISMATCH,R_UNIT_NOT_HOMOGENEOUS,R_HEADER_CONTRADICTION).size_checks.channel_count_issues:different_channel_countsnow compares only the images inside one folder (one imaging unit), never images across folders. This applies to the folder check and toreview_axes, so the notebook's axes step accepts the owner's 3-channel and 4-channel folders.run/steps.header_checksleaves out the replaced channel codes before it decides the bin count and the plane checks (GLOBAL_CHANNEL_CODESmoved intorun/steps).channel_plan(pure):[channels], sorted;channel_coverageclassifies each repeat and channel as full, partial or unavailable, and names the units that lack the channel.PlaneRecord(..., channels=<unit list>);write_plane_histograms(..., channel_ids=<declared IDs>);range_check_issueswork by channel ID.files[]entry recordschannel_ids, which are required and part of theRowKey, so rows recorded under other IDs are recomputed, never relabelled;NarrowRange.channelis an ID;experiment_descriptiongainschannel_coverage, and each unit record gainschannels.partial_channel_coverage: raised when a repeat has a stain in only some of its acquisitions. It never refuses the run.intensity,report,notebook_plots,run_labels:group_summariesraises normalization'sChannelScopeIncompleteError(A_SCOPE_INCOMPLETE, "present in k of n planes") for a partly present channel, unless the caller passespartial_channels="planes_with_channel", and the table marks that choice;RunLabelsno longer maps channel positions.RunInputs:read_plane_histogram_table;CsvFormatError(a v4 table) intoRunInputsError;v17.Decisions / Spec interpretation
v29) puts that layout underR_HETEROGENEOUS_LAYOUT_NOT_ENABLED, "lifted at Stage 3". The owner's decision enabled different channel counts, not mixed image types, and Gate G3 says "only then enable heterogeneous processing". This needs an owner decision. If the owner agrees to lift it, one run then holds two pixel types, which needs a design for dtype and bin count.v04,v05,v06andv17are now processed;v29stays refused. No other Spec test was weakened.v05(PHASE only in DrugA/rep1) andv17give a partial repeat. In the owner's extra-stain case the repeat is full and the other repeats are unavailable.unreadable_planes). Nothing of this run is published, and the earlier generation stays consistent with its own manifest. There is no per-channelChannelMeasurementFailurepath yet (see open questions).Evidence: homogeneous runs,
maindd8e86f (normalization v0.4.0) against this branch (v0.5.0)I dumped every channel histogram of the same trees from both runs and compared them per plane, with the v4 C index mapped to the v5 ID by the row's
channelsorder. Results:v13(180 channel histograms) andv01(86): counts, min, max, binning limits, valid, total and non-finite pixel counts are identical. C0 becomes DNA and C1 becomes ACTIN.Only the table format changes. The golden science tests (
test_histogram_goldens) pass unchanged in substance; only the column names became IDs.Tests
python tools/check.py: 5325 passed, 4 skipped, 0 failed; ruff, format and code rules are clean.tests/test_stage3_channels.py:channel_idsand coverage; a fit per repeat works; the global fit is refused until opted in; Compare groups refuses; the resolver gives "present in 4 of 12" with repeat 2 full and the others unavailable; reruns and full runs give identical bytes;R_UNIT_NOT_HOMOGENEOUS; a whole unit with a missing stain givesR_CHANNEL_COUNT_MISMATCH;v04swapped against unswapped gives identical per-ID histograms and summaries;v13,v04,v05,v06andv17, plus an ID with_(PAX_488);v17partial repeat is recorded;v29stays refused.tests/test_notebook_extra_stain.py: the notebook goes from the axes step and Channels (4 labels) to save, run and Compare groups, including the partial-presence question.tests/test_channel_counts_per_folder.py.Notebook files touched (to coordinate with the redesign branches
claude/redesign3-*)No
.ipynbfile was touched. Changed modules:notebook_results.py: the partial-presence question and the_group_summarieshelper;notebook_compact.py: one line,partial_boxin Compare groups;notebook_plots.py: channel buttons by ID,distribution_pngby ID;notebook_axis_step.py: one message text.Notebook tests touched:
test_notebook_ui.py,test_notebook_owner_fixes.py,test_notebook_debt.py, plus the newtest_notebook_extra_stain.py.Notes for review / open questions
manifest_version == "4"(MorphoFeature, CellPatcher) now refuse these runs explicitly, as the migration plan wants. Each brick still needs its own S3.3.unreadable_planes). Reporting the plane and the channel viaChannelMeasurementFailureis left for S3.4.Generated by Claude Code