allelix 2.2.2__py3-none-any.whl → 2.2.3__py3-none-any.whl
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.
- allelix/annotators/gnomad.py +21 -26
- allelix/parsers/twentythreeandme.py +27 -5
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/METADATA +5 -3
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/RECORD +8 -8
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/WHEEL +0 -0
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/entry_points.txt +0 -0
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/licenses/LICENSE +0 -0
- {allelix-2.2.2.dist-info → allelix-2.2.3.dist-info}/top_level.txt +0 -0
allelix/annotators/gnomad.py
CHANGED
|
@@ -247,34 +247,29 @@ class GnomadAnnotator(Annotator):
|
|
|
247
247
|
return {}
|
|
248
248
|
conn = self._connection()
|
|
249
249
|
result: dict[tuple[str, int], list[tuple[str, str, str]]] = {}
|
|
250
|
-
#
|
|
251
|
-
#
|
|
252
|
-
#
|
|
253
|
-
#
|
|
254
|
-
#
|
|
255
|
-
#
|
|
256
|
-
#
|
|
257
|
-
#
|
|
258
|
-
#
|
|
259
|
-
# ``
|
|
260
|
-
# serves the lookup directly. ``_BULK_BATCH_SIZE`` here
|
|
261
|
-
# refers to (chrom, pos) PAIRS not single ints, so each
|
|
262
|
-
# chunk binds 2 * batch_size parameters.
|
|
250
|
+
# Issue a single combined SQL statement per chunk using SQLite's
|
|
251
|
+
# row-value ``(chrom, pos) IN ((?, ?), ...)`` form instead of
|
|
252
|
+
# grouping by chromosome and issuing one statement per
|
|
253
|
+
# (chrom, chunk) pair. On WGS input each batch touches all ~24
|
|
254
|
+
# chromosomes; the per-chrom shape was a 24x query multiplier
|
|
255
|
+
# the ``idx_gnomad_position`` index could not amortize away. The
|
|
256
|
+
# row-value IN form keeps the same carrier-rule contract — both
|
|
257
|
+
# ``chrom`` and ``pos`` must match the input pair simultaneously
|
|
258
|
+
# — and the ``idx_gnomad_position`` covering index on
|
|
259
|
+
# ``(chrom, pos)`` serves the lookup directly.
|
|
263
260
|
#
|
|
264
|
-
#
|
|
265
|
-
#
|
|
266
|
-
#
|
|
267
|
-
#
|
|
268
|
-
#
|
|
269
|
-
#
|
|
270
|
-
#
|
|
271
|
-
#
|
|
272
|
-
|
|
273
|
-
# the runtime ``sqlite3.sqlite_version`` before assuming
|
|
274
|
-
# capacity.
|
|
261
|
+
# Each input pair binds 2 SQLite parameters (chrom + pos), so
|
|
262
|
+
# the chunk size is ``_BULK_BATCH_SIZE // 2`` to stay inside the
|
|
263
|
+
# 999-param convention every other annotator and gnomAD's own
|
|
264
|
+
# multi-param queries respect (``bulk_lookup_by_alt`` does the
|
|
265
|
+
# same 2-param shape with the same ``// 2``;
|
|
266
|
+
# ``bulk_lookup_by_position`` uses ``// 4`` for its 4-param
|
|
267
|
+
# shape, same convention scaled). Net effective batch size:
|
|
268
|
+
# 450 pairs x 2 = 900 params per chunk.
|
|
269
|
+
chunk_pairs = _BULK_BATCH_SIZE // 2
|
|
275
270
|
position_list = list(positions)
|
|
276
|
-
for i in range(0, len(position_list),
|
|
277
|
-
batch = position_list[i : i +
|
|
271
|
+
for i in range(0, len(position_list), chunk_pairs):
|
|
272
|
+
batch = position_list[i : i + chunk_pairs]
|
|
278
273
|
placeholders = ",".join("(?, ?)" for _ in batch)
|
|
279
274
|
params: list[str | int] = []
|
|
280
275
|
for chrom, pos in batch:
|
|
@@ -42,7 +42,26 @@ if TYPE_CHECKING:
|
|
|
42
42
|
|
|
43
43
|
logger = logging.getLogger(__name__)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
# Known canonical first-line banner variants 23andMe wraps raw exports in.
|
|
46
|
+
# The original v2/v3/v4-era exports used the verbatim ``generated by`` form;
|
|
47
|
+
# the June 2026 v5 export prose was edited to ``is generated by`` (with a
|
|
48
|
+
# trailing period in some samples). Match either; future vendor banner
|
|
49
|
+
# edits get a new entry here.
|
|
50
|
+
#
|
|
51
|
+
# Why a tuple of exact prefixes instead of a loose ``"23andMe" in line``
|
|
52
|
+
# substring match: a bare substring check false-positives on transcoded
|
|
53
|
+
# fixtures and third-party tool output. Files that strip the canonical
|
|
54
|
+
# banner entirely (WGSExtract output, Genetic Lifehacks converter output,
|
|
55
|
+
# privacy-conscious users who delete the comment block) are out of scope
|
|
56
|
+
# for this parser by design — they are handled by ``GenericTsvParser`` at
|
|
57
|
+
# the end of the dispatch chain (planned, see GH #146 / GH #127). That
|
|
58
|
+
# two-layer design keeps banner-bearing 23andMe files attributed to
|
|
59
|
+
# "23andMe" and banner-less 23andMe-shape files attributed to "generic-tsv"
|
|
60
|
+
# without guessing a vendor.
|
|
61
|
+
_CANONICAL_PREFIXES: tuple[str, ...] = (
|
|
62
|
+
"# This data file generated by 23andMe",
|
|
63
|
+
"# This data file is generated by 23andMe",
|
|
64
|
+
)
|
|
46
65
|
SNIFF_LINE_LIMIT = 50
|
|
47
66
|
EXPECTED_COLUMNS = 4
|
|
48
67
|
|
|
@@ -58,10 +77,13 @@ class TwentyThreeAndMeParser(GenotypeParser):
|
|
|
58
77
|
def can_parse(self, file_path: Path) -> bool:
|
|
59
78
|
"""Recognize a real 23andMe export by its canonical first-line header.
|
|
60
79
|
|
|
61
|
-
Real exports start with
|
|
80
|
+
Real exports start with one of the variants in ``_CANONICAL_PREFIXES``:
|
|
81
|
+
the historical ``# This data file generated by 23andMe at: ...`` form
|
|
82
|
+
or the June 2026 v5 ``# This data file is generated by 23andMe.`` form.
|
|
62
83
|
Some files have user-prepended comments before the canonical line; the
|
|
63
|
-
|
|
64
|
-
"23andMe" mention without the canonical
|
|
84
|
+
scan loop reads up to ``SNIFF_LINE_LIMIT`` comment lines. A bare
|
|
85
|
+
"23andMe" substring mention without one of the canonical prefixes is
|
|
86
|
+
rejected (see ``_CANONICAL_PREFIXES`` rationale).
|
|
65
87
|
"""
|
|
66
88
|
try:
|
|
67
89
|
with file_path.open("r", encoding="utf-8") as fh:
|
|
@@ -71,7 +93,7 @@ class TwentyThreeAndMeParser(GenotypeParser):
|
|
|
71
93
|
return False
|
|
72
94
|
if not line.startswith("#"):
|
|
73
95
|
return False
|
|
74
|
-
if line.startswith(
|
|
96
|
+
if any(line.startswith(p) for p in _CANONICAL_PREFIXES):
|
|
75
97
|
return True
|
|
76
98
|
except (OSError, UnicodeDecodeError):
|
|
77
99
|
return False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: allelix
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.3
|
|
4
4
|
Summary: Open-source genotype analysis toolkit. Format-agnostic ingestion, database-agnostic annotation, offline-first.
|
|
5
5
|
Author: Allelix
|
|
6
6
|
Maintainer-email: dial481 <dial481@users.noreply.github.com>
|
|
@@ -190,8 +190,10 @@ disease findings. Wherever you write them via `--output <path>`,
|
|
|
190
190
|
that's where they sit until you delete them. Allelix doesn't
|
|
191
191
|
auto-clean and won't warn you when you write to `/tmp/` or any
|
|
192
192
|
other shared location. Treat the files as personal data: read them,
|
|
193
|
-
move them somewhere you control, or delete when you're done.
|
|
194
|
-
|
|
193
|
+
move them somewhere you control, or delete when you're done.
|
|
194
|
+
`allelix db clean` (shipped in v2.2.0) handles the cache side of
|
|
195
|
+
the lifecycle; output reports are still the user's responsibility
|
|
196
|
+
to manage.
|
|
195
197
|
|
|
196
198
|
## Configuration
|
|
197
199
|
|
|
@@ -8,7 +8,7 @@ allelix/annotators/alphamissense.py,sha256=GT5y35jQ97oZW3X9SqJgTcmqYn-GgK2_WbSvl
|
|
|
8
8
|
allelix/annotators/base.py,sha256=emwF6-zs8I7v_m24bC_ocsUeppp2gP9vtGCfMyQQOTo,7994
|
|
9
9
|
allelix/annotators/cadd.py,sha256=BT7JqbHabdEhz9PiQ7nzPJjv25lu3tMDMuoMYQfsUf4,11065
|
|
10
10
|
allelix/annotators/clinvar.py,sha256=VUyDDf3L5VT_MRrTHVXZZKl9Z6RFln3TvRAky9itxv4,35894
|
|
11
|
-
allelix/annotators/gnomad.py,sha256=
|
|
11
|
+
allelix/annotators/gnomad.py,sha256=A4HGEvZT-x-OWxJwXQ8LYs5T3XGYwlwcP7ZAUkRudLI,14725
|
|
12
12
|
allelix/annotators/gwas.py,sha256=ZsZokbb65HDdJON_oMlIprny0LexrHvWDQPNjClxc5M,18786
|
|
13
13
|
allelix/annotators/pharmgkb.py,sha256=1knBbMtDoZd4ZdH3gIeAfr63tZsfMOaOkImrKE3KxHQ,21008
|
|
14
14
|
allelix/annotators/snpedia.py,sha256=WI0eaSKkr4qoQChpayyqkPLGE5XX_l8L4ZWIhu1zDmY,13844
|
|
@@ -48,7 +48,7 @@ allelix/parsers/ftdna_illumina.py,sha256=ZbejAa6vWT8wdwkdpCzsXA7g_1WoltbUEpO2K5t
|
|
|
48
48
|
allelix/parsers/livingdna.py,sha256=18-3Vjc3L7fVR3gHGjrVnPPEqC0Ype2nOb4Ltz1VzRc,5368
|
|
49
49
|
allelix/parsers/myhappygenes.py,sha256=3i8yKMA1WBs6vBPFNkIm7q5hVqNJBu_CZUmlyDMp-QE,4911
|
|
50
50
|
allelix/parsers/myheritage.py,sha256=N6aCdj9SD0tiW8S_yylNlVZy8CrUGazdQvTpr7rT29Y,4311
|
|
51
|
-
allelix/parsers/twentythreeandme.py,sha256=
|
|
51
|
+
allelix/parsers/twentythreeandme.py,sha256=757nA1mw7aEsG4nOdOFbHdKbwIIz0p05oaSzI90x268,6932
|
|
52
52
|
allelix/parsers/vcf.py,sha256=6KhqEyb29pL58ZniaC7zm87QELudEJG_R_VwLZeENNM,28105
|
|
53
53
|
allelix/reports/__init__.py,sha256=9WK8hR03DV1dP2bM7AloJfzSOTVQoFd6AOnaKjQyScs,1408
|
|
54
54
|
allelix/reports/_pipeline.py,sha256=SkT2WqnakB2I60Z-BCox6SIrmQCSFNCK_Na8Kxuggrs,40925
|
|
@@ -61,9 +61,9 @@ allelix/reports/terminal.py,sha256=cPdG3mwUsmty26WIdfbkLtgPF6CTr91ZMk7o2siTumQ,1
|
|
|
61
61
|
allelix/utils/__init__.py,sha256=ALRku0gzoAbTA6gipnMr0aEFYRyI2DUaTB25DHkXXLw,138
|
|
62
62
|
allelix/utils/allele.py,sha256=d7cT1b-XxcD6jID9bLDhvVCOxoK_2Ga4-nXcHRN-h4Q,9620
|
|
63
63
|
allelix/utils/build_detect.py,sha256=Sxlg0OXyL9vDuJAl04pQZQ8oizSVeUV4Gte9tVEvKu0,8718
|
|
64
|
-
allelix-2.2.
|
|
65
|
-
allelix-2.2.
|
|
66
|
-
allelix-2.2.
|
|
67
|
-
allelix-2.2.
|
|
68
|
-
allelix-2.2.
|
|
69
|
-
allelix-2.2.
|
|
64
|
+
allelix-2.2.3.dist-info/licenses/LICENSE,sha256=QWRhgdtPnw-Xay85rhILM_cxYofYh91NfTOWwI_AOQI,34841
|
|
65
|
+
allelix-2.2.3.dist-info/METADATA,sha256=9KMuC0LRIevmywag657PaoUeuCCOU3tMbPEyTohkh10,31800
|
|
66
|
+
allelix-2.2.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
67
|
+
allelix-2.2.3.dist-info/entry_points.txt,sha256=n75_TahJixgNPt1Xhk2V1wDR3RNCiKq4xAKa4_skYNI,45
|
|
68
|
+
allelix-2.2.3.dist-info/top_level.txt,sha256=2SoebaRt4WWVq8Ynk-5uNN1ATE_dJtOqsgj39oCHVbk,8
|
|
69
|
+
allelix-2.2.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|