Skip to content

Notebook: check and save, reopen (Stage 1, PR 16b) - #238

Merged
guijacquemet merged 3 commits into
mainfrom
claude/notebook-check-save
Nov 9, 2026
Merged

guijacquemet merged 3 commits into
mainfrom
claude/notebook-check-save

Conversation

@guijacquemet

@guijacquemet guijacquemet commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Stage 1 notebook PR 16b: screen 5 Check and save, reopen, thumbnails on screen 2, and the retirement of the global Image type card and labels toggle for described runs (design notebook-natural-design-2026-11-08.md §2 "Screen 5", "Reopen"; owner answers 2-5). Stacked on #237 (PR 16a); retarget to main once #237 merges.

Described run

PreprocessingNotebook(..., describe=True) is the shipped notebook (the notebook cell passes it, and shows masks_step() and check_save_step() before run_step()). Without describe the v0.4 cards stay exactly as they were (embedding bricks, existing API users; every existing notebook test runs that way unchanged). All mode overrides are in one mixin, notebook_described._DescribedRun, each calling the original when the run is not described. In a described run:

  • Step 1. The "Yes, the labels are correct" toggle is retired (labels shown, restated on screen 5). The check writes no design template. The design card keeps only the pairing; it is saved in the draft (pairing), never in experiment_design.csv. Its "comparable" questions are gone (moved to screen 5). The names card's "Yes, use these IDs" is retired: the save click adopts every short name.
  • Screen 2 thumbnails. Each folder of the pairing card shows its first image, channel 1 (PR 13 rules, through the confirmed axis roles; before that, "picture once the axis roles are confirmed").
  • Step 2. The global Image type card is retired; the image type is per unit on Your channels (Notebook: your channels (labels first, then tag per unit) (Stage 1, PR 15) #233); the run is given the type the saved description states.

Screen 5: Check and save (gates Run)

  • In words: "drug (Drug A) is compared against ctrl." / "ctrl is compared against nothing." / "drug: not answered yet". With more than one condition, an unanswered reference blocks the save: "no comparison" is an explicit answer (no silent default).
  • Per replicate: the folders with image counts, a picture of each, the channel chips of each acquisition; a label that some acquisitions lack is in orange ("drug/rep2 has no PHASE: an analysis of PHASE that includes it is refused (A_SCOPE_INCOMPLETE)"). Beside it, one ConfirmToggle "Were these prepared and imaged the same way, so they count as one replicate?"; its date is the day of the click (RepeatAnswer.confirmed_on).
  • Short names, by kind, "never change once saved".
  • Still to answer: every open question in words (untagged channels, unanswered masks, removals, references).
  • Checks on the exact bytes: description_candidate.check_candidate writes the candidate with the canonical writer, reads those bytes with the strict reader, then runs the run's own check_description (R_HETEROGENEOUS_LAYOUT_NOT_ENABLED said in words: saved but not runnable; the physical R_* checks once the axis roles are confirmed). The derived experiment_design.csv change is listed by row ("written for the first time (4 rows)", "new row …", "drug/rep2: confirmed_on … → …").
  • One click: "Yes, save the experiment description". It adopts every short name (names card rules), saves the draft, then publish_draft publishes under the lock (base SHA, strict re-read, transitions, records) and only then writes the derived experiment_design.csv (v1 §11), then deletes the draft. Afterwards: green "Saved . Step 3 can run."; the Run checklist item "Save the experiment description (Check and save)" is ticked and Run enabled (unless heterogeneous or the physical checks refuse).

Reopen

  • The published file is the answers: published_answers maps it back to DraftAnswers keyed by source folders (pairing label = repeat ID). The folder draft gets only the retired IDs as used_ids. carry_over keeps what still exists.
  • Nothing changed: every screen is folded behind one green line, "Saved on , nothing changed. [Run] [Change…]". The date is the file's modification day, display only.
  • New, removed or recounted folders: listed in orange at the top of screen 5. A removed folder gets one grouped question per condition (removal_questions) with Yes, remove. The save is blocked until it is answered, and the removal goes to publish_draft(removals=…) with the reconfirmations it covers, so removed records are written. A replicate whose folders changed (published_answers.reopened) loses only its comparability date and is asked "same way?" again on screen 5; the others keep confirmed_on byte for byte. A changed image count is recorded with the save day (recorded_on).
  • One file holds the answers: the draft carries the pairing, and the CSV is derived only at save, so the two cannot disagree.

Library

  • New, pure: published_answers.py, description_review.py.
  • New, io: description_candidate.py, description_reopen.py.
  • run.draft_file.publish_draft: takes removals and recorded_on, and writes the derived CSV.
  • Hooks in existing modules, each with an unchanged default: _base_draft, _resume_pairing, _wanted_ids, _folder_cell, _design_items/_gate_items, _design_for_run.
  • single_note now says so when only some folders lack the technical-repeat level (it used to claim the whole experiment had none).

Tests

  • tests/test_notebook_check_save.py (13 headless widget tests):
    • retired cards in a described run;
    • CSV written only at save;
    • screen 2 pictures, decoded: 64×64, non-constant;
    • sentences and per-replicate questions;
    • save → Saved and Run enabled;
    • orange missing label;
    • reopen unchanged → folded and Run enabled, Change… unfolds;
    • a folder that joins a replicate → only that replicate asked again;
    • removed folder → Yes, remove required, then removed record;
    • the draft carries the pairing across a reopen;
    • legacy mode unchanged;
    • each replicate row's picture is its own folder's thumbnail (decoded, compared);
    • the mask overlay is decoded and coloured only after the answer.
  • tests/test_published_answers.py (9 library tests):
    • round trip;
    • pairing under the ID;
    • retired IDs;
    • reopened repeats keep or lose dates;
    • review sentences and missing channels;
    • CSV row diff;
    • candidate check waits for roles;
    • published state removal questions;
    • publish_draft writes the CSV only with the description.
  • Changed: test_draft_file (publication now also writes the derived CSV, compared byte for byte), test_embedding_api (pins describe, check_save_step, save_experiment), test_notebook_setup (the fake notebook takes describe).
  • All new tests fail on the base (the modules, the describe mode and the behaviours do not exist there).

Gate

python tools/check.py (.[dev,notebook,zarr], Python 3.13) on 2a3e2b2's code:

  • ruff check and format clean;
  • code rules clean (the # noqa: ANN baseline shrank from 46 to 45; nothing grown; files ≤600 lines);
  • 4828 passed, 4 skipped, 0 failed (environment skips only: a case-sensitive file system ×3, file modes ×1).

The last commit (858f209) changes only the references help wording in described runs, plus one assert. It was checked with ruff, the code rules and the 4 notebook test files (142 passed). CI: see the checks below.

Screenshots

Rendered in headless Chromium (Playwright, deviceScaleFactor 2) from the real widget state (ipywidgets.embed) with synthetic structured images: nuclei-like blobs (DNA), fibre-like lines (ACTIN), a cell haze (PHASE), label and region masks; 2 conditions × 2 replicates, one replicate with two technical-repeat folders; plus an all-RGB experiment. Sent to the owner separately (not committed).

Open questions for the owner (each with a recommendation)

  1. describe default. The shipped notebook passes describe=True, but the class default is False, so embedding bricks and the API keep the v0.4 cards. Recommend: keep False until the UX re-evaluation, then flip it at v0.5.0.
  2. Reopen with changes opens every card, not only the affected rows. Changes are listed in orange at the top of screen 5, new units show untagged (orange) cells on Your channels, and only the changed replicates are asked again. Recommend: accept for now, and fold unchanged rows inside each card in the UX re-evaluation PR.
  3. "Yes, remove" is not kept in the draft file. If the notebook is closed before saving, it is asked again. Recommend: accept; the removal is confirmed again at the save, which is the moment that matters.
  4. An unanswered reference blocks the save when there are two or more conditions. "No comparison" is an explicit choice. Recommend: keep the block (no silent default), as asked in the design's finding 7.
  5. An RGB unit next to fluorescence units is still refused by the folder check (mixed_dtypes, inconsistent_dimensions), so a mixed experiment cannot reach these screens. The screenshots show an all-RGB experiment instead. Also, an all-RGB experiment still needs one label in step A of Your channels (Notebook: your channels (labels first, then tag per unit) (Stage 1, PR 15) #233 behaviour). Recommend: separate issues for both.
  6. "Saved on " uses the file's modification day; the description stores no publication date. Recommend: fine for display. Otherwise, a Spec field would be needed.

Fixes nothing by number (Stage 1 notebook PR 16b).

https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc


Generated by Claude Code

Screen 5 restates the experiment in sentences, asks "same way?" once per
replicate beside its folders, pictures and channels, and saves with one
click: every short name adopted, morphobricks.toml published under the
lock and the derived experiment_design.csv written only then. A
published file is the answers on reopening (folded when nothing
changed; removed folders need Yes, remove; a replicate whose folders
changed is asked again). PreprocessingNotebook(describe=True) retires
the labels toggle, the design card's comparable questions and CSV
writes, and the global Image type card.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The pairing card's pictures appear once the axis roles are confirmed;
tests decode the thumbnail and overlay PNGs (shape, non-constant pixels,
each replicate row shows its own folder's image, the overlay is drawn
only after the answer). The design card says where the pairing is kept
in a described run; the single note is right when only some folders
lack the technical-repeat level; R, G and B get their own chips.

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

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Base automatically changed from claude/notebook-masks to main November 9, 2026 06:01
@guijacquemet
guijacquemet marked this pull request as ready for review November 9, 2026 06:01
@guijacquemet
guijacquemet merged commit c446226 into main Nov 9, 2026
7 checks passed
@guijacquemet
guijacquemet deleted the claude/notebook-check-save branch November 9, 2026 06:29
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