Skip to content

Notebook rework 2: seven steps (Images, Axes, Channels, Masks, Design, Check and save, Run) - #276

Merged
guijacquemet merged 3 commits into
mainfrom
claude/rework-2-steps
Nov 10, 2026
Merged

guijacquemet merged 3 commits into
mainfrom
claude/rework-2-steps

Conversation

@guijacquemet

Copy link
Copy Markdown
Contributor

Stacked on #275. Owner's test of the first redesign (10 November 2026), items (o), (p) and (q): 12 steps become 7, in the owner's order, what the files hold first and what it means after.

The flow

  1. Images: quick scan, then the explicit Looks right: read all image headers.
  2. Axes: roles with the example, the pixel size, and the image type (what the channel dimension holds). Same pattern as the pixel size: one line for all folders, pre-filled from what the image headers say, recorded only by the click Use for all folders; Set per folder… holds each folder's row (the cells, notes and refusals of before); when the header suggestions differ nothing is pre-filled, one line says how many folders say what, and the per-folder part opens. Replacing answers already given asks first. Folders answered differently are named at once with the refusal that follows (R_HETEROGENEOUS_LAYOUT_NOT_ENABLED); colour pictures beside separate-channel images are still refused at the axes, as on main.
  3. Channels: Stains and Tag channels on one page.
  4. Masks: the masks the check paired (with Check the masks, moved from step 1), what each mask type is, and Describe the masks.
  5. Design: Conditions, Replicates and Compared against in one grid: conditions down, biological repeats across, each cell the folder, "compared against" as the last column. Proposals: IDs = folder names (only where the reader accepts them), folders of the same name = one repeat, "no comparison". Looks right: confirm the design adopts every ID as shown (the existing all-or-none adoption, each refusal listed) and records "no comparison" where nothing else was chosen. A name that cannot be proposed disables the click with its reason and opens Edit names or pairing… (the earlier rows, unchanged). Check and save waits for the click and says so.
  6. Check and save. 7. Run (with the collapsed Compare groups).

Does Describe the masks need the run? Yes

Verified in the code: the mask step reads the inputs the run recorded (mask_step.recorded_masks(output), prepare_mask_step(None, output_folder)), so it cannot run before a run exists. It is therefore an action of the Masks step that is greyed out, with its reason in a visible line, until a run recorded masks; after such a run the run step says to come back for it. Nothing about A_MASK_UNCHECKED changes (a brick still refuses a mask this step has not read). Moving the mask check before the run would need a change of the mask step itself: not done here, listed as a question.

Safety rules

  • No auto-confirm: the image type and the design are proposals until the click; tests assert that nothing is saved before it (no ID adopted, no reference, no image type).
  • No guessing: the image type is proposed only when every header agrees; the quick scan and the axes are unchanged.
  • No hidden refusal: every disabled action here has a line beside it (the design's click, Use for all folders, the save, Describe the masks).
  • Every refusal still shown, shorter: Check and save lists eight missing answers and folds the rest; every line is still there.
  • tests/test_spec_*.py are untouched and pass.
  • Same answers, same bytes. Run on the 28-image synthetic experiment with masks, a per-folder pixel-size statement and one comparison, on main b9f1408 and on this branch: morphobricks.toml, experiment_design.csv, plane_histograms.csv, calibration.csv, mask_relationships.json and mask_representation.json are byte-identical; run_manifest.json differs only in written_at and the output path (and discovery_report.* only in that manifest's hash). A test also pins that the stepper and the stacked pages publish the same description and design for the same answers.

Embedding API

welcome, folder_step (all keyword arguments), axis_step, channels_step, masks_step, check_save_step, run_step, results_step, check_button, confirm_button, confirmed_mapping, preflight are unchanged; tests/test_embedding_api.py is not modified and passes (the design's click is a private method so the pinned set of public methods stays exact). The stacked pages keep their cards, their own image-type column in the tag grid and the choose option of the comparison dropdowns.

What an embedder can notice, all of it text on the stacked pages:

  • the masks' "Before you run" items end in "(Masks)" (were "(step 1)" and "(step 1, Masks)");
  • the mask step's hint: "Available after a run that recorded masks: it reads the masks that run recorded (the masks folder is given in step 1)." (was "Available when the output folder holds a run that recorded masks (step 1's masks folder)."), and its help paragraph now starts with what it is needed for;
  • a mask question without labels: "declare them on Channels" (was "on Stains");
  • the missing-answer lines of Check and save end in "(Channels)", "(Design)", "(Axes)" (were "(Tag channels)", "(Stains)", "(Conditions or Replicates)", "(Image type)"), and more than eight of them are folded behind "and N more";
  • the "What next?" after the axes names "Channels … Masks, Design and Check and save".

MorphoRelate (folder_step(show_design=False), axis_step, run_step) and the MorphoFeature end-to-end notebook (welcome/steps/results_step) need no change. A brick that calls steps() gets the 7 steps.

Tests adapted, with the reason

  • test_notebook_stepper.py, test_notebook_compact.py, test_notebook_stains_na.py, test_notebook_axes_quick.py: step titles and positions (12 → 7).
  • test_notebook_check_save.answer_all: in the stepper it gives the Design step's one click (the save now waits for it).
  • test_notebook_owner_fixes.py: "no comparison" is a proposal saved by the Design click, not by re-selecting what is already shown; a refused loop goes back to that proposal.
  • test_notebook_masks.py, test_notebook_mask_step.py, test_notebook_tag_blocks.py: the texts listed above.
  • New: test_notebook_seven_steps.py (20 tests).

Docs

The notebook's Markdown cell (not its code cells, not RELEASE_REF) and docs/user_guide.md §4 describe the seven steps in short; the stale card-by-card text of §4 is removed.

Checks

python tools/check.py and CI: see the comment below.

Not decided here (questions for the owner)

  1. The tag grid and Check and save still grow with the experiment (one row of pictures per folder; one block per replicate). With no inner scroll box the page is long there. Fold the folders of a block after the first few?
  2. Should the mask step be able to run before the run (on the published description), so that Masks is finished in one visit? It needs a change of the mask step.
  3. docs/colab-release-check.md still walks the earlier steps; to rewrite with the v0.5.1 release PR.

Generated by Claude Code

… axes; Channels; Masks; Design)

Owner's test of the first redesign (10 November 2026), items (o), (p), (q). The stepper is
Images, Axes, Channels, Masks, Design, Check and save, Run:

- Axes asks the image type in one line for all folders, pre-filled from the image headers and
  recorded only by 'Use for all folders'; 'Set per folder' holds each folder's row; headers
  that differ pre-fill nothing and open it; replacing answers asks first.
- Channels is the stains and the tags on one page.
- Masks holds the paired masks, what each type is and the mask step, which waits visibly for
  a run that recorded masks (A_MASK_UNCHECKED unchanged).
- Design is one grid (conditions x biological repeats, cells = folders, compared against as
  the last column) of proposals, adopted by one click 'Looks right: confirm the design'
  (the all-or-none ID adoption, and 'no comparison' where nothing else was chosen); Check and
  save waits for it and says so.
- Check and save folds a long list of missing answers; every line is still there.

For the same answers the published description, design, histograms, calibration, mask files
and manifest (minus time and paths) are byte-identical to main; the stacked pages and the
public methods other bricks embed are unchanged. Notebook Markdown and user guide section 4
describe the seven steps.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The user guide's section 4 keeps the short seven-step text: the card-by-card text main
edited (the unread legacy experiment_design.csv) is no longer there.

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc

Copy link
Copy Markdown
Contributor Author

Checks on the head 85aeaaf (main f71e62f merged in through #275; the only conflict was the user guide's §4, where main had edited card-by-card text this PR removes):

  • python tools/check.py: 5261 passed, 4 skipped (the environment skips: a case-insensitive file system ×3, permissions that ignore file modes); Ruff check and format clean; code rules clean.
  • CI: 7/7 green (lint; Ubuntu, macOS, Windows on Python 3.11 and 3.13).
  • Owner test branch: claude/redesign-test-2 (this head, plus one commit that changes only the notebook's RELEASE_REF to 85aeaaf and calls PreprocessingNotebook()). Never merge it. Installing 85aeaaf from GitHub into a fresh environment and building welcome(), steps(), results_step(), then scan, check, answers, save and run, works.

Generated by Claude Code

One conflict in notebook_compact._run_page: both the Masks hint (this branch)
and the log text (rework-1-layout) are kept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc

Copy link
Copy Markdown
Contributor Author

Independent review, merged. The base is now main e858fa2 (#275 merged). Both of main's parents are ancestors of this head, so the merged tree is the tree that was gated.

  • Head 0b3f4a8 merges the two Notebook rework 1: one column, no inner scroll box, every channel in the quick scan; Compare groups in the run step #275 review fixes (see Notebook rework 1: one column, no inner scroll box, every channel in the quick scan; Compare groups in the run step #275). There was one conflict in notebook_compact._run_page, and both sides are kept.
  • Gate: python tools/check.py on 0b3f4a8 passes Ruff check and format (432 files) and the code rules: 5263 passed, 4 skipped. The 4 skips are the environment ones: test_cli_log.py:166, test_folder_rules.py:199 and :230 (a file system that tells names apart by case), and test_discovery.py:665 (permissions that ignore file modes). CI is 7/7 on 0b3f4a8.
  • Same answers give the same bytes: I re-ran this myself on main f71e62f against 85aeaaf and against 0b3f4a8, with my own data and scripts:
    • (A) masks, a per-folder pixel size, one comparison;
    • (B) RGB images, 3 conditions, no comparisons.
    • morphobricks.toml, experiment_design.csv, plane_histograms.csv, calibration.csv and both mask JSON files are byte-identical. run_manifest.json differs only in written_at.
  • No auto-confirm, probed directly:
    • Before the Design click the draft holds no condition ID and no reference.
    • With every other answer given, the save is refused with only "the design is not confirmed".
    • After the click, every ID and "no comparison" are adopted.
    • Building steps() after a check made on the stacked pages, or reopening a draft, records nothing.
    • The image type is pre-filled from the headers. "Use for all folders" with a folder answered otherwise asks first. Cancel changes nothing; "Replace them" writes.
  • Masks: A_MASK_UNCHECKED and its source files are unchanged. The masks-stale "Before you run" item still blocks the run. Describe stays greyed out, with a visible line, until a run recorded masks.
  • Embedding: tests/test_embedding_api.py and tests/test_spec_*.py are unmodified and pass.
    • MorphoRelate claude/stage2-w1-pins (60829ab): the notebook test results are identical with preprocessing main and with this head. The 8 errors and 1 failure are fixture problems on that branch: its runs are not described (A_DESCRIPTION_REQUIRED). YourDataNotebook's seven pages build, and the folder check and axis confirmation work on both.
    • MorphoFeature claude/stage2-mf0 (f77d845): the end-to-end cell 2.0 composition builds and checks on both. tests/test_e2e_notebook_file.py gives 13 passed and 1 failed on both; the failure is that branch's stale v0.4.0 pin in a copied notebook.

Notes for the owner, not blockers:

  • The image type proposes "separate channels" when no header says colour. This is an inference from the header having no RGB samples axis, and it is recorded only on the click.
  • The folder-exclusion input is still a 5em Textarea. It is an input, so I left it.
  • The masks table's number columns look misaligned (screenshot 20). This is cosmetic.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc


Generated by Claude Code

@guijacquemet
guijacquemet merged commit 9a5da03 into main Nov 10, 2026
7 checks passed
@guijacquemet
guijacquemet deleted the claude/rework-2-steps branch November 10, 2026 22:44
@guijacquemet guijacquemet mentioned this pull request Nov 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants