This release is a pre-release and may not be stable for production use.
SniffCell — 5hmC-compatible branch
SniffCell links somatic structural variants (SVs) and tandem-repeat (TR) expansions/contractions to the cell type they occurred in, using long-read DNA methylation. It calls cell-type-specific differentially methylated regions (ctDMRs) from a reference methylation atlas, discovers SVs and TRs directly from long-read BAMs, extracts read-level methylation, and assigns each variant's supporting reads to the cell population whose methylation profile they match.
This branch supports separate 5mC and 5hmC atlas signals for cell-type deconvolution.
Which Package Should I Use?
Use sniffcell when you are discovering variants from a BAM (no existing
callset yet):
- ctDMR discovery from an atlas (
find) - cell-type deconvolution and BAM splitting (
deconv) - cell-type-aware SV, tandem-repeat, and SNV discovery (
discover) - methylation-based annotation of the discovered variants (
anno,svanno) - visualization, IGV screenshots, differential methylation tests, and HTML reports
Use sniffcell-lite when you already have a variant callset with each
variant's supporting reads identified (e.g. from Sniffles/kanpig or another
caller) and just want fast ctDMR-based cell-type annotation, without running
the full deconvolution/discovery pipeline:
sniffcell-lite findsniffcell-lite anno
sniffcell-lite is published as a separate PyPI package and does not replace
the full sniffcell package:
pip install sniffcell-lite
sniffcell-lite --help
The lite package is maintained in the separate
Fu-Yilei/SniffCell-lite
repository.
Install SniffCell
5hmC alpha: v0.9.8a1. Install the prerelease explicitly:
pip install 'sniffcell==0.9.8a1'
See the release notes and the benchmark blog, bar plots, and implementation details. The blog evaluates a three-donor atlas with bcontrol1 held out; the downloadable atlas uses all four donors. This is an early-testing release.
To install the branch directly instead:
pip install "git+https://github.com/Fu-Yilei/SniffCell.git@5hmC_compatitible_atlas"
For the full external-tool environment:
micromamba env create -f environment.yml
micromamba activate sniffcell
pip install "git+https://github.com/Fu-Yilei/SniffCell.git@5hmC_compatitible_atlas"
Maintainers can follow the prerelease procedure. Only release tags trigger package publication.
Methylation Atlases
Download the processed methylation atlas inputs and precomputed cell-type-specific
differentially methylated regions (ctDMRs) from
Zenodo. For the legacy NumPy find interface, place
all_celltypes_blocks.npy, all_celltypes_blocks.index.gz,
index_to_major_celltypes.json, and all_celltypes.txt in the atlas/ directory.
Precomputed ctDMR tables are available for brain/cerebellum, PBMC, lung, liver,
pancreas, kidney, breast, and colon, and can be supplied directly to deconv
or anno with -b instead of running find.
To discuss tissue-specific atlases, additional tissues or cell types, or custom atlas support, please open a GitHub issue or email us.
Underlying 5hmC data: Raw 5hmC inputs used in the paper remain subject to access restrictions. The derived four-donor scoring catalog is available in the 5hmC atlas directory. For access inquiries and guidance on achieving better performance with the 5hmC-compatible workflow, please email us.
The held-out benchmark and implementation update reports precision and recall on identical FANS reads.
Example Workflows
SniffCell: discover and annotate SVs/TRs from a BAM
- Call ctDMRs from an atlas:
sniffcell find \
--mdb combined_loyfer_ont.mmdb \
--assay dual \
-cf atlas/celltypes.json \
-ck brain_cereb_ont \
-o brain_dual_ctdmr.tsv \
--diff_threshold 0.40
--assay dual calls separate 5mC and 5hmC views and records the assay in the
modification column; it does not collapse the two signals. The older
--npy/--index/--meta interface remains available as a legacy compatibility
path.
See the custom MDB atlas Wiki tutorial for the complete bedMethyl-to-ctDMR workflow. Use an atlas with separate 5mC and 5hmC assays and matching cell-type metadata; replace the example MDB and metadata paths with your own inputs. See the access note above for the 5hmC signal used in the paper.
- Split the BAM into cell-type groups using those ctDMRs:
sniffcell deconv \
-i sample.bam \
-r ref.fa \
-b brain_dual_ctdmr.tsv \
-o deconv_out \
--bam-modification auto \
--split_bam_groups "Neuron=Neuron;Oligodendrocyte=Oligodendrocyte" \
-t 8
With --bam-modification auto (the default), each ctDMR uses the channel named
in its modification column: BAM C+m calls for 5mC, C+h calls for
5hmC, and both for legacy modifiedC rows. Use an explicit 5mC, 5hmC,
or modifiedC value only to override every catalog row for a control analysis.
Catalogs without a modification column retain the previous combined-modified-C
behavior.
- Discover SVs and tandem repeats from the two cell-type-split BAMs:
sniffcell discover tools run \
--deconv-dir deconv_out \
--reference ref.fa \
--tr-bed tr_catalog.bed \
--sex female \
--run-id run1 \
--threads 8
This runs Sniffles/Kanpig/Truvari (SVs), TRGT or Medaka (tandem repeats), and
optionally Clair3 (SNVs) on the two split BAMs, then harmonizes everything
into deconv_out/deconv_requested_group_splits/discover/run1/harmonized_variants.tsv.
Tool binaries are resolved from PATH by default, or pass explicit
--sniffles-bin/--trgt-bin/etc. flags; run sniffcell discover tools check
to preflight-check dependencies first.
- Annotate the discovered SVs/TRs with cell-type methylation evidence:
sniffcell anno \
-i sample.bam \
-v deconv_out/deconv_requested_group_splits/discover/run1/harmonized_variants.tsv \
-r ref.fa \
-b brain_dual_ctdmr.tsv \
-o anno_out \
-t 8
- Build an HTML review report:
sniffcell report --anno_output anno_out
Open anno_out/report/index.html to review high-confidence calls and figures.
SniffCell Lite: annotate an existing callset
If you already have a variant and know its supporting read names, skip deconvolution and discovery entirely:
sniffcell-lite find -ck "Colon, Ascending" -o colon_ascending.ctdmr.tsv
sniffcell-lite anno \
-i sample.bam \
-r ref.fa \
--variant-name variant_001 \
--variant-location chr1:100000-101000 \
--supporting-reads readA,readB,readC \
--catalog colon_ascending.ctdmr.tsv \
-o anno_out
sniffcell-lite anno also supports a --batch variants.tsv mode for
annotating many variants at once. See the
SniffCell Lite README
for details.
Main Commands
| Command | Purpose |
|---|---|
sniffcell find |
Call ctDMRs from a methylation atlas |
sniffcell anno |
Extract BAM methylation and assign SVs/TRs to cell types |
sniffcell svanno |
Re-score SVs from a saved read-classification table |
sniffcell deconv |
Classify all reads and optionally split BAMs by group |
sniffcell discover |
Run cell-type-aware SV / TR / SNV discovery |
sniffcell viz |
Render per-SV methylation figures |
sniffcell igvviz |
Generate IGV batch screenshots |
sniffcell report |
Filter calls and build an HTML review report |
sniffcell dmsv |
Test methylation differences around SVs |
Inputs
| Input | Format | Used by |
|---|---|---|
| Long-read alignment | BAM with MM / ML modification tags |
anno, deconv, discover, dmsv, viz |
| Variants | VCF / VCF.GZ, harmonized TSV from discover, or a variant + supporting-read names (sniffcell-lite) |
anno, dmsv, viz, report |
| Reference genome | FASTA plus index | anno, deconv, discover, dmsv, viz |
| ctDMR table | TSV from sniffcell find |
anno, deconv, viz |
| Methylation atlas | MDB atlas with separate assay views, or legacy NumPy matrix, CpG index, and metadata | find |
Outputs
A find -> deconv -> discover -> anno -> report run produces:
brain_dual_ctdmr.tsv
deconv_out/
deconv_summary.tsv
deconv_reads_classification.tsv
deconv_requested_group_splits/
<group>.bam
discover/run1/
harmonized_variants.tsv
run_summary.json
anno_out/
reads_classification.tsv
blocks_classification.tsv
sv_assignment.tsv
sv_assignment_readable.tsv
sv_assignment_readable_long.tsv
anno_run_manifest.json
report/
index.html
high_confidence_sv.tsv
figures/
A sniffcell-lite find -> anno run produces:
colon_ascending.ctdmr.tsv
colon_ascending.ctdmr.tsv.igv.bed
anno_out/
variant_assignment.tsv
variant_assignment_readable.tsv
reads_classification.tsv
anno_compact_manifest.json
Discovery VCF exports
sniffcell discover tools run automatically exports matching caller records
beside harmonized_variants.tsv, when the corresponding source VCFs exist:
harmonized_variants.sv.vcf.gz
harmonized_variants.tr.<group>.vcf.gz
harmonized_variants.snv.<group>.vcf.gz
Each VCF is coordinate-sorted, BGZF-compressed, and tabix-indexed. SV records come from the joint Sniffles/Truvari/Kanpig postprocessing VCF; TR records come from each group's TRGT VCF; SNV records come from each group's Clair3 pileup VCF used for comparison. Original caller alleles, genotypes, quality, and filters are retained. These are subsets, not copies of the full callsets.
Additional INFO fields describe the SniffCell evidence:
| INFO field | Meaning |
|---|---|
SC_ID, SC_ROW |
Harmonized variant ID and one-based data-row number |
SC_CLASS, SC_SUBTYPE |
Variant class and change subtype |
SC_CATEGORY |
group_a_only, group_b_only, shared, or unknown |
SC_GROUP_A, SC_GROUP_B |
Actual comparison-group labels |
SC_TARGET_GROUP |
Group carrying the candidate change; absent for shared/unknown calls |
SC_SUPPORT_A, SC_SUPPORT_B |
Support counts from the harmonized TSV |
SC_CHANGE_BP |
SniffCell change size; for TRs, a between-group difference |
String values are percent-encoded so composite cell-type labels remain intact.
These annotations identify split-BAM group-specific candidates, not
methylation-confirmed assignments from anno. Zero support does not establish
reference genotype or coverage. For TRs, annotations describe a locus-level
change, not necessarily a particular TRGT ALT allele; SC_CHANGE_BP is not
reference-relative SVLEN. Multiple harmonized changes at one locus yield
separate annotated copies, distinguished by SC_ROW.
Missing source records are not reconstructed. Export paths, counts, and
unmatched data-row numbers are recorded in harmonized_variants_manifest.json,
with warnings for missing matches. Medaka-only TR runs currently have no TRGT
VCF export. An opposite-group SNV record may be absent even when the target
group has a matching call. These VCFs preserve caller genotypes rather than
inferring somatic genotypes; they are not somatic truth sets.
Documentation
For command-line options, run sniffcell --help or
sniffcell <command> --help (for example, sniffcell anno --help).
Full documentation is in the GitHub Wiki:
| Page | Contents |
|---|---|
| Installation | PyPI, conda, Docker, and tool setup |
| SniffCell Lite | Annotating an existing callset with sniffcell-lite |
| Find Workflow | ctDMR discovery parameters |
| Methods | Technical methods for core commands |
| CLI Reference | Command-line options |
| Test Examples | Validation and QA examples |
| SH3RF3 dual SV/TR example | Native-GRCh38 regional BAM example from atlas through report |
Citation
If you use SniffCell in your research, please cite:
Cell-type-resolved somatic variant discovery from bulk long-read sequencing Yilei Fu et al. medRxiv preprint (2026). DOI: 10.64898/2026.09.01.26361966.
License
Apache License 2.0. See LICENSE for details.
Metadata
Release files for sniffcell 0.9.8a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sniffcell-0.9.8a1.tar.gz | 240.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sniffcell-0.9.8a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 448.5 kB
Release files / sniffcell-0.9.8a1.tar.gz
| Download URL | sniffcell-0.9.8a1.tar.gz |
|---|---|
| Size | 240.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8b1a298e62db08cacbe322794b4756c9bc14a6ebabae31fd63578d7de47792cb
|
|
BLAKE2b-256 checksum How to use checksums |
4b1a4e9a374a0fac6f8225c7c46526f1ea3547aeb8705221cbbb8714840a6be7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency logRelease files / sniffcell-0.9.8a1-py3-none-any.whl
| Download URL | sniffcell-0.9.8a1-py3-none-any.whl |
|---|---|
| Size | 207.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2091f7e04d03d9f64b1696668bb9a9be4ba5ad8d6668a89c18ddcdc75fbf6c00
|
|
BLAKE2b-256 checksum How to use checksums |
862ba8500f87dbf6799b0f66b5c00ec6035ad5e404a9d9e9b16ff8af8f92cda3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 10, 2026.
Transparency log