v2 CN: cn annotate (JSON report, ISCN 2020, cytobands, genes) and the annotation bundle builder

cn call now records per-chromosome and sample statistics (percent het, LRR stats, BAF
deviations, robust LogR dev, call rate) in the sidecar; cn annotate writes
<sample>.cyto.json (CYTO-033) with ISCN microarray/traditional strings (CYTO-034), bands
and RefSeq gene lists (CYTO-035), LOH summaries, weighted median CN (CYTO-026); annotation
bundle from UCSC cytoBand + ncbiRefSeq (CYTO-036, IN-054). Tests for ISCN strings, gene
overlap, sidecar-missing error and an end-to-end call+annotate.
This commit is contained in:
kemal committed 2026-09-29 01:37:56 +01:00
1 parent 1255f37a16
commit d3097dd027
6 files changed
+428 -2

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env bash
# Build the cyto annotation bundle (spec CYTO-036, IN-054) from public UCSC tables:
# cytoBand (ISCN bands) and ncbiRefSeq (RefSeq transcripts with gene symbols, from NCBI RefSeq).
# Output: simurg-cyto-annot-<build>-<date>-<sha12>.zip with cytoBand.txt.gz, genes.tsv.gz and manifest.json.
# bash scripts/build_annotation_bundle.sh GRCh38|GRCh37 [OUT_DIR]
set -euo pipefail
BUILD=${1:?usage: build_annotation_bundle.sh GRCh38|GRCh37 [OUT_DIR]}
OUT=${2:-data/annotation}
case $BUILD in GRCh38) UCSC=hg38;; GRCh37) UCSC=hg19;; *) echo "unknown build $BUILD"; exit 2;; esac
BASE=https://hgdownload.soe.ucsc.edu/goldenPath/$UCSC/database
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT
mkdir -p "$OUT"
for t in cytoBand ncbiRefSeq; do curl -sSfL -o "$W/$t.txt.gz" "$BASE/$t.txt.gz"; done
curl -sSfL -o "$W/ncbiRefSeq.sql" "$BASE/ncbiRefSeq.sql" || true
# ncbiRefSeq columns: bin name chrom strand txStart txEnd cdsStart cdsEnd exonCount exonStarts exonEnds score name2 ...
zcat "$W/ncbiRefSeq.txt.gz" | awk -F'\t' 'BEGIN{OFS="\t"; print "chrom","start","end","gene","transcript"}
{ c=$3; sub(/^chr/,"",c); if (c ~ /_/) next; print c, $5+1, $6, $13, $2 }' | gzip -9 > "$W/genes.tsv.gz"
DATE=$(date -u +%Y%m%d)
python3 - "$W" "$BUILD" "$UCSC" "$DATE" <<'PY'
import hashlib, json, sys, pathlib
w, build, ucsc, date = pathlib.Path(sys.argv[1]), *sys.argv[2:]
files = {n: hashlib.sha256((w / n).read_bytes()).hexdigest() for n in ("cytoBand.txt.gz", "genes.tsv.gz")}
m = {"schema": "simurg.cyto_annotation/1", "build": build, "created": date,
"sources": [{"name": "UCSC cytoBand", "version": ucsc, "release_date": None},
{"name": "RefSeq (UCSC ncbiRefSeq)", "version": ucsc, "release_date": None}],
"files": files}
(w / "manifest.json").write_text(json.dumps(m, indent=1))
PY
( cd "$W" && zip -q -X bundle.zip manifest.json cytoBand.txt.gz genes.tsv.gz )
SHA=$(sha256sum "$W/bundle.zip" | cut -c1-12)
cp "$W/bundle.zip" "$OUT/simurg-cyto-annot-$BUILD-$DATE-$SHA.zip"
ls -la "$OUT/simurg-cyto-annot-$BUILD-$DATE-$SHA.zip"