vdjtools 2.1.0__tar.gz → 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vdjtools-2.1.0 → vdjtools-2.2.0}/PKG-INFO +22 -13
- {vdjtools-2.1.0 → vdjtools-2.2.0}/README.md +21 -12
- {vdjtools-2.1.0 → vdjtools-2.2.0}/include/vdjtools/model.hpp +7 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/pyproject.toml +1 -1
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/__init__.py +1 -1
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/biomarker/fisher.py +9 -9
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/biomarker/metaclonotype.py +7 -7
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/cli/__init__.py +2 -2
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/features/kmer.py +5 -5
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/features/physchem.py +12 -11
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/io/__init__.py +18 -4
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/io/batch.py +43 -2
- vdjtools-2.2.0/python/vdjtools/io/convert.py +395 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/io/read.py +13 -13
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/io/schema.py +18 -15
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/generate.py +5 -5
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/native.py +43 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/reference.py +95 -4
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/stitch.py +1 -1
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/cluster.py +2 -2
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/fuzzy.py +10 -10
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/metrics.py +4 -4
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/similarity.py +13 -13
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/tcrnet.py +7 -7
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/track.py +2 -2
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/correct.py +7 -7
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/decontaminate.py +3 -3
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/filter.py +7 -7
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/pool.py +13 -13
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/sc/__init__.py +3 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/sc/pair.py +9 -9
- vdjtools-2.2.0/python/vdjtools/sc/pgen.py +90 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/sc/read.py +15 -15
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/spectratype.py +4 -4
- vdjtools-2.2.0/skills/vdjtools/SKILL.md +99 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/src/_bindings.cpp +8 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/src/core.cpp +1 -1
- {vdjtools-2.1.0 → vdjtools-2.2.0}/src/pgen.cpp +39 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/.gitignore +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/CMakeLists.txt +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/LICENSE +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/environment.yml +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/include/vdjtools/core.hpp +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/include/vdjtools/inext.hpp +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/notebooks/model_explorer.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/biomarker/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/cli/__main__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/features/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/io/cohort.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/d2_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/d2_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/dd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/dd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGH/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGK/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/IGL/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRA/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/d2_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/d2_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/dd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/dd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRB/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/d2_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/d2_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/dd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/dd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRD/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/learned/TRG/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGH/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGK/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/IGL/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRA/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRB/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/d_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/d_gene.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/dj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/dj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/genes_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/n_d.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/vd_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRD/vd_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/genes_j.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/genes_v.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/j_5_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/j_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/manifest.json +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/v_3_del.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/v_choice.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/vj_dinucl.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/_bundled/olga/TRG/vj_ins.parquet +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/analyze.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/bundled.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/data.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/dd.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/events.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/infer.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/io.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/model.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/pgen.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/model/schema.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/overlap/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/batch.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/downsample.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/preprocess/join.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/py.typed +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/resources/.gitkeep +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/resources/aa_property_table.txt +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/sc/anndata.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/sc/cluster_eval.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/__init__.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/diversity.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/inext.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/rarefaction.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/python/vdjtools/stats/usage.py +0 -0
- {vdjtools-2.1.0 → vdjtools-2.2.0}/src/inext.cpp +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: vdjtools
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: TCR/BCR repertoire analysis — Pgen/generation/inference, diversity, overlap, biomarkers (Python + C++)
|
|
5
5
|
Keywords: immunology,tcr,bcr,airr,repertoire,pgen,olga,igor,bioinformatics
|
|
6
6
|
Author-Email: Mikhail Shugay <mikhail.shugay@gmail.com>
|
|
@@ -86,10 +86,12 @@ Built on the antigenomics ecosystem:
|
|
|
86
86
|
[vdjmatch](https://github.com/antigenomics/vdjmatch) (overlap + TCRnet),
|
|
87
87
|
[arda](https://github.com/antigenomics/arda) (AIRR annotation + markup repair).
|
|
88
88
|
|
|
89
|
-
> **Status: v2.
|
|
90
|
-
>
|
|
91
|
-
>
|
|
92
|
-
>
|
|
89
|
+
> **Status: `v2.2.0`** — the native V(D)J model engine plus the full analytics suite (diversity,
|
|
90
|
+
> overlap/TCRnet, preprocessing, biomarkers, single-cell), CDR features, and legacy-format ingestion
|
|
91
|
+
> (MiXcr, MiGec, immunoSEQ, IMGT/HighV-QUEST, Vidjil, RTCR). Clonotype columns follow the AIRR
|
|
92
|
+
> **junction** convention (`junction_nt` / `junction_aa`). The legacy v1.x tool lives on the
|
|
93
|
+
> [`legacy-1.x`](https://github.com/antigenomics/vdjtools/tree/legacy-1.x) branch and its releases
|
|
94
|
+
> remain available under the repository tags (`v0.0.1` … `1.2.1`).
|
|
93
95
|
|
|
94
96
|
## Install
|
|
95
97
|
|
|
@@ -129,6 +131,7 @@ model = load_bundled("TRB", source="olga") # or source="learned" (fit to rea
|
|
|
129
131
|
native.pgen_nt(model, "TGTGCCAGCAGC...") # nucleotide generation probability (native C++)
|
|
130
132
|
native.pgen_aa(model, "CASSLAPGATNEKLFF") # amino-acid Pgen (codon-marginalised)
|
|
131
133
|
native.pgen_aa(model, "CASSLAPGATNEKLFF", mismatches=1) # + the whole Hamming-1 ball
|
|
134
|
+
native.pgen_aa_batch(model, seqs, mismatches=1, threads=0) # Pgen over many CDR3s, thread-parallel (~11×)
|
|
132
135
|
generate(model, 1000) # sample a repertoire -> polars DataFrame
|
|
133
136
|
```
|
|
134
137
|
|
|
@@ -179,25 +182,31 @@ several times faster, and the built-in models keep the resident set small. Singl
|
|
|
179
182
|
| sequence generation | **~32 000 seq/s** | — |
|
|
180
183
|
|
|
181
184
|
Nucleotide Pgen (via the same transfer-matrix DP as the aa path — an in-frame CDR3 is an aa query with
|
|
182
|
-
one codon fixed per position) is exact vs OLGA across all loci
|
|
183
|
-
|
|
185
|
+
one codon fixed per position) is exact vs OLGA across all loci. Batched Pgen / 1-mismatch over many
|
|
186
|
+
CDR3s parallelises over sequences (`native.pgen_aa_batch`, **~11× on 16 cores**, bitwise-identical to
|
|
187
|
+
the serial result); the EM E-step parallelises over reads (~6.7× on 8 threads); diversity/rarefaction
|
|
188
|
+
run on a native iNEXT kernel (bootstrap + parallel batch). Memory
|
|
184
189
|
stays light — **~63 MB** resident for `import vdjtools` plus one loaded model, **~123 MB** with all
|
|
185
190
|
seven bundled models resident. Reproduce with `appendix/bench_pgen.py` and the `test_*_benchmark.py`
|
|
186
191
|
suites (`RUN_BENCHMARK=1`).
|
|
187
192
|
|
|
188
|
-
## Capabilities (
|
|
193
|
+
## Capabilities (see [ROADMAP.md](ROADMAP.md) and the [API reference](https://docs.isalgo.dev/vdjtools/))
|
|
189
194
|
|
|
195
|
+
- **IO** — canonical clonotype frame on AIRR **junction** columns (`junction_nt` / `junction_aa`);
|
|
196
|
+
readers for native vdjtools, AIRR Rearrangement TSV, and Parquet, plus format-detecting converters
|
|
197
|
+
for MiXcr (v1/2 + v3/4), MiGec, Adaptive immunoSEQ (v1/v2), IMGT/HighV-QUEST, Vidjil, and RTCR
|
|
198
|
+
([`vdjtools.io.convert`](python/vdjtools/io/convert.py)); metadata-driven batch + hive-partitioned cohorts.
|
|
190
199
|
- **Model** — native V(D)J recombination model: generation probability (Pgen — nt, aa,
|
|
191
|
-
1-mismatch, V/J-agnostic), sequence generation, and EM inference, all in a
|
|
192
|
-
core. Supersedes OLGA and IGoR: arda-driven scenario enumeration, polars marginal
|
|
193
|
-
read-parallelised EM, and **tandem-D (D-D)** support. Concordant with OLGA across all 7 loci;
|
|
200
|
+
1-mismatch, V/J-agnostic, **thread-parallel batch**), sequence generation, and EM inference, all in a
|
|
201
|
+
native (pybind11) core. Supersedes OLGA and IGoR: arda-driven scenario enumeration, polars marginal
|
|
202
|
+
tables, read-parallelised EM, and **tandem-D (D-D)** support. Concordant with OLGA across all 7 loci;
|
|
194
203
|
precomputed OLGA + real-data-learned models bundled ([`load_bundled`](python/vdjtools/model/bundled.py)).
|
|
195
204
|
- **Stats** — diversity (Chao1/Shannon/Simpson/…), spectratype, V/J/VJ usage.
|
|
196
205
|
- **Features** — CDR physicochemical profiles, k-mer / V+k-mer summaries.
|
|
197
|
-
- **Overlap** — sample overlap and TCRnet (via vdjmatch/seqtree).
|
|
206
|
+
- **Overlap** — sample overlap and TCRnet (via vdjmatch/seqtree), similarity-aware overlap, clustering.
|
|
198
207
|
- **Preprocess** — downsampling, error-correction, VJ-usage batch-effect correction, pooling/joining.
|
|
199
208
|
- **Biomarker** — incidence-based association (Fisher) vs HLA / condition / chain-pairing; metaclonotypes.
|
|
200
|
-
- **Single-cell** — AIRR Cell / 10x interoperability.
|
|
209
|
+
- **Single-cell** — AIRR Cell / 10x interoperability, chain pairing + QC, and paired α/β Pgen.
|
|
201
210
|
|
|
202
211
|
## License
|
|
203
212
|
|
|
@@ -27,10 +27,12 @@ Built on the antigenomics ecosystem:
|
|
|
27
27
|
[vdjmatch](https://github.com/antigenomics/vdjmatch) (overlap + TCRnet),
|
|
28
28
|
[arda](https://github.com/antigenomics/arda) (AIRR annotation + markup repair).
|
|
29
29
|
|
|
30
|
-
> **Status: v2.
|
|
31
|
-
>
|
|
32
|
-
>
|
|
33
|
-
>
|
|
30
|
+
> **Status: `v2.2.0`** — the native V(D)J model engine plus the full analytics suite (diversity,
|
|
31
|
+
> overlap/TCRnet, preprocessing, biomarkers, single-cell), CDR features, and legacy-format ingestion
|
|
32
|
+
> (MiXcr, MiGec, immunoSEQ, IMGT/HighV-QUEST, Vidjil, RTCR). Clonotype columns follow the AIRR
|
|
33
|
+
> **junction** convention (`junction_nt` / `junction_aa`). The legacy v1.x tool lives on the
|
|
34
|
+
> [`legacy-1.x`](https://github.com/antigenomics/vdjtools/tree/legacy-1.x) branch and its releases
|
|
35
|
+
> remain available under the repository tags (`v0.0.1` … `1.2.1`).
|
|
34
36
|
|
|
35
37
|
## Install
|
|
36
38
|
|
|
@@ -70,6 +72,7 @@ model = load_bundled("TRB", source="olga") # or source="learned" (fit to rea
|
|
|
70
72
|
native.pgen_nt(model, "TGTGCCAGCAGC...") # nucleotide generation probability (native C++)
|
|
71
73
|
native.pgen_aa(model, "CASSLAPGATNEKLFF") # amino-acid Pgen (codon-marginalised)
|
|
72
74
|
native.pgen_aa(model, "CASSLAPGATNEKLFF", mismatches=1) # + the whole Hamming-1 ball
|
|
75
|
+
native.pgen_aa_batch(model, seqs, mismatches=1, threads=0) # Pgen over many CDR3s, thread-parallel (~11×)
|
|
73
76
|
generate(model, 1000) # sample a repertoire -> polars DataFrame
|
|
74
77
|
```
|
|
75
78
|
|
|
@@ -120,25 +123,31 @@ several times faster, and the built-in models keep the resident set small. Singl
|
|
|
120
123
|
| sequence generation | **~32 000 seq/s** | — |
|
|
121
124
|
|
|
122
125
|
Nucleotide Pgen (via the same transfer-matrix DP as the aa path — an in-frame CDR3 is an aa query with
|
|
123
|
-
one codon fixed per position) is exact vs OLGA across all loci
|
|
124
|
-
|
|
126
|
+
one codon fixed per position) is exact vs OLGA across all loci. Batched Pgen / 1-mismatch over many
|
|
127
|
+
CDR3s parallelises over sequences (`native.pgen_aa_batch`, **~11× on 16 cores**, bitwise-identical to
|
|
128
|
+
the serial result); the EM E-step parallelises over reads (~6.7× on 8 threads); diversity/rarefaction
|
|
129
|
+
run on a native iNEXT kernel (bootstrap + parallel batch). Memory
|
|
125
130
|
stays light — **~63 MB** resident for `import vdjtools` plus one loaded model, **~123 MB** with all
|
|
126
131
|
seven bundled models resident. Reproduce with `appendix/bench_pgen.py` and the `test_*_benchmark.py`
|
|
127
132
|
suites (`RUN_BENCHMARK=1`).
|
|
128
133
|
|
|
129
|
-
## Capabilities (
|
|
134
|
+
## Capabilities (see [ROADMAP.md](ROADMAP.md) and the [API reference](https://docs.isalgo.dev/vdjtools/))
|
|
130
135
|
|
|
136
|
+
- **IO** — canonical clonotype frame on AIRR **junction** columns (`junction_nt` / `junction_aa`);
|
|
137
|
+
readers for native vdjtools, AIRR Rearrangement TSV, and Parquet, plus format-detecting converters
|
|
138
|
+
for MiXcr (v1/2 + v3/4), MiGec, Adaptive immunoSEQ (v1/v2), IMGT/HighV-QUEST, Vidjil, and RTCR
|
|
139
|
+
([`vdjtools.io.convert`](python/vdjtools/io/convert.py)); metadata-driven batch + hive-partitioned cohorts.
|
|
131
140
|
- **Model** — native V(D)J recombination model: generation probability (Pgen — nt, aa,
|
|
132
|
-
1-mismatch, V/J-agnostic), sequence generation, and EM inference, all in a
|
|
133
|
-
core. Supersedes OLGA and IGoR: arda-driven scenario enumeration, polars marginal
|
|
134
|
-
read-parallelised EM, and **tandem-D (D-D)** support. Concordant with OLGA across all 7 loci;
|
|
141
|
+
1-mismatch, V/J-agnostic, **thread-parallel batch**), sequence generation, and EM inference, all in a
|
|
142
|
+
native (pybind11) core. Supersedes OLGA and IGoR: arda-driven scenario enumeration, polars marginal
|
|
143
|
+
tables, read-parallelised EM, and **tandem-D (D-D)** support. Concordant with OLGA across all 7 loci;
|
|
135
144
|
precomputed OLGA + real-data-learned models bundled ([`load_bundled`](python/vdjtools/model/bundled.py)).
|
|
136
145
|
- **Stats** — diversity (Chao1/Shannon/Simpson/…), spectratype, V/J/VJ usage.
|
|
137
146
|
- **Features** — CDR physicochemical profiles, k-mer / V+k-mer summaries.
|
|
138
|
-
- **Overlap** — sample overlap and TCRnet (via vdjmatch/seqtree).
|
|
147
|
+
- **Overlap** — sample overlap and TCRnet (via vdjmatch/seqtree), similarity-aware overlap, clustering.
|
|
139
148
|
- **Preprocess** — downsampling, error-correction, VJ-usage batch-effect correction, pooling/joining.
|
|
140
149
|
- **Biomarker** — incidence-based association (Fisher) vs HLA / condition / chain-pairing; metaclonotypes.
|
|
141
|
-
- **Single-cell** — AIRR Cell / 10x interoperability.
|
|
150
|
+
- **Single-cell** — AIRR Cell / 10x interoperability, chain pairing + QC, and paired α/β Pgen.
|
|
142
151
|
|
|
143
152
|
## License
|
|
144
153
|
|
|
@@ -64,6 +64,13 @@ double pgen_aa(const PackedModel& m, const std::string& aa, int v_idx, int j_idx
|
|
|
64
64
|
// via the inclusion-exclusion identity over per-position wildcards. v_idx/j_idx as above.
|
|
65
65
|
double pgen_aa_hamming1(const PackedModel& m, const std::string& aa, int v_idx, int j_idx);
|
|
66
66
|
|
|
67
|
+
// Batch aa Pgen over many sequences, parallelized across sequences (mismatches: 0 = exact,
|
|
68
|
+
// 1 = Hamming-1 ball). Bitwise-identical to the per-sequence calls. Per-sequence v/j indices;
|
|
69
|
+
// empty v_idxs/j_idxs → all -1 (gene-agnostic). nthreads=0 → auto (hw-2).
|
|
70
|
+
std::vector<double> pgen_aa_batch(const PackedModel& m, const std::vector<std::string>& seqs,
|
|
71
|
+
const std::vector<int>& v_idxs, const std::vector<int>& j_idxs,
|
|
72
|
+
int mismatches, int nthreads);
|
|
73
|
+
|
|
67
74
|
// EM soft counts — one accumulator per event realization, laid out like the PackedModel prob
|
|
68
75
|
// arrays so the Python M-step can renormalize them directly.
|
|
69
76
|
struct Counts {
|
|
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vdjtools" # if the PyPI name is taken, fall back to a distinct dist name (cf. arda -> arda-mapper)
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.2.0"
|
|
8
8
|
description = "TCR/BCR repertoire analysis — Pgen/generation/inference, diversity, overlap, biomarkers (Python + C++)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -15,8 +15,8 @@ doi:10.1038/ng.3822). A feature is public if it is present in ``>= min_incidence
|
|
|
15
15
|
|
|
16
16
|
Two axes are exposed as first-class options:
|
|
17
17
|
|
|
18
|
-
- **V/J match requirement** — the ``key`` tuple. ``(
|
|
19
|
-
``(
|
|
18
|
+
- **V/J match requirement** — the ``key`` tuple. ``(junction_aa,)`` matches on CDR3 alone;
|
|
19
|
+
``(junction_aa, v_call)`` also requires the V gene; ``(junction_aa, v_call, j_call)`` (the
|
|
20
20
|
default, Emerson's definition) requires both.
|
|
21
21
|
- **exact vs 1-mismatch CDR3 matching** — ``match``. ``"exact"`` groups on the literal
|
|
22
22
|
key (pure polars, no extra deps). ``"1mm"`` first groups near-variant keys into
|
|
@@ -71,8 +71,8 @@ def fisher_association(
|
|
|
71
71
|
phenotype: One row per subject with ``sample_id`` and the binary ``pheno_col``
|
|
72
72
|
(bool / 0-1); subjects with a null label are dropped from both classes.
|
|
73
73
|
pheno_col: Name of the binary phenotype column in ``phenotype``.
|
|
74
|
-
key: Feature key — a subset of ``(
|
|
75
|
-
``
|
|
74
|
+
key: Feature key — a subset of ``(junction_aa, v_call, j_call)`` (must include
|
|
75
|
+
``junction_aa``). This is the **V/J match requirement**.
|
|
76
76
|
match: ``"exact"`` (literal key) or ``"1mm"`` (group near-variants into
|
|
77
77
|
metaclonotypes first; needs the ``[overlap]`` extra).
|
|
78
78
|
min_incidence: Minimum number of subjects a feature must appear in to be tested.
|
|
@@ -90,7 +90,7 @@ def fisher_association(
|
|
|
90
90
|
Hochberg) and ``direction`` (``"enriched"``/``"depleted"``), sorted by ``p_value``.
|
|
91
91
|
|
|
92
92
|
Raises:
|
|
93
|
-
ValueError: If ``alternative``/``match`` is unrecognised, ``key`` omits ``
|
|
93
|
+
ValueError: If ``alternative``/``match`` is unrecognised, ``key`` omits ``junction_aa``,
|
|
94
94
|
or the phenotype has only one class after dropping unknowns.
|
|
95
95
|
"""
|
|
96
96
|
if alternative not in _ALTERNATIVES:
|
|
@@ -98,8 +98,8 @@ def fisher_association(
|
|
|
98
98
|
if match not in ("exact", "1mm"):
|
|
99
99
|
raise ValueError(f"match must be 'exact' or '1mm'; got {match!r}")
|
|
100
100
|
key = tuple(key)
|
|
101
|
-
if S.
|
|
102
|
-
raise ValueError(f"key must include {S.
|
|
101
|
+
if S.JUNCTION_AA not in key:
|
|
102
|
+
raise ValueError(f"key must include {S.JUNCTION_AA!r}; got {key}")
|
|
103
103
|
|
|
104
104
|
lf = cohort.lazy()
|
|
105
105
|
|
|
@@ -115,9 +115,9 @@ def fisher_association(
|
|
|
115
115
|
raise ValueError("phenotype has only one class after dropping unknown labels")
|
|
116
116
|
|
|
117
117
|
# Feature engineering: productive filter + allele stripping on the key's V/J columns.
|
|
118
|
-
lf = lf.filter(pl.col(S.
|
|
118
|
+
lf = lf.filter(pl.col(S.JUNCTION_AA).is_not_null())
|
|
119
119
|
if productive_only:
|
|
120
|
-
lf = lf.filter(~pl.col(S.
|
|
120
|
+
lf = lf.filter(~pl.col(S.JUNCTION_AA).str.contains(r"[*_]"))
|
|
121
121
|
if strip_allele:
|
|
122
122
|
for c in (S.V_CALL, S.J_CALL):
|
|
123
123
|
if c in key:
|
|
@@ -17,7 +17,7 @@ from __future__ import annotations
|
|
|
17
17
|
|
|
18
18
|
import polars as pl
|
|
19
19
|
|
|
20
|
-
from ..io.schema import
|
|
20
|
+
from ..io.schema import JUNCTION_AA, J_CALL, V_CALL
|
|
21
21
|
|
|
22
22
|
_VDJMATCH_HINT = (
|
|
23
23
|
"vdjmatch is required for vdjtools.biomarker.metaclonotype; install the extra with "
|
|
@@ -39,12 +39,12 @@ def metaclonotypes(clonotypes: pl.DataFrame, *, scope: str = "1,0,0,1",
|
|
|
39
39
|
threads: int = 0) -> pl.DataFrame:
|
|
40
40
|
"""Group unique clonotype keys into metaclonotypes by CDR3 edit-scope neighbourhood.
|
|
41
41
|
|
|
42
|
-
Two keys share a ``meta_id`` iff their ``
|
|
42
|
+
Two keys share a ``meta_id`` iff their ``junction_aa`` are within ``scope`` **and** they
|
|
43
43
|
share a V call (when ``match_v``) and a J call (when ``match_j``). Grouping is
|
|
44
44
|
single-linkage (connected components of the neighbour graph).
|
|
45
45
|
|
|
46
46
|
Args:
|
|
47
|
-
clonotypes: A clonotype frame; must carry ``
|
|
47
|
+
clonotypes: A clonotype frame; must carry ``junction_aa`` and, when the corresponding
|
|
48
48
|
``match_*`` flag is set, ``v_call`` / ``j_call``.
|
|
49
49
|
scope: vdjmatch edit-distance scope ``"subs,ins,dels,total"`` (default one
|
|
50
50
|
substitution, length-preserving). ``"0,0,0,0"`` reduces to exact grouping.
|
|
@@ -53,7 +53,7 @@ def metaclonotypes(clonotypes: pl.DataFrame, *, scope: str = "1,0,0,1",
|
|
|
53
53
|
threads: Worker threads for the native search (``0`` = all cores).
|
|
54
54
|
|
|
55
55
|
Returns:
|
|
56
|
-
The distinct grouping keys (``
|
|
56
|
+
The distinct grouping keys (``junction_aa`` plus ``v_call``/``j_call`` as applicable)
|
|
57
57
|
with an added ``meta_id`` column (compact 0-based integer, singletons included).
|
|
58
58
|
|
|
59
59
|
Raises:
|
|
@@ -67,8 +67,8 @@ def metaclonotypes(clonotypes: pl.DataFrame, *, scope: str = "1,0,0,1",
|
|
|
67
67
|
if match_j and J_CALL in clonotypes.columns:
|
|
68
68
|
group_cols.append(J_CALL)
|
|
69
69
|
|
|
70
|
-
uniq = (clonotypes.select([
|
|
71
|
-
.drop_nulls(
|
|
70
|
+
uniq = (clonotypes.select([JUNCTION_AA, *group_cols])
|
|
71
|
+
.drop_nulls(JUNCTION_AA)
|
|
72
72
|
.unique(maintain_order=True)
|
|
73
73
|
.with_row_index("_gid"))
|
|
74
74
|
n = uniq.height
|
|
@@ -94,7 +94,7 @@ def metaclonotypes(clonotypes: pl.DataFrame, *, scope: str = "1,0,0,1",
|
|
|
94
94
|
# union-find over the returned positional pairs. No partition (CDR3-only) => one pass.
|
|
95
95
|
groups = uniq.group_by(group_cols, maintain_order=True) if group_cols else [((), uniq)]
|
|
96
96
|
for _, sub in groups:
|
|
97
|
-
cdr3s = sub[
|
|
97
|
+
cdr3s = sub[JUNCTION_AA].to_list()
|
|
98
98
|
if len(cdr3s) < 2:
|
|
99
99
|
continue
|
|
100
100
|
gids = sub["_gid"].to_list()
|
|
@@ -26,7 +26,7 @@ app = typer.Typer(
|
|
|
26
26
|
help="vdjtools — TCR/BCR repertoire analysis: Pgen, sequence generation, diversity, overlap.",
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
_SEQ_COLS = ("
|
|
29
|
+
_SEQ_COLS = ("junction_aa", "junction_nt", "cdr3_aa", "cdr3_nt", "cdr3aa", "cdr3nt", "cdr3", "junction")
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
# ---------------------------------------------------------------------------- helpers
|
|
@@ -165,7 +165,7 @@ def generate(
|
|
|
165
165
|
) -> None:
|
|
166
166
|
"""Sample recombined sequences from a model — like ``olga-generate_sequences``.
|
|
167
167
|
|
|
168
|
-
Emits ``
|
|
168
|
+
Emits ``junction_nt, junction_aa, v_call, d_call, d2_call, j_call, productive`` (``d2_call`` is the
|
|
169
169
|
tandem D on the learned D-bearing loci; null otherwise).
|
|
170
170
|
"""
|
|
171
171
|
from vdjtools.model.generate import generate as _generate
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""CDR3 amino-acid k-mer profiles and joint V + k-mer + C feature summaries.
|
|
2
2
|
|
|
3
|
-
K-mers are overlapping sliding windows over ``
|
|
3
|
+
K-mers are overlapping sliding windows over ``junction_aa``. Each k-mer occurrence
|
|
4
4
|
carries its clonotype's weight (reads, unique, or frequency); weights are summed.
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
@@ -9,7 +9,7 @@ import polars as pl
|
|
|
9
9
|
|
|
10
10
|
from ..io.schema import (
|
|
11
11
|
C_CALL,
|
|
12
|
-
|
|
12
|
+
JUNCTION_AA,
|
|
13
13
|
LOCUS,
|
|
14
14
|
V_CALL,
|
|
15
15
|
add_locus,
|
|
@@ -19,17 +19,17 @@ from ..io.schema import (
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def _explode_kmers(df: pl.DataFrame, k: int) -> pl.DataFrame:
|
|
22
|
-
"""Explode each clonotype's ``
|
|
22
|
+
"""Explode each clonotype's ``junction_aa`` into overlapping k-mers (column ``kmer``).
|
|
23
23
|
|
|
24
24
|
Rows whose CDR3 is shorter than ``k`` (or null) contribute no k-mers.
|
|
25
25
|
"""
|
|
26
26
|
if k < 1:
|
|
27
27
|
raise ValueError(f"k must be >= 1; got {k}")
|
|
28
|
-
df = df.with_columns(pl.col(
|
|
28
|
+
df = df.with_columns(pl.col(JUNCTION_AA).str.len_chars().alias("_len"))
|
|
29
29
|
df = df.filter(pl.col("_len") >= k) # shorter/null CDR3s yield no k-mers
|
|
30
30
|
df = df.with_columns(pl.int_ranges(0, pl.col("_len") - k + 1).alias("_pos"))
|
|
31
31
|
df = df.explode("_pos", empty_as_null=True)
|
|
32
|
-
df = df.with_columns(pl.col(
|
|
32
|
+
df = df.with_columns(pl.col(JUNCTION_AA).str.slice(pl.col("_pos"), k).alias("kmer"))
|
|
33
33
|
return df.drop("_len", "_pos")
|
|
34
34
|
|
|
35
35
|
|
|
@@ -4,12 +4,13 @@ For each clonotype the mean of a property over the residues of a chosen CDR3 reg
|
|
|
4
4
|
is computed, then averaged (weighted by reads/frequency, or unweighted) within a
|
|
5
5
|
group (e.g. per V-J pairing, or per locus).
|
|
6
6
|
|
|
7
|
-
Region definitions (over ``
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
Region definitions (over ``junction_aa``, length ``L``):
|
|
8
|
+
|
|
9
|
+
* ``all`` — the entire CDR3.
|
|
10
|
+
* ``trimmed`` — ``junction_aa[3:-3]`` (conserved-anchor-trimmed core); clonotypes with
|
|
11
|
+
``L <= 6`` have an empty core and are skipped for this region.
|
|
12
|
+
* ``center`` — the middle five residues ``junction_aa[L//2-2 : L//2+3]``; clonotypes
|
|
13
|
+
with ``L < 5`` are skipped for this region.
|
|
13
14
|
"""
|
|
14
15
|
from __future__ import annotations
|
|
15
16
|
|
|
@@ -19,7 +20,7 @@ from importlib import resources
|
|
|
19
20
|
|
|
20
21
|
import polars as pl
|
|
21
22
|
|
|
22
|
-
from ..io.schema import
|
|
23
|
+
from ..io.schema import JUNCTION_AA, LOCUS, add_locus, weight_expr
|
|
23
24
|
|
|
24
25
|
#: Default property subset: Kidera-factor-free physicochemistry + the 10 Kidera factors.
|
|
25
26
|
DEFAULT_PROPERTIES = (
|
|
@@ -49,16 +50,16 @@ def load_property_table() -> pl.DataFrame:
|
|
|
49
50
|
|
|
50
51
|
def _region_expr(region: str) -> pl.Expr:
|
|
51
52
|
"""Return the CDR3-region substring expression (null where the region is empty)."""
|
|
52
|
-
length = pl.col(
|
|
53
|
+
length = pl.col(JUNCTION_AA).str.len_chars()
|
|
53
54
|
if region == "all":
|
|
54
|
-
return pl.col(
|
|
55
|
+
return pl.col(JUNCTION_AA)
|
|
55
56
|
if region == "trimmed":
|
|
56
57
|
return (pl.when(length > 6)
|
|
57
|
-
.then(pl.col(
|
|
58
|
+
.then(pl.col(JUNCTION_AA).str.slice(3, length - 6))
|
|
58
59
|
.otherwise(None))
|
|
59
60
|
if region == "center":
|
|
60
61
|
return (pl.when(length >= 5)
|
|
61
|
-
.then(pl.col(
|
|
62
|
+
.then(pl.col(JUNCTION_AA).str.slice(length // 2 - 2, 5))
|
|
62
63
|
.otherwise(None))
|
|
63
64
|
raise ValueError(f"region must be 'all', 'trimmed' or 'center'; got {region!r}")
|
|
64
65
|
|
|
@@ -5,11 +5,19 @@ Readers return the canonical clonotype frame defined in :mod:`vdjtools.io.schema
|
|
|
5
5
|
from . import schema
|
|
6
6
|
from .batch import iter_samples, read, read_metadata, read_samples, sniff_format
|
|
7
7
|
from .cohort import ingest_cohort, scan_cohort
|
|
8
|
+
from .convert import (
|
|
9
|
+
read_imgt,
|
|
10
|
+
read_immunoseq,
|
|
11
|
+
read_migec,
|
|
12
|
+
read_mixcr,
|
|
13
|
+
read_rtcr,
|
|
14
|
+
read_vidjil,
|
|
15
|
+
)
|
|
8
16
|
from .read import read_airr, read_parquet, read_vdjtools
|
|
9
17
|
from .schema import (
|
|
10
18
|
C_CALL,
|
|
11
|
-
|
|
12
|
-
|
|
19
|
+
JUNCTION_AA,
|
|
20
|
+
JUNCTION_NT,
|
|
13
21
|
COLUMNS,
|
|
14
22
|
COUNT,
|
|
15
23
|
D_CALL,
|
|
@@ -30,6 +38,12 @@ __all__ = [
|
|
|
30
38
|
"read_airr",
|
|
31
39
|
"read_vdjtools",
|
|
32
40
|
"read_parquet",
|
|
41
|
+
"read_mixcr",
|
|
42
|
+
"read_migec",
|
|
43
|
+
"read_immunoseq",
|
|
44
|
+
"read_imgt",
|
|
45
|
+
"read_vidjil",
|
|
46
|
+
"read_rtcr",
|
|
33
47
|
"read_metadata",
|
|
34
48
|
"read_samples",
|
|
35
49
|
"iter_samples",
|
|
@@ -46,8 +60,8 @@ __all__ = [
|
|
|
46
60
|
"D_CALL",
|
|
47
61
|
"J_CALL",
|
|
48
62
|
"C_CALL",
|
|
49
|
-
"
|
|
50
|
-
"
|
|
63
|
+
"JUNCTION_AA",
|
|
64
|
+
"JUNCTION_NT",
|
|
51
65
|
"COUNT",
|
|
52
66
|
"FREQ",
|
|
53
67
|
"LOCUS",
|
|
@@ -6,14 +6,23 @@ metadata table into one long clonotype frame (or a per-sample dict).
|
|
|
6
6
|
"""
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
import gzip
|
|
9
10
|
import os
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
|
|
12
13
|
import polars as pl
|
|
13
14
|
|
|
15
|
+
from . import convert
|
|
14
16
|
from .read import read_airr, read_parquet, read_vdjtools
|
|
15
17
|
from .schema import COLUMNS, LOCUS
|
|
16
18
|
|
|
19
|
+
# Legacy third-party formats (vdjtools.io.convert), keyed by the fmt string used below.
|
|
20
|
+
_CONVERTERS = {
|
|
21
|
+
"mixcr": convert.read_mixcr, "migec": convert.read_migec,
|
|
22
|
+
"immunoseq": convert.read_immunoseq, "imgt": convert.read_imgt,
|
|
23
|
+
"vidjil": convert.read_vidjil, "rtcr": convert.read_rtcr,
|
|
24
|
+
}
|
|
25
|
+
|
|
17
26
|
|
|
18
27
|
def _header_columns(path: str | os.PathLike) -> list[str]:
|
|
19
28
|
"""Return the (lower-cased) header column names of a TSV without reading rows."""
|
|
@@ -21,6 +30,15 @@ def _header_columns(path: str | os.PathLike) -> list[str]:
|
|
|
21
30
|
return [c.lower() for c in cols]
|
|
22
31
|
|
|
23
32
|
|
|
33
|
+
def _peek(path: str | os.PathLike, n: int = 8) -> str:
|
|
34
|
+
"""Return the first ``n`` characters (gzip-transparent), for JSON detection."""
|
|
35
|
+
with open(path, "rb") as fb:
|
|
36
|
+
gz = fb.read(2) == b"\x1f\x8b"
|
|
37
|
+
opener = gzip.open if gz else open
|
|
38
|
+
with opener(path, "rt", errors="ignore") as f:
|
|
39
|
+
return f.read(n)
|
|
40
|
+
|
|
41
|
+
|
|
24
42
|
def sniff_format(path: str | os.PathLike) -> str:
|
|
25
43
|
"""Detect a clonotype file's format from its header.
|
|
26
44
|
|
|
@@ -39,10 +57,26 @@ def sniff_format(path: str | os.PathLike) -> str:
|
|
|
39
57
|
"""
|
|
40
58
|
if Path(path).suffix.lower() in (".parquet", ".pq"):
|
|
41
59
|
return "parquet"
|
|
60
|
+
if Path(path).suffix.lower() in (".vidjil", ".json") or _peek(path).lstrip()[:1] == "{":
|
|
61
|
+
return "vidjil" # Vidjil .vidjil JSON
|
|
42
62
|
cols = set(_header_columns(path))
|
|
63
|
+
# Specific third-party formats first (their signature columns don't collide with each other).
|
|
64
|
+
if "v-gene and allele" in cols and "junction" in cols:
|
|
65
|
+
return "imgt"
|
|
66
|
+
if "cdr3 nucleotide sequence" in cols and "v segments" in cols:
|
|
67
|
+
return "migec"
|
|
68
|
+
if "number of reads" in cols and "junction nucleotide sequence" in cols:
|
|
69
|
+
return "rtcr"
|
|
70
|
+
if cols & {"all v hits", "allvhitswithscore"} and \
|
|
71
|
+
cols & {"n. seq. cdr3", "nseqcdr3", "nseqimputedcdr3"}:
|
|
72
|
+
return "mixcr"
|
|
73
|
+
if "count (templates/reads)" in cols or ({"rearrangement", "amino_acid"} <= cols
|
|
74
|
+
and "v_gene" in cols):
|
|
75
|
+
return "immunoseq"
|
|
76
|
+
# Native vdjtools / migmap (cdr3nt/cdr3aa headers) and AIRR Rearrangement.
|
|
43
77
|
if "cdr3aa" in cols or {"count", "cdr3nt"} <= cols:
|
|
44
78
|
return "vdjtools"
|
|
45
|
-
if cols & {"v_call", "junction_aa", "cdr3_aa"}:
|
|
79
|
+
if cols & {"v_call", "junction_aa", "junction_nt", "cdr3_aa"}:
|
|
46
80
|
return "airr"
|
|
47
81
|
raise ValueError(f"unrecognised clonotype format; header columns: {sorted(cols)}")
|
|
48
82
|
|
|
@@ -72,7 +106,14 @@ def read(path: str | os.PathLike, fmt: str = "auto",
|
|
|
72
106
|
return read_airr(path, n_rows=n_rows)
|
|
73
107
|
if fmt == "parquet":
|
|
74
108
|
return read_parquet(path, n_rows=n_rows)
|
|
75
|
-
|
|
109
|
+
if fmt == "vidjil":
|
|
110
|
+
return convert.read_vidjil(path) # whole-JSON reader (no row cap)
|
|
111
|
+
if fmt in _CONVERTERS:
|
|
112
|
+
return _CONVERTERS[fmt](path, n_rows=n_rows)
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"fmt must be 'auto', 'vdjtools', 'airr', 'parquet', or a legacy format "
|
|
115
|
+
f"({', '.join(sorted(_CONVERTERS))}); got {fmt!r}"
|
|
116
|
+
)
|
|
76
117
|
|
|
77
118
|
|
|
78
119
|
def read_metadata(path: str | os.PathLike) -> pl.DataFrame:
|