Repository navigation
CP-3b: the other two notebooks, the normalization views, the installer layout - #72
Merged
Merged
Conversation
This repository's copy of LabConstrictor's bump_constructor.py, synced before the template fixed it (a76be61), makes construct.yaml copy the package to CellPatcher/src/cellpatcher/cellpatcher/, where find_packages(where="src") found no package: the installed app had no cellpatcher module (CP-3 review). setup.py now reads the package from src/cellpatcher/ when it is laid out so, and from src/ otherwise (the current template's layout). No template file is changed. tests/test_installers.py copies setup.py and the package as construct.yaml lists them, and as the current template maps them, pip-installs each and imports cellpatcher. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…n views The v0.2 notebook lost the old notebook's "Show parameters per group" table and its before/after normalization histograms (owner decision of 2026-11-02: they come back, computed in the package). - notebook_session.group_parameters_of_run opens and checks the run as an export does and returns normalization.group_parameters (the brick's fit) with the settings' normalization warnings, which the table shows rather than drops. - preview_image, with normalization, also patches the image without it and gives the first patches both ways (Preview.before_after). - normalization_review (pure) pairs them by patch_id and bins each shown plane with the normalization brick's compute_plane_histogram; nothing is re-implemented. - notebook_ui: a "Show parameters per group" button in the Normalization card (a group that cannot be normalized in red) and the before/after figure in the preview. - A missing file a table names (FileNotFoundError) is a settings card, not a traceback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…trictor)
Both installed main with a GITHUB_TOKEN secret, worked on synthetic in-memory arrays and
computed in their cells (galleries, pytest from a clone, parity checks). They get the
main notebook's treatment (CP-3b, owner decision of 2026-11-02):
- One Step 0 for every notebook (the main one's, generalised): its name, EXTRAS and
INTERFACE ("module:class") differ; Drive, the widget manager and the zarr extra only
under the Colab guard; no magics, no /content outside it; the install pinned to
RELEASE_TAG v0.2.0rc1; current_version 0.2.0rc1 and notebook_name as in
notebook_latest_versions.yaml; Colab and JupyterLab callouts, data on Drive.
- Strategy examples (cellpatcher.notebook_examples): the main notebook's step 1 (the
preprocessing run, read through RunInputs), then one page per strategy whose button
previews the chosen image with it: the main notebook's preview, nothing written.
- PyTorch (cellpatcher.notebook_torch, torch_session.load_exported_batch): the main
notebook's export read with ExportedPatchTorchDataset, with the arrays' axes from
patches.csv (output_axes), every channel and value as exported (channel_policy keep,
scale_policy none); patches of different sizes are refused, never resized.
- The main notebook names the new button and view.
tests/test_notebook_file.py checks every notebook (portability, pin, versions, the shared
Step 0, cells that only call the package) and runs each in a kernel over IPC (a TCP port
can be taken by another process between its choice and its use): the examples and the
PyTorch notebook with a test run or export filled in, the PyTorch notebook only with
torch installed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
README, notebooks of the three kinds; docs/normalization.md, the two views; docs/developer_notes.md, the shared Step 0 and the installer layout (the template sync is an owner decision); docs/plan.md, CP-3b done; CHANGELOG, a CP-3b section. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…alization) With the same settings the CellPatcher notebook's preview shows the examples' patches; the patch normalization scope can leave some out. Drop a test constant no test uses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
nbclient shuts down only kernels of the managers it creates; with the IPC manager the tests give it, each kernel lived until pytest exited (CI terminated one as an orphan). 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 2, 2026 11:34
…ivisor PatchTensorConfig(scale_policy='auto'), the default, divides an integer patch by its dtype maximum. Its DeprecationWarning was raised inside the library, where Python's default filters hide it, so ExportedPatchTorchDataset and PatchTorchDataset rescaled without a word. It is now a ScalePolicyDeprecationWarning (still a DeprecationWarning) shown under the default filters, and each item records scale_divisor. The default is unchanged (contract §15: an owner decision). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The batch was cast to float32 without a check, so an int32/uint32 value above 2^24 or a float64 value would have been rounded. The patches are read in their exported type and converted only when float32 holds every value; otherwise refused. The exported type is recorded and shown. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…patch_id Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
test_installers pip-installs both installer layouts and failed in a venv without pip (uv's). The IPC sockets of the kernel tests move out of pytest's tmp_path, whose path can exceed macOS's 104-byte socket path limit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
The template-sync PR before the final v0.2.0 (re-applying the CI rules job, the extras matrix and the rc refusal, proposed upstream) with a CPU-torch CI job; until then the PyTorch notebook's kernel run and the torch tests are skipped in CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
…o keep the type 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
Contributor
Author
Independent review: merged as
|
| Environment | Passed | Skipped |
|---|---|---|
.[test] |
1075 | 41 |
.[test,zarr] |
1096 | 20 |
.[test,zarr,notebook] |
1124 | 11 |
.[test,zarr,notebook] + CPU torch 2.15.0 |
1173 | 0 |
CI gave the same counts, green on 5ce56fd and 5f890f3. The torch tests and the PyTorch notebook kernel run are skipped in CI and were run locally only.
§9 figures:
- Largest file touched:
notebook_ui.py, 452 lines. - Largest function by executable lines:
torch_dataset.patch_array_to_tensor, 41 (existing). Among new functions,load_exported_batch, 37. - Highest complexity: 10 in
patch_array_to_tensor. Among new functions, 7 inbefore_after. - Most statements: 23, in
load_exported_batch. - Most parameters: 6, in
before_after. - Ratchet: the baseline is unchanged and the
# noqacount is 17 on both main and the branch.
Owner question (does not block rc1): should PatchTensorConfig require an explicit scale_policy (or default to "none"), and should repeat_to_rgb stop being the default? Either change breaks the API and needs a CHANGELOG note.
Not tagged.
Generated by Claude Code
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.
CP-3b of the CellPatcher v0.2.0 plan: the follow-ups of PR #71 that the owner decided on 2026-11-02 (design v0.4 §6 and §9 on MorphoFeature
claude/restart-doc). It is based onmainate24243f, which is3b42093plus the bot's CHANGELOG commit. This PR does not tag.v0.2.0rc1is tagged after it.Commits
1641c2eInstaller layout:setup.pynow also installs the package from the layout the installer uses. A test installs both layouts and importscellpatcher.9a15590Normalization views: the "Show parameters per group" table and the before/after normalization views come back. They are computed in the package and shown by the notebook.bf78173Two notebooks rewritten:CellPatcher_Strategy_ExamplesandCellPatcher_Pytorchare rewritten for v0.2 with the LabConstrictor treatment. All three notebooks now share one Step 0, and the tests run each notebook in a kernel.432dae6Docs and CHANGELOG.b876242Wording in the examples notebook, and an unused test constant removed.3e15ba3The kernel tests shut down their kernels. nbclient shuts down only the kernels of managers it creates, so each kernel lived until pytest exited (measured locally). The notebook job of the first CI run ended by terminating an orphan python process; the run on3e15ba3has none.2a48e08Torch adapters' default rescaling was silent (library, pre-existing): see "Review findings".42c9b3ePyTorch notebook's batch: float32 only when exact; the exported type recorded and shown.8c90c45The before/after figure no longer cuts apatch_idat/for its title.01a0e7dTests:pipin the test extra; kernel IPC sockets in a short temporary folder.821470aDocs: the owner decisions of the review (template-sync PR with a CPU-torch CI job before the finalv0.2.0).5ce56fdPyTorch notebook text on the dtype.5f890f3AGENTS.md health snapshot.1. The other two notebooks
What is the same in all three notebooks. Step 0 is the main notebook's cell, made general, and a test checks that the three are identical. Only four things differ: the title,
notebook_name,EXTRASandINTERFACE("module:class"). Every notebook has:# @title Run to …as the first line of every code cell, with hidden code;if "google.colab" in sys.modules:;/contentoutside that guard;git+install, pinned toRELEASE_TAG = "v0.2.0rc1", with noGITHUB_TOKEN,userdata,git cloneor unpinnedmain;current_version = "0.2.0rc1", andnotebook_nameequal to the file name, matchingnotebook_latest_versions.yaml(it was0.0.4/0.0.5, with free-text names);Strategy examples (
cellpatcher.notebook_examples.StrategyExamplesNotebook):RunInputs, and the user chooses an Example image.preview_image. It therefore shows the patches that the export gives with the same settings (tested), and it writes nothing.PyTorch (
cellpatcher.notebook_torch.TorchNotebookandcellpatcher.torch_session.load_exported_batch):pytestand parity checks in its cells.ExportedPatchTorchDatasetand shows the first batch: its shape, dtype, value range and images.output_axes, not the defaultaxes="YX", which fails onCYXpatches.channel_policy="keep", dtype_policy="keep", scale_policy="none". The defaultrepeat_to_rgbrefuses 2 channels. The defaultscale_policy="auto"divides integer patches by their dtype's maximum (deprecated).TorchBatch.exported_dtype) and shown (review fix).output_axesare refused, never guessed.2. The normalization views in the main notebook
Show parameters per group (step 2, the Normalization card):
notebook_session.group_parameters_of_runopens and checks the run as an export does. It then calls the existingnormalization.group_parameters, which uses the brick'sfit.NormalizationWarnings are shown with the table, not dropped. Other warnings are passed on unchanged.Normalization_Offset/Scaleequals its group's row.Before and after normalization (step 3):
preview_imagepatches the image a second time with normalization off.Preview.before_afterholds the first four patches both ways.cellpatcher.normalization_reviewis a new pure module. It pairs patches bypatch_id, never by order, so a patch that patch-scope normalization dropped is left out.output_axesand never transposes.compute_plane_histogram. Nothing inRESERVED_NAMESis defined here.3. Installer layout
What is wrong.
.tools/python/bump_constructor.pyis a stale copy of the template.src/cellpatcher/x.pytoCellPatcher/src/cellpatcher/cellpatcher/x.py. There,find_packages(where="src")finds nothing, so the installed app has nocellpatcher.a76be61(2026-07-06, "Fix the setup.py bug"). The current template maps toCellPatcher/src/cellpatcher/x.py.bump_constructor.py: it writes this branch'sconstruct.yamlbyte for byte (the 4 new modules are listed).The fix, in CellPatcher only.
setup.pyreads the package fromsrc/cellpatcher/whensrc/cellpatcher/cellpatcher/__init__.pyexists, and fromsrc/otherwise. No.tools/or.github/file is changed.The test.
test_the_installed_app_imports_cellpatcher[construct.yaml|template]:setup.pyand the package as each layout lists them;pip install --target;cellpatcherandcellpatcher.strategies.cellfrom the install.On old
main, theconstruct.yamllayout fails: 0 of its 40 modules are installed.Owner decision (2026-11-02): keep this
setup.pyfix now; the template sync comes in one PR before the finalv0.2.0(see "Owner decisions").Review check: mutating
SOURCE_ROOTto"src"fails theconstruct.yamlcase, and to"src/cellpatcher"fails thetemplatecase. No.tools/or.github/file is changed.Review findings (independent review, 2026-11-02)
2a48e08; library behaviour from before this PR, not the notebook path).PatchTensorConfig(scale_policy="auto"), the default, divides an integer patch by its dtype maximum. ItsDeprecationWarningwas raised insidecellpatcher.torch_dataset, where Python's default filters hide it:ExportedPatchTorchDataset(csv)[0]of a uint16 patch of 1000 gave 0.0153 (and 3 repeated channels) with no message (measured in a subprocess). Docs said "it warns when it rescales". Fix: the warning is now aScalePolicyDeprecationWarning, still aDeprecationWarningso existing filters andpytest.warnsstill match. It is shown under the default filters, once per place, and names the divisor. Each dataset item recordsscale_divisor(1.0 when the values are not rescaled). The change is additive. The default is unchanged, because contract §15 makes that an owner decision (see "Owner questions").42c9b3e).dtype_policydefaulted to"float32", so an int32/uint32 value above 2^24 or a float64 value would have been rounded silently. Now: the exported type is read, the batch is converted only when exact and refused otherwise, and the type is recorded and shown.8c90c45). The before/after title usedpatch_id.rsplit("/", 1)[-1]. A patch without a label is now numbered.01a0e7d).test_installersrunspython -m pip, and failed in uv venvs (2 failures in every environment).pipis now in the test extra.01a0e7d). IPC sockets were under pytest'stmp_path, which can exceed macOS's 104-byte socket path limit. They now go in a shortmkdtempfolder that is removed afterwards.Verified with no change needed:
output_axes, and mixed axes are refused. Patches of different sizes are refused.normalization_review: it pairs bypatch_idwithout parsing, never transposes, and bins with the brick'scompute_plane_histogram;RESERVED_NAMESpasses.group_parameters_of_run: it callsnormalization.group_parameters.NormalizationWarnings are kept as notes and other warnings are re-emitted. Groups with aproblemare listed in a red card.RELEASE_TAG = "v0.2.0rc1",notebook_latest_versions.yamlagrees, Colab code is guarded, and there are no magics,@param,GITHUB_TOKEN,userdataorgit clone. Cells only call the package.Regression tests (they fail on old main)
The new and changed test files were run against
origin/main(e24243f)src, notebooks andsetup.py, with CPU torch:test_normalization_review,test_notebook_examples,test_torch_sessionandtest_notebook_session;The new torch-session dtype tests also fail on the PR's original head
3e15ba3: 9 of 14.Gate (reviewer, own worktree and uv venvs, Python 3.11, preprocessing
v0.4.0rc2, head5ce56fd;tools/check.py --rulesexit 0 in every environment, fulltools/check.pyexit 0 with torch).[test].[test,zarr].[test,zarr,notebook].[test,zarr,notebook]+ CPU torch 2.15.05ce56fdis green with the same counts:test1075/41,test,zarr1096/20,test,zarr,notebook1124/11, and the rules job.test_torch_session, the torch tests and the new default-filters test are skipped in CI. They were run locally only, with the results above. A CPU-torch CI job comes with the template-sync PR (owner decision).tests/test_notebook_file.pywas run 3 times with torch, and passed 39/39 each time in 12.9, 13.2 and 14.0 s. Noipykernel_launcherprocess and nocpk-*socket folder was left.3e15ba3gave the PR's counts, except the 2 pip failures above (1162 + 2 failed with torch).§9 figures (new and changed code, measured by the reviewer)
normalization_review.py156 lines,notebook_examples.py105,notebook_torch.py90,torch_session.py181,notebook_session.py364,notebook_ui.py452,torch_dataset.py425. The largest test file touched istest_notebook_file.py, 377. All are within 600.torch_dataset.patch_array_to_tensor(existing); 7 among the new functions (before_after);patch_array_to_tensor; 37 among the new functions (load_exported_batch);load_exported_batch;before_after.normalization_reviewis pure,notebook_examples/notebook_torchare ui, andtorch_sessionis orchestration.torch_datasetstays io.tools/code_rules_baseline.jsonis unchanged from main, and the# noqacount is 17 on both. No exemption was added.Colab hand-check list (after tagging
v0.2.0rc1, because the notebooks install that tag)Main notebook
CellPatcher.ipynb:cellpatcher[notebook,zarr] @ …@v0.2.0rc1. The card shows 0.2.0rc1.Strategy examples:
cellpatcher[notebook,zarr] @ …@v0.2.0rc1. The card reads "CellPatcher strategy examples are ready", 0.2.0rc1.PyTorch:
cellpatcher[notebook,torch,zarr] @ …@v0.2.0rc1.(8, C, H, W),torch.float32, "exported as uint16 (or float32), converted exactly", and the range. The images are drawn.patches.csvshows a red card.Owner decisions (2026-11-02), recorded in
docs/plan.mdand the CHANGELOG "Not yet"setup.pylayout fix now. Before the finalv0.2.0(not before rc1), one PR syncs the LabConstrictor template. It re-applies CellPatcher's CI rules job, the extras matrix and the rc refusal, and proposes them upstream.Owner questions (none blocks rc1)
PatchTensorConfig()still defaults toscale_policy="auto"(divide integer patches by the dtype maximum) andchannel_policy="repeat_to_rgb"(repeat a grayscale patch to 3 channels). The rescaling is now visible and recorded, but a user who leaves the defaults still gets rescaled values. Requiring an explicitscale_policy(or defaulting to"none"), and possiblychannel_policy, is a breaking change: contract §15 needs your approval and a CHANGELOG breaking note. Should it go inv0.2.0final, or later?https://claude.ai/code/session_01G3qp9AxjpGPw9xfWAUJNqc
Generated by Claude Code