noise-outlier exclusion + robustness test (PCN-017/EDGE-026), platform from the CSV manifest (CLI-032) Also: star-allele calls are checked for one manifest/build per run (PGX-011), duplications at the CN cap are named xN (PGX-022), and tandem names attach supporting variants to their full copy. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01814GKVzZVL3FuF3DeiZXhv
62 lines
3.7 KiB
Markdown
62 lines
3.7 KiB
Markdown
# V2 — Targeted PGx copy number (PCN-001 … PCN-017)
|
||
|
||
Status: **implemented, interim validation** (2026-09-29). `simurg pgx copy-number train|call` (CLI-031/032), model
|
||
file `.simurg-pgxcn` (IN-050), region BED v1 built from UCSC ncbiRefSeq (`scripts/pgx/build_cn_regions.py`,
|
||
packaged as `simurg/pgx/data/pgx_cn_regions.GRCh38.v1.bed`), per-sample `*.pgx_cn.vcf.gz` + `.tbi`,
|
||
`pgx_cn_batch_summary.tsv`, `pgx_cn_sample_summary.tsv`. Unit tests: `tests/unit/test_pgx_cn.py`.
|
||
|
||
## Data
|
||
|
||
* **Arrays:** the GSA v4 PGx demo (`idats_Demo_36`, 36 arrays), genotyped by SimurgArray. Its CNV probes cover every
|
||
region (51–357 probes; GSTT1: 160 probes on `chr22_KI270879v1_alt` in the GRCh38 manifest).
|
||
* **Identities:** the demo arrays are 30 CEPH / 1000 Genomes individuals (6 replicate arrays). Identified by
|
||
genotype concordance with the 3202-sample 1000G 30x panel on 4647 chr22 SNPs: best match 0.992–0.996, next best
|
||
≤ 0.91 (relatives) — `scripts/pgx/demo36_identity.tsv`.
|
||
* **Truth:** NYGC 30x SV callset (1KGP_3202 GATK-SV/svtools freeze V3), RD_CN per individual
|
||
(`scripts/pgx/validate_cn_truth.py`).
|
||
* The GSE165845 GSA-MD v1 arrays (360 arrays, CN/LOH validation) have 0–9 probes per PGx region: not usable here.
|
||
|
||
## Result (30 individuals, model trained on the same 36 arrays with `--min-samples 30`)
|
||
|
||
| Region | Concordance with NYGC RD_CN | Mismatches (truth → call) |
|
||
|---|---|---|
|
||
| GSTM1 (whole gene) | **30/30** | – |
|
||
| UGT2B17 (whole gene) | **30/30** | – |
|
||
| SULT1A1 | 29/30 | 2→1 |
|
||
| CYP2A6.exon.1 | 29/30 | 3→2 |
|
||
| CYP2A6.intron.7 | 28/30 | 3→2, 1→2 |
|
||
| CYP2D6.p5 | 28/30 | 4→3, 2→1 |
|
||
| CYP2D6.intron.2 | 25/30 | 3→2 ×3, 4→3, 2→1 |
|
||
| CYP2D6.exon.9 | 25/30 | 3→2 ×3, 4→2, 2→1 |
|
||
| **all** | **224/240 (93.3 %)** | |
|
||
|
||
GSTT1 (no SV truth on the alt contig): CN 0/1/2 = 5/16/9, in Hardy–Weinberg proportions (null allele 0.43; CEU
|
||
literature ≈ 0.4–0.5). Details: `V2_pgx_cn_demo36.json`.
|
||
|
||
* CYP2D6 truth is one gene-level record; the exon-9 / intron-2 "misses" at truth CN 3 are expected for tandem
|
||
structures such as `*68+*4` or `*36+*10`, where not every sub-region is duplicated. Star-allele truth (GeT-RM)
|
||
is the right yardstick and follows with the star-allele caller.
|
||
* PCN-017 target (≥ 95 % per region) is met for GSTM1, UGT2B17, SULT1A1, CYP2A6.exon.1; not (yet) shown for the
|
||
CYP2D6 sub-regions.
|
||
|
||
## Additions
|
||
|
||
* PCN-006: a warning when the batch's IDAT scan dates span more than 14 days (no sample-sheet input in `pgx
|
||
copy-number call`, so the lot/batch-column check does not apply).
|
||
* PCN-010: `pgx_cn_baf_evidence.tsv` — per region the log-likelihood of CN 0 … 5 from the informative SNP BAFs
|
||
(binomial weights from the training cohort's B-allele frequency); `--bafs-in-cn` adds it to the CN posterior
|
||
(experimental, off by default). On the demo it agrees poorly with the LRR calls (e.g. GSTM1 2/36): the SNPs in
|
||
these regions do not separate the CN states here, so it stays informational.
|
||
* PCN-009 / EDGE-026: training excludes samples whose genome-wide level **or** noise is an outlier (robust |z| > 5);
|
||
`test_outlier_robustness` injects 10 % noisy, shifted arrays and requires ≥ 99 % unchanged calls for the others.
|
||
* CLI-032: the platform (LCG/EX) comes from the CSV manifest's `Assay Format` (`--csv`), or `--platform`; the demo
|
||
model records `EX`.
|
||
|
||
## Caveats (K-028)
|
||
|
||
* Trained and evaluated on the same 30 individuals (the spec requires ≥ 96 training samples; the priors were
|
||
chosen while looking at this truth). This is an optimistic, in-sample figure until an independent cohort is
|
||
available.
|
||
* Deviations from PCN-009: reference from the training cohort (not the calling batch); no GC-correction step; CN
|
||
model = compressed-intensity template + HWE-constrained weights (`simurg/pgx/cn.py`).
|