Files
SimurgArray/docs/validation/V2_pgx_star.md
T
kemal 304c69cb94 PGx: full call detail (PGX-016..020, 027/028, 031), pgx coverage (PGX-009/035), full HGVS
- supporting_variants.tsv, unresolved_variants.tsv, variants_not_covered.tsv with PGX-026 metadata; per-allele
  supporting/unresolved sites for both alleles of every candidate; variant_change vs top, distant_alternative,
  unexplained_variants, alleles_impacted_by_no_call, alleles_tested.
- simurg pgx coverage: callable / not_covered / masked / equivalent_to per allele and manifest.
- HGVS on GRCh38 RefSeq accessions (NC_...:g.).
2026-09-29 16:16:39 +01:00

4.5 KiB
Raw Blame History

V2 — PGx DB and star-allele calling (PGX-001 … PGX-021)

Status: implemented for CPIC star-allele genes, interim validation (2026-09-29).

  • scripts/pgx/fetch_sources.sh → CPIC API tables (CC0, data version 2026-08-03).
  • simurg pgx db build → deterministic SQLite: 22 genes, 1354 alleles, 1897 normalised variant rows; GSA v4 PGx probe map 5002 links; two builds byte-identical.
  • simurg pgx star-allele call → diplotype_summary.tsv, pgx_calls.json (11 star-allele genes).
  • simurg pgx phenotype (alias annotate) → per-sample <sample>.pgx.json (simurg.pgx/1) and diplotype_annotations.tsv with # metadata lines (PGX-024 … PGX-028); CPIC activity scores (xN = N × activity, *5/*0 = 0) and function-count lookups; disagreeing feasible solutions → Indeterminate plus per-solution phenotypes. tests/unit/test_pgx_phenotype.py.
  • Unit tests: tests/unit/test_pgx_db.py, tests/unit/test_pgx_star.py.

Data and truth

  • Arrays: the GSA v4 PGx demo (36 arrays = 30 CEPH/1000G individuals, scripts/pgx/demo36_identity.tsv), SNV VCFs and PGx CN VCFs from SimurgArray.
  • Star-allele truth: GeT-RM consolidated PGx/HLA table (CDC, 2025 V4) — 16 of the 30 individuals (scripts/pgx/getrm_truth.py).
  • Probe mask (PGX-010): array vs 1000G 30x (NYGC phased panel, fetched per gene over HTTPS) for the other 14 individuals (scripts/pgx/derive_masks.py), so the mask is independent of the GeT-RM validation set: 8 of 658 assessed records (23 probe names) below 95 % concordance — e.g. CYP2C19 rs367543002 and CYP2D6 rs1135836 called homozygous ALT in every sample, the UGT1A1 C>CATAT TA-repeat probe. Regenerate with the command in the script header (the mask lists vendor probe names and is not committed).

Result (16 individuals; replicate arrays counted once)

Gene Top solution = GeT-RM Truth among array-equivalent feasible solutions
CYP2C9 15/15 15/15
CYP2C19 14/15 15/15
CYP2D6 12/15 14/15
CYP3A5 15/15 15/15
TPMT 15/16 15/16
CYP2B6 12/14 12/14
CYP4F2 8/9 8/9
NAT2 8/9 8/9
NUDT15 1/1 1/1
total 100/109 (91.7 %) 103/109 (94.5 %)

PGX-032 target (≥ 90 % for CYP2D6/CYP2C19/CYP2C9 against truth): 41/45 = 91 % (top solution). Details and every discordant call: V2_pgx_star_getrm16.json.

Not in the total (GeT-RM uses pre-2023 names the CPIC definitions no longer carry): UGT1A1 (GeT-RM *60; 0/9 top) and SLCO1B1 (*1B/*17/*21 vs CPIC *37/*15/*20; 9/15 top).

Remaining discordances: CYP2D6 *3/(*68)+*4 (NA12878; *68 hybrids not modelled, *3 frameshift probe), CYP2D6 *2 vs *1 where the array cannot separate them (prior picks *1), CYP2C19 *8, TPMT *21, CYP2B6 *27, CYP4F2 *2 — rare alleles whose defining variants are absent or masked on this array.

Error model (K-029)

After masking, 0 of 9 740 array calls at DB variants disagreed with 1000G 30x in any GenCall-score bin (0.15–1.0), so the per-call error is 1e-3 (GS ≥ 0.15) and errors are handled by the probe mask. The first model, ε = 0.5·(1 − GS)², let correct low-GS calls lose to the prior (CYP2C9 7/15 → 15/15 after the change).

Caveats

  • 16 individuals, one array type, European (CEPH) only; masks from 14 individuals (spec: ≥ 100 samples).
  • CPIC now defines the GRCh38 reference as its own allele where it differs from *1 (CYP2C19 *38): a sample heterozygous at the *1-defining rs3758581 fits *1/*38 best (raw score 0.98), but *38 has no CPIC frequency, so the prior keeps *1/*1 on top — which is what legacy GeT-RM reports.
  • simurg pgx coverage (PGX-009/035) on GSA v4 PGx with the mask: 438 alleles callable, 68 array-equivalent to another allele, 88 not covered, 4 masked. Against the reference's known limitations: CYP4F2 *2 not covered (reported as *1) and *4 ≡ *3 — as the reference; UGT1A1 *28 callable (its C>CAT probe matches 1000G) and *37 masked (the C>CATAT probe fails); CYP2D6 *40/*58 and NUDT15 *6/*9 are separable here (CPIC core definitions differ from the reference's).
  • Detail outputs (PGX-016 … PGX-020, PGX-027/028, PGX-031): supporting_variants.tsv, unresolved_variants.tsv, variants_not_covered.tsv, per-allele supporting/unresolved sites for both alleles of every candidate, variant_change vs the top solution (distant_alternative above 3 changes), unexplained_variants, full HGVS on GRCh38 RefSeq accessions.
  • Not yet: named-haplotype (G6PD), variant-based and tagging genes; CYP2D6 hybrids (*13, *36, *68); PharmVar-only genes (CYP2A6, CYP3A4, CYP1A2, …); DPWG tables.