Skip to content

CP-3: notebook, docs, installers and code standards for v0.2.0 - #71

Merged
guijacquemet merged 18 commits into
mainfrom
claude/cp-3-notebook-docs-installers
Nov 2, 2026
Merged

guijacquemet merged 18 commits into
mainfrom
claude/cp-3-notebook-docs-installers

Conversation

@guijacquemet

@guijacquemet guijacquemet commented Nov 2, 2026 •

Copy link
Copy Markdown
Contributor

CP-3 of the CellPatcher v0.2.0 plan (design v0.4 §6, §8 and §9 on MorphoFeature claude/restart-doc), built on CP-1 (#68), CP-2a (#69) and CP-2b (#70). This PR does not tag. v0.2.0rc1 is tagged only after the CP-3b follow-up (see "Not in this PR").

At the coordinator's request it also re-pins to preprocessing v0.4.0rc2 (44971bc) and wires in rc2's check for files the run did not record.

Commits

Implementation:

  1. d2b8d20 Code standards (tooling only):
    • tools/code_rules.py is an identical copy of preprocessing's shared file (SHA-256 cc04a420…, tested; the same as preprocessing main at 6711b48).
    • tools/check.py and --rules.
    • tools/code_rules_baseline.json holds today's debt. It can only shrink, and it has a # noqa ratchet.
    • Guard fixtures, a CI rules job, and Ruff 0.17.3 pinned in the test extra.
  2. 09d668a Mechanical move: refuse_transposed_mask_axes moves from io to axes.
  3. 87c696b In-memory images with X before Y are refused, as masks already are (§6).
  4. b357297 Pin preprocessing v0.4.0rc2 (core and zarr extra).
  5. 0f08b0d rc2's unrecorded-files check is surfaced: unrecorded_files and zarr_extra_missing.
  6. 88c539d The preprocessing command names rc2's design step.
  7. d7b89a9 The notebook is rewritten for v0.2.
  8. 878614f Installers: construct.yaml lists every module; CI and the test extra run the notebook.
  9. 1d47a6d Docs, CHANGELOG and migration notes.

Independent review (fixes):
10. a58a5fb The object scan refuses X-before-Y in-memory axes. scan_cell_patch_size and scan_cell_objects refuse them, and so does CellSegmentationStrategy(mask_axes=…). Before this fix, a square mask declared XY was measured as if it were transposed: an object 7 high and 3 wide was reported as bbox_height 3 and bbox_width 7.
11. f26c471 A # noqa comment no longer hides a Ruff finding from the baseline.
- The shared ratchet counts only C901, PLR0913, PLR0915 and ANN. A new # noqa: F401 therefore hid a new finding, and check.py stayed green (shown with a mutation).
- Ruff now runs with --ignore-noqa.
- The 2 findings that were already suppressed are now recorded in the baseline, and 3 unused noqa comments are removed.
12. 5cc1c52 No installer is built for a release candidate (owner decision 4).
- .tools/python/bump_version.py refuses a pre-release version with a clear message, before it changes any file. The release workflow runs it first.
- This is tested.
- It is documented in docs/developer_notes.md.
13. 87d9924 The CP-3b follow-ups and the embedded-preprocessing plan are recorded in docs/plan.md and the CHANGELOG ("Not yet").
- Step 1 of the notebook now says plainly to run the preprocessing notebook or CLI first (tested).
14. 9f68c59 The preview equals the export with normalization (image scope), and the preview has exactly the image's exported patches.
15. ac3606b PatchTorchDataset refuses X-before-Y axes when it is built. Before, the refusal came only when an item was loaded, in a DataLoader worker. Tested with CPU torch.
16. bb51001 A file refused while it is read (RunInputsError during the preview or export) is shown as a refused run, not as "Please change the settings".
17. e45b823 CHANGELOG updated for these fixes; the notebook's docs link is now absolute (the relative one does not open on Colab).
18. 706accf Health snapshot.

Behaviour changes

  • Notebook (notebooks/CellPatcher/CellPatcher.ipynb):
    • It asks for the preprocessing run's output folder. It asks where the experiment and masks folder are now only if they were moved since preprocessing.
    • Every file is read through RunInputs.
    • It has four steps: the run, the settings, the preview and the export.
    • The code lives in cellpatcher.notebook_session (orchestration), notebook_ui and notebook_form (ui). The old notebook's 2,357-line inline class and 0.8 MB of widget state are gone.
    • It follows LabConstrictor portability, as preprocessing PR #118 does:
      • # @title Run to … starts every cell, and the code is hidden.
      • The Colab guard holds Drive, the widget manager and the zarr extra.
      • It uses no magics, and /content appears only in the guard.
      • RELEASE_TAG = "v0.2.0rc1", and no GITHUB_TOKEN.
      • The version index agrees.
      • It has Colab and JupyterLab callouts.
    • Refusals are shown with their code, files and action, and the step stops there.
  • Breaking: in-memory common.image_axes with X before Y (XY, CXY, XYZ) is refused by:
    • run_patching;
    • lazy delivery;
    • PatchTorchDataset;
    • the object scan (masks too).
  • Since rc2:
    • An unrecorded image or mask is unrecorded_files.
    • OME-Zarr images without zarr give zarr_extra_missing.
    • An rc1 mask record without axes gives preprocessing_run_refused.
    • No refusal is caught and continued.
  • no_preprocessing_run names check → design --confirm … → run (checked against rc2's cli_design.py).
  • Installers:
    • construct.yaml lists every module, and test_installers.py keeps it complete.
    • setup.py and __version__ are 0.2.0rc1.
    • Release candidates get no installer.

Not in this PR (owner decisions, 2026-11-02)

CP-3b, a follow-up PR before tagging v0.2.0rc1:

  • CellPatcher_Pytorch.ipynb and CellPatcher_Strategy_Examples.ipynb get the same LabConstrictor treatment. They still use the old GITHUB_TOKEN install of main.
  • The old notebook's "show parameters per group" table and its before/after normalization histograms come back. They will be computed in the package, never in notebook cells.

Before the final v0.2.0 installers:

  • LabConstrictor's construct.yaml copies the package to CellPatcher/src/cellpatcher/cellpatcher/.
  • In that layout, setup.py (find_packages(where="src")) finds no package, so the installed app has no cellpatcher.
  • The reviewer reproduced this by copying the files as construct.yaml lists them and pip-installing them.
  • This is pre-existing (main has the same layout). It is not fixed here because no installer is built for an rc. It needs fixing in the template or setup.py before the final installers.

After preprocessing v0.4.0 is final:

  • The notebook will include the preprocessing steps through preprocessing's declared embedding API: PreprocessingNotebook and notebook_style, pinned by its tests/test_embedding_api.py.
  • It will never copy their code.
  • Until then, it sends users to the preprocessing notebook or CLI first.

Accepted debt: Ruff findings are kept in the shrink-only baseline; ruff format is not enforced yet.

Gate (Python 3.11, uv venvs, preprocessing v0.4.0rc2, head 706accf)

Environment Passed Skipped
.[test,zarr], tools/check.py (exit 0) 1057 11 (7 torch, 4 notebook extra)
.[test], tools/check.py (exit 0) 1036 32 (21 zarr, 7 torch, 4 notebook extra)
.[test,zarr,notebook], tools/check.py (exit 0; includes the nbclient kernel run) 1068 7 (torch)
  • With CPU torch added, test_torch_dataset.py, test_delivery.py and test_biological_repeat.py passed: 57 tests.
  • tools/check.py --rules is clean. Ratcheted # noqa: 0.

§9 figures (measured on the new and rewritten code)

  • Files: notebook_ui.py 379 lines, notebook_form.py 307, notebook_session.py 284, tools/check.py 206.
  • Largest values in new code:
    • complexity 5 (check.main);
    • parameters 4 (export_patches_of_run);
    • executable lines 27 (run_open._refusal_issue);
    • statements 20 (CellPatcherNotebook.__init__).
  • Touched pre-existing functions (baselined debt, not grown):
    • PatchTorchDataset.__init__: 10 parameters, 46 executable lines;
    • scan_cell_objects: 45 executable lines, 6 parameters.
  • ruff --isolated --select C901,PLR0913,PLR0915,ANN,D (NumPy convention) passes on the new modules. Every module declares its layer.

Colab hand-check list (after tagging v0.2.0rc1, since the notebook installs that tag)

  1. Run Step 0 in Colab. Drive mounts at /content/drive. pip installs cellpatcher[notebook,zarr] @ …@v0.2.0rc1 (with preprocessing rc2). The ready card shows 0.2.0rc1.
  2. The widgets render. Browse… shows the "paste the path" card.
  3. Step 1 with a run on Drive shows the green card. Ticking "moved" reads from the copy. Adding a .tif gives a red [unrecorded_files] card.
  4. In Step 2, only the chosen mode's controls show. The dataset size comes from Scan the object sizes of the dataset.
  5. The Step 3 preview draws inline.
  6. The Step 4 export writes patches.csv, images.csv and run_config.json on Drive.
  7. With an OME-Zarr experiment there is no zarr_extra_missing.
  8. After a disconnect, run Step 0 and Step 1 again: there is no stale state.

https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc


Generated by Claude Code

…aseline

Tooling only, no behaviour change (design v0.4 §9):
- tools/code_rules.py: an identical copy of preprocessing's shared file
  (SHA-256 cc04a420..., checked by tests/test_code_rules.py, as there);
- tools/check.py: preprocessing's, plus Ruff's findings counted per file,
  function and rule against the same shrink-only baseline, since
  CellPatcher adopts the standards with existing debt; --rules for CI;
- tools/code_rules_baseline.json: today's debt (577 entries, noqa 0);
- pyproject.toml: tool settings only (Ruff with preprocessing's rule set,
  the code-rules owner, package and layers); setup.py still builds;
- tests/guard_fixtures: preprocessing's deliberately bad modules;
- CI: a rules job; Ruff pinned (0.17.3) in the test extra.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
A mechanical move, so the image refusal of the next commit sits beside it
in the pure axes module: refuse_transposed_mask_axes and
MASK_TRANSPOSE_HELP move verbatim from cellpatcher.io to cellpatcher.axes;
pipeline and delivery import them from there. No caller outside
CellPatcher (MorphoRelate, MorphoEmbed, MorphoFeature, MorphoObjects,
fiberfeatures checked). Baseline lowered: pipeline.py 1031 -> 1030 lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Design v0.4 §6 asks for a canonical-only layout for in-memory arrays (CP-2b
review follow-up). run_patching and lazy delivery accepted
common.image_axes='XY' (or 'CXY', 'XYZ'): a 12 x 20 array then gave the
whole-FOV patch y0..y1 = 0..20, x0..x1 = 0..12, the coordinates of the
transposed image. Now refused with the swapaxes fix
(axes.refuse_transposed_image_axes); run_patching checks images and masks
with one call (axes.refuse_transposed_inputs), so it shrinks by one line.

Regression tests: 13 of the new tests fail on main (12 run_patching cases,
one lazy delivery); the mask test now declares the image 'YX'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
rc2 (44971bc) refuses a mask whose header puts X before Y in the run
itself; with rc1 the run was written with no axes for that mask and the
file run refused the record. test_a_mask_file_whose_header_names_x_before_y
now checks the preprocessing run's refusal. The normalization pin (v0.3.2)
is the one rc2 pins, unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Since preprocessing v0.4.0rc2 RunInputs.open refuses an experiment holding
images or masks the run did not record (UnrecordedFilesError). CellPatcher
now reports that as its own issue, unrecorded_files, naming the files and
saying that no image is ever left out; a run with OME-Zarr images opened
without zarr is zarr_extra_missing, naming cellpatcher[zarr]. Every other
refusal keeps preprocessing_run_refused. Nothing is caught and continued.

This closes the CP-2a known limitation: an image added after the run was
not patched and nothing said so. Docs and CHANGELOG now state the refusal.

Regression tests (tests/test_unrecorded_files.py): an added image in a tree
and a folder run, an added mask, validate_image_and_mask_folders, the zarr
refusal and an rc1 mask record without axes. Against main's source (with
rc2 installed) 4 of the 6 fail: the codes were preprocessing_run_refused.
test_normalization's added-image test now expects the refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Since preprocessing v0.4.0rc2 `check` writes experiment_design.csv
prefilled from the folders, and `run` then stops (design_not_confirmed)
until its repeat groups are confirmed, so `check` then `run`, the advice of
no_preprocessing_run, no longer works. It now names the new `design`
command between them (verified with the rc2 CLI), or the notebook.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The notebook was broken on main: it imported the removed pair_masks,
read_ngff_mask and normalization.cached_statistics, asked for image axes
and a mask source, and held a 2,357-line app class inline (0.8 MB of saved
widget state). Rewritten like preprocessing's notebook (PR #118):

- The user gives the preprocessing run's output folder and, only for a
  moved or copied experiment, where it and its masks folder are now; every
  file is read through RunInputs. No axis, label or pairing question.
- The cells only call the package (AGENTS.md): cellpatcher.notebook_session
  (orchestration: summarize_run, preview_image, scan_object_sizes,
  export_patches_of_run, no widgets) and cellpatcher.notebook_ui /
  notebook_form (ui: the pages, with preprocessing's notebook_style).
  The preview is the file-run code on one image, so it gives the patches
  the export gives (tested); the export is the tree run, combined table.
- LabConstrictor portability: "# @title" first on every code cell, Colab
  code (Drive mount, custom widget manager, zarr extra) only inside
  if "google.colab" in sys.modules:, pip via subprocess, no magics and no
  /content outside the guard, one RELEASE_TAG (v0.2.0rc1) for the GitHub
  install (no GITHUB_TOKEN: the repository is public), current_version and
  notebook_name with the notebook_latest_versions.yaml entry, Colab and
  JupyterLab callouts, data and outputs on Drive.
- Refusals (unrecorded_files, a changed file, a missing design) are shown
  with their code, files and action; the step stops there.
- Version 0.2.0rc1 (setup.py, __version__, the notebook).
- file_runs._read_mask is now public read_run_mask (the object scan reads
  masks through the run as the patching does).

Tests: test_notebook_file.py (portability rules, pin, version index,
buttons named in the text, the cells run, and a headless nbclient run in
a local kernel), test_notebook_session.py, test_notebook_ui.py. The UI
tests skip without the notebook extra.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
- construct.yaml (LabConstrictor installer): its extra_files lacked every
  module added since CP-1 (file_runs, run_open, run_reading, run_session,
  run_delivery, run_config_file) and the new notebook modules, so the
  installed app could not import cellpatcher. Regenerated with
  .tools/python/bump_constructor.py, as the release workflow does;
  tests/test_installers.py fails a stale list (it fails on main).
  Its version line stays for the release workflow (bump_version.py reads
  X.Y.Z there); the installer installs setup.py, which pins
  preprocessing v0.4.0rc2 and is version 0.2.0rc1.
- The test extra adds nbclient, nbformat and ipykernel; CI adds a
  test,zarr,notebook job so the notebook's tests run there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
- README: files are read through the preprocessing run; the notebook's
  four steps; the pinned release install (no GITHUB_TOKEN); tools/check.py.
- quick_start: a file-run example through common.preprocessing_run.
- normalization.md: the workflow and Python example no longer declare
  image_axes for a tree run (refused since CP-2a); the v0.2 notebook's
  Normalization card; unrecorded_files and zarr_extra_missing messages.
- configuration_reference: in-memory image_axes must put Y before X.
- normalization_contract: the rc2 pin. plan.md: v0.2.0 status and the
  CP-1..CP-3 milestone; mask_source marked removed.
- developer_notes and AGENTS.md: tools/check.py and the code standards,
  the notebook's structure and portability rules, the release checklist,
  tools/ in the layout, today's test counts.
- CHANGELOG (0.2.0rc1): the notebook, the image refusal, the installers,
  the code standards, and migration notes for MorphoRelate
  (check_image_axes, read_patch_table versions), MorphoEmbed
  (PatchTorchDataset paths) and fiberfeatures (patch_config.json
  mask_source/mask_label_name).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
@guijacquemet
guijacquemet marked this pull request as ready for review November 2, 2026 10:14
scan_cell_patch_size and scan_cell_objects took mask_axes='XY' on a square
image and reported the transposed mask's sizes (bbox_height its width). They
now refuse X-before-Y image and mask axes as run_patching does (design v0.4
§6), and CellSegmentationStrategy refuses X-before-Y mask axes when built.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The shared noqa ratchet counts only C901, PLR0913, PLR0915 and ANN, so a new
"# noqa: F401" hid a new Ruff finding and check.py stayed green. Ruff now runs
with --ignore-noqa: every finding goes through the shrink-only baseline. The
two findings already suppressed (test_code_rules E402, as in preprocessing;
test_pipeline_strategies F401, on main) are recorded; the three unused E402
noqa comments of test_notebook_ui are removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Owner decision (2026-11-02): rc releases are pip/Colab only. bump_version.py,
which the release workflow runs first, refuses a pre-release version with
that reason before it changes any file, so no installer is built; a test
checks it (the .tools folder is synced from the LabConstrictor template).
The developer notes say so, and record that the installer's package layout
(src/cellpatcher/cellpatcher/, which setup.py does not find) must be fixed
before the final v0.2.0 installers.

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

docs/plan.md and the CHANGELOG record the owner decisions of 2026-11-02: the
other two notebooks and the dropped per-group parameters and normalization
histograms come in CP-3b before the v0.2.0rc1 tag; the notebook will embed the
preprocessing steps through preprocessing's embedding API only after v0.4.0
is final. Step 1 of the notebook now says plainly to run the preprocessing
notebook or command line first (tested). The CHANGELOG no longer says the
complete module list made the installed app importable.

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

The test compared each preview patch with its exported twin, but not that the
export has no other patch of the image, nor a normalized run. It now checks
both (image-scope normalization: the preview's arrays are the exported files).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
An in-memory image or mask declared with X before Y was accepted by the
dataset and refused only when an item was loaded, inside a DataLoader worker.
It is refused at construction now, as a file path already is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
RunInputsError is a ValueError, so a file changed after step 1 (refused by
RunInputs.read_plane or read_mask during the preview or export) was shown
under "Please change the settings". It is now shown as a preprocessing run
that cannot be used, with the brick's message.

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

The notebook's relative link to docs/README.md does not open on Colab or from
the installed app; it points to the repository's docs now.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
@guijacquemet
guijacquemet merged commit 3b42093 into main Nov 2, 2026
4 checks passed

Copy link
Copy Markdown
Contributor Author

Independent review: merged as 3b42093 (merge commit; branch kept)

Findings fixed on the branch

  1. a58a5fb: the object scan accepted X-before-Y axes. scan_cell_patch_size and scan_cell_objects took mask_axes='XY' on a square mask and reported the transposed sizes: an object 7 high and 3 wide came out as bbox_height 3 and bbox_width 7. Both now refuse X-before-Y image and mask axes. CellSegmentationStrategy(mask_axes=…) refuses them too.
  2. ac3606b: PatchTorchDataset refused X-before-Y axes too late. The refusal came only when an item was loaded, inside a DataLoader worker. It now comes when the dataset is built. Tested with CPU torch.
  3. f26c471: a # noqa comment could hide a new Ruff finding.
    • A new # noqa: F401 hid a new Ruff finding, and check.py --rules stayed green (shown with a mutation). The shared ratchet only counts C901, PLR0913, PLR0915 and ANN.
    • Ruff now runs with --ignore-noqa, so no comment can silence a finding past the baseline.
    • The 2 findings that were already suppressed are now in the baseline. 3 unused noqa comments are removed.
  4. 5cc1c52: no installer for release candidates (owner decision 4).
    • bump_version.py refuses a pre-release version with a clear message, before it changes anything. A test checks this, including after a template sync.
    • Documented in docs/developer_notes.md.
  5. 87d9924: owner decisions recorded.
    • The CP-3b follow-ups and the embedded-preprocessing plan are in docs/plan.md and the CHANGELOG ("Not yet").
    • Step 1 of the notebook now says plainly to run the preprocessing notebook or CLI first (tested).
  6. 9f68c59: the preview-equals-export test was one-way. It now checks set equality of the image's patches, and also a normalized (image-scope) run, comparing pixels with the exported files.
  7. bb51001: wrong error card. A RunInputsError raised while reading (for example, a file changed after Step 1) was shown as "Please change the settings". It is now shown as a refused run.
  8. e45b823: smaller fixes.
    • The CHANGELOG now covers these fixes.
    • The notebook's docs link is absolute, because the relative link breaks on Colab.
    • The CHANGELOG no longer claims that the module list made the installed app importable (see the installer finding below).

Verified

  • tools/code_rules.py is the shared copy. Its SHA-256 cc04a420… matches preprocessing main (6711b48) and v0.4.0rc2.
  • The baseline can only shrink. Proved by mutation; tools/check.py --rules exits 1 in each case:
    • a new finding → new violation;
    • pipeline.py grown by 2 lines → grew from 1029 to 1031;
    • an added # noqa: C901 → noqa: C901 grew from 0 to 1;
    • a blanket noqa;
    • after the fix, a # noqa: F401.
  • The rc2 refusals reach the user.
    • Every except around RunInputs.open and the read_* calls re-raises with a code: unrecorded_files, zarr_extra_missing or preprocessing_run_refused.
    • The notebook's guarded stops the step and shows the card.
    • Nothing is caught and continued.
  • No in-memory transposition anywhere. move_axes is not called internally. normalization._channel_planes only moves C.
  • The notebook calls only the package and follows the portability guide.
    • It does no reading or computing in its cells.
    • It follows the LabConstrictor guide and is consistent with preprocessing's tests/test_notebook_file.py.
    • RELEASE_TAG v0.2.0rc1 matches the version index and __version__.
  • The headless nbclient run really runs in CI. The notebook job ran 1068 tests with 7 skipped, all of them torch.
  • The migration notes match the other repositories' heads:
    • MorphoRelate ea19bb0: check_image_axes, read_patch_table;
    • MorphoEmbed a8e88df: PatchTorchDataset, CYX/YX;
    • fiberfeatures 362f1ba: the reference patch_config.json with mask_source set to the default tiff_tree.
  • The regression tests fail on old main. Run against main's source: 36 fail. These are all the new X-before-Y cases, 4 of the 6 unrecorded-file tests, the notebook-file tests, and the installer tests.

Gate (Python 3.11, uv venvs, head 706accf; CI green with the same counts)

Environment Passed Skipped
.[test,zarr], check.py (exit 0) 1057 11 (7 torch, 4 notebook extra)
.[test], check.py (exit 0) 1036 32 (21 zarr, 7 torch, 4 notebook extra)
.[test,zarr,notebook], check.py (exit 0) 1068 7 (torch)

With CPU torch: test_torch_dataset.py, test_delivery.py and test_biological_repeat.py gave 57 passed.

§9 figures

  • Files: notebook_ui.py 379 lines, notebook_form.py 307, notebook_session.py 284, tools/check.py 206.
  • Largest values in new code:
    • complexity 5 (check.main);
    • parameters 4 (export_patches_of_run);
    • executable lines 27 (run_open._refusal_issue);
    • statements 20 (CellPatcherNotebook.__init__).
  • Touched pre-existing debt (baselined, not grown):
    • PatchTorchDataset.__init__: 10 parameters, 46 executable lines;
    • scan_cell_objects: 45 executable lines.
  • Ratchet: ratcheted # noqa is 0. ruff --isolated --select C901,PLR0913,PLR0915,ANN,D is clean on the new modules.

For CP-3b (before tagging v0.2.0rc1)

  • The other two notebooks: apply the LabConstrictor treatment to CellPatcher_Pytorch and CellPatcher_Strategy_Examples.
  • The two dropped notebook views: bring back the per-group parameters table and the before/after normalization histograms, computed in the package.
  • Installer layout (pre-existing, must be fixed before the final v0.2.0 installers):
    • LabConstrictor's construct.yaml places the package at src/cellpatcher/cellpatcher/.
    • There, setup.py (find_packages(where="src")) finds no package. I reproduced this: the installed app has no cellpatcher module.
    • The fix needs the template or setup.py.

Not tagged.


Generated by Claude Code

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