Conversation
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
timtreis
force-pushed
the
feat/tvn-coral
branch
from
September 20, 2026 21:13
ae38dbe to
fa9cfda
Compare
timtreis
force-pushed
the
feat/jump-lite-embeddings
branch
2 times, most recently
from
September 20, 2026 21:23
844221d to
d44c07b
Compare
timtreis
force-pushed
the
feat/tvn-coral
branch
from
September 20, 2026 21:49
ae04f4f to
a4538bc
Compare
timtreis
force-pushed
the
feat/jump-lite-embeddings
branch
from
September 20, 2026 21:53
751a264 to
5997d44
Compare
timtreis
force-pushed
the
feat/tvn-coral
branch
from
September 20, 2026 23:39
a4538bc to
2af210f
Compare
timtreis
force-pushed
the
feat/jump-lite-embeddings
branch
from
September 21, 2026 00:04
5997d44 to
1e299ca
Compare
Documentation build overview
20 files changed ·
|
timtreis
force-pushed
the
feat/tvn-coral
branch
from
September 21, 2026 00:09
2af210f to
332ee25
Compare
timtreis
force-pushed
the
feat/jump-lite-embeddings
branch
from
September 21, 2026 00:12
1e299ca to
708ec0d
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #102 +/- ##
==========================================
+ Coverage 87.75% 87.79% +0.03%
==========================================
Files 81 81
Lines 6315 6360 +45
==========================================
+ Hits 5542 5584 +42
- Misses 773 776 +3
🚀 New features to boost your workflow:
|
Every other page measures cells with CellProfiler. This one swaps the feature block for a neural network's output on the same wells and says what changes: var carries no compartment or channel, so feature families, feature sets and the blocklist do not apply; normalization is unchanged; and feature selection is skipped, because the dimensions of an embedding are a basis rather than a list of measurements that can be dropped one at a time. It compares all six JUMP-Lite feature sets on target recall and replicate retrieval, keeps the untrained model in the comparison as the control that says whether the pipeline measures anything, and shows the trade between batch alignment and replicate agreement rather than presenting one of them as the default.
The page compared principal components against TVN and left the reader with a UMAP whose sources still separate, having shown no method that fixes it. Harmony does: over the six feature sets it leaves the least batch structure behind and gives the best replicate retrieval, while TVN remains the only one that lifts recall of annotated targets above chance. Neither buys the other's gain, so the page now says that rather than presenting one as the default. Both embeddings are drawn, because the contrast is the lesson. Chasing the detached cluster in the TVN panel found sixteen wells with a median of twelve cells against 252 elsewhere, which no correction fixes and neither readout in the table reports.
The page treated the laboratory as the nuisance to correct. Measured with the same pc_regression, the cell count explains seven to twelve times more of the variance than the source does on every trained embedding, and lands on the first component. The untrained model does not do it and cp_measure does not do it, so this is something the models learned and something averaging per-cell measurements removes — which makes it the sharpest difference between the two kinds of feature, and the reason the alignments moved target recall so little. Whether to act on it is measured rather than assumed. The thin wells are cytotoxic compounds, thin at more than one laboratory independently, so a cell-count floor would delete the largest effects; but two thin wells of different compounds are nearly as alike as replicates of the same one, so what they reproduce is mostly emptiness. Regressing the count out raises target recall under every alignment and takes replicate retrieval apart on two of the three. The page keeps every well and says why: for a compound the cell count is partly a treatment effect, which is why the JUMP recipe regresses it for the genetic arms and not for compounds. Also answers what transfers from scanpy — the count-based filters do not, the reductions do — and drops a private tl._similarity import for mt.tl.similarity.
The cell count dominating a learned embedding was reachable only by reading
tutorial 12 to the end, and it changes how three existing functions should be
used.
pp.regress_out defaults to keys=("Metadata_CellCount",), which is the call
the tutorial argues against for a compound screen, and said nothing about it;
it now records that the JUMP recipe regresses the count out of the genetic
arms and not the compound one, and why.
ds.jump_lite records that every trained set here puts the count on its first
component while the untrained one and cp_measure do not, since that is a
property of the data a reader will meet. tl.cytotoxicity records that the
confound is larger on an embedding than on a CellProfiler profile.
…cells ds.jump_lite went straight through read_profiles, so the CellProfiler name parser ran on names with no structure: openphenom_nahualX_17 became the nahualX feature group of an openphenom object, and scale became the dimension index. The docstring and the tutorial both said the opposite of what the code did. cp_measure is real measurements and keeps its annotation. The tutorial asserted several things no cell computed, and contradicted its own tables in four places. Each claim now sits in the section that measures it: the source variance is reported for every model and alignment where the question is asked, the cell count's place on the first component is shown per component rather than asserted, and the island in the TVN panel is named by clustering instead of from memory. jump_lite_targets drops missing genes before the cast, or every unannotated compound becomes the string 'nan' and they all count as a related pair. The CI cache script downloads the feature sets the tutorial reads, and the registry shape test knows JUMP-Lite publishes one count per well rather than per field.
…he contrast The CellProfiler grammar read cp_measure's `nuclei_3/max/radial_zernikesRadialDistribution_ZernikeMagnitude_9_9` as a group of `0/max/intensityIntensity` with no channel at all, so the one block on the page that was supposed to carry a compartment, a group and a channel carried none of them. Parse that grammar instead; the channel stays the index cp_measure numbers its inputs by, because the stain it stands for is not in the name. Tutorial 12 then rests on measurements rather than assertions. The CellProfiler block gets the standard pycytominer selection plus drop_outliers, without which a handful of unbounded shape moments are most of its variance and every number computed from it is about those moments. The chance level for `metrics.known_relationships` is measured per representation by shuffling the annotation rather than assumed to be 10%, which is what the untrained control's apparently high recall turned out to be. Replicate retrieval is `tl.map` with a cross-laboratory pair rule, which is what the prose already claimed and what scales past a dense similarity matrix. New sections describe the plates before analysing them and put the CellProfiler names back on the embedding's axes by regressing one block on the other. `well_qc` counted one row per well and failed every well on a well-level object, which the page recommended; it now declares the resolution it expects. `feature_select` warns when it selects nothing instead of handing an empty matrix to whatever runs next, which is how noise_removal fails here: its cutoff is an absolute threshold on the scale `normalize` left the values on.
timtreis
force-pushed
the
feat/jump-lite-embeddings
branch
from
September 21, 2026 03:17
f94645a to
1c63b33
Compare
…eady scored parse_feature_names is handed a whole column list, and the grammar is a property of the file that wrote it rather than of any one column, so decide it once over the list instead of probing every name inside _parse_one. A name that does not fit the chosen grammar is then a mixed file rather than something to guess at, and _read_suffixes takes the group rather than a flag derived from it at each call site. In the tutorial, the per-compound panels reuse the mAP the comparison table already computed rather than running the heaviest metric again for six of its eighteen conditions, the cell-count section reads obs off the block already in hand, the bridge branches off the normalized CellProfiler block instead of re-reading it, and the per-component variance table calls metrics.batch_variance_explained rather than stacking pc_regression by hand. Every number is unchanged.
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.
Stacked on #100, with #101 merged in.
ds.jump_litereads JUMP-Lite Target-2: four plates of the JUMP Target-2 plate map, one from each of four laboratories, with the same 1,536 wells measured six ways — five learned embeddings (OpenPhenom, DINOv2, an untrained DINOv2, SubCell, MorphEm) andcp_measure, the CellProfiler-equivalent. Rows and metadata are identical across all six, somodel=changes the feature block and nothing else. CC0, 2.2 to 26 MB per set, pinned by sha256 like every other dataset.ds.jump_lite_targetsreturns the RefChemDB gene annotations in the shapemetrics.known_relationshipsreads.Tutorial 12 is the reason for it. The package had no page on learned embeddings, and nothing in it assumes CellProfiler features, so the page is about what actually differs:
varcarries no compartment or channel, which retires feature families, feature sets and the blocklist; normalization is unchanged; feature selection is skipped, because the dimensions are a basis rather than measurements that can be dropped one at a time.io.stampbrings in a matrix produced elsewhere.The comparison scores three alignments — principal components,
pp.tvnandpp.harmony— on recall of compounds sharing an annotated target and on replicate retrieval across the four laboratories. They disagree: Harmony leaves the least batch structure behind and gives the best replicate retrieval, while TVN is the only one that lifts target recall above the 10% baseline. The page says that rather than presenting either as the default, and draws both embeddings, because the contrast is the lesson.It also keeps the untrained model in the comparison. Its replicate retrieval collapses where the trained models hold, under every alignment, which is the cheapest check that a pipeline measures anything at all.
Chasing the detached cluster in the TVN embedding found sixteen wells with a median of twelve cells against 252 elsewhere — a QC failure no correction fixes and neither readout reports. That is in the page too.
This is also what corrected #100:
cp_measuregains as much from TVN as the learned sets do, so the earlier reading that TVN fails on CellProfiler features was wrong.Verified: 815 tests pass, mypy, ruff and the formatters clean. The notebook executes end to end in the tutorials environment with no errors, and its committed outputs come from that run.