Skip to content

Validate real genomes: phase sets, canonical QUAL digest, batched shapes - #31

Merged
ecrum19 merged 2 commits into
mainfrom
fix/validation-real-files
Oct 4, 2026
Merged

ecrum19 merged 2 commits into
mainfrom
fix/validation-real-files

Conversation

@ecrum19

@ecrum19 ecrum19 commented Oct 2, 2026

Copy link
Copy Markdown
Owner

On a real genome (NG131FQA1I, first 250,000 records, 58.2M triples), v3.3.0's validation had two problems:

  • it reported a mismatch, even though every field of every record equals the VCF text;
  • its shape checks exhausted a 31 GB host.

None of these were conversion errors; all three causes were in the validator. This PR fixes all three.

Problem Fix
Q9/Q10 mismatch: the oracle didn't count GATK's phase sets (30,910 vcfc:PhaseSet) The census oracle now counts what the emitters write for phase sets, SV events, confidence intervals (including FALDO) and gVCF reference blocks. test_validation_real_files_unit.py checks the oracle against both emitters, for VCFv4.2 and 4.5.
Q11 mismatch: QLever prints a decimal QUAL canonically (30.10 → 30.1), so 788 digest buckets differed Q11 and the oracle both drop a decimal QUAL's trailing zeros before hashing. That changes 1,998 values, and 0 buckets then differ.
pyshacl loaded the whole graph Node-local shapes (the default core profile) are now checked a batch of whole records at a time, in parallel. Each batch also carries the file-level triples it points at, so the verdict is the same as checking the whole graph.

New options

  • --shacl-batch-triples (default 500,000) and --shacl-workers (default up to 4).
  • Measured with the core shapes: about 1.3 GB per batch. Time grows in step with batch size, so smaller batches cost no throughput.

Size limit for checking the whole graph

  • Shapes with SPARQL constraints (the full profile) are still checked as one graph, so they keep a size limit, --shacl-max-triples.
  • That limit drops from 50M to 10M triples. At the measured ~2.4 GB per million triples, 50M would need about 115 GB. The old comment said the campaign had shape-checked 17.1M triples, but its largest was 0.96M.
  • The wrapper no longer limits the core profile by size, since it is batched now.

Verification, all on bench-2 inside the rebuilt image:

  • Full suite: 1,284 tests OK (60 skipped).
  • End to end on NG131FQA1I's slice: validation PASS.
    • 13/13 comparisons equal.
    • Shapes PASS: 117 batches, 0 violations, 46 warnings. The warnings are VCF 4.5 recommending Source and Version on INFO declarations.
    • The shape checks took 89 min, and available memory never fell below 19.9 GB.
    • The earlier attempt with 2M-triple batches was stopped by the watchdog when available memory fell to 0.6 GB.

Docs updated: validation.md, validation-methodology.md, validation-migration-notes.md, cli-reference.md.

🤖 Generated with Claude Code

…nonically, batch shapes

On NG131FQA1I's first 250,000 records (58.2M triples) v3.3.0's validation
reported a mismatch on a graph whose every field equals the VCF, and its
shape checks exhausted a 31 GB host. Three fixes:

- The census oracle counts what the emitters write for phase sets, SV
  events, confidence intervals and gVCF reference blocks, so Q9 and Q10
  agree on files that carry them. A new test checks the oracle against
  both emitters for VCFv4.2 and 4.5.
- Q11's record digest drops a decimal QUAL's trailing zeros on both
  sides, so it no longer depends on how an engine prints decimals
  (QLever prints 30.10 as 30.1).
- Node-local shapes (the default core profile) are validated a batch of
  whole records at a time, in parallel, each batch with the file-level
  triples it points at, so memory follows the batch rather than the
  graph. New options --shacl-batch-triples (default 500,000) and
  --shacl-workers (default up to 4). Measured: about 1.3 GB per batch.
  Shapes with SPARQL constraints are still validated whole, under
  --shacl-max-triples, now 10M (about 24 GB at the measured 2.4 GB per
  million triples; 50M could not protect a 31 GB host). The wrapper no
  longer gates the core profile by size.

End to end on bench-2, NG131FQA1I's slice now validates PASS: 13/13
comparisons equal, shapes PASS (117 batches, 0 violations, 46 warnings)
in 89 min, with at least 19.9 GB of memory free throughout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov-commenter

codecov-commenter commented Oct 2, 2026 •

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 91.04803% with 41 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
test/test_validation_real_files_unit.py 88.63% 25 Missing ⚠️
src/validation/validation_runner.py 91.11% 16 Missing ⚠️

📢 Thoughts on this report? Let us know!

Covers the batched SHACL paths the first tests left out:
- a buffered split that flushes after every line gives the same batches;
- a result repeated in every batch (the header's warnings) is reported once;
- one violating batch fails the graph, and a batch that cannot run is
  EXECUTION_FAILED;
- a graph with no records is validated as its context alone;
- every batch runs in a fresh process.

The task is stubbed, so these need no pyshacl. Also pins the real
genome's 2,146 records per batch at the default, counter keys as IRIs,
an SV record with no ALT, and that --shacl-workers reaches
validate_shacl. The flush threshold is now a named constant so the test
can lower it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ecrum19
ecrum19 merged commit dbe7d7c into main Oct 4, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants