PGx star alleles: pgx star-allele call (PGX-011..021), probe masks vs 1000G, GeT-RM validation (K-029)
- simurg/pgx/star.py: solver-free diplotype enumeration incl. CN forms (deletion, xN), wildcards, array-equivalence classes, raw_score/score with CPIC frequency priors; calibrated error model (spec PGX-012 amended). - pipeline/pgx_star.py: DB gene models, SNV + PGx CN VCF evidence, masks, diplotype_summary.tsv + pgx_calls.json. - scripts/pgx: derive_masks.py (array vs 1000G 30x over HTTPS, GS calibration), getrm_truth.py, validate_star_getrm.py. - GSA v4 PGx demo vs GeT-RM (16 CEPH): 100/109 gene calls; CYP2D6/2C19/2C9 41/45 (docs/validation/V2_pgx_star.md).
This commit is contained in:
1 parent
0c5dd03ca8
commit
feb1d993b5
15 files changed
+1168
-5
No files matched your search
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Extract GeT-RM consensus diplotypes (CDC Genetic Testing Reference Material program, consolidated PGx/HLA table,
|
||||
public) for the individuals of an identity table.
|
||||
|
||||
python scripts/pgx/getrm_truth.py --xlsx Consolidated_PGx-HLA_table_1-22-25-V4.xlsx \
|
||||
--identity scripts/pgx/demo36_identity.tsv --out getrm_truth.tsv
|
||||
Writes ``individual, gene, diplotype`` (the table's text, trimmed) for the star-allele genes.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
GENES = ("CYP2B6", "CYP2C9", "CYP2C19", "CYP2D6", "CYP3A4", "CYP3A5", "CYP4F2", "NAT2", "NUDT15", "SLCO1B1", "TPMT",
|
||||
"UGT1A1", "DPYD", "CYP2A6", "CYP1A2", "CYP2C8", "GSTM1", "GSTT1", "UGT2B17") # fmt: skip
|
||||
|
||||
|
||||
def main() -> int:
|
||||
import openpyxl
|
||||
|
||||
ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
|
||||
ap.add_argument("--xlsx", required=True, type=Path)
|
||||
ap.add_argument("--identity", required=True, type=Path)
|
||||
ap.add_argument("--out", required=True, type=Path)
|
||||
a = ap.parse_args()
|
||||
with a.identity.open() as fh:
|
||||
inds = {r["individual"] for r in csv.DictReader((ln for ln in fh if not ln.startswith("#")), delimiter="\t")}
|
||||
wb = openpyxl.load_workbook(a.xlsx, read_only=True)
|
||||
rows = list(wb[wb.sheetnames[0]].iter_rows(values_only=True))
|
||||
head = [str(h or "").split("\n")[0].strip() for h in rows[1]]
|
||||
col = {g: head.index(g) for g in GENES if g in head}
|
||||
out = []
|
||||
for r in rows[2:]:
|
||||
if not r or not r[1] or str(r[1]).strip() not in inds:
|
||||
continue
|
||||
for g, i in col.items():
|
||||
v = r[i]
|
||||
if v is not None and str(v).strip():
|
||||
out.append((str(r[1]).strip(), g, " ".join(str(v).split())))
|
||||
with a.out.open("w") as fh:
|
||||
fh.write("individual\tgene\tdiplotype\n")
|
||||
for t in sorted(out):
|
||||
fh.write("\t".join(t) + "\n")
|
||||
print(f"{len({t[0] for t in out})} individual(s), {len(out)} gene call(s) -> {a.out}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user