6577d5ee1319bbea85988c1c89179436b4a94edf lrnassar Tue Jul 14 11:27:59 2026 -0700 Address code-review feedback on the Cardiomyopathy VCEP build scripts. refs #37446 - cmpVCEPCardioBoost.py: add the standard --db/--output-dir CLI. It previously hardcoded the working directory for both its input TSV and its output (unlike the 11 sibling scripts, and contrary to the makedoc's documented interface); the build loop's flags were silently ignored. Output is unchanged (31,236 variants per assembly). - Decode leftover HTML entities (arrows, >=, <=, +/-, x) in print/stderr diagnostics, comments, and docstrings across all scripts so build logs read cleanly. The mouseOver / bigBed display strings intentionally keep their entities. - cmpVCEPWalsh2019.py: fix the stale docstring that described the ClinVar-unmatched entries as "deferred" (they are mapped via the hgvsToVcf fallback, item L) and drop the unverified "163 rows" count. Per code-review feedback on commit aa5669fe64. No track data changed. diff --git src/hg/makeDb/scripts/cardiomyopathyVCEP/cmpVCEPWalshOR.py src/hg/makeDb/scripts/cardiomyopathyVCEP/cmpVCEPWalshOR.py index 46c99898e12..02be89c4b4a 100644 --- src/hg/makeDb/scripts/cardiomyopathyVCEP/cmpVCEPWalshOR.py +++ src/hg/makeDb/scripts/cardiomyopathyVCEP/cmpVCEPWalshOR.py @@ -1,32 +1,32 @@ #!/usr/bin/env python3 """ -B.9 — Walsh gene-level Odds Ratio track (PS4 calibration source). +B.9 - Walsh gene-level Odds Ratio track (PS4 calibration source). Rebuilt from WALSH 2017 (Genetics in Medicine, PMID 27532257) Tables S5A (HCM) and S5B (DCM), -the case-control OR + 95% CI by gene × disease × variant class. GN002 PS4 explicitly cites +the case-control OR + 95% CI by gene x disease x variant class. GN002 PS4 explicitly cites Walsh 2017 as the preferred case series and defines PS4 strength by the lower bound of the OR's 95% CI: STRONG CI-lower >= 20 (CSpec, explicit) MODERATE CI-lower >= 10 (CSpec, explicit) SUPPORTING CI-lower >= 5 (base ACMG PS4: OR > 5, CI excludes 1.0) below threshold otherwise (Earlier versions used Walsh 2019 Table S1 = non-truncating HCM EF across MAF bins, a different statistic; superseded per CSpec. Whether the VCEP also wants the 2019/EF values is a Phase-7 question.) -Gene-level features: one per (gene × {HCM,DCM} × {All protein-altering, Truncating, Non-truncating}), +Gene-level features: one per (gene x {HCM,DCM} x {All protein-altering, Truncating, Non-truncating}), spanning the gene CDS (MANE), filterable by gene / cohortDisease / variantClass / ps4Strength. hg38 built from MANE; hg19 via liftOver. Outputs: cmpVCEPWalshOR/cmpVCEPWalshOR.as cmpVCEPWalshOR/cmpVCEPWalshORHg{38,19}.bed + .bb """ import argparse, os, subprocess, sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) from cmpVCEPClinDomains import parse_mane_record WALSH2017_XLSX = ('/hive/users/lrnassar/claude/RM37446/cmp_downloads/walsh/' 'walsh2017_extracted/Supplementary_Tables_resubmit.xlsx') SHEETS = [('Table S5A', 'HCM'), ('Table S5B', 'DCM')] @@ -93,31 +93,31 @@ 'or': or_val, 'ci_lo': ci_lo, 'ci_hi': ci_hi, 'fishers': r[9], }) print(f' parsed {len(recs)} Walsh 2017 S5A/S5B rows (8 genes x HCM/DCM x variant class)', file=sys.stderr) return recs def main(): ap = argparse.ArgumentParser() ap.add_argument('--db', action='append', required=True, choices=['hg38', 'hg19']) ap.add_argument('--output-dir', required=True) args = ap.parse_args() out_dir = os.path.join(args.output_dir, 'cmpVCEPWalshOR') os.makedirs(out_dir, exist_ok=True) - print(' [B.9 Walsh 2017 gene-level OR — PS4]') + print(' [B.9 Walsh 2017 gene-level OR - PS4]') recs = load_walsh2017() mane_cache = {g: parse_mane_record(g) for g in OUR_GENES} bed_lines = [] strength_counts = {} for r in recs: mane = mane_cache[r['gene']] s, e = mane['thickStart'], mane['thickEnd'] strength = ps4_strength(r['ci_lo']) strength_counts[strength] = strength_counts.get(strength, 0) + 1 color = PS4_COLOR[strength] or_str = f'{r["or"]:.1f} ({r["ci_lo"]:.1f}-{r["ci_hi"]:.1f})' case_counts = f'{r["cases_with"]}/{(r["cases_with"] or 0) + (r["cases_without"] or 0)}' ctrl_counts = f'{r["ctrl_with"]}/{(r["ctrl_with"] or 0) + (r["ctrl_without"] or 0)}'