Corrections¶
Osteosarc fixes 35 known problems in the website's data, by default. Each time a snapshot is opened, every fix is checked against the data. You can see what changed, turn the fixes off, or add your own.
osteosarc corrections # every fix and its status
osteosarc corrections allele-MAP2-chr2-209694768 # one fix, with its evidence
osteosarc --no-corrections variants --gene MAP2 # the website's values
Compare corrected and published values¶
from osteosarc import Dataset
data = Dataset.open()
raw = Dataset.open(corrections=False)
map2 = data.variants()["MAP2-chr2-209694768"]
print("Corrected:", map2.allele)
print("Published:", raw.variants()[map2.id].allele)
print(map2.annotations["corrections"])
A fix that changes a variant's allele usually clears its read counts, since they were measured for a different allele or position; MAP2 is the exception (see below). Variant IDs are the snapshot's own, and newer snapshots may rename them. The MAP2 example checks a correction against the reads.
See every correction¶
for row in data.corrections:
print(row["id"], row["status"], row["summary"])
Every record a fix touches names it: a variant in its annotations (under corrections, or count_corrections when only some of its read counts changed), a file in its metadata, and a sample, timeline event, or row of counts, vaccines or measurements in its own corrections field.
When the website changes¶
Each fix records what the data should look like before it's applied, so it notices when the website changes. Its status says what it found:
| Status | Meaning |
|---|---|
| applied | The problem is still there, and the fix was applied |
| fixed_upstream | The website now has the right value, or has removed the bad record |
| stale | The data changed unexpectedly; the fix was skipped, with a warning |
| unavailable | The snapshot doesn't have the data the fix needs |
| disabled | Corrections are turned off |
A fix applies completely or not at all. Some also check a record they don't change, to confirm the problem is still there; tempus-grch37-counts, for example, checks PDZRN4's published 7/7 before clearing counts. When the website reorganizes records, a fix can list each layout it accepts; exactly one must match, or the fix is stale.
osteosarc corrections --strict
This exits with an error if a fix is stale or the data uses a label osteosarc doesn't
know. It checks the snapshot you have; run osteosarc sync --refresh first to check the
live website, and look at the new data before changing or removing a fix.
Labels are tidied separately, without counting as corrections: Boston Gene becomes BostonGene, and CITE becomes cite-seq. The original labels are kept.
Add your own correction¶
from osteosarc import CORRECTIONS, Change, Correction, glob
mine = Correction(
"my-lab-note", "Flag CITE-seq BAMs for QC review.",
(Change("bucket", {"key": glob("kamil/blood/output/*CITE*/outs/*.bam")}),),
evidence=("internal QC log 2026-09",), verified="2026-09-18",
)
data = Dataset.open(corrections=[*CORRECTIONS, mine])
A change picks records by exact field values or glob patterns (dotted names reach nested fields). Without new values to set, it only flags the records. To turn off some built-in fixes, pass a shorter list. A correction can accept other record layouts, and a change can require that no record matches; pair such a check with one on a record that should still be there, since a record disappearing doesn't prove a fix.
The corrections¶
Reviewed again against the website on 2026-10-05. Fifteen additional layouts accept
verified upstream changes, including renamed TRMO, literal MAP2/DCHS2/GAPVD1
alleles, the removed split MAP2 entries, the expanded FAM157A protein caveat,
corrected specimen descriptions, T0 Tempus tumor labels and ReyaGel's explicit end
year. Historical snapshots retain their original corrections and unexpected
future values still warn. Each fix's evidence is in
data.corrections and the
source. None
only rewrites a value in an equivalent form: each fixes a wrong value, fills in a
missing one, or flags something to be careful with.
Variants and read counts¶
| ID | Does | What |
|---|---|---|
| tempus-grch37-counts | edit | Clears counts measured in a GRCh37 Tempus exome BAM at GRCh38 positions, which describe unrelated places. Newer snapshots drop those rows. |
| allele-CABLES1-chr18-23135500 | edit | Gives the Tempus allele, chr18:23135764 T>TGGCGGC; the site had it 264 bp away as a dup placeholder. |
| allele-CCDC40-chr17-80058951 | edit | Gives the Tempus allele at chr17:80090148; the site had it 31 kb away, not reported. |
| allele-DCHS2-chr4-154322488 | edit | Gives the Tempus allele (a complex change) at chr4:154323273; the site had it 785 bp away with a wrong REF. |
| allele-GAPVD1-chr9-125299105 | edit | Gives the Tempus allele, chr9:125301980 TAGTGC>ATTGG; the site had it 2.9 kb away with a wrong REF. |
| allele-GOLGA6L2-chr15-23441121 | edit | Gives the Tempus allele, a 120-base insertion at chr15:23440197; the site had it 924 bp away as a dup. |
| allele-MAP2-chr2-209694768 | edit | The vaccine target's 22-bp deletion isn't what's in the tumor. Tempus calls one complex change (c.2599_2630delinsAGGG), CeGaT the same as three records, and the catalogue's protein and the reads match it. Its counts are kept: the site counts any large deletion there, which in the T0 exome is always this one. |
| allele-FAM157A-p_W70_Q71ins_14 | edit | Fills in the missing allele: a 42-base insertion at chr3:198153259, from a public Tempus call. |
| allele-COL3A1-Splice | edit | Fills in the missing allele: a 737-base deletion at chr2:189010889 that removes exactly intron 50, from a public Tempus call. |
| map2-split-representations | flag | Two other MAP2 entries are pieces of the same change; don't count them separately. |
| muc3a-grch38-placement | note | The Tempus call is on GRCh37, in a repeat that differs between builds, so its GRCh38 position stays unresolved. |
| ush2a-transposed-duplicate | note | USH2A-chr1-215560752 is a typo of USH2A-chr1-215650752. The site has merged them; the kept entry's location label and sequence context are fixed. |
| fam157a-withdrawn-protein | flag | NCBI withdrew the protein model behind FAM157A's insertion; the site now says so too. |
| natera-alleles-unavailable | flag | The original Natera report is not public. Independent Tempus and CeGaT calls supply matching COL3A1 and OTUD4 alleles; they do not verify that report or establish somatic status. |
| otud4-source-unavailable | note | Historical entries remain unresolved. The reviewed 2026-10-05 entry matches a public CeGaT normal-DNA deletion call, with transcript and assembly checks; this does not verify the original Natera call or somatic status. |
| transcript-DCHS2 | edit | NM_1142552 is missing two zeros: NM_001142552, which the site now uses. |
| transcript-COL4A2 | edit | NM_001846. has a stray dot. |
| transcript-GTF3C5 | edit | NM_00112283 is missing a digit: NM_001122823. |
| gene-symbol-TRMO | edit | TMRO is a typo for TRMO. |
The five moved alleles and MAP2's come from the Tempus TL-24-ALMY2X4KMV calls in the bucket, converted from GRCh37 to GRCh38 with Ensembl. Each REF matches GRCh38, and no equivalent way of writing an allele reaches its old position. These fixes make the catalogue match what Tempus called; several calls have few reads or sit in repeats, so they don't prove a variant is real. FAM157A and COL3A1 were also checked with UCSC's liftover and NCBI's reference sequence.
The GRCh37 counts were wrong because the site's pileup script looked up GRCh38 positions in a BAM aligned to GRCh37; MT-ND5's 0/0 has the same cause. These counts are cleared rather than read as zero.
Samples, pipelines and files¶
| ID | Does | What |
|---|---|---|
| viewer-label-BG009368 | edit | This reprocessed RNA is T1 2024-06, not T0 2022-12, by its FASTQ and allele fractions. The site now agrees. |
| viewer-label-SARC0277 | edit | Likewise, it's T2 UCLA 2025-01, not T0 BostonGene. The site now agrees. |
| provider-IPISRC044-T1-rna | edit | The oncoanalyser T1 RNA BAM was built from BostonGene's FASTQs, not UCLA's. |
| pvac-2025-detection | edit | CDC40, PIP5K1A, SMC5 and TECPR1 are in the 2025-04-27 pVACtools runs, which the site's detection flag misses. |
| pvac-header-only-filtered-reports | flag | Seven filtered pVACseq reports are empty, which doesn't mean no epitope passed. |
| pvac-rna-fields-na | flag | RNA depth, VAF and expression are NA in every pVACseq report: RNA was never given to pVACseq. |
| pvac-extended-run-no-class-i | flag | The "MHCI.extended" run has only Class II reports. |
Timeline and samples¶
| ID | Does | What |
|---|---|---|
| specimen-T1-site | edit | T1 was a UCLA biopsy, not a UCSF resection; it spans two UCLA biopsies, on 2024-06-06 and 2024-06-11. |
| specimen-T2-date-site | edit | T2 was a UCLA biopsy on 2025-01-28, not UCSF on 2025-01-06. |
| specimen-T3-site | edit | T3 was an MSKCC resection, not a UCSF biopsy. |
| pbmc-capture-dates | flag | Four blood samples are dated by cell capture; the blood was drawn two to four days earlier. |
| events-duplicate-rows | flag | SQ3370 and Trabectedin each appear twice. |
| tempus-timepoint | flag | The timeline dates the Tempus tests to T0 (2022), consistent with the data and the reviewed 2026-10-05 tumor-file labels. Historical file labels say T1 (2024-06). |
| tempus-file-labels | flag | Historical Tempus files are labeled T1, but carry T0 evidence. The reviewed 2026-10-05 metadata labels tumor products T0 and leaves the later normal draw without a tumor timepoint. Published labels are retained; overlapping RNA products remain dependent evidence. |
| apheresis-date | flag | The apheresis is 2024-05-14 on the timeline and 2024-05-15 in the ELISPOT records. |
| reyagel-end-date | flag | Historical ReyaGel's end date is 7/14 without a year. The reviewed 2026-10-05 sheet and event explicitly give 2026-07-14. |
Other things to know¶
- Some DRAGEN BAMs, mostly blood normals and organoid runs, aren't linked to a sample;
osteosarc files --prefix kamil/basespace/results/lists them. The four 2026 blood samples have only FASTQs so far. - An ELISPOT experiment's date is that of the earliest blood sample it used.
- The site's older treatment timeline file is out of date, and isn't used.
- The site lists LENS pipeline detections, but has no LENS files to download.