Repository navigation
Add cau mudata-builder: the two count matrices as one MuData - #14
Merged
Merged
Conversation
The design steps end at guide_metadata.tsv; nothing took a sequenced channel
and produced the object an analysis works in. This assembles one: modalities
gene and guide, a cell index of {barcode}_{measurement_set}, raw counts, and
each feature's annotation in var, laid out like the IGVF pipeline's own
object so the two can be compared field by field.
Assembly only. Nothing is derived from the counts, no cell is dropped, no
guide is called and no pair is proposed. QC and filtering are later steps,
and each is a judgement this one has no business making.
Three decisions worth stating. Cells are the union of the two matrices, not
their intersection, with obsm recording which modality holds each: on a real
channel that is 1,022,982 barcodes against 207,274 seen by both, so an
intersection would discard most of the object before anyone looked at it.
Every gene type is annotated rather than only the coding ones, because the
counts come from a transcriptome built on the whole GTF and two thirds of the
features would otherwise be nameless. And uns['reference'] carries the GTF
and genome by name, md5 and accession, so the object answers "which GENCODE"
without its run record beside it; a build whose store differs from the one
the guide metadata was written against is refused.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The docs page covers what the object holds, why cells are the union, why every gene type is annotated, the two traps that cost real debugging (PAR genes counted twice, and the version rule that must be the store's own), and what uns['reference'] records. The README's annotation line and two module docstrings still said `location` was exon/intron/intergenic, which stopped being true when the axes were split. Docs accuracy is a hard rule here, and these were the last three places that had not caught up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Why
The design steps end at
guide_metadata.tsv. Nothing took a sequencedchannel and produced the object an analysis works in, so that step was a
hand-written script every time.
What it does
Assembles one channel's gene and guide counts into a MuData laid out like the
IGVF CRISPR pipeline's own object, so the two can be compared field by field:
modalities
geneandguide, a cell index of{barcode}_{measurement_set},raw counts untouched, and each feature's annotation in
var.cau mudata-builder run \ --rna counts_unfiltered/adata.h5ad \ --guide counts_unfiltered_modified/adata.h5ad \ --guide-metadata results/igvf/guide_metadata.tsv \ --store gencode.v43.annotation.parquet \ --measurement-set IGVFDS8842PXCC \ --gtf-accession IGVFFI9561BASO \ --outdir results/What it deliberately does not do
No statistics, no QC, no filtering, no doublet calls, no guide assignment, no
pairs to test. Each is a judgement, and a step that makes judgements while
assembling hides them.
Three decisions worth reviewing
Cells are the union, not the intersection, with
obsmrecording whichmodality holds each. On a real channel that is 1,022,982 barcodes against
207,274 seen by both: an intersection would discard four fifths of the object
before anyone looked at it.
Every gene type is annotated, not only protein-coding. The counts come
from a transcriptome built on the whole GTF: 20,066 protein-coding against
42,691 lncRNA, pseudogenes and small RNAs, which would otherwise be nameless.
One GENCODE, checked. A build whose store differs from the one the guide
metadata was written against is refused, so genes and guides cannot describe
different genomes.
uns['reference']then carries the GTF and genome by name,md5 and accession, so the object answers "which GENCODE" without its run
record beside it. Only names are stored, never paths: the object is shared,
and a path carries the filesystem it was built on.
Two traps the tests pin
PAR genes appear twice -- 47 features with a
_PAR_Ysuffix and a chrX twinof identical sequence -- and are carried through untouched rather than summed
or de-duplicated.
kb indexes genes as
ENSG00000290825.1while the store drops the version.The join uses the store's own rule, which strips a trailing
.Nand leaves_PAR_Yalone; splitting on the first dot instead would hand the chrY copythe chrX gene's coordinates with nothing complaining.
Also
anndataandmudatabecome runtime dependencies, imported inside functionslike
pysamsocau --helploads neither. Both lockfiles regenerated.The README and two module docstrings still described
locationasexon/intron/intergenic, which stopped being true in #13. Corrected here.
Verified end to end on channel IGVFDS8842PXCC: 62,757 genes and 43,766 guides,
none unannotated on either side.
🤖 Generated with Claude Code