Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
5743410
Added initial IEDB annotation module
pramodsshinde Aug 14, 2026
04bdfb9
Added initial IEDB annotation module
pramodsshinde Aug 14, 2026
fa6d36c
Added annotation readme
pramodsshinde Aug 14, 2026
4e86aa9
Add empty placeholder files for CoV-AbDab and ASD
pramodsshinde Aug 14, 2026
2391e2c
Renamed annotations to specificity
pramodsshinde Aug 14, 2026
4282f63
Added specificity functions
pramodsshinde Sep 13, 2026
c23a139
Added specificity functions along side tests
pramodsshinde Sep 13, 2026
9068ca9
Added def, fuzzy functions and revised tests
pramodsshinde Sep 13, 2026
fd81806
Revised readme
pramodsshinde Sep 13, 2026
cf62f85
Merge origin/dev: move specificity databases under immvoke
pramodsshinde Oct 9, 2026
1617bbc
Make symscan the default annotate backend
pramodsshinde Oct 9, 2026
e0b7c7f
Run Specificity's tests in CI and fix its import order
pramodsshinde Oct 9, 2026
ce519f1
Leave CompAIRR out of annotate's docs and help
pramodsshinde Oct 9, 2026
629690b
Raise the pyarrow floor to 16
pramodsshinde Oct 9, 2026
98a24e9
Prefer IEDB's calculated V/D/J-gene calls over curated ones
pramodsshinde Oct 14, 2026
c05d09c
Rework annotate around a single annotateSpecificity() entry point
pramodsshinde Oct 14, 2026
2cdd615
Split Specificity docs into usage (README) and design (idea.md)
pramodsshinde Oct 14, 2026
ca5bb43
Download IEDB's own AIRR export for bcr instead of converting
pramodsshinde Oct 14, 2026
e65684b
Match through symscan only, with X, blank and gene-call rules
pramodsshinde Oct 14, 2026
27566cc
Drop the unused rapidfuzz dependency
pramodsshinde Oct 14, 2026
bd14034
Keep human receptors only from IEDB
pramodsshinde Oct 14, 2026
e519fc0
Compare V/J-gene calls at gene level only
pramodsshinde Oct 14, 2026
f7c246a
Rename CDR3 to CDR3H, keep IEDB's locus as is, table the workflow
pramodsshinde Oct 14, 2026
160348c
Add annotation output bundle, scored pairs, one folder per database
pramodsshinde Oct 23, 2026
d212c36
Bring docs and comments in line with the output bundle and layout
pramodsshinde Oct 23, 2026
dccf4dd
Fix numpy options, blank cell_ids and a pandas 4 break in annotate
pramodsshinde Oct 23, 2026
92dbeb8
Score every gated pair, name outputs by database, rows by sequence_id
pramodsshinde Oct 23, 2026
4d6ff54
Drop IEDB's raw mirror after download, write a readable AIRR validati…
pramodsshinde Oct 28, 2026
538029e
Remove the `specificity bcr` shortcut in favour of `iedb download bcr`
pramodsshinde Oct 28, 2026
1715f9d
Add --air_species to IEDB bcr/tcr, keep every species by default
pramodsshinde Oct 28, 2026
780380e
Add --outcome to IEDB bcr/tcr, replacing --qualitative_measure on bcell
pramodsshinde Oct 28, 2026
0b31a08
Spell specificity download's own flags with underscores
pramodsshinde Oct 28, 2026
11110f4
Add --antigen_species to IEDB bcr/tcr, resolved live against IEDB
pramodsshinde Oct 28, 2026
4c8a48d
Name specificity outputs <db>_<table>.tsv, e.g. iedb/iedb_bcr.tsv
pramodsshinde Oct 28, 2026
19f2c22
Drop IEDB's bcell and bcr_to_bcell tables, keep bcr and tcr only
pramodsshinde Oct 28, 2026
de8626c
Hash specificity rows a column at a time, fixing the slow tcr download
pramodsshinde Oct 28, 2026
f08e0bc
Make specificity search count what a table holds; group and describe …
pramodsshinde Oct 28, 2026
10b3ddb
Add each IEDB record's antigen and its source species at download
pramodsshinde Oct 28, 2026
413f87f
Report only each query's best hits, with antigen info; add --full-dis…
pramodsshinde Oct 29, 2026
ab1ae27
Add --antigen_structure_type to IEDB bcr/tcr, and its column
pramodsshinde Oct 29, 2026
c59e57e
Make specificity download say when it starts and finishes, with stats
pramodsshinde Oct 29, 2026
b03adc7
Leave out chains with no species recorded when --air_species is given
pramodsshinde Oct 29, 2026
8960c27
Let 'specificity <db> search|download all' take the filters its table…
pramodsshinde Oct 29, 2026
0140825
Add --assay_type, --disease and --paired_only to IEDB bcr/tcr
pramodsshinde Oct 29, 2026
6690dbd
Let 'immvoke schema' work on the specificity databases
pramodsshinde Oct 29, 2026
5c0edf6
Leave query rows with no hit out of the annotation table
pramodsshinde Oct 29, 2026
f365d38
Remove a full matrix an earlier run left when this one wants none
pramodsshinde Oct 29, 2026
4d666df
Say what an annotation is comparing while it runs
pramodsshinde Oct 29, 2026
635921f
Search one gene group at a time instead of gating afterwards
pramodsshinde Oct 30, 2026
f4b5354
Report every compared pair in the full matrix, not only the hits
pramodsshinde Oct 30, 2026
9ca0928
Write the annotation long, one row per hit, with a summary beside it
pramodsshinde Oct 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ jobs:
- name: Install package
run: pip install .
- name: Unit tests
run: python -m unittest discover -v
# Specificity keeps its tests beside its source (see pyproject.toml),
# where discovery from the top level does not reach.
run: |
python -m unittest discover -v
python -m unittest discover -v -s src/immvoke/Sources/Specificity/tests -t src

python-versions:
runs-on: ubuntu-latest
Expand All @@ -46,7 +50,11 @@ jobs:
python -m pip install --upgrade pip
pip install .
- name: Unit tests
run: python -m unittest discover -v
# Specificity keeps its tests beside its source (see pyproject.toml),
# where discovery from the top level does not reach.
run: |
python -m unittest discover -v
python -m unittest discover -v -s src/immvoke/Sources/Specificity/tests -t src

# Proves that the packaged schema snapshots and the runtime dependencies both
# ship in the wheel. Running from /tmp guarantees the source tree cannot be
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ jobs:
python -m pip install --upgrade pip build twine
pip install .
- name: Unit tests
run: python -m unittest discover -v
# Specificity keeps its tests beside its source (see pyproject.toml),
# where discovery from the top level does not reach.
run: |
python -m unittest discover -v
python -m unittest discover -v -s src/immvoke/Sources/Specificity/tests -t src
- name: Build sdist and wheel
run: python -m build
- name: Check distribution metadata
Expand Down
82 changes: 82 additions & 0 deletions NEWS.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,88 @@
Release Notes
================================================================================

Unreleased
-------------------------------------------------------------------------------

Specificity:

+ Added specificity databases IEDB_, CoV-AbDab_ and ASD_ under
``immvoke specificity <db> search|download``. IEDB's BCR and TCR tables
are downloaded as schema-validated AIRR rearrangement TSVs with one record
per chain, linked by ``cell_id``, taking IEDB's calculated (IMGT
standardized) V/D/J-gene calls over the curated ones, every receptor
species kept unless ``--air_species`` names one (e.g. ``--air_species
"Homo sapiens"``; a species includes its strains, and a chain with no
species recorded is left out), and every assay
outcome unless ``--outcome`` names one (``Positive`` or ``Negative``).
IEDB's B-cell assay tables (``bcell``, ``bcr_to_bcell``) are not
offered: each receptor record already carries its epitope, assay ids and
outcome.
``--antigen_species`` keeps receptors whose epitope comes from an antigen
organism, by any name IEDB uses, ignoring case (``--antigen_species
"Influenza A virus"`` takes in every flu strain); it asks IEDB's API for
the organisms of the table's epitopes when the table is downloaded.
+ ``immvoke specificity <db> search <table>`` counts what the table holds
once its filters are applied (rows, receptor groups, epitopes and the most
common loci, receptor, antigen species and structure types and outcomes,
``--top`` of each), instead of
printing the download URL; ``--out`` writes every count as a TSV. Its and
download's filters are grouped in ``--help``, each saying what it filters
on, and ``--limit`` is left only on ``download all``, the one place it
had an effect.
+ IEDB's bcr and tcr tables gain ``iedb_antigen``,
``iedb_antigen_source_species`` and ``iedb_antigen_structure_type``, each
record's epitope's antigen, its source species and the epitope's
structure type, looked up on IEDB's API at download time.
+ ``--antigen_structure_type`` keeps receptors whose epitope has that IEDB
structure type: ``Linear peptide``, ``Discontinuous peptide`` (which
includes ``Discontinuous peptide on multi chain``) or ``Non-peptidic``
(haptens, glycans, lipids...), IEDB's own Epitope Structure choice.
+ IEDB's bcr and tcr take ``--assay_type`` (e.g. ``neutralization``) and
``--disease`` (e.g. ``COVID-19``; a disease includes those under it),
looked up on IEDB's assay API only when given, and ``--paired_only``,
keeping receptors with both chains of a pair.
+ IEDB's bulk ZIP is cached in ``~/.cache/immvoke/iedb/`` for a day, shared
by search and download, so ``bcr`` then ``tcr`` fetch it once.
+ Filter flags generated from a source's schema are spelled with
underscores, as the field is (``--air_species``), and so are
``immvoke specificity ... download``'s own flags (``--dry_run``,
``--no_resume``, ``--strict_airr``).
+ Each specificity download lands in its database's own folder,
``<outdir>/<db>/``: the normalized ``<db>_<table>.tsv`` (e.g.
``iedb/iedb_bcr.tsv``) and its own ``download_metadata.yml``; IEDB's
``raw/`` (the bulk ZIP and what was taken from it) is deleted once the
tables are written.
+ Added ``immvoke annotate``, to annotate a query AIRR table against a
reference one (e.g. IEDB's BCR table) through symscan_: the heavy chain
CDR3, full VDJ or pooled CDR1-3 (``--sequence-region``), within the same
V/J-gene (``--partition-by``), exact or at an identity threshold
(``--identity-threshold``) under Hamming or Levenshtein distance
(``--distance-metric``), or heavy+light chain of the same antibody
(``--paired``, one chain of each kind per cell picked by
``--count-field``).
+ ``immvoke annotate --outdir`` writes ``annotation.tsv`` and
``annotation_metadata.yml`` (the options, inputs, reference database and
counts of the run), each named after the reference's database and table,
e.g. ``iedb_bcr_annotation.tsv``. The annotation keeps each query's best
hits, the highest identity (all of them on a tie): ``sequence_id``,
``identity``, ``hit_id`` and that hit's ``antigen``, ``epitope`` and
``antigen_source_species`` -- long rather than wide, one row per (query
row, matching reference row), since no separator is safe in IEDB's own
epitope names. A summary of the run in prose is written beside it as
``annotation_summary.txt``.
``--full-dist-matrix`` also writes ``annotation_full_matrix.txt``:
every pair the filters admit and how close it is (``sequence_id``,
``hit_id``, ``identity``). ``--identity-threshold`` does not apply to it
-- it answers how close a query is to everything it was compared with,
not what it matched -- but ``--partition-by`` does, and under ``hamming``
only equal-length sequences have a distance at all.

.. _IEDB: https://www.iedb.org/
.. _CoV-AbDab: https://opig.stats.ox.ac.uk/webapps/covabdab/
.. _ASD: https://naturalantibody.com/agab/
.. _symscan: https://github.com/yutanagano/symscan

Version 0.1.0: 2026.09.28
-------------------------------------------------------------------------------

Expand Down
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ dependencies = [
"pandas>=2.2.3",
"airr>=2.0",
"tqdm>=4.64",
# ASD's data unit is a Delta Lake of Parquet partitions, staged in a
# Google Drive folder: pyarrow reads the partitions, gdown fetches the
# folder, since it has no plain HTTP download. The floor is 16 for the
# same reason as the pandas floor above: pyarrow wheels before 16 were
# built against numpy 1.x and fail to import under numpy>=2.
"pyarrow>=16",
"gdown>=5.0",
# Symscan.py: annotate's matching engine for exact, Hamming and
# Levenshtein matching (a Rust symmetric-deletion index; numpy, which it
# returns its pairs in, comes with it and with pandas).
"symscan>=0.8",
]

[project.optional-dependencies]
Expand All @@ -56,6 +67,11 @@ path = "src/immvoke/Version.py"
# automatically as part of the package. Do not add a force-include for them: it
# duplicates every file and the build fails.
packages = ["src/immvoke"]
# Specificity's own tests live alongside its source
# (Sources/Specificity/tests/) rather than under the top level tests/
# directory; exclude them here so a built wheel still ships no test code,
# matching every other source under src/immvoke.
exclude = ["src/immvoke/Sources/Specificity/tests/*"]

[tool.ruff]
line-length = 90
Expand Down
3 changes: 3 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@ PyYAML>=6.0
pandas>=2.2.3
airr>=2.0
tqdm>=4.64
pyarrow>=16
gdown>=5.0
symscan>=0.8
Loading
Loading