PGx: ClinPGx variant-based genes (PGX-008) and --guideline dpwg (PGX-025)
- fetch_sources.sh downloads ClinPGx clinicalVariants (CC BY-SA 4.0); pgx db build adds genotype-only variant-based genes (levels 1A-2B, level 3 for the parity list), rsIDs resolved from the manifest's probes: 70 genes in the DB. - pgx phenotype --guideline dpwg: CPIC mappings for CPIC genes (as ClinPGx curates DPWG), no phenotype for DPWG-only genes (flags dpwg_via_cpic_mapping / dpwg_mapping_not_available). K-029 updated. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01814GKVzZVL3FuF3DeiZXhv
This commit is contained in:
1 parent
4176ef33de
commit
aee8caa39e
8 files changed
+161
-10
No files matched your search
@@ -17,6 +17,11 @@ from simurg.core.log import Reporter
|
||||
from simurg.pgx.phenotype import build_table, gene_phenotype
|
||||
|
||||
JSON_SCHEMA = "simurg.pgx/1"
|
||||
# PGX-025 DPWG gene coverage. ClinPGx curates DPWG guidelines with the CPIC allele-function and phenotype mappings for
|
||||
# genes CPIC covers [DOC: ClinPGx, "Genotype-phenotype mapping for curation of DPWG guidelines"], so those genes use the
|
||||
# CPIC tables (flag dpwg_via_cpic_mapping); DPWG-only genes have no public machine-readable mapping here.
|
||||
DPWG_GENES = ("CYP1A2", "CYP2B6", "CYP2C19", "CYP2C9", "CYP2D6", "CYP3A4", "CYP3A5", "DPYD", "NUDT15", "SLCO1B1",
|
||||
"TPMT", "UGT1A1", "VKORC1", "F5") # fmt: skip
|
||||
TSV_SCHEMA = "simurg.pgx_tsv/1"
|
||||
|
||||
|
||||
@@ -65,9 +70,8 @@ def run_phenotype(o: PhenoOptions, rep: Reporter) -> int:
|
||||
"""``simurg pgx phenotype`` (CLI-034)."""
|
||||
from simurg.core.atomic import atomic_write_text
|
||||
|
||||
if o.guideline != "cpic":
|
||||
raise SimurgError("E_PGX_GUIDELINE", f"guideline {o.guideline!r} is not in this PGx DB (CPIC only)",
|
||||
hint="DPWG tables are not built yet (K-029)") # fmt: skip
|
||||
if o.guideline not in ("cpic", "dpwg"):
|
||||
raise SimurgError("E_PGX_GUIDELINE", f"unknown guideline {o.guideline!r}", hint="cpic or dpwg")
|
||||
src = o.calls / "pgx_calls.json"
|
||||
if not src.exists():
|
||||
raise SimurgError("E_NO_INPUT", f"{src} not found", hint="run pgx star-allele call first")
|
||||
@@ -77,9 +81,11 @@ def run_phenotype(o: PhenoOptions, rep: Reporter) -> int:
|
||||
meta = db_meta(o.db)
|
||||
con = sqlite3.connect(o.db)
|
||||
tables = {}
|
||||
for (gene,) in con.execute("SELECT DISTINCT gene FROM phenotypes WHERE guideline = ?", (o.guideline,)):
|
||||
for (gene,) in con.execute("SELECT DISTINCT gene FROM phenotypes WHERE guideline = 'cpic'"):
|
||||
if o.guideline == "dpwg" and gene not in DPWG_GENES:
|
||||
continue
|
||||
rows = con.execute("SELECT lookup_key, activity_score, phenotype FROM phenotypes WHERE gene = ? AND "
|
||||
"guideline = ?", (gene, o.guideline)).fetchall() # fmt: skip
|
||||
"guideline = 'cpic'", (gene,)).fetchall() # fmt: skip
|
||||
alle = con.execute("SELECT allele, function, activity FROM alleles WHERE gene = ?", (gene,)).fetchall()
|
||||
tables[gene] = build_table(gene, rows, alle)
|
||||
tested = {g: [a for (a,) in con.execute("SELECT allele FROM alleles WHERE gene = ? AND defined = 1", (g,))]
|
||||
@@ -104,6 +110,8 @@ def run_phenotype(o: PhenoOptions, rep: Reporter) -> int:
|
||||
elif g.get("call_type") == "copy_number":
|
||||
res, per = None, []
|
||||
flags = list(g.get("flags", [])) + (res.flags if res else [])
|
||||
if o.guideline == "dpwg" and g["gene"] in DPWG_GENES:
|
||||
flags.append("dpwg_via_cpic_mapping" if t is not None else "dpwg_mapping_not_available")
|
||||
top = g["candidates"][0] if g["candidates"] else {}
|
||||
top_alleles = top.get("alleles", [])
|
||||
entry = {"gene": g["gene"], "call_type": g.get("call_type", "star_allele"), "genotype": g["genotype"],
|
||||
|
||||
Reference in new issue
Block a user