Source corrections

Osteosarc applies documented corrections to source records by default. You can inspect each change, disable corrections, or supply your own.

Compare corrected and published values

from osteosarc import Dataset

data = Dataset.open("baseline")
raw = Dataset.open("baseline", corrections=False)
map2 = data.variants()["MAP2-chr2-209694768"]
print("Corrected:", map2.allele)
print("Published:", raw.variants()[map2.id].allele)
print(map2.annotations["corrections"])

Allele corrections clear affected count rows to "" (unmeasured), because the original counts describe a different allele or locus. IDs are retained from each snapshot; newer website snapshots may rename entries. See the MAP2 example to check a correction against reads.

Inspect the changes and evidence

for row in data.corrections:
    print(row["id"], row["status"], row["summary"], row["evidence"])

Each correction edits or flags records. The affected objects carry its ID:

Object Correction IDs
Variant variant.annotations["corrections"]
Some of a variant's count rows variant.annotations["count_corrections"]
Asset asset.metadata["corrections"]
Count, vaccine, annotation, measurement, and specimen rows corrections field
Timeline event event.corrections
Variant selection / Varcode metadata source["corrections"]

Check for source changes

Every load checks that a correction still matches the published records.

Status Meaning
applied Expected source values match; correction applied
fixed_upstream The source contains the corrected values, or a reviewed upstream removal resolved the problem
stale An unexpected change or disappearance; correction skipped, with a warning
unavailable The snapshot lacks a required source
disabled Corrections were turned off

Corrections apply all or nothing. A correction may also check an unchanged record as evidence that the original problem remains. For example, tempus-grch37-counts checks PDZRN4's published 7/7 count before clearing rows. When upstream renames or removes records, a correction can recognize a reviewed source layout. Exactly one layout must match; an unknown or mixed layout is stale.

osteosarc curation baseline --strict
osteosarc --no-corrections variants baseline --gene MAP2

--strict exits nonzero for stale corrections or unrecognized source labels. Inspect the correction's changes field to see which records differ. Check the new source evidence before revising or removing a correction.

Source labels are normalized separately: for example, Boston Gene becomes BostonGene, and CITE becomes cite-seq. Original labels are retained. Unknown labels appear in data.unrecognized.

Add a local 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("baseline", corrections=[*CORRECTIONS, mine])

Change(source, match, expect={}, set={}) selects published records by exact field values or glob(...). Dotted names address nested fields. An empty set flags records without editing them. Pass a filtered list of CORRECTIONS to disable individual corrections.

For reviewed upstream changes, Correction(..., alternatives=(changes,)) adds another complete group of checks and edits. Change(..., absent=True) requires that no records match. Pair removal checks with surviving records as evidence; absence alone does not establish a fix.

Built-in corrections

The historical 2026-09-18 snapshot still uses all 32 corrections. On 2026-09-21, 29 applied and three were fixed upstream. Evidence URLs are available in data.corrections and the registry source.

The site moved CABLES1, CCDC40, DCHS2, GAPVD1 and GOLGA6L2 to their corrected positions and renamed their IDs. Their alleles remain placeholders, so Osteosarc still supplies the verified DNA sequences and clears the placeholder counts. The original correction IDs remain stable for provenance.

Read counts and alleles

ID Action What
tempus-grch37-counts edit Clear 200 wrongly mapped GRCh37 Tempus WES count rows in historical snapshots. New snapshots omit these rows and the viewer BAM; the original vendor BAM remains available.
allele-CABLES1-chr18-23135500 edit Literal Tempus allele at chr18:23135764 (T>TGGCGGC); the site had chr18:23135500 and dup.
allele-CCDC40-chr17-80058951 edit Literal Tempus allele at chr17:80090148; the site had not_reported.
allele-DCHS2-chr4-154322488 edit Literal Tempus delins at chr4:154323273.
allele-GAPVD1-chr9-125299105 edit Literal Tempus delins at chr9:125301980 (TAGTGC>ATTGG).
allele-GOLGA6L2-chr15-23441121 edit Literal Tempus 120-bp insertion at chr15:23440197.
allele-MAP2-chr2-209694768 edit The curated 22-bp deletion, a vaccine target, is not the observed allele. Tempus and CeGaT report one complex −28 bp event, which the catalogue's own protein sequence matches.
allele-FAM157A-p_W70_Q71ins_14 edit Supply the verified 42-base insertion at GRCh38 chr3:198153259; retain the withdrawn protein-model caveat.
allele-COL3A1-Splice edit Supply the public Tempus 737-base deletion matching c.4254+1_4255-1del, anchored at GRCh38 chr2:189010889.
map2-split-representations flag Two other MAP2 entries are pieces of that same event.
muc3a-grch38-placement annotate Record the GRCh37 call and assembly gap; leave GRCh38 placement unresolved.
ush2a-transposed-duplicate annotate Preserve the possible relationship in historical snapshots. After the site's merge, record its provenance and fix the retained entry's location label, preserving its allele and counts. Original Natera identity remains unconfirmed.
fam157a-withdrawn-protein flag The annotated protein model has been withdrawn by NCBI.
natera-alleles-unavailable flag The original Natera report is unavailable. COL3A1 now has independent Tempus evidence.
otud4-source-unavailable annotate No public genomic allele was found; retain the entry and identify the missing source.
transcript-DCHS2 edit Supply verified accession NM_001142552.1 for the old typo or the newer versionless accession.
gene-symbol-TRMO edit TMRO is a typo for TRMO; gene-symbol joins with pVACseq otherwise miss it.

The relocated alleles and MAP2 were mapped from the original GRCh37 Tempus TL-24-ALMY2X4KMV VCFs with Ensembl. Each mapped REF matched GRCh38. The published positions fall outside the indel-equivalence spans, so normalization does not explain the differences. Several wrong positions still matched a reference base in the correct gene; ready alone cannot validate an allele.

FAM157A and COL3A1 were checked separately against UCSC's GRCh37-to-GRCh38 chain and versioned NCBI RefSeq windows. The complete REF and surrounding sequence agree across assemblies. Offline fixtures test the source VCFs, reference bases and equivalent indel representations. See the five reviewed entries for usage and remaining limitations.

Samples, pipelines, and files

ID Action What
viewer-label-BG009368 edit The viewer label still says T0 2022-12; the consolidated metadata re-assigned it to T1 2024-06, with VAF evidence.
viewer-label-SARC0277 edit Likewise, from T0 BostonGene to T2 UCLA 2025-01.
provider-IPISRC044-T1-rna edit The oncoanalyser T1 RNA was built from BostonGene FASTQs, not UCLA ones.
pvac-2025-detection edit CDC40, PIP5K1A, SMC5 and TECPR1 are in the 2025-04-27 pVACtools runs.
pvac-header-only-filtered-reports flag Seven filtered reports contain only a header.
pvac-rna-fields-na flag RNA depth, VAF and expression are NA in all 131,209 report rows.
pvac-extended-run-no-class-i flag The "MHCI.extended" run has only Class-II reports.

Timeline and specimens

ID Action What
specimen-T1-site edit T1 was a UCLA biopsy, not a UCSF resection. It spans two UCLA biopsies (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 (the delivery folder date).
specimen-T3-site edit T3 was an MSKCC resection, not a UCSF biopsy.
pbmc-capture-dates flag Four PBMC specimen dates are capture dates; the flow-cytometry draws were 2–4 days earlier.
events-duplicate-rows flag SQ3370 and Trabectedin each appear twice.
tempus-timepoint flag The timeline places Tempus at T0, but all public Tempus data are TL-24 (T1 2024-06) accessions.
apheresis-date flag The apheresis is 2024-05-14 in the timeline and 2024-05-15 in the ELISPOT records.
reyagel-end-date flag The sheet's ReyaGel end date is 7/14 with no year, so the site shows a single day. It is the only malformed date among about 28,000.

Other source limitations (2026-09-18)

  • The Tempus 2022 detection label refers to a 2024 accession.
  • Three organoid DRAGEN BAMs and the T2 UCLA blood DRAGEN BAM have no specimen assignment in the consolidated metadata. Four 2026 blood specimens have no BAMs.
  • ELISPOT experiments[].date is the earliest PBMC sample date, not the assay date.
  • The legacy data/treatment_timeline.json is stale and is not used here.
  • LENS files and Natera/BostonGene clinical reports were absent from the bucket.

The Tempus count correction was checked against the site's pileup-json script: 171 of 172 SNV rows reproduced at the wrong locus. The BAM uses b37 (human_g1k_v37), while the site queried GRCh38 positions. Its MT-ND5 0/0 count also reflects a failed chrM to MT lookup. These rows are cleared, not interpreted as negative evidence.