From 24f43a1f6fb15bb43e4fa9ad47676ee334ad97f8 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Tue, 8 Sep 2026 14:15:04 +0200 Subject: [PATCH 1/9] VCF-Core v2.0.0 conformance and validation synchronization --- Dockerfile | 9 +- README.md | 108 +- changelog.md | 438 +++- conda-recipe/meta.yaml | 7 + docs/README.md | 15 +- docs/architecture.md | 46 +- docs/cli-reference.md | 25 +- docs/conversion.md | 273 ++- docs/datalinking-design.md | 13 +- docs/datalinking.md | 356 +++ docs/limitations.md | 119 +- docs/output-and-metrics.md | 45 +- docs/privacy-policy-design.md | 26 +- docs/rml-mappings.md | 123 +- docs/roadmap.md | 71 +- docs/sample-representation-guide.md | 137 +- docs/validation-methodology.md | 2 +- docs/validation-migration-notes.md | 178 ++ docs/validation.md | 67 +- docs/vcf-coverage.md | 258 ++- examples/linking/README.md | 23 + examples/linking/example.vcf | 8 + pyproject.toml | 10 +- rules/README.md | 39 +- rules/default_rules.ttl | 193 +- src/run_conversion.sh | 2 +- .../queries/common/preflight_blank_nodes.rq | 4 +- .../common/preflight_blank_nodes_count.rq | 2 +- .../common/preflight_distinct_triple_count.rq | 2 +- .../queries/common/preflight_empty_values.rq | 4 +- .../common/preflight_empty_values_count.rq | 2 +- .../preflight_missing_token_conformance.rq | 4 +- ...eflight_missing_token_conformance_count.rq | 4 +- .../common/preflight_position_datatype.rq | 4 +- .../preflight_position_datatype_count.rq | 4 +- .../common/preflight_record_cardinality.rq | 14 +- .../preflight_record_cardinality_count.rq | 14 +- .../queries/common/q01_record_density_1mb.rq | 4 +- .../common/q02_variant_shape_counts.rq | 4 +- src/validation/queries/common/q03_titv.rq | 4 +- .../queries/common/q04_filter_distribution.rq | 6 +- .../queries/common/q07_file_metadata.rq | 10 +- .../queries/common/q08_header_line_census.rq | 4 +- .../queries/common/q09_predicate_census.rq | 2 +- .../queries/common/q10_class_census.rq | 2 +- .../queries/common/q11_record_digest.rq | 22 +- .../queries/common/q12_info_value_digest.rq | 4 +- .../preflight_representation_profile.rq | 8 +- .../preflight_representation_profile_count.rq | 8 +- .../preflight_sample_gt_inventory.rq | 10 +- .../condensed/q05_sample_genotype_counts.rq | 20 +- .../condensed/q06_ac_an_distribution.rq | 18 +- .../condensed/q13_format_value_digest.rq | 4 +- .../preflight_representation_profile.rq | 8 +- .../preflight_representation_profile_count.rq | 8 +- .../expanded/preflight_sample_gt_inventory.rq | 8 +- .../expanded/q05_sample_genotype_counts.rq | 8 +- .../expanded/q06_ac_an_distribution.rq | 10 +- .../expanded/q13_format_value_digest.rq | 4 +- src/validation/validation_runner.py | 946 ++++++-- test/README.md | 14 +- test/test_linking_unit.py | 462 ++++ test/test_validation_benchmark_unit.py | 4 +- test/test_validation_engines_unit.py | 60 +- test/test_validation_logic_unit.py | 66 +- test/test_vcf_rdfizer_unit.py | 346 ++- test/validation_fixtures.py | 198 +- test/validation_mutations.py | 315 ++- vcf_rdfizer.py | 2049 ++++++++++++++--- vcf_rdfizer_data/linkers/__init__.py | 1 + vcf_rdfizer_data/linkers/gene-demo/README.md | 25 + vcf_rdfizer_data/linkers/gene-demo/genes.gff3 | 7 + vcf_rdfizer_data/linkers/gene-demo/linker.ttl | 22 + vcf_rdfizer_data/linkers/rsid-dbsnp/README.md | 19 + .../linkers/rsid-dbsnp/linker.ttl | 17 + .../linkers/rsid-ensembl/README.md | 29 + .../linkers/rsid-ensembl/linker.ttl | 21 + .../linkers/rsid-ensembl/resolver.py | 34 + vcf_rdfizer_data/rules/default_rules.ttl | 187 +- vcf_rdfizer_link.py | 176 ++ vcf_rdfizer_linking/__init__.py | 30 + vcf_rdfizer_linking/inputs.py | 151 ++ vcf_rdfizer_linking/manifest.py | 239 ++ vcf_rdfizer_linking/reference.py | 146 ++ vcf_rdfizer_linking/runner.py | 271 +++ vcf_rdfizer_linking/session.py | 193 ++ vcf_rdfizer_rules.py | 26 + vcf_rdfizer_vocab.py | 1126 +++++++++ 88 files changed, 8768 insertions(+), 1237 deletions(-) create mode 100644 docs/datalinking.md create mode 100644 docs/validation-migration-notes.md create mode 100644 examples/linking/README.md create mode 100644 examples/linking/example.vcf create mode 100644 test/test_linking_unit.py create mode 100644 vcf_rdfizer_data/linkers/__init__.py create mode 100644 vcf_rdfizer_data/linkers/gene-demo/README.md create mode 100644 vcf_rdfizer_data/linkers/gene-demo/genes.gff3 create mode 100644 vcf_rdfizer_data/linkers/gene-demo/linker.ttl create mode 100644 vcf_rdfizer_data/linkers/rsid-dbsnp/README.md create mode 100644 vcf_rdfizer_data/linkers/rsid-dbsnp/linker.ttl create mode 100644 vcf_rdfizer_data/linkers/rsid-ensembl/README.md create mode 100644 vcf_rdfizer_data/linkers/rsid-ensembl/linker.ttl create mode 100644 vcf_rdfizer_data/linkers/rsid-ensembl/resolver.py create mode 100644 vcf_rdfizer_link.py create mode 100644 vcf_rdfizer_linking/__init__.py create mode 100644 vcf_rdfizer_linking/inputs.py create mode 100644 vcf_rdfizer_linking/manifest.py create mode 100644 vcf_rdfizer_linking/reference.py create mode 100644 vcf_rdfizer_linking/runner.py create mode 100644 vcf_rdfizer_linking/session.py create mode 100644 vcf_rdfizer_vocab.py diff --git a/Dockerfile b/Dockerfile index 59d042d..1a5d06f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -166,9 +166,14 @@ COPY THIRD_PARTY_NOTICES.md /usr/share/licenses/vcf-rdfizer/THIRD_PARTY_NOTICES. COPY src/*.sh /opt/vcf-rdfizer/ COPY src/*.py /opt/vcf-rdfizer/ COPY src/validation/ /opt/vcf-rdfizer/validation/ -# Shared, dependency-free helper used by both the host CLI and the in-container -# conversion runner, so it lives at the repository root rather than in src/. +# Shared, dependency-free helpers used by both the host CLI and the in-container +# runners, so they live at the repository root rather than in src/. COPY vcf_rdfizer_gzip.py /opt/vcf-rdfizer/ +# The vocabulary terms, the VCF-version model and the lexical parsers. The +# validation runner imports this as a sibling module, so the oracle and the +# emitters share one description of what the graph should contain instead of +# mirroring each other. +COPY vcf_rdfizer_vocab.py /opt/vcf-rdfizer/validation/ RUN chmod +x /opt/vcf-rdfizer/*.sh \ && chmod +x /usr/local/bin/rdf2hdt \ diff --git a/README.md b/README.md index 744ee26..5a3dbcb 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,14 @@ VCF-RDFizer is a Docker-first CLI wrapper for: 2. Optional RDF compression/decompression 3. Semantic validation of a compressed RDF graph against its source VCF -The VCF-RDFizer vocabulary is available at [https://w3id.org/vcf-rdfizer/vocab#](https://w3id.org/vcf-rdfizer/vocab#). +The conversion targets the **VCF Core vocabulary**, published at +[https://w3id.org/vcf-core/vocab#](https://w3id.org/vcf-core/vocab#) (prefix +`vcfc:`). It replaces the retired VCF-RDFizer vocabulary +(`https://w3id.org/vcf-rdfizer/vocab#`), which is not redirected: that namespace +serves a deprecation document linking every former term to its successor. VCF +Core is a semantic target any conversion system can adopt, and its version line +is independent of this converter's — the emitted IRIs reference the namespace, +not a pinned version. This README is the task-oriented reference. For how the tool works, why it is built that way, and where it stops working, see the documentation set in @@ -195,7 +202,7 @@ vocabulary's published shapes. ```bash vcf-rdfizer --mode validation -i ./cohort.vcf.gz --rdf ./results/cohort/cohort.nt.gz \ - --shacl-shapes ./vocabulary/shacl/vcf-rdfizer-vocabulary.shacl.ttl \ + --shacl-shapes ./vocabulary/shacl/vcf-core-vocabulary.shacl.ttl \ --strict-conformance -o ./validation-results ``` @@ -284,11 +291,36 @@ structure is emitted; all default to the richer form. | Option | Effect | | --- | --- | | `--sample-representation {expanded,condensed}` | Genotype shape (see below) | -| `--info-representation {structured,raw}` | `structured` adds one `vcfr:InfoFieldValue` per record and key, with typed values, alongside `vcfr:infoRaw` | -| `--header-representation {structured,basic}` | `structured` types each `##` line with its vocabulary subclass and lifts FILTER/ALT/contig attributes into their own properties | - -QUAL is always emitted, typed `xsd:decimal` or `vcfr:Null`, because the -published SHACL shape requires a datatype that depends on the value. +| `--info-representation {structured,raw}` | `structured` adds one `vcfc:InfoFieldValue` per record and key, with typed values, alongside `vcfc:infoRaw` | +| `--vcf-version {auto,4.1,4.2,4.3,4.4,4.5}` | `auto` (the default) reads each input's `##fileformat` line, so nothing has to be supplied; an explicit version overrides it for a file whose declaration is missing or wrong | +| `--header-representation {structured,basic}` | `structured` types each `##` line with its vocabulary subclass, emits the ordered `vcfc:HeaderAttribute` resources the SHACL profile requires, and lifts the INFO/FORMAT/FILTER/ALT/contig/META/SAMPLE/PEDIGREE attributes into their own properties | + +`ID`, `ALT`, `QUAL`, `FILTER` and `infoRaw` are always emitted by the wrapper +rather than by the RML mapping, because each may be the VCF missing token and +the vocabulary requires that as `"."^^vcfc:Null` — a datatype that depends on +the row, which RML cannot express. QUAL additionally takes `xsd:decimal` for a +finite value and `vcfc:VCFFloat` for the `INF`/`INFINITY`/`NAN` spellings. + +### VCF versions + +VCF Core ships a SHACL overlay per VCF version (4.1–4.5). The converter detects +each input's version from its `##fileformat` line — required to be the first +line of a conforming VCF — and follows it **per input**, so a directory of mixed +versions converts correctly without any flag. The version selects the +`vcfc:VCF4xFile` class in the mapping and the behaviour that genuinely differs +between versions: whether `CIPOS`/`CIEND` carry one pair per record (4.1–4.3) or +one per ALT allele (4.4+), whether `CILEN`/`CICN` and `EVENTTYPE` exist at all, +and whether the local-allele and base-modification FORMAT families are defined. + +VCF 4.0 has no conformance overlay, so it converts with the newest supported +rules and no version class, and the run says so rather than assuming silently. + +`--info-representation structured` also carries the **allele layer** (ordered +`vcfc:ReferenceAllele`/`vcfc:AltAllele` with their kind, symbolic type and +breakend components), the `vcfc:FieldValueItem` decomposition of +`Number=A/R/G/P` values, and the structural-variant carriers. +`--header-representation basic` is the smallest header form but does **not** +produce a SHACL-conformant graph. [`docs/vcf-coverage.md`](docs/vcf-coverage.md) maps every VCF element to its RDF terms and to the validation check that covers it. @@ -306,11 +338,17 @@ selection trade-offs. ### Expanded (default) Use `--sample-representation expanded` for single-sample and low-sample VCFs. It -preserves the original vocabulary model: - -- every record/sample pair is a `vcfr:SampleCall`; -- every represented FORMAT slot is a `vcfr:FormatFieldValue`; -- the VCF file declares `vcfr:representationProfile vcfr:ExpandedRepresentation`. +preserves the per-sample vocabulary model: + +- every record/sample pair is a `vcfc:SampleCall`, linked to a reusable + `vcfc:VCFSample` with `vcfc:forSample`; +- every represented FORMAT slot is a `vcfc:FormatFieldValue`, linked to its + declaration with `vcfc:declaredBy`; +- `GT` is parsed into a `vcfc:Genotype` with an explicit `vcfc:phasingStatus` + and one `vcfc:GenotypeAlleleCall` per position, and `FT`, `PS`/`PSL`, `LAA`, + the copy-number and haplotype keys, and the `M`/`DPM`/`ADM` base-modification + families get their own resources; +- the VCF file declares `vcfc:representationProfile vcfc:ExpandedRepresentation`. With the default rules, these triples are appended directly from `records.tsv`; the large materialized helper TSVs are not created. The final graph is still @@ -326,19 +364,25 @@ vcf-rdfizer --mode full \ ### Condensed -Use `--sample-representation condensed` for large multi-sample cohorts. It -uses the vocabulary introduced in VCF-RDFizer Vocabulary 1.1.0: +Use `--sample-representation condensed` for large multi-sample cohorts: -- sample columns are declared once as an ordered `vcfr:SampleSet` of reusable - `vcfr:VCFSample` resources; -- each genotype-bearing call has one `vcfr:CohortCallMatrix`; -- each FORMAT key has one `vcfr:FormatValueVector`, rather than one RDF value +- sample columns are declared once as an ordered `vcfc:SampleSet` of reusable + `vcfc:VCFSample` resources; +- each genotype-bearing call has one `vcfc:CohortCallMatrix`; +- each FORMAT key has one `vcfc:FormatValueVector`, rather than one RDF value resource per sample; - the VCF file declares - `vcfr:representationProfile vcfr:CondensedRepresentation`. + `vcfc:representationProfile vcfc:CondensedRepresentation`. + +Condensed mode deliberately stops at the vector: it does **not** derive the +per-sample genotype, phase-set or base-modification resources that expanded mode +does, because that is exactly the per-sample materialization the profile exists +to avoid. Every value stays recoverable by decoding a vector against its FORMAT +definition and the matrix `SampleSet`. Both profiles do emit the file-level +`vcfc:SampleSet`, which costs one resource per sample column for the whole file. -`vcfr:encodedValues` uses `vcfr:VCFTextVector`: one tab-separated lexical item -per sample in `vcfr:sampleIndex` order. Commas inside a FORMAT value remain part +`vcfc:encodedValues` uses `vcfc:VCFTextVector`: one tab-separated lexical item +per sample in `vcfc:sampleIndex` order. Commas inside a FORMAT value remain part of that item, and absent values are emitted as `.` so all vectors stay aligned. Consumers reconstruct sample `i`'s value for a FORMAT key by selecting position `i` from its vector. This changes genotype graph growth to approximately @@ -843,6 +887,23 @@ finishes. - default rules file: `rules/default_rules.ttl` - rules guide: `rules/README.md` +### Data linking plug-ins + +Three installed examples cover declarative dbSNP links (`rsid-dbsnp`), interval +joins against a synthetic GFF3 bundle (`gene-demo`), and an Ensembl API resolver +(`rsid-ensembl`). Add `--link ` in full mode, or link an existing aggregate +without Docker: + +```bash +vcf-rdfizer --mode link --rdf ./results/sample/sample.nt.gz \ + --link rsid-dbsnp --offline -o ./linked-results +``` + +Links go into `sample.links.nt`; the base graph is unchanged. The +`vcf-rdfizer-link` companion CLI lists, scaffolds, checks and previews plug-ins. +See [Data linking](docs/datalinking.md) for all three worked examples, reference +and network safeguards, provenance, and the remaining design limitations. + ### Custom RML Mappings `--rules` accepts any RML mapping, so you can change what RDF the pipeline @@ -924,6 +985,8 @@ launches Docker, and reads back the JSON/CSV reports each stage writes. | --- | --- | | `vcf_rdfizer.py` | Host CLI: argument validation, output-collision planning, Docker orchestration, metrics assembly, mode dispatch. Also emits the multi-sample genotype RDF (see below). | | `vcf_rdfizer_rules.py` | `vcf-rdfizer-rules` CLI: scaffold, document, and validate custom RML mappings. | +| `vcf_rdfizer_link.py`, `vcf_rdfizer_linking/` | Linker authoring CLI and shared token/interval/API runner. | +| `vcf_rdfizer_data/linkers/` | Packaged examples of all three plug-in tiers. | | `vcf_rdfizer_gzip.py` | Uncompressed size of a gzip/BGZF VCF without decompressing it. Used by the host preflight estimate and, inside the image, by `run_conversion.sh`. | | `src/vcf_as_tsv.sh` | VCF -> per-input `records`/`header_lines`/`file_metadata` TSV, in one `awk` pass. | | `src/run_conversion.sh` | Runs RMLStreamer, normalizes Spark part files, merges them into one `.nt`/`.nt.gz` aggregate, records conversion metrics. | @@ -959,7 +1022,8 @@ how each part of the tool works, why, and where it stops working. | [CLI reference](docs/cli-reference.md) | Every flag, with constraints and interactions | | [Limitations](docs/limitations.md) | Everything the tool cannot do, in one place | | [Roadmap](docs/roadmap.md) | Planned work, known defects, and rejected options | -| [Data linking design](docs/datalinking-design.md) | Proposal: a plug-in system for external links | +| [Data linking](docs/datalinking.md) | Runnable examples of all three plug-in tiers, authoring, safeguards, and provenance | +| [Data linking design](docs/datalinking-design.md) | Broader proposal and remaining work | | [Privacy policy design](docs/privacy-policy-design.md) | Proposal: ODRL-based granular disclosure control over the graph | - [`changelog.md`](changelog.md) - dated change history diff --git a/changelog.md b/changelog.md index a2621a0..0c79420 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,421 @@ # Changelog +## 2026-09-08 — Verify against the published VCF Core 2.0.0 + +VCF Core is published at **2.0.0**, covering VCF 4.1 through 4.5. This checks +the converter against the released artifacts and closes the gap that made the +version model a private assumption. + +### Fixed + +- **A bracketed CHROM now links to its assembly contig.** VCF 4.5 lets CHROM + name a breakpoint-assembly contig in angle brackets (``) instead of a + declared reference sequence. The converter emitted only the raw `vcfc:chrom` + literal, which the published consistency profile rejects: a bracketed CHROM + must resolve to a `vcfc:AssemblyContig` whose `vcfc:assemblyContigId` matches + the bracketed text, and must *not* also name a declared `##contig`. The + record now carries `vcfc:chromAssemblyContig`, and the contig resource cites + the `##assembly` header line with `vcfc:declaredInAssembly`. + + Found by validating against the vocabulary's new `example-vcf45-boundaries` + fixture; the emitted IRIs and properties match its reference graph exactly. + +### Added + +- **The version model is cross-checked against the vocabulary's own registry.** + VCF Core publishes `ontology/versions/registry.json` as the single source of + truth for its version-scoped artifacts — the SHACL overlays, the reserved-key + snapshots and the `VCF4xFile` classes are generated from it. The converter + keeps a dependency-free copy of the same facts so it runs without the + vocabulary checked out; + `test_version_model_matches_the_published_registry` now pins the two together, + field by field: supported versions, `code`, `className`, + `leadingPhaseIndicator`, `svTupleScope`, the INFO/FORMAT `numberCodes`, and + the flattened-tuple keys and widths. It skips when no vocabulary checkout is + present; `VCF_CORE_VOCABULARY_DIR` points it at one. + + The two agree exactly as published — no drift to fix — but a new VCF version + or a corrected arity can no longer land on one side alone. + +- **`vcf_version` and `vcf_version_source` in the conversion metrics**, in both + `metrics.csv` and `stages/conversion/*.json`. The source is `declared`, + `forced` or `fallback`. Benchmarks need these to group runs: the version + selects the SHACL overlay, the tuple semantics and which FORMAT families + exist, so cost and graph size are not comparable across versions without + them. `metrics_layout_version` is now `3`. + +### Verified + +- Every VCF version resolves end to end: detection from `##fileformat`, the + correct `vcfc:VCF4xFile` on the file subject, the sentinel never left + unresolved, TSV paths rewritten, and `--vcf-version` overriding cleanly. + VCF 4.0, a missing declaration and a malformed one all fall back to the + newest supported rules with no version class, and say so. +- `--vcf-version` accepts exactly the versions the registry declares. +- The vocabulary's own example VCFs now include `example-vcf45-boundaries`, and + `example-condensed-cohort` declares VCFv4.1; both convert correctly. + +### Documentation + +- **`vcf-coverage.md` records the term-coverage delta.** VCF Core 2.0.0 defines + 338 terms; ten families are entirely unemitted — parsed FILTER, padding + semantics, parsed FORMAT keys, parsed record IDs, repeat units, breakend + mates, local-allele membership, mixed phasing, reference-block links, and + raw/decoded value pairs. None is required for conformance, and the table says + which kinds of benchmark the gap does and does not affect. +- `limitations.md` no longer lists the condensed terms, the `ALT=.` shape + contradiction or the ordinal datatype disagreement: all three are resolved in + the published release. What remains is VCF 4.0 having no overlay, and the + version table being a checked copy rather than the original. + +## 2026-09-07 — Stop a slow validation engine from looking like a hang + +A full run with `--validate` on a real cohort VCF spent 62 hours on its first +validation step. The cause was not a deadlock: it was three defects that +compound into one. + +### Fixed + +- **A timed-out query no longer costs one timeout for every remaining query.** + The per-query timeout defaults to 3600s and there are 27 queries per engine + per target, so one engine that cannot answer the graph burned **27 hours per + target** — the loop ran every query and only checked for failures afterwards. + It now stops at the first timeout, records which query tripped it and how many + were skipped, and moves on to the next engine. `--validation-continue-after-` + `query-timeout` restores the old behaviour. +- **A timed-out query no longer orphans its engine process.** Queries are + wrapped in `/usr/bin/time`, which forks the real engine. + `subprocess.run(timeout=)` signals only the process it started, so killing the + wrapper left the engine running — holding the entire graph in memory, because + that is what an in-memory SPARQL engine does. Twenty-seven of those is enough + to push a host into swap, which is what turned a slow step into an apparent + hang. Queries now run in their own session and the whole process group is + signalled, SIGTERM then SIGKILL. +- **The validation results mount is resolved.** Docker reads a relative bind + source as a *named volume*, so an unresolved path would have sent the reports + into a volume instead of onto the host. Every other mount in that command was + already resolved. + +### Added + +- **`--validation-time-budget`** (seconds, 0 = no ceiling, the default): a + wall-clock ceiling for one engine's whole query set. A backstop for queries + that are slow but never individually time out. +- **An up-front warning when an unindexed engine meets a large graph.** Comunica + has no persistent index: every query re-parses the whole source into memory, + so the cost is paid 27 times. Above 4 GiB the run now says so before + committing, states the worst-case hours at the current timeout, and points at + `--engine qlever` or `--validation-targets hdt`. This is the asymmetry behind + "QLever passed, Comunica did not": QLever builds an index once and answers + from it. +- **`summary.json` now carries a `validation` index.** Each target's stage + report, results directory, summary, benchmark JSON/CSV and the engines that + ran are named explicitly, with status, engine and wall time, instead of being + left to find among the report globs. + +## 2026-09-07 — Migrate the validation suite to VCF Core + +The conversion moved to VCF Core and became version-aware; the validation suite +still described the previous graph, so 31 of its tests failed. It now passes, +with its design intact: one declarative fixture deriving three artifacts, +coverage measured by mutation rather than asserted, and expectations derived +from the VCF rather than from the mapping. + +**415 tests pass.** Mutation score: **96/113 (85%)** across 60 mutations, up +from 42. + +### Fixed + +- **Every declared INFO and FORMAT definition was emitted twice.** The header + emitter produced a declaration's `fieldId`/`fieldNumber`/`fieldType`/ + `fieldDescription` from the `##` line, and the value emitters produced the + same four triples at the same header-line IRI when the key was first used. + The header emitter now owns any declaration derived from a `##` line; the + value emitters cite it with `vcfc:declaredBy` and invent a definition only for + a key no header declared. + + This is worth noting for what caught it: `preflight_duplicate_triples`, which + compares the parsed triple count against the distinct count. No SHACL shape + can express that — a duplicate triple is not a distinct RDF statement, so the + graph validated cleanly with the duplicates present. + +### Changed + +- **The runner and the wrapper share one vocabulary module.** + `validation_runner.py` carried its own copies of `HEADER_LINE_CLASSES`, + `rml_uri_component`, `parse_structured_header_fields` and + `parse_info_entries`, with unit tests asserting the copies stayed identical. + Both now import `vcf_rdfizer_vocab`, which the `Dockerfile` copies next to the + runner. The drift the tests policed is removed rather than policed. +- **The census derives every new resource family from the VCF.** Two shared + functions, `emitted_header_counters` and `emitted_record_counters`, are called + by the container's `parse_vcf` and by the fixture's `parser_summary`, so the + two oracles cannot disagree. They cover the header attributes, the allele + layer, the `vcfc:FieldValueItem` decomposition, the breakend components and + the parsed genotype layer. `parse_vcf` stays representation-independent; the + genotype counters are reported separately and merged for the expanded profile + only. +- **`base_triples()` tracks the new mapping**: the version class, the + `#CHROM` column-header line, `vcfc:lineIndex` and `vcfc:recordIndex` in, and + `ID`/`ALT`/`FILTER`/`infoRaw` out — those moved to the wrapper's emitter + because each may be the VCF missing token. +- **The fixture derives its expected version class** from its own declared + `FILE_FORMAT`, so changing that changes the expected graph with it. + +### Added + +- **18 mutations** for the layers VCF Core introduced: the version class, header + attributes, the allele layer, indexed values, reusable sample identity, the + parsed genotype layer and field-declaration ownership. Ten are recorded as + undetected, each naming what would close it — the score fell from 97% to 85% + because the denominator grew, which is the methodology working rather than a + regression. +- **`corrupt_sample_index` is split by profile**, because the same corruption is + detected in the condensed profile and not the expanded one. In the condensed + profile the ordinal associates a vector position with a sample, so corrupting + it moves genotypes between samples; in the expanded profile each `SampleCall` + carries its own `vcfc:sampleId` and nothing reads the ordinal. A real + difference in what the two profiles depend on, now recorded as such. +- Census tests asserting that every new family is in the inventory, and that the + genotype layer appears in the expanded census and *not* in the condensed one. + +## 2026-09-07 — Version-aware conversion for VCF 4.1 through 4.5 + +VCF Core gained a SHACL overlay per VCF version, each scoped by the file's +`vcfc:fileFormat`, plus optional `vcfc:VCF41File`…`vcfc:VCF45File` classes that +activate those gates. Three things the converter emits genuinely differ between +versions, so the conversion now follows the version of each input instead of +assuming 4.5. + +### Added + +- **Automatic version detection, per input.** `##fileformat` is required to be + the first line of a conforming VCF and `src/vcf_as_tsv.sh` already lifts it + into `file_metadata.tsv`, so detection costs one small read and needs nothing + from the user. It is per input rather than per run, so a directory of mixed + versions converts correctly. The run log states the version and how it was + chosen. +- **`--vcf-version {auto,4.1,…,4.5}`**, defaulting to `auto`. An explicit + version is an override for a file whose declaration is missing or wrong, and + the log says when the file's own declaration was overridden. +- **A version sentinel in the RML mapping.** `<#VCFFileMap>`'s subject map + carries `rr:class vcfc:VCFVersionFile`, which `render_rules_for_triplet` + rewrites per input — the same mechanism that already rewrites the five + `csvw:url` paths — to the `vcfc:VCF4xFile` subclass for that input's version. + One mapping stays the single source of truth for all five versions instead of + five near-identical copies that would drift apart. `vcf-rdfizer-rules check` + reports whether a custom mapping has the sentinel. +- **A `VCFVersion` model** in `vcf_rdfizer_vocab.py` carrying, per version, the + permitted Number codes, the flattened-tuple keys and their widths, whether + tuples repeat per ALT allele, and whether the local-allele, base-modification, + EVENTTYPE and leading-phase-indicator features exist. + +### Changed + +- **`CIPOS`/`CIEND` tuple semantics follow the version.** Before VCF 4.4 the + list is one pair describing the record, so its `vcfc:FieldValueItem`s carry an + index and a `vcfc:tupleArity` but no `vcfc:forAllele`, and every ALT allele of + a multi-allelic record shares the interval. From 4.4 the list repeats per ALT + and each item joins its own allele. `CILEN` and `CICN` are only tuple keys + from 4.4. +- **`EVENT` follows the version.** It is `Number=1` before 4.4 — one event for + the record — and `Number=A` from 4.4, one per ALT allele, so the `vcfc:inEvent` + link moved onto the allele there. `EVENTTYPE` does not exist before 4.4, and + `vcfc:VariantEventShape` requires an event type, so a pre-4.4 EVENT stays an + ordinary INFO value. +- **Families a version does not define are no longer invented.** A `LAA` column + in a 4.4 file, or an `M27551C` column in a 4.3 file, keeps its raw + `vcfc:fieldValue` and gets no `vcfc:LocalAlleleSet` or `vcfc:BaseModification` + resource. +- **VCF 4.0 is reported as unrecognized.** VCF Core claims no 4.0 overlay, so a + 4.0 file converts with the newest supported rules — nothing representable is + dropped — but emits no version class, so the graph never claims a gate that + cannot be checked. A missing or malformed `##fileformat` line behaves the + same. All three are reported, never assumed silently. + +Parsing leniency is deliberately unchanged: a GT with a leading phase indicator +in a 4.1 file is still parsed, and the version overlay reports it. The converter +transcribes; the validator judges. + +### Fixed + +Two defects found by validating against the new complete profile set: + +- **Flattened tuple keys were never decomposed.** `CIPOS` and friends are + declared `Number=.` in 4.4/4.5, which on its own says "no positional + meaning", so no `vcfc:FieldValueItem`s were emitted — but the version overlays + count those items against the ALT count. Tuple keys are now positional by + virtue of being tuple keys, whatever their declared Number. +- **Confidence-interval bounds were plain strings.** `vcfc:ciLower`/`ciUpper` + and the FALDO `begin`/`end` go through `vcfc:NumericLiteralShape`, which + requires an integer- or decimal-derived datatype. +- **A sites-only VCF got no representation profile.** Both sample emitters + returned early when the file declared no sample columns, so a VCF with only + the eight fixed columns violated `vcfc:RepresentationProfileShape`, which + requires exactly one profile on every `vcfc:VCFFile`. The profile is now + emitted regardless; the `vcfc:SampleSet` is still omitted, because + `vcfc:SampleSetShape` requires at least one member. + +### Verified + +Zero violations across 19 graphs against the **complete** profile set — the +portable, SPARQL and consistency profiles plus all five version overlays — run +with pySHACL using the bundled ontology plus every `ontology/versions/*.ttl` +and RDFS inference, which is the configuration the vocabulary's own +`tests/validate_shacl.py` uses. Inputs were all ten of the vocabulary +repository's example VCFs (4.1 through 4.5, including the breakend, gVCF, repeat +and condensed-cohort fixtures) and a hand-written stress file rendered for every +version plus a 4.0 variant, in both representation profiles. + +### Note on the vocabulary's own version number + +The vocabulary is now `owl:versionInfo "2.0.0"` with +`owl:versionIRI `, which matches the +v2.0.0 originally requested — it read 4.0.0 when the migration started. This +converter pins no version IRI, referencing only the namespace, so nothing here +needed changing and nothing goes stale. + +## 2026-09-07 — Retarget the conversion to the VCF Core vocabulary + +The conversion produced RDF in `https://w3id.org/vcf-rdfizer/vocab#`. That +namespace is retired: the vocabulary was renamed **VCF Core** and moved to +`https://w3id.org/vcf-core/vocab#` (prefix `vcfc:`), because it is a semantic +target any conversion system can adopt and its name should not carry the name of +one converter. The old namespace is **not** redirected — it serves a deprecation +document linking every former term to its successor — so this is a breaking +change to the emitted graph. + +VCF Core also models considerably more of VCF 4.5 than its predecessor. The +mapping rules and the wrapper's emitters were rewritten to cover it rather than +only re-prefixed. + +### Changed + +- **Namespace.** Every emitted IRI moves from `vcfr:` to `vcfc:`. One term was + renamed rather than re-namespaced: `vcfr:DenseRepresentation` is now + `vcfc:ExpandedRepresentation`. No version IRI is pinned anywhere — the + converter targets the namespace, and the vocabulary's release line is + independent of this one's. +- **The RML/wrapper split is now one rule**, stated in the mapping's header and + in [`architecture.md`](docs/architecture.md#4-where-the-split-leaks-and-why): + *RML carries every field whose RDF datatype is the same for every row; the + wrapper carries everything else.* Accordingly `ID`, `ALT`, `FILTER` and + `infoRaw` moved out of the mapping and into `emit_record_detail`, joining + `QUAL` and `fileDate`. Each may be the VCF missing token, which the vocabulary + requires as `"."^^vcfc:Null`, and RML cannot switch an object's datatype per + row. `CHROM`, `POS` and `REF` stay in the mapping precisely because VCF 4.5 + forbids them from being missing. +- **Ordinals are serialized `xsd:integer`, not `xsd:positiveInteger`.** The + SHACL profiles constrain every ordinal with `sh:datatype xsd:integer` and that + constraint compares the datatype IRI exactly, so an `xsd:positiveInteger` + literal fails the shape while an `xsd:integer` literal satisfies both the shape + and the ontology's declared range. This affects `vcfc:sampleIndex`, which the + condensed emitter previously typed `xsd:positiveInteger`. +- **`--header-representation basic` no longer produces a conformant graph.** + `vcfc:StructuredHeaderLineShape` requires at least one `vcfc:hasAttribute` on + every structured header line, and `basic` emits no subclass and no attributes. + It remains available as the smallest, fastest header form. +- **QUAL accepts the full VCF Float lexical space.** `INF`, `INFINITY` and `NAN` + in any case are emitted as `vcfc:VCFFloat` rather than coerced or flattened to + a plain literal; a finite value still takes `xsd:decimal` in its source lexical + form. + +### Added + +- **`vcf_rdfizer_vocab.py`** — the vocabulary terms and the VCF 4.5 parsers, as + pure functions so they are testable without producing RDF: allele + classification, breakend parsing, GT parsing, `Number` arity resolution, value- + item indexing, and base-modification key recognition. +- **Header layer.** Ordered `vcfc:HeaderAttribute` resources on every structured + line; `##assembly`, `##pedigreeDB`, `##META`, `##SAMPLE` and `##PEDIGREE` typed + and decomposed; `vcfc:ColumnHeaderLine` for `#CHROM` with + `vcfc:hasGenotypeColumns`; `vcfc:lineIndex` and `vcfc:recordIndex` for the + ordering constraints the SPARQL SHACL profile checks; `vcfc:fieldArity` and + `vcfc:fieldNumberInteger`; `fieldSource`/`fieldVersion`; typed contig `length` + and `URL`. An unrecognised `##` key is now typed as structured or unstructured + by the form of its value rather than left bare. +- **Allele layer.** `REF` and each `ALT` item become ordered + `vcfc:ReferenceAllele`/`vcfc:AltAllele` resources with `alleleIndex`, + `alleleValue` and `alleleKind`; symbolic alleles are linked to their `##ALT` + declaration and given a `vcfc:svType` where the ID is a reserved code; + breakends are parsed into orientation, replacement string and mate position; + records are linked to their contig declaration with `vcfc:chromosome`. +- **Value items.** `Number=A/R/LA/LR/G/LG/P` values are decomposed into ordered + `vcfc:FieldValueItem` resources joined to their allele with `vcfc:forAllele`, + with `vcfc:tupleArity` for the keys that flatten fixed-width tuples. This + closes the multi-valued-INFO gap previously recorded in `limitations.md`. +- **Structural variation.** `SVLEN`, `SVCLAIM`, `IMPRECISE`, `NOVEL`, `END`, + `EVENT`+`EVENTTYPE`, the `CI*` confidence intervals (FALDO `InRangePosition` + for `CIPOS`/`CIEND`), the `RN`/`RUS`/`RUL`/`RUC`/`RB` tandem-repeat structure, + and gVCF `<*>` reference blocks. +- **Genotype layer, expanded profile only.** `GT` parsed into a `vcfc:Genotype` + with `genotypeString`, `ploidy`, an explicit `vcfc:phasingStatus` and one + `vcfc:GenotypeAlleleCall` per position; plus `FT`, `PS`/`PSL`/`PSO`/`PSQ`, + `LAA`, the copy-number and haplotype keys, and the `M`/`DPM`/`ADM` + base-modification families with their ChEBI residue. The condensed profile + deliberately keeps these inside its vectors — deriving them per sample is the + materialization that profile exists to avoid. +- **Reusable sample identity in both profiles.** `vcfc:SampleSet` and its ordered + `vcfc:VCFSample` members are emitted in expanded mode too, and a `SampleCall` + links to its column with `vcfc:forSample`. It costs one resource per sample + column for the whole file. +- `docs/validation-migration-notes.md` — what the migration leaves to do in the + validation suite, and how the converter's SHACL conformance was verified. + +### Fixed + +- The condensed emitter omitted `vcfc:fieldType` on its `FormatFieldDefinition` + resources, which `vcfc:FormatFieldDefinitionShape` requires. Condensed graphs + were therefore non-conformant. +- Four modelling bugs found by running the vocabulary's SHACL profiles against + the output, all the same shape: a resource typed into a class whose shape + requires a property the record did not supply. `<*>` was typed + `vcfc:ReferenceBlock` without `referenceBlockLength`; `` was typed + `vcfc:TandemRepeatAllele` without `repeatSequenceCount`; `EVENT` minted a + `vcfc:VariantEvent` without `eventType`; and emitting `vcfc:endPosition` on a + symbolic SV allele made RDFS infer `vcfc:ReferenceBlock` for it. Each carrier + is now emitted only when the record supplies everything its shape needs. + +### Verified + +The output validates against both published SHACL profiles — +`vcf-core-vocabulary.shacl.ttl` and `vcf-core-vocabulary-sparql.shacl.ttl` — +with **zero violations**, in both representation profiles, run with pySHACL +using the bundled ontology and RDFS inference. Inputs were the vocabulary's own +`examples/example.vcf` and a VCF 4.5 stress file covering structured headers, +symbolic and breakend ALTs, tandem repeats, a gVCF reference block, +`Number=A/R/G` fields, phased GT with a phase set, `LAA`, `FT`, `CN` and a base +modification. + +### Known broken + +The validation suite was migrated separately; see the entry above it. At the +time of this change 31 of its tests failed because they asserted against the +retired namespace and the previous emitted shape. + +## 2026-09-06 — Runnable examples of all three data-linking tiers + +### Added + +- `rsid-dbsnp` declarative token links, `gene-demo` with a digest-pinned + synthetic GFF3 bundle, and a batched `rsid-ensembl` live resolver. +- A shared host-side runner with Turtle manifests, directory/entry-point + discovery, disk-backed key deduplication, interval joins, assembly refusal, + atomic side-graphs, provenance and per-linker run metrics. +- `--link` in full mode; Docker-free `--mode link --rdf`; and + `vcf-rdfizer-link list|keys|init|check|dry-run|run` authoring commands. +- Cached HTTPS sessions with per-host pacing, per-run request ceilings, + retries respecting `Retry-After`, offline replay and contact headers. +- Known-answer and failure tests for the three examples and their shared + runtime. The live resolver is tested using fake HTTP, not a public API. + +### Changed + +- RDFLib is now a runtime dependency for Turtle/N-Triples parsing. +- The [implementation guide](docs/datalinking.md) documents commands and + limitations; the original proposal is marked partially implemented. Allele + normalization, link merging and plug-in validation discovery remain planned. + ## 2026-09-04 — Multi-engine validation, native HDT/COTTAS querying, and benchmarking Validation was one engine against one N-Triples file. It is now up to four @@ -213,14 +629,14 @@ VCF contains. Mutation score **64/66 -> 76/78**, catalogue 36 -> 42 mutations. ### Added - `preflight_blank_nodes` — any blank node, in subject or object position. Every - class in the vocabulary declares an `vcfr:iriTemplate`, so a blank node means + class in the vocabulary declares an `vcfc:iriTemplate`, so a blank node means a term map produced no IRI; the record and value digests could not address such a node, and neither could anything that later merges the graph. A predicate cannot be blank in RDF, so it is not examined. - `preflight_empty_values` — empty or whitespace-only literals and IRIs, each labelled `EMPTY_LITERAL` or `EMPTY_IRI` in the sample. An empty literal means a value was lost rather than marked missing (the pipeline writes - `"."^^vcfr:Null` for a genuine missing token); an empty IRI means a template + `"."^^vcfc:Null` for a genuine missing token); an empty IRI means a template substitution collapsed. Whitespace-only counts as empty: it carries no more information and is just as certainly a defect. - `preflight_duplicate_triples` — the same statement emitted more than once. @@ -279,10 +695,10 @@ Phases 2-6 of the validation-coverage plan. Mutation score **29/45 -> 64/66** ### Fixed — silent data loss - **QUAL was extracted from every VCF and never mapped into RDF.** It is now - emitted, typed `xsd:decimal` or `"."^^vcfr:Null` as the published SHACL shape + emitted, typed `xsd:decimal` or `"."^^vcfc:Null` as the published SHACL shape requires. RML cannot choose a datatype per row, so it comes from a new record-detail emitter rather than `default_rules.ttl`. -- **`##fileDate` was never mapped.** Now emitted as `vcfr:fileDate`, typed +- **`##fileDate` was never mapped.** Now emitted as `vcfc:fileDate`, typed `xsd:date` when the value's form allows and lexically otherwise. ### Added — completeness (Phase 2) @@ -310,11 +726,11 @@ Phases 2-6 of the validation-coverage plan. Mutation score **29/45 -> 64/66** ### Added — structured INFO (Phase 4) - `--info-representation {structured,raw}`, default `structured`: one - `vcfr:InfoFieldValue` per record and key at the vocabulary's declared IRI - template, linked by `vcfr:declaredBy` to an `InfoFieldDefinition` carrying + `vcfc:InfoFieldValue` per record and key at the vocabulary's declared IRI + template, linked by `vcfc:declaredBy` to an `InfoFieldDefinition` carrying `fieldId`/`fieldNumber`/`fieldType`/`fieldDescription`. Single-valued Integer/Float fields also get `fieldValueInteger`/`fieldValueDecimal`; a Flag - gets `fieldValueBoolean true`. `vcfr:infoRaw` is retained. + gets `fieldValueBoolean true`. `vcfc:infoRaw` is retained. - The model was already fully defined in the vocabulary and simply unused. ### Added — header section (Phase 5) @@ -334,8 +750,8 @@ Phases 2-6 of the validation-coverage plan. Mutation score **29/45 -> 64/66** as a conformance failure. - It found three violations the other layers could not see. Two are fixed above. The third is a **contradiction inside the published vocabulary**: - `vcfr:missingValuePolicy` says a missing token SHOULD be `"."^^vcfr:Null`, - while `VCFRecordShape` constrains `vcfr:alt` to `xsd:string`, so a record with + `vcfc:missingValuePolicy` says a missing token SHOULD be `"."^^vcfc:Null`, + while `VCFRecordShape` constrains `vcfc:alt` to `xsd:string`, so a record with `ALT=.` cannot satisfy both. Recorded in `docs/vcf-coverage.md` for a decision in the vocabulary repository. @@ -682,7 +1098,7 @@ and for both `run_conversion.sh` storage modes. line-by-line. - `run()` discards subprocess output at the file-descriptor level instead of buffering a whole container's output in memory only to drop it. -- `run_conversion.sh`: the `"."` -> `"."^^vcfr:Null` rewrite is now applied to +- `run_conversion.sh`: the `"."` -> `"."^^vcfc:Null` rewrite is now applied to each RMLStreamer part while it is streamed into the aggregate, instead of as a separate pass over the finished aggregate. This removes one full read and one full write of the complete RDF output, and removes the transient @@ -764,7 +1180,7 @@ and for both `run_conversion.sh` storage modes. - Updated the CLI default and accepted values, internal workflow/emitter names, tests, RML comments, and user documentation. - The emitted profile IRI is now - `vcfr:representationProfile vcfr:ExpandedRepresentation`. + `vcfc:representationProfile vcfc:ExpandedRepresentation`. ## 2026-09-04 — Input-labelled, container-complete metrics layout diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 5cd1663..5a8aaf6 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -15,6 +15,7 @@ build: script: {{ PYTHON }} -m pip install . -vv entry_points: - vcf-rdfizer=vcf_rdfizer:main + - vcf-rdfizer-link=vcf_rdfizer_link:main requirements: host: @@ -25,14 +26,20 @@ requirements: run: - python >={{ python_min }} - rich >=13.7.0 + - rdflib >=7.0.0 test: requires: - python {{ python_min }} commands: - vcf-rdfizer --help + - vcf-rdfizer-link list imports: - vcf_rdfizer + # The vocabulary terms, VCF-version model and lexical parsers. Importing it + # here catches a packaging miss that would otherwise only surface at + # conversion time, since vcf_rdfizer imports it at module load. + - vcf_rdfizer_vocab about: home: https://github.com/ecrum19/VCF-RDFizer diff --git a/docs/README.md b/docs/README.md index 6cabb44..070c10d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -45,10 +45,10 @@ deciding whether the tool fits your problem, read - **[Custom RML mappings](rml-mappings.md)** — the `--rules` contract, the `vcf-rdfizer-rules` CLI, and an honest account of what a custom mapping does *not* control and what it costs in validation. -- **[Data linking design](datalinking-design.md)** — *proposal, not - implemented.* A plug-in architecture for connecting the graph to external - resources (rsIDs, genes, clinical assertions) with declarative linkers, - reference bundles, live-API safeguards, and provenance. +- **[Data linking](datalinking.md)** — three runnable plug-in tiers, full and + post-hoc usage, the authoring CLI, reference/assembly checks, network policy, + provenance, and measured implementation limits. The broader + **[design](datalinking-design.md)** records what remains planned. - **[Privacy policy design](privacy-policy-design.md)** — *proposal, not implemented.* Granular, machine-readable disclosure control over parts of the graph: an ODRL profile with graph selectors, three enforcement tiers, and @@ -62,7 +62,7 @@ deciding whether the tool fits your problem, read and an assessment of query-time decoding options. - **[VCF coverage matrix](vcf-coverage.md)** — element by element: is it represented, and would a corruption of it be detected. Includes the current - mutation score and the vocabulary alignment gaps. + mutation score and the vocabulary alignment status. ### Whether to trust it @@ -72,6 +72,9 @@ deciding whether the tool fits your problem, read - **[Validation methodology](validation-methodology.md)** — how coverage is *measured* rather than asserted: the mutation-testing harness, why known gaps are assertions rather than comments, and how to reproduce the score. +- **[Validation migration notes](validation-migration-notes.md)** — what the + move to the VCF Core vocabulary leaves to do in the validation suite, and how + the converter's SHACL conformance was verified in the meantime. ### Where it is going @@ -98,7 +101,7 @@ deciding whether the tool fits your problem, read [Custom RML mappings](rml-mappings.md) **"I want to add my own domain's links."** -[Data linking design](datalinking-design.md) → +[Data linking](datalinking.md) → [Data linking design](datalinking-design.md) → [Custom RML mappings](rml-mappings.md) → [Validation methodology](validation-methodology.md) diff --git a/docs/architecture.md b/docs/architecture.md index 1932b1f..2e84081 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -24,6 +24,7 @@ writes. ├─ docker run ────────────────────▶ src/vcf_as_tsv.sh (awk) │ src/run_conversion.sh (RMLStreamer/Flink) ├─ append direct RDF (see §4) + ├─ optional host-side linking ─────▶ .links.nt (separate side-graph) ├─ docker run ────────────────────▶ src/partitioned_compression.py │ src/cottas_tool.py │ src/ensure_hdt_index.sh @@ -37,8 +38,10 @@ awkward dependencies — RMLStreamer 2.5.0 on Flink, a Rust `hdtc` 1.1.0 build, `pycottas`, Comunica 5.3.0, QLever, `pyshacl`, `cyvcf2`, `bcftools`. Asking a user to assemble that on their own machine is asking for irreproducible results. Pinning it in one image means a run on a laptop and a run on a cluster execute -the same binaries. The price is that **Docker is a hard requirement** and the -image is large; see [`limitations.md`](limitations.md). +the same binaries. The price is that **Docker is a hard requirement for +conversion and representation operations** and the image is large; see +[`limitations.md`](limitations.md). Post-hoc linking and the authoring CLIs +run entirely on the host. ## 2. Host responsibilities @@ -52,6 +55,7 @@ image is large; see [`limitations.md`](limitations.md). | Progress rendering | Containers write a JSONL sidecar; the host polls and renders it | | Metrics assembly | Every stage's JSON is collected into one `run_metrics/` tree | | Interrupt handling | `Ctrl+C` triggers best-effort cleanup of tracked intermediates | +| Optional data linking | Python plug-ins, reference/response caches and an atomic side-graph share one host runner for full and post-hoc mode | ## 3. Container responsibilities @@ -67,16 +71,32 @@ image is large; see [`limitations.md`](limitations.md). ## 4. Where the split leaks, and why -The design intent is "all data processing happens in the container". There are -**three deliberate exceptions**, all in `vcf_rdfizer.py`, all appending directly +The conversion design intent is "all data processing happens in the container". +There are **three direct-emission exceptions**, all in `vcf_rdfizer.py`, appending directly to the RDF aggregate between the conversion container and the compression -container: +container. + +One rule decides what goes where: + +> **The RML mapping carries every field whose RDF datatype is the same for every +> row. The wrapper carries everything else.** + +Two kinds of field fall on the wrapper's side. A value that may be the VCF +missing token `.` needs `"."^^vcfc:Null` on some rows and a typed literal on +others, and RML cannot switch an object's datatype per row. A value that has to +be decomposed into several resources would need a materialized helper table +whose size is the product of its dimensions. | Emitter | Emits | Why not RML | | --- | --- | --- | -| `emit_sample_representation` | `SampleCall`/`FormatFieldValue`, or `SampleSet`/`CohortCallMatrix`/`FormatValueVector` | RML would first have to materialize a helper table of variants × samples (× FORMAT keys) — the largest intermediate the pipeline can produce | -| `append_header_representation_rdf` | Header-line subclasses, FILTER/ALT/contig attributes, INFO/FORMAT declarations | RML cannot choose a class per row from a parsed attribute string | -| `emit_record_detail` | `QUAL` (typed per value) and structured `InfoFieldValue` nodes | RML cannot switch a literal's datatype based on a declared `Type`, and structured INFO would need a variants × INFO-keys helper table | +| `emit_sample_representation` | Expanded: `SampleCall`/`FormatFieldValue`/`Genotype`/`PhaseSet`/`LocalAlleleSet`/`BaseModification`. Condensed: `SampleSet`/`CohortCallMatrix`/`FormatValueVector`. `SampleSet` and `VCFSample` in both. | RML would first have to materialize a helper table of variants × samples (× FORMAT keys) — the largest intermediate the pipeline can produce | +| `append_header_representation_rdf` | Header-line subclasses, the ordered `HeaderAttribute` resources every structured line needs, and the INFO/FORMAT/FILTER/ALT/contig/META/SAMPLE/PEDIGREE declaration properties | RML cannot choose a class per row, nor decompose one angle-bracketed cell into an ordered set of resources | +| `emit_record_detail` | `ID`, `ALT`, `QUAL`, `FILTER`, `infoRaw` (each may be the missing token); the allele layer (`ReferenceAllele`/`AltAllele`, breakends, symbolic types); structured `InfoFieldValue` with its `FieldValueItem` decomposition; and the SV carriers | RML cannot type the missing token per row, cannot switch a literal's datatype on a declared `Type`, and the allele and value-item layers would need variants × alleles and variants × INFO-keys helper tables | + +The exception count did not change with the move to the VCF Core vocabulary, but +what each emitter covers grew considerably: the vocabulary models the VCF 4.5 +logical model in full, and almost all of the additions are decompositions of a +single source cell, which is exactly the category RML cannot express. This is worth stating plainly because it has consequences: @@ -92,6 +112,14 @@ This is worth stating plainly because it has consequences: `_append_rdf_atomically`, so an interrupted append does not leave a half-written aggregate. +Optional data linking is a separate host-side stage in `vcf_rdfizer_linking/`. +It reads the completed aggregate, stages only join fields/keys in SQLite, +resolves the selected plug-ins, and atomically publishes a side-graph. That +extra graph scan preserves actual subject identities and makes full and +post-hoc linking share exactly one implementation. The reference interval +index lives in memory; HTTP and reference bytes are cached on disk. See +[`datalinking.md`](datalinking.md) for this extension's limits. + ## 5. Data flow in full mode ```text @@ -105,6 +133,8 @@ This is worth stating plainly because it has consequences: │ host-side direct emitters (§4) append in place ▼ complete aggregate + │ optional: --link (host-side; aggregate unchanged) + ├──────────────▶ .links.nt │ optional: --rdf-compression gzip,brotli ├──────────────▶ .nt.gz / .nt.br │ optional: --representations hdt,cottas (chunked) diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 9e3c716..a2df93b 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -5,8 +5,8 @@ the constraints that are enforced. `vcf-rdfizer --help` is the authority; this page adds the *why* and the interactions. Two companion CLIs are installed alongside: `vcf-rdfizer-rules` (see -[`rml-mappings.md`](rml-mappings.md)) and, once implemented, -`vcf-rdfizer-link` (see [`datalinking-design.md`](datalinking-design.md)). +[`rml-mappings.md`](rml-mappings.md)) and `vcf-rdfizer-link` (see +[`datalinking.md`](datalinking.md)). --- @@ -24,6 +24,7 @@ artifacts, run metrics and logs, and hidden intermediates all live beneath it. | `compress` | Compress an existing `.nt` / `.nt.gz` | `--rdf` | | `decompress` | Decode a compressed or indexed artifact back to N-Triples | `-C/--compressed-input` | | `validation` | Compare a source VCF against its RDF | `-i/--input` **and** `--rdf` | +| `link` | Write a side-graph from an existing `.nt` / `.nt.gz`, without Docker | `--rdf` **and** `--link` | | `index` | Regenerate an artifact's query index in place | exactly one of `-H/--hdt` or `--cottas` | ## Inputs and outputs @@ -31,7 +32,7 @@ artifacts, run metrics and logs, and hidden intermediates all live beneath it. | Flag | Meaning | | --- | --- | | `-i, --input` | VCF file or directory. Only `*.vcf` and `*.vcf.gz` are recognised; a directory is enumerated one level deep and snapshotted at run start | -| `--rdf` | RDF input for `compress`, or the artifact to check in `validation` | +| `--rdf` | RDF input for `compress`/`link`, or the artifact to check in `validation` | | `-C, --compressed-input` | `.nt.gz`, `.nt.br`, `.hdt`, `.cottas`, `.cottas.gz`, `.cottas.br` | | `-H, --hdt` / `--cottas` | Existing artifact for `--mode index` | | `-d, --decompress-out` | Explicit output `.nt` path; must be inside `--out` | @@ -46,6 +47,7 @@ artifacts, run metrics and logs, and hidden intermediates all live beneath it. | `--sample-representation` | `expanded`, `condensed` | `expanded` | Genotype graph shape | | `--info-representation` | `structured`, `raw` | `structured` | `structured` adds typed `InfoFieldValue` nodes alongside `infoRaw` | | `--header-representation` | `structured`, `basic` | `structured` | `structured` types each `##` line and lifts its attributes | +| `--vcf-version` | `auto`, `4.1`–`4.5` | `auto` | `auto` reads each input's `##fileformat` line; an explicit version overrides a missing or wrong declaration | There is **no automatic sample-count threshold**: the same command always produces the same graph shape, so a downstream consumer can rely on the contract @@ -54,6 +56,23 @@ it selected. QUAL is always emitted regardless of these options. `condensed` rejects a custom mapping that consumes the materialized sample helper tables, because that would emit both genotype representations at once. +## Data linking (`full` / `link`) + +| Flag | Meaning | +| --- | --- | +| `--link` | Comma-separated installed IDs; examples: `rsid-dbsnp`, `gene-demo`, `rsid-ensembl` | +| `--linker-path` | Additional linker directory or parent search directory; repeatable; also `VCF_RDFIZER_LINKER_PATH` | +| `--links-cache` | Reference/response cache; default `~/.cache/vcf-rdfizer/linkers` | +| `--offline` / `--links-cache-only` | Disable linker network access; require local reference bytes or cached responses | +| `--assembly` | Supply missing/unrecognised input assembly metadata; cannot override a recognised mismatch | +| `--links-contact-email` | Contact address for live resolver User-Agent headers | + +The side-graph is `.links.nt`. `gene-demo` contains synthetic intervals; +`rsid-ensembl` requires a real contact address before a live cache miss. The +companion CLI provides `list`, `keys`, `init`, `check`, `dry-run`, and `run`. +See [Data linking](datalinking.md) for commands and current limits. There is no +`--merge-links` in this initial implementation. + ## Compression plan | Flag | Values | Default | diff --git a/docs/conversion.md b/docs/conversion.md index 31d9d4c..2eda0bb 100644 --- a/docs/conversion.md +++ b/docs/conversion.md @@ -101,48 +101,106 @@ does not change the output, only how many parts are produced before the merge. Three classes of triple cannot come from RML, and are appended to the aggregate by the host process before compression. See [`architecture.md`](architecture.md#4-where-the-split-leaks-and-why) for why. +The rule is: **RML carries every field whose datatype is the same for every row; +the wrapper carries everything else** — anything that may be the missing token, +and anything that has to be decomposed out of a single source cell. -### `emit_record_detail` — QUAL and structured INFO +### `emit_record_detail` — the row-dependent fixed fields, alleles, INFO -`QUAL` is **always** emitted. The published SHACL shape is -`sh:or([sh:datatype xsd:decimal] [sh:datatype vcfr:Null])`, and RML cannot pick -a datatype per row: +Four fixed fields and the raw INFO string are **always** emitted here, because +each may be the VCF missing token and the vocabulary requires that as +`"."^^vcfc:Null`: + +| Field | Emitted as | +| --- | --- | +| `ID` | the lexical value, or `"."^^vcfc:Null` | +| `ALT` | the lexical value, or `"."^^vcfc:Null` | +| `FILTER` | the lexical value, or `"."^^vcfc:Null` | +| `INFO` (`vcfc:infoRaw`) | the lexical value, or `"."^^vcfc:Null` | +| `QUAL` | see below | + +`QUAL` has its own table because its shape is a disjunction over the whole VCF +Float lexical space: | QUAL value | Emitted as | | --- | --- | -| a number | `""^^xsd:decimal` — the source lexical form, so no precision is gained or lost | -| `.` or empty | `"."^^vcfr:Null` | +| a finite number | `""^^xsd:decimal` — the source lexical form, so no precision is gained or lost | +| `INF` / `INFINITY` / `NAN`, any case | `""^^vcfc:VCFFloat` — these are in the VCF Float lexical space but in no XSD numeric one | +| `.` or empty | `"."^^vcfc:Null` | | anything else | a plain string literal, deliberately kept rather than dropped, and reported by the SHACL layer | -`--info-representation structured` (the default) additionally emits one -`vcfr:InfoFieldValue` per record and key at -`…#call/{ROW_ID}/info/{KEY}`, linked to the `##INFO` declaration through -`vcfr:declaredBy`. A single-valued field (`Number=1`) whose declared `Type` is -`Integer` or `Float` also gets a typed `fieldValueInteger` / `fieldValueDecimal`; -a `Flag` gets `vcfr:fieldValueBoolean true`. A multi-valued field -(`Number=A/R/G/.`) keeps only the lexical value, because the vocabulary's IRI -template gives one node per key, not per value — a real modelling gap, recorded -in [`limitations.md`](limitations.md). - -`--info-representation raw` emits only the opaque `vcfr:infoRaw` string. +`--info-representation structured` (the default) additionally emits: + +- **The allele layer.** `REF` and each `ALT` item become an ordered + `vcfc:ReferenceAllele` / `vcfc:AltAllele` with `alleleIndex` (0 for REF, then + 1..n in source order), `alleleValue` and `alleleKind`. The kind is the VCF + syntactic category: a base sequence, the overlapping-deletion `*`, the missing + `.`, an angle-bracketed symbolic ID, the unspecified `<*>`/``, or a + breakend. A symbolic allele is joined to its `##ALT` declaration with + `declaredByAlt` and, when its ID is one of the reserved codes, given a + `vcfc:svType`. A breakend is parsed into its orientation, replacement string + and mate position. The record is also linked to the contig declaration its + `CHROM` names, with `vcfc:chromosome`. +- **Structured INFO.** One `vcfc:InfoFieldValue` per record and key at + `…#call/{ROW_ID}/info/{KEY}`, linked to the `##INFO` declaration through + `vcfc:declaredBy`. A single-valued field whose declared `Type` is `Integer` or + `Float` also gets a typed `fieldValueInteger` / `fieldValueDecimal`; a `Flag` + gets `vcfc:fieldValueBoolean true`. +- **Value items.** A field whose declared `Number` gives its positions meaning — + `A`, `R`, `LA`, `LR` (one per allele), `G`, `LG` (one per genotype), `P` (one + per GT allele) — is decomposed into ordered `vcfc:FieldValueItem` resources, + each joined to the allele it describes with `vcfc:forAllele`, or carrying its + genotype/GT ordinal. Keys that flatten fixed-width tuples (`CIPOS`, `MEINFO`, + …) record the width with `vcfc:tupleArity` so a consumer can regroup them. + This closes the multi-valued-INFO gap that earlier versions recorded in + `limitations.md`. +- **The SV carriers.** `SVLEN`, `SVCLAIM`, `IMPRECISE`, `NOVEL`, `END`, `EVENT` + with `EVENTTYPE`, the confidence intervals (`CIPOS`/`CIEND` through FALDO + `InRangePosition`, the rest as `vcfc:ConfidenceInterval`), and the + `RN`/`RUS`/`RUL`/`RUC`/`RB` tandem-repeat structure. + +Those carriers are emitted once per record, after the INFO values, rather than +key by key — several of them need more than one key to be well formed. A +`vcfc:VariantEvent` needs both `EVENT` and `EVENTTYPE`; a reference block needs +both `END` and `POS`; a tandem repeat needs `RN` before its repeat values have a +grouping. Where a record does not supply the whole set, the carrier is not +emitted and the values stay available as ordinary INFO values, rather than +producing a resource that would fail its SHACL shape. + +`--info-representation raw` emits only the opaque `vcfc:infoRaw` string, and +turns off the allele layer with it (the value items join to the alleles). ### `append_header_representation_rdf` — structured headers `--header-representation structured` (the default) types each `##` line with its -vocabulary subclass (`INFOHeaderLine`, `ContigHeaderLine`, `FilterDefinition`, -`AltDefinition`, …) and lifts the `` -attributes into their own properties. The attribute parser respects quoting and -backslash escapes, so a `Description` containing a comma is handled correctly. - -An **unrecognised** `##` key keeps only the base `vcfr:HeaderLine` type. -Inventing a subclass would put a term in the graph that the vocabulary does not -define. +vocabulary subclass (`INFOHeaderLine`, `ContigHeaderLine`, `FILTERHeaderLine`, +`ALTHeaderLine`, `MetaHeaderLine`, `SampleHeaderLine`, `PedigreeHeaderLine`, +`AssemblyHeaderLine`, `PedigreeDBHeaderLine`, …) and lifts its attributes into +their own properties. The attribute parser respects quoting and backslash +escapes, so a `Description` containing a comma is handled correctly. + +Every **structured** line also gets one ordered `vcfc:HeaderAttribute` per source +attribute, carrying `attributeKey`, `attributeValue` and a one-based +`attributeIndex`. This is not optional decoration: +`vcfc:StructuredHeaderLineShape` requires at least one `vcfc:hasAttribute`, so a +line typed as one of the structured subclasses without them is non-conformant. +It also keeps implementation-defined attributes queryable, which the dedicated +properties alone cannot do. + +An **unrecognised** `##` key is still typed as `vcfc:StructuredHeaderLine` or +`vcfc:UnstructuredHeaderLine` according to its value's form, which keeps it +queryable without inventing a subclass the vocabulary does not define. An +unstructured line is only typed when it has a value, because +`vcfc:UnstructuredHeaderLineShape` requires one. `##fileDate` is emitted as `xsd:date` when its form is recognisable, and verbatim as a plain literal otherwise — again preserved rather than dropped, and reported by SHACL. -`--header-representation basic` keeps only the base header-line triples. +`--header-representation basic` keeps only the base header-line triples the RML +mapping emits. It is the fastest and smallest header form, but **it does not +produce a SHACL-conformant graph**, because the structured lines then carry no +attributes and no subclass. ### `emit_sample_representation` — genotypes @@ -153,11 +211,107 @@ version: | Mode | Shape | Growth | | --- | --- | --- | -| `expanded` (default) | one `vcfr:SampleCall` per record × sample, one `vcfr:FormatFieldValue` per FORMAT key | ≈ variants × samples × FORMAT fields | -| `condensed` | one reusable `vcfr:SampleSet`, one `vcfr:CohortCallMatrix` per call, one `vcfr:FormatValueVector` per FORMAT key holding a tab-separated `vcfr:VCFTextVector` | ≈ samples + variants × FORMAT fields | - -The file declares which shape it carries via `vcfr:representationProfile`, so a -consumer can branch on it before querying. +| `expanded` (default) | one `vcfc:SampleCall` per record × sample, one `vcfc:FormatFieldValue` per FORMAT key, and the parsed genotype layer below | ≈ variants × samples × FORMAT fields | +| `condensed` | one reusable `vcfc:SampleSet`, one `vcfc:CohortCallMatrix` per call, one `vcfc:FormatValueVector` per FORMAT key holding a tab-separated `vcfc:VCFTextVector` | ≈ samples + variants × FORMAT fields | + +Both modes emit the file-level `vcfc:SampleSet` and its ordered `vcfc:VCFSample` +members, and link them from the `#CHROM` `vcfc:ColumnHeaderLine` with +`vcfc:hasGenotypeColumns`. That is one resource per sample column for the whole +file, not per record, so it costs nothing at cohort scale — and it gives the +expanded profile's `SampleCall` a reusable identity through `vcfc:forSample` +instead of relying on repeated `sampleId` literals. + +**Expanded mode additionally parses the per-sample values** into the vocabulary's +genotype layer: `GT` becomes a `vcfc:Genotype` with `genotypeString`, `ploidy`, +`phasingStatus` and one `vcfc:GenotypeAlleleCall` per position (each either +pointing at the allele it called or flagged `isNoCall`); `FT` becomes +`sampleFilter`; `PS`/`PSL`/`PSO`/`PSQ` become a `vcfc:PhaseSet`; `LAA` becomes a +`vcfc:LocalAlleleSet`; `CN`/`CNQ`/`CNL`/`CNP` and `HAP`/`AHAP` become their +copy-number and haplotype properties; and the pattern-defined `M`/`DPM`/`ADM` +keys become `vcfc:BaseModification` resources pointing at a ChEBI residue. + +**Condensed mode deliberately stops at the vector.** Decomposing GT per sample is +exactly the per-sample materialization the condensed profile exists to avoid. +Every value stays recoverable by decoding a vector against its FORMAT definition +and the matrix `SampleSet`. + +A `GT` value that is not in the `vcfc:GenotypeString` lexical space produces no +`Genotype` resource at all — the value remains present as the FORMAT field's +`fieldValue`, and inventing a genotype for it would create a resource that fails +`vcfc:GenotypeShape`. + +The file declares which shape it carries via `vcfc:representationProfile`, so a +consumer can branch on it before querying. The SPARQL SHACL profile enforces +that a graph never mixes the two. + +## 4a. VCF versions + +VCF Core ships one SHACL overlay per VCF version (4.1 through 4.5), each scoped +by the file's `vcfc:fileFormat`, plus an optional `vcfc:VCF4xFile` subclass that +activates that version's gate. The conversion follows the version of each input. + +### Detection is automatic + +`##fileformat` is required to be the first line of a conforming VCF, and +[`src/vcf_as_tsv.sh`](../src/vcf_as_tsv.sh) already lifts it into +`file_metadata.tsv`, so detection costs one small read and needs nothing from +you. It happens **per input**, not per run: a directory may hold files of +different versions and each gets its own mapping and emitter behaviour. + +`--vcf-version` overrides it, for a file whose declaration is missing or wrong: + +```bash +vcf-rdfizer --mode full -i ./cohort.vcf.gz --vcf-version 4.3 -o ./results +``` + +The run log states which version was used and how it was chosen — `(detected)`, +`(forced)`, or a warning that the declaration was not recognized. + +**VCF 4.0 is not recognized.** VCF Core claims no 4.0 conformance overlay, so a +4.0 file converts with the newest supported rules — nothing representable is +dropped — but no `vcfc:VCF4xFile` class is emitted, so the graph never claims a +version gate that cannot be checked. The same applies to a missing or malformed +`##fileformat` line. All three cases are reported, never assumed silently. + +### What the version changes + +| | 4.1 | 4.2 | 4.3 | 4.4 | 4.5 | +| --- | --- | --- | --- | --- | --- | +| `Number=R` | — | ✓ | ✓ | ✓ | ✓ | +| `Number=P` (FORMAT) | — | — | — | ✓ | ✓ | +| `Number=LA/LR/LG/M` (FORMAT) | — | — | — | — | ✓ | +| `CIPOS`/`CIEND` | one pair per record | one pair per record | one pair per record | one pair per ALT | one pair per ALT | +| `CILEN`/`CICN` | — | — | — | ✓ | ✓ | +| `EVENT` | one per record | one per record | one per record | one per ALT | one per ALT | +| `EVENTTYPE` | — | — | — | ✓ | ✓ | +| Local alleles (`LAA`) | — | — | — | — | ✓ | +| Base modifications (`M`/`DPM`/`ADM`) | — | — | — | — | ✓ | +| Leading GT phase indicator | — | — | — | ✓ | ✓ | + +Three consequences in the emitted graph: + +- **`vcfc:FieldValueItem` linkage.** Before 4.4 a `CIPOS` list is one pair + describing the record, so its items get a `vcfc:valueIndex` and a + `vcfc:tupleArity` but no `vcfc:forAllele` — there is no single allele to point + at, and each ALT allele of a multi-allelic record shares the interval. From + 4.4 the list repeats per ALT and each item joins its own allele. +- **Tuple items are always materialized.** The version overlays count a tuple + key's value items against the ALT count, so `CIPOS` and friends are decomposed + even though 4.4 and 4.5 declare them `Number=.`, which on its own would say + "no positional meaning". +- **Families a version does not define are not invented.** A `LAA` column in a + 4.4 file, or an `M27551C` column in a 4.3 file, keeps its raw + `vcfc:fieldValue` and gets no `vcfc:LocalAlleleSet` or + `vcfc:BaseModification` resource. + +### What it does *not* change + +The version does not affect parsing leniency. A GT with a leading phase +indicator in a 4.1 file is still parsed into a `vcfc:Genotype`; the version +overlay reports it as non-conformant, which is the right division of labour — +the converter transcribes, the validator judges. The same holds for a `Number=R` +declaration in a 4.1 file, or a reserved key declared with the wrong arity: the +graph records what the file says, and SHACL says whether the file was right. ## 5. The two helper tables @@ -183,14 +337,28 @@ conversion is deterministic and re-running it produces byte-comparable subjects. | `HeaderLine` | `file://{SOURCE_FILE}#header/line/{HEADER_INDEX}` | | `VCFRecord` | `file://{SOURCE_FILE}#record/{ROW_ID}` | | `VariantCall` | `file://{SOURCE_FILE}#call/{ROW_ID}` | +| `ColumnHeaderLine` | `file://{SOURCE_FILE}#header/columns` | +| `HeaderAttribute` | `file://{SOURCE_FILE}#header/line/{HEADER_INDEX}/attribute/{N}` | +| `SampleDeclaration` (`##SAMPLE`/`##PEDIGREE`) | `file://{SOURCE_FILE}#header/sample/{ID}` | | `InfoFieldValue` | `file://{SOURCE_FILE}#call/{ROW_ID}/info/{KEY}` | +| `Allele` (REF at 0, ALT from 1) | `file://{SOURCE_FILE}#record/{ROW_ID}/allele/{N}` | +| `FieldValueItem` | `/value/{N}` | +| `VariantEvent` | `file://{SOURCE_FILE}#record/{ROW_ID}/event/{EVENT}` | +| `SampleSet` (both profiles) | `file://{SOURCE_FILE}#samples` | +| `VCFSample` (both profiles) | `file://{SOURCE_FILE}#samples/{SAMPLE}` | | `SampleCall` (expanded) | `file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE}` | | `FormatFieldValue` (expanded) | `file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE}/fmt/{KEY}` | -| `SampleSet` (condensed) | `file://{SOURCE_FILE}#samples` | -| `VCFSample` (condensed) | `file://{SOURCE_FILE}#samples/{SAMPLE}` | +| `Genotype` (expanded) | `file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE}/genotype` | +| `GenotypeAlleleCall` (expanded) | `…/genotype/call/{N}` | +| `PhaseSet` (expanded) | `file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE}/phaseset` | | `CohortCallMatrix` (condensed) | `file://{SOURCE_FILE}#call/{ROW_ID}/matrix` | | `FormatValueVector` (condensed) | `file://{SOURCE_FILE}#call/{ROW_ID}/matrix/fmt/{KEY}` | +These follow the `vcfc:iriTemplate` patterns the vocabulary recommends for each +class. Where the vocabulary declares no template — the allele-layer, genotype +and SV resources — the IRI is minted beneath the resource it belongs to, so the +whole graph stays derivable from the filename and the row counter alone. + `{SOURCE_FILE}` is the **basename**, not a path, so a graph does not encode where the VCF happened to live. The consequence is that two different VCFs with the same filename mint the same IRIs; if you convert `chr1/data.vcf` and @@ -199,16 +367,21 @@ converting, or keep the graphs separate. ## 7. Missing values -The vocabulary's `vcfr:missingValuePolicy` says a missing token should be -`"."^^vcfr:Null`, and the conversion follows it. `preflight_missing_token_conformance` +The vocabulary's `vcfc:missingValuePolicy` says a missing token should be +`"."^^vcfc:Null`, and the conversion follows it. `preflight_missing_token_conformance` reports a plain `"."` literal as an anomaly, and `--strict-conformance` promotes that from a report to a failure. -This policy currently **conflicts with the published SHACL shapes** for -`ref`/`alt`/`chrom`, which constrain those to `sh:datatype xsd:string`. A record -with `ALT=.` therefore cannot satisfy both. The conflict is documented in -[`vcf-coverage.md`](vcf-coverage.md#an-open-conflict-inside-the-vocabulary) and -needs a decision in the vocabulary repository, not here. +This used to conflict with the published SHACL shapes, which constrained +`vcfc:alt` to `sh:datatype xsd:string` and so rejected every REF-only and +gVCF-style record. **The vocabulary fixed that**: `vcfc:VCFRecordShape` now +accepts `xsd:string` or `vcfc:Null` for `alt`, and `vcfc:VariantCallShape` +accepts the full VCF Float lexical space for `qual`. Emitting the missing token +as `vcfc:Null` is now both the policy and the conformant choice. + +`CHROM`, `POS` and `REF` are the three fixed fields VCF 4.5 forbids from being +the missing token, which is exactly why they can stay in the RML mapping while +`ID`, `ALT`, `QUAL` and `FILTER` cannot. ## 8. What conversion does *not* do @@ -219,14 +392,22 @@ needs a decision in the vocabulary repository, not here. the central problem the [data-linking design](datalinking-design.md) has to solve. - **No reference checking.** `REF` is not verified against any genome. -- **No structural-variant modelling.** Symbolic ALTs (``), breakends - (`N[chr2:321[`) and `*` are carried as literals. The validation suite - classifies them (`SYMBOLIC_OR_BREAKEND`) but the vocabulary gives them no - structure, and `INFO` keys such as `END` and `SVTYPE` get no special meaning. -- **No genotype interpretation.** A `GT` value is a lexical token. Phasing - (`|` versus `/`) is preserved in the literal but not modelled. - **No cross-file merging.** Each VCF produces its own graph. +Two entries that used to be in this list no longer belong here, because the move +to the VCF Core vocabulary added both: + +- **Structural variants are modelled.** Symbolic ALTs, breakends and `*` are + classified by `vcfc:alleleKind`, given a `vcfc:svType` where the identifier is + a reserved code, and parsed into their components; `END`, `SVLEN`, `SVCLAIM`, + `EVENT`/`EVENTTYPE`, the `CI*` intervals and the tandem-repeat keys all have + meaning. The raw literals are still there — the structure is added alongside, + not instead. +- **Genotypes are interpreted** in the expanded profile: `GT` is parsed into + ordered allele calls with an explicit `vcfc:phasingStatus`, so `|` versus `/` + is modelled rather than only preserved. The condensed profile keeps them + lexical by design. + --- ## See also diff --git a/docs/datalinking-design.md b/docs/datalinking-design.md index 4cc04db..020ce1a 100644 --- a/docs/datalinking-design.md +++ b/docs/datalinking-design.md @@ -1,14 +1,17 @@ # Data linking: a plug-in architecture -*Status: **design proposal**. Nothing described here is implemented yet. This -document exists to fix the extension contract before code is written, because -third-party linkers are the point and a contract is much harder to change once -people depend on it.* +*Status: **partially implemented**. Runnable examples now cover all three +plug-in tiers, with a shared runner, discovery/authoring CLI, full and post-hoc +entry points, side-graphs, provenance and network safeguards. See +[`datalinking.md`](datalinking.md) for the implemented contract and worked +commands. This document retains the broader proposal: allele normalization, +link merging, and automatic plug-in query/mutation discovery remain planned. +The manifest vocabulary is still provisional.* VCF-RDFizer converts a VCF into RDF that is faithful to the VCF and to nothing else. Every IRI it mints is derived from the source file, so the graph is self-contained, reproducible, and — deliberately — an island. It says -`vcfr:recordId "rs334"` and stops there. +`vcfc:recordId "rs334"` and stops there. Data linking is the step that connects that island to the rest of the linked-data web: the rsID becomes a dbSNP resource, the coordinate becomes an diff --git a/docs/datalinking.md b/docs/datalinking.md new file mode 100644 index 0000000..b0fc323 --- /dev/null +++ b/docs/datalinking.md @@ -0,0 +1,356 @@ +# Data linking: implementations and examples + +VCF-RDFizer can now connect its graph to external resources through three tiers +of linker plug-in. The output is a separate N-Triples linkset: enabling linking +does not change the aggregate, its compression inputs, or the core validation +queries. This is an initial implementation of +[`datalinking-design.md`](datalinking-design.md), with the remaining work listed +in §8 below. + +The examples and the runner are installed with the Python package. Linking runs +on the host; only conversion still needs Docker. RDFLib is now a runtime +dependency for parsing actual Turtle manifests and unordered N-Triples, rather +than approximating either syntax with regular expressions. + +--- + +## 1. Three runnable examples + +| Tier | Installed ID | Join and result | Network | +| --- | --- | --- | --- | +| 1: declarative | `rsid-dbsnp` | `ID` rsID tokens → dbSNP identifier IRIs | None | +| 2: reference bundle | `gene-demo` | Explicit allele REF spans → synthetic GFF3 gene intervals | None with the shipped local bundle | +| 3: live resolver | `rsid-ensembl` | Deduplicated rsID batches → service-confirmed Ensembl variation links | Ensembl HTTPS API, or cached responses | + +The canonical example directories are under +[`vcf_rdfizer_data/linkers/`](../vcf_rdfizer_data/linkers/). Each has its own +README and `linker.ttl`; only Tier 3 has `resolver.py`. + +`gene-demo` is deliberately **synthetic**. Its three genes use `example.org` +identifiers and invented intervals. Its `GRCh38` declaration exercises the +assembly guard; it does not turn the fixture into a biological annotation. +Use a real, digest-pinned reference before interpreting overlaps biologically. + +From a checkout: + +```bash +python -m pip install -e . +vcf-rdfizer-link list +vcf-rdfizer-link keys + +# Two local tiers, no Docker or network needed. +vcf-rdfizer-link run -i examples/linking/example.vcf \ + --link rsid-dbsnp,gene-demo --offline \ + --links-cache ./example-cache -o ./example.links.nt +``` + +This writes **seven links**: three dbSNP links and four gene overlaps, plus +provenance triples. Record 2 overlaps both demo genes A and B. Record 3 has no +rsID and falls beyond the gene interval; it produces no link. The JSON report +is `example.links.json`. Existing graph or report paths are refused. + +The companion `run -i` command derives subjects with the converter's default +IRI templates; it does not create or verify a base graph. To link an actual +conversion, use `--rdf` or one of the two entry points below. + +## 2. Conversion and post-hoc linking + +Full mode inserts the stage after the direct RDF emitters and before +compression: + +```bash +vcf-rdfizer --mode full -i examples/linking/example.vcf \ + --rdf-storage-mode plain --representations none --rdf-compression none \ + --link rsid-dbsnp,gene-demo --offline -o ./results +``` + +The aggregate is `results/example/example.nt`; the side-graph is +`results/example/example.links.nt`. Space-optimized `.nt.gz` aggregates work as +well. If linking fails, that input fails at `data-linking` and compression is +not started for it. The completed base aggregate remains available. + +To enrich an existing aggregate without conversion or Docker: + +```bash +vcf-rdfizer --mode link --rdf ./results/example/example.nt \ + --link rsid-dbsnp,gene-demo --offline -o ./relinked +``` + +The result is `relinked/example.links.nt`, with a normal `run_metrics/` tree. +`vcf-rdfizer-link run --rdf --link -o ` uses the +same runner but writes a single companion JSON report instead. + +Both RDF entry points read the graph's `hasRecord` and `hasCall` edges. They +retain the actual subjects, including custom IRI templates, and reject a call +whose subject is absent. They require the VCF-RDFizer predicates for those +edges and the selected join fields. Arbitrary custom vocabularies cannot be +inferred. N-Triples may be unordered; the input reader stores only relevant +fields in a temporary SQLite index and discards genotype triples after parsing. + +## 3. Tier 1: a manifest is the implementation + +[`rsid-dbsnp/linker.ttl`](../vcf_rdfizer_data/linkers/rsid-dbsnp/linker.ttl) +implements the proposal's token example unchanged in substance: + +- `vcfl:TokenJoin` reads `ID`, or a named INFO value using `INFO/`. +- `vcfl:splitOn` splits literal delimiters, defaulting to `;` for ID and `,` + for INFO. Flags, missing keys, empty tokens, and `.` do not create keys. +- `vcfl:accept` is a case-sensitive Python regular expression matched against + the **whole token**. Duplicate tokens do not duplicate a triple. +- `vcfl:objectTemplate` contains exactly one `{TOKEN}` placeholder. The runner + percent-encodes the value before substitution, then validates the IRI. +- `vcfl:subject` selects `vcfl:VariantCall` or `vcfl:VCFRecord`; the manifest + declares the predicate. The runner owns subject identity and serialization. + +This example asserts a weak identifier connection with `vcfl:sameVariantAs`. +It does not check whether dbSNP still recognises the rsID, resolve retired IDs, +or assert `owl:sameAs`. + +## 4. Tier 2: a reference, a digest, and an assembly + +[`gene-demo/linker.ttl`](../vcf_rdfizer_data/linkers/gene-demo/linker.ttl) +declares `vcfl:IntervalJoin`, a GFF3 reference, its exact SHA-256, and its +assembly. The interval index is the implementation; no plug-in Python is needed. + +The join uses **1-based closed intervals**: +`[POS, POS + len(REF) - 1]`. A position at either boundary overlaps. Nested +and overlapping features are retained. `vcfl:featureType` defaults to `gene`; +`vcfl:idAttribute` defaults to `ID`. GFF3 percent escapes are decoded and the +selected identifier feeds the `{ID}` object template. + +Limits are explicit: chromosome names must match exactly (`1` and `chr1` are +different); there is no contig aliasing or liftover. Symbolic alleles, +breakends, and spanning-deletion `*` records are skipped and counted in +`skipped_records`. The runner does not interpret INFO/END or confidence ranges. +It uses explicit DNA REF spans, including their anchor base, rather than an +inferred biological affected region. + +References may be HTTPS URLs, local `file:` URLs, or relative IRI references +such as `` resolved beside `linker.ttl`. An absolute URL string is +also accepted, as in the original proposal. Fetched/local bundles are cached +under `references/`; the digest is checked on every cache use. For +gzip references the digest covers the **compressed bytes**. The GFF3 index is +rebuilt in memory each invocation; the bundle bytes are cached, not the index. + +Before resolution, the runner compares the input reference against the bundle. +It recognises `GRCh37`, `GRCh38`, and the `hg19`/`hg38` aliases within reference +paths, or an exact declared assembly string. Missing/unrecognised metadata +requires `--assembly` after the user checks the input. That option cannot +override a recognised mismatch. No reference is fetched until the assembly +checks for all selected linkers have passed. + +To adapt the example: + +```bash +vcf-rdfizer-link init --example gene-demo -o my-gene-linker +# Edit id, reference URL, digest, assembly, attribute, and object template. +vcf-rdfizer-link check my-gene-linker --links-cache ./reference-cache +vcf-rdfizer-link dry-run my-gene-linker -i your-small.vcf --limit 100 +``` + +`check` parses the manifest, verifies/acquires the reference and parses its +features. Without an input VCF it cannot certify input assembly compatibility. + +## 5. Tier 3: a narrow Python resolver + +The shipped resolver calls Ensembl's +[batch variation endpoint](https://rest.ensembl.org/documentation/info/variation_post). +It submits one POST per batch (up to 100 rsIDs in this example) and emits links +only for returned variation objects with a name. Missing IDs produce no link; +malformed response objects abort the linker. No clinical assertions or +frequencies are inferred from the response. + +```python +from vcf_rdfizer_linking import Link, LinkKey, LinkerContext + +def resolve(batch, ctx): + response = ctx.session.post( + "https://rest.ensembl.org/variation/homo_sapiens", + json={"ids": [key.token for key in batch]}, + ) + response.raise_for_status() + # Inspect response.json(), then yield Link(key, absolute_object_iri). +``` + +`LinkKey` is immutable (`token`, `chrom`, `start`, `end`). `Link` contains only +`key` and `object`. A resolver cannot supply a subject or change the manifest's +predicate through this protocol, and returning an undispatched key is an error. +The session offers `get(url, params=...)` and `post(url, json=...)`; responses +have `status_code`, `headers`, `content`, `json()`, and `raise_for_status()`. + +Preview first, then supply your actual contact address for a live run: + +```bash +vcf-rdfizer-link init --example rsid-ensembl -o ensembl-example +vcf-rdfizer-link dry-run ensembl-example -i examples/linking/example.vcf + +vcf-rdfizer-link run -i examples/linking/example.vcf --link rsid-ensembl \ + --links-contact-email you@your-institution.org \ + --links-cache ./ensembl-cache -o ./ensembl.links.nt + +# Reuse identical request batches without contacting the service. +vcf-rdfizer-link run -i examples/linking/example.vcf --link rsid-ensembl \ + --offline --links-cache ./ensembl-cache -o ./ensembl-replay.links.nt +``` + +The built-in manifest's placeholder contact blocks a cache-miss live request; +an offline replay can still use its cache. Set `vcfl:contactEmail` in a copied +manifest or use `--links-contact-email`. Selecting a live linker sends its join +keys to the declared service; no sample/genotype payload is passed to this +example's resolver. + +The session implements: + +- A declared HTTPS endpoint origin and path. Redirects are refused, including + reference-download redirects, so hidden requests cannot change hosts. +- A mandatory disk cache under `responses///.json`. + The hash includes method, URL and canonical JSON body; stored bodies have + digests. Only successful responses are cached. Corrupt entries fail closed. +- Full key deduplication **per input aggregate**, before any request. Sorted + keys make batching deterministic. SQLite stores key-to-subject associations + and resolved triples so those do not need to fit in memory. +- A per-host token bucket with capacity one, shared by selected linkers, using + the strictest declared rate. At most one request is in flight per run. + Per-linker request ceilings are shared across inputs in a directory run. +- Up to four HTTP attempts for 429/5xx, with exponential delay and numeric or + HTTP-date `Retry-After` honoured. Retries count toward the run ceiling. This + follows Ensembl's documented + [rate-limit protocol](https://github.com/Ensembl/ensembl-rest/wiki/Rate-Limits). +- A 30-second request timeout and 16 MiB response limit. Other HTTP failures, + connection failures, and exhausted budgets abort the linker. +- `--offline` / `--links-cache-only`: no network, with clear cache-miss errors. + Verified local GFF3 references remain usable on a cold cache. + +The limiter is shared within one invocation, not across separate processes. +Directory inputs are deduplicated individually; identical request batches in +later inputs use the response cache. Different batch membership produces a +different cache key even if some identifiers overlap. Cache entries have no +automatic expiry: use a fresh cache directory or a new plug-in version to +refresh service answers deliberately. + +**Python plug-ins are trusted code.** The session constrains traffic made +through its methods. Importing a third-party resolver is not a security sandbox +and cannot prevent that code from opening its own socket. The shipped resolver +uses only `ctx.session`. `list`, `check`, and `dry-run` do not import resolver +modules; Python entry-point discovery does execute the installed provider. + +Tier 3 remains suitable for filtered variant sets. Genome-wide linking should +use a suitable local reference bundle. The network budget is a hard ceiling, +not a promise that a large run will finish. + +## 6. Discovery, authoring, and previews + +`vcf-rdfizer-link init -o my-linker` copies the annotated Tier 1 example; +`--example` selects any of the three tiers. It refuses an existing destination. +Give copies a new `vcfl:id` before adding them to a search path. Discovery reads +packaged examples, repeatable `--linker-path` directories, the platform-separated +`VCF_RDFIZER_LINKER_PATH`, and `vcf_rdfizer.linkers` Python entry points. + +A path may be a linker directory or a parent containing linker directories. +Duplicate IDs at different locations are rejected rather than shadowed. +Entry points export a zero-argument callable returning an installed directory: + +```toml +[project.entry-points."vcf_rdfizer.linkers"] +my-linker = "my_package:linker_directory" +``` + +```python +from pathlib import Path + +def linker_directory(): + return Path(__file__).parent / "my-linker" +``` + +Package that directory's manifest, resolver and optional local data. `list` +prints versions, tiers, references, licensing and terms; `list --json` provides +the parsed fields. `check --json` is available for automation. IDs and versions +must be safe path components. Unsupported joins, template variables, unknown +`vcfl:` properties, invalid regexes, bad digests and invalid budgets are errors. + +`dry-run -i --limit N` reads the first N records (default 100), +writes no persistent graph/report/cache, and never makes a network request. It +shows up to 20 concrete triples for local tiers, total local link counts, and +Tier 3 unique-key/batch counts and the declared request ceiling. A remote +Tier 2 bundle must already be cached. For Tier 3 it reports a **plan**, not +imagined API results; a general resolver's response-dependent request count +cannot be predicted without executing it. The shipped resolver makes one +request per batch before retries. + +## 7. Output integrity and accounting + +The runner stages all resolutions before serializing into a temporary file +with the wrapper's `_append_rdf_atomically` contract. It publishes the completed +side-graph atomically and refuses existing outputs. Failures preserve the base +aggregate and publish no partial linkset. Successful response/reference caches +from a failed run are retained for retry. + +Each source/linker pair has a `vcfl:Linkset` node, even with zero matches. It +records producer ID/version, source, link count, generation time, and manifest +digest; Tier 2 adds reference digest and assembly; Tier 3 adds resolver and used +response digests. `linkCount` counts distinct links emitted by that linker for +that source and excludes provenance. If two linkers emit the same triple, it +appears once in the side-graph but counts in each linker's own provenance. + +Full and post-hoc wrapper runs record linking results in `run.json` and +`stages/linking/.links.json`, with `RunTracker` logging and the normal +progress sidecar protocol (`--quiet`/`--no-progress` apply). Reports include +unique keys, skipped records, links, requests, cache hits, transferred response +bytes, elapsed time, final HTTP status and cached-response timestamps/digests. +Failure reports carry the error and per-linker status. Main-aggregate triple +counts continue to exclude side-graph triples. `--mode link` summary counts are +the new side-graph's triples, including provenance. + +An offline replay reproduces links from the same cached requests. Its +`generatedAtTime` and run timings are new; the entire side-graph is therefore +not promised byte-identical. + +## 8. What remains from the proposal + +The implemented tiers are examples of the extension contract, not completion +of every feature in the proposal: + +- **No allele join or allele normalization.** Tier 3 uses token keys. No + ClinVar/gnomAD/CADD matching is implied by this implementation. +- **No production gene bundle is shipped.** The synthetic fixture demonstrates + digest checking, indexing and assembly refusal. Users supply real references. +- **No `--merge-links`.** Keeping side-graphs separate leaves core validation + intact; the wrapper's custom-mapping report-only forwarding gap is still open. +- **No plug-in SPARQL/mutation auto-discovery.** Optional `queries/` and + `mutations.py` from the proposal are not executed. The new unit tests cover + linker invariants and failures but do not extend the published core mutation + score. No standalone linkset validator is claimed. +- **No HDT/COTTAS input reader for linking.** Supply `.nt` or `.nt.gz`. +- **No persisted interval index or global cross-process quota.** Reference + features are indexed in memory; temporary SQLite storage still requires disk + proportional to join fields and associations. This implementation has not + been benchmarked on genome-scale cohorts. +- **The manifest vocabulary is provisional.** Third-party authors should pin + the tool version while the remaining joins and validation contract settle. + +## 9. Verification + +[`test/test_linking_unit.py`](../test/test_linking_unit.py) exercises known-answer +token links, INFO splitting/escaping, interval boundaries and nested features, +assembly refusal, digest corruption, unordered and gzip RDF, custom subjects, +empty inputs, full-mode integration, discovery, authoring commands, API batching, +cache replay, host pacing, retries, ceilings and failure atomicity. + +The shipped Ensembl resolver runs in these tests against a fake HTTP transport; +tests never contact Ensembl or require Docker. That verifies its response +handling and the session policy, not the current availability or completeness +of a public service. + +```bash +python -m unittest test.test_linking_unit -v +python -m unittest discover -s test -p 'test_*_unit.py' +``` + +--- + +## See also + +- [Original design](datalinking-design.md) — rationale and remaining ambitions +- [Custom mappings](rml-mappings.md) — subject and vocabulary compatibility +- [Output and metrics](output-and-metrics.md) — the shared run report layout +- [Validation methodology](validation-methodology.md) — the separate core suite diff --git a/docs/limitations.md b/docs/limitations.md index cf0dcb3..6615bdb 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -11,7 +11,9 @@ Each item says what it is, why it is that way, and whether it is fixable. ## 1. Operational -**Docker is mandatory.** There is no pure-Python path. The toolchain — Flink, +**Docker is mandatory for conversion and representation operations.** There +is no pure-Python conversion path. Post-hoc data linking and the authoring CLIs +run on the host without Docker. The conversion toolchain — Flink, RMLStreamer, a Rust `hdtc`, `pycottas`, Comunica, QLever, `pyshacl`, `cyvcf2`, `bcftools` — is pinned in one image, which is what makes results reproducible across machines. The cost is a large image, a Docker daemon requirement, and no @@ -71,18 +73,63 @@ joinable with normalized external resources, which is the central problem the **No reference checking.** `REF` is never verified against a genome, and the declared assembly is recorded but not used for anything. -**Structural variants are literals.** Symbolic ALTs (``), breakends and `*` -are carried as strings. The validation suite classifies them -(`SYMBOLIC_OR_BREAKEND`) but the vocabulary gives them no structure, and `END` / -`SVTYPE` carry no special meaning. - -**Multi-valued INFO fields keep only their lexical value.** A field declared -`Number=A/R/G/.` gets no typed per-value nodes, because the vocabulary's IRI -template gives one node per key rather than per value. This is a modelling gap -in the vocabulary, not a bug in the conversion. - -**Genotypes are lexical.** Phasing is preserved inside the literal but not -modelled; ploidy is not interpreted. +**Structural variants and genotypes are no longer lexical-only.** Moving the +target to the VCF Core vocabulary closed three gaps that used to be listed here: +symbolic ALTs, breakends and `*` are now classified and parsed; `Number=A/R/G/P` +values are decomposed into per-allele `vcfc:FieldValueItem` resources; and `GT` +is parsed into ordered allele calls with an explicit phasing status. See +[`conversion.md`](conversion.md#4-stage-three--the-wrappers-own-emitters). + +What remains true: + +**Genotype interpretation is expanded-only.** The condensed profile keeps +per-sample values inside `vcfc:encodedValues` vectors, so there is no +`vcfc:Genotype`, no phase set and no base-modification resource in a condensed +graph. That is the point of the profile — the values stay recoverable by +decoding a vector against its FORMAT definition and the matrix `SampleSet` — but +a SPARQL engine cannot filter inside a vector payload without a decoder. Choose +`expanded` if you need to query genotypes directly. + +**Symbolic ALT types are only recognised for the reserved codes.** A +caller-specific `` gets `vcfc:SymbolicAllele` and a link to its +`##ALT` declaration, but no `vcfc:svType`, because the vocabulary enumerates +only the codes VCF 4.5 reserves. + +**Some SV carriers need more than one INFO key to be emitted.** A +`vcfc:VariantEvent` needs `EVENT` *and* `EVENTTYPE`; a gVCF reference block +needs `END` *and* `POS`; a tandem repeat needs `RN` before `RUS`/`RUL`/`RUC`/`RB` +have a grouping. Where the record supplies only part of the set, the carrier is +omitted and the values remain as ordinary INFO values. Emitting a partial +carrier would produce a resource that fails its SHACL shape, which is worse than +not producing it. + +**VCF 4.0 has no conformance overlay.** VCF Core supplies version overlays for +4.1 through 4.5 only. A 4.0 file converts with the newest supported rules, so +nothing representable is dropped, but it gets no `vcfc:VCF4xFile` class and its +graph is only checked by the version-neutral profiles. The same applies to a +file with a missing or malformed `##fileformat` line. All three cases are +reported in the run log rather than assumed silently. + +**Version detection trusts the file's own declaration.** `##fileformat` is +required to be the first line of a conforming VCF, and that is what the +converter reads. A file whose declared version does not match its actual content +converts against the declared one; `--vcf-version` is the override. The +converter does not sniff content to second-guess the declaration, because a +wrong guess would silently produce a graph that validates against rules the file +was never written to. + +**Parsing stays lenient across versions.** A GT with a leading phase indicator +in a VCF 4.1 file is still parsed into a `vcfc:Genotype`, and a `Number=R` +declaration in a 4.1 file is still recorded. The version overlays report both as +non-conformant. This is deliberate: the converter transcribes, the validator +judges, and a converter that refused to represent a slightly non-conforming file +would be less useful than one that represents it faithfully and lets SHACL say +so. + +**`--header-representation basic` is not SHACL-conformant.** It emits no +header-line subclass and no `vcfc:HeaderAttribute` resources, and +`vcfc:StructuredHeaderLineShape` requires at least one attribute on every +structured line. It remains available as the smallest, fastest header form. **Triples only.** No named graphs anywhere in the pipeline, and no blank nodes — a blank node is treated as a validation failure, because every class in the @@ -93,9 +140,10 @@ vocabulary declares an IRI template. ## 4. The custom-mapping extension point **`--rules` does not control the whole graph.** Three families of triple — -genotypes, structured headers, and QUAL/structured INFO — are emitted by the -wrapper rather than by RML, because RML cannot choose a datatype or class per -row and the alternatives require materializing enormous helper tables. See +genotypes, structured headers, and the record detail (the fixed fields that may +be missing, the allele layer, structured INFO and the SV carriers) — are emitted +by the wrapper rather than by RML, because RML cannot choose a datatype or class +per row and the alternatives require materializing enormous helper tables. See [`architecture.md`](architecture.md#4-where-the-split-leaks-and-why). They can be narrowed with `--sample-representation` / `--header-representation` / `--info-representation`, but not replaced by a mapping. @@ -151,7 +199,7 @@ corruption we thought to write down is caught". It is a lower bound on blindness, not a measure of correctness, and a score that rises without the catalogue growing means nothing. -**`vcfr:contigCount` is counted, not read**, so a wrong derived contig total is +**`vcfc:contigCount` is counted, not read**, so a wrong derived contig total is undetected. **Header line values are not compared** — only how many lines carry each key, their types, and the structured attributes lifted out of them. @@ -164,17 +212,23 @@ argv is recorded in every report so a future divergence is diagnosable. ## 7. Vocabulary -**Condensed graphs are not ontology-backed.** The tool emits 17 terms that -`https://w3id.org/vcf-rdfizer/vocab#` does not define, all belonging to the -condensed representation. Dereferencing any of them returns nothing. This is the -one remaining publication blocker, and the work is in the vocabulary repository. +**VCF Core is published at 2.0.0** (`https://w3id.org/vcf-core/vocab#`) and +covers VCF 4.1 through 4.5. The three constraints listed here previously — the +condensed terms being undefined, the `ALT=.` shape contradiction, and the +ordinal datatype disagreement — are all resolved in that release. What remains: + +**VCF 4.0 has no conformance overlay.** The vocabulary claims 4.1–4.5. A 4.0 +file converts with the newest supported rules, so nothing representable is +dropped, but it gets no `vcfc:VCF4xFile` class and only the version-neutral +profiles check it. Reported in the run log, never assumed silently. -**The published SHACL shapes contradict the missing-value policy.** -`vcfr:missingValuePolicy` says a missing token should be `"."^^vcfr:Null`, while -`VCFRecordShape` constrains `vcfr:alt` to `sh:datatype xsd:string`. A record with -`ALT=.` cannot satisfy both. The conversion follows the missing-value policy. -The vocabulary needs a decision; see -[`vcf-coverage.md`](vcf-coverage.md#an-open-conflict-inside-the-vocabulary). +**The converter's version table is a copy.** VCF Core publishes +`ontology/versions/registry.json` as the source of truth for version-scoped +behaviour; the converter keeps its own dependency-free copy so it runs without +the vocabulary checked out. +`test_version_model_matches_the_published_registry` cross-checks the two when a +vocabulary checkout is available (`VCF_CORE_VOCABULARY_DIR`), and skips +otherwise — so drift is caught in development but not in a minimal CI. **Condensed mode has no query-time decoder.** Reconstructing sample *i*'s value means splitting a tab-separated literal, which SPARQL cannot do portably. The @@ -184,9 +238,12 @@ none is currently implemented. ## 8. Scope -**No data linking yet.** The graph is self-contained and connects to nothing -external. This is by design so far, and the plan to change it is -[`datalinking-design.md`](datalinking-design.md). +**Data linking is an initial implementation.** Optional plug-ins can produce +separate linksets through token joins, GFF3 intervals or a guarded live session. +The gene example is synthetic; allele normalization and automatic plug-in +validation are not implemented. See [`datalinking.md`](datalinking.md) for the +implemented contract and [`datalinking-design.md`](datalinking-design.md) for +the remaining proposal. The base graph remains a faithful, separate artifact. **No disclosure control.** Conversion is all-or-nothing: every sample, every genotype, every header line and every free-text `Description` goes into the @@ -198,7 +255,7 @@ record what an artifact was permitted to contain. Three consequences today: is a monotonic counter that discloses source ordering. - **Header lines are a leak surface.** `##source`, `##SAMPLE`, `##PEDIGREE` and free-text `Description` fields are transcribed verbatim into - `vcfr:headerValue`. + `vcfc:headerValue`. - **Even if that were fixed, genotypes identify people.** A few dozen independent common variants are enough to single out an individual, so no amount of label removal makes a released genotype graph non-identifying. diff --git a/docs/output-and-metrics.md b/docs/output-and-metrics.md index 0fcccb4..ec46d55 100644 --- a/docs/output-and-metrics.md +++ b/docs/output-and-metrics.md @@ -18,6 +18,7 @@ everything lives beneath it: .hdt + .hdt.index.v1-1 .cottas .hdt.gz | .cottas.br | ... + .links.nt optional --link side-graph run_metrics/__/ per-run reports and logs .intermediate/tsv/ hidden intermediates decompressed/ --mode decompress default target @@ -28,6 +29,11 @@ with its recognized VCF/RDF/representation suffix removed. `--mode compress` on `test-larger.nt` and on `test-larger.nt.gz` therefore both write into `/test-larger/`. +`--mode link` is host-only and writes `/.links.nt`, with the usual +`run_metrics/` directory. Full mode writes its linkset beside the aggregate +inside `//`. Side-graph triples are excluded from the base +conversion's triple counts. See [Data linking](datalinking.md). + **Collision policy.** Before Docker starts, the wrapper computes every artifact the run intends to write and fails if any already exists. It never overwrites a planned pipeline artifact. Choose a new `--out`, or move the conflicting file. @@ -60,17 +66,40 @@ recognisable without opening a timestamp-named folder. | --- | --- | | `run.json` | Source identity, resolved input paths, requested configuration, image selection | | `summary.json` | Final status, wrapper wall time, summary rows, and an index of every stage report and log | -| `metrics.csv` | Analysis-ready per-output table | +| `metrics.csv` | Analysis-ready per-output table, including `vcf_version` and `vcf_version_source` | | `tsv_metrics.csv` | TSV-mode benchmark table | | `wrapper_execution_times.csv` | Host-side stage timings | | `logs/wrapper.log`, `logs/progress.log` | Command log and progress history | | `timings//…` | Raw GNU `time -v` output from inside the relevant container | | `stages/tsv/`, `stages/conversion/`, `stages/compression/`, `stages/compression_operations/`, `stages/decompression/`, `stages/index/`, `stages/validation/` | Structured per-stage results | | `stages/partitioned/.json` | Full handoff from the partitioned-compression container | +| `stages/linking/.links.json` | Linker counts, reference/response digests, network accounting and success/failure; also collected in `run.json` | | `reports/index_warnings.json` | Degraded-index events | | `reports/failed_inputs.csv` | Inputs abandoned during a multi-file run | | `reports/validation//` | Detailed semantic-validation reports | +**Finding a validation run.** Its artifacts are spread across three trees by +design — the stage JSON with the other stages, the detail beside the other +reports, the raw engine output under that — which is convenient for analysis and +awkward when diagnosing. `summary.json` therefore carries a `validation` array +naming all of them per target: + +```json +{"validation": [{ + "validation_id": "chr20", + "status": "PASS", "engine": "qlever", "validation_target": "aggregate", + "wall_seconds": 812.4, + "stage_report": "stages/validation/chr20.json", + "results_dir": "reports/validation/chr20", + "summary": "reports/validation/chr20/summary.json", + "benchmark_csv":"reports/validation/chr20/benchmark.csv", + "engines": ["comunica", "qlever"] +}]} +``` + +Start there rather than globbing. A target validated against a non-aggregate +artifact is suffixed: `chr20__hdt`. + `compression_operations/` preserves the per-RDF operation and round-trip validation reports; `compression/` is the final output-level summary over them. @@ -81,6 +110,20 @@ RSS, exit codes, and bounded `stderr` diagnostics — **and it survives the deletion of the temporary Docker volume**, which is what makes a failed cohort-scale run diagnosable at all. +**Recording the VCF version.** `metrics.csv` and +`stages/conversion/*.json` carry `vcf_version` (the specification version the +input was converted under, e.g. `VCFv4.4`) and `vcf_version_source`: + +| `vcf_version_source` | Meaning | +| --- | --- | +| `declared` | Read from the input's own `##fileformat` line | +| `forced` | `--vcf-version` overrode the declaration | +| `fallback` | The declaration was missing, malformed, or a version with no conformance overlay (VCF 4.0); the newest supported rules were used and no `vcfc:VCF4xFile` class was emitted | + +Benchmarks should group by these. The version selects the SHACL overlay, the +flattened-tuple semantics and which FORMAT families exist, so conversion cost +and graph size are not comparable across versions without them. + ## 3. Input size accounting `input_vcf_size_bytes` in `stages/conversion/*.json` and `metrics.csv` is the diff --git a/docs/privacy-policy-design.md b/docs/privacy-policy-design.md index 7fe6128..228663a 100644 --- a/docs/privacy-policy-design.md +++ b/docs/privacy-policy-design.md @@ -28,7 +28,7 @@ haplotypes have been used to recover surnames from public genealogy databases Three consequences follow, and they shape everything below: -1. **Removing `vcfr:sampleId` does not anonymize anything.** The genotype vector +1. **Removing `vcfc:sampleId` does not anonymize anything.** The genotype vector that remains is a stronger identifier than the label you deleted. 2. **Access control is not anonymization.** A policy layer governs *who is permitted to receive what*, and creates an audit trail. It does not make the @@ -52,8 +52,8 @@ the shapes the conversion already emits (see | Cut | Addresses | Example | | --- | --- | --- | -| **By class** | all resources of a type | every `vcfr:SampleCall` | -| **By predicate** | all triples with a predicate | every `vcfr:sampleName` | +| **By class** | all resources of a type | every `vcfc:SampleCall` | +| **By predicate** | all triples with a predicate | every `vcfc:sampleName` | | **By sample** | one participant's contribution | everything hanging off `#samples/NA12878` | | **By region** | a genomic interval | `chr19:44,905,791-44,909,393` (*APOE*) | | **By declared field** | one INFO or FORMAT key | `DP` yes, `GT` no | @@ -69,10 +69,10 @@ easy to forget when thinking in terms of genotypes: - **IRIs themselves.** `file://cohort.vcf#sample/1/NA12878` contains the sample name. `#record/{ROW_ID}` is a monotonic counter, so row identifiers disclose the source ordering — and therefore approximate genomic position — even if - `vcfr:pos` is dropped. And `{SOURCE_FILE}` is the VCF's basename, which in + `vcfc:pos` is dropped. And `{SOURCE_FILE}` is the VCF's basename, which in practice is often `patient_12345.vcf`. Filtering triples while leaving IRIs intact leaks membership. See §7. -- **Header lines.** `vcfr:headerValue` and the raw line text carry `##source` +- **Header lines.** `vcfc:headerValue` and the raw line text carry `##source` (pipeline and centre identifiers), `##SAMPLE` and `##PEDIGREE` (family structure, by design), free-text `Description` fields, and `##fileDate`. A policy that covers genotypes and ignores the header section has not covered @@ -132,7 +132,7 @@ Namespace `vcfp:` = `https://w3id.org/vcf-rdfizer/policy#`, declared through ```turtle @prefix odrl: . @prefix vcfp: . -@prefix vcfr: . +@prefix vcfc: . @prefix duo: . <#apoe-locus> a odrl:Asset , vcfp:GraphSelection ; @@ -144,7 +144,7 @@ Namespace `vcfp:` = `https://w3id.org/vcf-rdfizer/policy#`, declared through <#direct-identifiers> a odrl:Asset , vcfp:GraphSelection ; vcfp:selector [ a vcfp:PredicateSelector ; - vcfp:predicate vcfr:sampleName , vcfr:sampleId ] . + vcfp:predicate vcfc:sampleName , vcfc:sampleId ] . <#withdrawn-participants> a odrl:Asset , vcfp:GraphSelection ; vcfp:selector [ a vcfp:SampleSelector ; @@ -293,7 +293,7 @@ For applying a policy to a graph that has already been converted Triple- and predicate-level rules are a single streaming pass. **Region rules are not**, because an N-Triples stream has no ordering guarantee: by the time -you see `<…#sample/4711/NA12878> vcfr:fieldValue "0/1"`, the triple that told +you see `<…#sample/4711/NA12878> vcfc:fieldValue "0/1"`, the triple that told you record 4711 is at `chr19:44906000` may be long gone. This needs two passes: pass one builds a `row_id → (chrom, pos)` map restricted to records that fall in a policy region, pass two filters. Memory scales with the number of **in-scope** @@ -380,7 +380,7 @@ This one is specific to VCF-RDFizer and easy to miss until it produces a leak. In **expanded** mode, one participant's value is its own resource: ```text -<…#sample/4711/NA12878/fmt/GT> vcfr:fieldValue "0/1" . +<…#sample/4711/NA12878/fmt/GT> vcfc:fieldValue "0/1" . ``` Excluding a sample is triple filtering. Straightforward. @@ -389,7 +389,7 @@ In **condensed** mode, all participants' values for one FORMAT key live in **one literal**: ```text -<…#call/4711/matrix/fmt/GT> vcfr:encodedValues "0/1\t0/0\t1/1\t./."^^vcfr:VCFTextVector . +<…#call/4711/matrix/fmt/GT> vcfc:encodedValues "0/1\t0/0\t1/1\t./."^^vcfc:VCFTextVector . ``` There is no triple to remove for one sample. Graph-pattern access control cannot @@ -400,7 +400,7 @@ Two consequences: 1. **Redaction must rewrite the literal.** `vcfp:maskVectorPositions` replaces the masked participant's token with `.`, which is the VCF missing marker and - keeps the vector aligned with `vcfr:sampleIndex` — alignment the format + keeps the vector aligned with `vcfc:sampleIndex` — alignment the format depends on. Dropping a position instead would silently shift every downstream sample's value, which is a data-corruption bug wearing a privacy feature's clothing. @@ -458,7 +458,7 @@ linkset node in [`datalinking-design.md`](datalinking-design.md#5-output-and-pro vcfp:policyDigest "sha256:9f2c…" ; vcfp:duoVersion "2024-11-03" ; vcfp:pseudonymKeyId "release-2026-09-key-3" ; - vcfp:representation vcfr:ExpandedRepresentation ; + vcfp:representation vcfc:ExpandedRepresentation ; vcfp:triplesWithheld 1840221 ; vcfp:samplesWithheld 2 ; vcfp:thresholdApplied 5 ; @@ -489,7 +489,7 @@ release that fails one is not published. This turns "the APOE region was excluded" from a claim into a measurement — the distinction [`validation-methodology.md`](validation-methodology.md) is built around. -**SHACL for shape-level guarantees.** "No `vcfr:sampleName` appears anywhere" is +**SHACL for shape-level guarantees.** "No `vcfc:sampleName` appears anywhere" is naturally a shape constraint, and the `--shacl-shapes` layer already exists. **Mutation testing the redactor.** Add a mutation class to diff --git a/docs/rml-mappings.md b/docs/rml-mappings.md index 5f43668..4c76062 100644 --- a/docs/rml-mappings.md +++ b/docs/rml-mappings.md @@ -78,20 +78,87 @@ helper-table consumers works in both modes. ## 3. What a custom mapping does *not* control -This is the part most easily missed. Three families of triple are emitted by the -wrapper, not by RML, and they appear in your graph regardless of your mapping: +This is the part most easily missed, and it grew with the move to the VCF Core +vocabulary. Several families of triple are emitted by the wrapper, not by RML, +and they appear in your graph regardless of your mapping. + +The split follows one rule: + +> **The RML mapping carries every field whose RDF datatype is the same for every +> row. The wrapper carries everything else.** + +"Everything else" is two things. A value that may be the VCF missing token `.` +needs `"."^^vcfc:Null` on some rows and a typed literal on others, and RML +cannot switch an object's datatype per row. A value that has to be *decomposed* +— an angle-bracketed header line, an ALT list, a GT string, a comma-separated +`Number=A`/`R`/`G` payload — would need a materialized helper table whose size +is the product of its dimensions. | Triples | Turned off with | | --- | --- | -| Genotypes (`SampleCall`/`FormatFieldValue`, or the condensed equivalents) | nothing — one emitter always runs; choose which with `--sample-representation` | -| `QUAL`, and structured `InfoFieldValue` nodes | `--info-representation raw` still emits QUAL | -| Header-line subclasses and lifted FILTER/ALT/contig/INFO/FORMAT attributes | `--header-representation basic` | +| `ID`, `ALT`, `QUAL`, `FILTER`, `infoRaw` — the fixed fields that may be missing | nothing; they are the record's mandatory content | +| `fileDate` — no mandated format in VCF, so the value must be inspected to type it | nothing | +| Genotypes (`SampleCall`/`FormatFieldValue`/`Genotype`, or the condensed `CohortCallMatrix`/`FormatValueVector`) | nothing — one emitter always runs; choose which with `--sample-representation` | +| Structured `InfoFieldValue` nodes, the allele layer, `FieldValueItem` decomposition, and the SV carriers | `--info-representation raw` (`QUAL`, `ID`, `ALT`, `FILTER` and `infoRaw` are still emitted) | +| Header-line subclasses, `HeaderAttribute` resources, and the lifted INFO/FORMAT/FILTER/ALT/contig/META/SAMPLE/PEDIGREE attributes | `--header-representation basic` | +| The `vcfc:VCF4xFile` version class | nothing directly; `--vcf-version` selects which one, and a mapping without the sentinel emits none | + +Two of those are worth calling out because they are new: + +- **The allele layer travels with `--info-representation structured`** (the + default). `vcfc:hasReferenceAllele` and `vcfc:hasAltAllele` are minted there + because the `Number=A`/`R`/`G` value items join to them; turning INFO down to + `raw` turns the alleles off too. +- **`--header-representation basic` no longer produces a SHACL-conformant + graph.** `vcfc:StructuredHeaderLineShape` requires at least one + `vcfc:hasAttribute` on every structured header line, and `basic` emits no + subclass and no attributes at all. It remains available as the minimal, + fastest header form; it is simply not a conforming one. + +The reasons are in [`architecture.md`](architecture.md#4-where-the-split-leaks-and-why). +It is a real constraint on the extension point, not an oversight, but a mapping +author who assumes `--rules` is the sole source of truth for the graph will be +surprised. + +## 3a. The version sentinel + +The mapping carries one placeholder the wrapper resolves per input: + +```turtle +rr:subjectMap [ + rr:template "file://{SOURCE_FILE}" ; + rr:class vcfc:VCFFile ; + rr:class vcfc:VCFVersionFile # rewritten per input +] ; +``` -The reasons are in [`architecture.md`](architecture.md#4-where-the-split-leaks-and-why): -RML cannot choose a datatype or a class per row, and the alternatives would -require materializing helper tables. It is a real constraint on the extension -point, not an oversight, but a mapping author who assumes `--rules` is the sole -source of truth for the graph will be surprised. +`vcfc:VCFVersionFile` is not a vocabulary term. The wrapper rewrites it, exactly +the way it rewrites the five `csvw:url` paths, to the `vcfc:VCF4xFile` subclass +for the version that input's `##fileformat` line declares — which activates that +version's SHACL overlay gate. When the version has no conformance overlay +(VCFv4.0, or a missing or malformed line) it is rewritten to `vcfc:VCFFile`, +which the subject map already asserts, so the graph never claims a gate that +cannot be checked and never gains an undefined term. + +One mapping is therefore the single source of truth for all five versions, +rather than five near-identical copies that would drift apart. + +`vcf-rdfizer-rules check` reports whether your mapping has the sentinel. A +mapping without it still converts, and the version-dependent *emitter* behaviour +still follows each input's own `##fileformat` line — only the class is missing, +so the version overlay's gate stays inactive: + +``` +Warnings: + - No vcfc:VCFVersionFile sentinel in the file subject map. … +``` + +To render a materialized per-version mapping — to read it, or to hand-edit one +version's rules — render it for a specific version and inspect the result: + +```bash +vcf-rdfizer-rules init -o my_rules.ttl # keeps the sentinel +``` ## 4. What a custom mapping costs in validation @@ -144,8 +211,11 @@ Recommendations that come from experience rather than from the checker: 1. **Preserve the stable subject templates** (`file://{SOURCE_FILE}`, `file://{SOURCE_FILE}#record/{ROW_ID}`, `file://{SOURCE_FILE}#call/{ROW_ID}`) if you want joins with the wrapper-emitted triples to keep working. The - genotype, QUAL, INFO and header emitters all mint IRIs against those - templates and will not follow a mapping that changes them. + genotype, record-detail, allele and header emitters all mint IRIs against + those templates and will not follow a mapping that changes them. The allele + and genotype layers additionally depend on + `file://{SOURCE_FILE}#record/{ROW_ID}/allele/{n}` and + `file://{SOURCE_FILE}#samples/{SAMPLE_URI_ID}`. 2. **Add, don't replace.** A mapping that extends the default with additional `rr:TriplesMap` blocks keeps the full validation suite meaningful for the parts it did not change; one that rebuilds the graph from scratch does not. @@ -154,11 +224,30 @@ Recommendations that come from experience rather than from the checker: ## 6. SHACL -The SHACL constraints are maintained in the vocabulary repository, not here: -[`vcf-rdfizer-vocabulary.shacl.ttl`](https://github.com/ecrum19/VCF-RDFizer-vocabulary/blob/main/shacl/vcf-rdfizer-vocabulary.shacl.ttl). +The SHACL constraints are maintained in the vocabulary repository, not here. +VCF Core ships two profiles: + +- `shacl/vcf-core-vocabulary.shacl.ttl` — the portable profile: required + structural links, VCF 4.5 lexical patterns, and field type/arity constraints. +- `shacl/vcf-core-vocabulary-sparql.shacl.ttl` — cross-resource checks that need + SPARQL: header and record ordering, sample uniqueness, GT-first FORMAT order, + and the rule that a graph must not mix expanded sample calls with condensed + call matrices. + Point `--shacl-shapes` at them to check a graph structurally, independently of -the VCF. Note the known contradiction inside the published shapes, recorded in -[`vcf-coverage.md`](vcf-coverage.md#an-open-conflict-inside-the-vocabulary). +the VCF. Both profiles need the bundled ontology as an ontology graph and RDFS +inference enabled — subclass-based targets and `sh:class` constraints do not +resolve without it (a concrete `INFOHeaderLine` is also an +`InfoFieldDefinition`, and only inference makes that true). + +The default mapping's output validates against both profiles with zero +violations in both representation profiles. One inconsistency inside the +published vocabulary is worth knowing about: the ontology declares +`rdfs:range xsd:positiveInteger` on the ordinal properties while every SHACL +shape constrains them with `sh:datatype xsd:integer`, and a SHACL datatype +constraint compares the datatype IRI exactly. This converter emits +`xsd:integer`, which satisfies both. See +[`validation-migration-notes.md`](validation-migration-notes.md#3-ordinals-are-now-xsdinteger-not-xsdpositiveinteger). --- @@ -168,3 +257,5 @@ the VCF. Note the known contradiction inside the published shapes, recorded in - [Architecture](architecture.md) — why some triples bypass RML - [Validation](validation.md) — what changes under a custom mapping - [`rules/README.md`](../rules/README.md) — the mapping directory itself +- [Validation migration notes](validation-migration-notes.md) — what the move to + VCF Core leaves to do in the validation suite diff --git a/docs/roadmap.md b/docs/roadmap.md index fdf3c14..69115dc 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -9,30 +9,51 @@ block something else, not by effort. --- +## Resolved by the move to the VCF Core vocabulary + +Both items that previously blocked publication are closed. They are kept here +briefly because the reasoning is referenced elsewhere. + +### ~~1. Vocabulary coverage for the condensed representation~~ — **done** + +The 17 condensed-representation terms the conversion emitted without an +ontology behind them — `CohortCallMatrix`, `FormatValueVector`, `SampleSet`, +`VCFSample`, `VCFTextVector`, `representationProfile`, `sampleIndex` and the +rest — are all defined in VCF Core, with SHACL shapes. Condensed graphs are +ontology-backed and citable as linked data. + +### ~~2. The SHACL / missing-value contradiction~~ — **done** + +`vcfc:VCFRecordShape` now accepts `xsd:string` or `vcfc:Null` for `vcfc:alt`, so +a record with `ALT=.` satisfies both the shape and `vcfc:missingValuePolicy`. +`vcfc:VariantCallShape` likewise accepts the full VCF Float lexical space for +`qual`. + ## Blocking publication -### 1. Vocabulary coverage for the condensed representation +### ~~1. The validation suite has not been migrated~~ — **done** -The conversion emits 17 terms that `https://w3id.org/vcf-rdfizer/vocab#` does -not define — `CohortCallMatrix`, `FormatValueVector`, `SampleSet`, `VCFSample`, -`VCFTextVector`, `representationProfile`, `sampleIndex` and the rest. They do -not dereference, so **condensed graphs are not ontology-backed**. +The suite passes: 415 tests, mutation score 96/113 (85%) across 60 mutations. +The runner and the wrapper now share one vocabulary module instead of mirroring +each other, and the census derives every new resource family from the VCF. Ten +of the eighteen new mutations are recorded gaps, each with what would close it. +What changed and what remains: +[`validation-migration-notes.md`](validation-migration-notes.md). -The work is in the vocabulary repository, not here. Until it lands, the -condensed representation is usable but not citable as linked data. -Full list: [`vcf-coverage.md`](vcf-coverage.md#vocabulary-alignment). +### 2. SHACL conformance is not a test -### 2. The SHACL / missing-value contradiction +Checking the output against the vocabulary's own SHACL profiles found four real +modelling bugs during the migration, all of the same kind: a resource typed into +a class whose shape requires a property the record did not supply. That is a +cheap, strong invariant and it should not be a manual step. It needs `pyshacl` +and `rdflib` as dev dependencies and access to the vocabulary's `ontology/` and +`shacl/` directories. -`vcfr:missingValuePolicy` requires `"."^^vcfr:Null` for a missing token; -`VCFRecordShape` constrains `vcfr:alt` to `sh:datatype xsd:string`. A record with -`ALT=.` cannot satisfy both, so it is impossible for the tool to be conformant. +### ~~3. Ordinal datatype inconsistency in the vocabulary~~ — **done** -The fix is a decision in the vocabulary: either relax the `alt`/`ref`/`chrom` -shapes to `sh:or([xsd:string] [vcfr:Null])` — as the `qual` shape already does — -or drop the missing-value policy for those fields. The conversion currently -follows the policy. -[Detail](vcf-coverage.md#an-open-conflict-inside-the-vocabulary). +VCF Core now supplies `vcfc:IntegerLiteralShape`, which accepts `xsd:integer` +and every integer-derived XSD datatype with the bound applied numerically. The +ontology range and the shapes no longer disagree. ## Known defects @@ -53,11 +74,11 @@ Small change; it makes the custom-mapping extension point actually usable. From [`vcf-coverage.md`](vcf-coverage.md#remaining-gaps): -- **`vcfr:contigCount` is counted, not read.** A wrong derived contig total is +- **`vcfc:contigCount` is counted, not read.** A wrong derived contig total is undetected. Needs the value in a comparison, not just the predicate in the census. - **Header line values are not compared.** `q08` compares how many lines carry - each key and `q10` their types; `vcfr:headerValue` itself is only counted. The + each key and `q10` their types; `vcfc:headerValue` itself is only counted. The structured attributes that matter are already covered. Both are query-set additions with matching mutation-catalogue entries, so @@ -68,14 +89,16 @@ closing either one will *fail* the mutation harness until ### 5. Data linking as a plug-in system -The largest planned addition: let users connect the graph to external resources -(rsIDs, genes, clinical assertions, frequencies) through declarative, -distributable linker plugins rather than by patching the tool. +An initial implementation now connects the graph through declarative, +distributable linker plug-ins, with examples of all three tiers: dbSNP token +links, a synthetic GFF3 interval bundle, and an Ensembl API resolver. Full design, including the three join strategies, the three plugin tiers, the network safeguards, the provenance model and the build order, is in -[`datalinking-design.md`](datalinking-design.md). Nothing is implemented yet; -the design exists to fix the extension contract before code depends on it. +[`datalinking-design.md`](datalinking-design.md). The implemented contract and +commands are in [`datalinking.md`](datalinking.md). Allele joins/normalization, +link merging, and plug-in validation/mutation auto-discovery remain planned; +the manifest vocabulary is provisional. The hardest part is not the plugin system — it is allele normalization (§9 of that document), because an under-matching join looks exactly like a true diff --git a/docs/sample-representation-guide.md b/docs/sample-representation-guide.md index 287c112..60fc8dd 100644 --- a/docs/sample-representation-guide.md +++ b/docs/sample-representation-guide.md @@ -45,24 +45,41 @@ that is much more economical for large cohorts. ## 2. Expanded representation: one RDF object per sample value Expanded mode preserves the original, explicit vocabulary model. For every -variant/sample pair, VCF-RDFizer creates a `vcfr:SampleCall`. For every FORMAT -field in that pair, it creates a `vcfr:FormatFieldValue`. +variant/sample pair, VCF-RDFizer creates a `vcfc:SampleCall`. For every FORMAT +field in that pair, it creates a `vcfc:FormatFieldValue`. For the example above, the conceptual graph includes resources like these (the full output has one line per RDF statement): ```text - vcfr:hasSampleCall . + vcfc:hasSampleCall . - a vcfr:SampleCall ; - vcfr:sampleId "SAMPLE_A" ; - vcfr:hasFormatValue . + a vcfc:SampleCall ; + vcfc:sampleId "SAMPLE_A" ; + vcfc:forSample ; + vcfc:hasFormatValue ; + vcfc:hasGenotype . - a vcfr:FormatFieldValue ; - vcfr:fieldValue "0/1" . + a vcfc:FormatFieldValue ; + vcfc:declaredBy ; + vcfc:fieldValue "0/1" . + + + a vcfc:Genotype ; + vcfc:genotypeString "0/1"^^vcfc:GenotypeString ; + vcfc:ploidy 2 ; + vcfc:phasingStatus vcfc:Unphased ; + vcfc:hasAlleleCall , + . + + + a vcfc:GenotypeAlleleCall ; + vcfc:callIndex 1 ; + vcfc:isNoCall false ; + vcfc:calledAllele . ``` The same structure is repeated for `DP` and `AD`, and then repeated again for @@ -73,14 +90,22 @@ The same structure is repeated for `DP` and `AD`, and then repeated again for Expanded mode makes each value easy to address directly: - a consumer can find one sample call without decoding a vector; -- a consumer can ask for one FORMAT field as one RDF resource; -- existing consumers that expect `SampleCall` and `FormatFieldValue` can use - the graph directly; -- the sample identifier is attached to every sample-call resource. +- a consumer can ask for one FORMAT field as one RDF resource, and follow + `vcfc:declaredBy` to the `##FORMAT` declaration that defines it; +- the sample identifier is attached to every sample-call resource, and + `vcfc:forSample` additionally gives it a reusable, file-scoped identity, so a + sample is a resource rather than a repeated literal; +- **genotypes are queryable directly.** `GT` is parsed into an ordered + `vcfc:Genotype`: a consumer can filter on `vcfc:phasingStatus`, count + `vcfc:ploidy`, or join `vcfc:calledAllele` straight to the record's allele + resources — without string-matching `"0/1"` or `"0|1"` in SPARQL. `FT`, + `PS`/`PSL`, `LAA`, the copy-number and haplotype keys, and the `M`/`DPM`/`ADM` + base modifications get their own resources on the same principle. The VCF file is marked with -`vcfr:representationProfile vcfr:ExpandedRepresentation`, so a consumer can -identify the graph shape explicitly. +`vcfc:representationProfile vcfc:ExpandedRepresentation`, so a consumer can +identify the graph shape explicitly. The SPARQL SHACL profile enforces that a +graph never carries both profiles at once. ### Expanded growth @@ -97,15 +122,18 @@ V × S SampleCall resources V × S × F FormatFieldValue resources ``` -In the simplified case where each sample call has three structural statements -(link, type, and sample ID), and each FORMAT value has three statements (link, -type, and value), the sample portion of the graph contains approximately: +In the simplified case where each sample call has four structural statements +(link, type, sample ID, and `forSample`), and each FORMAT value has four +statements (link, type, `declaredBy`, and value), the sample portion of the +graph contains approximately: ```text -3 × (V × S) + 3 × (V × S × F) +4 × (V × S) + 4 × (V × S × F) ``` -statements, before counting the rest of the VCF graph. +statements, before counting the parsed genotype layer and the rest of the VCF +graph. A diploid `GT` adds roughly nine more statements per sample call: five +for the `vcfc:Genotype` and four for each `vcfc:GenotypeAlleleCall`. For the worked example (`V=1`, `S=3`, `F=3`): @@ -113,9 +141,16 @@ For the worked example (`V=1`, `S=3`, `F=3`): |---|---:| | `SampleCall` resources | 3 | | `FormatFieldValue` resources | 9 | -| Approximate sample-related statements | 36 | +| `Genotype` resources | 3 | +| `GenotypeAlleleCall` resources | 6 | +| Approximate sample-related statements | 75 | +| File-level `SampleSet` + `VCFSample` statements | 18 | | Representation-profile statement | 1 | +The genotype layer makes expanded mode more expensive than it was, which sharpens +rather than changes the trade-off below: expanded mode buys direct queryability +at a cost that multiplies by both samples and FORMAT fields. + The exact number can vary when values are missing or when custom mappings add properties, but the important pattern is the multiplication by both samples and FORMAT fields. @@ -130,15 +165,15 @@ For the same example, the graph first declares a reusable sample set: ```text - a vcfr:SampleSet ; - vcfr:hasSample ; - vcfr:hasSample ; - vcfr:hasSample . + a vcfc:SampleSet ; + vcfc:hasSample ; + vcfc:hasSample ; + vcfc:hasSample . - a vcfr:VCFSample ; - vcfr:sampleName "SAMPLE_A" ; - vcfr:sampleIndex "1" . + a vcfc:VCFSample ; + vcfc:sampleName "SAMPLE_A" ; + vcfc:sampleIndex "1" . ``` The variant then has one cohort matrix. The matrix points back to the sample @@ -146,14 +181,14 @@ set and has one vector for each FORMAT key: ```text - a vcfr:CohortCallMatrix ; - vcfr:appliesToSampleSet ; - vcfr:hasFormatValueVector . + a vcfc:CohortCallMatrix ; + vcfc:appliesToSampleSet ; + vcfc:hasFormatValueVector . - a vcfr:FormatValueVector ; - vcfr:valueEncoding vcfr:VCFTextVector ; - vcfr:encodedValues "0/1\t0/0\t1/1" . + a vcfc:FormatValueVector ; + vcfc:valueEncoding vcfc:VCFTextVector ; + vcfc:encodedValues "0/1\t0/0\t1/1" . ``` The three tab-separated items in `encodedValues` are in `sampleIndex` order: @@ -170,7 +205,7 @@ it is not treated as a sample separator. If a value is absent, the vector uses `.` to keep every sample position aligned. The file is marked with -`vcfr:representationProfile vcfr:CondensedRepresentation`. +`vcfc:representationProfile vcfc:CondensedRepresentation`. ### What condensed mode provides @@ -187,6 +222,18 @@ Condensed mode therefore moves repetition from RDF structure into the literal payload of a vector. It is a storage and graph-shape optimization, not a loss of genotype information. +**What it does not carry.** Condensed mode stops at the vector: it derives no +`vcfc:Genotype`, `vcfc:PhaseSet`, `vcfc:LocalAlleleSet` or +`vcfc:BaseModification`. Those are one resource per sample per record, which is +precisely the growth this profile exists to prevent. The values are still all +there — inside the vectors — but a SPARQL engine cannot filter on them without +a decoder or an application-level vector function. If you need to query +genotypes directly, that is the argument for expanded mode. + +Everything *not* per-sample is identical in both profiles: the header layer, the +allele layer, structured INFO with its value items, and the SV carriers are all +emitted the same way. + ### Condensed growth Using the same variables, condensed mode creates approximately: @@ -369,7 +416,7 @@ text values. See the [GeoSPARQL function table](https://graphdb.ontotext.com/doc and [GraphDB GeoSPARQL extensions](https://graphdb.ontotext.com/documentation/11.5/sparql-ext-functions-reference.html#geosparql-extension-functions). Our condensed value is instead a normal RDF string associated with -`vcfr:VCFTextVector`, for example: +`vcfc:VCFTextVector`, for example: ```text "0/1\t0/0\t1/1" @@ -390,13 +437,13 @@ each split item. The implementation is described as using Java's could look like this: ```sparql -PREFIX vcfr: +PREFIX vcfc: PREFIX spif: SELECT ?vector ?token WHERE { - ?vector a vcfr:FormatValueVector ; - vcfr:valueEncoding vcfr:VCFTextVector ; - vcfr:encodedValues ?encoded . + ?vector a vcfc:FormatValueVector ; + vcfc:valueEncoding vcfc:VCFTextVector ; + vcfc:encodedValues ?encoded . ?token spif:split (STR(?encoded) "\t") . } ``` @@ -415,7 +462,7 @@ generate a sequence of integers, but the reference does not provide a direct that `spif:split` alone is not a complete, reliable sample lookup mechanism. The page also lists RDF-list functions such as `list:index` and -`list:length`. Those operate on RDF Collections. `vcfr:encodedValues` is a +`list:length`. Those operate on RDF Collections. `vcfc:encodedValues` is a single string literal, not an RDF Collection, so these functions do not apply unless the data model is changed to materialize every vector item as list structure. That would reintroduce much of the per-item RDF overhead that @@ -433,7 +480,7 @@ they do not automatically parse a persisted VCF vector literal. | `spif:for` | Generate expected sample positions | Helpful support function, but does not pair positions with split tokens | | `list:index` / `list:length` | Index RDF Collections | Not applicable to the current string encoding | | `helper:tuple` / `helper:iterate` | Work with internal query lists | Not a persisted-vector parser | -| A custom `vcfr:` vector function | Return value at a sample index | Most direct future SPARQL integration | +| A custom `vcfc:` vector function | Return value at a sample index | Most direct future SPARQL integration | | Application-side parsing | Decode one selected vector after retrieval | Best portable near-term approach | GraphDB explicitly labels these as extensions beyond the W3C SPARQL @@ -453,16 +500,16 @@ returns both the position and the value. Conceptually, it could have a function or magic-predicate contract like: ```text -vcfr:vectorValue(?vector, ?sampleIndex) → ?value +vcfc:vectorValue(?vector, ?sampleIndex) → ?value ``` or: ```text -?vector vcfr:valueAt (?sampleIndex ?value) +?vector vcfc:valueAt (?sampleIndex ?value) ``` -For a sample-aware form, the function could accept the `vcfr:VCFSample` IRI +For a sample-aware form, the function could accept the `vcfc:VCFSample` IRI instead of an integer, resolve that resource's `sampleIndex`, and then extract the matching token. Returning the index as well as the value would make it possible to validate that a vector has the expected number of positions. @@ -523,7 +570,7 @@ Large multi-sample cohort + storage/scale focus → condensed ``` If a consumer is unsure which graph it received, inspect the file’s -`vcfr:representationProfile` value before querying. That profile is the +`vcfc:representationProfile` value before querying. That profile is the explicit signal that tells the consumer whether sample values are represented as individual resources or as ordered vectors. diff --git a/docs/validation-methodology.md b/docs/validation-methodology.md index 47000a6..adc3cc5 100644 --- a/docs/validation-methodology.md +++ b/docs/validation-methodology.md @@ -94,7 +94,7 @@ clean result. The SHACL layer earned its place immediately: it found three conformance violations the other two could not see, two of which were fixed (QUAL typed as -a plain literal instead of `xsd:decimal`/`vcfr:Null`; `##fileDate` untyped +a plain literal instead of `xsd:decimal`/`vcfc:Null`; `##fileDate` untyped instead of `xsd:date`) and one of which is a contradiction inside the vocabulary itself, recorded in [`vcf-coverage.md`](vcf-coverage.md). diff --git a/docs/validation-migration-notes.md b/docs/validation-migration-notes.md new file mode 100644 index 0000000..6f70518 --- /dev/null +++ b/docs/validation-migration-notes.md @@ -0,0 +1,178 @@ +# Validation and the VCF Core migration + +The conversion targets the **VCF Core vocabulary** +(`https://w3id.org/vcf-core/vocab#`, prefix `vcfc:`), replacing the retired +VCF-RDFizer vocabulary (`https://w3id.org/vcf-rdfizer/vocab#`, prefix `vcfr:`), +and follows each input's declared VCF version. The validation suite has been +migrated with it. This file records what changed, what it found, and what is +still open. + +**Status: the suite passes.** 415 tests, no failures. The mutation score is +96/113 (85%) across 60 mutations, each listed with its expected detector. + +--- + +## What the migration preserved + +The suite's design is what made this tractable, so it was kept intact: + +- **One declarative fixture, three derived artifacts.** + `test/validation_fixtures.py` still declares one VCF and derives the graph and + the oracle from it, so a fixture change cannot make the two disagree. +- **Coverage measured, not asserted.** A mutation the suite cannot catch is + recorded with `known_undetected`, and the harness asserts it is *still* not + caught — so closing a gap fails a test and forces the catalogue and the + coverage documentation to be updated together. +- **Expectations derived from the VCF, never from the mapping.** Deriving them + from `default_rules.ttl` would make the mapping test itself, which is how QUAL + once stayed invisible. `base_triples()` still hand-writes what the mapping + produces, so a mapping change the fixture does not follow shows up as a + mismatch rather than being absorbed. + +## What changed + +### 1. One vocabulary module, not two mirrored copies + +`src/validation/validation_runner.py` carried its own copies of +`HEADER_LINE_CLASSES`, `rml_uri_component`, `parse_structured_header_fields` and +`parse_info_entries`, with unit tests asserting the copies stayed identical to +the wrapper's. They are gone: both import `vcf_rdfizer_vocab`, and the +`Dockerfile` copies that module next to the runner so the import resolves the +same way inside the container and on the host. + +That removes the drift the tests were policing rather than continuing to police +it. `test_header_class_map_matches_the_wrapper` now compares a module against +itself; it is kept as a guard against someone reintroducing a second copy. + +### 2. The census learned the new layers + +`expected_census` asserts an exact inventory — *these* predicates and classes +with *these* counts and nothing else — so every family the VCF Core emitters +added had to become derivable from the VCF. Two shared functions do that: + +- `emitted_header_counters(header_lines)` — header-line subclasses, + `vcfc:HeaderAttribute` resources, the INFO/FORMAT/FILTER/ALT/contig/META/ + SAMPLE/PEDIGREE declaration properties, `assemblyUrl`, `pedigreeDbUrl`. +- `emitted_record_counters(rows, samples, …)` — the allele layer, the + `vcfc:FieldValueItem` decomposition, the breakend components, and — reported + separately, because it is expanded-only — the parsed genotype layer. + +Both are called by `parse_vcf` inside the container and by the fixture's +`parser_summary` on the host, so the two oracles cannot disagree about what the +graph should contain. `parse_vcf` stays representation-independent, which is +what lets one parse serve both censuses. + +### 3. `vcfc:VCF4xFile` is part of the expectation + +The mapping's version sentinel resolves to the subclass for the version the +input declares, so the census expects that class. The fixture derives it from +its own `FILE_FORMAT` rather than hard-coding it, so changing the fixture's +declared version changes the expected graph with it. + +### 4. Fields that moved from RML to the wrapper + +`ID`, `ALT`, `FILTER` and `infoRaw` left `base_triples()`: each may be the VCF +missing token, which the vocabulary requires as `"."^^vcfc:Null`, and RML cannot +switch an object's datatype per row. The counts are unchanged — one per record — +so only the fixture's account of *which half emits them* moved. + +`preflight_missing_token_conformance` is consequently expected to return zero +rows for any input now. Before the migration, a record with `ID=.` produced a +plain `"."` literal and the check reported it. + +### 5. Ordinals are `xsd:integer` + +The fixture's `XSD_POSITIVE_INTEGER` is gone. VCF Core's +`vcfc:IntegerLiteralShape` accepts `xsd:integer` and every integer-derived +datatype with the bound applied numerically, so the ontology range and the +shapes no longer disagree. + +## What the suite found + +Running it against the migrated emitters surfaced a real conversion defect that +neither the unit tests nor SHACL had caught: + +> **Every declared INFO and FORMAT definition was emitted twice.** The header +> emitter produced a declaration's `fieldId`/`fieldNumber`/`fieldType`/ +> `fieldDescription` from the `##` line, and the value emitters produced the +> same four triples at the same header-line IRI when the key was first +> referenced — twenty duplicate triples in the fixture graph alone. + +`preflight_duplicate_triples` caught it: a check that compares the parsed triple +count against the distinct count. No shape can express that, because a duplicate +triple is not a distinct RDF statement at all — SHACL validated the graph +happily, since the duplicate simply vanishes on parse. It is a good argument for +keeping the graph-integrity preflights alongside the shape layer rather than +treating SHACL as a replacement for them. + +The fix gives the header emitter sole ownership of any declaration derived from +a `##` line. The value emitters cite it with `vcfc:declaredBy` and invent a +definition only for a key no header declared. +`test_declared_field_definitions_are_emitted_exactly_once` pins it. + +## Recorded gaps + +Ten of the 18 new mutations are undetected, each with what would close it. They +fall into three groups. + +**Values counted but not compared.** `corrupt_allele_value`, +`corrupt_allele_kind`, `corrupt_attribute_value`, `corrupt_value_item_allele`, +`corrupt_called_allele`, `flip_phasing_status`, `wrong_declaration_owner`. +Dropping any of these resources is caught by the census; corrupting one inside +is not. Closing them means digests over those resources, the way `q11` covers +the record fields. Several are already checked by the vocabulary's own +`vcf-core-consistency.shacl.ttl`, which verifies raw/parsed agreement — so the +cheapest route is probably to run that profile rather than to reimplement it in +SPARQL. + +**Ordering, covered in a different layer.** `corrupt_record_index` is undetected +by the queries. The SPARQL SHACL profile enforces index uniqueness, nondecreasing +POS within a CHROM block, and contiguous CHROM blocks. + +**One profile-specific asymmetry, worth stating.** `corrupt_sample_index` is +detected in the condensed profile and not in the expanded one, and the catalogue +carries it as two entries for that reason. In the condensed profile the ordinal +is what associates a vector position with a sample, so corrupting it moves +genotypes between samples and `q05`/`q06` shift. In the expanded profile each +`SampleCall` carries its own `vcfc:sampleId`, so nothing reads the ordinal. That +is a real difference in what the two profiles depend on, not a testing +oversight. + +## Still open + +**SHACL conformance is not a test.** Validating the output against the +vocabulary's profiles found seven modelling bugs during this work and is a +stronger, cheaper invariant than a hand-derived oracle. It needs `pyshacl` and +`rdflib` as dev dependencies plus a path to the vocabulary's `ontology/`, +`ontology/versions/` and `shacl/` directories, and it is slow — roughly ten +seconds per graph with the full profile set — so it belongs in a marked slow +suite rather than the default unit run. + +**The fixture declares one VCF version.** Version-dependent behaviour is covered +by unit tests and by the version overlays, not by the mutation harness. The +vocabulary repository ships one example VCF per version under +`examples/vcf-versions/`, a ready-made corpus for a per-version fixture matrix +if that coverage is wanted. + +**The SV carriers have no mutation.** They are represented and conformant, and +the census counts the families the fixture exercises, but the fixture contains +no structural variants, so `emitted_record_counters` is untested against +breakends, tandem repeats and reference blocks. Adding one SV record to the +fixture would exercise them through the existing machinery. + +## How conformance was verified + +Separately from the suite, the converter's output was validated against the +**complete** published profile set — the portable, SPARQL and consistency +profiles plus all five version overlays — with pySHACL, the bundled ontology +plus every `ontology/versions/*.ttl`, and RDFS inference. That is the +configuration the vocabulary's own `tests/validate_shacl.py` uses. + +Inputs: all ten example VCFs from the vocabulary repository (4.1 through 4.5, +including the breakend, gVCF, repeat and condensed-cohort fixtures), and a +hand-written stress file rendered for every version plus a 4.0 variant, in both +representation profiles. + +Result: **zero violations** across 19 graphs. The only results are `sh:Warning`s +that VCF 4.5 recommends `Source` and `Version` on `##INFO` declarations — a +property of the input files, which the converter correctly does not fabricate. diff --git a/docs/validation.md b/docs/validation.md index 5b45242..fcd7d45 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -24,6 +24,67 @@ Raptor syntax validation and for the SPARQL queries, and removes any temporary decode before the container exits. No decoded RDF is written beneath `--out`; only reports are retained. +## Choosing an engine, and what happens when it cannot keep up + +**Comunica has no persistent index.** `comunica-sparql-file` parses the whole +source into an in-memory store, answers one query, and exits — so a run pays +that parse **once per query**, 27 times. That is fine for a fixture and +unworkable for a cohort-scale graph, where the parse alone can exceed the +per-query timeout. + +**QLever builds an index once** and answers every query from it. On a large +graph the index build dominates and the queries are cheap. This is why a graph +can pass with QLever and time out with Comunica: it is a scale property of the +engine, not a disagreement about the data. + +| Graph size | Recommended | +| --- | --- | +| Fixtures, small VCFs | `--validation-engine comunica` (default; no index build) | +| Anything above a few GiB of N-Triples | `--validation-engine qlever`, or validate the indexed artifact with `--validate-artifacts hdt` | + +Above 4 GiB the runner warns before it starts, states the worst case at the +current timeout, and names the alternatives. + +### If validation seems to hang + +It is almost certainly an engine that cannot answer the graph inside +`--validation-query-timeout` (default 3600s). Since this is per query and there +are 27 of them, a run that answers none of them used to take 27 hours per engine +per target before reporting anything. + +That no longer happens: the first query to exceed the timeout abandons that +engine's remaining queries, and the report records which query tripped it and +how many were skipped: + +```json +{"status": "EXECUTION_FAILED", + "abandoned": "q01_record_density_1mb exceeded the 3600s per-query timeout; skipped 26 further queries …", + "queriesRun": 1, "queriesPlanned": 27} +``` + +Options from there: + +```bash +# Index once and query from it, instead of re-parsing per query. +vcf-rdfizer --mode full -i cohort.vcf.gz --validate --validation-engine qlever -o ./out + +# Or validate the HDT artifact, which is already indexed. +vcf-rdfizer --mode full -i cohort.vcf.gz --validate --validate-artifacts hdt -o ./out + +# Or allow longer per query, with a ceiling on the whole engine. +vcf-rdfizer --mode full -i cohort.vcf.gz --validate \ + --validation-query-timeout 14400 --validation-time-budget 86400 -o ./out +``` + +`--validation-continue-after-query-timeout` restores the old behaviour of +running every query regardless; it is off by default because the remaining +queries are no easier than the one that just failed. + +Queries run in their own process session, so a timeout kills the engine along +with its `/usr/bin/time` wrapper. Before that fix the engine survived the +timeout still holding the whole graph in memory, and enough of those pushed the +host into swap — which is what made a slow step look like a stuck one. + ## Run it Use the representation selected when the RDF was created. @@ -376,7 +437,7 @@ anomaly count. Reports carry both, plus `sampleTruncated`, so a graph with ten million anomalies is never confused with one that has a hundred. `--strict-conformance` promotes a missing-token conformance failure (a plain -`"."` literal not typed as `vcfr:Null`) from a report-only observation to a +`"."` literal not typed as `vcfc:Null`) from a report-only observation to a validation failure. ### SHACL @@ -416,7 +477,7 @@ backed by a named mutation in [`test/validation_mutations.py`](../test/validation_mutations.py), so a change that closes a gap fails a test rather than passing silently. -**`vcfr:contigCount` is counted, not read.** The census asserts the predicate is +**`vcfc:contigCount` is counted, not read.** The census asserts the predicate is present the expected number of times; nothing compares its *value*. A derived contig total that is simply wrong passes. This is the one mutation in the catalogue that is still undetected. @@ -424,7 +485,7 @@ catalogue that is still undetected. **Header line values are compared only through their structured form.** The attributes that matter - `filterId`, `altId`, `contigId`, contig length/md5/ assembly, and the INFO/FORMAT declarations - are lifted into their own -properties and compared. The raw `vcfr:headerValue` literal itself is counted +properties and compared. The raw `vcfc:headerValue` literal itself is counted but never read. **Multi-valued INFO fields keep only their lexical value.** A `Number=1` INFO diff --git a/docs/vcf-coverage.md b/docs/vcf-coverage.md index 37d1a6d..3feab54 100644 --- a/docs/vcf-coverage.md +++ b/docs/vcf-coverage.md @@ -15,66 +15,135 @@ Two independent questions per row, deliberately kept apart: mutation in [`test/validation_mutations.py`](../test/validation_mutations.py), not by inspection. -Last measured mutation score: **76/78 (97%)** across 42 distinct mutations. -Regenerate with: +Last measured mutation score: **96/113 (85%)** across 60 distinct mutations, +measured against the VCF Core vocabulary. Regenerate with: ```bash VCF_RDFIZER_MUTATION_REPORT=mutation-score.json \ python -m unittest test.test_validation_mutation_unit ``` +The score fell from 97% because the denominator grew, not because anything +regressed: the migration added 18 mutations covering the layers VCF Core +introduced, and 10 of those are recorded gaps. That is the methodology working +as intended — a new capability that nothing checks shows up as a lower score +rather than as silent confidence. Every gap is listed under +[Remaining gaps](#remaining-gaps) with what would close it. + --- ## Fixed fields (the eight mandatory columns) | VCF element | `records.tsv` | RDF term | Represented | Validated by | Mutation | | --- | --- | --- | --- | --- | --- | -| CHROM | `CHROM` | `vcfr:chrom` | yes | `q01`, `q11` | `corrupt_chrom` | -| POS | `POS` | `vcfr:pos` (`xsd:integer`) | yes | `q01`, `q11`, `preflight_position_datatype` | `corrupt_pos`, `drop_pos`, `retype_pos_as_string` | +| CHROM | `CHROM` | `vcfc:chrom` | yes | `q01`, `q11` | `corrupt_chrom` | +| POS | `POS` | `vcfc:pos` (`xsd:integer`) | yes | `q01`, `q11`, `preflight_position_datatype` | `corrupt_pos`, `drop_pos`, `retype_pos_as_string` | | POS ↔ record binding | — | — | yes | `q11_record_digest` | `permute_pos` | -| ID | `ID` | `vcfr:recordId` | yes | `q11_record_digest` | (covered by digest) | -| REF | `REF` | `vcfr:ref` | yes | `q02`, `q03`, `q11` | `corrupt_alt` | -| ALT | `ALT` | `vcfr:alt` | yes | `q02`, `q03`, `q11` | `corrupt_alt` | +| ID | `ID` | `vcfc:recordId` | yes | `q11_record_digest` | (covered by digest) | +| REF | `REF` | `vcfc:ref` | yes | `q02`, `q03`, `q11` | `corrupt_alt` | +| ALT | `ALT` | `vcfc:alt` | yes | `q02`, `q03`, `q11` | `corrupt_alt` | | REF/ALT ↔ record binding | — | — | yes | `q11_record_digest` | `permute_ref_alt` | -| QUAL | `QUAL` | `vcfr:qual` (`xsd:decimal` / `vcfr:Null`) | yes | `q09`, `q11` | `drop_qual`, `drop_all_qual`, `corrupt_qual` | -| FILTER | `FILTER` | `vcfr:filter` | yes | `q04` (exact lexical), `q11` | `drop_filter`, `corrupt_filter_lexical` | -| INFO (raw) | `INFO` | `vcfr:infoRaw` | yes | `q11_record_digest` | `corrupt_info_raw` | -| INFO (structured) | `INFO` | `vcfr:hasInfoValue` → `vcfr:InfoFieldValue` → `vcfr:declaredBy` | yes | `q09`, `q12_info_value_digest` | `drop_info_value`, `corrupt_info_value`, `retype_info_value` | +| QUAL | `QUAL` | `vcfc:qual` (`xsd:decimal` / `vcfc:Null`) | yes | `q09`, `q11` | `drop_qual`, `drop_all_qual`, `corrupt_qual` | +| FILTER | `FILTER` | `vcfc:filter` | yes | `q04` (exact lexical), `q11` | `drop_filter`, `corrupt_filter_lexical` | +| INFO (raw) | `INFO` | `vcfc:infoRaw` | yes | `q11_record_digest` | `corrupt_info_raw` | +| INFO (structured) | `INFO` | `vcfc:hasInfoValue` → `vcfc:InfoFieldValue` → `vcfc:declaredBy` | yes | `q09`, `q12_info_value_digest` | `drop_info_value`, `corrupt_info_value`, `retype_info_value` | -INFO values carry `vcfr:fieldValue` plus a typed `fieldValueInteger` / +INFO values carry `vcfc:fieldValue` plus a typed `fieldValueInteger` / `fieldValueDecimal` when the declaration says `Number=1` and the value parses; -a Flag entry carries `vcfr:fieldValueBoolean true`. A multi-valued field -(`Number=A/R/G/.`) keeps only the lexical value, because the vocabulary's IRI -template gives one node per key. +a Flag entry carries `vcfc:fieldValueBoolean true`. A multi-valued field is no +longer lexical-only: `Number=A`/`R`/`LA`/`LR`/`G`/`LG`/`P` values are decomposed +into ordered `vcfc:FieldValueItem` resources joined to their allele with +`vcfc:forAllele`, or carrying a genotype/GT ordinal. + +### Allele layer + +| VCF element | RDF term | Represented | Validated by | Mutation | +| --- | --- | --- | --- | --- | +| REF as an ordered allele | `vcfc:hasReferenceAllele` → `vcfc:ReferenceAllele` (`alleleIndex` 0) | yes | — | — | +| Each ALT item, in source order | `vcfc:hasAltAllele` → `vcfc:AltAllele` (`alleleIndex` 1..n) | yes | — | — | +| ALT syntactic category | `vcfc:alleleKind` | yes | — | — | +| Symbolic ALT reserved type | `vcfc:svType` → `vcfc:SymbolicAlleleType` | yes | — | — | +| Symbolic ALT ↔ `##ALT` declaration | `vcfc:declaredByAlt` | yes | — | — | +| Breakend structure | `vcfc:Breakend`, `breakendOrientation`, `breakendReplacementString`, `isSingleBreakend` | yes | — | — | +| CHROM ↔ contig declaration | `vcfc:chromosome` | yes | — | — | +| Indexed field values | `vcfc:hasValueItem` → `vcfc:FieldValueItem` (`valueIndex`, `itemValue`, `forAllele`, `tupleArity`) | yes | — | — | + +### Structural variation + +| VCF element | RDF term | Represented | Validated by | Mutation | +| --- | --- | --- | --- | --- | +| `SVLEN` | `vcfc:svLength` on the allele | yes | — | — | +| `SVCLAIM` | `vcfc:svClaim` → `vcfc:SVClaim` | yes | — | — | +| `IMPRECISE`, `NOVEL` | `vcfc:isImprecise`, `vcfc:isNovel` | yes | — | — | +| `EVENT` + `EVENTTYPE` | `vcfc:inEvent` → `vcfc:VariantEvent` with `vcfc:eventType` | yes (both keys required) | — | — | +| `CIPOS`, `CIEND` | `vcfc:posConfidenceInterval` / `endConfidenceInterval` → FALDO `InRangePosition` | yes | — | — | +| `CILEN`, `CICN` | `vcfc:ConfidenceInterval` with `ciLower` / `ciUpper` | yes | — | — | +| `RN` + `RUS`/`RUL`/`RUC`/`RB` | `vcfc:TandemRepeatAllele` → `vcfc:RepeatSequence` | yes (`RN` required) | — | — | +| gVCF `<*>` with `END` | `vcfc:ReferenceBlock`, `endPosition`, `referenceBlockLength` | yes (`END` required) | — | — | ## Genotype fields | VCF element | RDF term | Represented | Validated by | Mutation | | --- | --- | --- | --- | --- | -| FORMAT declaration | `vcfr:formatRaw` | yes | `q09_predicate_census` | — | -| Sample identity | `vcfr:sampleId` / `vcfr:sampleName` | yes | `preflight_sample_gt_inventory`, `q09` | `drop_sample_call` | -| GT values | `vcfr:hasFormatValue` → `vcfr:fieldValue` | yes | `q05`, `q06`, `q13` | `flip_genotype` | -| Non-GT FORMAT (DP, GQ, AD, PL…) | `vcfr:FormatFieldValue` / `vcfr:FormatValueVector` | yes | `q13_format_value_digest` | `drop_format_value_dp`, `corrupt_format_value_dp`, `corrupt_format_vector` | +| FORMAT declaration | `vcfc:formatRaw` | yes | `q09_predicate_census` | — | +| Sample identity | `vcfc:sampleId` / `vcfc:sampleName` | yes | `preflight_sample_gt_inventory`, `q09` | `drop_sample_call` | +| GT values (lexical) | `vcfc:hasFormatValue` → `vcfc:fieldValue` | yes | `q05`, `q06`, `q13` | `flip_genotype` | +| Non-GT FORMAT (DP, GQ, AD, PL…) | `vcfc:FormatFieldValue` / `vcfc:FormatValueVector` | yes | `q13_format_value_digest` | `drop_format_value_dp`, `corrupt_format_value_dp`, `corrupt_format_vector` | +| Reusable sample identity | `vcfc:SampleSet` → `vcfc:VCFSample` (`sampleName`, `sampleIndex`); `vcfc:forSample` from a `SampleCall` | yes, both profiles | — | — | +| `#CHROM` sample columns | `vcfc:ColumnHeaderLine` → `vcfc:hasGenotypeColumns` | yes | — | — | +| FORMAT value ↔ declaration | `vcfc:declaredBy` → `vcfc:FormatFieldDefinition` | yes | — | — | + +**Parsed genotype layer — expanded profile only.** The condensed profile keeps +these values inside `vcfc:encodedValues`, which is the point of the profile. + +| VCF element | RDF term | Represented | Validated by | Mutation | +| --- | --- | --- | --- | --- | +| `GT` parsed | `vcfc:hasGenotype` → `vcfc:Genotype` (`genotypeString`, `ploidy`) | expanded only | — | — | +| Phasing (`\|` vs `/`) | `vcfc:phasingStatus` → `vcfc:Phased` / `vcfc:Unphased` | expanded only | — | — | +| Each GT position | `vcfc:hasAlleleCall` → `vcfc:GenotypeAlleleCall` (`callIndex`, `isNoCall`, `calledAllele`) | expanded only | — | — | +| `FT` | `vcfc:sampleFilter` | expanded only | — | — | +| `PS`/`PSL`/`PSO`/`PSQ` | `vcfc:inPhaseSet` → `vcfc:PhaseSet` | expanded only | — | — | +| `LAA` | `vcfc:hasLocalAlleleSet` → `vcfc:LocalAlleleSet` | expanded only | — | — | +| `CN`/`CNQ`/`CNL`/`CNP` | `vcfc:copyNumber` and friends | expanded only | — | — | +| `HAP`/`AHAP` | `vcfc:haplotypeId`, `vcfc:ancestralHaplotypeId` | expanded only | — | — | +| `M*`/`DPM*`/`ADM*` | `vcfc:BaseModification` with a ChEBI `modifiedResidue` | expanded only | — | — | ## Header section | VCF element | RDF term | Represented | Validated by | Mutation | | --- | --- | --- | --- | --- | -| `##` line count and keys | `vcfr:HeaderLine` + `vcfr:headerKey` | yes | `q08_header_line_census` | `drop_header_line` | +| `##` line count and keys | `vcfc:HeaderLine` + `vcfc:headerKey` | yes | `q08_header_line_census` | `drop_header_line` | | Line type | `FileFormatHeaderLine`, `INFOHeaderLine`, `ContigHeaderLine`, … | yes | `q10_class_census` | `untype_header_line` | -| `##fileformat` | `vcfr:fileFormat` | yes | `q07_file_metadata` | `corrupt_file_metadata` | -| `##reference` | `vcfr:referenceGenome` | yes | `q07_file_metadata` | `drop_reference_genome` | -| `##source` | `vcfr:sourceSoftware` | yes | `q07_file_metadata` | — | -| `##fileDate` | `vcfr:fileDate` (`xsd:date` when the form allows) | yes | `q09_predicate_census` | `drop_file_date` | -| `##FILTER` | `vcfr:FilterDefinition` + `vcfr:filterId` | yes | `q09`, `q10` | `drop_filter_definition` | -| `##ALT` | `vcfr:AltDefinition` + `vcfr:altId` | yes | `q09`, `q10` | `drop_alt_definition` | -| `##contig` | `vcfr:ContigHeaderLine` + `contigId`/`contigLength`/`contigMd5`/`contigAssembly` | yes | `q09`, `q10` | `drop_contig_attribute` | -| `##INFO` / `##FORMAT` definitions | `vcfr:InfoFieldDefinition` / `vcfr:FormatFieldDefinition` with `fieldId`/`fieldNumber`/`fieldType`/`fieldDescription` | yes | `q09`, `q10` | `drop_info_definition` | -| Header line *values* | `vcfr:headerValue` | yes | `q09` (count only) | — | -| `vcfr:contigCount` | derived scalar | yes | **count only, not value** | `corrupt_contig_count` | - -An unrecognized `##` key keeps only the base `vcfr:HeaderLine` type: inventing -a subclass would put a term in the graph that the vocabulary does not define. +| `##fileformat` | `vcfc:fileFormat` | yes | `q07_file_metadata` | `corrupt_file_metadata` | +| `##reference` | `vcfc:referenceGenome` | yes | `q07_file_metadata` | `drop_reference_genome` | +| `##source` | `vcfc:sourceSoftware` | yes | `q07_file_metadata` | — | +| `##fileDate` | `vcfc:fileDate` (`xsd:date` when the form allows) | yes | `q09_predicate_census` | `drop_file_date` | +| `##FILTER` | `vcfc:FilterDefinition` + `vcfc:filterId` | yes | `q09`, `q10` | `drop_filter_definition` | +| `##ALT` | `vcfc:AltDefinition` + `vcfc:altId` | yes | `q09`, `q10` | `drop_alt_definition` | +| `##contig` | `vcfc:ContigHeaderLine` + `contigId`/`contigLength` (`xsd:integer`)/`contigMd5`/`contigAssembly`/`contigUrl` (`xsd:anyURI`) | yes | `q09`, `q10` | `drop_contig_attribute` | +| `##INFO` / `##FORMAT` definitions | `vcfc:InfoFieldDefinition` / `vcfc:FormatFieldDefinition` with `fieldId`/`fieldNumber`/`fieldType`/`fieldDescription` | yes | `q09`, `q10` | `drop_info_definition` | +| `Number` arity and fixed count | `vcfc:fieldArity` → `vcfc:VCFNumberArity`, `vcfc:fieldNumberInteger` | yes | — | — | +| `##INFO` `Source` / `Version` | `vcfc:fieldSource`, `vcfc:fieldVersion` | yes | — | — | +| Structured-line attributes (all of them) | `vcfc:hasAttribute` → `vcfc:HeaderAttribute` (`attributeKey`, `attributeValue`, `attributeIndex`) | yes | — | — | +| `#CHROM` column-header line | `vcfc:ColumnHeaderLine` + `vcfc:hasColumnHeader` | yes | — | — | +| Header line order | `vcfc:lineIndex` (`xsd:integer`) | yes | — | — | +| `##assembly` | `vcfc:AssemblyHeaderLine` + `vcfc:assemblyUrl` | yes | — | — | +| `##pedigreeDB` | `vcfc:PedigreeDBHeaderLine` + `vcfc:pedigreeDbUrl` | yes | — | — | +| `##META` | `vcfc:MetaHeaderLine` / `vcfc:MetaDefinition` + `vcfc:metaAllowedValue` | yes | — | — | +| `##SAMPLE` | `vcfc:SampleHeaderLine` → `vcfc:declaresSample` → `vcfc:SampleDeclaration` | yes | — | — | +| `##PEDIGREE` | `vcfc:PedigreeHeaderLine` + `pedigreeMother`/`pedigreeFather`/`pedigreeOriginal`/`pedigreeAncestor` + `ancestorRole` | yes | — | — | +| Header line *values* | `vcfc:headerValue` | yes | `q09` (count only) | — | +| `vcfc:contigCount` | derived scalar | yes | **count only, not value** | `corrupt_contig_count` | + +An unrecognized `##` key is typed as `vcfc:StructuredHeaderLine` or +`vcfc:UnstructuredHeaderLine` according to the form of its value, which keeps it +queryable without inventing a subclass the vocabulary does not define. + +Every structured line carries its `vcfc:HeaderAttribute` resources whether or +not it also has dedicated properties. `vcfc:StructuredHeaderLineShape` requires +at least one, and they are the only way an implementation-defined attribute +stays queryable. This is why `--header-representation basic` does not produce a +conformant graph. ## Graph-level properties @@ -86,6 +155,8 @@ a subclass would put a term in the graph that the vocabulary does not define. | Missing-token policy | `preflight_missing_token_conformance`, fatal under `--strict-conformance` | `plain_dot_literal` | | Representation profile | `preflight_representation_profile` | `wrong_representation_profile` | | Record count | q01/q02/q04 totals | `drop_record`, `duplicate_record` | +| Record order (`vcfc:recordIndex`) | SPARQL SHACL profile: uniqueness, nondecreasing POS within CHROM, contiguous CHROM blocks | — | +| Expanded/condensed exclusivity | SPARQL SHACL profile | `wrong_representation_profile` | | **No extraneous triples** | `q09_predicate_census` (extra rows) | `spurious_predicate` | | **No blank nodes** | `preflight_blank_nodes` | `introduce_blank_node`, `blank_node_object` | | **No empty or whitespace-only terms** | `preflight_empty_values` | `empty_literal`, `whitespace_only_literal` | @@ -95,50 +166,121 @@ a subclass would put a term in the graph that the vocabulary does not define. ## Remaining gaps -1. **`vcfr:contigCount` is counted, not read.** A wrong derived contig total is +1. **`vcfc:contigCount` is counted, not read.** A wrong derived contig total is not detected. Closing it needs the value in a comparison, not just the predicate in the census. 2. **Header line values are not compared.** `q08` compares how many lines carry - each key and `q10` their types, but `vcfr:headerValue` itself is only + each key and `q10` their types, but `vcfc:headerValue` itself is only counted. The structured attributes that matter (`filterId`, `contigId`, …) *are* covered. 3. **The census assumes the shipped mapping.** A custom `--rules` changes the inventory and IRI templates by design, so `q09`–`q13` fall back to report-only. That is correct, but it means a custom mapping is validated only by the aggregate comparisons. +4. **The new layers are counted but their values are not compared.** The + allele layer, header attributes, value items and the parsed genotype layer + all appear in the predicate and class censuses, so *dropping* one is caught. + Corrupting a value inside one is not: `corrupt_allele_value`, + `corrupt_allele_kind`, `corrupt_attribute_value`, `corrupt_value_item_allele`, + `corrupt_called_allele`, `flip_phasing_status` and `wrong_declaration_owner` + are all recorded as undetected. Closing them needs digests over those + resources, the way `q11` already covers the record fields — or leaning on the + vocabulary's own consistency SHACL profile, which checks several of these + agreements directly. +5. **Ordering is checked by shapes, not by queries.** `vcfc:lineIndex` and + `vcfc:recordIndex` are counted, but `corrupt_record_index` is undetected by + the query layer. The SPARQL SHACL profile enforces uniqueness, nondecreasing + POS within a CHROM block, and contiguous CHROM blocks, so the coverage exists + — in a different layer. +6. **Version overlays have no mutation.** The converter detects each input's VCF + version and follows it, and `drop_version_class` / `wrong_version_class` + cover the file class. The version-dependent *behaviour* — per-ALT versus + per-record `CIPOS` linkage, the families a version does not define — is + covered by unit tests and by the version overlays themselves, not by the + mutation harness, because the fixture declares a single version. +7. **SHACL conformance is not yet a test.** It was checked by hand and found + seven real modelling bugs; wiring it in would make that a standing invariant. + It needs `pyshacl` and `rdflib` as dev dependencies. ## Vocabulary alignment -The tool emits 17 terms that `https://w3id.org/vcf-rdfizer/vocab#` does **not** -define — all belonging to the condensed representation: +The conversion targets the **VCF Core vocabulary**, +`https://w3id.org/vcf-core/vocab#` (prefix `vcfc:`), **published at 2.0.0** and +covering VCF 4.1 through 4.5. It replaces the retired +`https://w3id.org/vcf-rdfizer/vocab#`, which is **not** redirected: it serves a +deprecation document in which every former term is present, deprecated, and +linked to its successor. Only one term was renamed rather than re-namespaced — +`vcfr:DenseRepresentation` became `vcfc:ExpandedRepresentation`. + +The converter references the namespace, not a version IRI. The vocabulary's +release cadence is independent of this converter's, and pinning a version here +would go stale without adding anything: the namespace is what the emitted IRIs +actually contain. + + -`CohortCallMatrix`, `CondensedRepresentation`, `ExpandedRepresentation`, -`FormatValueVector`, `SampleSet`, `VCFSample`, `VCFTextVector`, -`appliesToSampleSet`, `encodedValues`, `hasCallMatrix`, `hasFormatValueVector`, -`hasSample`, `hasSampleSet`, `representationProfile`, `sampleIndex`, -`sampleName`, `valueEncoding` +### VCF version coverage -Dereferencing any of these returns nothing, so **condensed graphs are not -ontology-backed**. This is the one remaining publication blocker and is work in -the vocabulary repository, not here. +VCF Core supplies a conformance overlay per VCF version, and the converter +follows each input's own `##fileformat` line automatically. Coverage: + +| Version | Overlay | Detected | Notes | +| --- | --- | --- | --- | +| 4.0 | none claimed by the vocabulary | reported as unrecognized | converts with 4.5 rules and **no** `vcfc:VCF4xFile` class | +| 4.1 | `vcf-4.1.shacl.ttl` | ✓ `vcfc:VCF41File` | no `Number=R`; `CIPOS` is one pair per record | +| 4.2 | `vcf-4.2.shacl.ttl` | ✓ `vcfc:VCF42File` | `Number=R` added | +| 4.3 | `vcf-4.3.shacl.ttl` | ✓ `vcfc:VCF43File` | | +| 4.4 | `vcf-4.4.shacl.ttl` | ✓ `vcfc:VCF44File` | `Number=P`; tuples become per-ALT; `CILEN`/`CICN`/`EVENTTYPE` added | +| 4.5 | `vcf-4.5.shacl.ttl` | ✓ `vcfc:VCF45File` | `Number=LA/LR/LG/M`; local alleles and base modifications | + +See [`conversion.md`](conversion.md#4a-vcf-versions) for what each difference +changes in the emitted graph. + +### What the converter emits, versus what VCF Core can express + +VCF Core 2.0.0 defines 338 terms. The converter emits from most of them, and its +output is conformant, but the vocabulary can express more than the converter +currently derives. Ten families are entirely unemitted: + +| Family | Terms | What it would add | +| --- | --- | --- | +| Parsed FILTER | `filterStatus`, `FiltersPassed/Failed/NotApplied`, `FilterCode`, `hasFilterCode`, `declaredByFilter` | FILTER as resources joined to their `##FILTER` declarations, instead of only the raw string | +| Padding semantics | `PaddingInterpretation`, `paddingRule`, `paddingSide`, `paddingAnchorPosition`, `paddingBaseCount` and their individuals | Which base of REF/ALT is the VCF padding base, and why | +| Parsed FORMAT keys | `FormatKey`, `hasFormatKey`, `fieldIndex`, `keyPattern` | The FORMAT key list as ordered resources, not only `formatRaw` | +| Parsed record IDs | `RecordIdentifier`, `hasIdentifier`, `identifierValue`, `aliasOf` | The semicolon-separated ID column split into individual identifiers | +| Repeat units | `RepeatUnit`, `hasRepeatUnit`, `repeatUnitBases`, `rucConfidenceInterval`, `rbConfidenceInterval` | `RUB`-level detail below a repeat sequence | +| Breakend mates | `mateBreakend`, `partnerBreakend`, `insertedSequence`, `isTelomereBreakend` | Resolving a breakend to the record describing its mate | +| Local-allele membership | `LocalAlleleMembership`, `localAllele`, `localIndex` | LAA membership with its own index, beside the current `LocalAlleleSet` | +| Mixed phasing | `MixedPhasing`, `phaseIndicator`, `allelePhaseSet` | Per-position phase indicators rather than one status per genotype | +| Reference blocks | `hasReferenceBlock`, `blockAllele` | A record-level link to its gVCF block | +| Raw/decoded values | `rawValue`, `decodedValue`, `percentEncodingPolicy`, `sampleFieldsRaw` | Percent-decoded companions beside the lossless source values | -### An open conflict inside the vocabulary +**None of these is required for conformance.** Across 19 graphs — every example +VCF the vocabulary ships, plus a stress matrix for 4.0 through 4.5 in both +representation profiles — the complete profile set reports zero violations +without them. They are enrichment the vocabulary supports and the converter does +not yet derive. -Running SHACL surfaced a contradiction between two parts of the published -vocabulary that the tool cannot satisfy simultaneously: +This matters for benchmarking in one direction only: a benchmark of conversion +throughput, graph size or compression is measuring the converter's actual output +and is unaffected. A benchmark of *query* coverage against the vocabulary would +be measuring a subset, and should say so. -- `vcfr:missingValuePolicy` says a missing token SHOULD be `"."^^vcfr:Null`. -- `VCFRecordShape` constrains `vcfr:alt` to `sh:datatype xsd:string`. +### Conformance -A record with `ALT=.` therefore violates the shape no matter which rule the -conversion follows. The tool currently follows the missing-value policy. This -needs a decision in the vocabulary: either relax the `alt`/`ref`/`chrom` shapes -to `sh:or([xsd:string] [vcfr:Null])`, as the `qual` shape already does, or drop -the missing-value policy for those fields. +The default mapping's output validates against the **complete** published +profile set — the portable and SPARQL profiles, the consistency profile, and all +five version overlays — with **zero violations**, in both representation +profiles, checked with pySHACL using the bundled ontology plus every +`ontology/versions/*.ttl` and RDFS inference, which is the configuration the +vocabulary's own `tests/validate_shacl.py` uses. See +[`validation-migration-notes.md`](validation-migration-notes.md#how-this-was-verified) +for exactly what was covered. -Two shape violations found the same way have already been fixed here: QUAL is -now `xsd:decimal`/`vcfr:Null` rather than a plain literal, and `##fileDate` is -typed `xsd:date` when its form allows. +The only results reported are `sh:Warning`s where an input VCF omits the +`Source` and `Version` attributes that VCF 4.5 recommends on `##INFO` +declarations. Those are properties of the input, and the converter deliberately +does not fabricate them. --- diff --git a/examples/linking/README.md b/examples/linking/README.md new file mode 100644 index 0000000..152e2ef --- /dev/null +++ b/examples/linking/README.md @@ -0,0 +1,23 @@ +# Linking example input + +`example.vcf` has four artificial records with a GRCh38 reference declaration. +Its coordinates are chosen to exercise the synthetic `gene-demo` GFF3 intervals; +the rsIDs demonstrate token parsing and are not claims about those coordinates. + +```bash +vcf-rdfizer-link run -i examples/linking/example.vcf \ + --link rsid-dbsnp,gene-demo --offline \ + --links-cache ./example-cache -o ./example.links.nt +``` + +Expected links, excluding provenance: + +| VCF row | dbSNP tokens | Demo genes | +| --- | --- | --- | +| 1 | rs334 | A | +| 2 | rs699, rs334 | A, B | +| 3 | none | none | +| 4 | none | C | + +Seven links in total. Live resolver usage, caching and authoring are documented +in [`docs/datalinking.md`](../../docs/datalinking.md). diff --git a/examples/linking/example.vcf b/examples/linking/example.vcf new file mode 100644 index 0000000..26dbe6f --- /dev/null +++ b/examples/linking/example.vcf @@ -0,0 +1,8 @@ +##fileformat=VCFv4.3 +##reference=GRCh38 +##INFO= +#CHROM POS ID REF ALT QUAL FILTER INFO +1 100 rs334 A G . PASS RS=rs334 +1 190 rs699;rs334 AT A . PASS RS=rs699,rs334 +1 251 . C T . PASS . +2 20 local-id G A . PASS . diff --git a/pyproject.toml b/pyproject.toml index 695dcc5..203ed88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ classifiers = [ ] dependencies = [ "rich>=13.7.0", + "rdflib>=7.0.0", ] [project.urls] @@ -35,20 +36,19 @@ Issues = "https://github.com/ecrum19/VCF-RDFizer/issues" [project.scripts] vcf-rdfizer = "vcf_rdfizer:main" vcf-rdfizer-rules = "vcf_rdfizer_rules:main" +vcf-rdfizer-link = "vcf_rdfizer_link:main" [project.optional-dependencies] dev = [ "build>=1.2.2", "twine>=5.1.1", - # Test-only: an in-process SPARQL engine for the validation mutation harness, - # so it needs no Docker. The suite skips those tests when it is absent. - "rdflib>=7.0.0", ] [tool.setuptools] -py-modules = ["vcf_rdfizer", "vcf_rdfizer_gzip", "vcf_rdfizer_rules"] -packages = ["vcf_rdfizer_data", "vcf_rdfizer_data.rules"] +py-modules = ["vcf_rdfizer", "vcf_rdfizer_gzip", "vcf_rdfizer_rules", "vcf_rdfizer_link", "vcf_rdfizer_vocab"] +packages = ["vcf_rdfizer_data", "vcf_rdfizer_data.rules", "vcf_rdfizer_data.linkers", "vcf_rdfizer_linking"] include-package-data = true [tool.setuptools.package-data] "vcf_rdfizer_data.rules" = ["default_rules.ttl"] +"vcf_rdfizer_data.linkers" = ["*/linker.ttl", "*/resolver.py", "*/genes.gff3", "*/README.md"] diff --git a/rules/README.md b/rules/README.md index 32edbe1..b1a3584 100644 --- a/rules/README.md +++ b/rules/README.md @@ -18,7 +18,9 @@ See "Custom RML Mappings" in the top-level `README.md` for the full contract. - `default_rules.ttl` - Active default mapping for this repository. - - Targets the VCF-RDFizer vocabulary (`https://w3id.org/vcf-rdfizer/vocab#`). + - Targets the VCF Core vocabulary (`https://w3id.org/vcf-core/vocab#`, + prefix `vcfc:`), which replaces the retired + `https://w3id.org/vcf-rdfizer/vocab#`. No version IRI is pinned. - Uses template TSV paths: - `/data/tsv/file_metadata.tsv` - `/data/tsv/header_lines.tsv` @@ -60,15 +62,32 @@ after RMLStreamer emits the custom record-level graph. ## SHACL Notes -The related SHACL constraints are maintained in the vocabulary repository: +The related SHACL constraints are maintained in the vocabulary repository, in +two profiles: -- [vcf-rdfizer-vocabulary.shacl.ttl](https://github.com/ecrum19/VCF-RDFizer-vocabulary/blob/main/shacl/vcf-rdfizer-vocabulary.shacl.ttl) +- `shacl/vcf-core-vocabulary.shacl.ttl` — portable: structural links, VCF 4.5 + lexical patterns, field type and arity constraints. +- `shacl/vcf-core-vocabulary-sparql.shacl.ttl` — cross-resource: header and + record ordering, sample uniqueness, and the rule that a graph must not mix + expanded sample calls with condensed call matrices. -The default mapping is structured to align with those classes/properties, especially: +Both need the bundled ontology as an ontology graph and RDFS inference enabled. -- `vcfr:VCFFile` + `vcfr:hasHeader` -- `vcfr:VCFHeader` + `vcfr:hasHeaderLine` -- `vcfr:VCFRecord` core fields (`chrom`, `pos`, `ref`, `alt`) -- `vcfr:VariantCall` with raw call attributes -- expanded `vcfr:SampleCall` / `vcfr:FormatFieldValue` resources, or condensed - `vcfr:CohortCallMatrix` / `vcfr:FormatValueVector` resources +This mapping emits: + +- `vcfc:VCFFile` + `vcfc:hasHeader`, `vcfc:fileFormat`, `vcfc:sourceSoftware`, + `vcfc:referenceGenome` +- `vcfc:VCFHeader` + `vcfc:hasHeaderLine`, and `vcfc:hasColumnHeader` to the + `#CHROM` `vcfc:ColumnHeaderLine` +- `vcfc:HeaderLine` with `headerKey`, `headerValue` and `lineIndex` +- `vcfc:VCFRecord` with `chrom`, `pos`, `ref`, `recordIndex` and `hasCall` +- `vcfc:VariantCall` with `formatRaw` +- the expanded `vcfc:SampleCall` / `vcfc:FormatFieldValue` compatibility maps + +`ID`, `ALT`, `QUAL`, `FILTER` and `infoRaw` are **not** here. Each may be the +VCF missing token, which the vocabulary requires as `"."^^vcfc:Null`, and RML +cannot switch an object's datatype per row — so the wrapper emits them, along +with the header attributes, the allele layer, structured INFO, the SV carriers +and the genotype layer. The rule is stated at the top of `default_rules.ttl`: +**RML carries every field whose datatype is the same for every row; the wrapper +carries everything else.** diff --git a/rules/default_rules.ttl b/rules/default_rules.ttl index d229b3c..a4e0107 100644 --- a/rules/default_rules.ttl +++ b/rules/default_rules.ttl @@ -3,9 +3,17 @@ @prefix ql: . @prefix csvw: . @prefix xsd: . -@prefix vcfr: . +@prefix vcfc: . -# Default VCF-RDFizer RML rules. +# Default VCF-RDFizer RML rules, targeting the VCF Core vocabulary. +# +# Namespace +# --------- +# The target is https://w3id.org/vcf-core/vocab# (prefix vcfc:), which replaces +# the retired https://w3id.org/vcf-rdfizer/vocab# (prefix vcfr:). The retired +# namespace is not redirected: it serves a deprecation document in which every +# former term is linked to its successor. No version IRI is pinned; these rules +# target the namespace, whose release cadence is independent of the converter's. # # Expected TSV inputs produced by src/vcf_as_tsv.sh: # - /data/tsv/.file_metadata.tsv @@ -14,12 +22,60 @@ # - /data/tsv/.sample_calls.tsv (header-only compatibility source) # - /data/tsv/.sample_format_values.tsv (header-only compatibility source) # The wrapper rewrites the template paths below for each input sample. -# The wrapper selects exactly one direct sample emitter: expanded SampleCall / -# FormatFieldValue triples, or condensed SampleSet / CohortCallMatrix / -# FormatValueVector triples. The helper tables stay header-only in either mode. +# +# What is here and what is not +# ---------------------------- +# The division is a single rule: this mapping carries every field whose RDF +# datatype is the same for every row, and the wrapper's direct N-Triples +# emitters carry everything else. RML cannot choose an object datatype per row, +# and it cannot decompose one source cell into several resources without a +# materialized helper table whose size is the product of its dimensions. +# +# Emitted by the wrapper, not here: +# - ID, ALT, QUAL, FILTER and INFO. Each may be the VCF missing token, which the +# vocabulary requires as "."^^vcfc:Null rather than a plain string, so the +# datatype depends on the row. +# - fileDate. The published shape requires xsd:date, but ##fileDate has no +# mandated format in the VCF specification, so the value must be inspected. +# - The structured header representation: header-line subclasses, the +# vcfc:HeaderAttribute resources that vcfc:StructuredHeaderLineShape requires +# on every ##INFO/##FORMAT/##FILTER/##ALT/##contig/##META/##SAMPLE/##PEDIGREE +# line, and the INFO/FORMAT/FILTER/ALT/contig/META declaration properties. +# These all live inside one angle-bracketed cell. +# - The allele layer: vcfc:ReferenceAllele and vcfc:AltAllele resources with +# their index, kind, symbolic type and breakend components, parsed out of the +# REF and ALT columns. +# - The structured INFO representation, its vcfc:FieldValueItem decomposition, +# and the SV carriers derived from reserved INFO keys. +# - Genotype data. The wrapper selects exactly one direct sample emitter: +# expanded SampleCall / FormatFieldValue / Genotype triples, or condensed +# SampleSet / CohortCallMatrix / FormatValueVector triples. The helper tables +# stay header-only in either mode. +# +# Ordinals +# -------- +# vcfc:lineIndex and vcfc:recordIndex are typed xsd:integer, not +# xsd:positiveInteger. The SHACL profiles constrain every ordinal with +# sh:datatype xsd:integer plus a sh:minInclusive bound, and a SHACL datatype +# constraint compares the datatype IRI exactly. An xsd:integer literal +# satisfies both the shape and the ontology's xsd:positiveInteger range, since +# the value 1 belongs to that value space however it is written. +# +# VCF versions +# ------------ +# VCF Core supplies one SHACL overlay per VCF version, each scoped by the file's +# vcfc:fileFormat. Most of this mapping is version-neutral, because the fixed +# columns and the header-line structure do not change between 4.1 and 4.5. The +# one version-dependent thing RML can carry is the optional vcfc:VCF4xFile +# subclass on the file subject, which is the sentinel in <#VCFFileMap> below. +# +# The version-dependent *semantics* -- which INFO keys flatten a tuple, whether +# that tuple repeats per ALT allele, and whether the local-allele and +# base-modification FORMAT families exist -- are decompositions of one source +# cell, so they live in the wrapper's emitters like every other decomposition. # # Output format: -# - The default conversion now targets triples (N-Triples) without named graph terms. +# - The default conversion targets triples (N-Triples) without named graph terms. <#VCFFileMap> a rr:TriplesMap ; @@ -37,25 +93,30 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}" ; - rr:class vcfr:VCFFile + rr:class vcfc:VCFFile ; + # Version overlay. The wrapper rewrites this sentinel per input to the + # optional subclass for the version the file's ##fileformat line declares + # -- vcfc:VCF41File through vcfc:VCF45File -- which activates that version's + # SHACL gate. When the version has no conformance overlay (VCFv4.0, or a + # missing or malformed line) the sentinel is rewritten to vcfc:VCFFile, + # which is already asserted above, so the graph never claims a version gate + # it cannot support and never gains an undefined term. + rr:class vcfc:VCFVersionFile ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasHeader ; + rr:predicate vcfc:hasHeader ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#header" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:fileFormat ; + rr:predicate vcfc:fileFormat ; rr:objectMap [ rml:reference "FILE_FORMAT" ] ] ; - # fileDate is emitted by the wrapper: the published shape requires xsd:date, - # but ##fileDate has no mandated format in the VCF specification, so the - # value has to be inspected before it can be typed. rr:predicateObjectMap [ - rr:predicate vcfr:sourceSoftware ; + rr:predicate vcfc:sourceSoftware ; rr:objectMap [ rml:reference "SOURCE_SOFTWARE" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:referenceGenome ; + rr:predicate vcfc:referenceGenome ; rr:objectMap [ rml:reference "REFERENCE_GENOME" ] ] . @@ -75,9 +136,34 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#header" ; - rr:class vcfr:VCFHeader + rr:class vcfc:VCFHeader + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:hasColumnHeader ; + rr:objectMap [ rr:template "file://{SOURCE_FILE}#header/columns" ] + ] . + +# The mandatory #CHROM line. Its ordered sample columns are attached by the +# wrapper with vcfc:hasGenotypeColumns, because they live in the records TSV +# header rather than in a row of any source table. +<#ColumnHeaderLineMap> + a rr:TriplesMap ; + rml:logicalSource [ + rml:source [ + a csvw:Table ; + csvw:url "/data/tsv/file_metadata.tsv" ; + csvw:dialect [ + a csvw:Dialect ; + csvw:delimiter "\t" ; + csvw:headerRowCount 1 + ] + ] ; + rml:referenceFormulation ql:CSV ] ; - . + rr:subjectMap [ + rr:template "file://{SOURCE_FILE}#header/columns" ; + rr:class vcfc:ColumnHeaderLine + ] . # NOTE: # Use explicit link maps (template-based) instead of parentTriplesMap joins. @@ -100,7 +186,7 @@ rr:template "file://{SOURCE_FILE}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasRecord ; + rr:predicate vcfc:hasRecord ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#record/{ROW_ID}" ] @@ -124,12 +210,16 @@ rr:template "file://{SOURCE_FILE}#header" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasHeaderLine ; + rr:predicate vcfc:hasHeaderLine ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#header/line/{HEADER_INDEX}" ] ] . +# Every '##' line as a base vcfc:HeaderLine. The wrapper adds the subclass, the +# ordered vcfc:HeaderAttribute resources and the declaration properties. +# vcfc:lineIndex is what the SPARQL SHACL profile uses to check that header +# indices are unique and that ##fileformat is line 1. <#HeaderLineMap> a rr:TriplesMap ; rml:logicalSource [ @@ -146,17 +236,24 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#header/line/{HEADER_INDEX}" ; - rr:class vcfr:HeaderLine + rr:class vcfc:HeaderLine ] ; rr:predicateObjectMap [ - rr:predicate vcfr:headerKey ; + rr:predicate vcfc:headerKey ; rr:objectMap [ rml:reference "HEADER_KEY" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:headerValue ; + rr:predicate vcfc:headerValue ; rr:objectMap [ rml:reference "HEADER_VALUE" ] + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:lineIndex ; + rr:objectMap [ rml:reference "HEADER_INDEX" ; rr:datatype xsd:integer ] ] . +# CHROM, POS and REF are the three fixed fields VCF 4.5 forbids from being the +# missing token, so their datatype is fixed for every row and they belong here. +# ID and ALT may be missing and are emitted by the wrapper. <#VCFRecordMap> a rr:TriplesMap ; rml:logicalSource [ @@ -173,33 +270,32 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#record/{ROW_ID}" ; - rr:class vcfr:VCFRecord + rr:class vcfc:VCFRecord ] ; rr:predicateObjectMap [ - rr:predicate vcfr:chrom ; + rr:predicate vcfc:chrom ; rr:objectMap [ rml:reference "CHROM" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:pos ; + rr:predicate vcfc:pos ; rr:objectMap [ rml:reference "POS" ; rr:datatype xsd:integer ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:recordId ; - rr:objectMap [ rml:reference "ID" ] - ] ; - rr:predicateObjectMap [ - rr:predicate vcfr:ref ; + rr:predicate vcfc:ref ; rr:objectMap [ rml:reference "REF" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:alt ; - rr:objectMap [ rml:reference "ALT" ] + rr:predicate vcfc:recordIndex ; + rr:objectMap [ rml:reference "ROW_ID" ; rr:datatype xsd:integer ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasCall ; + rr:predicate vcfc:hasCall ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ] ] . +# FORMAT is the only call-level column whose datatype is fixed: VCF 4.5 defines +# it as a colon-separated key list with no missing form. QUAL, FILTER and INFO +# are emitted by the wrapper. <#VariantCallMap> a rr:TriplesMap ; rml:logicalSource [ @@ -216,21 +312,10 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ; - rr:class vcfr:VariantCall - ] ; - # QUAL is emitted by the wrapper, not here: the published SHACL shape - # requires xsd:decimal or vcfr:Null depending on whether the value is - # present, and RML cannot choose a datatype per row. - rr:predicateObjectMap [ - rr:predicate vcfr:filter ; - rr:objectMap [ rml:reference "FILTER" ] - ] ; - rr:predicateObjectMap [ - rr:predicate vcfr:infoRaw ; - rr:objectMap [ rml:reference "INFO" ] + rr:class vcfc:VariantCall ] ; rr:predicateObjectMap [ - rr:predicate vcfr:formatRaw ; + rr:predicate vcfc:formatRaw ; rr:objectMap [ rml:reference "FORMAT" ] ] . @@ -252,7 +337,7 @@ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasSampleCall ; + rr:predicate vcfc:hasSampleCall ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ] @@ -274,11 +359,17 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ; - rr:class vcfr:SampleCall + rr:class vcfc:SampleCall ] ; rr:predicateObjectMap [ - rr:predicate vcfr:sampleId ; + rr:predicate vcfc:sampleId ; rr:objectMap [ rml:reference "SAMPLE_ID" ] + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:forSample ; + rr:objectMap [ + rr:template "file://{SOURCE_FILE}#samples/{SAMPLE_URI_ID}" + ] ] . <#SampleCallToFormatValueLinkMap> @@ -299,7 +390,7 @@ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasFormatValue ; + rr:predicate vcfc:hasFormatValue ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}/fmt/{FORMAT_KEY}" ] @@ -321,9 +412,9 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}/fmt/{FORMAT_KEY}" ; - rr:class vcfr:FormatFieldValue + rr:class vcfc:FormatFieldValue ] ; rr:predicateObjectMap [ - rr:predicate vcfr:fieldValue ; + rr:predicate vcfc:fieldValue ; rr:objectMap [ rml:reference "FORMAT_VALUE" ] ] . diff --git a/src/run_conversion.sh b/src/run_conversion.sh index 3affc27..1e81d79 100644 --- a/src/run_conversion.sh +++ b/src/run_conversion.sh @@ -307,7 +307,7 @@ count_triples_json() { # Replace plain VCF null marker literals (`"."`) with typed null literals. # Ontology alignment: -# "." -> "."^^vcfr:Null +# "." -> "."^^vcfc:Null # # The rewrite is per-line and has no cross-line context, so it is applied to # each RMLStreamer part as it is streamed into the aggregate. Running it as a diff --git a/src/validation/queries/common/preflight_blank_nodes.rq b/src/validation/queries/common/preflight_blank_nodes.rq index bc217a3..9edffc2 100644 --- a/src/validation/queries/common/preflight_blank_nodes.rq +++ b/src/validation/queries/common/preflight_blank_nodes.rq @@ -1,8 +1,8 @@ -PREFIX vcfr: +PREFIX vcfc: # Blank nodes anywhere in the graph. # -# Every class in the VCF-RDFizer vocabulary declares an vcfr:iriTemplate, so a +# Every class in the VCF-RDFizer vocabulary declares an vcfc:iriTemplate, so a # blank node means a term map produced no IRI. That is always a defect here: # blank-node identity is scoped to the file, so the record and value digests # could not address such a node, and neither could anything downstream that diff --git a/src/validation/queries/common/preflight_blank_nodes_count.rq b/src/validation/queries/common/preflight_blank_nodes_count.rq index 8cfd553..4e459b8 100644 --- a/src/validation/queries/common/preflight_blank_nodes_count.rq +++ b/src/validation/queries/common/preflight_blank_nodes_count.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of triples involving a blank node. SELECT (COUNT(*) AS ?anomalyCount) diff --git a/src/validation/queries/common/preflight_distinct_triple_count.rq b/src/validation/queries/common/preflight_distinct_triple_count.rq index 6b23075..94f4313 100644 --- a/src/validation/queries/common/preflight_distinct_triple_count.rq +++ b/src/validation/queries/common/preflight_distinct_triple_count.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # How many distinct triples the graph contains. # diff --git a/src/validation/queries/common/preflight_empty_values.rq b/src/validation/queries/common/preflight_empty_values.rq index 2d0effb..e811ef4 100644 --- a/src/validation/queries/common/preflight_empty_values.rq +++ b/src/validation/queries/common/preflight_empty_values.rq @@ -1,10 +1,10 @@ -PREFIX vcfr: +PREFIX vcfc: # Empty or whitespace-only terms. # # The pipeline should never materialize one. RML emits no triple for an empty # reference, and every direct emitter either guards on a non-empty value or -# substitutes the VCF missing token, which becomes "."^^vcfr:Null. An empty +# substitutes the VCF missing token, which becomes "."^^vcfc:Null. An empty # literal therefore means a value was lost rather than marked missing, and an # empty IRI means a template substitution collapsed. # diff --git a/src/validation/queries/common/preflight_empty_values_count.rq b/src/validation/queries/common/preflight_empty_values_count.rq index 022c095..780d464 100644 --- a/src/validation/queries/common/preflight_empty_values_count.rq +++ b/src/validation/queries/common/preflight_empty_values_count.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of triples carrying an empty or whitespace-only term. SELECT (COUNT(*) AS ?anomalyCount) diff --git a/src/validation/queries/common/preflight_missing_token_conformance.rq b/src/validation/queries/common/preflight_missing_token_conformance.rq index bfbec42..7aaf36e 100644 --- a/src/validation/queries/common/preflight_missing_token_conformance.rq +++ b/src/validation/queries/common/preflight_missing_token_conformance.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?s ?p ?o (DATATYPE(?o) AS ?datatype) WHERE { ?s ?p ?o . FILTER(ISLITERAL(?o) && STR(?o) = ".") - FILTER(DATATYPE(?o) != vcfr:Null) + FILTER(DATATYPE(?o) != vcfc:Null) } LIMIT 100 diff --git a/src/validation/queries/common/preflight_missing_token_conformance_count.rq b/src/validation/queries/common/preflight_missing_token_conformance_count.rq index a909af3..f77867e 100644 --- a/src/validation/queries/common/preflight_missing_token_conformance_count.rq +++ b/src/validation/queries/common/preflight_missing_token_conformance_count.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of missing tokens serialized as a plain "." literal. SELECT (COUNT(*) AS ?anomalyCount) WHERE { ?s ?p ?o . FILTER(ISLITERAL(?o) && STR(?o) = ".") - FILTER(DATATYPE(?o) != vcfr:Null) + FILTER(DATATYPE(?o) != vcfc:Null) } diff --git a/src/validation/queries/common/preflight_position_datatype.rq b/src/validation/queries/common/preflight_position_datatype.rq index 132a55e..cff817c 100644 --- a/src/validation/queries/common/preflight_position_datatype.rq +++ b/src/validation/queries/common/preflight_position_datatype.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: PREFIX xsd: # POS must carry an integer datatype, never a plain string or a fractional type. @@ -11,7 +11,7 @@ PREFIX xsd: # xsd:decimal, xsd:double, a plain literal - is still reported. SELECT ?record ?pos (DATATYPE(?pos) AS ?datatype) WHERE { - ?record a vcfr:VCFRecord ; vcfr:pos ?pos . + ?record a vcfc:VCFRecord ; vcfc:pos ?pos . FILTER(DATATYPE(?pos) NOT IN ( xsd:integer, xsd:int, xsd:long, xsd:short, xsd:byte, xsd:nonNegativeInteger, xsd:positiveInteger, diff --git a/src/validation/queries/common/preflight_position_datatype_count.rq b/src/validation/queries/common/preflight_position_datatype_count.rq index e773e8e..ed89f84 100644 --- a/src/validation/queries/common/preflight_position_datatype_count.rq +++ b/src/validation/queries/common/preflight_position_datatype_count.rq @@ -1,10 +1,10 @@ -PREFIX vcfr: +PREFIX vcfc: PREFIX xsd: # Exact number of POS values outside the XSD integer family. SELECT (COUNT(*) AS ?anomalyCount) WHERE { - ?record a vcfr:VCFRecord ; vcfr:pos ?pos . + ?record a vcfc:VCFRecord ; vcfc:pos ?pos . FILTER(DATATYPE(?pos) NOT IN ( xsd:integer, xsd:int, xsd:long, xsd:short, xsd:byte, xsd:nonNegativeInteger, xsd:positiveInteger, diff --git a/src/validation/queries/common/preflight_record_cardinality.rq b/src/validation/queries/common/preflight_record_cardinality.rq index 5b683cb..c05fd1a 100644 --- a/src/validation/queries/common/preflight_record_cardinality.rq +++ b/src/validation/queries/common/preflight_record_cardinality.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?record (COUNT(DISTINCT ?chrom) AS ?chromCount) @@ -7,12 +7,12 @@ SELECT ?record (COUNT(DISTINCT ?alt) AS ?altCount) (COUNT(DISTINCT ?call) AS ?callCount) WHERE { - ?record a vcfr:VCFRecord . - OPTIONAL { ?record vcfr:chrom ?chrom } - OPTIONAL { ?record vcfr:pos ?pos } - OPTIONAL { ?record vcfr:ref ?ref } - OPTIONAL { ?record vcfr:alt ?alt } - OPTIONAL { ?record vcfr:hasCall ?call } + ?record a vcfc:VCFRecord . + OPTIONAL { ?record vcfc:chrom ?chrom } + OPTIONAL { ?record vcfc:pos ?pos } + OPTIONAL { ?record vcfc:ref ?ref } + OPTIONAL { ?record vcfc:alt ?alt } + OPTIONAL { ?record vcfc:hasCall ?call } } GROUP BY ?record HAVING(COUNT(DISTINCT ?chrom) != 1 || COUNT(DISTINCT ?pos) != 1 || COUNT(DISTINCT ?ref) != 1 || COUNT(DISTINCT ?alt) != 1 || COUNT(DISTINCT ?call) != 1) diff --git a/src/validation/queries/common/preflight_record_cardinality_count.rq b/src/validation/queries/common/preflight_record_cardinality_count.rq index 1f25ced..8d4d81b 100644 --- a/src/validation/queries/common/preflight_record_cardinality_count.rq +++ b/src/validation/queries/common/preflight_record_cardinality_count.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of records with anomalous property cardinality. # The companion query returns at most 100 example rows for diagnosis; this one @@ -7,12 +7,12 @@ SELECT (COUNT(*) AS ?anomalyCount) WHERE { SELECT ?record WHERE { - ?record a vcfr:VCFRecord . - OPTIONAL { ?record vcfr:chrom ?chrom } - OPTIONAL { ?record vcfr:pos ?pos } - OPTIONAL { ?record vcfr:ref ?ref } - OPTIONAL { ?record vcfr:alt ?alt } - OPTIONAL { ?record vcfr:hasCall ?call } + ?record a vcfc:VCFRecord . + OPTIONAL { ?record vcfc:chrom ?chrom } + OPTIONAL { ?record vcfc:pos ?pos } + OPTIONAL { ?record vcfc:ref ?ref } + OPTIONAL { ?record vcfc:alt ?alt } + OPTIONAL { ?record vcfc:hasCall ?call } } GROUP BY ?record HAVING(COUNT(DISTINCT ?chrom) != 1 || COUNT(DISTINCT ?pos) != 1 || COUNT(DISTINCT ?ref) != 1 || COUNT(DISTINCT ?alt) != 1 || COUNT(DISTINCT ?call) != 1) diff --git a/src/validation/queries/common/q01_record_density_1mb.rq b/src/validation/queries/common/q01_record_density_1mb.rq index e37b999..6b30f44 100644 --- a/src/validation/queries/common/q01_record_density_1mb.rq +++ b/src/validation/queries/common/q01_record_density_1mb.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: PREFIX xsd: SELECT ?chrom ?windowIndex (COUNT(DISTINCT ?record) AS ?recordCount) WHERE { - ?record a vcfr:VCFRecord ; vcfr:chrom ?chrom ; vcfr:pos ?pos . + ?record a vcfc:VCFRecord ; vcfc:chrom ?chrom ; vcfc:pos ?pos . BIND(FLOOR((xsd:integer(?pos) - 1) / 1000000) AS ?windowIndex) } GROUP BY ?chrom ?windowIndex diff --git a/src/validation/queries/common/q02_variant_shape_counts.rq b/src/validation/queries/common/q02_variant_shape_counts.rq index 6f29eb0..546f6b3 100644 --- a/src/validation/queries/common/q02_variant_shape_counts.rq +++ b/src/validation/queries/common/q02_variant_shape_counts.rq @@ -1,8 +1,8 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?variantClass (COUNT(DISTINCT ?record) AS ?recordCount) WHERE { - ?record a vcfr:VCFRecord ; vcfr:ref ?refLiteral ; vcfr:alt ?altLiteral . + ?record a vcfc:VCFRecord ; vcfc:ref ?refLiteral ; vcfc:alt ?altLiteral . BIND(UCASE(STR(?refLiteral)) AS ?ref) BIND(UCASE(STR(?altLiteral)) AS ?alt) BIND( diff --git a/src/validation/queries/common/q03_titv.rq b/src/validation/queries/common/q03_titv.rq index a768a91..b805791 100644 --- a/src/validation/queries/common/q03_titv.rq +++ b/src/validation/queries/common/q03_titv.rq @@ -1,11 +1,11 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT (COUNT(DISTINCT ?record) AS ?biallelicSnvCount) (SUM(IF((?ref = "A" && ?alt = "G") || (?ref = "G" && ?alt = "A") || (?ref = "C" && ?alt = "T") || (?ref = "T" && ?alt = "C"), 1, 0)) AS ?transitionCount) (SUM(IF((?ref = "A" && ?alt = "G") || (?ref = "G" && ?alt = "A") || (?ref = "C" && ?alt = "T") || (?ref = "T" && ?alt = "C"), 0, 1)) AS ?transversionCount) WHERE { - ?record a vcfr:VCFRecord ; vcfr:ref ?refLiteral ; vcfr:alt ?altLiteral . + ?record a vcfc:VCFRecord ; vcfc:ref ?refLiteral ; vcfc:alt ?altLiteral . BIND(UCASE(STR(?refLiteral)) AS ?ref) BIND(UCASE(STR(?altLiteral)) AS ?alt) FILTER(REGEX(?ref, "^[ACGT]$") && REGEX(?alt, "^[ACGT]$") && ?ref != ?alt) diff --git a/src/validation/queries/common/q04_filter_distribution.rq b/src/validation/queries/common/q04_filter_distribution.rq index 9545410..3bc2ebd 100644 --- a/src/validation/queries/common/q04_filter_distribution.rq +++ b/src/validation/queries/common/q04_filter_distribution.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?filterStatus ?filterLexical (COUNT(DISTINCT ?record) AS ?recordCount) WHERE { - ?record a vcfr:VCFRecord ; vcfr:hasCall ?call . - ?call vcfr:filter ?filterLiteral . + ?record a vcfc:VCFRecord ; vcfc:hasCall ?call . + ?call vcfc:filter ?filterLiteral . BIND(STR(?filterLiteral) AS ?filterLexical) BIND(IF(?filterLexical = "PASS", "PASS", IF(?filterLexical = ".", "NOT_APPLIED", "FAILED")) AS ?filterStatus) } diff --git a/src/validation/queries/common/q07_file_metadata.rq b/src/validation/queries/common/q07_file_metadata.rq index 26155d3..03b5f34 100644 --- a/src/validation/queries/common/q07_file_metadata.rq +++ b/src/validation/queries/common/q07_file_metadata.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # The file-level declarations carried over from the VCF meta-information lines. # @@ -10,8 +10,8 @@ SELECT (COALESCE(?rg, "(absent)") AS ?referenceGenome) (COALESCE(?ss, "(absent)") AS ?sourceSoftware) WHERE { - ?file a vcfr:VCFFile . - OPTIONAL { ?file vcfr:fileFormat ?ffLiteral BIND(STR(?ffLiteral) AS ?ff) } - OPTIONAL { ?file vcfr:referenceGenome ?rgLiteral BIND(STR(?rgLiteral) AS ?rg) } - OPTIONAL { ?file vcfr:sourceSoftware ?ssLiteral BIND(STR(?ssLiteral) AS ?ss) } + ?file a vcfc:VCFFile . + OPTIONAL { ?file vcfc:fileFormat ?ffLiteral BIND(STR(?ffLiteral) AS ?ff) } + OPTIONAL { ?file vcfc:referenceGenome ?rgLiteral BIND(STR(?rgLiteral) AS ?rg) } + OPTIONAL { ?file vcfc:sourceSoftware ?ssLiteral BIND(STR(?ssLiteral) AS ?ss) } } diff --git a/src/validation/queries/common/q08_header_line_census.rq b/src/validation/queries/common/q08_header_line_census.rq index 4bfa223..494ace4 100644 --- a/src/validation/queries/common/q08_header_line_census.rq +++ b/src/validation/queries/common/q08_header_line_census.rq @@ -1,11 +1,11 @@ -PREFIX vcfr: +PREFIX vcfc: # One row per '##' meta-information key, with how many lines carry it. # Counting per key rather than in total means a dropped INFO or FILTER # declaration is localized instead of only shifting a single number. SELECT ?headerKey (COUNT(DISTINCT ?line) AS ?lineCount) WHERE { - ?line a vcfr:HeaderLine ; vcfr:headerKey ?headerKeyLiteral . + ?line a vcfc:HeaderLine ; vcfc:headerKey ?headerKeyLiteral . BIND(STR(?headerKeyLiteral) AS ?headerKey) } GROUP BY ?headerKey diff --git a/src/validation/queries/common/q09_predicate_census.rq b/src/validation/queries/common/q09_predicate_census.rq index cd62500..ced0b7b 100644 --- a/src/validation/queries/common/q09_predicate_census.rq +++ b/src/validation/queries/common/q09_predicate_census.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Every predicate in the graph and how many triples use it. # diff --git a/src/validation/queries/common/q10_class_census.rq b/src/validation/queries/common/q10_class_census.rq index 872a642..72f2064 100644 --- a/src/validation/queries/common/q10_class_census.rq +++ b/src/validation/queries/common/q10_class_census.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Every asserted rdf:type and how many resources carry it. Complements the # predicate census: together they bound both the properties and the resources diff --git a/src/validation/queries/common/q11_record_digest.rq b/src/validation/queries/common/q11_record_digest.rq index 69d686b..d59e903 100644 --- a/src/validation/queries/common/q11_record_digest.rq +++ b/src/validation/queries/common/q11_record_digest.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Per-record identity, aggregated into a fixed-size histogram. # @@ -17,16 +17,16 @@ PREFIX vcfr: # made to collide by shifting a field boundary. SELECT ?bucket (COUNT(*) AS ?recordCount) WHERE { - ?record a vcfr:VCFRecord ; - vcfr:chrom ?chrom ; - vcfr:pos ?pos ; - vcfr:recordId ?recordIdLiteral ; - vcfr:ref ?ref ; - vcfr:alt ?alt ; - vcfr:hasCall ?call . - ?call vcfr:qual ?qual ; - vcfr:filter ?filter ; - vcfr:infoRaw ?info . + ?record a vcfc:VCFRecord ; + vcfc:chrom ?chrom ; + vcfc:pos ?pos ; + vcfc:recordId ?recordIdLiteral ; + vcfc:ref ?ref ; + vcfc:alt ?alt ; + vcfc:hasCall ?call . + ?call vcfc:qual ?qual ; + vcfc:filter ?filter ; + vcfc:infoRaw ?info . BIND(SUBSTR(SHA256(CONCAT( STR(?record), "\u001F", STR(?chrom), "\u001F", diff --git a/src/validation/queries/common/q12_info_value_digest.rq b/src/validation/queries/common/q12_info_value_digest.rq index 48b2a4b..be41651 100644 --- a/src/validation/queries/common/q12_info_value_digest.rq +++ b/src/validation/queries/common/q12_info_value_digest.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Structured INFO values, bound to the node that identifies record and key. # @@ -9,7 +9,7 @@ PREFIX vcfr: # engine - GROUP_CONCAT would not be portable here. SELECT ?bucket (COUNT(*) AS ?valueCount) WHERE { - ?value a vcfr:InfoFieldValue ; vcfr:fieldValue ?lexLiteral . + ?value a vcfc:InfoFieldValue ; vcfc:fieldValue ?lexLiteral . BIND(STR(?lexLiteral) AS ?lex) BIND(SUBSTR(SHA256(CONCAT(STR(?value), "\u001F", STR(?lex))), 1, 2) AS ?bucket) } diff --git a/src/validation/queries/condensed/preflight_representation_profile.rq b/src/validation/queries/condensed/preflight_representation_profile.rq index 362062c..0c51676 100644 --- a/src/validation/queries/condensed/preflight_representation_profile.rq +++ b/src/validation/queries/condensed/preflight_representation_profile.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?file ?profile WHERE { - ?file a vcfr:VCFFile . - OPTIONAL { ?file vcfr:representationProfile ?profile } - FILTER(!BOUND(?profile) || ?profile != vcfr:CondensedRepresentation) + ?file a vcfc:VCFFile . + OPTIONAL { ?file vcfc:representationProfile ?profile } + FILTER(!BOUND(?profile) || ?profile != vcfc:CondensedRepresentation) } LIMIT 100 diff --git a/src/validation/queries/condensed/preflight_representation_profile_count.rq b/src/validation/queries/condensed/preflight_representation_profile_count.rq index 2c90126..4edfce7 100644 --- a/src/validation/queries/condensed/preflight_representation_profile_count.rq +++ b/src/validation/queries/condensed/preflight_representation_profile_count.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of VCFFile resources not declaring the condensed profile. SELECT (COUNT(*) AS ?anomalyCount) WHERE { - ?file a vcfr:VCFFile . - OPTIONAL { ?file vcfr:representationProfile ?profile } - FILTER(!BOUND(?profile) || ?profile != vcfr:CondensedRepresentation) + ?file a vcfc:VCFFile . + OPTIONAL { ?file vcfc:representationProfile ?profile } + FILTER(!BOUND(?profile) || ?profile != vcfc:CondensedRepresentation) } diff --git a/src/validation/queries/condensed/preflight_sample_gt_inventory.rq b/src/validation/queries/condensed/preflight_sample_gt_inventory.rq index 9fbde64..635b110 100644 --- a/src/validation/queries/condensed/preflight_sample_gt_inventory.rq +++ b/src/validation/queries/condensed/preflight_sample_gt_inventory.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT (COUNT(DISTINCT ?sample) AS ?sampleCount) @@ -6,11 +6,11 @@ SELECT (COUNT(DISTINCT ?gtVector) AS ?gtVectorCount) WHERE { OPTIONAL { - ?sampleSet a vcfr:SampleSet ; vcfr:hasSample ?sample . - ?sample vcfr:sampleName ?sampleId . + ?sampleSet a vcfc:SampleSet ; vcfc:hasSample ?sample . + ?sample vcfc:sampleName ?sampleId . } OPTIONAL { - ?gtVector a vcfr:FormatValueVector ; vcfr:declaredBy ?definition ; vcfr:encodedValues ?encoded . - ?definition vcfr:fieldId "GT" . + ?gtVector a vcfc:FormatValueVector ; vcfc:declaredBy ?definition ; vcfc:encodedValues ?encoded . + ?definition vcfc:fieldId "GT" . } } diff --git a/src/validation/queries/condensed/q05_sample_genotype_counts.rq b/src/validation/queries/condensed/q05_sample_genotype_counts.rq index 32bf44a..39faf14 100644 --- a/src/validation/queries/condensed/q05_sample_genotype_counts.rq +++ b/src/validation/queries/condensed/q05_sample_genotype_counts.rq @@ -1,17 +1,17 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?sampleId ?genotypeClass (COUNT(DISTINCT ?record) AS ?callCount) WHERE { - ?file a vcfr:VCFFile ; vcfr:hasRecord ?record ; vcfr:hasSampleSet ?sampleSet . - ?record a vcfr:VCFRecord ; vcfr:hasCall ?call . - ?sampleSet vcfr:hasSample ?sample . - ?sample vcfr:sampleName ?sampleId ; vcfr:sampleIndex ?sampleIndex . + ?file a vcfc:VCFFile ; vcfc:hasRecord ?record ; vcfc:hasSampleSet ?sampleSet . + ?record a vcfc:VCFRecord ; vcfc:hasCall ?call . + ?sampleSet vcfc:hasSample ?sample . + ?sample vcfc:sampleName ?sampleId ; vcfc:sampleIndex ?sampleIndex . OPTIONAL { - ?sample vcfr:sampleIndex ?sampleIndexForVector . - ?call vcfr:hasCallMatrix ?matrix . - ?matrix vcfr:appliesToSampleSet ?sampleSet ; vcfr:hasFormatValueVector ?gtVector . - ?gtVector vcfr:declaredBy ?definition ; vcfr:encodedValues ?encoded . - ?definition vcfr:fieldId "GT" . + ?sample vcfc:sampleIndex ?sampleIndexForVector . + ?call vcfc:hasCallMatrix ?matrix . + ?matrix vcfc:appliesToSampleSet ?sampleSet ; vcfc:hasFormatValueVector ?gtVector . + ?gtVector vcfc:declaredBy ?definition ; vcfc:encodedValues ?encoded . + ?definition vcfc:fieldId "GT" . BIND(?sampleIndexForVector - 1 AS ?zeroIndex) BIND(REPLACE(STR(?encoded), CONCAT("^(?:[^\\t]*\\t){", STR(?zeroIndex), "}([^\\t]*).*$"), "$1") AS ?gtLiteral) } diff --git a/src/validation/queries/condensed/q06_ac_an_distribution.rq b/src/validation/queries/condensed/q06_ac_an_distribution.rq index 5c26b70..7faf472 100644 --- a/src/validation/queries/condensed/q06_ac_an_distribution.rq +++ b/src/validation/queries/condensed/q06_ac_an_distribution.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?an ?ac (COUNT(DISTINCT ?record) AS ?siteCount) WHERE { @@ -8,15 +8,15 @@ WHERE { { SELECT DISTINCT ?record ?sample ?gt WHERE { - ?file a vcfr:VCFFile ; vcfr:hasRecord ?record ; vcfr:hasSampleSet ?sampleSet . - ?record a vcfr:VCFRecord ; vcfr:alt ?altLiteral ; vcfr:hasCall ?call . + ?file a vcfc:VCFFile ; vcfc:hasRecord ?record ; vcfc:hasSampleSet ?sampleSet . + ?record a vcfc:VCFRecord ; vcfc:alt ?altLiteral ; vcfc:hasCall ?call . FILTER(STR(?altLiteral) != "." && !CONTAINS(STR(?altLiteral), ",")) - ?sampleSet vcfr:hasSample ?sample . - ?sample vcfr:sampleIndex ?sampleIndex . - ?call vcfr:hasCallMatrix ?matrix . - ?matrix vcfr:appliesToSampleSet ?sampleSet ; vcfr:hasFormatValueVector ?gtVector . - ?gtVector vcfr:declaredBy ?definition ; vcfr:encodedValues ?encoded . - ?definition vcfr:fieldId "GT" . + ?sampleSet vcfc:hasSample ?sample . + ?sample vcfc:sampleIndex ?sampleIndex . + ?call vcfc:hasCallMatrix ?matrix . + ?matrix vcfc:appliesToSampleSet ?sampleSet ; vcfc:hasFormatValueVector ?gtVector . + ?gtVector vcfc:declaredBy ?definition ; vcfc:encodedValues ?encoded . + ?definition vcfc:fieldId "GT" . BIND(?sampleIndex - 1 AS ?zeroIndex) BIND(REPLACE(STR(?encoded), CONCAT("^(?:[^\\t]*\\t){", STR(?zeroIndex), "}([^\\t]*).*$"), "$1") AS ?gtLiteral) BIND(REPLACE(STR(?gtLiteral), "[|]", "/") AS ?gt) diff --git a/src/validation/queries/condensed/q13_format_value_digest.rq b/src/validation/queries/condensed/q13_format_value_digest.rq index c8e4ff6..dbe1350 100644 --- a/src/validation/queries/condensed/q13_format_value_digest.rq +++ b/src/validation/queries/condensed/q13_format_value_digest.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # The condensed equivalent of the expanded per-cell FORMAT digest. # @@ -7,7 +7,7 @@ PREFIX vcfr: # per-cell nodes of the expanded shape. SELECT ?bucket (COUNT(*) AS ?valueCount) WHERE { - ?value a vcfr:FormatValueVector ; vcfr:encodedValues ?lexLiteral . + ?value a vcfc:FormatValueVector ; vcfc:encodedValues ?lexLiteral . BIND(STR(?lexLiteral) AS ?lex) BIND(SUBSTR(SHA256(CONCAT(STR(?value), "\u001F", STR(?lex))), 1, 2) AS ?bucket) } diff --git a/src/validation/queries/expanded/preflight_representation_profile.rq b/src/validation/queries/expanded/preflight_representation_profile.rq index 3adeb40..eef0fa0 100644 --- a/src/validation/queries/expanded/preflight_representation_profile.rq +++ b/src/validation/queries/expanded/preflight_representation_profile.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?file ?profile WHERE { - ?file a vcfr:VCFFile . - OPTIONAL { ?file vcfr:representationProfile ?profile } - FILTER(!BOUND(?profile) || ?profile != vcfr:ExpandedRepresentation) + ?file a vcfc:VCFFile . + OPTIONAL { ?file vcfc:representationProfile ?profile } + FILTER(!BOUND(?profile) || ?profile != vcfc:ExpandedRepresentation) } LIMIT 100 diff --git a/src/validation/queries/expanded/preflight_representation_profile_count.rq b/src/validation/queries/expanded/preflight_representation_profile_count.rq index 9174a06..e49b4d4 100644 --- a/src/validation/queries/expanded/preflight_representation_profile_count.rq +++ b/src/validation/queries/expanded/preflight_representation_profile_count.rq @@ -1,9 +1,9 @@ -PREFIX vcfr: +PREFIX vcfc: # Exact number of VCFFile resources not declaring the expanded profile. SELECT (COUNT(*) AS ?anomalyCount) WHERE { - ?file a vcfr:VCFFile . - OPTIONAL { ?file vcfr:representationProfile ?profile } - FILTER(!BOUND(?profile) || ?profile != vcfr:ExpandedRepresentation) + ?file a vcfc:VCFFile . + OPTIONAL { ?file vcfc:representationProfile ?profile } + FILTER(!BOUND(?profile) || ?profile != vcfc:ExpandedRepresentation) } diff --git a/src/validation/queries/expanded/preflight_sample_gt_inventory.rq b/src/validation/queries/expanded/preflight_sample_gt_inventory.rq index aa59ccb..5925a42 100644 --- a/src/validation/queries/expanded/preflight_sample_gt_inventory.rq +++ b/src/validation/queries/expanded/preflight_sample_gt_inventory.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT (COUNT(DISTINCT ?sampleCall) AS ?sampleCallCount) @@ -6,11 +6,11 @@ SELECT (COUNT(DISTINCT ?gtValueNode) AS ?gtValueNodeCount) WHERE { OPTIONAL { - ?sampleCall a vcfr:SampleCall ; vcfr:sampleId ?sampleId . + ?sampleCall a vcfc:SampleCall ; vcfc:sampleId ?sampleId . OPTIONAL { - ?sampleCall vcfr:hasFormatValue ?gtValueNode . + ?sampleCall vcfc:hasFormatValue ?gtValueNode . FILTER(STRENDS(STR(?gtValueNode), "/fmt/GT")) - ?gtValueNode vcfr:fieldValue ?gtLiteral . + ?gtValueNode vcfc:fieldValue ?gtLiteral . } } } diff --git a/src/validation/queries/expanded/q05_sample_genotype_counts.rq b/src/validation/queries/expanded/q05_sample_genotype_counts.rq index bed78a2..c389b94 100644 --- a/src/validation/queries/expanded/q05_sample_genotype_counts.rq +++ b/src/validation/queries/expanded/q05_sample_genotype_counts.rq @@ -1,12 +1,12 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?sampleId ?genotypeClass (COUNT(DISTINCT ?sampleCall) AS ?callCount) WHERE { - ?sampleCall a vcfr:SampleCall ; vcfr:sampleId ?sampleId . + ?sampleCall a vcfc:SampleCall ; vcfc:sampleId ?sampleId . OPTIONAL { - ?sampleCall vcfr:hasFormatValue ?gtValueNode . + ?sampleCall vcfc:hasFormatValue ?gtValueNode . FILTER(STRENDS(STR(?gtValueNode), "/fmt/GT")) - ?gtValueNode vcfr:fieldValue ?gtLiteral . + ?gtValueNode vcfc:fieldValue ?gtLiteral . } BIND(IF(BOUND(?gtLiteral), REPLACE(STR(?gtLiteral), "[|]", "/"), "") AS ?gt) BIND(IF(!BOUND(?gtLiteral), "NO_GT_FIELD", diff --git a/src/validation/queries/expanded/q06_ac_an_distribution.rq b/src/validation/queries/expanded/q06_ac_an_distribution.rq index 1a0fc93..8d33589 100644 --- a/src/validation/queries/expanded/q06_ac_an_distribution.rq +++ b/src/validation/queries/expanded/q06_ac_an_distribution.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: SELECT ?an ?ac (COUNT(DISTINCT ?record) AS ?siteCount) WHERE { @@ -8,12 +8,12 @@ WHERE { { SELECT DISTINCT ?record ?sampleCall ?gt WHERE { - ?record a vcfr:VCFRecord ; vcfr:alt ?altLiteral ; vcfr:hasCall ?call . + ?record a vcfc:VCFRecord ; vcfc:alt ?altLiteral ; vcfc:hasCall ?call . FILTER(STR(?altLiteral) != "." && !CONTAINS(STR(?altLiteral), ",")) - ?call vcfr:hasSampleCall ?sampleCall . - ?sampleCall vcfr:hasFormatValue ?gtValueNode . + ?call vcfc:hasSampleCall ?sampleCall . + ?sampleCall vcfc:hasFormatValue ?gtValueNode . FILTER(STRENDS(STR(?gtValueNode), "/fmt/GT")) - ?gtValueNode vcfr:fieldValue ?gtLiteral . + ?gtValueNode vcfc:fieldValue ?gtLiteral . BIND(REPLACE(STR(?gtLiteral), "[|]", "/") AS ?gt) } } diff --git a/src/validation/queries/expanded/q13_format_value_digest.rq b/src/validation/queries/expanded/q13_format_value_digest.rq index 647abed..c777293 100644 --- a/src/validation/queries/expanded/q13_format_value_digest.rq +++ b/src/validation/queries/expanded/q13_format_value_digest.rq @@ -1,4 +1,4 @@ -PREFIX vcfr: +PREFIX vcfc: # Every FORMAT value, bound to the node that identifies record, sample and key. # @@ -7,7 +7,7 @@ PREFIX vcfr: # hashing it with the value makes each cell individually accountable. SELECT ?bucket (COUNT(*) AS ?valueCount) WHERE { - ?value a vcfr:FormatFieldValue ; vcfr:fieldValue ?lexLiteral . + ?value a vcfc:FormatFieldValue ; vcfc:fieldValue ?lexLiteral . BIND(STR(?lexLiteral) AS ?lex) BIND(SUBSTR(SHA256(CONCAT(STR(?value), "\u001F", STR(?lex))), 1, 2) AS ?bucket) } diff --git a/src/validation/validation_runner.py b/src/validation/validation_runner.py index ecc2db5..36ed904 100644 --- a/src/validation/validation_runner.py +++ b/src/validation/validation_runner.py @@ -33,6 +33,7 @@ import re import shlex import shutil +import signal import subprocess import sys import tempfile @@ -330,27 +331,37 @@ def classify_genotype(alleles: tuple[int | None, ...] | None, *, has_gt: bool) - # A custom mapping therefore invalidates them, and the wrapper switches the # policy to report-only in that case. -VCFR = "https://w3id.org/vcf-rdfizer/vocab#" -RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" +# The vocabulary terms, the VCF-version model and the lexical parsers are +# shared with the wrapper rather than mirrored here. They used to be duplicated, +# with unit tests asserting the copies stayed identical; one module removes the +# drift the tests were policing. `Dockerfile` copies it next to this runner, so +# it imports the same way inside the container and on the host. +try: + import vcf_rdfizer_vocab as vocab +except ImportError: + # In the container the module sits next to this file; in a source checkout + # it is at the repository root. Try both before giving up, so the runner + # works as a script in either layout. + for candidate in (SCRIPT_DIR, SCRIPT_DIR.parent.parent): + if (candidate / "vcf_rdfizer_vocab.py").is_file(): + sys.path.insert(0, str(candidate)) + break + import vcf_rdfizer_vocab as vocab + +VCFC = vocab.VCFC_NAMESPACE +RDF_TYPE = vocab.RDF_TYPE_URI def _nonzero(counts: dict[str, int]) -> dict[str, int]: return {key: value for key, value in counts.items() if value} +rml_uri_component = vocab.rml_uri_component + + #: Field separator for the record digest. U+001F cannot appear in a VCF field, #: so no shift of a field boundary can make two different records collide. The #: query in q11_record_digest.rq writes it as a SPARQL \\u001F escape. -def rml_uri_component(value: str) -> str: - """Encode a template value the way RMLStreamer 2.5.0 does. - - Mirrors ``_rml_uri_component`` in ``vcf_rdfizer.py``; that module is not on - the container's import path, and ``test_validation_logic_unit.py`` asserts - the two agree so they cannot drift. - """ - encoded = quote_plus(value, safe="*-._", encoding="utf-8", errors="strict") - # urllib leaves '~' unescaped; java.net.URLEncoder does not. - return encoded.replace("+", "%20").replace("~", "%7E") DIGEST_SEPARATOR = "\u001f" @@ -366,6 +377,351 @@ def record_digest_bucket(fields: list[str]) -> str: return hashlib.sha256(joined.encode("utf-8")).hexdigest()[:DIGEST_BUCKET_CHARS] +# --------------------------------------------------------------------------- +# Emitted-shape counters +# --------------------------------------------------------------------------- +# +# The census asserts an exact inventory: these predicates and classes, with +# these counts, and nothing else. So every resource family the emitters produce +# has to be counted here, from the VCF, without reading the graph or the +# mapping. These two functions are the single derivation: parse_vcf calls them +# with the columns it read, and the test fixture calls them with the columns it +# declares, so the container oracle and the fixture oracle cannot disagree. +# +# They mirror append_header_representation_rdf and append_record_detail_rdf. +# Where a decision depends on a shared table (which '##' keys are structured, +# which INFO keys carry an SV carrier, which Number tokens are positional), the +# table comes from vcf_rdfizer_vocab rather than being restated. + + +def _count_field_definition(counts: Counter, *, number: str, has_type: bool, + has_description: bool) -> None: + """Count the ID/Number/Type/Description quartet of one field definition.""" + counts["fieldId"] += 1 + counts["fieldNumber"] += 1 + if vocab.arity_individual(number) is not None: + counts["fieldArity"] += 1 + if vocab.number_as_integer(number) is not None: + counts["fieldNumberInteger"] += 1 + if has_type: + counts["fieldType"] += 1 + if has_description: + counts["fieldDescription"] += 1 + + +def emitted_header_counters(header_lines: list[tuple[str, str]]) -> dict[str, Any]: + """Counters for everything append_header_representation_rdf emits. + + ``header_lines`` is the ordered ``(key, value)`` list of '##' lines, without + the leading '##' and split on the first '='. + """ + classes: Counter[str] = Counter() + predicates: Counter[str] = Counter() + contigs = 0 + declarations: set[str] = set() + + for key, value in header_lines: + key_lower = key.lower() + structured = vocab.is_structured_header_value(value) + line_class = HEADER_LINE_CLASSES.get(key_lower) + if line_class is None: + # An unrecognized key is still one of the two VCF forms. An + # unstructured line is only typed when it has a value, because + # vcfc:UnstructuredHeaderLineShape requires one. + if structured: + line_class = "StructuredHeaderLine" + elif value: + line_class = "UnstructuredHeaderLine" + else: + continue + classes[line_class] += 1 + + if not structured: + if key_lower == "assembly" and value: + predicates["assemblyUrl"] += 1 + elif key_lower == "pedigreedb" and value: + predicates["pedigreeDbUrl"] += 1 + continue + + attributes = parse_structured_header_attributes(value) + classes["HeaderAttribute"] += len(attributes) + for name in ("hasAttribute", "attributeKey", "attributeValue", "attributeIndex"): + predicates[name] += len(attributes) + + fields = dict(attributes) + identifier = (fields.get("ID") or "").strip() + + if key_lower in {"info", "format"}: + if not identifier: + continue + # An absent Description is synthesized, so the property is always + # present on an INFO or FORMAT declaration. + _count_field_definition( + predicates, number=fields.get("Number") or ".", + has_type=True, has_description=True, + ) + if key_lower == "info": + for attribute, predicate in vocab.INFO_EXTRA_ATTRIBUTES.items(): + if fields.get(attribute): + predicates[predicate] += 1 + elif key_lower == "filter": + if identifier: + predicates["filterId"] += 1 + predicates["fieldDescription"] += 1 + elif key_lower == "alt": + if identifier: + predicates["altId"] += 1 + predicates["fieldDescription"] += 1 + elif key_lower == "contig": + if not identifier: + continue + contigs += 1 + predicates["contigId"] += 1 + for attribute, (predicate, _datatype) in vocab.CONTIG_ATTRIBUTES.items(): + if fields.get(attribute): + predicates[predicate] += 1 + elif key_lower == "meta": + if not identifier: + continue + _count_field_definition( + predicates, number=fields.get("Number") or ".", + has_type=True, has_description=fields.get("Description") is not None, + ) + predicates["metaAllowedValue"] += len(_meta_values(fields.get("Values"))) + elif key_lower == "sample": + if identifier: + predicates["declaresSample"] += 1 + if identifier not in declarations: + declarations.add(identifier) + classes["SampleDeclaration"] += 1 + elif key_lower == "pedigree": + for attribute_key, attribute_value in attributes: + if attribute_key == "ID" or not attribute_value: + continue + predicates[ + vocab.PEDIGREE_ROLE_PROPERTIES.get(attribute_key, "pedigreeAncestor") + ] += 1 + predicates["ancestorRole"] += 1 + if attribute_value not in declarations: + declarations.add(attribute_value) + classes["SampleDeclaration"] += 1 + + if contigs: + predicates["contigCount"] += 1 + return { + "emittedHeaderClasses": dict(classes), + "emittedHeaderPredicates": dict(predicates), + } + + +def _meta_values(raw: str | None) -> list[str]: + """Split a ##META ``Values=[a, b, c]`` list, as the emitter does.""" + if not raw: + return [] + inner = raw.strip() + if inner.startswith("[") and inner.endswith("]"): + inner = inner[1:-1] + return [item.strip() for item in inner.split(",") if item.strip()] + + +def emitted_record_counters( + rows: list[list[str]], + samples: list[str], + *, + version: Any, + contig_ids: set[str], + alt_declaration_ids: set[str], + has_assembly_line: bool = False, + info_numbers: dict[str, str], + format_numbers: dict[str, str], +) -> dict[str, Any]: + """Counters for the allele, INFO, value-item, SV and genotype families. + + ``rows`` are the raw tab-split VCF data columns. Everything is derived from + those and from the version, exactly as the emitters derive it. + """ + classes: Counter[str] = Counter() + predicates: Counter[str] = Counter() + + assembly_contig_ids: set[str] = set() + reference_alleles = alt_alleles = 0 + value_items = value_item_alleles = tuple_items = 0 + genotypes = genotype_calls = called_alleles = 0 + + for row in rows: + chrom = row[0] if len(row) > 0 else "" + ref = row[3] if len(row) > 3 else "" + alt = row[4] if len(row) > 4 else "" + info = row[7] if len(row) > 7 else "" + + # A bracketed CHROM names a breakpoint-assembly contig instead of a + # declared reference sequence; the two are mutually exclusive. + assembly_id = vocab.parse_bracketed_chrom(chrom) + if assembly_id is not None: + predicates["chromAssemblyContig"] += 1 + if assembly_id not in assembly_contig_ids: + assembly_contig_ids.add(assembly_id) + classes["AssemblyContig"] += 1 + predicates["assemblyContigId"] += 1 + if has_assembly_line: + predicates["declaredInAssembly"] += 1 + elif chrom in contig_ids: + predicates["chromosome"] += 1 + + alleles = vocab.parse_alt_alleles(ref, alt) + allele_uris = {allele.index for allele in alleles} + alt_count = sum(1 for allele in alleles if allele.index >= 1) + for allele in alleles: + if allele.index == 0: + reference_alleles += 1 + else: + alt_alleles += 1 + if allele.symbolic_id and allele.symbolic_id in alt_declaration_ids: + predicates["declaredByAlt"] += 1 + if allele.symbolic_type: + predicates["svType"] += 1 + if allele.breakend is not None: + classes["Breakend"] += 1 + if allele.breakend.orientation is not None: + predicates["breakendOrientation"] += 1 + if allele.breakend.replacement: + predicates["breakendReplacementString"] += 1 + if allele.breakend.is_single: + predicates["isSingleBreakend"] += 1 + + entries = parse_info_entries(info) + for key, value in entries: + if value is None: + continue + number = info_numbers.get(key, ".") + if not (allele_uris and version.is_positional(key, number)): + continue + items = vocab.split_value_items(value) + value_items += len(items) + arity = version.tuple_arity(key) + if arity is not None: + tuple_items += len(items) + for index in range(len(items)): + link = version.value_item_link(key, number, index) + if link.allele_index is not None and link.allele_index in allele_uris: + value_item_alleles += 1 + elif link.genotype_index is not None: + predicates["forGenotypeIndex"] += 1 + elif link.gt_allele_index is not None: + predicates["forGTAlleleIndex"] += 1 + + if samples: + format_keys = (row[8].split(":") if len(row) > 8 and row[8] else []) + payloads = row[9 : 9 + len(samples)] + if "GT" in format_keys: + gt_index = format_keys.index("GT") + for payload in payloads: + fields = payload.split(":") if payload else [] + raw_gt = fields[gt_index] if gt_index < len(fields) else "" + parsed = vocab.parse_genotype(raw_gt) + if parsed is None: + continue + genotypes += 1 + genotype_calls += len(parsed.calls) + called_alleles += sum( + 1 for call in parsed.calls + if call.allele_index is not None and call.allele_index <= alt_count + ) + + if reference_alleles: + classes["ReferenceAllele"] = reference_alleles + predicates["hasReferenceAllele"] = reference_alleles + if alt_alleles: + classes["AltAllele"] = alt_alleles + predicates["hasAltAllele"] = alt_alleles + total_alleles = reference_alleles + alt_alleles + for name in ("alleleIndex", "alleleValue", "alleleKind"): + predicates[name] += total_alleles + + if value_items: + classes["FieldValueItem"] += value_items + for name in ("hasValueItem", "valueIndex", "itemValue"): + predicates[name] += value_items + predicates["forAllele"] += value_item_alleles + predicates["tupleArity"] += tuple_items + + # The parsed genotype layer is expanded-only, so it is reported separately + # and merged by expected_census for that profile alone. Keeping parse_vcf + # representation-independent is what lets one parse serve both censuses. + genotype_classes: Counter[str] = Counter() + genotype_predicates: Counter[str] = Counter() + if genotypes: + genotype_classes["Genotype"] += genotypes + genotype_classes["GenotypeAlleleCall"] += genotype_calls + for name in ("hasGenotype", "genotypeString", "ploidy", "phasingStatus"): + genotype_predicates[name] += genotypes + for name in ("hasAlleleCall", "callIndex", "isNoCall"): + genotype_predicates[name] += genotype_calls + genotype_predicates["calledAllele"] += called_alleles + + return { + "emittedRecordClasses": dict(classes), + "emittedRecordPredicates": dict(predicates), + "emittedGenotypeClasses": dict(genotype_classes), + "emittedGenotypePredicates": dict(genotype_predicates), + "alleleCount": total_alleles, + "valueItemCount": value_items, + "genotypeCount": genotypes, + "genotypeAlleleCallCount": genotype_calls, + } + + +def synthesized_definition_numbers( + rows: list[list[str]], *, declared_info: set[str], declared_format: set[str] +) -> dict[str, list[str]]: + """The Number token of every definition the value emitters have to invent. + + A key declared by a '##INFO' or '##FORMAT' line is owned by the header + emitter, which emits its ID/Number/Type/Description at the header line's + own IRI. Only an undeclared key gets a definition invented at value time, + with Number "0" for a Flag and "." otherwise. + """ + info: list[str] = [] + format_keys: list[str] = [] + seen_info: set[str] = set() + seen_format: set[str] = set() + for row in rows: + for key, value in parse_info_entries(row[7] if len(row) > 7 else ""): + if key in declared_info or key in seen_info: + continue + seen_info.add(key) + info.append("0" if value is None else ".") + declared_keys = row[8].split(":") if len(row) > 8 and row[8] else [] + payloads = [p.split(":") if p else [] for p in row[9:]] + width = max([len(declared_keys), *(len(p) for p in payloads)], default=0) + for index in range(width): + key = (declared_keys[index] + if index < len(declared_keys) and declared_keys[index] + else f"FIELD_{index + 1}") + if key in declared_format or key in seen_format: + continue + seen_format.add(key) + format_keys.append(".") + return {"synthesizedInfoNumbers": info, "synthesizedFormatNumbers": format_keys} + + +def _count_definitions(predicates: dict[str, int], numbers: list[str]) -> None: + """Count the field* triples of each synthesized field definition. + + A synthesized definition always carries ID, Number, Type and Description, + plus the arity individual or the fixed count its Number token implies. + """ + for number in numbers: + for name in ("fieldId", "fieldNumber", "fieldType", "fieldDescription"): + predicates[f"{VCFC}{name}"] = predicates.get(f"{VCFC}{name}", 0) + 1 + if vocab.arity_individual(number) is not None: + predicates[f"{VCFC}fieldArity"] = predicates.get(f"{VCFC}fieldArity", 0) + 1 + if vocab.number_as_integer(number) is not None: + predicates[f"{VCFC}fieldNumberInteger"] = ( + predicates.get(f"{VCFC}fieldNumberInteger", 0) + 1 + ) + + def expected_census( parser: dict[str, Any], representation: str, *, info_representation: str = "structured", header_representation: str = "structured", @@ -376,113 +732,141 @@ def expected_census( header_lines = parser["headerLineCount"] classes: dict[str, int] = { - f"{VCFR}VCFFile": 1, - f"{VCFR}VCFHeader": 1, - f"{VCFR}HeaderLine": header_lines, - f"{VCFR}VCFRecord": records, - f"{VCFR}VariantCall": records, + f"{VCFC}VCFFile": 1, + f"{VCFC}VCFHeader": 1, + f"{VCFC}ColumnHeaderLine": 1, + f"{VCFC}HeaderLine": header_lines, + f"{VCFC}VCFRecord": records, + f"{VCFC}VariantCall": records, } + # The mapping's version sentinel resolves to the subclass for the version + # the file declares, or back to vcfc:VCFFile when the version has no + # conformance overlay -- in which case it adds no new class. + version = vocab.parse_vcf_version(parser.get("fileFormat")) + if version is not None: + classes[f"{VCFC}{version.file_class}"] = 1 predicates: dict[str, int] = { - f"{VCFR}hasHeader": 1, - f"{VCFR}hasHeaderLine": header_lines, - f"{VCFR}headerKey": header_lines, - f"{VCFR}headerValue": parser["headerValueCount"], - f"{VCFR}hasRecord": records, - f"{VCFR}chrom": records, - f"{VCFR}pos": records, - f"{VCFR}recordId": records, - f"{VCFR}ref": records, - f"{VCFR}alt": records, - f"{VCFR}hasCall": records, - f"{VCFR}qual": records, - f"{VCFR}filter": records, - f"{VCFR}infoRaw": records, - f"{VCFR}formatRaw": parser["recordsWithFormatColumn"], + f"{VCFC}hasHeader": 1, + f"{VCFC}hasColumnHeader": 1, + f"{VCFC}hasHeaderLine": header_lines, + f"{VCFC}headerKey": header_lines, + f"{VCFC}headerValue": parser["headerValueCount"], + f"{VCFC}lineIndex": header_lines, + f"{VCFC}hasRecord": records, + f"{VCFC}chrom": records, + f"{VCFC}pos": records, + f"{VCFC}ref": records, + f"{VCFC}recordIndex": records, + f"{VCFC}hasCall": records, + # ID, ALT, QUAL, FILTER and INFO moved out of the mapping and into the + # wrapper's emitter, because each may be the VCF missing token and RML + # cannot type an object per row. They are still one per record. + f"{VCFC}recordId": records, + f"{VCFC}alt": records, + f"{VCFC}qual": records, + f"{VCFC}filter": records, + f"{VCFC}infoRaw": records, + f"{VCFC}formatRaw": parser["recordsWithFormatColumn"], } # RMLStreamer emits nothing for an absent value, so an undeclared # meta-information line contributes no triple rather than an empty one. for field, predicate in ( - ("fileFormat", f"{VCFR}fileFormat"), - ("referenceGenome", f"{VCFR}referenceGenome"), - ("sourceSoftware", f"{VCFR}sourceSoftware"), + ("fileFormat", f"{VCFC}fileFormat"), + ("referenceGenome", f"{VCFC}referenceGenome"), + ("sourceSoftware", f"{VCFC}sourceSoftware"), ): predicates[predicate] = 0 if parser[field] == METADATA_ABSENT else 1 + # A sites-only VCF still declares a profile: vcfc:RepresentationProfileShape + # requires exactly one on every file, and a file with no genotype columns + # has no genotype data to condense. + predicates[f"{VCFC}representationProfile"] = 1 if samples: - predicates[f"{VCFR}representationProfile"] = 1 + definitions = parser["distinctFormatKeyCount"] + # The reusable sample set is file-scoped, not profile-scoped: both + # profiles emit it, and the #CHROM line links to its members. + classes[f"{VCFC}SampleSet"] = 1 + classes[f"{VCFC}VCFSample"] = samples + classes[f"{VCFC}FormatFieldDefinition"] = definitions + predicates[f"{VCFC}hasSampleSet"] = 1 + predicates[f"{VCFC}hasSample"] = samples + predicates[f"{VCFC}sampleName"] = samples + predicates[f"{VCFC}sampleIndex"] = samples + predicates[f"{VCFC}hasGenotypeColumns"] = samples + # A FORMAT key declared by a '##FORMAT' line gets its + # ID/Number/Type/Description from the header emitter, at the same IRI. + # Only a key the header never declared needs an invented definition + # here, so only those are counted. + _count_definitions(predicates, parser.get("synthesizedFormatNumbers", [])) + if representation == "expanded": - classes[f"{VCFR}SampleCall"] = records * samples - classes[f"{VCFR}FormatFieldValue"] = parser["formatValueSlots"] - predicates[f"{VCFR}hasSampleCall"] = records * samples - predicates[f"{VCFR}sampleId"] = records * samples - predicates[f"{VCFR}hasFormatValue"] = parser["formatValueSlots"] - predicates[f"{VCFR}fieldValue"] = parser["nonEmptyFormatValues"] + for class_name, count in parser.get("emittedGenotypeClasses", {}).items(): + classes[f"{VCFC}{class_name}"] = classes.get(f"{VCFC}{class_name}", 0) + count + for name, count in parser.get("emittedGenotypePredicates", {}).items(): + predicates[f"{VCFC}{name}"] = predicates.get(f"{VCFC}{name}", 0) + count + classes[f"{VCFC}SampleCall"] = records * samples + classes[f"{VCFC}FormatFieldValue"] = parser["formatValueSlots"] + predicates[f"{VCFC}hasSampleCall"] = records * samples + predicates[f"{VCFC}sampleId"] = records * samples + predicates[f"{VCFC}forSample"] = records * samples + predicates[f"{VCFC}hasFormatValue"] = parser["formatValueSlots"] + predicates[f"{VCFC}fieldValue"] = parser["nonEmptyFormatValues"] + # Every expanded FORMAT value now cites its declaration. + predicates[f"{VCFC}declaredBy"] = ( + predicates.get(f"{VCFC}declaredBy", 0) + parser["formatValueSlots"] + ) else: - definitions = parser["distinctFormatKeyCount"] - classes[f"{VCFR}SampleSet"] = 1 - classes[f"{VCFR}VCFSample"] = samples - classes[f"{VCFR}CohortCallMatrix"] = parser["recordsWithFormatKeys"] - classes[f"{VCFR}FormatValueVector"] = parser["formatKeyOccurrences"] - classes[f"{VCFR}FormatFieldDefinition"] = definitions - predicates[f"{VCFR}hasSampleSet"] = 1 - predicates[f"{VCFR}hasSample"] = samples - predicates[f"{VCFR}sampleName"] = samples - predicates[f"{VCFR}sampleIndex"] = samples - predicates[f"{VCFR}hasCallMatrix"] = parser["recordsWithFormatKeys"] - predicates[f"{VCFR}appliesToSampleSet"] = parser["recordsWithFormatKeys"] - predicates[f"{VCFR}hasFormatValueVector"] = parser["formatKeyOccurrences"] - predicates[f"{VCFR}declaredBy"] = parser["formatKeyOccurrences"] - predicates[f"{VCFR}valueEncoding"] = parser["formatKeyOccurrences"] - predicates[f"{VCFR}encodedValues"] = parser["formatKeyOccurrences"] - predicates[f"{VCFR}fieldId"] = definitions - predicates[f"{VCFR}fieldNumber"] = definitions - predicates[f"{VCFR}fieldDescription"] = definitions - - predicates[f"{VCFR}fileDate"] = 0 if parser["fileDate"] == METADATA_ABSENT else 1 + classes[f"{VCFC}CohortCallMatrix"] = parser["recordsWithFormatKeys"] + classes[f"{VCFC}FormatValueVector"] = parser["formatKeyOccurrences"] + predicates[f"{VCFC}hasCallMatrix"] = parser["recordsWithFormatKeys"] + predicates[f"{VCFC}appliesToSampleSet"] = parser["recordsWithFormatKeys"] + predicates[f"{VCFC}hasFormatValueVector"] = parser["formatKeyOccurrences"] + predicates[f"{VCFC}valueEncoding"] = parser["formatKeyOccurrences"] + predicates[f"{VCFC}encodedValues"] = parser["formatKeyOccurrences"] + predicates[f"{VCFC}declaredBy"] = ( + predicates.get(f"{VCFC}declaredBy", 0) + parser["formatKeyOccurrences"] + ) + + predicates[f"{VCFC}fileDate"] = 0 if parser["fileDate"] == METADATA_ABSENT else 1 if header_representation == "structured": - for class_name, count in parser["headerLineClassCounts"].items(): - classes[f"{VCFR}{class_name}"] = classes.get(f"{VCFR}{class_name}", 0) + count - # A FILTER/ALT line carries both its header-line subclass and its - # definition class, so it contributes two rdf:type triples. - classes[f"{VCFR}FilterDefinition"] = parser["filterDefinitionCount"] - classes[f"{VCFR}AltDefinition"] = parser["altDefinitionCount"] - predicates[f"{VCFR}filterId"] = parser["filterDefinitionCount"] - predicates[f"{VCFR}altId"] = parser["altDefinitionCount"] - predicates[f"{VCFR}contigId"] = parser["contigCount"] - predicates[f"{VCFR}contigCount"] = 1 if parser["contigCount"] else 0 - for attribute, predicate in ( - ("length", "contigLength"), ("md5", "contigMd5"), ("assembly", "contigAssembly"), - ): - predicates[f"{VCFR}{predicate}"] = parser["contigAttributeCounts"].get(attribute, 0) - predicates[f"{VCFR}fieldDescription"] = ( - predicates.get(f"{VCFR}fieldDescription", 0) - + parser["describedDefinitionCount"] - ) + # Every structured-header family is counted once, by + # emitted_header_counters, from the same '##' lines the emitter reads. + # vcfc:FilterDefinition and vcfc:AltDefinition are no longer asserted: + # vcfc:FILTERHeaderLine and vcfc:ALTHeaderLine are subclasses of them in + # the vocabulary, so RDFS supplies the type and an explicit triple would + # be redundant. + for class_name, count in parser["emittedHeaderClasses"].items(): + classes[f"{VCFC}{class_name}"] = classes.get(f"{VCFC}{class_name}", 0) + count + for name, count in parser["emittedHeaderPredicates"].items(): + predicates[f"{VCFC}{name}"] = predicates.get(f"{VCFC}{name}", 0) + count if info_representation == "structured": values = parser["infoValueCount"] definitions = parser["infoDefinitionCount"] - classes[f"{VCFR}InfoFieldValue"] = values - classes[f"{VCFR}InfoFieldDefinition"] = definitions - predicates[f"{VCFR}hasInfoValue"] = values - predicates[f"{VCFR}fieldValueBoolean"] = parser["infoFlagCount"] - predicates[f"{VCFR}fieldValueInteger"] = parser["infoTypedIntegerCount"] - predicates[f"{VCFR}fieldValueDecimal"] = parser["infoTypedDecimalCount"] - predicates[f"{VCFR}fieldType"] = definitions - # declaredBy and the field* descriptors are shared with the condensed - # FORMAT definitions, so accumulate rather than overwrite. - for predicate, count in ( - (f"{VCFR}declaredBy", values), - (f"{VCFR}fieldId", definitions), - (f"{VCFR}fieldNumber", definitions), - (f"{VCFR}fieldDescription", definitions), - ): - predicates[predicate] = predicates.get(predicate, 0) + count - predicates[f"{VCFR}fieldValue"] = ( - predicates.get(f"{VCFR}fieldValue", 0) + values - parser["infoFlagCount"] + classes[f"{VCFC}InfoFieldValue"] = values + classes[f"{VCFC}InfoFieldDefinition"] = definitions + predicates[f"{VCFC}hasInfoValue"] = values + predicates[f"{VCFC}fieldValueBoolean"] = parser["infoFlagCount"] + predicates[f"{VCFC}fieldValueInteger"] = parser["infoTypedIntegerCount"] + predicates[f"{VCFC}fieldValueDecimal"] = parser["infoTypedDecimalCount"] + # declaredBy and the field* descriptors are shared with the FORMAT + # definitions, so accumulate rather than overwrite. + predicates[f"{VCFC}declaredBy"] = predicates.get(f"{VCFC}declaredBy", 0) + values + # As above: only an INFO key with no '##INFO' declaration needs its + # definition invented, and only those contribute field* triples here. + _count_definitions(predicates, parser.get("synthesizedInfoNumbers", [])) + predicates[f"{VCFC}fieldValue"] = ( + predicates.get(f"{VCFC}fieldValue", 0) + values - parser["infoFlagCount"] ) + # The allele layer, the value items, the SV carriers and the parsed + # genotype layer travel with the structured INFO representation. + for class_name, count in parser["emittedRecordClasses"].items(): + classes[f"{VCFC}{class_name}"] = classes.get(f"{VCFC}{class_name}", 0) + count + for name, count in parser["emittedRecordPredicates"].items(): + predicates[f"{VCFC}{name}"] = predicates.get(f"{VCFC}{name}", 0) + count + classes = _nonzero(classes) predicates = _nonzero(predicates) # Every typed resource contributes exactly one rdf:type triple here. @@ -515,76 +899,13 @@ def sample_uri_ids(sample_ids: list[str]) -> list[str]: return out -#: '##' key (lower-cased) -> vocabulary subclass. Mirrors HEADER_LINE_CLASSES -#: in vcf_rdfizer.py; the unit tests assert the two stay identical. -HEADER_LINE_CLASSES = { - "fileformat": "FileFormatHeaderLine", - "filedate": "FileDateHeaderLine", - "source": "SourceHeaderLine", - "reference": "ReferenceHeaderLine", - "info": "INFOHeaderLine", - "format": "FORMATHeaderLine", - "filter": "FILTERHeaderLine", - "alt": "ALTHeaderLine", - "contig": "ContigHeaderLine", -} - - -def parse_structured_header_fields(value: str) -> dict[str, str]: - """Parse '' attributes, respecting quoting. - - Mirrors ``_parse_structured_header_fields`` in ``vcf_rdfizer.py``; the unit - tests assert the two agree. - """ - inner = value.strip() - if inner.startswith("<") and inner.endswith(">"): - inner = inner[1:-1] - tokens: list[str] = [] - token: list[str] = [] - in_quotes = escaped = False - for character in inner: - if escaped: - token.append(character) - escaped = False - elif character == "\\" and in_quotes: - token.append(character) - escaped = True - elif character == '"': - token.append(character) - in_quotes = not in_quotes - elif character == "," and not in_quotes: - tokens.append("".join(token)) - token = [] - else: - token.append(character) - tokens.append("".join(token)) - fields: dict[str, str] = {} - for item in tokens: - if "=" not in item: - continue - key, raw_value = item.split("=", 1) - parsed = raw_value.strip() - if len(parsed) >= 2 and parsed[0] == parsed[-1] == '"': - parsed = parsed[1:-1].replace('\\"', '"').replace("\\\\", "\\") - fields[key.strip()] = parsed - return fields - - -def parse_info_entries(info: str) -> list[tuple[str, str | None]]: - """Split an INFO column into ``(key, value)`` pairs; a bare key is a Flag. - - Mirrors ``parse_info_entries`` in ``vcf_rdfizer.py``. The two are asserted - to agree in ``test_validation_logic_unit.py``. - """ - if info in ("", "."): - return [] - entries: list[tuple[str, str | None]] = [] - for item in info.split(";"): - if not item: - continue - key, separator, value = item.partition("=") - entries.append((key, value if separator else None)) - return entries +# Shared with the wrapper through vcf_rdfizer_vocab, so the oracle and the +# emitter cannot disagree about what a '##' line means or how it parses. +HEADER_LINE_CLASSES = vocab.HEADER_LINE_CLASSES +STRUCTURED_HEADER_KEYS = vocab.STRUCTURED_HEADER_KEYS +parse_structured_header_fields = vocab.parse_structured_header_fields +parse_structured_header_attributes = vocab.parse_structured_header_attributes +parse_info_entries = vocab.parse_info_entries def info_declared_types(raw_header: str) -> dict[str, str]: @@ -650,42 +971,44 @@ def parse_header_metadata(raw_header: str) -> dict[str, Any]: # A repeated declaration keeps the first, matching the awk parser. if field is not None and metadata[field] == METADATA_ABSENT: metadata[field] = value - # Header-representation counters. The class map mirrors HEADER_LINE_CLASSES - # in vcf_rdfizer.py; the two are asserted to agree in the unit tests. - header_classes: Counter[str] = Counter() - filter_definitions = alt_definitions = contigs = described = 0 - contig_attributes: Counter[str] = Counter() + # Header-representation counters, derived by the one shared implementation + # the emitter's shape is described by. + header_lines: list[tuple[str, str]] = [] + contig_ids: set[str] = set() + alt_ids: set[str] = set() + info_numbers: dict[str, str] = {} + format_numbers: dict[str, str] = {} for line in raw_header.splitlines(): if not line.startswith("##"): continue key, _, value = line[2:].partition("=") - class_name = HEADER_LINE_CLASSES.get(key.lower()) - if class_name is None: - continue - header_classes[class_name] += 1 - if key.lower() not in {"filter", "alt", "contig"}: + header_lines.append((key, value)) + lowered = key.lower() + if lowered not in {"contig", "alt", "info", "format"}: continue fields = parse_structured_header_fields(value) - if not (fields.get("ID") or "").strip(): - continue - if key.lower() == "contig": - contigs += 1 - for attribute in ("length", "md5", "assembly"): - if fields.get(attribute): - contig_attributes[attribute] += 1 + identifier = (fields.get("ID") or "").strip() + if not identifier: continue - if key.lower() == "filter": - filter_definitions += 1 + if lowered == "contig": + contig_ids.add(identifier) + elif lowered == "alt": + alt_ids.add(identifier) + elif lowered == "info": + info_numbers.setdefault(identifier, fields.get("Number") or ".") else: - alt_definitions += 1 - if fields.get("Description"): - described += 1 - metadata["headerLineClassCounts"] = dict(header_classes) - metadata["filterDefinitionCount"] = filter_definitions - metadata["altDefinitionCount"] = alt_definitions - metadata["contigCount"] = contigs - metadata["contigAttributeCounts"] = dict(contig_attributes) - metadata["describedDefinitionCount"] = described + format_numbers.setdefault(identifier, fields.get("Number") or ".") + + metadata.update(emitted_header_counters(header_lines)) + metadata["headerLines"] = header_lines + metadata["contigIds"] = sorted(contig_ids) + metadata["hasAssemblyLine"] = any( + key.lower() == "assembly" and value for key, value in header_lines + ) + metadata["altDeclarationIds"] = sorted(alt_ids) + metadata["infoKeyNumbers"] = info_numbers + metadata["formatKeyNumbers"] = format_numbers + metadata["contigCount"] = len(contig_ids) metadata["headerLineCount"] = sum(keys.values()) metadata["headerValueCount"] = sum( 1 for line in raw_header.splitlines() @@ -751,6 +1074,7 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: info_definitions: set[str] = set() info_values = info_flags = info_typed_integers = info_typed_decimals = 0 source_component = rml_uri_component(vcf_path.name) + record_rows: list[list[str]] = [] records_with_format_column = records_with_format_keys = 0 format_key_occurrences = format_value_slots = non_empty_format_values = 0 distinct_format_keys: set[str] = set() @@ -781,12 +1105,13 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: if has_gt: gt_records += 1 - # `vcfr:formatRaw` comes from the FORMAT column itself, so it is + # `vcfc:formatRaw` comes from the FORMAT column itself, so it is # present whenever that column is non-empty - samples or not. if format_keys: records_with_format_column += 1 columns = str(variant).rstrip("\r\n").split("\t") + record_rows.append(columns) # The record digest is computed from the raw line so it matches the # lexical values the mapping puts in the graph, character for # character, with no round-trip through cyvcf2's typed accessors. @@ -909,12 +1234,24 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: "filterOracle": "bcftools" if use_bcftools else "cyvcf2-serialization", "headerLineCount": header_metadata["headerLineCount"], "fileDate": header_metadata["fileDate"], - "headerLineClassCounts": header_metadata["headerLineClassCounts"], - "filterDefinitionCount": header_metadata["filterDefinitionCount"], - "altDefinitionCount": header_metadata["altDefinitionCount"], + "emittedHeaderClasses": header_metadata["emittedHeaderClasses"], + "emittedHeaderPredicates": header_metadata["emittedHeaderPredicates"], "contigCount": header_metadata["contigCount"], - "contigAttributeCounts": header_metadata["contigAttributeCounts"], - "describedDefinitionCount": header_metadata["describedDefinitionCount"], + **emitted_record_counters( + record_rows, + samples, + version=vocab.resolve_vcf_version(header_metadata["fileFormat"])[0], + contig_ids=set(header_metadata["contigIds"]), + alt_declaration_ids=set(header_metadata["altDeclarationIds"]), + has_assembly_line=header_metadata["hasAssemblyLine"], + info_numbers=header_metadata["infoKeyNumbers"], + format_numbers=header_metadata["formatKeyNumbers"], + ), + **synthesized_definition_numbers( + record_rows, + declared_info=set(header_metadata["infoKeyNumbers"]), + declared_format=set(header_metadata["formatKeyNumbers"]), + ), "headerValueCount": header_metadata["headerValueCount"], "recordsWithFormatColumn": records_with_format_column, "recordsWithFormatKeys": records_with_format_keys, @@ -1342,8 +1679,93 @@ def _envelope( return envelope +#: Above this decoded-graph size, an engine with no persistent index spends +#: more time parsing than querying. It is not a hard limit -- host memory and +#: query shape decide the real ceiling -- but it is the point at which the +#: per-query parse starts to dominate, and where a 27-query run stops being a +#: reasonable thing to start without knowing that. +UNINDEXED_ENGINE_ADVICE_BYTES = 4 * 1024 * 1024 * 1024 + + +def engine_advice(engine_name: str, source: Path, query_count: int, timeout: int) -> str | None: + """Warn before a run commits to an engine that cannot finish it. + + Comunica has no persistent index: every query re-parses the whole source + into memory. On a cohort-scale graph each parse can exceed the per-query + timeout, and the cost is paid again for every remaining query. + """ + if engine_name != "comunica": + return None + try: + size = source.stat().st_size + except OSError: + return None + if size < UNINDEXED_ENGINE_ADVICE_BYTES: + return None + return ( + f"comunica re-parses the whole graph for each of the {query_count} " + f"queries and keeps it in memory; this source is " + f"{size / (1024 ** 3):.1f} GiB. Worst case at the current " + f"--query-timeout is {query_count * timeout / 3600:.0f}h. Prefer " + f"--engine qlever, or validate an indexed artifact " + f"(--validation-targets hdt)." + ) + + +def run_query_process( + command: list[str], *, stdout_path: Path, stderr_path: Path, timeout: int +) -> tuple[int, str | None]: + """Run one query process, killing its whole process tree on timeout. + + ``subprocess.run(timeout=...)`` signals only the process it started. Every + query here is wrapped in ``/usr/bin/time``, which forks the real engine, so + killing the wrapper leaves the engine running -- holding the entire graph in + memory, because that is what an in-memory SPARQL engine does. A handful of + those orphans is enough to push a host into swap and make the rest of the + run appear to hang rather than fail. + + Starting a new session and signalling the group kills the wrapper and the + engine together. SIGTERM first so the engine can unmap its store, SIGKILL if + it does not go. + """ + with stdout_path.open("wb") as stdout, stderr_path.open("wb") as stderr: + process = subprocess.Popen( + command, stdout=stdout, stderr=stderr, start_new_session=True + ) + try: + return process.wait(timeout=timeout), None + except subprocess.TimeoutExpired: + _terminate_process_group(process) + return 124, f"query exceeded {timeout}s" + + +def _terminate_process_group(process: subprocess.Popen) -> None: + """Signal a process group, escalating to SIGKILL, and reap the leader.""" + for signal_number, grace in ((signal.SIGTERM, 10), (signal.SIGKILL, 5)): + try: + os.killpg(os.getpgid(process.pid), signal_number) + except (ProcessLookupError, PermissionError): + break + try: + process.wait(timeout=grace) + return + except subprocess.TimeoutExpired: + continue + try: + process.wait(timeout=5) + except subprocess.TimeoutExpired: + pass + + class ComunicaEngine(QueryEngine): - """Query the N-Triples file directly with comunica-sparql-file.""" + """Query the N-Triples file directly with comunica-sparql-file. + + Comunica has no persistent index: each invocation parses the whole source + into an in-memory store, answers one query, and exits. That is fine for a + fixture and unworkable for a cohort-scale graph, where the parse alone can + exceed the per-query timeout -- and then does so again for every remaining + query. ``engine_advice`` reports that before a run commits to it. + """ name = "comunica" @@ -1383,17 +1805,10 @@ def execute(self, query_id: str, query_path: Path) -> dict[str, Any]: else command ) started = time.monotonic() - try: - with raw_path.open("wb") as stdout, stderr_path.open("wb") as stderr: - result = subprocess.run( - timed, check=False, stdout=stdout, stderr=stderr, - timeout=self.query_timeout, - ) - returncode = result.returncode - error = None - except subprocess.TimeoutExpired: - returncode = 124 - error = f"query exceeded {self.query_timeout}s" + returncode, error = run_query_process( + timed, stdout_path=raw_path, stderr_path=stderr_path, + timeout=self.query_timeout, + ) return self._envelope( query_id, query_path, returncode=returncode, started=started, raw_path=raw_path, stderr_path=stderr_path, time_path=time_path, error=error, @@ -1700,15 +2115,10 @@ def execute(self, query_id: str, query_path: Path) -> dict[str, Any]: "-t", "application/sparql-results+json", ] started = time.monotonic() - try: - with raw_path.open("wb") as stdout, stderr_path.open("wb") as stderr: - result = subprocess.run( - command, check=False, stdout=stdout, stderr=stderr, - timeout=self.query_timeout, - ) - returncode, error = result.returncode, None - except subprocess.TimeoutExpired: - returncode, error = 124, f"query exceeded {self.query_timeout}s" + returncode, error = run_query_process( + command, stdout_path=raw_path, stderr_path=stderr_path, + timeout=self.query_timeout, + ) return self._envelope( query_id, query_path, returncode=returncode, started=started, raw_path=raw_path, stderr_path=stderr_path, error=error, @@ -2440,6 +2850,7 @@ def run_validation(args: argparse.Namespace) -> int: # multi-engine run usable as a benchmark. per_engine: dict[str, dict[str, Any]] = {} engine_descriptions: dict[str, Any] = {} + engine_warnings: dict[str, list[str]] = {} for engine_name in args.engines: engine_raw_dir = raw_dir / engine_name engine_raw_dir.mkdir(parents=True, exist_ok=True) @@ -2450,6 +2861,12 @@ def run_validation(args: argparse.Namespace) -> int: progress.emit("progress", completed=0, detail=f"preparing {engine_name} engine") if not quiet: print(f"[{args.dataset_id}] preparing {engine_name} engine", flush=True) + advice = engine_advice( + engine_name, decoded, len(query_ids), args.query_timeout + ) + if advice: + engine_warnings.setdefault(engine_name, []).append(advice) + eprint(f"[{args.dataset_id}] warning: {advice}") try: engine.prepare() except (RuntimeError, OSError) as error: @@ -2461,6 +2878,8 @@ def run_validation(args: argparse.Namespace) -> int: continue executions: dict[str, dict[str, Any]] = {} + abandoned: str | None = None + engine_started = time.monotonic() try: engine_descriptions[engine_name] = engine.describe() for completed, query_id in enumerate(query_ids, start=1): @@ -2481,16 +2900,61 @@ def run_validation(args: argparse.Namespace) -> int: "progress", completed=completed, query_id=query_id, detail=f"{engine_name}: completed {query_id}", ) + + # A query that exceeded the timeout says the engine + # cannot answer this graph in the time allowed, and the + # remaining queries are no easier. Running all of them + # anyway costs one timeout each: with the defaults that + # is 27 hours per engine per target, which is how a + # validation step comes to look like a hang rather than + # a failure. Stop and report instead. + if ( + args.stop_after_query_timeout + and executions[query_id].get("exitCode") == 124 + ): + abandoned = ( + f"{query_id} exceeded the {engine.query_timeout}s " + f"per-query timeout; skipped " + f"{len(query_ids) - completed} further queries " + f"rather than spending that timeout on each. " + f"Raise --query-timeout, or use an indexed " + f"engine or artifact for a graph this size." + ) + break + + budget = args.validation_time_budget + if budget and time.monotonic() - engine_started > budget: + abandoned = ( + f"engine exceeded the {budget}s validation time " + f"budget after {completed} of {len(query_ids)} " + f"queries. Raise or clear " + f"--validation-time-budget to allow more." + ) + break finally: engine.stop() + if abandoned is not None: + if not quiet: + eprint(f"[{args.dataset_id}] {engine_name}: {abandoned}") + progress.emit( + "progress", completed=len(query_ids), + detail=f"{engine_name}: abandoned", + ) + engine_dir = results_dir / "engines" / engine_name engine_dir.mkdir(parents=True, exist_ok=True) write_json(engine_dir / "query-executions.json", executions) - if any(item["status"] != "PASS" for item in executions.values()): + if abandoned is not None or any( + item["status"] != "PASS" for item in executions.values() + ): per_engine[engine_name] = { "status": "EXECUTION_FAILED", "queryExecutions": executions, } + if abandoned is not None: + per_engine[engine_name]["abandoned"] = abandoned + per_engine[engine_name]["queriesRun"] = len(executions) + per_engine[engine_name]["queriesPlanned"] = len(query_ids) continue verdict = evaluate_validation( @@ -2506,6 +2970,10 @@ def run_validation(args: argparse.Namespace) -> int: verdict["executions"] = executions per_engine[engine_name] = verdict + for engine_name, warnings in engine_warnings.items(): + if engine_name in per_engine: + per_engine[engine_name]["warnings"] = warnings + benchmark = build_benchmark( per_engine, engine_descriptions, oracle_seconds=oracle_seconds, @@ -2635,6 +3103,29 @@ def build_arg_parser() -> argparse.ArgumentParser: f"(choices: {', '.join(SPARQL_ENGINES)}; default: comunica)" ), ) + parser.add_argument( + "--validation-time-budget", + type=int, + default=0, + help=( + "Wall-clock ceiling in seconds for one engine's whole query set " + "(default: 0, no ceiling). A backstop for queries that are slow but " + "never individually time out; the per-query timeout and " + "--stop-after-query-timeout handle the common case." + ), + ) + parser.add_argument( + "--continue-after-query-timeout", + dest="stop_after_query_timeout", + action="store_false", + default=True, + help=( + "Keep running an engine's remaining queries after one exceeds the " + "per-query timeout. Off by default: a timeout means the engine " + "cannot answer this graph in the time allowed, and the remaining " + "queries cost one timeout each" + ), + ) parser.add_argument( "--query-timeout", type=int, @@ -2688,7 +3179,7 @@ def build_arg_parser() -> argparse.ArgumentParser: action="store_true", help=( "Treat a missing-token conformance failure (a plain '.' literal not " - "typed as vcfr:Null) as a validation failure instead of a report-only " + "typed as vcfc:Null) as a validation failure instead of a report-only " "observation" ), ) @@ -2792,6 +3283,9 @@ def resolve_args(parser: argparse.ArgumentParser, argv: list[str] | None = None) ): if value <= 0: parser.error(f"{name} must be a positive integer") + # 0 is meaningful here: no ceiling. + if args.validation_time_budget < 0: + parser.error("--validation-time-budget must be zero or a positive integer") if not 1 <= args.qlever_port <= 65535: parser.error("--qlever-port must be between 1 and 65535") if args.shacl_shapes is not None: diff --git a/test/README.md b/test/README.md index c66c5d7..4fb422f 100644 --- a/test/README.md +++ b/test/README.md @@ -4,6 +4,15 @@ This repository uses `unittest` (Python standard library) to isolate orchestrati ## What is covered +- `test/test_linking_unit.py` + - Exercises all three shipped linkers with known-answer token and interval + cases, the actual Ensembl resolver over fake HTTP, offline cache replay, + budgets/retries/host pacing, digest and assembly refusal, and atomic output. + - Covers unordered/plain/gzip RDF, existing subject identity, full/post-hoc + wiring, discovery, scaffolding and previews. No Docker or public API calls. + - These checks do not change the core semantic mutation score; plug-in + SPARQL/mutation auto-discovery remains planned. See `docs/datalinking.md`. + - `test/test_vcf_rdfizer_unit.py` - Verifies wrapper control flow for the 5-step pipeline. - Verifies image/version resolution behavior and error handling. @@ -38,8 +47,9 @@ This repository uses `unittest` (Python standard library) to isolate orchestrati - Mutation testing for the semantic validation suite: corrupts a correct graph in 42 named ways and asserts which corruptions the validator detects, producing a reproducible mutation score (currently 76/78). - - Requires `rdflib` (test-only, in the `dev` extra); the tests skip cleanly - without it. See `docs/validation-methodology.md`. + - Requires `rdflib` (now a runtime dependency for linking); the tests still + skip cleanly without it in source-only environments. See + `docs/validation-methodology.md`. - The fixture derives the VCF, the RDF graph and the parser oracle from one declarative spec, and builds its graph with the project's own emitters, so the two halves cannot drift apart. diff --git a/test/test_linking_unit.py b/test/test_linking_unit.py new file mode 100644 index 0000000..230a736 --- /dev/null +++ b/test/test_linking_unit.py @@ -0,0 +1,462 @@ +"""Known-answer linking and failure tests. No Docker or public API calls.""" + +from contextlib import redirect_stderr, redirect_stdout +from dataclasses import replace +import gzip +import hashlib +from io import BytesIO, StringIO +import json +from pathlib import Path +import shutil +import sys +import tempfile +import unittest +from unittest import mock +from urllib.error import HTTPError + +from rdflib import Graph, Literal, RDF, URIRef + +import vcf_rdfizer +import vcf_rdfizer_link +from vcf_rdfizer_linking import Link, LinkKey +from vcf_rdfizer_linking.inputs import Record, Source, read_rdf, read_tsv, read_vcf +from vcf_rdfizer_linking.manifest import VCFL, VCFR, absolute_iri, discover, load_manifest, select +from vcf_rdfizer_linking.reference import IntervalIndex, acquire_reference, check_assembly +from vcf_rdfizer_linking.runner import LinkRunError, keys_for, run_linkers, run_stage +from vcf_rdfizer_linking.session import CachedSession, NetworkPolicy + +ROOT = Path(__file__).resolve().parents[1] +EXAMPLE = ROOT / "examples/linking/example.vcf" + + +def base_graph(path=EXAMPLE): + graph = Graph() + for row in read_vcf(path): + source = URIRef(row.source) + graph.add((source, RDF.type, VCFR.VCFFile)) + graph.add((source, VCFR.referenceGenome, Literal(row.reference))) + if isinstance(row, Source): + continue + record, call = URIRef(row.record), URIRef(row.call) + graph.add((source, VCFR.hasRecord, record)) + graph.add((record, RDF.type, VCFR.VCFRecord)) + graph.add((record, VCFR.hasCall, call)) + graph.add((call, RDF.type, VCFR.VariantCall)) + for key, value in (("chrom", row.chrom), ("pos", row.pos), ("ref", row.ref), ("alt", row.alt), ("recordId", row.id)): + graph.add((record, VCFR[key], Literal(value))) + graph.add((call, VCFR.infoRaw, Literal(row.info))) + return graph + + +class HTTPResponse(BytesIO): + def __init__(self, body, code=200, headers=None): + super().__init__(body if isinstance(body, bytes) else json.dumps(body).encode()) + self.code, self.headers = code, headers or {} + + +class FakeClock: + def __init__(self): + self.now, self.delays = 0, [] + + def __call__(self): + return self.now + + def sleep(self, seconds): + self.delays.append(seconds) + self.now += seconds + + +class LinkingTests(unittest.TestCase): + def setUp(self): + self.temp = tempfile.TemporaryDirectory() + self.addCleanup(self.temp.cleanup) + self.root = Path(self.temp.name) + self.cache = self.root / "cache" + self.output = self.root / "example.links.nt" + self.manifests = discover() + self.token = self.manifests["rsid-dbsnp"] + self.interval = self.manifests["gene-demo"] + self.live = replace(self.manifests["rsid-ensembl"], contact_email="test@example.org") + self.clock = FakeClock() + + def policy(self, *manifests): + return NetworkPolicy(manifests or [self.live], clock=self.clock, sleep=self.clock.sleep) + + def run_examples(self, manifests=None, records=None, **options): + return run_linkers(records if records is not None else read_vcf(EXAMPLE), + manifests or [self.token, self.interval], self.output, cache_dir=self.cache, **options) + + def copy_manifest(self, manifest, transform=lambda text: text): + directory = self.root / manifest.id + shutil.copytree(manifest.directory, directory) + path = directory / "linker.ttl" + path.write_text(transform(path.read_text())) + return directory + + def session(self, transport, *, manifest=None, offline=False, policy=None): + return CachedSession(manifest or self.live, self.cache, policy or self.policy(manifest or self.live), offline=offline, transport=transport) + + def test_tier_1_and_2_known_answers_provenance_and_unique_terms(self): + report = self.run_examples(offline=True) + graph = Graph().parse(self.output, format="nt") + self.assertEqual(report["records"], 4) + self.assertEqual(report["link_triples"], 7) + self.assertEqual([m["unique_keys"] for m in report["linkers"]], [2, 4]) + self.assertEqual(set(graph.objects(URIRef("file://example.vcf#call/2"), VCFL.overlapsGene)), + {URIRef("https://example.org/genes/demo-gene-A"), URIRef("https://example.org/genes/demo-gene-B")}) + self.assertFalse(list(graph.objects(URIRef("file://example.vcf#call/3"), VCFL.overlapsGene))) + self.assertEqual(len(graph), report["triples"]) + self.assertEqual(len(self.output.read_text().splitlines()), len(graph)) + self.assertTrue(all(isinstance(s, URIRef) and isinstance(o, (URIRef, Literal)) for s, _, o in graph)) + for manifest, expected in ((self.token, 3), (self.interval, 4)): + node = URIRef("file://example.vcf#linkset/" + manifest.id) + self.assertEqual(int(graph.value(node, VCFL.linkCount)), expected) + self.assertEqual(str(graph.value(URIRef("file://example.vcf#linkset/gene-demo"), VCFL.referenceDigest)), "sha256:" + self.interval.reference.sha256) + + def test_info_tokens_missing_values_and_uri_encoding(self): + m = replace(self.token, field="INFO/RS", split_on=",", accept=".+") + record = next(r for r in read_vcf(EXAMPLE) if isinstance(r, Record)) + record = replace(record, info="RS=rs1,rs1,.,a/b?c,,é") + report = self.run_examples([m], [record]) + self.assertEqual(report["link_triples"], 3) + self.assertIn("dbsnp:a%2Fb%3Fc", self.output.read_text()) + self.assertIn("dbsnp:%C3%A9", self.output.read_text()) + self.assertEqual(keys_for(replace(record, info="DB;XX=x"), m), []) + with self.assertRaisesRegex(ValueError, "Duplicate INFO"): + keys_for(replace(record, info="RS=rs1;RS=rs2"), m) + + def test_token_regex_matches_whole_token(self): + record = next(r for r in read_vcf(EXAMPLE) if isinstance(r, Record)) + self.assertEqual(keys_for(replace(record, id="rs334;RS1;xrs2;rs3x;.;"), self.token), [LinkKey(token="rs334")]) + + def test_interval_closed_boundaries_ref_span_and_exact_chromosome(self): + path = acquire_reference(self.interval.reference, self.cache, offline=True) + index = IntervalIndex(path, self.interval.reference) + expected = {99: set(), 100: {"demo-gene-A"}, 200: {"demo-gene-A", "demo-gene-B"}, 250: {"demo-gene-B"}, 251: set()} + for pos, matches in expected.items(): + self.assertEqual(set(index.overlaps(LinkKey(chrom="1", start=pos, end=pos))), matches) + self.assertEqual(set(index.overlaps(LinkKey(chrom="1", start=99, end=100))), {"demo-gene-A"}) + self.assertEqual(list(index.overlaps(LinkKey(chrom="chr1", start=100, end=100))), []) + row = next(r for r in read_vcf(EXAMPLE) if isinstance(r, Record)) + self.assertEqual(keys_for(replace(row, pos="99", ref="AT"), self.interval), [LinkKey(chrom="1", start=99, end=100)]) + for alt in ("", "*", "N]2:20]"): + self.assertEqual(keys_for(replace(row, alt=alt), self.interval), []) + + def test_nested_gff_features_are_not_missed(self): + gff = self.root / "nested.gff3" + gff.write_text("1\tx\tgene\t1\t1000\t.\t+\t.\tID=long\n1\tx\tgene\t5\t10\t.\t+\t.\tID=short\n") + index = IntervalIndex(gff, self.interval.reference) + self.assertEqual(list(index.overlaps(LinkKey(chrom="1", start=999, end=999))), ["long"]) + + def test_assembly_missing_conflicting_and_override(self): + for reference in ("GRCh38", "file:///genomes/Homo_sapiens.GRCh38.dna.fa", "hg38"): + check_assembly(reference, "GRCh38") + check_assembly("unknown.fa", "GRCh38", "GRCh38") + for reference, override in (("GRCh37", None), ("GRCh37", "GRCh38"), ("GRCh38", "GRCh37"), (".", None)): + with self.assertRaises(ValueError): + check_assembly(reference, "GRCh38", override) + + def test_assembly_failure_precedes_any_resolution(self): + records = [replace(row, reference="GRCh37") for row in read_vcf(EXAMPLE)] + with mock.patch("vcf_rdfizer_linking.runner.load_resolver") as resolver: + with self.assertRaisesRegex(LinkRunError, "Assembly mismatch"): + self.run_examples([self.live, self.interval], records) + resolver.assert_not_called() + self.assertFalse(self.output.exists()) + + def test_digest_mismatch_and_corrupt_reference_cache_fail_closed(self): + directory = self.copy_manifest(self.interval) + (directory / "genes.gff3").write_text("tampered") + with self.assertRaisesRegex(ValueError, "digest mismatch"): + acquire_reference(load_manifest(directory).reference, self.cache, offline=True) + path = acquire_reference(self.interval.reference, self.cache, offline=True) + path.write_text("tampered cache") + with self.assertRaisesRegex(ValueError, "digest mismatch"): + acquire_reference(self.interval.reference, self.cache, offline=True) + + def test_https_bundle_stream_cache_gzip_and_offline_miss(self): + raw = gzip.compress((self.interval.directory / "genes.gff3").read_bytes()) + reference = replace(self.interval.reference, url="https://example.org/genes.gff3.gz", sha256=hashlib.sha256(raw).hexdigest()) + with self.assertRaisesRegex(ValueError, "cache miss"): + acquire_reference(reference, self.cache, offline=True) + opener = mock.Mock() + opener.open.return_value = HTTPResponse(raw) + with mock.patch("vcf_rdfizer_linking.reference.build_opener", return_value=opener): + path = acquire_reference(reference, self.cache) + self.assertEqual(path, acquire_reference(reference, self.cache, offline=True)) + self.assertEqual(opener.open.call_count, 1) + self.assertEqual(list(IntervalIndex(path, reference).overlaps(LinkKey(chrom="2", start=20, end=20))), ["demo-gene-C"]) + + def test_tier_3_real_resolver_batches_deduplicates_and_replays_offline(self): + calls = [] + def transport(request, timeout): + calls.append(request) + self.assertEqual(json.loads(request.data), {"ids": ["rs334", "rs699"]}) + return HTTPResponse({"rs334": {"name": "rs334"}, "rs699": {"name": "rs699"}}) + def factory(m, cache, policy, offline): + return CachedSession(m, cache, policy, offline=offline, transport=transport) + report = self.run_examples([self.live], session_factory=factory) + self.assertEqual(len(calls), 1) + self.assertIn("test@example.org", calls[0].get_header("User-agent")) + self.assertEqual(report["link_triples"], 3) + self.assertEqual(report["linkers"][0]["requests"], 1) + first = set(Graph().parse(self.output, format="nt").triples((None, VCFL.sameVariantAs, None))) + self.output.unlink() + report = self.run_examples([self.live], session_factory=factory, offline=True) + self.assertEqual(len(calls), 1) + self.assertEqual(report["linkers"][0]["cache_hits"], 1) + self.assertEqual(first, set(Graph().parse(self.output, format="nt").triples((None, VCFL.sameVariantAs, None)))) + + def test_live_missing_identifier_emits_nothing_and_bad_payload_fails(self): + from vcf_rdfizer_linking.runner import load_resolver + from vcf_rdfizer_linking import LinkerContext + resolver = load_resolver(self.live) + session = mock.Mock() + session.post.return_value.json.return_value = {"rs334": {"name": "rs334"}} + self.assertEqual(len(list(resolver([LinkKey(token="rs334"), LinkKey(token="rs699")], LinkerContext(session)))), 1) + for payload in ([], {"rs334": "bad"}, {"rs334": {}}): + session.post.return_value.json.return_value = payload + with self.assertRaises(ValueError): + list(resolver([LinkKey(token="rs334")], LinkerContext(session))) + + def test_offline_cache_miss_issues_no_request(self): + transport = mock.Mock() + with self.assertRaisesRegex(ValueError, "offline/cache-only"): + self.session(transport, offline=True).get(self.live.endpoint) + transport.assert_not_called() + + def test_retry_after_and_per_run_budget_include_retries(self): + transport = mock.Mock(side_effect=[HTTPResponse({}, 429, {"Retry-After": "4.5"}), HTTPResponse({}, 503), HTTPResponse({})]) + session = self.session(transport) + session.get(self.live.endpoint) + self.assertEqual(session.stats["requests"], 3) + self.assertEqual(self.clock.delays, [4.5, 2.0]) + self.assertEqual(session.stats["final_service_status"], 200) + manifest = replace(self.live, max_requests=1) + session = self.session(mock.Mock(return_value=HTTPResponse({}, 503)), manifest=manifest) + with self.assertRaisesRegex(ValueError, "maxRequestsPerRun=1 exhausted"): + session.get(self.live.endpoint + "/different") + self.assertEqual(session.stats["requests"], 1) + + def test_retry_after_http_date_is_honoured(self): + transport = mock.Mock(side_effect=[HTTPResponse({}, 429, {"Retry-After": "Wed, 21 Oct 2099 07:28:00 GMT"}), HTTPResponse({})]) + self.session(transport).get(self.live.endpoint) + self.assertGreater(self.clock.delays[0], 1_000_000) + + def test_httperror_response_is_retried(self): + error = HTTPError(self.live.endpoint, 429, "slow", {"Retry-After": "3"}, BytesIO(b"{}")) + session = self.session(mock.Mock(side_effect=[error, HTTPResponse({})])) + session.get(self.live.endpoint) + self.assertEqual(session.stats["requests"], 2) + self.assertEqual(self.clock.delays, [3.0]) + + def test_host_rate_shared_across_linkers_and_budget_across_sessions(self): + other = replace(self.live, id="second", requests_per_second=0.5) + policy = self.policy(self.live, other) + self.session(mock.Mock(return_value=HTTPResponse({})), policy=policy).get(self.live.endpoint) + self.session(mock.Mock(return_value=HTTPResponse({})), manifest=other, policy=policy).get(other.endpoint) + self.assertEqual(self.clock.delays, [2.0]) + limited = replace(self.live, max_requests=1) + with self.assertRaisesRegex(ValueError, "exhausted"): + self.session(mock.Mock(), manifest=limited, policy=policy).get(self.live.endpoint + "/other") + + def test_cache_separates_version_method_and_request_body_and_checks_digest(self): + transport = mock.Mock(side_effect=lambda *a, **k: HTTPResponse({})) + for manifest, method, body in ((self.live, "GET", None), (self.live, "POST", {"ids": ["rs1"]}), + (self.live, "POST", {"ids": ["rs2"]}), (replace(self.live, version="2"), "GET", None)): + session = self.session(transport, manifest=manifest) + session.get(manifest.endpoint) if method == "GET" else session.post(manifest.endpoint, json=body) + self.assertEqual(transport.call_count, 4) + files = list(self.cache.rglob("*.json")) + self.assertEqual(len(files), 4) + for file in files: + cached = json.loads(file.read_text()) + cached["sha256"] = "0" * 64 + file.write_text(json.dumps(cached)) + with self.assertRaisesRegex(ValueError, "Corrupt response cache"): + self.session(transport, offline=True).get(self.live.endpoint) + + def test_undeclared_hosts_paths_redirects_and_placeholder_contact(self): + transport = mock.Mock() + for url in ("https://other.org/variation/homo_sapiens", "https://rest.ensembl.org/other", "http://rest.ensembl.org/variation/homo_sapiens"): + with self.assertRaisesRegex(ValueError, "outside declared"): + self.session(transport).get(url) + transport.assert_not_called() + with self.assertRaisesRegex(ValueError, "contact"): + self.session(transport, manifest=self.manifests["rsid-ensembl"]).get(self.live.endpoint) + with self.assertRaisesRegex(ValueError, "HTTP 302"): + self.session(mock.Mock(return_value=HTTPResponse({}, 302))).get(self.live.endpoint) + + def test_resolver_invalid_key_and_iri_leave_no_partial_output(self): + for bad in (Link(LinkKey(token="rs999"), "https://example.org/ok"), Link(LinkKey(token="rs334"), 'https://example.org/> ')): + with mock.patch("vcf_rdfizer_linking.runner.load_resolver", return_value=lambda batch, ctx: [bad]): + with self.assertRaises(LinkRunError): + self.run_examples([self.token, self.live]) + self.assertFalse(self.output.exists()) + + def test_resolver_exception_records_failure_and_never_changes_base_graph(self): + rdf = self.root / "base.nt" + original = base_graph().serialize(format="nt").encode() + rdf.write_bytes(original) + with mock.patch("vcf_rdfizer_linking.runner.load_resolver", return_value=mock.Mock(side_effect=ValueError("broken resolver"))): + with self.assertRaisesRegex(LinkRunError, "broken resolver"): + run_stage(rdf, [self.token, self.live], self.output, metrics_dir=self.root / "metrics", cache_dir=self.cache) + self.assertEqual(rdf.read_bytes(), original) + self.assertFalse(self.output.exists()) + report = json.loads(next((self.root / "metrics/stages/linking").glob("*.json")).read_text()) + self.assertEqual(report["status"], "failed") + self.assertEqual(report["linkers"][1]["status"], "failed") + self.assertIn("linking", json.loads((self.root / "metrics/run.json").read_text())) + + def test_unordered_plain_and_gz_rdf_preserve_custom_subjects(self): + graph = base_graph() + old = URIRef("file://example.vcf#call/1") + custom = URIRef("https://example.org/custom-call") + renamed = Graph() + for s, p, o in graph: + renamed.add((custom if s == old else s, p, custom if o == old else o)) + graph = renamed + nt = "\n".join(reversed(graph.serialize(format="nt").splitlines())) + "\n" + for suffix in (".nt", ".nt.gz"): + with self.subTest(suffix=suffix): + path = self.root / ("base" + suffix) + path.write_bytes(gzip.compress(nt.encode()) if suffix.endswith("gz") else nt.encode()) + report = self.run_examples(records=read_rdf(path), offline=True) + linked = Graph().parse(self.output, format="nt") + self.assertEqual(report["link_triples"], 7) + self.assertTrue(list(linked.objects(custom, VCFL.sameVariantAs))) + self.assertTrue(all(s in set(graph.subjects()) for s, p, o in linked if p in {VCFL.sameVariantAs, VCFL.overlapsGene})) + self.output.unlink() + + def test_rdf_missing_call_subject_and_ambiguous_fields_fail(self): + for mutation in ("call", "id"): + graph = base_graph() + if mutation == "call": + graph.remove((URIRef("file://example.vcf#call/1"), None, None)) + else: + graph.add((URIRef("file://example.vcf#record/1"), VCFR.recordId, Literal("rs999"))) + path = self.root / "bad.nt" + path.write_text(graph.serialize(format="nt")) + with self.assertRaises(ValueError): + list(read_rdf(path)) + + def test_empty_vcf_and_rdf_emit_zero_count_provenance(self): + empty = self.root / "empty.vcf" + empty.write_text("##fileformat=VCFv4.3\n##reference=GRCh38\n#CHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\tINFO\n") + rdf = self.root / "empty.nt" + rdf.write_text(base_graph(empty).serialize(format="nt")) + for records in (read_vcf(empty), read_rdf(rdf)): + report = self.run_examples(records=records, offline=True) + self.assertEqual(report["link_triples"], 0) + self.assertEqual(len(list(Graph().parse(self.output, format="nt").subjects(RDF.type, VCFL.Linkset))), 2) + self.output.unlink() + + def test_preview_uses_no_network_no_resolver_import_and_no_cache_writes(self): + for manifest in (self.token, self.interval, self.live): + with mock.patch("vcf_rdfizer_linking.runner.load_resolver", side_effect=AssertionError("must not load")): + report = run_linkers(read_vcf(EXAMPLE, limit=2), [manifest], None, cache_dir=self.cache, dry_run=True) + self.assertEqual(report["records"], 2) + self.assertEqual(report["linkers"][0]["batches"], 1) + self.assertEqual(report["linkers"][0]["status"], "planned") + self.assertFalse(self.cache.exists()) + + def test_output_collision_preserves_existing_file(self): + self.output.write_text("keep me") + with self.assertRaisesRegex(ValueError, "overwrite"): + self.run_examples() + self.assertEqual(self.output.read_text(), "keep me") + + def test_publication_failure_removes_temporary_graph(self): + with mock.patch("vcf_rdfizer_linking.runner.os.link", side_effect=OSError("cannot publish")): + with self.assertRaisesRegex(LinkRunError, "cannot publish"): + self.run_examples([self.token]) + self.assertEqual(list(self.root.glob("*.nt")), []) + + def test_manifest_errors_are_early_and_actionable(self): + changes = [('"rsid-dbsnp"', '"../bad"'), ('"1.0.0"', '"../version"'), ("TokenJoin", "AlleleJoin"), + ('"ID"', '"FORMAT/GT"'), ("{TOKEN}", "{BAD}"), ("sameVariantAs", "bad predicate"), + ("splitOn", "spltiOn"), ('"^rs[0-9]+$"', '"["')] + for before, after in changes: + with self.subTest(change=before): + directory = self.copy_manifest(self.token, lambda t: t.replace(before, after)) + with self.assertRaises(ValueError): + load_manifest(directory) + shutil.rmtree(directory) + for before, after in (("batchSize 100", "batchSize 0"), ("maxRequestsPerRun 100", "maxRequestsPerRun -1"), + ("maxRequestsPerSecond 2", 'maxRequestsPerSecond "nan"'), ("https://rest", "http://rest")): + directory = self.copy_manifest(self.live, lambda t: t.replace(before, after)) + with self.assertRaises(ValueError): + load_manifest(directory) + shutil.rmtree(directory) + + def test_discovery_path_environment_entry_point_and_duplicates(self): + directory = self.copy_manifest(self.token, lambda t: t.replace('"rsid-dbsnp"', '"custom"')) + self.assertIn("custom", discover([directory])) + with mock.patch.dict("os.environ", {"VCF_RDFIZER_LINKER_PATH": str(directory)}): + self.assertEqual(select("custom,custom")[0].id, "custom") + entry = mock.Mock() + entry.load.return_value = lambda: directory + with mock.patch("vcf_rdfizer_linking.manifest.importlib.metadata.entry_points", return_value=[entry]): + self.assertIn("custom", discover()) + (directory / "linker.ttl").write_text((directory / "linker.ttl").read_text().replace('"custom"', '"rsid-dbsnp"')) + with self.assertRaisesRegex(ValueError, "Ambiguous"): + discover([directory]) + + def test_cli_init_check_and_dry_run(self): + directory = self.root / "my-linker" + with redirect_stdout(StringIO()), redirect_stderr(StringIO()): + self.assertEqual(vcf_rdfizer_link.main(["init", "--example", "gene-demo", "-o", str(directory)]), 0) + self.assertEqual(vcf_rdfizer_link.main(["check", str(directory), "--offline", "--links-cache", str(self.cache)]), 0) + self.assertEqual(vcf_rdfizer_link.main(["dry-run", str(directory), "-i", str(EXAMPLE), "--limit", "2", "--links-cache", str(self.cache)]), 0) + self.assertEqual(vcf_rdfizer_link.main(["init", "-o", str(directory)]), 1) + + def test_main_link_mode_has_no_docker_dependency_and_writes_metrics(self): + rdf = self.root / "base.nt" + rdf.write_text(base_graph().serialize(format="nt")) + args = ["vcf-rdfizer", "--mode", "link", "--rdf", str(rdf), "--link", "rsid-dbsnp,gene-demo", "--offline", + "--links-cache", str(self.cache), "-o", str(self.root / "results")] + with mock.patch.object(sys, "argv", args), mock.patch.object(vcf_rdfizer, "check_docker", side_effect=AssertionError("Docker must not run")), redirect_stdout(StringIO()): + self.assertEqual(vcf_rdfizer.main(), 0) + self.assertTrue((self.root / "results/base.links.nt").is_file()) + run = json.loads(next((self.root / "results/run_metrics").rglob("run.json")).read_text()) + self.assertEqual(run["mode"], "link") + self.assertEqual(next(iter(run["linking"].values()))["link_triples"], 7) + + def test_full_mode_links_plain_and_gzip_aggregates_without_changing_them(self): + from test.test_vcf_rdfizer_unit import invoke_main, mocked_triplets + input_dir = self.root / "inputs" + input_dir.mkdir() + vcf = input_dir / "sample.vcf" + shutil.copyfile(EXAMPLE, vcf) + rules = self.root / "rules.ttl" + rules.write_text("@prefix ex: .\n") + original = base_graph(vcf).serialize(format="nt").encode() + for storage in ("plain", "space-optimized"): + out = self.root / storage + def fake_run(cmd, **kwargs): + if "/opt/vcf-rdfizer/run_conversion.sh" in cmd: + directory = out / "sample" + directory.mkdir(parents=True, exist_ok=True) + if storage == "plain": + (directory / "sample.nt").write_bytes(original) + else: + (directory / "sample.nt.gz").write_bytes(gzip.compress(original)) + return 0 + with mock.patch.object(vcf_rdfizer, "run", side_effect=fake_run), \ + mock.patch.object(vcf_rdfizer, "check_docker", return_value=True), \ + mock.patch.object(vcf_rdfizer, "docker_image_exists", return_value=True), \ + mock.patch.object(vcf_rdfizer, "discover_tsv_triplets", return_value=mocked_triplets()), \ + mock.patch.object(vcf_rdfizer, "emit_record_detail", return_value=None), \ + redirect_stdout(StringIO()), redirect_stderr(StringIO()): + code = invoke_main(["--input", str(input_dir), "--rules", str(rules), "--rdf-storage-mode", storage, + "--header-representation", "basic", "--compression", "none", "--out", str(out), + "--keep-tsv", "--link", "rsid-dbsnp,gene-demo", "--offline", "--links-cache", str(self.cache)]) + self.assertEqual(code, 0) + linked = Graph().parse(out / "sample/sample.links.nt", format="nt") + self.assertEqual(len(list(linked.triples((None, VCFL.overlapsGene, None)))), 4) + actual = (out / "sample/sample.nt").read_bytes() if storage == "plain" else gzip.decompress((out / "sample/sample.nt.gz").read_bytes()) + self.assertEqual(actual, original) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_validation_benchmark_unit.py b/test/test_validation_benchmark_unit.py index 47fe899..d80e4c1 100644 --- a/test/test_validation_benchmark_unit.py +++ b/test/test_validation_benchmark_unit.py @@ -171,9 +171,9 @@ def test_hdt_queries_are_addressed_with_comunicas_typed_source_prefix(self): def fake_run(command, **kwargs): recorded["command"] = command - return mock.Mock(returncode=0) + return 0, None - with mock.patch.object(V.subprocess, "run", side_effect=fake_run): + with mock.patch.object(V, "run_query_process", side_effect=fake_run): envelope = engine.execute("q01", query) self.assertEqual(recorded["command"][1], f"hdt@{tmp_path / 'cohort.hdt'}") diff --git a/test/test_validation_engines_unit.py b/test/test_validation_engines_unit.py index 45afa60..1c0d9d4 100644 --- a/test/test_validation_engines_unit.py +++ b/test/test_validation_engines_unit.py @@ -11,6 +11,7 @@ import os import subprocess import tempfile +import time import unittest from pathlib import Path from unittest import mock @@ -214,11 +215,11 @@ def test_comunica_engine_builds_the_expected_command(self): def fake_run(command, **kwargs): captured.append(command) - return subprocess.CompletedProcess(command, 0) + return 0, None with mock.patch.object(V.shutil, "which", return_value="/usr/bin/comunica-sparql-file"), \ mock.patch.object(V, "tool_version", return_value=None), \ - mock.patch.object(V.subprocess, "run", side_effect=fake_run): + mock.patch.object(V, "run_query_process", side_effect=fake_run): engine.start() result = engine.execute("q02_variant_shape_counts", query) self.assertEqual(result["status"], "PASS") @@ -226,6 +227,61 @@ def fake_run(command, **kwargs): self.assertIn(str(source), captured[0]) self.assertIn("application/sparql-results+json", captured[0]) + def test_query_timeout_kills_the_whole_process_tree(self): + """A timed-out query must not leave its engine running as an orphan. + + Every query is wrapped in /usr/bin/time, which forks the real engine. + subprocess.run(timeout=) signals only the process it started, so the + engine survived - still holding the whole graph in memory. A few of + those is enough to push a host into swap, which is what made a slow + validation step look like a hang. + """ + with tempfile.TemporaryDirectory() as td: + tmp = Path(td) + marker = tmp / "still-alive" + # A shell that forks a child, exactly as /usr/bin/time does. + script = ( + f"(sleep 30; touch {marker}) & " + "wait" + ) + started = time.monotonic() + returncode, error = V.run_query_process( + ["/bin/sh", "-c", script], + stdout_path=tmp / "out", stderr_path=tmp / "err", timeout=1, + ) + elapsed = time.monotonic() - started + + self.assertEqual(returncode, 124) + self.assertIn("exceeded", error or "") + # The kill must be prompt, not the child's own 30s lifetime. + self.assertLess(elapsed, 20) + # And the grandchild must be gone: if it survived it would create + # the marker once its sleep finished. + time.sleep(2) + self.assertFalse(marker.exists(), "grandchild survived the timeout") + + def test_unindexed_engine_advice_warns_before_a_long_run(self): + """Comunica on a large graph is reported before the run commits to it.""" + with tempfile.TemporaryDirectory() as td: + source = Path(td) / "graph.nt" + source.write_bytes(b"x") + # Small graph: nothing to say. + self.assertIsNone(V.engine_advice("comunica", source, 27, 3600)) + # QLever indexes once, so the advice never applies to it. + self.assertIsNone(V.engine_advice("qlever", source, 27, 3600)) + + big = Path(td) / "big.nt" + big.write_bytes(b"") + with mock.patch.object( + Path, "stat", + return_value=os.stat_result((0, 0, 0, 0, 0, 0, 40 * 1024 ** 3, 0, 0, 0)), + ): + advice = V.engine_advice("comunica", big, 27, 3600) + self.assertIsNotNone(advice) + # It must say what it will cost and what to do instead. + self.assertIn("27h", advice) + self.assertIn("qlever", advice) + def test_comunica_reports_a_missing_binary_clearly(self): """An image without Comunica must say so, not fail obscurely.""" with tempfile.TemporaryDirectory() as td: diff --git a/test/test_validation_logic_unit.py b/test/test_validation_logic_unit.py index a945cec..4f59d55 100644 --- a/test/test_validation_logic_unit.py +++ b/test/test_validation_logic_unit.py @@ -35,13 +35,13 @@ def load_runner(): V = load_runner() -def parser_fixture() -> dict: +def parser_fixture(representation: str = "expanded") -> dict: """The canonical fixture's oracle. Shared with the graph-level mutation harness rather than hand-written here, so there is exactly one description of what the fixture VCF contains. """ - return copy.deepcopy(fixtures.parser_summary("expanded")) + return copy.deepcopy(fixtures.parser_summary(representation)) def sparql_fixture() -> dict: @@ -182,8 +182,8 @@ def test_core_query_set_is_pinned(self): def test_digest_covers_every_fixed_field(self): """ID, QUAL and INFO are only covered through the record digest.""" query = (V.QUERY_ROOT / "common" / "q11_record_digest.rq").read_text(encoding="utf-8") - for term in ("vcfr:chrom", "vcfr:pos", "vcfr:recordId", "vcfr:ref", - "vcfr:alt", "vcfr:qual", "vcfr:filter", "vcfr:infoRaw"): + for term in ("vcfc:chrom", "vcfc:pos", "vcfc:recordId", "vcfc:ref", + "vcfc:alt", "vcfc:qual", "vcfc:filter", "vcfc:infoRaw"): self.assertIn(term, query, f"{term} missing from the record digest") def test_runner_and_wrapper_agree_on_template_encoding(self): @@ -319,7 +319,61 @@ def test_census_covers_qual_and_structured_info(self): """The elements added in Phases 2, 4 and 5 are in the expected inventory.""" predicates = {row["predicate"] for row in parser_fixture()["q09_predicate_census"]} for term in ("qual", "hasInfoValue", "fileDate", "contigId", "filterId", "altId"): - self.assertIn(f"{V.VCFR}{term}", predicates, term) + self.assertIn(f"{V.VCFC}{term}", predicates, term) + + def test_census_covers_the_vcf_core_layers(self): + """Every family the VCF Core emitters added is in the inventory too. + + The census asserts an exact set, so a family missing from it would make + a correct graph report extra predicates rather than passing. + """ + summary = parser_fixture() + predicates = {row["predicate"] for row in summary["q09_predicate_census"]} + classes = {row["class"] for row in summary["q10_class_census"]} + + for term in ( + # Ordering, required by the SPARQL SHACL profile. + "lineIndex", "recordIndex", + # Header attributes and the #CHROM line. + "hasAttribute", "attributeKey", "attributeValue", "attributeIndex", + "hasColumnHeader", "hasGenotypeColumns", + # The allele layer. + "hasReferenceAllele", "hasAltAllele", "alleleIndex", "alleleValue", + "alleleKind", "chromosome", + # Indexed values. + "hasValueItem", "valueIndex", "itemValue", "forAllele", + # Reusable sample identity, emitted in both profiles. + "hasSampleSet", "hasSample", "sampleName", "sampleIndex", + # Field declarations. + "fieldArity", "fieldNumberInteger", "fieldType", + ): + self.assertIn(f"{V.VCFC}{term}", predicates, term) + + for name in ( + "ColumnHeaderLine", "HeaderAttribute", "ReferenceAllele", "AltAllele", + "FieldValueItem", "SampleSet", "VCFSample", "FormatFieldDefinition", + ): + self.assertIn(f"{V.VCFC}{name}", classes, name) + + # The mapping's version sentinel resolves to the subclass for the + # version the fixture declares. + self.assertIn(f"{V.VCFC}{fixtures.VERSION_FILE_CLASS}", classes) + + def test_expanded_census_covers_the_parsed_genotype_layer(self): + """The genotype layer is expanded-only, and the census must say so.""" + expanded = { + row["predicate"] for row in parser_fixture("expanded")["q09_predicate_census"] + } + condensed = { + row["predicate"] for row in parser_fixture("condensed")["q09_predicate_census"] + } + for term in ("hasGenotype", "genotypeString", "ploidy", "phasingStatus", + "hasAlleleCall", "callIndex", "isNoCall", "calledAllele", + "forSample"): + self.assertIn(f"{V.VCFC}{term}", expanded, term) + # The condensed profile keeps these values inside its vectors, so + # deriving them there would be exactly the growth it prevents. + self.assertNotIn(f"{V.VCFC}{term}", condensed, term) def test_digest_separator_prevents_field_boundary_collisions(self): """Shifting a field boundary must not be able to forge a matching digest.""" @@ -344,7 +398,7 @@ def test_info_entry_parsers_agree(self): ) def test_qual_is_typed_as_the_published_shape_requires(self): - """The shape demands xsd:decimal or vcfr:Null, never a plain literal.""" + """The shape demands xsd:decimal or vcfc:Null, never a plain literal.""" import vcf_rdfizer self.assertIn("XMLSchema#decimal", vcf_rdfizer._qual_object("12.5")) diff --git a/test/test_vcf_rdfizer_unit.py b/test/test_vcf_rdfizer_unit.py index 5dea3b7..a2368de 100644 --- a/test/test_vcf_rdfizer_unit.py +++ b/test/test_vcf_rdfizer_unit.py @@ -271,6 +271,23 @@ def latest_metrics_run_dir(metrics_root: Path) -> Path: return run_dirs[-1][1] + +def _vocabulary_registry_path() -> Path | None: + """Locate the published VCF Core version registry, if it is available.""" + override = os.environ.get("VCF_CORE_VOCABULARY_DIR") + candidates = [Path(override)] if override else [] + repo_root = Path(__file__).resolve().parents[1] + candidates += [ + repo_root.parent / "vcf-core-vocabulary", + repo_root.parent / "vcf-rdfizer-vocabulary", + ] + for candidate in candidates: + registry = candidate / "ontology" / "versions" / "registry.json" + if registry.is_file(): + return registry + return None + + class WrapperUnitTests(VerboseTestCase): def test_metrics_directory_uses_recognizable_input_label(self): """Metrics runs keep the full input stem alongside their timestamp.""" @@ -1701,21 +1718,44 @@ def test_default_sample_maps_stream_without_expanded_helper_tables(self): self.assertEqual(stats["records"], 1) self.assertEqual(stats["sample_calls"], 2) self.assertEqual(stats["format_values"], 4) - self.assertEqual(stats["triples"], 19) + # One GT per sample, each diploid. + self.assertEqual(stats["genotypes"], 2) + self.assertEqual(stats["genotype_calls"], 4) rdf_lines = rdf_path.read_text(encoding="utf-8").splitlines() - self.assertEqual(len(rdf_lines), 20) + self.assertEqual(len(rdf_lines), stats["triples"] + 1) self.assertIn( - " " - " .", + " " + " .", rdf_lines, ) self.assertIn( - " " + " " " .", rdf_lines, ) + # The expanded profile gives each call a reusable sample identity in + # addition to its sampleId literal. self.assertIn( - '"."^^ .', + " " + " .", + rdf_lines, + ) + # GT is parsed into an ordered genotype, and its no-call positions + # are marked rather than given a fabricated allele. + self.assertIn( + " " + " " + '"0/1"^^ .', + rdf_lines, + ) + self.assertIn( + " " + " " + '"true"^^ .', + rdf_lines, + ) + self.assertIn( + '"."^^ .', rdf_lines[-1], ) @@ -1746,9 +1786,18 @@ def test_sample_streaming_accepts_a_csv_field_larger_than_python_default(self): self.assertEqual(stats["sample_calls"], 2504) self.assertEqual(stats["format_values"], 2504) - self.assertEqual(stats["triples"], 1 + (2504 * 6)) + self.assertEqual(stats["samples"], 2504) + # The payload is not in the GT lexical space, so no Genotype is + # invented for it; the value stays as the FORMAT field's literal. + self.assertEqual(stats["genotypes"], 0) + # 3 file-level triples (profile, hasSampleSet, SampleSet type) and 6 + # for the single synthesized FORMAT definition, then per sample: 5 + # for the VCFSample and its column-header link, 4 for the SampleCall + # and 4 for its one FORMAT value. + expected = 3 + 6 + (2504 * 13) + self.assertEqual(stats["triples"], expected) with gzip.open(rdf_path, "rt", encoding="utf-8") as handle: - self.assertEqual(sum(1 for _line in handle), 2 + (2504 * 6)) + self.assertEqual(sum(1 for _line in handle), expected + 1) def test_sample_support_strategy_preserves_custom_helper_consumers(self): """Only the exact canonical helper maps use direct RDF streaming.""" @@ -1823,19 +1872,290 @@ def test_condensed_sample_emitter_uses_shared_samples_and_ordered_vectors(self): self.assertEqual(stats["matrices"], 1) self.assertEqual(stats["format_vectors"], 3) self.assertEqual(stats["format_definitions"], 3) - self.assertEqual(stats["triples"], 45) rdf_text = rdf_path.read_text(encoding="utf-8") + self.assertEqual(len(rdf_text.splitlines()), stats["triples"] + 1) self.assertIn("vocab#CondensedRepresentation", rdf_text) self.assertIn("vocab#SampleSet", rdf_text) - self.assertIn("#samples/S3> ", rdf_text) + # Ordinals are xsd:integer so they satisfy the SHACL profiles, which + # constrain every one of them with sh:datatype xsd:integer. + self.assertIn( + "#samples/S3> " + '"3"^^', + rdf_text, + ) self.assertIn("#call/7/matrix/fmt/GT", rdf_text) self.assertIn('"0/1\\t./.\\t1/1"', rdf_text) self.assertIn('"30,12\\t.\\t."', rdf_text) + # A vector cites its declaration at the header line's own IRI. self.assertIn("#header/line/1> .", rdf_text) - self.assertIn("vocab#fieldNumber> \"1\"", rdf_text) - self.assertIn("vocab#fieldDescription> \"Genotype\"", rdf_text) + self.assertIn( + "vocab#FormatFieldDefinition>", rdf_text, + "the vector's declaration must be typed", + ) + # The declaration's ID/Number/Type/Description belong to the header + # emitter, which owns that IRI. Emitting them here too produced two + # copies of every one of those triples, which the validation + # suite's duplicate-triple preflight rejects. + for owned in ("vocab#fieldId>", "vocab#fieldNumber>", + "vocab#fieldType>", "vocab#fieldDescription>"): + self.assertNotIn(owned, rdf_text, owned) self.assertNotIn("vocab#hasSampleCall", rdf_text) self.assertNotIn("vocab#FormatFieldValue", rdf_text) + # The condensed profile keeps genotype values inside their vectors, + # so no per-sample Genotype is derived. (hasGenotypeColumns, on the + # #CHROM line, is a different property and is expected.) + self.assertNotIn("vocab#hasGenotype>", rdf_text) + self.assertIn("vocab#hasGenotypeColumns>", rdf_text) + + def test_version_model_matches_the_published_registry(self): + """The converter's version table must agree with the vocabulary's own. + + VCF Core publishes ``ontology/versions/registry.json`` as the single + source of truth for its version-scoped artifacts: the SHACL overlays, + the reserved-key snapshots and the VCF4xFile classes are all generated + from it. The converter keeps its own dependency-free copy of the same + facts so it works without the vocabulary checked out; this pins the two + together so a new VCF version, or a corrected arity, cannot land on one + side alone. + + Skipped when the vocabulary is not available. Point + VCF_CORE_VOCABULARY_DIR at a checkout to run it. + """ + registry_path = _vocabulary_registry_path() + if registry_path is None: + self.skipTest( + "VCF Core vocabulary not found; set VCF_CORE_VOCABULARY_DIR to " + "a checkout to cross-check the version model" + ) + registry = json.loads(registry_path.read_text(encoding="utf-8")) + vocab = vcf_rdfizer.vocab + + published = {entry["id"] for entry in registry["versions"]} + self.assertEqual( + published, set(vocab.VCF_VERSIONS), + "the converter and the vocabulary disagree about which VCF " + "versions are supported", + ) + # The newest published version is what an unrecognized file falls back + # to, so that has to track the registry too. + self.assertEqual(vocab.FALLBACK_VERSION.short, registry["current"]) + + for entry in registry["versions"]: + version = vocab.VCF_VERSIONS[entry["id"]] + with self.subTest(version=entry["id"]): + self.assertEqual(version.token, entry["code"]) + self.assertEqual(version.file_class, entry["className"]) + self.assertEqual( + version.leading_phase_indicator, entry["leadingPhaseIndicator"] + ) + # "perAlt" means a tuple repeats once per ALT allele; "fixed" + # means one tuple describes the whole record. + self.assertEqual( + version.tuples_per_alt, entry["svTupleScope"] == "perAlt" + ) + + # numberCodes lists regex alternatives; "[0-9]+" and "[.]" are + # the integer and missing forms the model handles separately. + for scope, is_format in (("info", False), ("format", True)): + codes = { + code for code in entry["numberCodes"][scope] + if code != "[0-9]+" + } + codes = {"." if code == "[.]" else code for code in codes} + allowed = { + code for code in vocab.ARITY_INDIVIDUALS + if version.allows_number(code, is_format=is_format) + } + self.assertEqual( + allowed, codes, + f"{scope} Number codes disagree for {entry['id']}", + ) + + expected_tuples = { + key: group["width"] + for group in entry["svTuples"] for key in group["keys"] + } + self.assertEqual( + version.tuple_keys, expected_tuples, + f"flattened-tuple keys disagree for {entry['id']}", + ) + + def test_vcf_version_is_detected_from_the_fileformat_line(self): + """Auto-detection reads ##fileformat; nothing has to be supplied.""" + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + for declared, expected_short, expected_recognized in ( + ("VCFv4.1", "4.1", True), + ("VCFv4.3", "4.3", True), + ("VCFv4.5", "4.5", True), + # VCF Core claims no 4.0 conformance overlay, so 4.0 is not + # recognized and no version class may be claimed for it. + ("VCFv4.0", "4.5", False), + ("", "4.5", False), + ("nonsense", "4.5", False), + ): + metadata = tmp_path / f"{expected_short}-{declared or 'none'}.tsv" + metadata.write_text( + "SOURCE_FILE\tFILE_FORMAT\tFILE_DATE\tSOURCE_SOFTWARE\t" + "REFERENCE_GENOME\tHEADER_COUNT\tRECORD_COUNT\n" + f"x.vcf\t{declared}\t\t\t\t1\t1\n", + encoding="utf-8", + ) + version, recognized, raw = vcf_rdfizer.read_declared_vcf_version(metadata) + self.assertEqual(version.short, expected_short, declared) + self.assertEqual(recognized, expected_recognized, declared) + self.assertEqual(raw, declared) + + def test_rules_rendering_resolves_the_version_class_sentinel(self): + """The mapping's version sentinel becomes the input's own file class.""" + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + template = tmp_path / "template.ttl" + template.write_text( + "rr:class vcfc:VCFFile ;\n rr:class vcfc:VCFVersionFile\n", + encoding="utf-8", + ) + + rendered = tmp_path / "v43.ttl" + vcf_rdfizer.render_rules_for_triplet( + template, rendered, "r.tsv", "h.tsv", "m.tsv", "sc.tsv", "sf.tsv", + vcf_version=vcf_rdfizer.vocab.VCF_VERSIONS["4.3"], + ) + self.assertIn("rr:class vcfc:VCF43File", rendered.read_text()) + self.assertNotIn("VCFVersionFile", rendered.read_text()) + + # An unrecognized version resolves to the base class the subject map + # already asserts, so the graph never claims a gate that cannot be + # checked and never gains a term the vocabulary does not define. + neutral = tmp_path / "neutral.ttl" + vcf_rdfizer.render_rules_for_triplet( + template, neutral, "r.tsv", "h.tsv", "m.tsv", "sc.tsv", "sf.tsv", + vcf_version=None, + ) + text = neutral.read_text() + self.assertNotIn("VCFVersionFile", text) + self.assertEqual(text.count("rr:class vcfc:VCFFile"), 2) + + def test_confidence_intervals_follow_the_version_tuple_rule(self): + """CIPOS is one pair per record before VCF 4.4 and one per ALT after.""" + vocab = vcf_rdfizer.vocab + early, late = vocab.VCF_VERSIONS["4.3"], vocab.VCF_VERSIONS["4.4"] + + # Both treat CIPOS as a materialized tuple, so its items are emitted + # even though 4.4 declares it Number=. -- the overlay counts them. + self.assertTrue(early.is_positional("CIPOS", "2")) + self.assertTrue(late.is_positional("CIPOS", ".")) + + # Before 4.4 an item has a position but no allele to point at. + self.assertTrue(early.value_item_link("CIPOS", "2", 0).is_empty) + # From 4.4 items 0-1 belong to ALT 1 and items 2-3 to ALT 2. + self.assertEqual( + [late.value_item_link("CIPOS", ".", i).allele_index for i in range(4)], + [1, 1, 2, 2], + ) + + # CILEN and CICN are not tuple keys before 4.4 at all. + self.assertIsNone(early.tuple_arity("CILEN")) + self.assertEqual(late.tuple_arity("CILEN"), 2) + + def test_version_gates_number_codes_and_format_families(self): + """Number codes and the LA/M families arrived in specific versions.""" + vocab = vcf_rdfizer.vocab + v41, v42, v44, v45 = ( + vocab.VCF_VERSIONS[s] for s in ("4.1", "4.2", "4.4", "4.5") + ) + # Number=R arrived in 4.2, P in 4.4, and LA/LR/LG/M in 4.5. + self.assertFalse(v41.allows_number("R", is_format=True)) + self.assertTrue(v42.allows_number("R", is_format=True)) + self.assertFalse(v42.allows_number("P", is_format=True)) + self.assertTrue(v44.allows_number("P", is_format=True)) + self.assertFalse(v44.allows_number("M", is_format=True)) + self.assertTrue(v45.allows_number("M", is_format=True)) + # A plain integer count is legal in every version. + self.assertTrue(v41.allows_number("2", is_format=False)) + + self.assertFalse(v44.local_alleles) + self.assertTrue(v45.local_alleles) + self.assertFalse(v44.base_modifications) + self.assertTrue(v45.base_modifications) + # EVENT is one per record before 4.4 and one per ALT after; EVENTTYPE + # does not exist before 4.4 at all. + self.assertFalse(v42.events_per_alt) + self.assertFalse(v42.event_types) + self.assertTrue(v44.events_per_alt) + self.assertTrue(v44.event_types) + + def test_expanded_emitter_omits_families_the_version_lacks(self): + """A 4.4 file gets no base modifications and no local-allele set.""" + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + records_tsv = tmp_path / "s.records.tsv" + records_tsv.write_text( + "SOURCE_FILE\tROW_ID\tCHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\t" + "INFO\tFORMAT\tS1\n" + "s.vcf\t1\t1\t100\t.\tA\tG\t50\tPASS\t.\tGT:LAA:M27551C\t" + "0/1:1:0.8\n", + encoding="utf-8", + ) + vocab = vcf_rdfizer.vocab + + for short, expect_families in (("4.4", False), ("4.5", True)): + rdf_path = tmp_path / f"{short}.nt" + rdf_path.write_text("

.\n", encoding="utf-8") + stats = vcf_rdfizer.append_expanded_sample_rdf( + records_tsv, rdf_path, None, + version=vocab.VCF_VERSIONS[short], + progress_interval_records=0, + ) + expected = 1 if expect_families else 0 + self.assertEqual(stats["local_allele_sets"], expected, short) + self.assertEqual(stats["base_modifications"], expected, short) + # The raw FORMAT values are present either way; only the + # derived resources the version does not define are withheld. + text = rdf_path.read_text(encoding="utf-8") + self.assertIn('vocab#fieldValue> "1"', text) + self.assertIn('vocab#fieldValue> "0.8"', text) + + + def test_declared_field_definitions_are_emitted_exactly_once(self): + """The header emitter owns a declared definition; value emitters cite it. + + Both used to emit ID/Number/Type/Description at the same header-line + IRI, so every declared INFO and FORMAT key produced a duplicate of each + of those triples. + """ + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + records_tsv = tmp_path / "s.records.tsv" + records_tsv.write_text( + "SOURCE_FILE\tROW_ID\tCHROM\tPOS\tID\tREF\tALT\tQUAL\tFILTER\t" + "INFO\tFORMAT\tS1\n" + "s.vcf\t1\t1\t100\t.\tA\tG\t50\tPASS\tDP=7\tGT:DP\t0/1:7\n", + encoding="utf-8", + ) + headers_tsv = tmp_path / "s.header_lines.tsv" + headers_tsv.write_text( + "SOURCE_FILE\tHEADER_INDEX\tHEADER_KEY\tHEADER_VALUE\tRAW_LINE\n" + "s.vcf\t1\tfileformat\tVCFv4.5\tx\n" + "s.vcf\t2\tINFO\t\tx\n" + "s.vcf\t3\tFORMAT\t\tx\n" + "s.vcf\t4\tFORMAT\t\tx\n", + encoding="utf-8", + ) + rdf_path = tmp_path / "s.nt" + rdf_path.write_text("", encoding="utf-8") + + vcf_rdfizer.append_expanded_sample_rdf( + records_tsv, rdf_path, headers_tsv, progress_interval_records=0 + ) + vcf_rdfizer.append_header_representation_rdf(headers_tsv, rdf_path) + vcf_rdfizer.append_record_detail_rdf( + records_tsv, headers_tsv, rdf_path, progress_interval_records=0 + ) + + lines = [l for l in rdf_path.read_text(encoding="utf-8").splitlines() if l.strip()] + duplicates = {line for line in lines if lines.count(line) > 1} + self.assertEqual(duplicates, set(), "duplicate triples emitted") def test_structured_format_header_parser_preserves_quoted_commas(self): """FORMAT descriptions with commas and escaped quotes remain one attribute.""" @@ -2015,7 +2335,7 @@ def test_help_flag_prints_usage_guide(self): self.assertEqual(exc.exception.code, 0) text = out_buf.getvalue() self.assertIn("Examples:", text) - self.assertIn("-m {full,compress,decompress,tsv,index,validation}", text) + self.assertIn("-m {full,compress,decompress,tsv,index,validation,link}", text) self.assertIn("-i INPUT", text) self.assertIn("--keep-rmlstreamer-rdf-output", text) self.assertIn("--remove-rdf-storage-output", text) diff --git a/test/validation_fixtures.py b/test/validation_fixtures.py index 458ffc7..e879188 100644 --- a/test/validation_fixtures.py +++ b/test/validation_fixtures.py @@ -21,10 +21,9 @@ from dataclasses import dataclass, field from pathlib import Path -VCFR = "https://w3id.org/vcf-rdfizer/vocab#" +VCFC = "https://w3id.org/vcf-core/vocab#" RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" XSD_INTEGER = "http://www.w3.org/2001/XMLSchema#integer" -XSD_POSITIVE_INTEGER = "http://www.w3.org/2001/XMLSchema#positiveInteger" def _runner(): """Load the shipped validation runner (it lives outside the package path).""" @@ -44,6 +43,12 @@ def _runner(): FILE_DATE = "20260101" SOURCE_SOFTWARE = "vcf-rdfizer-fixture" REFERENCE_GENOME = "GRCh38" +#: The optional vcfc subclass the mapping's version sentinel resolves to for +#: this fixture's declared version. Derived rather than hard-coded so changing +#: FILE_FORMAT above changes the expected graph with it. +VERSION_FILE_CLASS = f"VCF{FILE_FORMAT.removeprefix('VCFv').replace('.', '')}File" +#: The bare version, as vcf_rdfizer_vocab.VCF_VERSIONS keys it. +FIXTURE_VERSION = FILE_FORMAT.removeprefix("VCFv") #: ``##`` meta-information lines, in file order. The ``#CHROM`` line is not one #: of these; ``header_count`` below counts only the ``##`` lines. @@ -163,7 +168,7 @@ def header_lines_tsv_text() -> str: def _literal(value: str) -> str: escaped = value.replace("\\", "\\\\").replace('"', '\\"') if value == ".": - return f'"{escaped}"^^<{VCFR}Null>' + return f'"{escaped}"^^<{VCFC}Null>' return f'"{escaped}"' @@ -184,46 +189,57 @@ def _info_entries(record: "FixtureRecord") -> list[tuple[str, str | None]]: def base_triples(*, include_qual: bool = True, include_info: bool = True) -> list[str]: """The triples RMLStreamer produces from `default_rules.ttl`. - ``include_qual`` is on because the shipped mapping now emits ``vcfr:qual``; - turning it off models the pre-fix mapping, which is how the harness shows - that dropping QUAL is now detected. ``include_info`` models the structured - INFO representation. + This has to track the shipped mapping, and the division it follows is one + rule: RML carries every field whose RDF datatype is the same for every row. + ID, ALT, QUAL, FILTER and INFO are therefore *not* here -- each may be the + VCF missing token, which the vocabulary requires as ``"."^^vcfc:Null``, so + the wrapper's own emitter produces them and ``build_graph`` appends them. + + ``include_qual`` and ``include_info`` are kept because the harness uses them + to model a graph missing those emitter outputs, which is how it shows that + dropping them is detected. """ file_uri = f"file://{SOURCE_FILE}" header_uri = f"{file_uri}#header" + columns_uri = f"{file_uri}#header/columns" out = [ - f"<{file_uri}> <{RDF_TYPE}> <{VCFR}VCFFile> .", - f"<{file_uri}> <{VCFR}fileFormat> {_literal(FILE_FORMAT)} .", - f"<{file_uri}> <{VCFR}sourceSoftware> {_literal(SOURCE_SOFTWARE)} .", - f"<{file_uri}> <{VCFR}referenceGenome> {_literal(REFERENCE_GENOME)} .", - - f"<{file_uri}> <{VCFR}hasHeader> <{header_uri}> .", - f"<{header_uri}> <{RDF_TYPE}> <{VCFR}VCFHeader> .", + f"<{file_uri}> <{RDF_TYPE}> <{VCFC}VCFFile> .", + # The mapping's version sentinel, resolved per input to the subclass for + # the version the file declares. The fixture declares VCFv4.2. + f"<{file_uri}> <{RDF_TYPE}> <{VCFC}{VERSION_FILE_CLASS}> .", + f"<{file_uri}> <{VCFC}fileFormat> {_literal(FILE_FORMAT)} .", + f"<{file_uri}> <{VCFC}sourceSoftware> {_literal(SOURCE_SOFTWARE)} .", + f"<{file_uri}> <{VCFC}referenceGenome> {_literal(REFERENCE_GENOME)} .", + + f"<{file_uri}> <{VCFC}hasHeader> <{header_uri}> .", + f"<{header_uri}> <{RDF_TYPE}> <{VCFC}VCFHeader> .", + # The mandatory #CHROM line. Its ordered sample columns are attached by + # the wrapper, because they live in the records TSV header. + f"<{header_uri}> <{VCFC}hasColumnHeader> <{columns_uri}> .", + f"<{columns_uri}> <{RDF_TYPE}> <{VCFC}ColumnHeaderLine> .", ] for index, (key, value) in enumerate(HEADER_LINES, start=1): line_uri = f"{file_uri}#header/line/{index}" out += [ - f"<{header_uri}> <{VCFR}hasHeaderLine> <{line_uri}> .", - f"<{line_uri}> <{RDF_TYPE}> <{VCFR}HeaderLine> .", - f"<{line_uri}> <{VCFR}headerKey> {_literal(key)} .", - f"<{line_uri}> <{VCFR}headerValue> {_literal(value)} .", + f"<{header_uri}> <{VCFC}hasHeaderLine> <{line_uri}> .", + f"<{line_uri}> <{RDF_TYPE}> <{VCFC}HeaderLine> .", + f"<{line_uri}> <{VCFC}headerKey> {_literal(key)} .", + f"<{line_uri}> <{VCFC}headerValue> {_literal(value)} .", + f'<{line_uri}> <{VCFC}lineIndex> "{index}"^^<{XSD_INTEGER}> .', ] for record in RECORDS: record_uri = f"{file_uri}#record/{record.row_id}" call_uri = f"{file_uri}#call/{record.row_id}" out += [ - f"<{file_uri}> <{VCFR}hasRecord> <{record_uri}> .", - f"<{record_uri}> <{RDF_TYPE}> <{VCFR}VCFRecord> .", - f"<{record_uri}> <{VCFR}chrom> {_literal(record.chrom)} .", - f'<{record_uri}> <{VCFR}pos> "{record.pos}"^^<{XSD_INTEGER}> .', - f"<{record_uri}> <{VCFR}recordId> {_literal(record.record_id)} .", - f"<{record_uri}> <{VCFR}ref> {_literal(record.ref)} .", - f"<{record_uri}> <{VCFR}alt> {_literal(record.alt)} .", - f"<{record_uri}> <{VCFR}hasCall> <{call_uri}> .", - f"<{call_uri}> <{RDF_TYPE}> <{VCFR}VariantCall> .", - f"<{call_uri}> <{VCFR}filter> {_literal(record.filter_value)} .", - f"<{call_uri}> <{VCFR}infoRaw> {_literal(record.info)} .", - f"<{call_uri}> <{VCFR}formatRaw> {_literal(':'.join(record.format_keys))} .", + f"<{file_uri}> <{VCFC}hasRecord> <{record_uri}> .", + f"<{record_uri}> <{RDF_TYPE}> <{VCFC}VCFRecord> .", + f"<{record_uri}> <{VCFC}chrom> {_literal(record.chrom)} .", + f'<{record_uri}> <{VCFC}pos> "{record.pos}"^^<{XSD_INTEGER}> .', + f"<{record_uri}> <{VCFC}ref> {_literal(record.ref)} .", + f'<{record_uri}> <{VCFC}recordIndex> "{record.row_id}"^^<{XSD_INTEGER}> .', + f"<{record_uri}> <{VCFC}hasCall> <{call_uri}> .", + f"<{call_uri}> <{RDF_TYPE}> <{VCFC}VariantCall> .", + f"<{call_uri}> <{VCFC}formatRaw> {_literal(':'.join(record.format_keys))} .", ] return out @@ -256,14 +272,21 @@ def build_graph( "\n".join(base_triples(include_qual=include_qual, include_info=include_info)) + "\n", encoding="utf-8", ) - if include_qual or include_info: - vcf_rdfizer.append_record_detail_rdf( - records_tsv, headers_tsv, graph, - emit_qual=include_qual, emit_info=include_info, + # The fixture declares a VCF version; the emitters follow it exactly as + # a real conversion does, so version-dependent behaviour is exercised + # rather than assumed. + version = vcf_rdfizer.vocab.VCF_VERSIONS[FIXTURE_VERSION] + vcf_rdfizer.append_record_detail_rdf( + records_tsv, headers_tsv, graph, + emit_qual=include_qual, emit_info=include_info, + emit_alleles=include_info, version=version, + progress_interval_records=0, + ) + if representation == "expanded": + vcf_rdfizer.append_expanded_sample_rdf( + records_tsv, graph, headers_tsv, version=version, progress_interval_records=0, ) - if representation == "expanded": - vcf_rdfizer.append_expanded_sample_rdf(records_tsv, graph, progress_interval_records=0) else: vcf_rdfizer.append_condensed_sample_rdf( records_tsv, headers_tsv, graph, progress_interval_records=0 @@ -348,42 +371,80 @@ def _format_shape() -> dict: } -def _header_shape() -> dict: - """Header counters the census needs, derived with the shipped parser.""" +def _declared_numbers(header_key: str) -> dict[str, str]: + """Map each declared INFO or FORMAT ID to its Number token.""" runner = _runner() - classes: Counter[str] = Counter() - filters = alts = contigs = described = 0 - attributes: Counter[str] = Counter() + numbers: dict[str, str] = {} for key, value in HEADER_LINES: - class_name = runner.HEADER_LINE_CLASSES.get(key.lower()) - if class_name is None: - continue - classes[class_name] += 1 - if key.lower() not in {"filter", "alt", "contig"}: + if key.upper() != header_key: continue fields = runner.parse_structured_header_fields(value) - if not (fields.get("ID") or "").strip(): - continue - if key.lower() == "contig": - contigs += 1 - for attribute in ("length", "md5", "assembly"): - if fields.get(attribute): - attributes[attribute] += 1 + ident = (fields.get("ID") or "").strip() + if ident: + numbers.setdefault(ident, fields.get("Number") or ".") + return numbers + + +def _declared_ids(header_key: str) -> set[str]: + """The set of IDs declared by one structured header key.""" + runner = _runner() + ids: set[str] = set() + for key, value in HEADER_LINES: + if key.upper() != header_key: continue - if key.lower() == "filter": - filters += 1 - else: - alts += 1 - if fields.get("Description"): - described += 1 - return { - "headerLineClassCounts": dict(classes), - "filterDefinitionCount": filters, - "altDefinitionCount": alts, - "contigCount": contigs, - "contigAttributeCounts": dict(attributes), - "describedDefinitionCount": described, - } + ident = (runner.parse_structured_header_fields(value).get("ID") or "").strip() + if ident: + ids.add(ident) + return ids + + +def _record_rows() -> list[list[str]]: + """The raw VCF data columns, as the runner's oracle sees them.""" + return [ + [record.chrom, str(record.pos), record.record_id, record.ref, record.alt, + record.qual, record.filter_value, record.info, + ":".join(record.format_keys), *record.sample_payloads] + for record in RECORDS + ] + + +def _header_shape() -> dict: + """Header counters, derived by the shipped runner rather than restated. + + The census asserts an exact inventory, so this has to cover every family the + header emitter produces. Delegating keeps the fixture and the container + oracle on one implementation. + """ + runner = _runner() + shape = dict(runner.emitted_header_counters(list(HEADER_LINES))) + shape["headerValueCount"] = sum(1 for _key, value in HEADER_LINES if value != "") + return shape + + +def _synthesized_definition_numbers() -> dict: + """Delegated to the runner, so the two oracles cannot disagree.""" + return dict(_runner().synthesized_definition_numbers( + _record_rows(), + declared_info=set(_declared_numbers("INFO")), + declared_format=set(_declared_numbers("FORMAT")), + )) + + +def _record_shape() -> dict: + """Allele, value-item, SV and genotype counters, derived the same way.""" + runner = _runner() + return dict(runner.emitted_record_counters( + _record_rows(), + list(SAMPLES), + version=runner.vocab.VCF_VERSIONS[FIXTURE_VERSION], + contig_ids=_declared_ids("CONTIG"), + alt_declaration_ids=_declared_ids("ALT"), + has_assembly_line=any( + key.lower() == "assembly" and value for key, value in HEADER_LINES + ), + info_numbers=_declared_numbers("INFO"), + format_numbers=_declared_numbers("FORMAT"), + )) def _info_shape() -> dict: @@ -486,7 +547,6 @@ def parser_summary( "singleAltRecordCount": single_alt, "q06EligibleSiteCount": q06_eligible, "headerLineCount": len(HEADER_LINES), - "headerValueCount": sum(1 for _key, value in HEADER_LINES if value != ""), **_format_shape(), **_info_shape(), "fileFormat": FILE_FORMAT, @@ -494,6 +554,8 @@ def parser_summary( "sourceSoftware": SOURCE_SOFTWARE, "fileDate": FILE_DATE, **_header_shape(), + **_record_shape(), + **_synthesized_definition_numbers(), "q07_file_metadata": { "fileFormat": FILE_FORMAT, "referenceGenome": REFERENCE_GENOME, diff --git a/test/validation_mutations.py b/test/validation_mutations.py index 21d8285..088737f 100644 --- a/test/validation_mutations.py +++ b/test/validation_mutations.py @@ -16,7 +16,7 @@ from dataclasses import dataclass, field from typing import Callable -VCFR = "https://w3id.org/vcf-rdfizer/vocab#" +VCFC = "https://w3id.org/vcf-core/vocab#" FILE = "file://fixture.vcf" @@ -78,6 +78,11 @@ def swap_objects(text: str, *, subject_a: str, subject_b: str, predicate: str) - new_object=objects[subject_a]) +def drop_line_containing(text: str, needle: str) -> str: + """Remove every line containing ``needle`` (an object IRI, typically).""" + return _join([line for line in _lines(text) if needle not in line]) + + def append_lines(text: str, *new: str) -> str: return _join(_lines(text) + list(new)) @@ -135,7 +140,7 @@ class Mutation: id="drop_pos", description="Remove one record's POS triple.", vcf_element="POS", - apply=lambda t: drop_matching(t, subject=f"{FILE}#record/1", predicate=f"{VCFR}pos"), + apply=lambda t: drop_matching(t, subject=f"{FILE}#record/1", predicate=f"{VCFC}pos"), expected_detected_by="preflight_record_cardinality", ), Mutation( @@ -143,7 +148,7 @@ class Mutation: description="Move a record into a different 1 Mb window.", vcf_element="POS", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}pos", + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}pos", new_object='"9100100"^^'), expected_detected_by="q01_record_density_1mb", ), @@ -153,7 +158,7 @@ class Mutation: vcf_element="record identity", apply=lambda t: swap_objects( t, subject_a=f"{FILE}#record/1", subject_b=f"{FILE}#record/2", - predicate=f"{VCFR}pos"), + predicate=f"{VCFC}pos"), expected_detected_by="q11_record_digest", ), Mutation( @@ -162,9 +167,9 @@ class Mutation: vcf_element="record identity", apply=lambda t: swap_objects( swap_objects(t, subject_a=f"{FILE}#record/1", subject_b=f"{FILE}#record/6", - predicate=f"{VCFR}ref"), + predicate=f"{VCFC}ref"), subject_a=f"{FILE}#record/1", subject_b=f"{FILE}#record/6", - predicate=f"{VCFR}alt"), + predicate=f"{VCFC}alt"), expected_detected_by="q11_record_digest", ), Mutation( @@ -172,7 +177,7 @@ class Mutation: description="Change one record's CHROM.", vcf_element="CHROM", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}chrom", new_object='"X"'), + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}chrom", new_object='"X"'), expected_detected_by="q01_record_density_1mb", ), Mutation( @@ -180,7 +185,7 @@ class Mutation: description="Change one record's ALT so its shape class changes.", vcf_element="ALT", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}alt", new_object='"GGG"'), + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}alt", new_object='"GGG"'), expected_detected_by="q02_variant_shape_counts", ), Mutation( @@ -188,7 +193,7 @@ class Mutation: description="Emit POS as a plain string instead of an integer.", vcf_element="POS datatype", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}pos", new_object='"100"'), + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}pos", new_object='"100"'), expected_detected_by="preflight_position_datatype", ), Mutation( @@ -204,7 +209,7 @@ class Mutation: description="Emit a record as a blank node instead of an IRI.", vcf_element="graph integrity", apply=lambda t: append_lines( - t, f'_:orphan <{VCFR}chrom> "20" .'), + t, f'_:orphan <{VCFC}chrom> "20" .'), expected_detected_by="preflight_blank_nodes", ), Mutation( @@ -212,7 +217,7 @@ class Mutation: description="Point a record at a blank node instead of its call resource.", vcf_element="graph integrity", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}hasCall", + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}hasCall", new_object="_:call1"), expected_detected_by="preflight_blank_nodes", ), @@ -221,7 +226,7 @@ class Mutation: description="Emit an empty literal where a value was expected.", vcf_element="graph integrity", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/1", predicate=f"{VCFR}chrom", new_object='""'), + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}chrom", new_object='""'), expected_detected_by="preflight_empty_values", ), Mutation( @@ -229,7 +234,7 @@ class Mutation: description="Emit a literal containing only whitespace.", vcf_element="graph integrity", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/2", predicate=f"{VCFR}chrom", new_object='" "'), + t, subject=f"{FILE}#record/2", predicate=f"{VCFC}chrom", new_object='" "'), expected_detected_by="preflight_empty_values", ), Mutation( @@ -237,7 +242,7 @@ class Mutation: description="Emit the same statement twice, as a duplicated RDF part would.", vcf_element="graph integrity", apply=lambda t: append_lines( - t, f'<{FILE}#record/1> <{VCFR}chrom> "20" .'), + t, f'<{FILE}#record/1> <{VCFC}chrom> "20" .'), expected_detected_by="preflight_duplicate_triples", ), Mutation( @@ -252,14 +257,14 @@ class Mutation: description="Add a triple using a predicate the vocabulary does not define.", vcf_element="graph completeness", apply=lambda t: append_lines( - t, f'<{FILE}#record/1> <{VCFR}notARealProperty> "x" .'), + t, f'<{FILE}#record/1> <{VCFC}notARealProperty> "x" .'), expected_detected_by="q09_predicate_census (extra row)", ), Mutation( id="drop_filter", description="Remove one FILTER triple.", vcf_element="FILTER", - apply=lambda t: drop_matching(t, subject=f"{FILE}#call/1", predicate=f"{VCFR}filter"), + apply=lambda t: drop_matching(t, subject=f"{FILE}#call/1", predicate=f"{VCFC}filter"), expected_detected_by="q04_filter_distribution", ), Mutation( @@ -267,15 +272,15 @@ class Mutation: description="Change a FILTER value while keeping its broad status class.", vcf_element="FILTER", apply=lambda t: replace_object( - t, subject=f"{FILE}#call/3", predicate=f"{VCFR}filter", new_object='"q20"'), + t, subject=f"{FILE}#call/3", predicate=f"{VCFC}filter", new_object='"q20"'), expected_detected_by="q04_filter_distribution", ), Mutation( id="plain_dot_literal", - description="Emit a missing token as a plain '.' instead of '.'^^vcfr:Null.", + description="Emit a missing token as a plain '.' instead of '.'^^vcfc:Null.", vcf_element="missing-value policy", apply=lambda t: replace_object( - t, subject=f"{FILE}#record/2", predicate=f"{VCFR}recordId", new_object='"."'), + t, subject=f"{FILE}#record/2", predicate=f"{VCFC}recordId", new_object='"."'), expected_detected_by="preflight_missing_token_conformance (--strict-conformance)", ), Mutation( @@ -283,7 +288,7 @@ class Mutation: description="Change one sample's GT value.", vcf_element="FORMAT/GT", apply=lambda t: replace_object( - t, subject=f"{FILE}#sample/1/HG001/fmt/GT", predicate=f"{VCFR}fieldValue", + t, subject=f"{FILE}#sample/1/HG001/fmt/GT", predicate=f"{VCFC}fieldValue", new_object='"1/1"'), expected_detected_by="q05_sample_genotype_counts", representations=("expanded",), @@ -309,7 +314,7 @@ class Mutation: description="Change a DP value.", vcf_element="FORMAT/DP", apply=lambda t: replace_object( - t, subject=f"{FILE}#sample/1/HG001/fmt/DP", predicate=f"{VCFR}fieldValue", + t, subject=f"{FILE}#sample/1/HG001/fmt/DP", predicate=f"{VCFC}fieldValue", new_object='"999"'), expected_detected_by="q13_format_value_digest", representations=("expanded",), @@ -318,14 +323,14 @@ class Mutation: id="drop_qual", description="Remove a QUAL triple.", vcf_element="QUAL", - apply=lambda t: drop_matching(t, subject=f"{FILE}#call/1", predicate=f"{VCFR}qual"), + apply=lambda t: drop_matching(t, subject=f"{FILE}#call/1", predicate=f"{VCFC}qual"), expected_detected_by="q09_predicate_census", ), Mutation( id="drop_all_qual", description="Emit no QUAL at all, as the mapping did before it was fixed.", vcf_element="QUAL", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}qual", limit=None), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}qual", limit=None), expected_detected_by="q09_predicate_census", ), Mutation( @@ -333,14 +338,14 @@ class Mutation: description="Change a QUAL value.", vcf_element="QUAL", apply=lambda t: replace_object( - t, subject=f"{FILE}#call/1", predicate=f"{VCFR}qual", new_object='"0"'), + t, subject=f"{FILE}#call/1", predicate=f"{VCFC}qual", new_object='"0"'), expected_detected_by="q11_record_digest", ), Mutation( id="drop_info_value", description="Remove a structured INFO value node.", vcf_element="INFO", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}hasInfoValue"), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}hasInfoValue"), expected_detected_by="q09_predicate_census", ), Mutation( @@ -348,7 +353,7 @@ class Mutation: description="Change a structured INFO value.", vcf_element="INFO", apply=lambda t: replace_object( - t, subject=f"{FILE}#call/1/info/AC", predicate=f"{VCFR}fieldValue", + t, subject=f"{FILE}#call/1/info/AC", predicate=f"{VCFC}fieldValue", new_object='"99"'), expected_detected_by="q12_info_value_digest", ), @@ -357,14 +362,14 @@ class Mutation: description="Remove an INFO field declaration resource.", vcf_element="INFO declaration", apply=lambda t: drop_matching( - t, subject=f"{FILE}#header/line/6", predicate=f"{VCFR}fieldType"), + t, subject=f"{FILE}#header/line/6", predicate=f"{VCFC}fieldType"), expected_detected_by="q09_predicate_census", ), Mutation( id="retype_info_value", description="Drop the typed integer form of an INFO value.", vcf_element="INFO typing", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}fieldValueInteger"), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}fieldValueInteger"), expected_detected_by="q09_predicate_census", ), Mutation( @@ -372,7 +377,7 @@ class Mutation: description="Change a record's raw INFO string.", vcf_element="INFO", apply=lambda t: replace_object( - t, subject=f"{FILE}#call/1", predicate=f"{VCFR}infoRaw", new_object='"AC=99"'), + t, subject=f"{FILE}#call/1", predicate=f"{VCFC}infoRaw", new_object='"AC=99"'), expected_detected_by="q11_record_digest", ), Mutation( @@ -380,7 +385,7 @@ class Mutation: description="Change one sample's value inside a condensed FORMAT vector.", vcf_element="FORMAT/DP", apply=lambda t: replace_object( - t, subject=f"{FILE}#call/1/matrix/fmt/DP", predicate=f"{VCFR}encodedValues", + t, subject=f"{FILE}#call/1/matrix/fmt/DP", predicate=f"{VCFC}encodedValues", new_object='"999\t28"'), expected_detected_by="q13_format_value_digest", representations=("condensed",), @@ -405,28 +410,28 @@ class Mutation: id="drop_contig_attribute", description="Remove a contig's declared length.", vcf_element="contig declaration", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}contigLength"), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}contigLength"), expected_detected_by="q09_predicate_census", ), Mutation( id="drop_filter_definition", description="Remove a FILTER declaration's id.", vcf_element="FILTER declaration", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}filterId"), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}filterId"), expected_detected_by="q09_predicate_census", ), Mutation( id="drop_alt_definition", description="Remove a symbolic ALT declaration's id.", vcf_element="ALT declaration", - apply=lambda t: drop_matching(t, predicate=f"{VCFR}altId"), + apply=lambda t: drop_matching(t, predicate=f"{VCFC}altId"), expected_detected_by="q09_predicate_census", ), Mutation( id="drop_file_date", description="Remove the declared file date.", vcf_element="file metadata", - apply=lambda t: drop_matching(t, subject=FILE, predicate=f"{VCFR}fileDate"), + apply=lambda t: drop_matching(t, subject=FILE, predicate=f"{VCFC}fileDate"), expected_detected_by="q09_predicate_census", ), Mutation( @@ -434,7 +439,7 @@ class Mutation: description="Declare the wrong number of contigs.", vcf_element="contig declaration", apply=lambda t: replace_object( - t, subject=FILE, predicate=f"{VCFR}contigCount", + t, subject=FILE, predicate=f"{VCFC}contigCount", new_object='"99"^^'), expected_detected_by="header census", known_undetected=( @@ -447,23 +452,255 @@ class Mutation: description="Change the declared fileformat.", vcf_element="file metadata", apply=lambda t: replace_object( - t, subject=FILE, predicate=f"{VCFR}fileFormat", new_object='"VCFv9.9"'), + t, subject=FILE, predicate=f"{VCFC}fileFormat", new_object='"VCFv9.9"'), expected_detected_by="q07_file_metadata (Phase 1c)", ), Mutation( id="drop_reference_genome", description="Remove the declared reference genome.", vcf_element="file metadata", - apply=lambda t: drop_matching(t, subject=FILE, predicate=f"{VCFR}referenceGenome"), + apply=lambda t: drop_matching(t, subject=FILE, predicate=f"{VCFC}referenceGenome"), expected_detected_by="q07_file_metadata (Phase 1c)", ), + # ------------------------------------------------------------------ + # The layers the VCF Core vocabulary added. Each names one way the new + # emitters could regress; whether the suite catches it is measured, not + # asserted, so a `known_undetected` entry here is a recorded gap. + # ------------------------------------------------------------------ + Mutation( + id="drop_version_class", + description="Remove the vcfc:VCF4xFile class the version sentinel resolves to.", + vcf_element="VCF version", + apply=lambda t: drop_line_containing(t, f"<{VCFC}VCF42File>"), + expected_detected_by="q10_class_census", + ), + Mutation( + id="wrong_version_class", + description="Type the file with a VCF version it does not declare.", + vcf_element="VCF version", + apply=lambda t: t.replace(f"<{VCFC}VCF42File>", f"<{VCFC}VCF45File>"), + expected_detected_by="q10_class_census", + ), + Mutation( + id="drop_line_index", + description="Remove one header line's ordering index.", + vcf_element="header ordering", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#header/line/1", predicate=f"{VCFC}lineIndex"), + expected_detected_by="q09_predicate_census", + ), + Mutation( + id="corrupt_record_index", + description="Renumber one record, breaking the file's record order.", + vcf_element="record ordering", + apply=lambda t: replace_object( + t, subject=f"{FILE}#record/2", predicate=f"{VCFC}recordIndex", + new_object='"99"^^'), + expected_detected_by="nothing yet", + known_undetected=( + "recordIndex is counted by q09 but its values are not compared. " + "The SPARQL SHACL profile checks uniqueness and ordering; the " + "aggregate queries do not." + ), + ), + Mutation( + id="drop_header_attribute", + description="Remove one vcfc:HeaderAttribute from a structured header line.", + vcf_element="header attributes", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#header/line/6/attribute/1", limit=None), + expected_detected_by="q09_predicate_census, q10_class_census", + ), + Mutation( + id="corrupt_attribute_value", + description="Change one header attribute's value.", + vcf_element="header attributes", + apply=lambda t: replace_object( + t, subject=f"{FILE}#header/line/6/attribute/1", + predicate=f"{VCFC}attributeValue", new_object='"WRONG"'), + expected_detected_by="nothing yet", + known_undetected=( + "Attribute values are counted but not compared. Closing this needs " + "a digest over the structured header attributes, the way q11 covers " + "record fields." + ), + ), + Mutation( + id="drop_alt_allele", + description="Remove one ALT allele resource from a multi-allelic record.", + vcf_element="allele layer", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#record/4/allele/2", limit=None), + expected_detected_by="q09_predicate_census, q10_class_census", + ), + Mutation( + id="corrupt_allele_value", + description="Change one parsed ALT allele's lexical value.", + vcf_element="allele layer", + apply=lambda t: replace_object( + t, subject=f"{FILE}#record/1/allele/1", predicate=f"{VCFC}alleleValue", + new_object='"TTT"'), + expected_detected_by="nothing yet", + known_undetected=( + "Allele values are counted but not compared against the raw ALT " + "column. A digest joining vcfc:alleleValue to vcfc:alt would close " + "it; the vocabulary's own consistency SHACL profile already checks " + "this agreement." + ), + ), + Mutation( + id="corrupt_allele_kind", + description="Misclassify an SNV allele as a symbolic one.", + vcf_element="allele layer", + apply=lambda t: replace_object( + t, subject=f"{FILE}#record/1/allele/1", predicate=f"{VCFC}alleleKind", + new_object=f"<{VCFC}SymbolicAllele>"), + expected_detected_by="nothing yet", + known_undetected=( + "alleleKind is counted but its value is not compared. q02 already " + "classifies variant shape from REF/ALT, so cross-checking the two " + "would close this without a new oracle." + ), + ), + Mutation( + id="drop_contig_link", + description="Unlink one record from the contig its CHROM names.", + vcf_element="allele layer", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#record/1", predicate=f"{VCFC}chromosome"), + expected_detected_by="q09_predicate_census", + ), + Mutation( + id="drop_value_item", + description="Remove one parsed item of a Number=A INFO value.", + vcf_element="indexed values", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#call/4/info/AC/value/1", limit=None), + expected_detected_by="q09_predicate_census, q10_class_census", + ), + Mutation( + id="corrupt_value_item_allele", + description="Point a Number=A value item at the wrong ALT allele.", + vcf_element="indexed values", + apply=lambda t: replace_object( + t, subject=f"{FILE}#call/4/info/AC/value/0", predicate=f"{VCFC}forAllele", + new_object=f"<{FILE}#record/4/allele/2>"), + expected_detected_by="nothing yet", + known_undetected=( + "forAllele is counted but the join is not checked. The vocabulary's " + "consistency profile checks item/raw agreement; an equivalent " + "aggregate here would need a per-item digest." + ), + ), + Mutation( + id="drop_sample_set", + description="Remove the file's reusable sample set.", + vcf_element="sample identity", + apply=lambda t: drop_matching(t, subject=f"{FILE}#samples", limit=None), + expected_detected_by="q09_predicate_census, q10_class_census", + ), + # The same corruption is detected in one profile and not the other, which + # is worth recording rather than smoothing over: in the condensed profile + # the ordinal is what associates a vector position with a sample, so + # breaking it moves genotypes between samples and the aggregates shift. In + # the expanded profile each SampleCall carries its own vcfc:sampleId, so the + # set ordinal is decorative and nothing downstream reads it. + Mutation( + id="corrupt_sample_index", + description="Give two samples the same ordinal in the sample set.", + vcf_element="sample identity", + apply=lambda t: replace_object( + t, subject=f"{FILE}#samples/HG002", predicate=f"{VCFC}sampleIndex", + new_object='"1"^^'), + expected_detected_by="q05_sample_genotype_counts, q06_ac_an_distribution", + representations=("condensed",), + ), + Mutation( + id="corrupt_sample_index_expanded", + description="The same ordinal corruption, where nothing decodes by position.", + vcf_element="sample identity", + apply=lambda t: replace_object( + t, subject=f"{FILE}#samples/HG002", predicate=f"{VCFC}sampleIndex", + new_object='"1"^^'), + expected_detected_by="nothing yet", + known_undetected=( + "In the expanded profile the sample set is a convenience: each " + "SampleCall carries vcfc:sampleId and vcfc:forSample, so no query " + "reads the ordinal. The SPARQL SHACL profile rejects duplicate " + "sampleIndex values within a file, so the shape layer covers it." + ), + representations=("expanded",), + ), + Mutation( + id="drop_genotype", + description="Remove one parsed genotype resource.", + vcf_element="genotype layer", + apply=lambda t: drop_matching( + t, subject=f"{FILE}#sample/1/HG001/genotype", limit=None), + expected_detected_by="q09_predicate_census, q10_class_census", + representations=("expanded",), + ), + Mutation( + id="flip_phasing_status", + description="Report a phased genotype as unphased.", + vcf_element="genotype layer", + apply=lambda t: replace_object( + t, subject=f"{FILE}#sample/1/HG001/genotype", + predicate=f"{VCFC}phasingStatus", new_object=f"<{VCFC}Unphased>"), + expected_detected_by="nothing yet", + known_undetected=( + "Phasing is counted but not compared. q05 classifies genotypes from " + "the raw GT string and normalizes '|' to '/', so it cannot see the " + "difference; cross-checking vcfc:phasingStatus against the raw " + "genotypeString would close it." + ), + representations=("expanded",), + ), + Mutation( + id="corrupt_called_allele", + description="Point a genotype allele call at the wrong allele.", + vcf_element="genotype layer", + apply=lambda t: replace_object( + t, subject=f"{FILE}#sample/1/HG001/genotype/call/0", + predicate=f"{VCFC}calledAllele", + new_object=f"<{FILE}#record/1/allele/1>"), + expected_detected_by="nothing yet", + known_undetected=( + "calledAllele is counted but the join is not checked. q05 reads the " + "raw GT, so a parsed call pointing at the wrong allele is invisible " + "to it." + ), + representations=("expanded",), + ), + Mutation( + id="duplicate_field_definition", + description="Emit a declared field definition's ID twice.", + vcf_element="field declarations", + apply=lambda t: append_lines( + t, f'<{FILE}#header/line/6> <{VCFC}fieldId> "AC" .'), + expected_detected_by="preflight_duplicate_triples", + ), + Mutation( + id="wrong_declaration_owner", + description="Move a declared definition's ID onto the wrong header line.", + vcf_element="field declarations", + apply=lambda t: replace_object( + t, subject=f"{FILE}#header/line/6", predicate=f"{VCFC}fieldId", + new_object='"DB"'), + expected_detected_by="nothing yet", + known_undetected=( + "Field IDs are counted but not tied to their header line. q08 " + "counts lines per '##' key and q09 counts fieldId triples, so " + "swapping which line carries which ID changes neither." + ), + ), Mutation( id="wrong_representation_profile", description="Declare the wrong sample representation profile.", vcf_element="representation profile", apply=lambda t: replace_object( - t, subject=FILE, predicate=f"{VCFR}representationProfile", - new_object=f"<{VCFR}ExpandedRepresentation>"), + t, subject=FILE, predicate=f"{VCFC}representationProfile", + new_object=f"<{VCFC}ExpandedRepresentation>"), expected_detected_by="preflight_representation_profile", representations=("condensed",), ), diff --git a/vcf_rdfizer.py b/vcf_rdfizer.py index 3a15403..835f3db 100644 --- a/vcf_rdfizer.py +++ b/vcf_rdfizer.py @@ -68,13 +68,22 @@ from dataclasses import dataclass from datetime import datetime from pathlib import Path -from urllib.parse import quote_plus try: import vcf_rdfizer_gzip except ImportError: # pragma: no cover - shipped alongside this module vcf_rdfizer_gzip = None +import vcf_rdfizer_vocab as vocab +from vcf_rdfizer_vocab import ( + CONTIG_ATTRIBUTES, + HEADER_LINE_CLASSES, + VCFC_NAMESPACE, + VCF_VALUE_TYPE_INDIVIDUALS, + file_date_object, + parse_info_entries, +) + try: from rich.console import Console from rich.progress import ( @@ -119,6 +128,12 @@ "timestamp", "output_name", "output_dir", + # The VCF specification version this input was converted under, and how it + # was chosen. Benchmarks group by these: the version selects the SHACL + # overlay, the tuple semantics and which FORMAT families exist, so a run's + # cost and graph size are not comparable across versions without them. + "vcf_version", + "vcf_version_source", "exit_code_java", "wall_seconds_java", "user_seconds_java", @@ -303,28 +318,31 @@ ) CANONICAL_SAMPLE_RULE_FRAGMENTS = ( 'rr:template "file://{SOURCE_FILE}#call/{ROW_ID}"', - "rr:predicate vcfr:hasSampleCall", + "rr:predicate vcfc:hasSampleCall", 'rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}"', - "rr:class vcfr:SampleCall", - "rr:predicate vcfr:sampleId", + "rr:class vcfc:SampleCall", + "rr:predicate vcfc:sampleId", 'rml:reference "SAMPLE_ID"', - "rr:predicate vcfr:hasFormatValue", + "rr:predicate vcfc:hasFormatValue", 'rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}/fmt/{FORMAT_KEY}"', - "rr:class vcfr:FormatFieldValue", - "rr:predicate vcfr:fieldValue", + "rr:class vcfc:FormatFieldValue", + "rr:predicate vcfc:fieldValue", 'rml:reference "FORMAT_VALUE"', ) -VCFR_NAMESPACE = "https://w3id.org/vcf-rdfizer/vocab#" -RDF_TYPE_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" -XSD_POSITIVE_INTEGER_URI = "http://www.w3.org/2001/XMLSchema#positiveInteger" +RDF_TYPE_URI = vocab.RDF_TYPE_URI +#: Ordinals are serialized as xsd:integer, not xsd:positiveInteger: the SHACL +#: profiles constrain every one of them with sh:datatype xsd:integer, and that +#: constraint compares the datatype IRI exactly. See vcf_rdfizer_vocab. +XSD_ORDINAL_URI = vocab.XSD_ORDINAL_URI SAMPLE_RDF_BUFFER_BYTES = 8 * 1024 * 1024 # An N-Triples subject is always an IRI reference or a blank node label, so a # line starting with one of these bytes and ending in " ." is a statement. _NTRIPLES_SUBJECT_STARTS = (b"<", b"_") SAMPLE_REPRESENTATION_CHOICES = {"expanded", "condensed"} # How the INFO column is represented. "raw" is the historical behaviour (an -# opaque vcfr:infoRaw string). "structured" additionally emits one -# vcfr:InfoFieldValue per record and key, which is what makes INFO queryable. +# opaque vcfc:infoRaw string). "structured" additionally emits one +# vcfc:InfoFieldValue per record and key, plus the allele layer and the +# vcfc:FieldValueItem decomposition, which is what makes INFO queryable. INFO_REPRESENTATION_CHOICES = ("raw", "structured") DEFAULT_INFO_REPRESENTATION = "structured" # Semantic validation accepts any artifact the pipeline can produce. Anything @@ -377,7 +395,7 @@ def parse_validation_engines(raw: str) -> list[str]: # This is an internal rules-compatibility value, not a third public # representation. It means that custom helper TSV rows must be materialized. SAMPLE_HELPER_STRATEGY_MATERIALIZED = "expanded" -METRICS_LAYOUT_VERSION = 2 +METRICS_LAYOUT_VERSION = 3 # --------------------------------------------------------------------------- @@ -1873,45 +1891,19 @@ def _sample_id_to_uri_id(sample_id: str, fallback_index: int) -> str: return candidate or f"sample_{fallback_index}" -# Characters that ``quote_plus(..., safe="*-._")`` leaves untouched. Sample -# ids, FORMAT keys, and numeric row ids are almost always drawn from this set, -# so the fast path below skips percent-encoding entirely for them. -_URI_COMPONENT_PASSTHROUGH_RE = re.compile(r"[A-Za-z0-9*\-._]*\Z") -# Characters that require N-Triples escaping. VCF genotype/FORMAT payloads -# essentially never contain them, so the common case avoids five str.replace -# scans of the value. -_NTRIPLES_ESCAPE_RE = re.compile(r'[\\"\n\r\t]') - - -def _rml_uri_component(value: str) -> str: - """Match RMLStreamer's Java URLEncoder-based template substitution.""" - if _URI_COMPONENT_PASSTHROUGH_RE.match(value) is not None: - return value - encoded = quote_plus(value, safe="*-._", encoding="utf-8", errors="strict") - # urllib follows current RFC rules and always leaves '~' unescaped, whereas - # java.net.URLEncoder (used by RMLStreamer 2.5.0) encodes it. - return encoded.replace("+", "%20").replace("~", "%7E") - - -def _ntriples_string_literal(value: str) -> str: - """Serialize an RDF 1.1 plain/xsd:string literal for N-Triples.""" - if _NTRIPLES_ESCAPE_RE.search(value) is None: - return f'"{value}"' - escaped = ( - value.replace("\\", "\\\\") - .replace('"', '\\"') - .replace("\n", "\\n") - .replace("\r", "\\r") - .replace("\t", "\\t") - ) - return f'"{escaped}"' +# The serialization helpers live in vcf_rdfizer_vocab so the parsers there can +# use them; these names stay because the emitters below and the unit tests +# reference them. +_rml_uri_component = vocab.rml_uri_component +_ntriples_string_literal = vocab.ntriples_string_literal +_ntriples_literal = vocab.ntriples_literal +_ntriples_typed_literal = vocab.ntriples_typed_literal +_ordinal_literal = vocab.ordinal_literal -def _ntriples_literal(value: str) -> str: - literal = _ntriples_string_literal(value) - if value == ".": - literal += f"^^<{VCFR_NAMESPACE}Null>" - return literal +def _vocab(local_name: str) -> str: + """Absolute IRI of one VCF Core term.""" + return f"{VCFC_NAMESPACE}{local_name}" @dataclass(frozen=True) @@ -1929,12 +1921,20 @@ class ParsedSampleRecord: source_file: str row_id: str - #: Raw QUAL and INFO columns, needed by the record-detail emitter. + #: Raw fixed-field columns the record-detail emitter needs: the three whose + #: datatype depends on the row (ID, QUAL, FILTER), the INFO payload, and + #: CHROM/REF/ALT, which the allele layer decomposes. qual: str info: str format_keys: tuple[str, ...] sample_payloads: tuple[str, ...] sample_values: tuple[tuple[str, ...], ...] + chrom: str = "" + pos: str = "" + record_id: str = "" + ref: str = "" + alt: str = "" + filter_value: str = "" class SampleRecordStream: @@ -2020,7 +2020,13 @@ def _parse_row(self, row: list[str]) -> ParsedSampleRecord: f"'{source_file}'" ) row_id = row[1] if len(row) > 1 else "" + chrom_raw = row[2] if len(row) > 2 else "" + pos_raw = row[3] if len(row) > 3 else "" + record_id_raw = row[4] if len(row) > 4 else "" + ref_raw = row[5] if len(row) > 5 else "" + alt_raw = row[6] if len(row) > 6 else "" qual_raw = row[7] if len(row) > 7 else "" + filter_raw = row[8] if len(row) > 8 else "" info_raw = row[9] if len(row) > 9 else "" format_raw = row[10] if len(row) > 10 else "" samples_raw = row[-1] if len(row) >= 12 else "" @@ -2068,6 +2074,12 @@ def _parse_row(self, row: list[str]) -> ParsedSampleRecord: format_keys=format_keys, sample_payloads=tuple(sample_payloads), sample_values=sample_values, + chrom=chrom_raw, + pos=pos_raw, + record_id=record_id_raw, + ref=ref_raw, + alt=alt_raw, + filter_value=filter_raw, ) @@ -2111,22 +2123,272 @@ def emit(line: str): raise +def _emit_sample_set(emit, *, file_uri: str, columns, stats: dict) -> str: + """Emit the file's ordered sample columns once, and return the set IRI. + + ``vcfc:SampleSet`` and ``vcfc:VCFSample`` are file-scoped, not profile- + scoped: the condensed profile needs the set to interpret its vectors, and + the expanded profile uses it to give each ``vcfc:SampleCall`` a reusable + identity through ``vcfc:forSample`` instead of relying on repeated + ``vcfc:sampleId`` literals. Emitting it in both profiles does not mix them, + because what the SPARQL profile forbids mixing is per-sample calls and + cohort matrices, not the sample set itself. + + The ``#CHROM`` column header line also gains ``vcfc:hasGenotypeColumns`` + here, because the sample columns live in the records TSV header rather than + in any row of the header-lines table. + """ + if not columns: + # A sites-only VCF declares no sample columns. vcfc:SampleSetShape + # requires at least one vcfc:hasSample, so an empty set would be worse + # than no set at all; vcfc:hasSampleSet is optional on the file. + return "" + sample_set_uri = f"{file_uri}#samples" + column_header_uri = f"{file_uri}#header/columns" + emit(f"<{file_uri}> <{_vocab('hasSampleSet')}> <{sample_set_uri}> .\n") + emit(f"<{sample_set_uri}> <{RDF_TYPE_URI}> <{_vocab('SampleSet')}> .\n") + for column in columns: + sample_uri = f"{sample_set_uri}/{_rml_uri_component(column.uri_id)}" + emit(f"<{sample_set_uri}> <{_vocab('hasSample')}> <{sample_uri}> .\n") + emit(f"<{sample_uri}> <{RDF_TYPE_URI}> <{_vocab('VCFSample')}> .\n") + emit( + f"<{sample_uri}> <{_vocab('sampleName')}> " + f"{_ntriples_string_literal(column.sample_id)} .\n" + ) + emit( + f"<{sample_uri}> <{_vocab('sampleIndex')}> " + f"{_ordinal_literal(column.index)} .\n" + ) + emit( + f"<{column_header_uri}> <{_vocab('hasGenotypeColumns')}> " + f"<{sample_uri}> .\n" + ) + stats["samples"] += 1 + return sample_set_uri + + +def _emit_format_field_definition( + emit, + *, + definition: "FormatDefinition", + field_id: str, + emitted: set, + stats: dict | None = None, +) -> str: + """Emit one ``vcfc:FormatFieldDefinition`` the first time its key is seen.""" + if definition.uri in emitted: + return definition.uri + emitted.add(definition.uri) + emit( + f"<{definition.uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('FormatFieldDefinition')}> .\n" + ) + # A key declared by a '##FORMAT' line already has its ID/Number/Type/ + # Description from the header emitter, at this very IRI; emitting them + # again would duplicate every one of those triples. + if definition.synthesized: + _emit_field_definition_attributes( + emit, + definition.uri, + field_id=field_id, + number=definition.field_number, + # A FORMAT field may not be a Flag, so an undeclared key defaults + # to String rather than inheriting the INFO fallback. + value_type=definition.value_type or "String", + description=definition.description, + ) + if stats is not None: + stats["format_definitions"] += 1 + return definition.uri + + +def _synthesized_format_definition(file_uri: str, format_key: str, component: str) -> "FormatDefinition": + """Build a definition for a FORMAT key the header never declared.""" + return FormatDefinition( + uri=f"{file_uri}#header/format/{component}", + field_number=".", + description=f"Synthesized definition for undeclared FORMAT key {format_key}", + value_type="String", + synthesized=True, + ) + + +def _emit_genotype( + emit, + *, + sample_uri: str, + record_uri: str, + value: str, + alt_count: int, + stats: dict, +) -> None: + """Emit the parsed GT of one sample call. + + A GT that is absent or outside the vcfc:GenotypeString lexical space + produces no Genotype resource: the value is still present as the FORMAT + field's ``vcfc:fieldValue``, and inventing a Genotype for it would create a + resource that fails ``vcfc:GenotypeShape``. + """ + parsed = vocab.parse_genotype(value) + if parsed is None: + return + genotype_uri = f"{sample_uri}/genotype" + emit(f"<{sample_uri}> <{_vocab('hasGenotype')}> <{genotype_uri}> .\n") + emit(f"<{genotype_uri}> <{RDF_TYPE_URI}> <{_vocab('Genotype')}> .\n") + emit( + f"<{genotype_uri}> <{_vocab('genotypeString')}> " + f"{_ntriples_typed_literal(parsed.genotype_string, vocab.GENOTYPE_STRING_DATATYPE_URI)} .\n" + ) + emit( + f"<{genotype_uri}> <{_vocab('ploidy')}> " + f"{_ordinal_literal(parsed.ploidy)} .\n" + ) + emit( + f"<{genotype_uri}> <{_vocab('phasingStatus')}> " + f"<{_vocab('Phased' if parsed.is_phased else 'Unphased')}> .\n" + ) + for call in parsed.calls: + call_uri = f"{genotype_uri}/call/{call.call_index}" + emit(f"<{genotype_uri}> <{_vocab('hasAlleleCall')}> <{call_uri}> .\n") + emit( + f"<{call_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('GenotypeAlleleCall')}> .\n" + ) + emit( + f"<{call_uri}> <{_vocab('callIndex')}> " + f"{_ordinal_literal(call.call_index)} .\n" + ) + emit( + f"<{call_uri}> <{_vocab('isNoCall')}> " + f'"{"true" if call.is_no_call else "false"}"^^<{XSD_BOOLEAN_URI}> .\n' + ) + if call.allele_index is not None and call.allele_index <= alt_count: + emit( + f"<{call_uri}> <{_vocab('calledAllele')}> " + f"<{record_uri}/allele/{call.allele_index}> .\n" + ) + stats["genotype_calls"] += 1 + stats["genotypes"] += 1 + + +def _emit_phase_set(emit, *, sample_uri: str, phase_fields: dict, stats: dict) -> None: + """Emit the PS/PSL/PSO/PSQ phase-set carrier of one sample call.""" + identifier = phase_fields.get("PS") + name = phase_fields.get("PSL") + if vocab.is_missing(identifier) and vocab.is_missing(name): + return + phase_set_uri = f"{sample_uri}/phaseset" + genotype_uri = f"{sample_uri}/genotype" + emit(f"<{genotype_uri}> <{_vocab('inPhaseSet')}> <{phase_set_uri}> .\n") + emit(f"<{phase_set_uri}> <{RDF_TYPE_URI}> <{_vocab('PhaseSet')}> .\n") + if not vocab.is_missing(identifier): + emit( + f"<{phase_set_uri}> <{_vocab('phaseSetId')}> " + f"{_ntriples_string_literal(identifier)} .\n" + ) + if not vocab.is_missing(name): + emit( + f"<{phase_set_uri}> <{_vocab('phaseSetName')}> " + f"{_ntriples_string_literal(name)} .\n" + ) + ordinal = phase_fields.get("PSO") + if not vocab.is_missing(ordinal) and ordinal.lstrip("-").isdigit(): + emit( + f"<{phase_set_uri}> <{_vocab('phaseSetOrdinal')}> " + f"{_ntriples_typed_literal(ordinal, XSD_INTEGER_URI)} .\n" + ) + quality = phase_fields.get("PSQ") + if not vocab.is_missing(quality): + emit( + f"<{phase_set_uri}> <{_vocab('phaseSetQuality')}> " + f"{_ntriples_literal(quality)} .\n" + ) + stats["phase_sets"] += 1 + + +def _emit_local_allele_set( + emit, *, sample_uri: str, record_uri: str, value: str, alt_count: int, stats: dict +) -> None: + """Emit the LAA local-allele subset declared for one sample.""" + indices = [index for index in vocab.parse_local_allele_indices(value) if index <= alt_count] + if not indices: + return + set_uri = f"{sample_uri}/localalleles" + genotype_uri = f"{sample_uri}/genotype" + emit(f"<{genotype_uri}> <{_vocab('hasLocalAlleleSet')}> <{set_uri}> .\n") + emit(f"<{set_uri}> <{RDF_TYPE_URI}> <{_vocab('LocalAlleleSet')}> .\n") + for local_index, allele_index in enumerate(indices, start=1): + allele_uri = f"{record_uri}/allele/{allele_index}" + emit(f"<{set_uri}> <{_vocab('hasLocalAllele')}> <{allele_uri}> .\n") + emit( + f"<{allele_uri}> <{_vocab('localAlleleIndex')}> " + f"{_ordinal_literal(local_index)} .\n" + ) + stats["local_allele_sets"] += 1 + + +def _emit_base_modification( + emit, *, sample_uri: str, modification, value: str, stats: dict +) -> None: + """Emit the vcfc:BaseModification carrier for one M/DPM/ADM FORMAT key.""" + if vocab.is_missing(value): + return + modification_uri = f"{sample_uri}/basemod/{_rml_uri_component(modification.key)}" + emit( + f"<{modification_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('BaseModification')}> .\n" + ) + emit( + f"<{modification_uri}> <{_vocab('modifiedResidue')}> " + f"<{modification.residue_uri}> .\n" + ) + # VCF 4.5 gives the base-modification FORMAT families a per-base offset; + # without an explicit one, position 0 is the modified base named by the key. + emit( + f"<{modification_uri}> <{_vocab('modifiedBaseOffset')}> " + f"{_ordinal_literal(0)} .\n" + ) + emit( + f"<{modification_uri}> <{_vocab(modification.value_property)}> " + f"{_ntriples_literal(value)} .\n" + ) + stats["base_modifications"] += 1 + + def append_expanded_sample_rdf( records_tsv: Path, rdf_path: Path, + header_lines_tsv: Path | None = None, *, + version: "vocab.VCFVersion | None" = None, progress_interval_records: int = 10_000, ) -> dict: - """Append the expanded SampleCall/FormatFieldValue representation. - - This produces the same canonical SampleCall and FormatFieldValue triples as - the default RML maps without materializing V*S and V*S*F helper TSV rows. + """Append the expanded per-sample representation. + + Produces the canonical SampleCall and FormatFieldValue resources without + materializing the V*S and V*S*F helper TSV rows, and adds the genotype layer + the vocabulary defines for this profile: the parsed GT of each sample as a + ``vcfc:Genotype`` with one ``vcfc:GenotypeAlleleCall`` per position, the + FT sample filter, the PS/PSL phase set, the LAA local-allele subset, the + copy-number and haplotype fields, and the M/DPM/ADM base modifications. + + The genotype layer is expanded-only by design. Decomposing GT per sample is + exactly the per-sample materialization the condensed profile exists to + avoid, so the condensed emitter keeps those values inside their vectors. """ stats = { "representation": "expanded", "records": 0, + "samples": 0, "sample_calls": 0, "format_values": 0, + "format_definitions": 0, + "genotypes": 0, + "genotype_calls": 0, + "phase_sets": 0, + "local_allele_sets": 0, + "base_modifications": 0, + "value_items": 0, "triples": 0, "appended_bytes": 0, } @@ -2135,17 +2397,32 @@ def append_expanded_sample_rdf( if not rdf_path.is_file(): raise FileNotFoundError(f"RDF aggregate not found for sample streaming: {rdf_path}") + version = version or vocab.FALLBACK_VERSION + definitions = ( + _load_format_definitions(header_lines_tsv) + if header_lines_tsv is not None + else {} + ) + with SampleRecordStream(records_tsv) as record_stream: - if not record_stream.columns or not record_stream.source_file: + if not record_stream.source_file: return stats def produce(emit): source_component = _rml_uri_component(record_stream.source_file) file_uri = f"file://{source_component}" + # The profile is declared even for a sites-only VCF. + # vcfc:RepresentationProfileShape requires exactly one on every + # vcfc:VCFFile, and a file with no genotype columns has no genotype + # data to condense, so the expanded profile is the honest claim. emit( - f"<{file_uri}> <{VCFR_NAMESPACE}representationProfile> " - f"<{VCFR_NAMESPACE}ExpandedRepresentation> .\n" + f"<{file_uri}> <{_vocab('representationProfile')}> " + f"<{_vocab('ExpandedRepresentation')}> .\n" ) + _emit_sample_set( + emit, file_uri=file_uri, columns=record_stream.columns, stats=stats + ) + # Sample columns and their serialized sampleId literal are fixed for # the whole file; FORMAT keys are drawn from a handful of distinct # values. Encoding them once per file instead of once per @@ -2158,14 +2435,24 @@ def produce(emit): for column in record_stream.columns ] format_components: dict[str, str] = {} + emitted_definitions: set[str] = set() + # Base-modification FORMAT keys are pattern-defined, so each distinct + # key is classified once rather than per sample and record. + base_modifications: dict[str, object] = {} sample_call_count = 0 format_value_count = 0 for record in record_stream: row_component = _rml_uri_component(record.row_id) call_uri = f"{file_uri}#call/{row_component}" + record_uri = f"{file_uri}#record/{row_component}" format_keys = record.format_keys record_sample_values = record.sample_values + alt_count = ( + 0 + if vocab.is_missing(record.alt) + else len(record.alt.split(",")) + ) for sample_index, (sample_component, sample_id_literal) in enumerate( sample_prefixes @@ -2173,14 +2460,19 @@ def produce(emit): sample_uri = f"{file_uri}#sample/{row_component}/{sample_component}" sample_values = record_sample_values[sample_index] - emit(f"<{call_uri}> <{VCFR_NAMESPACE}hasSampleCall> <{sample_uri}> .\n") - emit(f"<{sample_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}SampleCall> .\n") + emit(f"<{call_uri}> <{_vocab('hasSampleCall')}> <{sample_uri}> .\n") + emit(f"<{sample_uri}> <{RDF_TYPE_URI}> <{_vocab('SampleCall')}> .\n") emit( - f"<{sample_uri}> <{VCFR_NAMESPACE}sampleId> " + f"<{sample_uri}> <{_vocab('sampleId')}> " f"{sample_id_literal} .\n" ) + emit( + f"<{sample_uri}> <{_vocab('forSample')}> " + f"<{file_uri}#samples/{sample_component}> .\n" + ) sample_call_count += 1 + phase_fields: dict[str, str] = {} for format_index, format_key in enumerate(format_keys): format_value = sample_values[format_index] format_component = format_components.get(format_key) @@ -2188,15 +2480,114 @@ def produce(emit): format_component = _rml_uri_component(format_key) format_components[format_key] = format_component format_uri = f"{sample_uri}/fmt/{format_component}" - emit(f"<{sample_uri}> <{VCFR_NAMESPACE}hasFormatValue> <{format_uri}> .\n") - emit(f"<{format_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}FormatFieldValue> .\n") + + definition = definitions.get(format_key) + if definition is None: + definition = _synthesized_format_definition( + file_uri, format_key, format_component + ) + definitions[format_key] = definition + _emit_format_field_definition( + emit, + definition=definition, + field_id=format_key, + emitted=emitted_definitions, + stats=stats, + ) + + emit(f"<{sample_uri}> <{_vocab('hasFormatValue')}> <{format_uri}> .\n") + emit( + f"<{format_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('FormatFieldValue')}> .\n" + ) + emit( + f"<{format_uri}> <{_vocab('declaredBy')}> " + f"<{definition.uri}> .\n" + ) if format_value: emit( - f"<{format_uri}> <{VCFR_NAMESPACE}fieldValue> " + f"<{format_uri}> <{_vocab('fieldValue')}> " f"{_ntriples_literal(format_value)} .\n" ) + if alt_count: + _emit_value_items( + emit, + parent_uri=format_uri, + field_key=format_key, + value=format_value, + number=definition.field_number, + allele_uris={ + index: f"{record_uri}/allele/{index}" + for index in range(alt_count + 1) + }, + version=version, + stats=stats, + ) format_value_count += 1 + if not format_value: + continue + if format_key == "GT": + _emit_genotype( + emit, + sample_uri=sample_uri, + record_uri=record_uri, + value=format_value, + alt_count=alt_count, + stats=stats, + ) + elif format_key == "FT": + emit( + f"<{sample_uri}> <{_vocab('sampleFilter')}> " + f"{_ntriples_literal(format_value)} .\n" + ) + elif format_key in vocab.PHASE_SET_FORMAT_KEYS: + phase_fields[format_key] = format_value + elif format_key == "LAA" and version.local_alleles: + _emit_local_allele_set( + emit, + sample_uri=sample_uri, + record_uri=record_uri, + value=format_value, + alt_count=alt_count, + stats=stats, + ) + elif format_key in vocab.COPY_NUMBER_FORMAT_KEYS: + emit( + f"<{sample_uri}> " + f"<{_vocab(vocab.COPY_NUMBER_FORMAT_KEYS[format_key])}> " + f"{_ntriples_literal(format_value)} .\n" + ) + elif format_key in vocab.HAPLOTYPE_FORMAT_KEYS: + if format_value.lstrip("-").isdigit(): + emit( + f"<{sample_uri}> " + f"<{_vocab(vocab.HAPLOTYPE_FORMAT_KEYS[format_key])}> " + f"{_ntriples_typed_literal(format_value, XSD_INTEGER_URI)} .\n" + ) + elif version.base_modifications: + if format_key not in base_modifications: + base_modifications[format_key] = ( + vocab.parse_base_modification_key(format_key) + ) + modification = base_modifications[format_key] + if modification is not None: + _emit_base_modification( + emit, + sample_uri=sample_uri, + modification=modification, + value=format_value, + stats=stats, + ) + + if phase_fields: + _emit_phase_set( + emit, + sample_uri=sample_uri, + phase_fields=phase_fields, + stats=stats, + ) + stats["records"] += 1 stats["sample_calls"] = sample_call_count stats["format_values"] = format_value_count @@ -2213,20 +2604,24 @@ def produce(emit): def append_canonical_sample_rdf( records_tsv: Path, rdf_path: Path, + header_lines_tsv: Path | None = None, *, + version: "vocab.VCFVersion | None" = None, progress_interval_records: int = 10_000, ) -> dict: """Backward-compatible name for the expanded sample RDF emitter.""" return append_expanded_sample_rdf( records_tsv, rdf_path, + header_lines_tsv, + version=version, progress_interval_records=progress_interval_records, ) @dataclass(frozen=True) class FormatDefinition: - """Structured attributes and RDF identity for one FORMAT declaration.""" + """Structured attributes and RDF identity for one INFO/FORMAT declaration.""" uri: str field_number: str @@ -2234,46 +2629,21 @@ class FormatDefinition: #: The declared VCF Type (Integer/Float/Flag/Character/String). Defaults to #: String so an undeclared field still has a usable value type. value_type: str = "String" + #: ##INFO recommends Source and Version; the SHACL profile warns when a + #: concrete INFO declaration omits them. + source: str | None = None + version: str | None = None + #: True when no '##' line declared this key and the definition was invented + #: so the value still has something to cite. A declared definition is owned + #: by the header emitter, which emits its ID/Number/Type/Description from + #: the header line; emitting them again here would duplicate every triple. + synthesized: bool = False -def _parse_structured_header_fields(value: str) -> dict[str, str]: - """Parse comma-delimited VCF header attributes while respecting quotes.""" - inner = value.strip() - if inner.startswith("<") and inner.endswith(">"): - inner = inner[1:-1] - - tokens: list[str] = [] - token: list[str] = [] - in_quotes = False - escaped = False - for character in inner: - if escaped: - token.append(character) - escaped = False - elif character == "\\" and in_quotes: - token.append(character) - escaped = True - elif character == '"': - token.append(character) - in_quotes = not in_quotes - elif character == "," and not in_quotes: - tokens.append("".join(token)) - token = [] - else: - token.append(character) - tokens.append("".join(token)) - - fields: dict[str, str] = {} - for item in tokens: - if "=" not in item: - continue - key, raw_value = item.split("=", 1) - parsed_value = raw_value.strip() - if len(parsed_value) >= 2 and parsed_value[0] == parsed_value[-1] == '"': - parsed_value = parsed_value[1:-1] - parsed_value = parsed_value.replace('\\"', '"').replace("\\\\", "\\") - fields[key.strip()] = parsed_value - return fields +#: Kept as module-level names because the emitters and the unit tests use them. +_parse_structured_header_fields = vocab.parse_structured_header_fields +_parse_structured_header_attributes = vocab.parse_structured_header_attributes +_typed_info_object = vocab.typed_field_object def _load_field_definitions( @@ -2283,7 +2653,7 @@ def _load_field_definitions( Serves both ``##FORMAT`` and ``##INFO`` declarations, which share the ```` syntax and the same vocabulary shape - (``vcfr:FieldDefinition`` with ``fieldId``/``fieldNumber``/``fieldType``). + (``vcfc:FieldDefinition`` with ``fieldId``/``fieldNumber``/``fieldType``). """ definitions: dict[str, FormatDefinition] = {} if not header_lines_tsv.is_file(): @@ -2310,6 +2680,8 @@ def _load_field_definitions( or f"{wanted} field {field_id} (source declaration has no Description)" ), value_type=fields.get("Type") or "String", + source=fields.get("Source"), + version=fields.get("Version"), ), ) return definitions @@ -2320,134 +2692,160 @@ def _load_format_definitions(header_lines_tsv: Path) -> dict[str, FormatDefiniti return _load_field_definitions(header_lines_tsv, "FORMAT") -#: Maps a declared VCF INFO/FORMAT Type to its vocabulary value-type class. -VCF_VALUE_TYPE_CLASSES = { - "Integer": "IntegerType", - "Float": "FloatType", - "Flag": "FlagType", - "Character": "CharacterType", - "String": "StringType", -} -#: Typed value predicates used when a single-valued field declares a numeric or -#: flag type. Multi-valued fields (Number=A/R/G/.) keep only the lexical value, -#: because the vocabulary gives one InfoFieldValue node per key. -XSD_INTEGER_URI = "http://www.w3.org/2001/XMLSchema#integer" -XSD_DECIMAL_URI = "http://www.w3.org/2001/XMLSchema#decimal" -XSD_BOOLEAN_URI = "http://www.w3.org/2001/XMLSchema#boolean" +def _load_assembly_line_uri(header_lines_tsv: Path) -> str | None: + """Return the IRI of the ``##assembly`` header line, if the file has one. + + A bracketed CHROM names a contig from that assembly FASTA, so the assembly + contig cites the line that located it. + """ + if not header_lines_tsv.is_file(): + return None + _set_max_csv_field_size() + with header_lines_tsv.open(newline="", encoding="utf-8") as handle: + for row in csv.DictReader(handle, delimiter="\t"): + if (row.get("HEADER_KEY") or "").strip().lower() != "assembly": + continue + source_component = _rml_uri_component(row.get("SOURCE_FILE") or "") + index_component = _rml_uri_component(row.get("HEADER_INDEX") or "") + return f"file://{source_component}#header/line/{index_component}" + return None -def parse_info_entries(info: str) -> list[tuple[str, str | None]]: - """Split an INFO column into ``(key, value)`` pairs. +def _load_contig_line_uris(header_lines_tsv: Path) -> dict[str, str]: + """Map each declared contig ID to the IRI of its ``##contig`` header line. - An entry without ``=`` is a Flag: a presence assertion with no value, which - the vocabulary models as ``vcfr:fieldValueBoolean true``. + ``vcfc:chromosome`` links a record to the contig declaration its CHROM value + names, which is what the SPARQL profile's POS-versus-contig-length check + traverses. """ - if info in ("", "."): - return [] - entries: list[tuple[str, str | None]] = [] - for item in info.split(";"): - if not item: - continue - key, separator, value = item.partition("=") - entries.append((key, value if separator else None)) - return entries + contigs: dict[str, str] = {} + if not header_lines_tsv.is_file(): + return contigs + _set_max_csv_field_size() + with header_lines_tsv.open(newline="", encoding="utf-8") as handle: + for row in csv.DictReader(handle, delimiter="\t"): + if (row.get("HEADER_KEY") or "").strip().lower() != "contig": + continue + fields = _parse_structured_header_fields(row.get("HEADER_VALUE") or "") + contig_id = (fields.get("ID") or "").strip() + if not contig_id: + continue + source_component = _rml_uri_component(row.get("SOURCE_FILE") or "") + index_component = _rml_uri_component(row.get("HEADER_INDEX") or "") + contigs.setdefault( + contig_id, + f"file://{source_component}#header/line/{index_component}", + ) + return contigs -def _typed_info_object(value: str, declared_type: str) -> tuple[str, str] | None: - """Return ``(predicate_local_name, literal)`` for a typed single value.""" - if "," in value or value == ".": - return None - try: - if declared_type == "Integer": - return "fieldValueInteger", f'"{int(value)}"^^<{XSD_INTEGER_URI}>' - if declared_type == "Float": - # Serialize the source lexical form rather than a reparsed float, so - # the graph never gains or loses precision relative to the VCF. - float(value) - return "fieldValueDecimal", f'"{value}"^^<{XSD_DECIMAL_URI}>' - except ValueError: - # A value that contradicts its declared type is kept as a plain literal - # rather than dropped; the conversion must not silently lose data. - return None - return None +#: Retained name for the VCF Type individuals. Since vocabulary 3.0.0 these are +#: owl:NamedIndividual members of vcfc:VCFValueType rather than classes, so they +#: only ever appear as the object of vcfc:fieldType. +VCF_VALUE_TYPE_CLASSES = VCF_VALUE_TYPE_INDIVIDUALS + +XSD_INTEGER_URI = vocab.XSD_INTEGER_URI +XSD_DECIMAL_URI = vocab.XSD_DECIMAL_URI +XSD_BOOLEAN_URI = vocab.XSD_BOOLEAN_URI +XSD_DATE_URI = vocab.XSD_DATE_URI +XSD_ANY_URI = vocab.XSD_ANY_URI +FILE_DATE_PATTERNS = vocab.FILE_DATE_PATTERNS # How the VCF meta-information block is represented. "basic" is the historical -# behaviour: every '##' line becomes an untyped vcfr:HeaderLine carrying its raw +# behaviour: every '##' line becomes an untyped vcfc:HeaderLine carrying its raw # key and value. "structured" additionally types each line with the vocabulary's -# subclass and lifts the attributes of FILTER, ALT and contig declarations into -# their own properties, so the header becomes queryable rather than just present. +# subclass, emits the ordered vcfc:HeaderAttribute resources that +# vcfc:StructuredHeaderLineShape requires, and lifts the INFO, FORMAT, FILTER, +# ALT, contig, META, SAMPLE and PEDIGREE attributes into their own properties, +# so the header becomes queryable rather than just present. +# +# Only "structured" produces a graph that satisfies the published SHACL +# profiles: a header line typed with one of the structured subclasses must +# carry at least one vcfc:hasAttribute, and "basic" emits no subclass at all. HEADER_REPRESENTATION_CHOICES = ("basic", "structured") DEFAULT_HEADER_REPRESENTATION = "structured" -#: '##' key (lower-cased) -> the vocabulary subclass for that line. -HEADER_LINE_CLASSES = { - "fileformat": "FileFormatHeaderLine", - "filedate": "FileDateHeaderLine", - "source": "SourceHeaderLine", - "reference": "ReferenceHeaderLine", - "info": "INFOHeaderLine", - "format": "FORMATHeaderLine", - "filter": "FILTERHeaderLine", - "alt": "ALTHeaderLine", - "contig": "ContigHeaderLine", -} -#: contig attribute -> vocabulary predicate. -CONTIG_ATTRIBUTES = { - "length": "contigLength", - "md5": "contigMd5", - "assembly": "contigAssembly", -} - - -XSD_DATE_URI = "http://www.w3.org/2001/XMLSchema#date" -#: ##fileDate has no mandated format. These are the two forms seen in practice -#: that map unambiguously onto xsd:date, which the SHACL shape requires. -FILE_DATE_PATTERNS = ( - (re.compile(r"^(\d{4})(\d{2})(\d{2})$"), "{0}-{1}-{2}"), - (re.compile(r"^(\d{4})-(\d{2})-(\d{2})$"), "{0}-{1}-{2}"), -) +# Which VCF specification version the conversion should follow. "auto" reads it +# from the input's own ##fileformat line, which VCF requires to be the first +# line of the file, so the default needs nothing from the user. An explicit +# version is an override for a file whose declaration is missing or wrong. +VCF_VERSION_CHOICES = ("auto", *sorted(vocab.VCF_VERSIONS)) +DEFAULT_VCF_VERSION = "auto" -def file_date_object(value: str) -> str | None: - """Serialize ##fileDate as xsd:date when its form allows, else lexically. - - Returns None for an absent value so no triple is emitted, matching RML's - behaviour for an empty reference. +def _emit_field_definition_attributes( + emit, + line_uri: str, + *, + field_id: str, + number: str, + value_type: str | None, + description: str | None, +) -> None: + """Emit the ID/Number/Type/Description quartet shared by field definitions. + + ``vcfc:fieldNumber`` keeps the source token losslessly. ``vcfc:fieldArity`` + is added for a symbolic token and ``vcfc:fieldNumberInteger`` for a fixed + count; the SPARQL profile requires the arity individual's code to equal the + fieldNumber token, so both are derived from the same string. """ - value = (value or "").strip() - if not value or value == ".": - return None - for pattern, template in FILE_DATE_PATTERNS: - match = pattern.match(value) - if match: - return f'"{template.format(*match.groups())}"^^<{XSD_DATE_URI}>' - # An unrecognized form is preserved verbatim rather than dropped; the SHACL - # layer reports it as non-conformant. - return _ntriples_string_literal(value) + emit( + f"<{line_uri}> <{_vocab('fieldId')}> " + f"{_ntriples_string_literal(field_id)} .\n" + ) + emit( + f"<{line_uri}> <{_vocab('fieldNumber')}> " + f"{_ntriples_string_literal(number)} .\n" + ) + arity = vocab.arity_individual(number) + if arity is not None: + emit(f"<{line_uri}> <{_vocab('fieldArity')}> <{_vocab(arity)}> .\n") + fixed_count = vocab.number_as_integer(number) + if fixed_count is not None: + emit( + f"<{line_uri}> <{_vocab('fieldNumberInteger')}> " + f"{_ordinal_literal(fixed_count)} .\n" + ) + if value_type: + individual = VCF_VALUE_TYPE_INDIVIDUALS.get(value_type, "StringType") + emit(f"<{line_uri}> <{_vocab('fieldType')}> <{_vocab(individual)}> .\n") + if description is not None: + emit( + f"<{line_uri}> <{_vocab('fieldDescription')}> " + f"{_ntriples_string_literal(description)} .\n" + ) def append_header_representation_rdf( header_lines_tsv: Path, rdf_path: Path, ) -> dict: - """Append typed header lines and structured FILTER/ALT/contig declarations. + """Append the structured VCF meta-information representation. - The default mapping emits every '##' line as an untyped ``vcfr:HeaderLine`` - with a raw key and value. The vocabulary already defines a subclass per line - type and dedicated properties for the FILTER, ALT and contig attributes; - this emits them, which is what makes the meta-information block queryable. + The RML mapping emits every '##' line as an untyped ``vcfc:HeaderLine`` with + its raw key, value and line index. Everything that lives inside the + angle-bracketed value is added here: the line's vocabulary subclass, one + ordered ``vcfc:HeaderAttribute`` per source attribute, and the dedicated + properties for INFO, FORMAT, FILTER, ALT, contig, META, SAMPLE and PEDIGREE + declarations. Emitted directly rather than through RML because the attributes live inside - a single ```` value that RML cannot decompose. + a single ```` cell that RML cannot decompose, and because + several of them (contig length, contig URL, assembly URL) need a datatype + that the raw string does not carry. """ stats = { "representation": "header", "header_lines": 0, "typed_lines": 0, + "attributes": 0, + "field_definitions": 0, "filter_definitions": 0, "alt_definitions": 0, "contigs": 0, + "sample_declarations": 0, + "pedigree_relations": 0, "file_dates": 0, "triples": 0, "appended_bytes": 0, @@ -2465,6 +2863,17 @@ def produce(emit): source_file = rows[0].get("SOURCE_FILE", "") if rows else "" file_uri = f"file://{_rml_uri_component(source_file)}" contig_count = 0 + # ##SAMPLE declares a subject that ##PEDIGREE lines refer to by ID, so + # both mint the same IRI for one declared sample. + declaration_uris: dict[str, str] = {} + + def declaration_uri(identifier: str) -> str: + existing = declaration_uris.get(identifier) + if existing is None: + existing = f"{file_uri}#header/sample/{_rml_uri_component(identifier)}" + declaration_uris[identifier] = existing + return existing + for row in rows: key = (row.get("HEADER_KEY") or "").strip() value = row.get("HEADER_VALUE") or "" @@ -2472,95 +2881,663 @@ def produce(emit): line_uri = f"file://{_rml_uri_component(row.get('SOURCE_FILE') or '')}" \ f"#header/line/{index_component}" stats["header_lines"] += 1 + key_lower = key.lower() - line_class = HEADER_LINE_CLASSES.get(key.lower()) + line_class = HEADER_LINE_CLASSES.get(key_lower) + structured = vocab.is_structured_header_value(value) if line_class is None: - # An unrecognized '##' key keeps only the base HeaderLine type - # the mapping already emitted; inventing a subclass for it would - # put a term in the graph that the vocabulary does not define. - continue - emit(f"<{line_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}{line_class}> .\n") + # An unrecognized '##' key still belongs to one of the two VCF + # meta-information forms. Typing it keeps it queryable without + # inventing a subclass the vocabulary does not define. An + # unstructured line is only typed when it has a value, because + # vcfc:UnstructuredHeaderLineShape requires one. + if structured: + line_class = "StructuredHeaderLine" + elif value: + line_class = "UnstructuredHeaderLine" + else: + continue + emit(f"<{line_uri}> <{RDF_TYPE_URI}> <{_vocab(line_class)}> .\n") stats["typed_lines"] += 1 - if key.lower() not in {"filter", "alt", "contig"}: + if not structured: + if key_lower == "assembly" and value: + emit( + f"<{line_uri}> <{_vocab('assemblyUrl')}> " + f"{_ntriples_typed_literal(value, XSD_ANY_URI)} .\n" + ) + elif key_lower == "pedigreedb" and value: + emit( + f"<{line_uri}> <{_vocab('pedigreeDbUrl')}> " + f"{_ntriples_typed_literal(value, XSD_ANY_URI)} .\n" + ) continue - fields = _parse_structured_header_fields(value) + + # vcfc:StructuredHeaderLineShape requires at least one attribute on + # every structured line, so these are emitted for all of them, not + # only the ones with dedicated properties below. + attributes = _parse_structured_header_attributes(value) + for position, (attribute_key, attribute_value) in enumerate(attributes, start=1): + attribute_uri = f"{line_uri}/attribute/{position}" + emit(f"<{line_uri}> <{_vocab('hasAttribute')}> <{attribute_uri}> .\n") + emit( + f"<{attribute_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('HeaderAttribute')}> .\n" + ) + emit( + f"<{attribute_uri}> <{_vocab('attributeKey')}> " + f"{_ntriples_string_literal(attribute_key)} .\n" + ) + emit( + f"<{attribute_uri}> <{_vocab('attributeValue')}> " + f"{_ntriples_string_literal(attribute_value)} .\n" + ) + emit( + f"<{attribute_uri}> <{_vocab('attributeIndex')}> " + f"{_ordinal_literal(position)} .\n" + ) + stats["attributes"] += 1 + + fields = dict(attributes) identifier = (fields.get("ID") or "").strip() - if not identifier: - continue description = fields.get("Description") - if key.lower() == "filter": - emit(f"<{line_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}FilterDefinition> .\n") + if key_lower in {"info", "format"}: + if not identifier: + continue + _emit_field_definition_attributes( + emit, + line_uri, + field_id=identifier, + number=fields.get("Number") or ".", + value_type=fields.get("Type") or "String", + description=( + description + or f"{key.upper()} field {identifier} " + "(source declaration has no Description)" + ), + ) + if key_lower == "info": + for attribute, predicate in vocab.INFO_EXTRA_ATTRIBUTES.items(): + attribute_value = fields.get(attribute) + if attribute_value: + emit( + f"<{line_uri}> <{_vocab(predicate)}> " + f"{_ntriples_string_literal(attribute_value)} .\n" + ) + stats["field_definitions"] += 1 + elif key_lower == "filter": + if not identifier: + continue emit( - f"<{line_uri}> <{VCFR_NAMESPACE}filterId> " + f"<{line_uri}> <{_vocab('filterId')}> " f"{_ntriples_string_literal(identifier)} .\n" ) + emit( + f"<{line_uri}> <{_vocab('fieldDescription')}> " + f"{_ntriples_string_literal(description or f'FILTER {identifier}')} .\n" + ) stats["filter_definitions"] += 1 - elif key.lower() == "alt": - emit(f"<{line_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}AltDefinition> .\n") + elif key_lower == "alt": + if not identifier: + continue emit( - f"<{line_uri}> <{VCFR_NAMESPACE}altId> " + f"<{line_uri}> <{_vocab('altId')}> " f"{_ntriples_string_literal(identifier)} .\n" ) + emit( + f"<{line_uri}> <{_vocab('fieldDescription')}> " + f"{_ntriples_string_literal(description or f'ALT {identifier}')} .\n" + ) stats["alt_definitions"] += 1 - else: + elif key_lower == "contig": + if not identifier: + continue contig_count += 1 stats["contigs"] += 1 emit( - f"<{line_uri}> <{VCFR_NAMESPACE}contigId> " + f"<{line_uri}> <{_vocab('contigId')}> " f"{_ntriples_string_literal(identifier)} .\n" ) - for attribute, predicate in CONTIG_ATTRIBUTES.items(): + for attribute, (predicate, datatype) in CONTIG_ATTRIBUTES.items(): attribute_value = fields.get(attribute) - if attribute_value: + if not attribute_value: + continue + if datatype == XSD_INTEGER_URI and not attribute_value.lstrip("-").isdigit(): + # A non-numeric length is preserved lexically rather + # than dropped; the SHACL layer reports it. emit( - f"<{line_uri}> <{VCFR_NAMESPACE}{predicate}> " + f"<{line_uri}> <{_vocab(predicate)}> " f"{_ntriples_string_literal(attribute_value)} .\n" ) - continue - - if description: + continue + emit( + f"<{line_uri}> <{_vocab(predicate)}> " + f"{_ntriples_typed_literal(attribute_value, datatype)} .\n" + ) + elif key_lower == "meta": + if not identifier: + continue + _emit_field_definition_attributes( + emit, + line_uri, + field_id=identifier, + number=fields.get("Number") or ".", + # vcfc:MetaDefinitionShape excludes Flag, which VCF also + # forbids for a ##META attribute. + value_type=fields.get("Type") or "String", + description=description, + ) + for allowed in _parse_meta_values(fields.get("Values")): + emit( + f"<{line_uri}> <{_vocab('metaAllowedValue')}> " + f"{_ntriples_string_literal(allowed)} .\n" + ) + stats["field_definitions"] += 1 + elif key_lower == "sample": + if not identifier: + continue + subject_uri = declaration_uri(identifier) + emit(f"<{line_uri}> <{_vocab('declaresSample')}> <{subject_uri}> .\n") emit( - f"<{line_uri}> <{VCFR_NAMESPACE}fieldDescription> " - f"{_ntriples_string_literal(description)} .\n" + f"<{subject_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('SampleDeclaration')}> .\n" ) + stats["sample_declarations"] += 1 + elif key_lower == "pedigree": + emitted_relation = False + for attribute_key, attribute_value in attributes: + if attribute_key == "ID" or not attribute_value: + continue + ancestor_uri = declaration_uri(attribute_value) + predicate = vocab.PEDIGREE_ROLE_PROPERTIES.get( + attribute_key, "pedigreeAncestor" + ) + emit(f"<{line_uri}> <{_vocab(predicate)}> <{ancestor_uri}> .\n") + emit( + f"<{ancestor_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('SampleDeclaration')}> .\n" + ) + emit( + f"<{line_uri}> <{_vocab('ancestorRole')}> " + f"{_ntriples_string_literal(attribute_key)} .\n" + ) + emitted_relation = True + if emitted_relation: + stats["pedigree_relations"] += 1 for row in rows: if (row.get("HEADER_KEY") or "").strip().lower() != "filedate": continue date_object = file_date_object(row.get("HEADER_VALUE") or "") if date_object is not None: - emit(f"<{file_uri}> <{VCFR_NAMESPACE}fileDate> {date_object} .\n") + emit(f"<{file_uri}> <{_vocab('fileDate')}> {date_object} .\n") stats["file_dates"] += 1 break if contig_count: emit( - f"<{file_uri}> <{VCFR_NAMESPACE}contigCount> " - f'"{contig_count}"^^<{XSD_INTEGER_URI}> .\n' + f"<{file_uri}> <{_vocab('contigCount')}> " + f"{_ordinal_literal(contig_count)} .\n" ) return _append_rdf_atomically(rdf_path, stats, produce) -def _qual_object(value: str) -> str: - """Serialize QUAL as the SHACL shape requires: xsd:decimal, or vcfr:Null. +def _parse_meta_values(raw: str | None) -> list[str]: + """Split a ##META ``Values=[a, b, c]`` list into its members.""" + if not raw: + return [] + inner = raw.strip() + if inner.startswith("[") and inner.endswith("]"): + inner = inner[1:-1] + return [item.strip() for item in inner.split(",") if item.strip()] + - The shape is ``sh:or([sh:datatype xsd:decimal] [sh:datatype vcfr:Null])``, - which RML cannot satisfy because the datatype depends on the row. A value - that is neither numeric nor the missing token is kept as a plain literal - rather than dropped: a non-conformant graph is more useful than a lossy one, - and the SHACL layer reports it. +_qual_object = vocab.qual_object + + +def _emit_allele_layer( + emit, + *, + record_uri: str, + alleles: list, + alt_definitions: dict[str, str], + stats: dict, +) -> dict[int, str]: + """Emit the record's ordered REF/ALT allele resources. + + Returns allele index -> allele IRI so the INFO value items, the SV carriers + and the per-sample genotype calls can all join the same resources. The index + is record-global: 0 for REF, then 1..n in source ALT order, which is exactly + the join key VCF Number=A and Number=R define. """ - if value in ("", "."): - return f'"."^^<{VCFR_NAMESPACE}Null>' - try: - float(value) - except ValueError: - return _ntriples_string_literal(value) - # Serialize the source lexical form so no precision is gained or lost. - return f'"{value}"^^<{XSD_DECIMAL_URI}>' + allele_uris: dict[int, str] = {} + for allele in alleles: + allele_uri = f"{record_uri}/allele/{allele.index}" + allele_uris[allele.index] = allele_uri + if allele.index == 0: + emit(f"<{record_uri}> <{_vocab('hasReferenceAllele')}> <{allele_uri}> .\n") + allele_class = "ReferenceAllele" + else: + emit(f"<{record_uri}> <{_vocab('hasAltAllele')}> <{allele_uri}> .\n") + allele_class = "AltAllele" + emit(f"<{allele_uri}> <{RDF_TYPE_URI}> <{_vocab(allele_class)}> .\n") + emit( + f"<{allele_uri}> <{_vocab('alleleIndex')}> " + f"{_ordinal_literal(allele.index)} .\n" + ) + emit( + f"<{allele_uri}> <{_vocab('alleleValue')}> " + f"{_ntriples_literal(allele.value)} .\n" + ) + emit(f"<{allele_uri}> <{_vocab('alleleKind')}> <{_vocab(allele.kind)}> .\n") + stats["alleles"] += 1 + + if allele.symbolic_id: + definition_uri = alt_definitions.get(allele.symbolic_id) + if definition_uri is not None: + emit( + f"<{allele_uri}> <{_vocab('declaredByAlt')}> " + f"<{definition_uri}> .\n" + ) + if allele.symbolic_type: + emit( + f"<{allele_uri}> <{_vocab('svType')}> " + f"<{_vocab(allele.symbolic_type)}> .\n" + ) + # vcfc:TandemRepeatAllele and vcfc:ReferenceBlock are deliberately not + # assigned here. Both shapes require a property that only the record's + # INFO can supply -- repeatSequenceCount from RN, referenceBlockLength + # from END -- so _emit_sv_layer types those alleles once it has them. + if allele.breakend is not None: + _emit_breakend(emit, allele_uri, allele.breakend) + stats["breakends"] += 1 + return allele_uris + + +def _emit_breakend(emit, allele_uri: str, breakend) -> None: + """Emit the parsed components of one breakend ALT expression.""" + emit(f"<{allele_uri}> <{RDF_TYPE_URI}> <{_vocab('Breakend')}> .\n") + if breakend.orientation is not None: + emit( + f"<{allele_uri}> <{_vocab('breakendOrientation')}> " + f"<{_vocab(breakend.orientation)}> .\n" + ) + if breakend.replacement: + emit( + f"<{allele_uri}> <{_vocab('breakendReplacementString')}> " + f"{_ntriples_typed_literal(breakend.replacement, vocab.BREAKEND_STRING_DATATYPE_URI)} .\n" + ) + if breakend.is_single: + emit( + f"<{allele_uri}> <{_vocab('isSingleBreakend')}> " + f'"true"^^<{XSD_BOOLEAN_URI}> .\n' + ) + + +def _emit_value_items( + emit, + *, + parent_uri: str, + field_key: str, + value: str, + number: str, + allele_uris: dict[int, str], + version: "vocab.VCFVersion", + stats: dict, +) -> None: + """Decompose a comma-separated payload into indexed vcfc:FieldValueItems. + + A field is decomposed when its items have a meaning per position. That is + usually decided by the declared Number -- A, R, LA, LR (one per allele), G, + LG (one per genotype), P (one per GT allele) -- but the version's flattened + tuple keys are positional too, even though the specification declares them + ``Number=.``: the version overlay checks their item count against the ALT + count, so their items have to be materialized. + + Which keys those are, and whether the tuple repeats per ALT allele, is + version-dependent. CIPOS is one pair for the whole record in VCF 4.1-4.3 and + one pair per ALT from 4.4; CILEN and CICN only become tuple keys in 4.4. + + Once any item of a field is materialized, all of them must be, contiguously + indexed from zero -- vcfc:ValueItemCountShape checks exactly that. + """ + if not version.is_positional(field_key, number): + return + items = vocab.split_value_items(value) + if not items: + return + tuple_arity = version.tuple_arity(field_key) + for item_index, item in enumerate(items): + item_uri = f"{parent_uri}/value/{item_index}" + emit(f"<{parent_uri}> <{_vocab('hasValueItem')}> <{item_uri}> .\n") + emit(f"<{item_uri}> <{RDF_TYPE_URI}> <{_vocab('FieldValueItem')}> .\n") + emit( + f"<{item_uri}> <{_vocab('valueIndex')}> " + f"{_ordinal_literal(item_index)} .\n" + ) + emit(f"<{item_uri}> <{_vocab('itemValue')}> {_ntriples_literal(item)} .\n") + if tuple_arity is not None: + emit( + f"<{item_uri}> <{_vocab('tupleArity')}> " + f"{_ordinal_literal(tuple_arity)} .\n" + ) + link = version.value_item_link(field_key, number, item_index) + if link.allele_index is not None: + allele_uri = allele_uris.get(link.allele_index) + if allele_uri is not None: + emit(f"<{item_uri}> <{_vocab('forAllele')}> <{allele_uri}> .\n") + elif link.genotype_index is not None: + emit( + f"<{item_uri}> <{_vocab('forGenotypeIndex')}> " + f"{_ordinal_literal(link.genotype_index)} .\n" + ) + elif link.gt_allele_index is not None: + emit( + f"<{item_uri}> <{_vocab('forGTAlleleIndex')}> " + f"{_ordinal_literal(link.gt_allele_index)} .\n" + ) + stats["value_items"] += 1 + + +def _emit_sv_layer( + emit, + *, + record_uri: str, + pos: str, + info_map: dict[str, str | None], + allele_uris: dict[int, str], + alleles_by_index: dict[int, object], + version: "vocab.VCFVersion", + stats: dict, +) -> None: + """Attach the reserved SV INFO keys to the alleles they describe. + + Called once per record with the whole INFO map rather than per key, because + several of these carriers need more than one key to be well formed: a + vcfc:VariantEvent needs both EVENT and EVENTTYPE, a reference block needs + both END and POS, and a tandem repeat needs RN before its RUS/RUL/RUC/RB + values mean anything. + + That coupling matters because the vocabulary's properties carry rdfs:domain + axioms. Emitting vcfc:endPosition on an allele infers vcfc:ReferenceBlock + for it under RDFS, which then requires vcfc:referenceBlockLength -- so a + carrier is only emitted when the record supplies everything its shape needs. + """ + alt_uris = {index: uri for index, uri in allele_uris.items() if index >= 1} + if not alt_uris: + return + + for key, predicate in vocab.SV_FLAG_INFO_KEYS.items(): + if key in info_map: + for allele_uri in alt_uris.values(): + emit( + f"<{allele_uri}> <{_vocab(predicate)}> " + f'"true"^^<{XSD_BOOLEAN_URI}> .\n' + ) + + for key, predicate in vocab.SV_ALLELE_INFO_KEYS.items(): + value = info_map.get(key) + if value is None: + continue + for offset, item in enumerate(vocab.split_value_items(value), start=1): + allele_uri = alt_uris.get(offset) + if allele_uri is not None: + emit( + f"<{allele_uri}> <{_vocab(predicate)}> " + f"{_ntriples_literal(item)} .\n" + ) + + claims = info_map.get("SVCLAIM") + if claims is not None: + for offset, item in enumerate(vocab.split_value_items(claims), start=1): + allele_uri = alt_uris.get(offset) + claim = vocab.SV_CLAIMS.get(item.strip().upper()) + if allele_uri is not None and claim is not None: + emit(f"<{allele_uri}> <{_vocab('svClaim')}> <{_vocab(claim)}> .\n") + + _emit_reference_block( + emit, + pos=pos, + end=info_map.get("END"), + alt_uris=alt_uris, + alleles_by_index=alleles_by_index, + stats=stats, + ) + _emit_variant_event( + emit, + record_uri=record_uri, + event=info_map.get("EVENT"), + event_type=info_map.get("EVENTTYPE"), + alt_uris=alt_uris, + version=version, + stats=stats, + ) + _emit_tandem_repeats( + emit, info_map=info_map, alt_uris=alt_uris, + alleles_by_index=alleles_by_index, stats=stats, + ) + + for key in (*vocab.FALDO_INTERVAL_INFO_KEYS, *vocab.CONFIDENCE_INTERVAL_INFO_KEYS): + value = info_map.get(key) + if value is None: + continue + if version.tuple_arity(key) is None: + # CILEN and CICN do not exist before VCF 4.4. A file that uses the + # name anyway keeps it as an ordinary INFO value rather than being + # given a carrier this version does not define. + continue + _emit_confidence_intervals( + emit, key=key, value=value, alt_uris=alt_uris, + version=version, stats=stats, + ) + + +def _emit_reference_block( + emit, *, pos: str, end: str | None, alt_uris: dict, alleles_by_index: dict, stats: dict +) -> None: + """Close a gVCF reference block with its END position and derived length. + + Only the ``<*>``/```` allele is a reference block. VCF also uses + END on symbolic SV records, but the vocabulary has no generic END property + there: the extent of such an allele is carried by SVLEN and the CI keys, so + END stays in its INFO value alone rather than being forced onto a class it + does not belong to. + """ + if end is None or not end.lstrip("-").isdigit(): + return + for index, allele_uri in alt_uris.items(): + allele = alleles_by_index.get(index) + if allele is None or allele.kind != "UnspecifiedAllele": + continue + emit(f"<{allele_uri}> <{RDF_TYPE_URI}> <{_vocab('ReferenceBlock')}> .\n") + emit( + f"<{allele_uri}> <{_vocab('endPosition')}> " + f"{_ntriples_typed_literal(end, XSD_INTEGER_URI)} .\n" + ) + if pos.isdigit(): + # VCF 4.5 reference blocks are inclusive of both endpoints. + length = max(int(end) - int(pos) + 1, 0) + emit( + f"<{allele_uri}> <{_vocab('referenceBlockLength')}> " + f"{_ordinal_literal(length)} .\n" + ) + emit( + f"<{allele_uri}> <{_vocab('isReferenceBlockStart')}> " + f'"true"^^<{XSD_BOOLEAN_URI}> .\n' + ) + stats["reference_blocks"] += 1 + + +def _emit_variant_event( + emit, + *, + record_uri: str, + event: str | None, + event_type: str | None, + alt_uris: dict, + version: "vocab.VCFVersion", + stats: dict, +) -> None: + """Group a record, or each of its ALT alleles, into a named EVENT. + + EVENT changed arity in VCF 4.4. Before that it is ``Number=1``: one event + for the whole record, and EVENTTYPE does not exist. From 4.4 both are + ``Number=A``: one event per ALT allele, in source order, so the link hangs + off the allele rather than the record. + + ``vcfc:VariantEventShape`` requires exactly one ``vcfc:eventType``, so an + event resource is only minted when a reserved EVENTTYPE code is available to + give it one. In a pre-4.4 file there is none, so EVENT stays an ordinary + INFO value rather than becoming a resource that fails its shape. + """ + if not event: + return + if not version.event_types or not event_type: + return + + events = vocab.split_value_items(event) + types = vocab.split_value_items(event_type) + if not version.events_per_alt: + events, types = events[:1], types[:1] + + for offset, name in enumerate(events): + if vocab.is_missing(name): + continue + code = types[offset] if offset < len(types) else None + individual = ( + vocab.EVENT_TYPES.get(code.strip().upper()) if code else None + ) + if individual is None: + continue + event_uri = f"{record_uri}/event/{_rml_uri_component(name)}" + subject = record_uri + if version.events_per_alt: + allele_uri = alt_uris.get(offset + 1) + if allele_uri is None: + continue + subject = allele_uri + emit(f"<{subject}> <{_vocab('inEvent')}> <{event_uri}> .\n") + emit(f"<{event_uri}> <{RDF_TYPE_URI}> <{_vocab('VariantEvent')}> .\n") + emit(f"<{event_uri}> <{_vocab('eventType')}> <{_vocab(individual)}> .\n") + stats["variant_events"] += 1 + + +def _emit_tandem_repeats( + emit, *, info_map: dict, alt_uris: dict, alleles_by_index: dict, stats: dict +) -> None: + """Emit the RN/RUS/RUL/RUC/RB repeat structure of a allele. + + RN gives the number of repeat sequences per ALT allele and is what makes an + allele a ``vcfc:TandemRepeatAllele``: without it the remaining keys have no + grouping, and the class's required ``vcfc:repeatSequenceCount`` would be + missing. The repeat-sequence values are flat comma lists across all alleles, + so RN also supplies the stride into them. + """ + counts = vocab.split_value_items(info_map.get("RN") or "") + if not counts: + return + consumed = 0 + for offset, count_token in enumerate(counts, start=1): + allele_uri = alt_uris.get(offset) + allele = alleles_by_index.get(offset) + if allele_uri is None or not count_token.isdigit(): + continue + count = int(count_token) + if allele is not None and allele.symbolic_type != "SymbolicTandemRepeat": + consumed += count + continue + emit( + f"<{allele_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('TandemRepeatAllele')}> .\n" + ) + emit( + f"<{allele_uri}> <{_vocab('repeatSequenceCount')}> " + f"{_ordinal_literal(count)} .\n" + ) + for position in range(count): + sequence_uri = f"{allele_uri}/repeat/{position + 1}" + emit( + f"<{allele_uri}> <{_vocab('hasRepeatSequence')}> " + f"<{sequence_uri}> .\n" + ) + emit( + f"<{sequence_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('RepeatSequence')}> .\n" + ) + emit( + f"<{sequence_uri}> <{_vocab('repeatSequenceIndex')}> " + f"{_ordinal_literal(position + 1)} .\n" + ) + for key, predicate in vocab.REPEAT_SEQUENCE_INFO_KEYS.items(): + items = vocab.split_value_items(info_map.get(key) or "") + flat_index = consumed + position + if flat_index < len(items): + emit( + f"<{sequence_uri}> <{_vocab(predicate)}> " + f"{_ntriples_literal(items[flat_index])} .\n" + ) + stats["repeat_sequences"] += 1 + consumed += count + stats["tandem_repeats"] += 1 + + +def _emit_confidence_intervals( + emit, *, key: str, value: str, alt_uris: dict, version: "vocab.VCFVersion", stats: dict +) -> None: + """Emit the (lower, upper) pairs of a CI* INFO key. + + CIPOS and CIEND use a FALDO InRangePosition, as the SV module specifies; the + remaining CI keys use a vcfc:ConfidenceInterval. + + Before VCF 4.4 the list holds exactly one pair describing the record, so + every ALT allele of a multi-allelic record shares it. From 4.4 the list + holds one pair per ALT allele in source order, and each allele gets its own. + """ + items = vocab.split_value_items(value) + for offset, allele_index in enumerate(sorted(alt_uris)): + # A pre-4.4 record has a single pair, so every allele reads items 0-1. + pair = offset if version.tuples_per_alt else 0 + lower = items[pair * 2] if pair * 2 < len(items) else None + upper = items[pair * 2 + 1] if pair * 2 + 1 < len(items) else None + if lower is None or upper is None: + break + allele_uri = alt_uris[allele_index] + interval_uri = f"{allele_uri}/ci/{key}" + if key in vocab.FALDO_INTERVAL_INFO_KEYS: + predicate = vocab.FALDO_INTERVAL_INFO_KEYS[key] + emit(f"<{allele_uri}> <{_vocab(predicate)}> <{interval_uri}> .\n") + emit( + f"<{interval_uri}> <{RDF_TYPE_URI}> " + f"<{vocab.FALDO_NAMESPACE}InRangePosition> .\n" + ) + emit( + f"<{interval_uri}> <{vocab.FALDO_NAMESPACE}begin> " + f"{vocab.numeric_literal(lower)} .\n" + ) + emit( + f"<{interval_uri}> <{vocab.FALDO_NAMESPACE}end> " + f"{vocab.numeric_literal(upper)} .\n" + ) + else: + predicate = vocab.CONFIDENCE_INTERVAL_INFO_KEYS[key] + emit(f"<{allele_uri}> <{_vocab(predicate)}> <{interval_uri}> .\n") + emit( + f"<{interval_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('ConfidenceInterval')}> .\n" + ) + # vcfc:ConfidenceIntervalShape puts both bounds through + # vcfc:NumericLiteralShape, so a plain string will not do. + emit( + f"<{interval_uri}> <{_vocab('ciLower')}> " + f"{vocab.numeric_literal(lower)} .\n" + ) + emit( + f"<{interval_uri}> <{_vocab('ciUpper')}> " + f"{vocab.numeric_literal(upper)} .\n" + ) + stats["confidence_intervals"] += 1 def append_record_detail_rdf( @@ -2570,24 +3547,25 @@ def append_record_detail_rdf( *, emit_qual: bool = True, emit_info: bool = True, + emit_alleles: bool = True, + version: "vocab.VCFVersion | None" = None, progress_interval_records: int = 10_000, ) -> dict: """Append per-record detail the RML mapping cannot express. - Covers QUAL (whose datatype depends on the value) and the structured INFO - representation (which would otherwise need a materialized helper table of - variants x INFO keys). Both are per-record, so they share one pass over - ``records.tsv``. - - The default mapping emits INFO only as an opaque ``vcfr:infoRaw`` string. - This adds the structured form the vocabulary already defines - one - ``vcfr:InfoFieldValue`` per record and key, at the IRI template the - vocabulary declares - so INFO becomes queryable rather than just present. - - Emitted directly rather than through RML for the same reason the genotype - representations are: RML would need a materialized helper table of - variants x INFO keys, and it cannot switch value datatype on a declared - ``Type``. + Three groups of things land here, all of them per-record, so they share one + pass over ``records.tsv``: + + * The fixed fields whose datatype depends on the row -- ID, ALT, QUAL and + FILTER. Each may be the VCF missing token, which the vocabulary requires + as ``"."^^vcfc:Null``, and RML cannot switch datatype per row. + * The allele layer: ``vcfc:ReferenceAllele`` and ``vcfc:AltAllele`` + resources parsed out of REF and ALT, with their index, kind, symbolic + type and breakend components, plus the ``vcfc:chromosome`` link to the + contig declaration named by CHROM. + * The structured INFO representation: one ``vcfc:InfoFieldValue`` per record + and key, its ``vcfc:FieldValueItem`` decomposition for Number=A/R/G/P + fields, and the SV carriers the reserved INFO keys imply. """ stats = { "representation": "record-detail", @@ -2595,6 +3573,17 @@ def append_record_detail_rdf( "qual_values": 0, "info_values": 0, "info_definitions": 0, + "alleles": 0, + "breakends": 0, + "value_items": 0, + "variant_events": 0, + "confidence_intervals": 0, + "reference_blocks": 0, + "tandem_repeats": 0, + "repeat_sequences": 0, + "contig_links": 0, + "assembly_contigs": 0, + "assembly_contig_links": 0, "triples": 0, "appended_bytes": 0, } @@ -2603,7 +3592,16 @@ def append_record_detail_rdf( if not rdf_path.is_file(): raise FileNotFoundError(f"RDF aggregate not found for INFO streaming: {rdf_path}") + version = version or vocab.FALLBACK_VERSION definitions = _load_field_definitions(header_lines_tsv, "INFO") + contig_line_uris = _load_contig_line_uris(header_lines_tsv) if emit_alleles else {} + assembly_line_uri = _load_assembly_line_uri(header_lines_tsv) if emit_alleles else None + alt_definition_uris = { + identifier: definition.uri + for identifier, definition in _load_field_definitions( + header_lines_tsv, "ALT" + ).items() + } with SampleRecordStream(records_tsv) as record_stream: if not record_stream.source_file: @@ -2613,6 +3611,7 @@ def produce(emit): source_component = _rml_uri_component(record_stream.source_file) file_uri = f"file://{source_component}" emitted_definitions: set[str] = set() + emitted_assembly_contigs: set[str] = set() key_components: dict[str, str] = {} value_count = 0 definition_count = 0 @@ -2620,14 +3619,90 @@ def produce(emit): qual_count = 0 for record in record_stream: row_component = _rml_uri_component(record.row_id) + record_uri = f"{file_uri}#record/{row_component}" call_uri = f"{file_uri}#call/{row_component}" + + # ID and ALT are record-level; FILTER and QUAL are call-level. + # All four are emitted here so the missing token is typed. + emit( + f"<{record_uri}> <{_vocab('recordId')}> " + f"{_ntriples_literal(record.record_id or '.')} .\n" + ) + emit( + f"<{record_uri}> <{_vocab('alt')}> " + f"{_ntriples_literal(record.alt or '.')} .\n" + ) + emit( + f"<{call_uri}> <{_vocab('filter')}> " + f"{_ntriples_literal(record.filter_value or '.')} .\n" + ) + emit( + f"<{call_uri}> <{_vocab('infoRaw')}> " + f"{_ntriples_literal(record.info or '.')} .\n" + ) if emit_qual: emit( - f"<{call_uri}> <{VCFR_NAMESPACE}qual> " + f"<{call_uri}> <{_vocab('qual')}> " f"{_qual_object(record.qual)} .\n" ) qual_count += 1 - for key, value in (parse_info_entries(record.info) if emit_info else ()): + + allele_uris: dict[int, str] = {} + alleles_by_index: dict[int, object] = {} + if emit_alleles: + # VCF 4.5 lets CHROM name a breakpoint-assembly contig in + # angle brackets instead of a declared reference sequence. + # The two are mutually exclusive: the vocabulary's + # consistency profile rejects a bracketed CHROM that also + # resolves to a ##contig declaration. + assembly_id = vocab.parse_bracketed_chrom(record.chrom) + if assembly_id is not None: + assembly_uri = ( + f"{file_uri}#assembly/contig/" + f"{_rml_uri_component(assembly_id)}" + ) + emit( + f"<{record_uri}> <{_vocab('chromAssemblyContig')}> " + f"<{assembly_uri}> .\n" + ) + if assembly_uri not in emitted_assembly_contigs: + emitted_assembly_contigs.add(assembly_uri) + emit( + f"<{assembly_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('AssemblyContig')}> .\n" + ) + emit( + f"<{assembly_uri}> <{_vocab('assemblyContigId')}> " + f"{_ntriples_string_literal(assembly_id)} .\n" + ) + if assembly_line_uri is not None: + emit( + f"<{assembly_uri}> " + f"<{_vocab('declaredInAssembly')}> " + f"<{assembly_line_uri}> .\n" + ) + stats["assembly_contigs"] += 1 + stats["assembly_contig_links"] += 1 + else: + contig_uri = contig_line_uris.get(record.chrom) + if contig_uri is not None: + emit( + f"<{record_uri}> <{_vocab('chromosome')}> " + f"<{contig_uri}> .\n" + ) + stats["contig_links"] += 1 + parsed_alleles = vocab.parse_alt_alleles(record.ref, record.alt) + alleles_by_index = {a.index: a for a in parsed_alleles} + allele_uris = _emit_allele_layer( + emit, + record_uri=record_uri, + alleles=parsed_alleles, + alt_definitions=alt_definition_uris, + stats=stats, + ) + + info_entries = parse_info_entries(record.info) if emit_info else [] + for key, value in info_entries: key_component = key_components.get(key) if key_component is None: key_component = _rml_uri_component(key) @@ -2638,67 +3713,84 @@ def produce(emit): if definition is None: definition = FormatDefinition( uri=f"{file_uri}#header/info/{key_component}", - field_number=".", + field_number="0" if value is None else ".", description=( f"Synthesized definition for undeclared INFO key {key}" ), value_type="Flag" if value is None else "String", + synthesized=True, ) if definition.uri not in emitted_definitions: emitted_definitions.add(definition.uri) definition_count += 1 - type_class = VCF_VALUE_TYPE_CLASSES.get( - definition.value_type, "StringType" - ) emit( f"<{definition.uri}> <{RDF_TYPE_URI}> " - f"<{VCFR_NAMESPACE}InfoFieldDefinition> .\n" - ) - emit( - f"<{definition.uri}> <{VCFR_NAMESPACE}fieldId> " - f"{_ntriples_string_literal(key)} .\n" - ) - emit( - f"<{definition.uri}> <{VCFR_NAMESPACE}fieldNumber> " - f"{_ntriples_string_literal(definition.field_number)} .\n" - ) - emit( - f"<{definition.uri}> <{VCFR_NAMESPACE}fieldDescription> " - f"{_ntriples_string_literal(definition.description)} .\n" - ) - emit( - f"<{definition.uri}> <{VCFR_NAMESPACE}fieldType> " - f"<{VCFR_NAMESPACE}{type_class}> .\n" + f"<{_vocab('InfoFieldDefinition')}> .\n" ) + # A key declared by a '##INFO' line already has its + # ID/Number/Type/Description from the header emitter, at + # this very IRI. Only an invented definition needs them. + if definition.synthesized: + _emit_field_definition_attributes( + emit, + definition.uri, + field_id=key, + number=definition.field_number, + value_type=definition.value_type, + description=definition.description, + ) - emit(f"<{call_uri}> <{VCFR_NAMESPACE}hasInfoValue> <{info_uri}> .\n") + emit(f"<{call_uri}> <{_vocab('hasInfoValue')}> <{info_uri}> .\n") emit( f"<{info_uri}> <{RDF_TYPE_URI}> " - f"<{VCFR_NAMESPACE}InfoFieldValue> .\n" + f"<{_vocab('InfoFieldValue')}> .\n" ) emit( - f"<{info_uri}> <{VCFR_NAMESPACE}declaredBy> " + f"<{info_uri}> <{_vocab('declaredBy')}> " f"<{definition.uri}> .\n" ) if value is None: emit( - f"<{info_uri}> <{VCFR_NAMESPACE}fieldValueBoolean> " + f"<{info_uri}> <{_vocab('fieldValueBoolean')}> " f'"true"^^<{XSD_BOOLEAN_URI}> .\n' ) else: emit( - f"<{info_uri}> <{VCFR_NAMESPACE}fieldValue> " + f"<{info_uri}> <{_vocab('fieldValue')}> " f"{_ntriples_literal(value)} .\n" ) typed = _typed_info_object(value, definition.value_type) if typed is not None: predicate, literal = typed emit( - f"<{info_uri}> <{VCFR_NAMESPACE}{predicate}> " + f"<{info_uri}> <{_vocab(predicate)}> " f"{literal} .\n" ) + if allele_uris: + _emit_value_items( + emit, + parent_uri=info_uri, + field_key=key, + value=value, + number=definition.field_number, + allele_uris=allele_uris, + version=version, + stats=stats, + ) value_count += 1 + if allele_uris and info_entries: + _emit_sv_layer( + emit, + record_uri=record_uri, + pos=record.pos, + info_map=dict(info_entries), + allele_uris=allele_uris, + alleles_by_index=alleles_by_index, + version=version, + stats=stats, + ) + stats["records"] += 1 stats["qual_values"] = qual_count stats["info_values"] = value_count @@ -2721,9 +3813,24 @@ def append_condensed_sample_rdf( header_lines_tsv: Path, rdf_path: Path, *, + emit_sample_data_raw: bool = False, progress_interval_records: int = 10_000, ) -> dict: - """Append sample-ordered cohort matrices and FORMAT value vectors.""" + """Append sample-ordered cohort matrices and FORMAT value vectors. + + This profile deliberately stops at the vector. The vocabulary defines + ``vcfc:encodedValues`` as a compact payload rather than a set of + independently asserted values, so the genotype, phase-set, local-allele and + base-modification resources that the expanded emitter derives per sample are + not produced here: doing so would reintroduce the per-sample growth the + condensed profile exists to avoid. Every value remains recoverable by + decoding a vector against its FORMAT definition and the matrix SampleSet. + + ``emit_sample_data_raw`` additionally stores each record's genotype columns + verbatim on the matrix. It is off by default because the FORMAT vectors + already preserve the semantic values, and the raw copy roughly doubles the + condensed payload. + """ stats = { "representation": "condensed", "records": 0, @@ -2741,38 +3848,23 @@ def append_condensed_sample_rdf( definitions = _load_format_definitions(header_lines_tsv) with SampleRecordStream(records_tsv) as record_stream: - if not record_stream.columns or not record_stream.source_file: + if not record_stream.source_file: return stats def produce(emit): source_component = _rml_uri_component(record_stream.source_file) file_uri = f"file://{source_component}" - sample_set_uri = f"{file_uri}#samples" emitted_definitions: set[str] = set() # FORMAT keys repeat on every record; encode each distinct key once. format_components: dict[str, str] = {} emit( - f"<{file_uri}> <{VCFR_NAMESPACE}representationProfile> " - f"<{VCFR_NAMESPACE}CondensedRepresentation> .\n" + f"<{file_uri}> <{_vocab('representationProfile')}> " + f"<{_vocab('CondensedRepresentation')}> .\n" + ) + sample_set_uri = _emit_sample_set( + emit, file_uri=file_uri, columns=record_stream.columns, stats=stats ) - emit(f"<{file_uri}> <{VCFR_NAMESPACE}hasSampleSet> <{sample_set_uri}> .\n") - emit(f"<{sample_set_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}SampleSet> .\n") - - for sample_column in record_stream.columns: - sample_component = _rml_uri_component(sample_column.uri_id) - sample_uri = f"{sample_set_uri}/{sample_component}" - emit(f"<{sample_set_uri}> <{VCFR_NAMESPACE}hasSample> <{sample_uri}> .\n") - emit(f"<{sample_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}VCFSample> .\n") - emit( - f"<{sample_uri}> <{VCFR_NAMESPACE}sampleName> " - f"{_ntriples_string_literal(sample_column.sample_id)} .\n" - ) - emit( - f"<{sample_uri}> <{VCFR_NAMESPACE}sampleIndex> " - f'"{sample_column.index}"^^<{XSD_POSITIVE_INTEGER_URI}> .\n' - ) - stats["samples"] += 1 for record in record_stream: if not record.format_keys: @@ -2780,12 +3872,20 @@ def produce(emit): row_component = _rml_uri_component(record.row_id) call_uri = f"{file_uri}#call/{row_component}" matrix_uri = f"{call_uri}/matrix" - emit(f"<{call_uri}> <{VCFR_NAMESPACE}hasCallMatrix> <{matrix_uri}> .\n") - emit(f"<{matrix_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}CohortCallMatrix> .\n") + emit(f"<{call_uri}> <{_vocab('hasCallMatrix')}> <{matrix_uri}> .\n") emit( - f"<{matrix_uri}> <{VCFR_NAMESPACE}appliesToSampleSet> " + f"<{matrix_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('CohortCallMatrix')}> .\n" + ) + emit( + f"<{matrix_uri}> <{_vocab('appliesToSampleSet')}> " f"<{sample_set_uri}> .\n" ) + if emit_sample_data_raw: + emit( + f"<{matrix_uri}> <{_vocab('sampleDataRaw')}> " + f"{_ntriples_string_literal(chr(9).join(record.sample_payloads))} .\n" + ) stats["matrices"] += 1 for format_index, format_key in enumerate(record.format_keys): @@ -2796,52 +3896,39 @@ def produce(emit): vector_uri = f"{matrix_uri}/fmt/{format_component}" definition = definitions.get(format_key) if definition is None: - definition = FormatDefinition( - uri=f"{file_uri}#header/format/{format_component}", - field_number=".", - description=( - f"Synthesized definition for undeclared FORMAT key {format_key}" - ), + definition = _synthesized_format_definition( + file_uri, format_key, format_component ) - definition_uri = definition.uri - if definition_uri not in emitted_definitions: - emit( - f"<{definition_uri}> <{RDF_TYPE_URI}> " - f"<{VCFR_NAMESPACE}FormatFieldDefinition> .\n" - ) - emit( - f"<{definition_uri}> <{VCFR_NAMESPACE}fieldId> " - f"{_ntriples_string_literal(format_key)} .\n" - ) - emit( - f"<{definition_uri}> <{VCFR_NAMESPACE}fieldNumber> " - f"{_ntriples_string_literal(definition.field_number)} .\n" - ) - emit( - f"<{definition_uri}> <{VCFR_NAMESPACE}fieldDescription> " - f"{_ntriples_string_literal(definition.description)} .\n" - ) - emitted_definitions.add(definition_uri) - stats["format_definitions"] += 1 + definitions[format_key] = definition + definition_uri = _emit_format_field_definition( + emit, + definition=definition, + field_id=format_key, + emitted=emitted_definitions, + stats=stats, + ) encoded_values = "\t".join( values[format_index] or "." for values in record.sample_values ) emit( - f"<{matrix_uri}> <{VCFR_NAMESPACE}hasFormatValueVector> " + f"<{matrix_uri}> <{_vocab('hasFormatValueVector')}> " f"<{vector_uri}> .\n" ) - emit(f"<{vector_uri}> <{RDF_TYPE_URI}> <{VCFR_NAMESPACE}FormatValueVector> .\n") emit( - f"<{vector_uri}> <{VCFR_NAMESPACE}declaredBy> " + f"<{vector_uri}> <{RDF_TYPE_URI}> " + f"<{_vocab('FormatValueVector')}> .\n" + ) + emit( + f"<{vector_uri}> <{_vocab('declaredBy')}> " f"<{definition_uri}> .\n" ) emit( - f"<{vector_uri}> <{VCFR_NAMESPACE}valueEncoding> " - f"<{VCFR_NAMESPACE}VCFTextVector> .\n" + f"<{vector_uri}> <{_vocab('valueEncoding')}> " + f"<{_vocab('VCFTextVector')}> .\n" ) emit( - f"<{vector_uri}> <{VCFR_NAMESPACE}encodedValues> " + f"<{vector_uri}> <{_vocab('encodedValues')}> " f"{_ntriples_string_literal(encoded_values)} .\n" ) stats["format_vectors"] += 1 @@ -2863,17 +3950,23 @@ def emit_record_detail( records_tsv: Path, header_lines_tsv: Path, rdf_path: Path, + version: "vocab.VCFVersion | None" = None, ) -> dict | None: - """Append QUAL and, when selected, the structured INFO representation. + """Append the record detail, and when selected the structured INFO form. - QUAL is always emitted: the RML mapping cannot type it per row, so this is - the only place it can come from. + ID, ALT, QUAL, FILTER and INFO raw are always emitted: the RML mapping + cannot type the missing token per row, so this is the only place they can + come from. The allele layer travels with the structured INFO representation, + because the Number=A/R/G value items are joined to the allele resources it + mints. """ if info_representation not in INFO_REPRESENTATION_CHOICES: raise ValueError(f"unknown INFO representation: {info_representation}") + structured = info_representation == "structured" return append_record_detail_rdf( records_tsv, header_lines_tsv, rdf_path, - emit_qual=True, emit_info=info_representation == "structured", + emit_qual=True, emit_info=structured, emit_alleles=structured, + version=version, ) @@ -2883,12 +3976,15 @@ def emit_sample_representation( records_tsv: Path, header_lines_tsv: Path, rdf_path: Path, + version: "vocab.VCFVersion | None" = None, ) -> dict | None: """Execute the workflow's sole direct RDF emitter, if it has one.""" if workflow.emitter is None: return None if workflow.emitter == "expanded": - return append_expanded_sample_rdf(records_tsv, rdf_path) + return append_expanded_sample_rdf( + records_tsv, rdf_path, header_lines_tsv, version=version + ) if workflow.emitter == "condensed": return append_condensed_sample_rdf(records_tsv, header_lines_tsv, rdf_path) raise RuntimeError(f"unknown sample RDF emitter: {workflow.emitter}") @@ -2902,6 +3998,8 @@ def update_conversion_metrics_after_sample_stream( rdf_path: Path, total_triples: int, sample_stats: dict, + vcf_version: str | None = None, + vcf_version_source: str | None = None, ): """Bring conversion JSON/CSV metrics in sync after direct sample emission.""" safe_name = safe_metrics_name(output_name) @@ -2922,6 +4020,9 @@ def update_conversion_metrics_after_sample_stream( payload["sample_representation"] = sample_stats # Retained for consumers of pre-condensed conversion metrics. payload["sample_streaming"] = sample_stats + if vcf_version is not None: + payload["vcf_version"] = vcf_version + payload["vcf_version_source"] = vcf_version_source metrics_json.write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") except (OSError, json.JSONDecodeError): pass @@ -2939,6 +4040,9 @@ def update_conversion_metrics_after_sample_stream( if row.get("run_id") == run_id and row.get("output_name") == output_name: row["output_triples"] = str(int(total_triples)) row["output_dir_size_bytes"] = str(output_size) + if vcf_version is not None and "vcf_version" in fieldnames: + row["vcf_version"] = vcf_version + row["vcf_version_source"] = vcf_version_source or "" changed = True if changed: with metrics_csv.open("w", newline="", encoding="utf-8") as handle: @@ -2998,6 +4102,12 @@ def build_sample_support_tsvs(records_tsv: Path, sample_calls_tsv: Path, sample_ # --------------------------------------------------------------------------- # RML mapping rendering and Docker image resolution # --------------------------------------------------------------------------- +#: The mapping's placeholder for the optional per-version file subclass. It is +#: rewritten per input, the same way the TSV paths are, so one mapping stays the +#: single source of truth instead of five near-identical per-version copies. +VCF_VERSION_CLASS_SENTINEL = "vcfc:VCFVersionFile" + + def render_rules_for_triplet( template_rules: Path, output_rules: Path, @@ -3006,17 +4116,56 @@ def render_rules_for_triplet( metadata_name: str, sample_calls_name: str, sample_format_name: str, + vcf_version: "vocab.VCFVersion | None" = None, ): - """Render per-input mapping rules by substituting TSV placeholders.""" + """Render per-input mapping rules by substituting TSV placeholders. + + ``vcf_version`` additionally resolves the version sentinel to that version's + optional ``vcfc:VCF4xFile`` subclass, which activates its SHACL overlay + gate. Passing None resolves the sentinel to ``vcfc:VCFFile``, which the + subject map already asserts: an unrecognized version therefore produces the + version-neutral graph rather than a claim the vocabulary cannot check. + + A custom mapping without the sentinel is unaffected; the substitution simply + finds nothing. + """ text = template_rules.read_text() text = text.replace('/data/tsv/records.tsv', f'/data/tsv/{records_name}') text = text.replace('/data/tsv/header_lines.tsv', f'/data/tsv/{headers_name}') text = text.replace('/data/tsv/file_metadata.tsv', f'/data/tsv/{metadata_name}') text = text.replace('/data/tsv/sample_calls.tsv', f'/data/tsv/{sample_calls_name}') text = text.replace('/data/tsv/sample_format_values.tsv', f'/data/tsv/{sample_format_name}') + version_class = ( + f"vcfc:{vcf_version.file_class}" if vcf_version is not None else "vcfc:VCFFile" + ) + text = text.replace(VCF_VERSION_CLASS_SENTINEL, version_class) output_rules.write_text(text) +def read_declared_vcf_version(metadata_tsv: Path) -> tuple["vocab.VCFVersion", bool, str]: + """Detect the VCF version from an input's ``##fileformat`` line. + + VCF requires ``##fileformat`` to be the first line of the file, and + ``src/vcf_as_tsv.sh`` already lifts it into ``file_metadata.tsv``, so + detection costs one small read and never needs the user to supply anything. + + Returns the version to convert with, whether it was recognized, and the raw + declared token for reporting. An unrecognized version -- absent, malformed, + or VCFv4.0, for which VCF Core claims no conformance overlay -- falls back to + the newest supported version so no representable content is dropped, and is + reported rather than silently assumed. + """ + declared = "" + if metadata_tsv.is_file(): + _set_max_csv_field_size() + with metadata_tsv.open(newline="", encoding="utf-8") as handle: + for row in csv.DictReader(handle, delimiter="\t"): + declared = (row.get("FILE_FORMAT") or "").strip() + break + version, recognized = vocab.resolve_vcf_version(declared) + return version, recognized, declared + + def resolve_default_rules_path(repo_root: Path) -> Path: """Resolve default rules path for both source checkout and installed package. @@ -3316,6 +4465,55 @@ def update_run_manifest(metrics_dir: Path, **updates) -> None: pass +def _validation_index(metrics_dir: Path) -> list[dict]: + """Point at every artifact one validation target produced. + + The reports are spread across three trees by design -- the stage JSON with + the other stages, the detail beside the other reports, the raw engine output + under it -- which makes them hard to find when a run is being diagnosed + rather than analysed. This collects them per target. + """ + stage_dir = metrics_dir / "stages" / "validation" + if not stage_dir.is_dir(): + return [] + entries: list[dict] = [] + for stage_path in sorted(stage_dir.glob("*.json")): + target_id = stage_path.stem + results_dir = metrics_dir / "reports" / "validation" / target_id + entry = { + "validation_id": target_id, + "stage_report": stage_path.relative_to(metrics_dir).as_posix(), + "results_dir": ( + results_dir.relative_to(metrics_dir).as_posix() + if results_dir.is_dir() else None + ), + } + try: + stage = json.loads(stage_path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError): + stage = {} + entry["status"] = stage.get("status") + entry["engine"] = stage.get("engine") + entry["validation_target"] = stage.get("validation_target") + entry["wall_seconds"] = (stage.get("timing") or {}).get("wall_seconds") + for label, name in ( + ("summary", "summary.json"), + ("benchmark", "benchmark.json"), + ("benchmark_csv", "benchmark.csv"), + ): + candidate = results_dir / name + entry[label] = ( + candidate.relative_to(metrics_dir).as_posix() + if candidate.is_file() else None + ) + engines_dir = results_dir / "engines" + entry["engines"] = sorted( + child.name for child in engines_dir.iterdir() if child.is_dir() + ) if engines_dir.is_dir() else [] + entries.append(entry) + return entries + + def write_run_summary( *, metrics_dir: Path, @@ -3363,6 +4561,10 @@ def write_run_summary( }, "stage_reports": stage_reports, "reports": reports, + # Validation writes a per-stage JSON, a detailed report directory and a + # benchmark CSV per target, which is a lot of places to look. Name them + # explicitly rather than leaving them to be found among the globs above. + "validation": _validation_index(metrics_dir), "logs": [ path.relative_to(metrics_dir).as_posix() for path in sorted((metrics_dir / "logs").rglob("*")) @@ -5188,6 +6390,7 @@ def run_full_mode( sample_workflow: SampleWorkflow, info_representation: str = DEFAULT_INFO_REPRESENTATION, header_representation: str = DEFAULT_HEADER_REPRESENTATION, + vcf_version: str = DEFAULT_VCF_VERSION, run_validation: bool = False, validation_artifacts: list[str] | None = None, validation_engine: str | list[str] = DEFAULT_VALIDATION_ENGINE, @@ -5209,8 +6412,14 @@ def run_full_mode( timestamp: str, wrapper_log_path: Path, run_tracker: RunTracker | None = None, + linking_manifests: list | None = None, + linking_options: dict | None = None, ): """Execute full pipeline: per-input TSV -> RDF -> compression -> validation.""" + linking_options = dict(linking_options or {}) + if linking_manifests: + from vcf_rdfizer_linking.session import NetworkPolicy + linking_options["policy"] = NetworkPolicy(linking_manifests) pipeline_label = "TSV -> RDF -> compression" if run_validation: pipeline_label += " -> validation" @@ -5392,6 +6601,41 @@ def fail_current(stage: str, message: str): triplet["sample_calls"] = sample_calls_tsv triplet["sample_format_values"] = sample_format_tsv safe_prefix = slugify(prefix) + + # The VCF version is detected per input, not per run: a directory may + # hold files of different versions, and each one's mapping and emitters + # have to follow its own ##fileformat line. + detected_version, version_recognized, declared_version = ( + read_declared_vcf_version(triplet["metadata"]) + ) + if vcf_version == "auto": + active_version = detected_version if version_recognized else None + else: + active_version = vocab.VCF_VERSIONS[vcf_version] + effective_version = active_version or vocab.FALLBACK_VERSION + + if vcf_version != "auto": + if version_recognized and detected_version.short != vcf_version: + print( + f" ! VCF version overridden: file declares " + f"{detected_version.token}, converting as " + f"{effective_version.token}" + ) + else: + print(f" * VCF version: {effective_version.token} (forced)") + elif version_recognized: + print(f" * VCF version: {effective_version.token} (detected)") + else: + # VCFv4.0 and anything malformed land here. VCF Core claims no + # conformance overlay for those, so no version class is emitted and + # the newest supported rules are used, which is stated rather than + # assumed silently. + shown = declared_version or "no ##fileformat line" + print( + f" ! VCF version not recognized ({shown}); converting with " + f"{effective_version.token} rules and no version class" + ) + generated_rules = generated_rules_dir / f"{safe_prefix}.rules.ttl" render_rules_for_triplet( rules_path, @@ -5401,6 +6645,7 @@ def fail_current(stage: str, message: str): triplet["metadata"].name, triplet["sample_calls"].name, triplet["sample_format_values"].name, + vcf_version=active_version, ) output_name = safe_prefix or slugify(out_name) @@ -5557,6 +6802,7 @@ def fail_current(stage: str, message: str): records_tsv=triplet["records"], header_lines_tsv=triplet["headers"], rdf_path=raw_rdf_files[0], + version=effective_version, ) except Exception as exc: fail_current( @@ -5612,6 +6858,7 @@ def fail_current(stage: str, message: str): records_tsv=triplet["records"], header_lines_tsv=triplet["headers"], rdf_path=raw_rdf_files[0], + version=effective_version, ) except Exception as exc: fail_current( @@ -5629,6 +6876,19 @@ def fail_current(stage: str, message: str): f"declarations: {info_stats['info_definitions']:,}" ) + if linking_manifests: + from vcf_rdfizer_linking.runner import run_stage + print(" * Linking: " + ", ".join(m.id for m in linking_manifests)) + try: + run_stage( + raw_rdf_files[0], linking_manifests, + out_dir / output_name / f"{output_name}.links.nt", + metrics_dir=metrics_dir, tracker=run_tracker, **linking_options, + ) + except Exception as exc: + fail_current("data-linking", str(exc)) + continue + if triples_produced is None: triples_produced = count_triples_in_nt_files(raw_rdf_files) if header_stats is not None: @@ -5643,6 +6903,12 @@ def fail_current(stage: str, message: str): rdf_path=raw_rdf_files[0], total_triples=triples_produced, sample_stats=sample_stats, + vcf_version=effective_version.token, + vcf_version_source=( + "declared" if vcf_version == "auto" and version_recognized + else "forced" if vcf_version != "auto" + else "fallback" + ), ) if triples_produced is not None: saw_triple_counts = True @@ -6699,6 +7965,7 @@ def run_validation_mode( engine_args: list[str] = ["--engine", ",".join(engine_list)] for flag, key in ( ("--query-timeout", "query_timeout"), + ("--validation-time-budget", "validation_time_budget"), ("--qlever-memory-gb", "qlever_memory_gb"), ("--qlever-port", "qlever_port"), ("--qlever-startup-timeout", "qlever_startup_timeout"), @@ -6706,6 +7973,8 @@ def run_validation_mode( value = options.get(key) if value is not None: engine_args.extend([flag, str(value)]) + if options.get("continue_after_query_timeout"): + engine_args.append("--continue-after-query-timeout") for flag, key in ( ("--qlever-index-arg", "qlever_index_args"), ("--qlever-server-arg", "qlever_server_args"), @@ -6729,7 +7998,10 @@ def run_validation_mode( "-v", f"{str(rdf_path.parent)}:/data/rdf:ro", "-v", - f"{str(results_dir)}:/data/validation", + # Resolved, like every other mount here: Docker reads a relative + # source as a *named volume*, so an unresolved path would silently send + # the reports into a volume instead of onto the host. + f"{str(results_dir.resolve())}:/data/validation", "-v", f"{str(metrics_dir.resolve())}:/data/metrics", *shacl_mount, @@ -6925,9 +8197,9 @@ def main(): parser.add_argument( "-m", "--mode", - choices=["full", "compress", "decompress", "tsv", "index", "validation"], + choices=["full", "compress", "decompress", "tsv", "index", "validation", "link"], default="full", - help="Run mode: full pipeline, TSV benchmark, compression, decompression, validation, or index-only regeneration", + help="Run mode: full pipeline, TSV benchmark, compression, decompression, validation, data linking, or index-only regeneration", ) parser.add_argument( "-i", @@ -6990,14 +8262,31 @@ def main(): f"(default: {DEFAULT_HEADER_REPRESENTATION})" ), ) + parser.add_argument( + "--vcf-version", + choices=VCF_VERSION_CHOICES, + default=DEFAULT_VCF_VERSION, + help=( + "VCF specification version to convert against. auto (the default) " + "reads each input's ##fileformat line, so nothing has to be " + "supplied; an explicit version overrides that for a file whose " + "declaration is missing or wrong. The version selects the " + "vcfc:VCF4xFile subclass in the mapping and the version-dependent " + "emitter behaviour (which INFO keys flatten a tuple, whether that " + "tuple repeats per ALT allele, and whether the local-allele and " + "base-modification FORMAT families exist). VCF 4.0 has no " + "conformance overlay and converts with no version class" + ), + ) parser.add_argument( "--info-representation", choices=INFO_REPRESENTATION_CHOICES, default=DEFAULT_INFO_REPRESENTATION, help=( "INFO column representation: structured also emits one " - "vcfr:InfoFieldValue per record and key alongside the raw string, " - "making INFO queryable; raw keeps only vcfr:infoRaw " + "vcfc:InfoFieldValue per record and key alongside the raw string, " + "along with the allele layer and per-allele value items, making " + "INFO queryable; raw keeps only vcfc:infoRaw " f"(default: {DEFAULT_INFO_REPRESENTATION})" ), ) @@ -7161,7 +8450,7 @@ def main(): action="store_true", help=( "Fail validation when a missing token is serialized as a plain '.' " - "literal instead of '.'^^vcfr:Null (reported but non-fatal by default)" + "literal instead of '.'^^vcfc:Null (reported but non-fatal by default)" ), ) parser.add_argument( @@ -7193,6 +8482,25 @@ def main(): default=None, help="Per-query timeout in seconds for validation (default: engine default)", ) + parser.add_argument( + "--validation-time-budget", + default=None, + help=( + "Wall-clock ceiling in seconds for one engine's whole validation " + "query set (0 = no ceiling, the default). A backstop for queries " + "that are slow but never individually time out" + ), + ) + parser.add_argument( + "--validation-continue-after-query-timeout", + action="store_true", + help=( + "Keep running an engine's remaining validation queries after one " + "exceeds the per-query timeout. Off by default: a timeout means " + "the engine cannot answer this graph in the time allowed, and each " + "remaining query costs another full timeout" + ), + ) parser.add_argument( "--qlever-memory-gb", default=None, @@ -7235,7 +8543,12 @@ def main(): action="store_true", help="Explicitly remove the aggregate .nt/.nt.gz output after successful compression", ) + from vcf_rdfizer_link import add_link_arguments, run_options, run_posthoc, selected_linkers + add_link_arguments(parser) args = parser.parse_args() + if args.mode not in {"full", "link"} and (args.link or args.linker_path or args.offline or args.links_cache_only or args.assembly or args.links_contact_email): + eprint("Error: linking options require --mode full or --mode link") + return 2 global _PROGRESS_ALLOWED, _PROGRESS_EVENTS_ALLOWED, _QUIET _QUIET = bool(args.quiet) @@ -7245,6 +8558,9 @@ def main(): _PROGRESS_ALLOWED = not (args.no_progress or args.quiet) _PROGRESS_EVENTS_ALLOWED = not args.no_progress + if args.mode == "link": + return run_posthoc(args) + if args.build and args.no_build: eprint("Error: --build and --no-build are mutually exclusive.") return 2 @@ -7269,7 +8585,10 @@ def main(): validation_engines: list[str] = [DEFAULT_VALIDATION_ENGINE] validation_engine_options: dict = {} shacl_shapes_path: Path | None = None + linking_manifests = [] try: + if args.link: + linking_manifests = selected_linkers(args) for option_name, key in ( ("--validation-query-timeout", "query_timeout"), ("--qlever-memory-gb", "qlever_memory_gb"), @@ -7281,6 +8600,16 @@ def main(): validation_engine_options[key] = parse_positive_int( raw_value, name=option_name ) + if args.validation_time_budget is not None: + # 0 is meaningful: no ceiling. + budget = int(args.validation_time_budget) + if budget < 0: + raise ValueError( + "--validation-time-budget must be zero or a positive integer" + ) + validation_engine_options["validation_time_budget"] = budget + if args.validation_continue_after_query_timeout: + validation_engine_options["continue_after_query_timeout"] = True if args.qlever_index_arg: validation_engine_options["qlever_index_args"] = list(args.qlever_index_arg) if args.qlever_server_arg: @@ -7391,6 +8720,10 @@ def main(): methods=full_methods, partitioned=full_uses_partitioning, ) + if linking_manifests: + output_plans[f"input {index} ({prefix})"].add( + out_dir / output_name / f"{output_name}.links.nt" + ) validate_no_output_collisions(output_plans) elif args.run_validation: raise ValueError("--validate/--run-validation is only valid in --mode full") @@ -7592,11 +8925,14 @@ def main(): ) return 2 manifest_options = { + "link": [m.id for m in linking_manifests], + "linking_options": {k: str(v) if isinstance(v, Path) else v for k, v in run_options(args).items()} if linking_manifests else None, "requested_image": args.image, "requested_image_version": args.image_version, "sample_representation": args.sample_representation if mode == "full" else None, "info_representation": args.info_representation if mode == "full" else None, "header_representation": args.header_representation if mode == "full" else None, + "vcf_version": args.vcf_version if mode == "full" else None, "rdf_storage_mode": args.rdf_storage_mode if mode == "full" else None, "compression_methods": ( full_methods if mode == "full" else methods if mode == "compress" else [] @@ -7801,6 +9137,9 @@ def execute_mode(): sample_workflow=sample_workflow, info_representation=args.info_representation, header_representation=args.header_representation, + vcf_version=args.vcf_version, + linking_manifests=linking_manifests, + linking_options=run_options(args), run_validation=args.run_validation, validation_artifacts=validation_artifacts, validation_engine=validation_engines, diff --git a/vcf_rdfizer_data/linkers/__init__.py b/vcf_rdfizer_data/linkers/__init__.py new file mode 100644 index 0000000..bc54638 --- /dev/null +++ b/vcf_rdfizer_data/linkers/__init__.py @@ -0,0 +1 @@ +"""Packaged example linkers; copy with vcf-rdfizer-link init --example ID.""" diff --git a/vcf_rdfizer_data/linkers/gene-demo/README.md b/vcf_rdfizer_data/linkers/gene-demo/README.md new file mode 100644 index 0000000..2eaf602 --- /dev/null +++ b/vcf_rdfizer_data/linkers/gene-demo/README.md @@ -0,0 +1,25 @@ +# Tier 2 — synthetic gene intervals + +This plug-in exercises an interval join without Python. `linker.ttl` declares +the local `genes.gff3`, its SHA-256 and an assembly guard. The genes and their +coordinates are **synthetic**, licensed with the example under MIT. The GRCh38 +label exists to test assembly matching; these are not biological annotations. + +```bash +vcf-rdfizer-link init --example gene-demo -o my-gene-linker +vcf-rdfizer-link check my-gene-linker --offline +vcf-rdfizer-link dry-run my-gene-linker -i sample.vcf --limit 100 +``` + +Intervals are 1-based closed; keys cover POS through POS + len(REF) - 1. The +example contains overlapping genes A/B and a gene C on chromosome 2. Exons are +ignored. Chromosome names match exactly. Symbolic alleles are skipped. + +For a real reference, change the plug-in ID, reference URL, actual SHA-256, +assembly and object template. Point `idAttribute` at the GFF3 attribute your +template needs; do not assume every publisher's `ID` is an Ensembl gene ID. +HTTPS and local file URLs are supported. Gzip digests cover compressed bytes. +Keep the reference's licensing and terms visible in the manifest. + +The source repository's `docs/datalinking.md` explains caching and assembly +refusal, including the limited role of `--assembly`. diff --git a/vcf_rdfizer_data/linkers/gene-demo/genes.gff3 b/vcf_rdfizer_data/linkers/gene-demo/genes.gff3 new file mode 100644 index 0000000..8aedec7 --- /dev/null +++ b/vcf_rdfizer_data/linkers/gene-demo/genes.gff3 @@ -0,0 +1,7 @@ +##gff-version 3 +##sequence-region 1 1 1000 +# Synthetic intervals for testing; these are not biological gene annotations. +1 VCF-RDFizer-demo gene 100 200 . + . ID=demo-gene-A +1 VCF-RDFizer-demo gene 180 250 . - . ID=demo-gene-B +1 VCF-RDFizer-demo exon 190 195 . + . ID=ignored-exon;Parent=demo-gene-A +2 VCF-RDFizer-demo gene 10 20 . + . ID=demo-gene-C diff --git a/vcf_rdfizer_data/linkers/gene-demo/linker.ttl b/vcf_rdfizer_data/linkers/gene-demo/linker.ttl new file mode 100644 index 0000000..7ef2ddd --- /dev/null +++ b/vcf_rdfizer_data/linkers/gene-demo/linker.ttl @@ -0,0 +1,22 @@ +@prefix vcfl: . + +# Tier 2: a deliberately tiny SYNTHETIC bundle, not a gene annotation release. +# Relative IRIs resolve beside this manifest, including after `init`/pip install. +# To adapt: declare your GFF3 HTTPS URL, its actual SHA-256 and assembly, then +# change featureType/idAttribute/objectTemplate to match that bundle. +<#demoGenes> a vcfl:Linker ; + vcfl:id "gene-demo" ; + vcfl:version "1.0.0" ; + vcfl:title "Synthetic GFF3 gene overlap example" ; + vcfl:license "MIT (manifest and synthetic reference data)" ; + vcfl:termsOfUse ; + vcfl:join [ a vcfl:IntervalJoin ; + vcfl:featureType "gene" ; + vcfl:idAttribute "ID" ] ; + vcfl:reference [ vcfl:url ; + vcfl:sha256 "c343c83fbb27ca6a22079fccab7e385fc3e9c89967b521fd77bd9b0930b87aa3" ; + vcfl:assembly "GRCh38" ; + vcfl:format vcfl:GFF3 ] ; + vcfl:emit [ vcfl:subject vcfl:VariantCall ; + vcfl:predicate vcfl:overlapsGene ; + vcfl:objectTemplate "https://example.org/genes/{ID}" ] . diff --git a/vcf_rdfizer_data/linkers/rsid-dbsnp/README.md b/vcf_rdfizer_data/linkers/rsid-dbsnp/README.md new file mode 100644 index 0000000..ffb0215 --- /dev/null +++ b/vcf_rdfizer_data/linkers/rsid-dbsnp/README.md @@ -0,0 +1,19 @@ +# Tier 1 — rsID to dbSNP + +This entire plug-in is `linker.ttl`: split VCF ID on semicolons, accept complete +`rs` + digits tokens, and emit a `vcfl:sameVariantAs` link to the dbSNP IRI. +There is no resolver, reference or network. This constructs identifier links; +it does not check whether an identifier is current or retired. + +```bash +vcf-rdfizer-link init --example rsid-dbsnp -o my-rsid-linker +vcf-rdfizer-link check my-rsid-linker +vcf-rdfizer-link dry-run my-rsid-linker -i sample.vcf --limit 100 +``` + +To read INFO tokens, change `field` to `INFO/` and select the delimiter. +To change the target, edit `objectTemplate` while retaining `{TOKEN}`. Change +`id` before installing a copy beside this example. The runner escapes the +token, owns the subject and removes duplicate triples. + +The source repository's `docs/datalinking.md` documents the full contract. diff --git a/vcf_rdfizer_data/linkers/rsid-dbsnp/linker.ttl b/vcf_rdfizer_data/linkers/rsid-dbsnp/linker.ttl new file mode 100644 index 0000000..027434a --- /dev/null +++ b/vcf_rdfizer_data/linkers/rsid-dbsnp/linker.ttl @@ -0,0 +1,17 @@ +@prefix vcfl: . + +# Tier 1: no code, reference download, or API request. +# ID is a semicolon-separated VCF column. Matching is case-sensitive. +<#rsIDdbSNP> a vcfl:Linker ; + vcfl:id "rsid-dbsnp" ; + vcfl:version "1.0.0" ; + vcfl:title "rsID to dbSNP" ; + vcfl:license "MIT (plug-in code and manifest)" ; + vcfl:termsOfUse ; + vcfl:join [ a vcfl:TokenJoin ; + vcfl:field "ID" ; + vcfl:splitOn ";" ; + vcfl:accept "^rs[0-9]+$" ] ; + vcfl:emit [ vcfl:subject vcfl:VariantCall ; + vcfl:predicate vcfl:sameVariantAs ; + vcfl:objectTemplate "https://identifiers.org/dbsnp:{TOKEN}" ] . diff --git a/vcf_rdfizer_data/linkers/rsid-ensembl/README.md b/vcf_rdfizer_data/linkers/rsid-ensembl/README.md new file mode 100644 index 0000000..87596bc --- /dev/null +++ b/vcf_rdfizer_data/linkers/rsid-ensembl/README.md @@ -0,0 +1,29 @@ +# Tier 3 — Ensembl variation service + +`resolver.py` sends one POST per deduplicated batch to Ensembl's +[variation endpoint](https://rest.ensembl.org/documentation/info/variation_post). +It links returned identifiers to Ensembl variation pages; it does not add +clinical significance, frequencies, or allele-level equivalence assertions. + +```bash +vcf-rdfizer-link init --example rsid-ensembl -o my-api-linker +vcf-rdfizer-link check my-api-linker +vcf-rdfizer-link dry-run my-api-linker -i sample.vcf --limit 100 + +vcf-rdfizer-link run -i sample.vcf --link rsid-ensembl \ + --links-contact-email you@your-institution.org \ + --links-cache ./api-cache -o sample.ensembl.links.nt +``` + +Set the contact address before a live cache miss. The shipped budget is 2 +requests/second, 100 total HTTP attempts per invocation, 100 rsIDs per batch; +retries consume the ceiling. Use filtered inputs. The runner's session owns +HTTPS access, caching, host pacing and retries; the resolver imports no HTTP +client. The session is a policy API, not a sandbox for untrusted Python. + +`dry-run` reports batches without calling the service or executing the resolver. +An offline replay needs an existing matching cache. A missing ID is skipped; +malformed responses, service failures and exhausted budgets abort the linker. +The example's code/manifest are MIT; service terms are linked in the manifest. + +The source repository's `docs/datalinking.md` documents the protocol and limits. diff --git a/vcf_rdfizer_data/linkers/rsid-ensembl/linker.ttl b/vcf_rdfizer_data/linkers/rsid-ensembl/linker.ttl new file mode 100644 index 0000000..842e75d --- /dev/null +++ b/vcf_rdfizer_data/linkers/rsid-ensembl/linker.ttl @@ -0,0 +1,21 @@ +@prefix vcfl: . + +# Tier 3: POST one batch of rsIDs to Ensembl, linking only returned variants. +# Copy this example and set contactEmail to your own address before live use. +<#rsIDEnsembl> a vcfl:Linker ; + vcfl:id "rsid-ensembl" ; + vcfl:version "1.0.0" ; + vcfl:title "Service-confirmed rsID to Ensembl" ; + vcfl:license "MIT (plug-in code and manifest)" ; + vcfl:termsOfUse ; + vcfl:endpoint ; + vcfl:maxRequestsPerSecond 2 ; + vcfl:maxRequestsPerRun 100 ; + vcfl:batchSize 100 ; + vcfl:contactEmail "replace-me@example.org" ; + vcfl:join [ a vcfl:TokenJoin ; + vcfl:field "ID" ; + vcfl:splitOn ";" ; + vcfl:accept "^rs[0-9]+$" ] ; + vcfl:emit [ vcfl:subject vcfl:VariantCall ; + vcfl:predicate vcfl:sameVariantAs ] . diff --git a/vcf_rdfizer_data/linkers/rsid-ensembl/resolver.py b/vcf_rdfizer_data/linkers/rsid-ensembl/resolver.py new file mode 100644 index 0000000..9779156 --- /dev/null +++ b/vcf_rdfizer_data/linkers/rsid-ensembl/resolver.py @@ -0,0 +1,34 @@ +"""Ensembl variation POST example: one request per deduplicated batch. + +API contract: https://rest.ensembl.org/documentation/info/variation_post +Only confirm returned identifiers. Do not infer clinical significance, allele +equivalence, frequencies, or current identifiers for merged/retired rsIDs. +""" + +from collections.abc import Iterable, Sequence +from urllib.parse import quote + +from vcf_rdfizer_linking import Link, LinkKey, LinkerContext + + +def resolve(batch: Sequence[LinkKey], ctx: LinkerContext) -> Iterable[Link]: + response = ctx.session.post( + "https://rest.ensembl.org/variation/homo_sapiens", + json={"ids": [key.token for key in batch]}, + ) + response.raise_for_status() + payload = response.json() + if not isinstance(payload, dict): + raise ValueError("Expected an Ensembl object keyed by requested identifiers") + for key in batch: + variant = payload.get(key.token) + if variant is None: + continue + if not isinstance(variant, dict): + raise ValueError(f"Invalid Ensembl variation object for {key.token}") + if variant.get("error"): + continue + if not isinstance(variant.get("name"), str): + raise ValueError(f"Ensembl response for {key.token} has no variant name") + # Preserve the submitted identifier; the website handles redirects. + yield Link(key, "https://www.ensembl.org/Homo_sapiens/Variation/Explore?v=" + quote(key.token, safe="")) diff --git a/vcf_rdfizer_data/rules/default_rules.ttl b/vcf_rdfizer_data/rules/default_rules.ttl index 7332230..a4e0107 100644 --- a/vcf_rdfizer_data/rules/default_rules.ttl +++ b/vcf_rdfizer_data/rules/default_rules.ttl @@ -3,9 +3,17 @@ @prefix ql: . @prefix csvw: . @prefix xsd: . -@prefix vcfr: . +@prefix vcfc: . -# Default VCF-RDFizer RML rules. +# Default VCF-RDFizer RML rules, targeting the VCF Core vocabulary. +# +# Namespace +# --------- +# The target is https://w3id.org/vcf-core/vocab# (prefix vcfc:), which replaces +# the retired https://w3id.org/vcf-rdfizer/vocab# (prefix vcfr:). The retired +# namespace is not redirected: it serves a deprecation document in which every +# former term is linked to its successor. No version IRI is pinned; these rules +# target the namespace, whose release cadence is independent of the converter's. # # Expected TSV inputs produced by src/vcf_as_tsv.sh: # - /data/tsv/.file_metadata.tsv @@ -14,12 +22,60 @@ # - /data/tsv/.sample_calls.tsv (header-only compatibility source) # - /data/tsv/.sample_format_values.tsv (header-only compatibility source) # The wrapper rewrites the template paths below for each input sample. -# The wrapper selects exactly one direct sample emitter: expanded SampleCall / -# FormatFieldValue triples, or condensed SampleSet / CohortCallMatrix / -# FormatValueVector triples. The helper tables stay header-only in either mode. +# +# What is here and what is not +# ---------------------------- +# The division is a single rule: this mapping carries every field whose RDF +# datatype is the same for every row, and the wrapper's direct N-Triples +# emitters carry everything else. RML cannot choose an object datatype per row, +# and it cannot decompose one source cell into several resources without a +# materialized helper table whose size is the product of its dimensions. +# +# Emitted by the wrapper, not here: +# - ID, ALT, QUAL, FILTER and INFO. Each may be the VCF missing token, which the +# vocabulary requires as "."^^vcfc:Null rather than a plain string, so the +# datatype depends on the row. +# - fileDate. The published shape requires xsd:date, but ##fileDate has no +# mandated format in the VCF specification, so the value must be inspected. +# - The structured header representation: header-line subclasses, the +# vcfc:HeaderAttribute resources that vcfc:StructuredHeaderLineShape requires +# on every ##INFO/##FORMAT/##FILTER/##ALT/##contig/##META/##SAMPLE/##PEDIGREE +# line, and the INFO/FORMAT/FILTER/ALT/contig/META declaration properties. +# These all live inside one angle-bracketed cell. +# - The allele layer: vcfc:ReferenceAllele and vcfc:AltAllele resources with +# their index, kind, symbolic type and breakend components, parsed out of the +# REF and ALT columns. +# - The structured INFO representation, its vcfc:FieldValueItem decomposition, +# and the SV carriers derived from reserved INFO keys. +# - Genotype data. The wrapper selects exactly one direct sample emitter: +# expanded SampleCall / FormatFieldValue / Genotype triples, or condensed +# SampleSet / CohortCallMatrix / FormatValueVector triples. The helper tables +# stay header-only in either mode. +# +# Ordinals +# -------- +# vcfc:lineIndex and vcfc:recordIndex are typed xsd:integer, not +# xsd:positiveInteger. The SHACL profiles constrain every ordinal with +# sh:datatype xsd:integer plus a sh:minInclusive bound, and a SHACL datatype +# constraint compares the datatype IRI exactly. An xsd:integer literal +# satisfies both the shape and the ontology's xsd:positiveInteger range, since +# the value 1 belongs to that value space however it is written. +# +# VCF versions +# ------------ +# VCF Core supplies one SHACL overlay per VCF version, each scoped by the file's +# vcfc:fileFormat. Most of this mapping is version-neutral, because the fixed +# columns and the header-line structure do not change between 4.1 and 4.5. The +# one version-dependent thing RML can carry is the optional vcfc:VCF4xFile +# subclass on the file subject, which is the sentinel in <#VCFFileMap> below. +# +# The version-dependent *semantics* -- which INFO keys flatten a tuple, whether +# that tuple repeats per ALT allele, and whether the local-allele and +# base-modification FORMAT families exist -- are decompositions of one source +# cell, so they live in the wrapper's emitters like every other decomposition. # # Output format: -# - The default conversion now targets triples (N-Triples) without named graph terms. +# - The default conversion targets triples (N-Triples) without named graph terms. <#VCFFileMap> a rr:TriplesMap ; @@ -37,22 +93,30 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}" ; - rr:class vcfr:VCFFile + rr:class vcfc:VCFFile ; + # Version overlay. The wrapper rewrites this sentinel per input to the + # optional subclass for the version the file's ##fileformat line declares + # -- vcfc:VCF41File through vcfc:VCF45File -- which activates that version's + # SHACL gate. When the version has no conformance overlay (VCFv4.0, or a + # missing or malformed line) the sentinel is rewritten to vcfc:VCFFile, + # which is already asserted above, so the graph never claims a version gate + # it cannot support and never gains an undefined term. + rr:class vcfc:VCFVersionFile ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasHeader ; + rr:predicate vcfc:hasHeader ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#header" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:fileFormat ; + rr:predicate vcfc:fileFormat ; rr:objectMap [ rml:reference "FILE_FORMAT" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:sourceSoftware ; + rr:predicate vcfc:sourceSoftware ; rr:objectMap [ rml:reference "SOURCE_SOFTWARE" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:referenceGenome ; + rr:predicate vcfc:referenceGenome ; rr:objectMap [ rml:reference "REFERENCE_GENOME" ] ] . @@ -72,9 +136,34 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#header" ; - rr:class vcfr:VCFHeader + rr:class vcfc:VCFHeader + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:hasColumnHeader ; + rr:objectMap [ rr:template "file://{SOURCE_FILE}#header/columns" ] + ] . + +# The mandatory #CHROM line. Its ordered sample columns are attached by the +# wrapper with vcfc:hasGenotypeColumns, because they live in the records TSV +# header rather than in a row of any source table. +<#ColumnHeaderLineMap> + a rr:TriplesMap ; + rml:logicalSource [ + rml:source [ + a csvw:Table ; + csvw:url "/data/tsv/file_metadata.tsv" ; + csvw:dialect [ + a csvw:Dialect ; + csvw:delimiter "\t" ; + csvw:headerRowCount 1 + ] + ] ; + rml:referenceFormulation ql:CSV ] ; - . + rr:subjectMap [ + rr:template "file://{SOURCE_FILE}#header/columns" ; + rr:class vcfc:ColumnHeaderLine + ] . # NOTE: # Use explicit link maps (template-based) instead of parentTriplesMap joins. @@ -97,7 +186,7 @@ rr:template "file://{SOURCE_FILE}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasRecord ; + rr:predicate vcfc:hasRecord ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#record/{ROW_ID}" ] @@ -121,12 +210,16 @@ rr:template "file://{SOURCE_FILE}#header" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasHeaderLine ; + rr:predicate vcfc:hasHeaderLine ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#header/line/{HEADER_INDEX}" ] ] . +# Every '##' line as a base vcfc:HeaderLine. The wrapper adds the subclass, the +# ordered vcfc:HeaderAttribute resources and the declaration properties. +# vcfc:lineIndex is what the SPARQL SHACL profile uses to check that header +# indices are unique and that ##fileformat is line 1. <#HeaderLineMap> a rr:TriplesMap ; rml:logicalSource [ @@ -143,17 +236,24 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#header/line/{HEADER_INDEX}" ; - rr:class vcfr:HeaderLine + rr:class vcfc:HeaderLine ] ; rr:predicateObjectMap [ - rr:predicate vcfr:headerKey ; + rr:predicate vcfc:headerKey ; rr:objectMap [ rml:reference "HEADER_KEY" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:headerValue ; + rr:predicate vcfc:headerValue ; rr:objectMap [ rml:reference "HEADER_VALUE" ] + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:lineIndex ; + rr:objectMap [ rml:reference "HEADER_INDEX" ; rr:datatype xsd:integer ] ] . +# CHROM, POS and REF are the three fixed fields VCF 4.5 forbids from being the +# missing token, so their datatype is fixed for every row and they belong here. +# ID and ALT may be missing and are emitted by the wrapper. <#VCFRecordMap> a rr:TriplesMap ; rml:logicalSource [ @@ -170,33 +270,32 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#record/{ROW_ID}" ; - rr:class vcfr:VCFRecord + rr:class vcfc:VCFRecord ] ; rr:predicateObjectMap [ - rr:predicate vcfr:chrom ; + rr:predicate vcfc:chrom ; rr:objectMap [ rml:reference "CHROM" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:pos ; + rr:predicate vcfc:pos ; rr:objectMap [ rml:reference "POS" ; rr:datatype xsd:integer ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:recordId ; - rr:objectMap [ rml:reference "ID" ] - ] ; - rr:predicateObjectMap [ - rr:predicate vcfr:ref ; + rr:predicate vcfc:ref ; rr:objectMap [ rml:reference "REF" ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:alt ; - rr:objectMap [ rml:reference "ALT" ] + rr:predicate vcfc:recordIndex ; + rr:objectMap [ rml:reference "ROW_ID" ; rr:datatype xsd:integer ] ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasCall ; + rr:predicate vcfc:hasCall ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ] ] . +# FORMAT is the only call-level column whose datatype is fixed: VCF 4.5 defines +# it as a colon-separated key list with no missing form. QUAL, FILTER and INFO +# are emitted by the wrapper. <#VariantCallMap> a rr:TriplesMap ; rml:logicalSource [ @@ -213,18 +312,10 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ; - rr:class vcfr:VariantCall - ] ; - rr:predicateObjectMap [ - rr:predicate vcfr:filter ; - rr:objectMap [ rml:reference "FILTER" ] - ] ; - rr:predicateObjectMap [ - rr:predicate vcfr:infoRaw ; - rr:objectMap [ rml:reference "INFO" ] + rr:class vcfc:VariantCall ] ; rr:predicateObjectMap [ - rr:predicate vcfr:formatRaw ; + rr:predicate vcfc:formatRaw ; rr:objectMap [ rml:reference "FORMAT" ] ] . @@ -246,7 +337,7 @@ rr:template "file://{SOURCE_FILE}#call/{ROW_ID}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasSampleCall ; + rr:predicate vcfc:hasSampleCall ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ] @@ -268,11 +359,17 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ; - rr:class vcfr:SampleCall + rr:class vcfc:SampleCall ] ; rr:predicateObjectMap [ - rr:predicate vcfr:sampleId ; + rr:predicate vcfc:sampleId ; rr:objectMap [ rml:reference "SAMPLE_ID" ] + ] ; + rr:predicateObjectMap [ + rr:predicate vcfc:forSample ; + rr:objectMap [ + rr:template "file://{SOURCE_FILE}#samples/{SAMPLE_URI_ID}" + ] ] . <#SampleCallToFormatValueLinkMap> @@ -293,7 +390,7 @@ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}" ] ; rr:predicateObjectMap [ - rr:predicate vcfr:hasFormatValue ; + rr:predicate vcfc:hasFormatValue ; rr:objectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}/fmt/{FORMAT_KEY}" ] @@ -315,9 +412,9 @@ ] ; rr:subjectMap [ rr:template "file://{SOURCE_FILE}#sample/{ROW_ID}/{SAMPLE_URI_ID}/fmt/{FORMAT_KEY}" ; - rr:class vcfr:FormatFieldValue + rr:class vcfc:FormatFieldValue ] ; rr:predicateObjectMap [ - rr:predicate vcfr:fieldValue ; + rr:predicate vcfc:fieldValue ; rr:objectMap [ rml:reference "FORMAT_VALUE" ] ] . diff --git a/vcf_rdfizer_link.py b/vcf_rdfizer_link.py new file mode 100644 index 0000000..723ef5d --- /dev/null +++ b/vcf_rdfizer_link.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python3 +"""Inspect, scaffold, preview and run data-linking plug-ins without Docker.""" + +import argparse +from dataclasses import asdict, replace +from datetime import datetime +import json +from pathlib import Path +import shutil +import sys +import time + +from vcf_rdfizer_linking.inputs import read_rdf, read_vcf +from vcf_rdfizer_linking.manifest import discover, load_manifest, select +from vcf_rdfizer_linking.reference import acquire_reference, check_assembly, IntervalIndex +from vcf_rdfizer_linking.runner import DEFAULT_CACHE, LinkRunError, run_linkers, run_stage + + +def add_link_arguments(parser): + parser.add_argument("--link", help="Comma-separated linker IDs (full/link modes)") + parser.add_argument("--linker-path", action="append", default=[], help="Additional linker search directory (repeatable)") + parser.add_argument("--links-cache", default=str(DEFAULT_CACHE), help="Reference and HTTP response cache directory") + parser.add_argument("--offline", action="store_true", help="Disable linker network access; local references and cached responses only") + parser.add_argument("--links-cache-only", action="store_true", help="Alias for --offline for linking") + parser.add_argument("--assembly", help="Input assembly when reference metadata is absent/unrecognized; cannot override a mismatch") + parser.add_argument("--links-contact-email", help="Contact address sent in live linker User-Agent headers") + + +def selected_linkers(args): + import re + manifests = select(args.link or "", args.linker_path) + if args.links_contact_email: + if not re.fullmatch(r"[^\s<>@]+@[^\s<>@]+\.[^\s<>@]+", args.links_contact_email): + raise ValueError("--links-contact-email must be an email address") + manifests = [replace(m, contact_email=args.links_contact_email) if m.tier == 3 else m for m in manifests] + return manifests + + +def run_options(args): + return {"cache_dir": Path(args.links_cache).expanduser(), + "offline": args.offline or args.links_cache_only, "assembly": args.assembly} + + +def run_posthoc(args): + """Host-only --mode link, with the standard run_metrics tree.""" + from vcf_rdfizer import (RunTracker, metrics_run_directory, metrics_run_label, + write_run_manifest, write_run_summary, rdf_output_basename) + try: + if not args.rdf or not args.link: + raise ValueError("--mode link requires --rdf and --link") + rdf = Path(args.rdf).expanduser().resolve() + if not rdf.is_file() or not rdf.name.endswith((".nt", ".nt.gz")): + raise ValueError("--rdf must be an existing .nt or .nt.gz file") + manifests = selected_linkers(args) + root = Path(args.out).expanduser().resolve() + output = root / (rdf_output_basename(rdf) + ".links.nt") + if output.exists(): + raise ValueError(f"Refusing to overwrite existing linkset: {output}") + except (ValueError, OSError) as exc: + print(f"error: {exc}", file=sys.stderr) + return 2 + run_id = datetime.now().strftime("%Y%m%dT%H%M%S%f") + timestamp = datetime.now().isoformat(timespec="seconds") + metrics = metrics_run_directory(root / "run_metrics", metrics_run_label([rdf], rdf), run_id) + started, tracker, report, code = time.monotonic(), None, None, 1 + try: + write_run_manifest(metrics_dir=metrics, run_id=run_id, timestamp=timestamp, + mode="link", source_label=rdf.name, source_paths=[rdf], out_root=root, + options={"link": [m.id for m in manifests], **{k: str(v) if isinstance(v, Path) else v for k, v in run_options(args).items()}}) + tracker = RunTracker(metrics / "logs" / "progress.log") + report = run_stage(rdf, manifests, output, metrics_dir=metrics, tracker=tracker, **run_options(args)) + print(f"Wrote {output} ({report['link_triples']} links); metrics: {metrics}") + code = 0 + except (ValueError, OSError) as exc: + print(f"error: {exc}", file=sys.stderr) + except KeyboardInterrupt: + print("Linking interrupted; no partial side-graph published", file=sys.stderr) + code = 130 + finally: + if tracker: + tracker.close() + write_run_summary(metrics_dir=metrics, run_id=run_id, timestamp=timestamp, mode="link", + exit_code=code, elapsed_seconds=time.monotonic() - started, + total_triples=report["triples"] if report else None) + return code + + +def build_parser(): + parser = argparse.ArgumentParser(prog="vcf-rdfizer-link", description=__doc__) + commands = parser.add_subparsers(dest="command", required=True) + listing = commands.add_parser("list", help="List installed IDs, versions, tiers, references and licensing") + listing.add_argument("--linker-path", action="append", default=[]) + listing.add_argument("--json", action="store_true") + commands.add_parser("keys", help="Describe the supported join-key contract") + init = commands.add_parser("init", help="Copy an annotated example into a new linker directory") + init.add_argument("-o", "--output", required=True) + init.add_argument("--example", default="rsid-dbsnp", choices=["rsid-dbsnp", "gene-demo", "rsid-ensembl"]) + check = commands.add_parser("check", help="Parse a manifest and verify its reference (no resolver execution)") + check.add_argument("directory") + check.add_argument("--json", action="store_true") + add_link_arguments(check) + dry = commands.add_parser("dry-run", help="Preview first N VCF records; no network or persistent writes") + dry.add_argument("directory") + dry.add_argument("-i", "--input", required=True) + dry.add_argument("--limit", type=int, default=100) + add_link_arguments(dry) + run = commands.add_parser("run", help="Write a side-graph from VCF or an existing RDF aggregate") + inputs = run.add_mutually_exclusive_group(required=True) + inputs.add_argument("-i", "--input", help="VCF to link using the default subject templates") + inputs.add_argument("--rdf", help="Existing .nt/.nt.gz; subjects are read from the graph") + run.add_argument("-o", "--output", required=True, help="New .links.nt output file") + add_link_arguments(run) + return parser + + +def main(argv=None): + args = build_parser().parse_args(argv) + try: + if args.command == "keys": + print("TokenJoin: field ID (splitOn ';') or INFO/ (splitOn ','); accept uses full regex matches; {TOKEN} is percent-encoded.") + print("IntervalJoin: CHROM exact match; [POS, POS + len(REF) - 1], 1-based closed; explicit DNA alleles only. GFF3 attribute -> {ID}.") + print("Subjects: vcfl:VariantCall or vcfl:VCFRecord. AlleleJoin is not implemented.") + elif args.command == "list": + manifests = discover(args.linker_path) + if args.json: + print(json.dumps([asdict(m) for m in manifests.values()], default=str, indent=2)) + else: + for m in manifests.values(): + print(f"{m.id} {m.version} — tier {m.tier}: {m.title}") + print(f" License: {m.license}; terms: {m.terms_of_use or 'unspecified'}") + if m.reference: + print(f" Reference: {m.reference.url}; {m.reference.assembly}; sha256:{m.reference.sha256}") + elif args.command == "init": + output = Path(args.output).expanduser() + if output.exists(): + raise ValueError(f"Refusing to overwrite {output}") + source = discover()[args.example].directory + shutil.copytree(source, output, ignore=shutil.ignore_patterns("__pycache__", "*.pyc")) + print(f"Wrote {output}. Change its id before adding it to a search path, then run check.") + elif args.command == "check": + m = load_manifest(Path(args.directory)) + if m.reference: + if args.assembly: + check_assembly(args.assembly, m.reference.assembly) + path = acquire_reference(m.reference, Path(args.links_cache), offline=args.offline or args.links_cache_only) + IntervalIndex(path, m.reference) + print(json.dumps({"ok": True, "id": m.id, "tier": m.tier, "assembly": m.reference.assembly if m.reference else None, + "note": "Input assembly is checked at run time; resolver code was not executed"}, indent=2)) + elif args.command == "dry-run": + if args.limit < 1: + raise ValueError("--limit must be positive") + report = run_linkers(read_vcf(Path(args.input).expanduser(), args.limit), [load_manifest(Path(args.directory))], None, dry_run=True, **run_options(args)) + print(json.dumps(report, indent=2)) + else: + manifests = selected_linkers(args) + output = Path(args.output).expanduser() + if not output.name.endswith(".nt"): + raise ValueError("Link output must end in .nt") + if output.with_suffix(".json").exists(): + raise ValueError(f"Refusing to overwrite existing report: {output.with_suffix('.json')}") + records = read_rdf(Path(args.rdf).expanduser()) if args.rdf else read_vcf(Path(args.input).expanduser()) + report = run_linkers(records, manifests, output, **run_options(args)) + from vcf_rdfizer_linking.session import atomic_bytes + atomic_bytes(output.with_suffix(".json"), (json.dumps(report, indent=2) + "\n").encode()) + print(f"Wrote {output} ({report['link_triples']} links)") + return 0 + except (ValueError, OSError) as exc: + if getattr(args, "json", False): + print(json.dumps({"ok": False, "errors": [str(exc)]})) + else: + print(f"error: {exc}", file=sys.stderr) + return 1 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/vcf_rdfizer_linking/__init__.py b/vcf_rdfizer_linking/__init__.py new file mode 100644 index 0000000..7689715 --- /dev/null +++ b/vcf_rdfizer_linking/__init__.py @@ -0,0 +1,30 @@ +"""Public, deliberately narrow protocol for data-linking plug-ins. + +Resolvers receive deduplicated keys and return objects; the runner owns subject +identity, predicates, serialization, batching, and network policy. +""" + +from dataclasses import dataclass +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from .session import CachedSession + + +@dataclass(frozen=True, order=True) +class LinkKey: + token: str = "" + chrom: str = "" + start: int = 0 + end: int = 0 + + +@dataclass(frozen=True) +class Link: + key: LinkKey + object: str + + +@dataclass(frozen=True) +class LinkerContext: + session: "CachedSession" diff --git a/vcf_rdfizer_linking/inputs.py b/vcf_rdfizer_linking/inputs.py new file mode 100644 index 0000000..df9153b --- /dev/null +++ b/vcf_rdfizer_linking/inputs.py @@ -0,0 +1,151 @@ +"""Join-key inputs, preserving the wrapper's file/record/call identities.""" + +import csv +from dataclasses import dataclass +import gzip +from pathlib import Path +import sqlite3 +import tempfile + +from rdflib import Literal, RDF, URIRef +from rdflib.plugins.parsers.ntriples import W3CNTriplesParser + +from .manifest import VCFR + + +@dataclass(frozen=True) +class Source: + source: str + reference: str + + +@dataclass(frozen=True) +class Record: + source: str + record: str + call: str + reference: str + chrom: str + pos: str + ref: str + alt: str + id: str + info: str + + +def open_text(path): + return gzip.open(path, "rt", encoding="utf-8") if path.name.endswith(".gz") else path.open(encoding="utf-8") + + +def make_record(source_file, row_id, reference, fields): + from vcf_rdfizer import _rml_uri_component + + source = "file://" + _rml_uri_component(source_file) + row = _rml_uri_component(str(row_id)) + return Record(source, f"{source}#record/{row}", f"{source}#call/{row}", reference, + *(fields.get(k, ".") for k in ("CHROM", "POS", "REF", "ALT", "ID", "INFO"))) + + +def read_vcf(path: Path, limit=None): + reference, row, header = "", 0, False + with open_text(path) as handle: + for line in handle: + if line.startswith("##reference="): + value = line.strip().split("=", 1)[1] + if reference and value != reference: + raise ValueError("VCF declares conflicting ##reference values") + reference = value + if line.startswith("#CHROM\t"): + header = True + if line.startswith("#") or not line.strip(): + continue + if not header: + raise ValueError("VCF is missing the #CHROM header") + if limit is not None and row >= limit: + break + if row == 0: + from vcf_rdfizer import _rml_uri_component + yield Source("file://" + _rml_uri_component(path.name), reference) + fields = line.rstrip("\r\n").split("\t") + row += 1 + if len(fields) < 8: + raise ValueError(f"VCF record {row} has fewer than eight columns") + yield make_record(path.name, row, reference, + dict(zip(("CHROM", "POS", "ID", "REF", "ALT", "QUAL", "FILTER", "INFO"), fields))) + if not header: + raise ValueError("VCF is missing the #CHROM header") + if row == 0: + from vcf_rdfizer import _rml_uri_component + yield Source("file://" + _rml_uri_component(path.name), reference) + + +def read_tsv(records: Path, metadata: Path): + with metadata.open(encoding="utf-8", newline="") as handle: + references = {r["SOURCE_FILE"]: r["REFERENCE_GENOME"] for r in csv.DictReader(handle, delimiter="\t")} + from vcf_rdfizer import _rml_uri_component + for source, reference in references.items(): + yield Source("file://" + _rml_uri_component(source), reference) + with records.open(encoding="utf-8", newline="") as handle: + for row in csv.DictReader(handle, delimiter="\t"): + yield make_record(row["SOURCE_FILE"], row["ROW_ID"], references[row["SOURCE_FILE"]], row) + + +def read_rdf(path: Path): + """Stream unordered N-Triples into a disk-backed index of just join fields. + + Follow hasRecord/hasCall edges rather than guessing a subject from its IRI. + Genotype triples are parsed but never retained. RDFLib owns term decoding. + """ + if not path.is_file() or not path.name.endswith((".nt", ".nt.gz")): + raise ValueError("Link input must be an existing .nt or .nt.gz file") + keep = {str(VCFR[name]) for name in ("hasRecord", "hasCall", "referenceGenome", "chrom", "pos", "ref", "alt", "recordId", "infoRaw")} + types = {VCFR.VCFFile, VCFR.VCFRecord, VCFR.VariantCall} + with tempfile.TemporaryDirectory(prefix="vcfr-link-input-") as work: + db = sqlite3.connect(str(Path(work) / "input.sqlite")) + try: + db.execute("CREATE TABLE terms (s TEXT, p TEXT, o TEXT, iri INTEGER, PRIMARY KEY(s,p,o,iri))") + db.execute("CREATE INDEX predicates ON terms(p,s)") + + class Sink: + def triple(self, s, p, o): + if str(p) not in keep and not (p == RDF.type and o in types): + return + if not isinstance(s, URIRef) or not isinstance(o, (URIRef, Literal)): + raise ValueError("Linking requires IRI subjects and IRI/literal join fields") + db.execute("INSERT OR IGNORE INTO terms VALUES (?,?,?,?)", (str(s), str(p), str(o), isinstance(o, URIRef))) + + with open_text(path) as handle: + W3CNTriplesParser(sink=Sink()).parse(handle) + db.commit() + + def one(subject, predicate, *, iri=False, required=True): + rows = db.execute("SELECT o,iri FROM terms WHERE s=? AND p=?", (subject, str(predicate))).fetchall() + if not rows and not required: + return "." + if len(rows) != 1 or bool(rows[0][1]) != iri: + raise ValueError(f"Expected one {'IRI' if iri else 'literal'} {predicate} on {subject}") + return rows[0][0] + + sources = db.execute("SELECT DISTINCT s FROM terms WHERE p=?", (str(VCFR.hasRecord),)).fetchall() + if not sources: + # A typed empty VCF graph is a valid zero-link input. + sources = db.execute("SELECT s FROM terms WHERE p=? AND o=?", (str(RDF.type), str(VCFR.VCFFile))).fetchall() + if not sources: + raise ValueError("No VCFFile/hasRecord edges found; the RDF must retain the VCF-RDFizer vocabulary") + duplicate_owner = db.execute("SELECT o FROM terms WHERE p=? GROUP BY o HAVING COUNT(*) > 1 LIMIT 1", (str(VCFR.hasRecord),)).fetchone() + if duplicate_owner: + raise ValueError("Each hasRecord object must belong to one source file") + for (source,) in sources: + reference = one(source, VCFR.referenceGenome, required=False) + yield Source(source, reference) + for record, iri in db.execute("SELECT o,iri FROM terms WHERE s=? AND p=?", (source, str(VCFR.hasRecord))): + if not iri: + raise ValueError("Each hasRecord object must be an IRI belonging to one source file") + call = one(record, VCFR.hasCall, iri=True) + if not db.execute("SELECT 1 FROM terms WHERE s=? LIMIT 1", (call,)).fetchone(): + raise ValueError(f"Call subject does not exist in the base graph: {call}") + yield Record(source, record, call, reference, + *(one(record, VCFR[k], required=False) for k in ("chrom", "pos", "ref", "alt", "recordId")), + one(call, VCFR.infoRaw, required=False)) + finally: + db.close() diff --git a/vcf_rdfizer_linking/manifest.py b/vcf_rdfizer_linking/manifest.py new file mode 100644 index 0000000..823c952 --- /dev/null +++ b/vcf_rdfizer_linking/manifest.py @@ -0,0 +1,239 @@ +"""Turtle manifests and deterministic directory/entry-point discovery.""" + +import importlib.metadata +import math +import os +from dataclasses import dataclass +from pathlib import Path +import re +from string import Formatter +from urllib.parse import quote, urlsplit + +from rdflib import Graph, Literal, Namespace, RDF, URIRef + +VCFL = Namespace("https://w3id.org/vcf-rdfizer/linking#") +# The converter's own linking vocabulary keeps its namespace; only the +# conversion target moved to VCF Core. +VCFC = Namespace("https://w3id.org/vcf-core/vocab#") +#: Retained alias: the linking stage reads back converted RDF, so it must +#: use whatever namespace the emitters wrote. +VCFR = VCFC +SAFE_NAME = re.compile(r"[A-Za-z0-9][A-Za-z0-9._-]*\Z") + + +def absolute_iri(value: str) -> str: + """Reject terms that cannot safely appear inside N-Triples angle brackets.""" + if (not value or not re.match(r"^[A-Za-z][A-Za-z0-9+.-]*:", value) + or re.search(r'[\x00-\x20<>"{}|^`\\\x7f]', value)): + raise ValueError(f"Not an absolute, N-Triples-safe IRI: {value!r}") + parts = urlsplit(value) + if parts.scheme in {"http", "https"} and not parts.hostname: + raise ValueError(f"IRI has no host: {value!r}") + return value + + +@dataclass(frozen=True) +class Reference: + url: str + sha256: str + assembly: str + feature_type: str + id_attribute: str + + +@dataclass(frozen=True) +class Manifest: + directory: Path + id: str + version: str + title: str + license: str + terms_of_use: str + tier: int + strategy: str + field: str + split_on: str + accept: str + subject: str + predicate: str + object_template: str + reference: Reference | None + endpoint: str + requests_per_second: float + max_requests: int + batch_size: int + contact_email: str + + +def load_manifest(directory: Path) -> Manifest: + directory = directory.expanduser().resolve() + if directory.is_file(): + directory = directory.parent + graph = Graph() + try: + graph.parse(directory / "linker.ttl", format="turtle") + except Exception as exc: + raise ValueError(f"Cannot parse {directory / 'linker.ttl'}: {exc}") from exc + roots = list(graph.subjects(RDF.type, VCFL.Linker)) + if len(roots) != 1: + raise ValueError("Manifest must declare exactly one vcfl:Linker") + root = roots[0] + + allowed = {"id", "version", "title", "license", "termsOfUse", "join", "emit", "reference", + "field", "splitOn", "accept", "subject", "predicate", "objectTemplate", "format", + "url", "sha256", "assembly", "featureType", "idAttribute", "endpoint", + "maxRequestsPerSecond", "maxRequestsPerRun", "batchSize", "contactEmail"} + for predicate in graph.predicates(): + if str(predicate).startswith(str(VCFL)) and str(predicate)[len(str(VCFL)):] not in allowed: + raise ValueError(f"Unsupported manifest property: {predicate}") + + def one(node, name, default=None, iri=False, resource=False, url=False): + values = list(graph.objects(node, VCFL[name])) + if len(values) > 1 or (not values and default is None): + raise ValueError(f"Expected one vcfl:{name}") + if not values: + return default + value = values[0] + if url: + if not isinstance(value, (URIRef, Literal)): + raise ValueError(f"vcfl:{name} must be a URL IRI or string") + return absolute_iri(str(value)) + if resource: + if isinstance(value, Literal): + raise ValueError(f"vcfl:{name} must be a resource") + return value + if not isinstance(value, URIRef if iri else Literal): + raise ValueError(f"vcfl:{name} must be {'an IRI' if iri else 'a literal'}") + return absolute_iri(str(value)) if iri else str(value) + + linker_id = one(root, "id") + version = one(root, "version") + if not SAFE_NAME.fullmatch(linker_id) or not SAFE_NAME.fullmatch(version): + raise ValueError("Linker id/version must be safe names (letters, digits, . _ -)") + join = one(root, "join", resource=True) + types = set(graph.objects(join, RDF.type)) + if types == {VCFL.TokenJoin}: + strategy = "token" + elif types == {VCFL.IntervalJoin}: + strategy = "interval" + else: + raise ValueError("Supported joins: TokenJoin and IntervalJoin; allele normalization is not implemented") + emit = one(root, "emit", resource=True) + subject = one(emit, "subject", iri=True) + if subject not in {str(VCFL.VariantCall), str(VCFL.VCFRecord)}: + raise ValueError("vcfl:subject must be vcfl:VariantCall or vcfl:VCFRecord") + field = one(join, "field", "ID") + if field != "ID" and not re.fullmatch(r"INFO/[A-Za-z_][A-Za-z0-9_.]*", field): + raise ValueError("Token field must be ID or INFO/") + split_on = one(join, "splitOn", ";" if field == "ID" else ",") + if not split_on: + raise ValueError("vcfl:splitOn cannot be empty") + accept = one(join, "accept", ".+") + try: + re.compile(accept) + except re.error as exc: + raise ValueError(f"Invalid vcfl:accept regular expression: {exc}") from exc + + reference_node = one(root, "reference", "", resource=True) + reference = None + if reference_node: + if one(reference_node, "format", iri=True) != str(VCFL.GFF3): + raise ValueError("Only vcfl:GFF3 reference bundles are supported") + digest = one(reference_node, "sha256") + if not re.fullmatch(r"[0-9a-f]{64}", digest): + raise ValueError("vcfl:sha256 must contain 64 lowercase hexadecimal digits") + assembly = one(reference_node, "assembly") + if not assembly: + raise ValueError("A reference must declare a nonempty assembly") + reference = Reference(one(reference_node, "url", url=True), digest, assembly, + one(join, "featureType", "gene"), one(join, "idAttribute", "ID")) + resolver = directory / "resolver.py" + tier = 3 if resolver.is_file() else 2 if reference else 1 + if strategy == "interval" and (reference is None or tier == 3): + raise ValueError("IntervalJoin requires a GFF3 reference and no resolver.py") + if reference and strategy != "interval": + raise ValueError("Reference bundles currently require IntervalJoin") + template = one(emit, "objectTemplate", "") + if tier != 3: + allowed = "TOKEN" if strategy == "token" else "ID" + try: + fields = list(Formatter().parse(template)) + variables = [name for _, name, _, _ in fields if name is not None] + if variables != [allowed] or any(spec or conv for _, _, spec, conv in fields): + raise ValueError(f"Template must contain exactly one {{{allowed}}} placeholder") + absolute_iri(template.format(**{allowed: "example"})) + except (KeyError, IndexError, ValueError) as exc: + raise ValueError(f"Invalid vcfl:objectTemplate: {exc}") from exc + elif template: + raise ValueError("Tier 3 objects come from the resolver; omit objectTemplate") + + endpoint, rps, max_requests, batch_size, contact = "", 0.0, 0, 1000, "" + if tier == 3: + endpoint = one(root, "endpoint", iri=True) + parts = urlsplit(endpoint) + if parts.scheme != "https" or parts.username or parts.password or parts.fragment: + raise ValueError("vcfl:endpoint must be an HTTPS URL without credentials or fragment") + try: + rps = float(one(root, "maxRequestsPerSecond")) + max_requests = int(one(root, "maxRequestsPerRun")) + batch_size = int(one(root, "batchSize")) + except ValueError as exc: + raise ValueError("Invalid network budget: expected positive numbers") from exc + if not math.isfinite(rps) or rps <= 0 or max_requests <= 0 or not 1 <= batch_size <= 1000: + raise ValueError("Network budgets must be positive; batchSize must be 1..1000") + contact = one(root, "contactEmail") + if not re.fullmatch(r"[^\s<>@]+@[^\s<>@]+\.[^\s<>@]+", contact): + raise ValueError("vcfl:contactEmail must be an email address") + return Manifest(directory, linker_id, version, one(root, "title"), + one(root, "license", "unspecified"), one(root, "termsOfUse", "", iri=True), + tier, strategy, field, split_on, accept, subject, + one(emit, "predicate", iri=True), template, reference, endpoint, + rps, max_requests, batch_size, contact) + + +def template_object(manifest: Manifest, value: str) -> str: + name = "TOKEN" if manifest.strategy == "token" else "ID" + return absolute_iri(manifest.object_template.format(**{name: quote(value, safe="")})) + + +def discover(search_paths=()) -> dict[str, Manifest]: + """Reject ambiguous IDs; never silently replace an installed linker.""" + import vcf_rdfizer_data.linkers + + roots = [Path(vcf_rdfizer_data.linkers.__file__).parent] + roots.extend(Path(p).expanduser() for p in search_paths) + roots.extend(Path(p).expanduser() for p in os.environ.get("VCF_RDFIZER_LINKER_PATH", "").split(os.pathsep) if p) + directories = set() + for root in roots: + if not root.is_dir(): + raise ValueError(f"Linker search path is not a directory: {root}") + if (root / "linker.ttl").is_file(): + directories.add(root.resolve()) + else: + directories.update(p.parent.resolve() for p in root.glob("*/linker.ttl")) + for entry in importlib.metadata.entry_points(group="vcf_rdfizer.linkers"): + # An entry point exports a zero-argument function returning a directory. + directory = Path(entry.load()()).resolve() + if not (directory / "linker.ttl").is_file(): + raise ValueError(f"Entry point {entry.name} did not return a linker directory") + directories.add(directory) + found = {} + for directory in sorted(directories): + manifest = load_manifest(directory) + if manifest.id in found: + raise ValueError(f"Ambiguous linker id {manifest.id!r}: {found[manifest.id].directory} and {directory}") + found[manifest.id] = manifest + return found + + +def select(raw: str, search_paths=()) -> list[Manifest]: + found = discover(search_paths) + names = raw.split(",") + if not raw or any(not n.strip() for n in names): + raise ValueError("--link requires comma-separated linker IDs") + selected = [] + for name in dict.fromkeys(n.strip() for n in names): + if name not in found: + raise ValueError(f"Unknown linker {name!r}; run vcf-rdfizer-link list") + selected.append(found[name]) + return selected diff --git a/vcf_rdfizer_linking/reference.py b/vcf_rdfizer_linking/reference.py new file mode 100644 index 0000000..c84efba --- /dev/null +++ b/vcf_rdfizer_linking/reference.py @@ -0,0 +1,146 @@ +"""Digest-pinned GFF3 acquisition and interval lookup.""" + +from bisect import bisect_left +from collections import defaultdict +import gzip +import hashlib +from pathlib import Path +import re +import tempfile +from urllib.parse import unquote, urlsplit +from urllib.request import build_opener, Request, url2pathname + +from .session import NoRedirects + + +def digest_file(path): + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1024 * 1024), b""): + digest.update(chunk) + return digest.hexdigest() + + +def check_assembly(reference, declared, override=None): + """An explicit assembly can fill missing metadata, never override a mismatch.""" + aliases = {"hg19": "GRCh37", "hg38": "GRCh38"} + + def identify(value): + value = value.strip().strip('"') + if value == declared: + return declared + names = set(re.findall(r"(? 1: + raise ValueError(f"Ambiguous reference assembly: {value}") + return next(iter(names), None) + + expected = aliases.get(declared, declared) + observed = identify(reference) + explicit = identify(override) if override else None + if observed and aliases.get(observed, observed) != expected: + raise ValueError(f"Assembly mismatch: input is {observed}; reference bundle is {declared}") + if override and explicit != expected: + raise ValueError(f"Assembly mismatch: --assembly {override}; reference bundle is {declared}") + if not observed and not explicit: + raise ValueError(f"Cannot establish assembly from {reference!r}; supply --assembly {declared} after checking the input") + + +def acquire_reference(reference, cache_dir, *, offline=False, dry_run=False, stats=None): + """Hash the stored bytes (compressed bytes for .gz), including on cache hits.""" + parts = urlsplit(reference.url) + target = cache_dir / "references" / reference.sha256 + if target.is_file(): + if digest_file(target) != reference.sha256: + raise ValueError(f"Reference cache digest mismatch: {target}") + if stats is not None: + stats["cache_hits"] += 1 + return target + if parts.scheme == "file": + if parts.netloc not in {"", "localhost"}: + raise ValueError("Reference file URL must be local") + source = Path(url2pathname(parts.path)) + if digest_file(source) != reference.sha256: + raise ValueError(f"Reference digest mismatch: {source}") + # Local bundles already are offline references. No copy on dry-run. + if dry_run: + return source + elif parts.scheme != "https": + raise ValueError("References must use file: or https: URLs") + elif offline or dry_run: + raise ValueError(f"Reference cache miss (network disabled): {reference.sha256}") + target.parent.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile(dir=target.parent, delete=False) as output: + temporary = Path(output.name) + try: + if parts.scheme == "file": + input_handle = source.open("rb") + else: + if stats is not None: + stats["requests"] += 1 + input_handle = build_opener(NoRedirects()).open(Request(reference.url, headers={"User-Agent": "VCF-RDFizer/reference-fetch"}), timeout=60) + if stats is not None: + stats["final_service_status"] = input_handle.code + with input_handle: + for chunk in iter(lambda: input_handle.read(1024 * 1024), b""): + output.write(chunk) + if parts.scheme != "file" and stats is not None: + stats["bytes_transferred"] += len(chunk) + output.close() + if digest_file(temporary) != reference.sha256: + raise ValueError(f"Reference digest mismatch: {reference.url}") + temporary.replace(target) + finally: + temporary.unlink(missing_ok=True) + return target + + +class IntervalIndex: + """Sorted starts plus prefix-max ends: handles nested/overlapping features.""" + + def __init__(self, path, reference): + features = defaultdict(list) + with path.open("rb") as raw: + compressed = raw.read(2) == b"\x1f\x8b" + opener = gzip.open if compressed else open + with opener(path, "rt", encoding="utf-8") as handle: + for number, line in enumerate(handle, 1): + if line.startswith("##FASTA"): + break + if line.startswith("#") or not line.strip(): + continue + columns = line.rstrip("\r\n").split("\t") + if len(columns) != 9: + raise ValueError(f"GFF3 line {number}: expected nine columns") + if columns[2] != reference.feature_type: + continue + try: + start, end = int(columns[3]), int(columns[4]) + except ValueError as exc: + raise ValueError(f"GFF3 line {number}: invalid coordinates") from exc + if start < 1 or end < start: + raise ValueError(f"GFF3 line {number}: invalid interval") + attributes = dict(item.split("=", 1) for item in columns[8].split(";") if "=" in item) + identifier = unquote(attributes.get(reference.id_attribute, "")) + if not identifier: + raise ValueError(f"GFF3 line {number}: missing {reference.id_attribute}") + features[columns[0]].append((start, end, identifier)) + self.chromosomes = {} + for chrom, rows in features.items(): + rows.sort() + maximum, ends = 0, [] + for _, end, _ in rows: + maximum = max(maximum, end) + ends.append(maximum) + self.chromosomes[chrom] = (rows, [r[0] for r in rows], ends) + if not features: + raise ValueError(f"GFF3 contains no {reference.feature_type!r} features") + + def overlaps(self, key): + rows, starts, max_ends = self.chromosomes.get(key.chrom, ([], [], [])) + index = bisect_left(starts, key.end + 1) - 1 + while index >= 0 and max_ends[index] >= key.start: + start, end, identifier = rows[index] + if end >= key.start: + yield identifier + index -= 1 diff --git a/vcf_rdfizer_linking/runner.py b/vcf_rdfizer_linking/runner.py new file mode 100644 index 0000000..011c600 --- /dev/null +++ b/vcf_rdfizer_linking/runner.py @@ -0,0 +1,271 @@ +"""One linking implementation for previews, full conversion, and existing RDF.""" + +from dataclasses import asdict +from datetime import datetime, timezone +import importlib.util +import hashlib +from itertools import islice +import json +import os +from pathlib import Path +import re +import sqlite3 +import tempfile +import time + +from rdflib import Literal, RDF, URIRef, XSD + +from . import Link, LinkKey, LinkerContext +from .inputs import Source +from .manifest import VCFL, absolute_iri, template_object +from .reference import IntervalIndex, acquire_reference, check_assembly +from .session import CachedSession, NetworkPolicy, atomic_bytes + +DEFAULT_CACHE = Path.home() / ".cache" / "vcf-rdfizer" / "linkers" +PROV_TIME = "http://www.w3.org/ns/prov#generatedAtTime" + + +class LinkRunError(ValueError): + def __init__(self, message, report): + super().__init__(message) + self.report = report + + +def keys_for(record, manifest): + if manifest.strategy == "token": + value = record.id + if manifest.field.startswith("INFO/"): + wanted = manifest.field.split("/", 1)[1] + values = [part.split("=", 1)[1] for part in record.info.split(";") + if "=" in part and part.split("=", 1)[0] == wanted] + if len(values) > 1: + raise ValueError(f"Duplicate INFO key {wanted} on {record.record}") + value = values[0] if values else "." + return [LinkKey(token=token) for token in dict.fromkeys(value.split(manifest.split_on)) + if token and token != "." and re.fullmatch(manifest.accept, token)] + # POS and GFF3 intervals are both 1-based closed. Explicit REF spans only; + # END, symbolic alleles and breakends require a different coordinate policy. + if not re.fullmatch(r"[ACGTNacgtn]+", record.ref) or any( + not re.fullmatch(r"[ACGTNacgtn]+|\.", alt) for alt in record.alt.split(",")): + return [] + try: + start = int(record.pos) + except ValueError as exc: + raise ValueError(f"Invalid POS on {record.record}: {record.pos!r}") from exc + if start < 1 or record.chrom in {"", "."}: + raise ValueError(f"Invalid interval key on {record.record}") + return [LinkKey(chrom=record.chrom, start=start, end=start + len(record.ref) - 1)] + + +def load_resolver(manifest): + path = manifest.directory / "resolver.py" + spec = importlib.util.spec_from_file_location(f"vcfr_linker_{manifest.id.replace('-', '_')}", path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + if not callable(getattr(module, "resolve", None)): + raise ValueError(f"{path} must define resolve(batch, ctx)") + return module.resolve + + +def triple(subject, predicate, obj): + return f"<{absolute_iri(subject)}> <{absolute_iri(str(predicate))}> {obj} .\n" + + +def literal(value): + from vcf_rdfizer import _ntriples_literal + return _ntriples_literal(str(value)) + + +def run_linkers(records, manifests, output: Path | None, *, cache_dir=DEFAULT_CACHE, + offline=False, assembly=None, dry_run=False, policy=None, session_factory=CachedSession, + progress=None): + """Deduplicate all keys on disk before any resolution; publish only on success. + + Dry-run writes no persistent artifacts, imports no resolver code, and never + fetches a reference. It resolves local tiers and reports Tier 3 batch plans. + """ + started = time.monotonic() + report = {"status": "running", "records": 0, "triples": 0, "appended_bytes": 0, + "output": str(output) if output else None, "dry_run": dry_run, "linkers": [], "preview": []} + if not manifests: + raise ValueError("Select at least one linker") + if not dry_run and output is None: + raise ValueError("An output path is required") + if output and not output.name.endswith(".nt"): + raise ValueError("Link output must end in .nt") + if output and output.exists(): + raise ValueError(f"Refusing to overwrite existing linkset: {output}") + policy = policy or NetworkPolicy(manifests) + cache_dir = Path(cache_dir).expanduser() + sources, stats_by_id = {}, {} + for manifest in manifests: + stats = {"id": manifest.id, "version": manifest.version, "tier": manifest.tier, + "manifest_sha256": hashlib.sha256((manifest.directory / "linker.ttl").read_bytes()).hexdigest(), + "reference_digest": manifest.reference.sha256 if manifest.reference else None, + "assembly": manifest.reference.assembly if manifest.reference else None, + "unique_keys": 0, "skipped_records": 0, "links": 0, "requests": 0, + "cache_hits": 0, "bytes_transferred": 0, "final_service_status": None, + "status": "pending", "wall_seconds": 0} + if manifest.tier == 3: + stats["resolver_sha256"] = hashlib.sha256((manifest.directory / "resolver.py").read_bytes()).hexdigest() + stats_by_id[manifest.id] = stats + report["linkers"].append(stats) + current = None + try: + with tempfile.TemporaryDirectory(prefix="vcfr-link-keys-") as work: + db = sqlite3.connect(str(Path(work) / "joins.sqlite")) + try: + db.execute("CREATE TABLE keys (linker TEXT, key TEXT, subject TEXT, source TEXT, PRIMARY KEY(linker,key,subject,source))") + db.execute("CREATE TABLE links (linker TEXT, source TEXT, subject TEXT, predicate TEXT, object TEXT, PRIMARY KEY(linker,source,subject,predicate,object))") + # Finish key extraction and assembly checks for every linker first. + for record in records: + absolute_iri(record.source) + if record.source not in sources: + for manifest in manifests: + if manifest.reference: + check_assembly(record.reference, manifest.reference.assembly, assembly) + sources[record.source] = record.reference + elif sources[record.source] != record.reference: + raise ValueError(f"Conflicting reference metadata for {record.source}") + if isinstance(record, Source): + continue + report["records"] += 1 + if progress and report["records"] % 10_000 == 0: + progress(f"Indexed {report['records']} records for linking") + for manifest in manifests: + keys = keys_for(record, manifest) + if not keys: + stats_by_id[manifest.id]["skipped_records"] += 1 + subject = record.call if manifest.subject == str(VCFL.VariantCall) else record.record + absolute_iri(subject) + db.executemany("INSERT OR IGNORE INTO keys VALUES (?,?,?,?)", [ + (manifest.id, json.dumps(asdict(key), sort_keys=True), subject, record.source) for key in keys]) + db.commit() + for manifest in manifests: + current = stats_by_id[manifest.id] + linker_start = time.monotonic() + current["status"] = "running" + current["unique_keys"] = db.execute("SELECT COUNT(DISTINCT key) FROM keys WHERE linker=?", (manifest.id,)).fetchone()[0] + if progress: + progress(f"Linking {manifest.id}: {current['unique_keys']} unique keys") + reference_index, session, resolver = None, None, None + try: + if manifest.tier == 2: + path = acquire_reference(manifest.reference, cache_dir, offline=offline, dry_run=dry_run, stats=current) + reference_index = IntervalIndex(path, manifest.reference) + if manifest.tier == 3: + current["batches"] = (current["unique_keys"] + manifest.batch_size - 1) // manifest.batch_size + current["max_requests_per_run"] = manifest.max_requests + if dry_run: + current["status"] = "planned" + continue + session = session_factory(manifest, cache_dir, policy, offline=offline) + resolver = load_resolver(manifest) + rows = db.execute("SELECT DISTINCT key FROM keys WHERE linker=? ORDER BY key", (manifest.id,)) + while True: + raw_keys = [r[0] for r in islice(rows, manifest.batch_size)] + if not raw_keys: + break + batch = [LinkKey(**json.loads(key)) for key in raw_keys] + encoded = dict(zip(batch, raw_keys)) + if manifest.tier == 1: + links = (Link(key, template_object(manifest, key.token)) for key in batch) + elif manifest.tier == 2: + links = (Link(key, template_object(manifest, identifier)) for key in batch for identifier in reference_index.overlaps(key)) + else: + links = resolver(tuple(batch), LinkerContext(session)) + for link in links: + if not isinstance(link, Link) or link.key not in encoded: + raise ValueError(f"{manifest.id}: resolver returned a link for an undispatched key") + obj = absolute_iri(link.object) + db.execute("INSERT OR IGNORE INTO links SELECT linker,source,subject,?,? FROM keys WHERE linker=? AND key=?", + (manifest.predicate, obj, manifest.id, encoded[link.key])) + current["links"] = db.execute("SELECT COUNT(*) FROM links WHERE linker=?", (manifest.id,)).fetchone()[0] + current["status"] = "success" + except BaseException: + current["status"] = "failed" + raise + finally: + if session: + current.update(session.stats) + current["wall_seconds"] = round(time.monotonic() - linker_start, 6) + db.commit() + report["preview"] = [triple(s, p, f"<{o}>").rstrip() for s, p, o in db.execute("SELECT DISTINCT subject,predicate,object FROM links ORDER BY subject,predicate,object LIMIT 20")] + report["link_triples"] = db.execute("SELECT COUNT(*) FROM (SELECT DISTINCT subject,predicate,object FROM links)").fetchone()[0] + if not dry_run: + output.parent.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile(dir=output.parent, suffix=".nt", delete=False) as handle: + temporary = Path(handle.name) + try: + from vcf_rdfizer import _append_rdf_atomically + + def produce(emit): + for s, p, o in db.execute("SELECT DISTINCT subject,predicate,object FROM links ORDER BY subject,predicate,object"): + emit(triple(s, p, f"<{o}>")) + for source in sorted(sources): + for manifest in manifests: + node = source + "#linkset/" + manifest.id + count = db.execute("SELECT COUNT(*) FROM links WHERE linker=? AND source=?", (manifest.id, source)).fetchone()[0] + emit(triple(node, RDF.type, URIRef(VCFL.Linkset).n3())) + emit(triple(node, VCFL.producedBy, URIRef(f"https://w3id.org/vcf-rdfizer/linker/{manifest.id}/{manifest.version}").n3())) + emit(triple(node, VCFL.linkCount, Literal(count, datatype=XSD.integer).n3())) + emit(triple(node, VCFL.source, URIRef(source).n3())) + emit(triple(node, VCFL.manifestDigest, literal("sha256:" + stats_by_id[manifest.id]["manifest_sha256"]))) + if manifest.tier == 3: + emit(triple(node, VCFL.resolverDigest, literal("sha256:" + stats_by_id[manifest.id]["resolver_sha256"]))) + for digest in sorted({r["sha256"] for r in stats_by_id[manifest.id].get("responses", [])}): + emit(triple(node, VCFL.responseDigest, literal("sha256:" + digest))) + emit(triple(node, PROV_TIME, Literal(datetime.now(timezone.utc).isoformat(), datatype=XSD.dateTime).n3())) + if manifest.reference: + emit(triple(node, VCFL.referenceDigest, literal("sha256:" + manifest.reference.sha256))) + emit(triple(node, VCFL.assembly, literal(manifest.reference.assembly))) + _append_rdf_atomically(temporary, report, produce) + # Hard-link publication is atomic and fails if another run + # claimed this output after preflight; never overwrite it. + os.link(temporary, output) + finally: + temporary.unlink(missing_ok=True) + finally: + db.close() + report["status"] = "success" + return report + except Exception as exc: + report["status"] = "failed" + report["error"] = str(exc) + if current and current["status"] == "running": + current["status"] = "failed" + raise LinkRunError(str(exc), report) from exc + finally: + report["wall_seconds"] = round(time.monotonic() - started, 6) + + +def run_stage(rdf_path, manifests, output, *, metrics_dir, tracker=None, **options): + """Record success and failure using the wrapper's existing run manifest.""" + from vcf_rdfizer import (update_run_manifest, ProgressSession, + progress_event_path, progress_events_enabled) + from .inputs import read_rdf + + stage = metrics_dir / "stages" / "linking" / (output.stem + ".json") + event_path = progress_event_path(metrics_dir, "linking", output.stem) if progress_events_enabled() else None + try: + with ProgressSession(event_path, f"Linking: {output.stem}") as session: + def progress(message): + if tracker: + tracker.mark(message) + if event_path: + with event_path.open("a", encoding="utf-8") as handle: + handle.write(json.dumps({"stage": "linking", "phase": "working", "detail": message}) + "\n") + session.poll_events() + report = run_linkers(read_rdf(rdf_path), manifests, output, progress=progress, **options) + except LinkRunError as exc: + report = exc.report + raise + finally: + if "report" in locals(): + atomic_bytes(stage, (json.dumps(report, indent=2) + "\n").encode()) + # Preserve other inputs' linking reports in a directory conversion. + reports = {p.stem: json.loads(p.read_text()) for p in stage.parent.glob("*.json")} + update_run_manifest(metrics_dir, linking=reports) + if tracker: + tracker.mark(f"Linking {report['status']}: {output.name}") + return report diff --git a/vcf_rdfizer_linking/session.py b/vcf_rdfizer_linking/session.py new file mode 100644 index 0000000..4bc0285 --- /dev/null +++ b/vcf_rdfizer_linking/session.py @@ -0,0 +1,193 @@ +"""Runner-owned HTTP access: cache, budgets, host pacing, retries and accounting. + +Python resolvers are trusted code, not sandboxed code. These guarantees cover +requests made through this session, not arbitrary sockets opened by a plug-in. +""" + +import base64 +from datetime import datetime, timezone +from email.utils import parsedate_to_datetime +import hashlib +import importlib.metadata +import json +import json as json_module +import math +from pathlib import Path +import tempfile +import threading +import time +from urllib.error import HTTPError, URLError +from urllib.parse import urlencode, urlsplit +from urllib.request import HTTPRedirectHandler, Request, build_opener + +from .manifest import Manifest, absolute_iri + +MAX_RESPONSE_BYTES = 16 * 1024 * 1024 + + +def atomic_bytes(path: Path, data: bytes): + path.parent.mkdir(parents=True, exist_ok=True) + with tempfile.NamedTemporaryFile(dir=path.parent, delete=False) as handle: + temporary = Path(handle.name) + try: + handle.write(data) + handle.close() + temporary.replace(path) + finally: + temporary.unlink(missing_ok=True) + + +class NoRedirects(HTTPRedirectHandler): + def redirect_request(self, req, fp, code, msg, headers, newurl): + # Redirects otherwise evade host declarations and request accounting. + return None + + +class NetworkPolicy: + """A capacity-one bucket per host, and one in-flight request per run. + + All selected linkers are registered up front; a host gets the strictest + declared rate. Retry attempts consume the same per-linker run budget. + """ + + def __init__(self, manifests, *, clock=time.monotonic, sleep=time.sleep): + self.clock, self.sleep = clock, sleep + self.lock = threading.Lock() + self.rates, self.next_request, self.requests = {}, {}, {} + for manifest in manifests: + if manifest.tier == 3: + host = urlsplit(manifest.endpoint).hostname + self.rates[host] = min(self.rates.get(host, math.inf), manifest.requests_per_second) + + def issue(self, manifest, operation): + with self.lock: + count = self.requests.get(manifest.id, 0) + if count >= manifest.max_requests: + raise ValueError(f"{manifest.id}: maxRequestsPerRun={manifest.max_requests} exhausted") + host = urlsplit(manifest.endpoint).hostname + delay = self.next_request.get(host, 0) - self.clock() + if delay > 0: + self.sleep(delay) + self.next_request[host] = self.clock() + 1 / self.rates[host] + self.requests[manifest.id] = count + 1 + return operation() + + def defer(self, host, seconds): + with self.lock: + self.next_request[host] = max(self.next_request.get(host, 0), self.clock() + seconds) + + +class Response: + def __init__(self, status_code, headers, content): + self.status_code, self.headers, self.content = status_code, headers, content + + def json(self): + return json.loads(self.content) + + def raise_for_status(self): + if not 200 <= self.status_code < 300: + raise ValueError(f"Linker service returned HTTP {self.status_code}") + + +class CachedSession: + def __init__(self, manifest: Manifest, cache_dir: Path, policy: NetworkPolicy, + *, offline=False, transport=None): + self.manifest, self.cache_dir, self.policy = manifest, cache_dir, policy + self.offline = offline + self.transport = transport or build_opener(NoRedirects()).open + self.stats = {"requests": 0, "cache_hits": 0, "bytes_transferred": 0, + "final_service_status": None, "responses": []} + + def get(self, url, *, params=None): + if params: + url += ("&" if "?" in url else "?") + urlencode(sorted(params.items())) + return self._request("GET", url, None) + + def post(self, url, *, json): + body = json_module.dumps(json, sort_keys=True, separators=(",", ":")).encode() + return self._request("POST", url, body) + + def _request(self, method, url, body): + absolute_iri(url) + declared, requested = urlsplit(self.manifest.endpoint), urlsplit(url) + if (requested.scheme, requested.netloc) != (declared.scheme, declared.netloc) or requested.fragment: + raise ValueError(f"{self.manifest.id}: request outside declared endpoint origin") + if requested.path != declared.path and not requested.path.startswith(declared.path.rstrip("/") + "/"): + raise ValueError(f"{self.manifest.id}: request outside declared endpoint path") + signature = method.encode() + b"\n" + url.encode() + b"\n" + (body or b"") + request_hash = hashlib.sha256(signature).hexdigest() + path = self.cache_dir / "responses" / self.manifest.id / self.manifest.version / (request_hash + ".json") + if path.is_file(): + try: + cached = json.loads(path.read_text(encoding="utf-8")) + content = base64.b64decode(cached["body"], validate=True) + if cached["sha256"] != hashlib.sha256(content).hexdigest() or cached["request_hash"] != request_hash: + raise ValueError("digest mismatch") + response = Response(cached["status"], cached["headers"], content) + response.raise_for_status() + except (ValueError, KeyError, TypeError) as exc: + raise ValueError(f"Corrupt response cache: {path}: {exc}") from exc + self.stats["cache_hits"] += 1 + self._account_response(request_hash, cached) + return response + if self.offline: + raise ValueError(f"{self.manifest.id}: offline/cache-only response miss: {request_hash}") + if self.manifest.contact_email == "replace-me@example.org": + raise ValueError("Set --links-contact-email (or vcfl:contactEmail in a copied manifest) before live requests") + try: + version = importlib.metadata.version("vcf-rdfizer") + except importlib.metadata.PackageNotFoundError: + version = "development" + request = Request(url, data=body, method=method, headers={ + "Accept": "application/json", "Content-Type": "application/json", + "User-Agent": f"VCF-RDFizer/{version} ({self.manifest.contact_email})", + }) + for attempt in range(4): + def fetch(): + self.stats["requests"] += 1 + try: + raw = self.transport(request, timeout=30) + except HTTPError as exc: + raw = exc + with raw: + content = raw.read(MAX_RESPONSE_BYTES + 1) + self.stats["bytes_transferred"] += len(content) + self.stats["final_service_status"] = raw.code + if len(content) > MAX_RESPONSE_BYTES: + raise ValueError("Linker service response exceeds 16 MiB") + return Response(raw.code, dict(raw.headers.items()), content) + try: + response = self.policy.issue(self.manifest, fetch) + except (URLError, TimeoutError, OSError) as exc: + self.stats["final_service_status"] = "network-error" + raise ValueError(f"{self.manifest.id}: network request failed: {exc}") from exc + if response.status_code == 429 or 500 <= response.status_code <= 599: + retry = next((v for k, v in response.headers.items() if k.lower() == "retry-after"), "") + delay = float(2 ** attempt) + if retry: + try: + retry_seconds = float(retry) + except ValueError: + try: + retry_seconds = (parsedate_to_datetime(retry) - datetime.now(timezone.utc)).total_seconds() + except (ValueError, TypeError, OverflowError): + retry_seconds = 0 + if math.isfinite(retry_seconds): + delay = max(delay, retry_seconds) + self.policy.defer(requested.hostname, delay) + if attempt < 3: + continue + response.raise_for_status() + cached = {"request_hash": request_hash, "status": response.status_code, + "headers": response.headers, "body": base64.b64encode(response.content).decode(), + "sha256": hashlib.sha256(response.content).hexdigest(), + "fetched_at": datetime.now(timezone.utc).isoformat()} + atomic_bytes(path, (json.dumps(cached, sort_keys=True) + "\n").encode()) + self._account_response(request_hash, cached) + return response + raise AssertionError("unreachable") + + def _account_response(self, request_hash, cached): + self.stats["final_service_status"] = cached["status"] + self.stats["responses"].append({"request_hash": request_hash, + "sha256": cached["sha256"], "fetched_at": cached["fetched_at"]}) diff --git a/vcf_rdfizer_rules.py b/vcf_rdfizer_rules.py index ea7b5ef..d2fa03d 100644 --- a/vcf_rdfizer_rules.py +++ b/vcf_rdfizer_rules.py @@ -200,6 +200,11 @@ def referenced_columns(text: str) -> set[str]: return names +#: Placeholder the wrapper rewrites to the per-input vcfc:VCF4xFile subclass. +#: Kept in step with vcf_rdfizer.VCF_VERSION_CLASS_SENTINEL. +VCF_VERSION_CLASS_SENTINEL = "vcfc:VCFVersionFile" + + def check_rules(rules_path: Path) -> dict: """Validate one mapping against the wrapper contract. @@ -214,9 +219,30 @@ def check_rules(rules_path: Path) -> dict: "sources": [], "columns": [], "sample_representations": {}, + "vcf_version_sentinel": False, } text = rules_path.read_text(encoding="utf-8") + # The wrapper rewrites this sentinel per input to the vcfc:VCF4xFile + # subclass for the version that input's ##fileformat line declares. A + # mapping without it still converts; it just never claims a version gate. + report["vcf_version_sentinel"] = VCF_VERSION_CLASS_SENTINEL in text + if report["vcf_version_sentinel"]: + report["info"].append( + "Version overlay: the file subject carries the " + f"{VCF_VERSION_CLASS_SENTINEL} sentinel, so each input is typed with " + "the vcfc:VCF4xFile subclass for its own declared VCF version." + ) + else: + report["warnings"].append( + f"No {VCF_VERSION_CLASS_SENTINEL} sentinel in the file subject map. The " + "conversion still works and the version-dependent emitter behaviour " + "still follows each input's ##fileformat line, but the graph will not " + "carry a vcfc:VCF4xFile class, so the version-specific SHACL overlay " + "gate stays inactive. Copy the rr:class line from the shipped default " + "mapping to enable it." + ) + if not TRIPLES_MAP_RE.search(text): report["errors"].append( "No rml:logicalSource or rr:subjectMap found; this does not look like an " diff --git a/vcf_rdfizer_vocab.py b/vcf_rdfizer_vocab.py new file mode 100644 index 0000000..ec76c37 --- /dev/null +++ b/vcf_rdfizer_vocab.py @@ -0,0 +1,1126 @@ +#!/usr/bin/env python3 +"""VCF Core vocabulary terms and the VCF 4.5 parsers the RDF emitters need. + +The conversion splits in two. The RML mapping in ``rules/default_rules.ttl`` +carries every field whose RDF datatype is the same for every row of the TSV. +Everything else lives here and in the ``append_*_rdf`` emitters of +``vcf_rdfizer.py``: a value whose datatype depends on the row (QUAL, ALT, ID, +FILTER, INFO), and any value that has to be decomposed before it can be +represented (a structured header line, an ALT list, a GT string, a +comma-separated ``Number=A``/``R``/``G`` payload, a breakend expression). + +This module holds only pure functions and constants, so the parsers can be +tested without producing RDF. + +Target vocabulary: VCF Core (``https://w3id.org/vcf-core/vocab#``), which +replaces the retired ``https://w3id.org/vcf-rdfizer/vocab#`` namespace. No +version IRI is pinned here: the converter targets the namespace, and the +vocabulary's own release cadence is independent of this converter's. +""" + +from __future__ import annotations + +import re +from dataclasses import dataclass +from urllib.parse import quote_plus + +#: The VCF Core vocabulary namespace. Formerly +#: ``https://w3id.org/vcf-rdfizer/vocab#``, which is retired and serves a +#: deprecation document rather than redirecting here. +VCFC_NAMESPACE = "https://w3id.org/vcf-core/vocab#" + +RDF_TYPE_URI = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type" +FALDO_NAMESPACE = "http://biohackathon.org/resource/faldo#" + +XSD_NAMESPACE = "http://www.w3.org/2001/XMLSchema#" +XSD_STRING_URI = f"{XSD_NAMESPACE}string" +XSD_INTEGER_URI = f"{XSD_NAMESPACE}integer" +XSD_DECIMAL_URI = f"{XSD_NAMESPACE}decimal" +XSD_BOOLEAN_URI = f"{XSD_NAMESPACE}boolean" +XSD_DATE_URI = f"{XSD_NAMESPACE}date" +XSD_ANY_URI = f"{XSD_NAMESPACE}anyURI" + +#: Every ordinal in the published SHACL profiles is constrained with +#: ``sh:datatype xsd:integer`` and a ``sh:minInclusive`` bound, even where the +#: ontology declares ``rdfs:range xsd:positiveInteger``. A SHACL datatype +#: constraint compares the literal's datatype IRI exactly, so an +#: ``xsd:positiveInteger`` literal fails the shape while an ``xsd:integer`` +#: literal satisfies both the shape and the range (the value 1 is in the value +#: space of xsd:positiveInteger however it is written). Ordinals are therefore +#: always serialized as xsd:integer. +XSD_ORDINAL_URI = XSD_INTEGER_URI + + +def term(local_name: str) -> str: + """Return the absolute IRI of one VCF Core term.""" + return f"{VCFC_NAMESPACE}{local_name}" + + +NULL_DATATYPE_URI = term("Null") +VCF_FLOAT_DATATYPE_URI = term("VCFFloat") +GENOTYPE_STRING_DATATYPE_URI = term("GenotypeString") +BREAKEND_STRING_DATATYPE_URI = term("BreakendString") + + +# --------------------------------------------------------------------------- +# Lexical serialization +# --------------------------------------------------------------------------- + +# Characters that ``quote_plus(..., safe="*-._")`` leaves untouched. Sample ids, +# FORMAT keys and numeric row ids are almost always drawn from this set, so the +# fast path below skips percent-encoding entirely for them. +_URI_COMPONENT_PASSTHROUGH_RE = re.compile(r"[A-Za-z0-9*\-._]*\Z") +# Characters that require N-Triples escaping. VCF genotype/FORMAT payloads are +# overwhelmingly free of them, so testing before substituting is worthwhile. +_NTRIPLES_ESCAPE_RE = re.compile(r'[\\"\n\r\t]') +_NTRIPLES_ESCAPES = { + "\\": "\\\\", + '"': '\\"', + "\n": "\\n", + "\r": "\\r", + "\t": "\\t", +} + + +def rml_uri_component(value: str) -> str: + """Match RMLStreamer's Java URLEncoder-based template substitution. + + The wrapper's directly emitted IRIs have to be byte-identical to the ones + RMLStreamer mints from the same value, or the two halves of the graph would + describe different resources. + """ + if _URI_COMPONENT_PASSTHROUGH_RE.match(value) is not None: + return value + encoded = quote_plus(value, safe="*-._", encoding="utf-8", errors="strict") + # urllib follows current RFC rules and always leaves '~' unescaped, whereas + # java.net.URLEncoder (used by RMLStreamer 2.5.0) encodes it. + return encoded.replace("+", "%20").replace("~", "%7E") + + +def ntriples_string_literal(value: str) -> str: + """Serialize ``value`` as a plain (xsd:string) N-Triples literal.""" + if _NTRIPLES_ESCAPE_RE.search(value): + value = _NTRIPLES_ESCAPE_RE.sub(lambda m: _NTRIPLES_ESCAPES[m.group(0)], value) + return f'"{value}"' + + +def ntriples_typed_literal(value: str, datatype_uri: str) -> str: + """Serialize ``value`` as an N-Triples literal with an explicit datatype.""" + return f"{ntriples_string_literal(value)}^^<{datatype_uri}>" + + +def ntriples_literal(value: str) -> str: + """Serialize a VCF value, typing the missing token as ``vcfc:Null``. + + The vocabulary's missing-value policy is that the VCF token ``.`` is + serialized as ``"."^^vcfc:Null`` rather than as a plain string, so that + missingness stays distinguishable from a literal period. + """ + if value == ".": + return f'"."^^<{NULL_DATATYPE_URI}>' + return ntriples_string_literal(value) + + +def ordinal_literal(value: int | str) -> str: + """Serialize a one-based or zero-based ordinal as xsd:integer.""" + return f'"{value}"^^<{XSD_ORDINAL_URI}>' + + +def is_missing(value: str | None) -> bool: + """Return True for an absent value or the VCF missing token.""" + return value is None or value == "" or value == "." + + +# --------------------------------------------------------------------------- +# VCF lexical spaces +# --------------------------------------------------------------------------- + +#: VCF 4.5 Float: a decimal/scientific form, or INF/INFINITY/NAN in any case, +#: optionally signed. The non-finite spellings have no XSD numeric datatype, so +#: they are serialized with vcfc:VCFFloat instead of being coerced. +_VCF_FLOAT_FINITE_RE = re.compile(r"^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$") +_VCF_FLOAT_SPECIAL_RE = re.compile(r"^[-+]?(INF|INFINITY|NAN)$", re.IGNORECASE) + +#: VCF 4.5 reserves Integer values -2147483648..-2147483641 because BCF cannot +#: encode them; a value in that range is kept lexically rather than typed. +_VCF_INTEGER_RESERVED_LOW = -2147483648 +_VCF_INTEGER_RESERVED_HIGH = -2147483641 + +_GENOTYPE_RE = re.compile(r"^[|/]?[0-9.]+([|/][0-9.]+)*$") + + +def is_vcf_float(value: str) -> bool: + """Return True when ``value`` is in the VCF Float lexical space.""" + return bool(_VCF_FLOAT_FINITE_RE.match(value) or _VCF_FLOAT_SPECIAL_RE.match(value)) + + +def is_finite_vcf_float(value: str) -> bool: + """Return True for a VCF Float that xsd:decimal can carry without loss.""" + return bool(_VCF_FLOAT_FINITE_RE.match(value)) + + +def is_vcf_integer(value: str) -> bool: + """Return True for a VCF Integer outside the BCF-reserved range.""" + try: + parsed = int(value) + except ValueError: + return False + return not (_VCF_INTEGER_RESERVED_LOW <= parsed <= _VCF_INTEGER_RESERVED_HIGH) + + +def is_genotype_string(value: str) -> bool: + """Return True when ``value`` is in the vcfc:GenotypeString lexical space.""" + return bool(_GENOTYPE_RE.match(value)) + + +# --------------------------------------------------------------------------- +# VCF Number arities +# --------------------------------------------------------------------------- + +#: Number token -> the vcfc:VCFNumberArity individual carrying that arityCode. +#: The SPARQL SHACL profile requires fieldArity and fieldNumber to agree, so the +#: two are always derived from the same source token. +ARITY_INDIVIDUALS = { + "A": "ArityPerAlt", + "R": "ArityPerAllele", + "G": "ArityPerGenotype", + ".": "ArityVariable", + "LA": "ArityPerLocalAlt", + "LR": "ArityPerLocalAllele", + "LG": "ArityPerLocalGenotype", + "P": "ArityPerGTAllele", + "M": "ArityPerBaseModification", +} + +#: Number tokens whose values are one-per-ALT-allele, so value item i joins ALT +#: allele i+1; and those that are one-per-allele including REF, where item i +#: joins allele i. +_ARITY_PER_ALT = {"A", "LA"} +_ARITY_PER_ALLELE = {"R", "LR"} +_ARITY_PER_GENOTYPE = {"G", "LG"} + + +def arity_individual(number: str) -> str | None: + """Return the vcfc arity individual for a Number token, if it is symbolic.""" + return ARITY_INDIVIDUALS.get((number or "").strip()) + + +def number_as_integer(number: str) -> int | None: + """Return the fixed count declared by a Number token, if it is an integer.""" + token = (number or "").strip() + if not token.isdigit(): + return None + return int(token) + + +#: Keys that flatten fixed-width tuples into one comma list, and the width of +#: each tuple. Recording the width with vcfc:tupleArity lets a consumer regroup +#: them without knowing the key. Which keys are in this set, and whether the +#: list repeats per ALT allele, depends on the VCF version -- see VCFVersion. +TUPLE_ARITIES = { + "CIPOS": 2, + "CIEND": 2, + "CILEN": 2, + "CICN": 2, + "CIRUC": 2, + "CIRB": 2, + "MEINFO": 4, + "METRANS": 4, +} + + +@dataclass(frozen=True) +class ValueItemLink: + """How one parsed value item joins back to the record's alleles. + + ``allele_index`` is the record-global allele index (0 for REF), which is + what vcfc:forAllele points at. ``genotype_index`` and ``gt_allele_index`` + carry the Number=G and Number=P orderings, which are ordinals rather than + allele references. All three being None means the item has a position but no + resource to join it to, which is correct for a version whose tuple keys + describe the record rather than one allele. + """ + + allele_index: int | None = None + genotype_index: int | None = None + gt_allele_index: int | None = None + + @property + def is_empty(self) -> bool: + return ( + self.allele_index is None + and self.genotype_index is None + and self.gt_allele_index is None + ) + + +def value_item_link(number: str, item_index: int, *, tuple_arity: int | None) -> ValueItemLink: + """Resolve which allele or ordinal one comma-list item belongs to. + + ``item_index`` is zero-based within the comma list. When the field flattens + fixed-width tuples, the allele stride is the tuple width, so items 0 and 1 + of a per-ALT CIPOS list both belong to ALT allele 1. + + This is the version-neutral form, driven only by the declared Number token. + Prefer :meth:`VCFVersion.value_item_link`, which also knows which keys are + positional in a given version despite declaring ``Number=.``. + """ + token = (number or "").strip() + stride = tuple_arity or 1 + group = item_index // stride + if token in _ARITY_PER_ALT: + return ValueItemLink(allele_index=group + 1) + if token in _ARITY_PER_ALLELE: + return ValueItemLink(allele_index=group) + if token in _ARITY_PER_GENOTYPE: + return ValueItemLink(genotype_index=group) + if token == "P": + return ValueItemLink(gt_allele_index=group) + return ValueItemLink() + + +# --------------------------------------------------------------------------- +# VCF versions +# --------------------------------------------------------------------------- +# +# VCF Core ships one SHACL overlay per VCF version, each scoped by the file's +# vcfc:fileFormat, plus an optional vcfc:VCF4xFile subclass that turns the +# version gate on. Three things the converter emits genuinely differ between +# versions, so the emitters take a VCFVersion rather than assuming 4.5: +# +# * which Number codes exist at all -- R arrived in 4.2, P in 4.4, and +# LA/LR/LG/M in 4.5; +# * which INFO keys carry flattened tuples, and whether the tuple repeats per +# ALT allele. CIPOS is two values for the whole record in 4.1-4.3 and two +# values per ALT from 4.4; CILEN and CICN only become tuple keys in 4.4; +# * whether the local-allele and base-modification FORMAT families exist. + + +@dataclass(frozen=True) +class VCFVersion: + """One VCF specification version and the conversion behaviour it implies.""" + + #: The exact ##fileformat token, e.g. "VCFv4.5". + token: str + #: The bare version, e.g. "4.5". This is what --vcf-version accepts. + short: str + #: The optional vcfc subclass that activates this version's SHACL gate. + file_class: str + #: Number codes this version permits in an INFO / FORMAT declaration. + info_numbers: frozenset[str] + format_numbers: frozenset[str] + #: INFO keys whose value is a flattened tuple, and that tuple's width. + tuple_keys: dict[str, int] + #: True when a tuple key's list repeats once per ALT allele (4.4 onward); + #: False when it carries exactly one tuple for the whole record. + tuples_per_alt: bool + #: Whether the LAA/LA/LR/LG local-allele family exists. + local_alleles: bool + #: Whether the M/DPM/ADM base-modification families exist. + base_modifications: bool + #: Whether GT may carry a leading phase indicator (4.4 onward). + leading_phase_indicator: bool + #: Whether EVENT names one event per ALT allele (Number=A, 4.4 onward) + #: rather than one event for the whole record (Number=1, 4.1-4.3). + events_per_alt: bool + #: Whether the EVENTTYPE key exists at all (4.4 onward). + event_types: bool + + def allows_number(self, number: str, *, is_format: bool) -> bool: + """Whether a Number token is legal for this version and field kind.""" + token = (number or "").strip() + if token.isdigit(): + return True + allowed = self.format_numbers if is_format else self.info_numbers + return token in allowed + + def tuple_arity(self, field_id: str) -> int | None: + """The flattened-tuple width of an INFO key in this version, if any.""" + return self.tuple_keys.get(field_id) + + def is_positional(self, field_id: str, number: str) -> bool: + """Whether a field's comma list has one meaning per position. + + A tuple key is positional even though the specification declares it + ``Number=.``: the version overlay checks its item count against the ALT + count, so its items must be materialized. Everything else is positional + only when its declared Number says so. + """ + if self.tuple_arity(field_id) is not None: + return True + return not value_item_link(number, 0, tuple_arity=None).is_empty + + def value_item_link(self, field_id: str, number: str, item_index: int) -> ValueItemLink: + """Resolve one comma-list item's allele or ordinal, for this version.""" + arity = self.tuple_arity(field_id) + if arity is not None: + if not self.tuples_per_alt: + # The tuple describes the record, not one allele, so the item + # has an index but nothing to point vcfc:forAllele at. + return ValueItemLink() + return ValueItemLink(allele_index=(item_index // arity) + 1) + return value_item_link(number, item_index, tuple_arity=None) + + +def _version( + short: str, + *, + info_numbers: str, + format_numbers: str, + tuple_keys: dict[str, int], + tuples_per_alt: bool, + local_alleles: bool = False, + base_modifications: bool = False, + leading_phase_indicator: bool = False, + events_per_alt: bool = False, + event_types: bool = False, +) -> VCFVersion: + return VCFVersion( + token=f"VCFv{short}", + short=short, + file_class=f"VCF{short.replace('.', '')}File", + info_numbers=frozenset(info_numbers.split()), + format_numbers=frozenset(format_numbers.split()), + tuple_keys=tuple_keys, + tuples_per_alt=tuples_per_alt, + local_alleles=local_alleles, + base_modifications=base_modifications, + leading_phase_indicator=leading_phase_indicator, + events_per_alt=events_per_alt, + event_types=event_types, + ) + + +#: Tuple keys before 4.4: one (lower, upper) pair per record, and MEINFO / +#: METRANS as one four-value tuple. CILEN and CICN are not yet defined. +_EARLY_TUPLE_KEYS = {"CIPOS": 2, "CIEND": 2, "MEINFO": 4, "METRANS": 4} +#: From 4.4 the confidence-interval family grew and every tuple repeats per ALT. +_LATE_TUPLE_KEYS = { + "CIPOS": 2, + "CIEND": 2, + "CILEN": 2, + "CICN": 2, + "MEINFO": 4, + "METRANS": 4, +} + +#: The VCF versions VCF Core supplies a conformance overlay for. VCF 4.0 file +#: labels remain syntactically valid but no 4.0 overlay is claimed, so this +#: converter treats 4.0 as unrecognized: it emits the version-neutral graph and +#: says so, rather than validating a 4.0 file against 4.1 rules. +VCF_VERSIONS: dict[str, VCFVersion] = { + version.short: version + for version in ( + _version( + "4.1", + info_numbers="A G .", + format_numbers="A G .", + tuple_keys=_EARLY_TUPLE_KEYS, + tuples_per_alt=False, + ), + _version( + "4.2", + info_numbers="A R G .", + format_numbers="A R G .", + tuple_keys=_EARLY_TUPLE_KEYS, + tuples_per_alt=False, + ), + _version( + "4.3", + info_numbers="A R G .", + format_numbers="A R G .", + tuple_keys=_EARLY_TUPLE_KEYS, + tuples_per_alt=False, + ), + _version( + "4.4", + info_numbers="A R G .", + format_numbers="A R G . P", + tuple_keys=_LATE_TUPLE_KEYS, + tuples_per_alt=True, + leading_phase_indicator=True, + events_per_alt=True, + event_types=True, + ), + _version( + "4.5", + info_numbers="A R G .", + format_numbers="A R G . P LA LR LG M", + tuple_keys=_LATE_TUPLE_KEYS, + tuples_per_alt=True, + local_alleles=True, + base_modifications=True, + leading_phase_indicator=True, + events_per_alt=True, + event_types=True, + ), + ) +} + +#: Used when the ##fileformat line is absent, malformed, or names a version with +#: no conformance overlay. It behaves as the newest supported version so no +#: representable content is silently dropped, but no vcfc:VCF4xFile class is +#: emitted, so no version gate is claimed for the graph. +FALLBACK_VERSION = VCF_VERSIONS["4.5"] + +_FILEFORMAT_RE = re.compile(r"^\s*VCFv(?P[0-9]+\.[0-9]+)\s*$", re.IGNORECASE) + + +def parse_vcf_version(file_format: str | None) -> VCFVersion | None: + """Resolve a ##fileformat value to a supported version, or None. + + Returns None for an absent or malformed value, and for a syntactically valid + version that has no conformance overlay (notably VCFv4.0). The caller + decides what to do about it; nothing here guesses. + """ + if not file_format: + return None + match = _FILEFORMAT_RE.match(file_format) + if not match: + return None + return VCF_VERSIONS.get(match.group("short")) + + +def resolve_vcf_version(file_format: str | None) -> tuple[VCFVersion, bool]: + """Return the version to convert with, and whether it was recognized.""" + detected = parse_vcf_version(file_format) + if detected is not None: + return detected, True + return FALLBACK_VERSION, False + + +# --------------------------------------------------------------------------- +# Alleles +# --------------------------------------------------------------------------- + +#: The reserved symbolic ALT identifiers VCF 4.5 defines, mapped to the +#: vcfc:SymbolicAlleleType individual for each. Subtypes are matched before +#: their first-level type so ```` does not resolve to ``DUP``. +SYMBOLIC_ALLELE_TYPES = { + "CNV:TR": "SymbolicTandemRepeat", + "DUP:TANDEM": "SymbolicTandemDuplication", + "DEL:ME": "SymbolicMobileElementDeletion", + "INS:ME": "SymbolicMobileElementInsertion", + "DEL": "SymbolicDeletion", + "INS": "SymbolicInsertion", + "DUP": "SymbolicDuplication", + "INV": "SymbolicInversion", + "CNV": "SymbolicCopyNumberVariation", +} + +#: The reserved EVENTTYPE codes, mapped to their vcfc:EventType individual. +EVENT_TYPES = { + "DEL": "EventDeletion", + "DEL:ME": "EventMobileElementDeletion", + "INS": "EventInsertion", + "INS:ME": "EventMobileElementInsertion", + "DUP": "EventDuplication", + "DUP:TANDEM": "EventTandemDuplication", + "DUP:DISPERSED": "EventDispersedDuplication", + "INV": "EventInversion", + "TRA": "EventTranslocation", + "TRA:BALANCED": "EventBalancedTranslocation", + "TRA:UNBALANCED": "EventUnbalancedTranslocation", + "CHROMOTHRIPSIS": "EventChromothripsis", + "CHROMOPLEXY": "EventChromoplexy", + "BFB": "EventBreakageFusionBridge", + "DOUBLEMINUTE": "EventDoubleMinute", +} + +#: The per-ALT SVCLAIM codes. +SV_CLAIMS = { + "D": "AbundanceClaim", + "J": "AdjacencyClaim", + "DJ": "AbundanceAndAdjacencyClaim", + "JD": "AbundanceAndAdjacencyClaim", +} + +#: ALT forms that assert an unspecified alternate allele rather than a symbolic +#: variant type. gVCF uses <*>; GATK's older spelling is . +_UNSPECIFIED_ALT_IDS = {"*", "NON_REF"} + +_BREAKEND_RE = re.compile( + r"^(?:" + r"(?P[ACGTNacgtn]*)(?P[\[\]])(?P[^\[\]]+)(?P=open)" + r"|" + r"(?P[\[\]])(?P[^\[\]]+)(?P=open2)(?P[ACGTNacgtn]*)" + r")$" +) +_SINGLE_BREAKEND_RE = re.compile(r"^(?:\.[ACGTNacgtn]+|[ACGTNacgtn]+\.)$") + + +@dataclass(frozen=True) +class ParsedAllele: + """One allele of a record, classified by its VCF lexical form.""" + + index: int + value: str + #: The vcfc:AlleleKind individual local name. + kind: str + #: The vcfc:SymbolicAlleleType individual local name, for a symbolic ALT + #: whose identifier is one of the reserved codes. + symbolic_type: str | None = None + #: The bare symbolic identifier without angle brackets, used to join an ALT + #: allele to the ##ALT declaration that defines it. + symbolic_id: str | None = None + #: Set for a bracketed or single breakend expression. + breakend: "ParsedBreakend | None" = None + + +@dataclass(frozen=True) +class ParsedBreakend: + """The queryable components of a VCF breakend ALT expression.""" + + #: The vcfc:BreakendOrientation individual local name, or None for a single + #: breakend, which has no bracket and therefore no orientation. + orientation: str | None + #: The replacement sequence on the record's own side of the adjacency. + replacement: str + #: The mate position, as written: ``chrom:pos``. + mate: str | None + is_single: bool = False + + +_ORIENTATIONS = { + ("before", "["): "SequenceBeforeLeftBracket", + ("before", "]"): "SequenceBeforeRightBracket", + ("after", "["): "SequenceAfterLeftBracket", + ("after", "]"): "SequenceAfterRightBracket", +} + + +def parse_breakend(value: str) -> ParsedBreakend | None: + """Parse a VCF breakend ALT expression into its structural components. + + VCF 4.5 writes an adjacency in one of four bracketed forms -- ``t[p[``, + ``t]p]``, ``[p[t`` and ``]p]t`` -- where ``t`` is the replacement sequence + and ``p`` the mate position. A single breakend, whose partner is unknown, + is written ``.t`` or ``t.`` and has no bracket. + """ + match = _BREAKEND_RE.match(value) + if match: + if match.group("open"): + bracket = match.group("open") + return ParsedBreakend( + orientation=_ORIENTATIONS[("before", bracket)], + replacement=match.group("before"), + mate=match.group("mate"), + ) + bracket = match.group("open2") + return ParsedBreakend( + orientation=_ORIENTATIONS[("after", bracket)], + replacement=match.group("after"), + mate=match.group("mate2"), + ) + if _SINGLE_BREAKEND_RE.match(value): + return ParsedBreakend( + orientation=None, + replacement=value.replace(".", ""), + mate=None, + is_single=True, + ) + return None + + +def classify_allele(value: str, index: int) -> ParsedAllele: + """Classify one REF or ALT lexical form into a vcfc:AlleleKind. + + ``index`` is the record-global allele index: 0 for REF, then 1..n in source + ALT order, which is the join key for every Number=A and Number=R value. + """ + if value == ".": + return ParsedAllele(index, value, "MissingAllele") + if value == "*": + return ParsedAllele(index, value, "OverlappingDeletionAllele") + if value.startswith("<") and value.endswith(">"): + identifier = value[1:-1] + if identifier in _UNSPECIFIED_ALT_IDS: + return ParsedAllele( + index, value, "UnspecifiedAllele", symbolic_id=identifier + ) + return ParsedAllele( + index, + value, + "SymbolicAllele", + symbolic_type=_symbolic_type_for(identifier), + symbolic_id=identifier, + ) + breakend = parse_breakend(value) + if breakend is not None: + return ParsedAllele(index, value, "BreakendAllele", breakend=breakend) + return ParsedAllele(index, value, "BaseSequenceAllele") + + +def _symbolic_type_for(identifier: str) -> str | None: + """Resolve a symbolic ALT identifier to its reserved type, subtype first. + + An unreserved identifier such as ```` has no vcfc type; + it stays a plain SymbolicAllele joined to its ##ALT declaration. + """ + upper = identifier.upper() + if upper in SYMBOLIC_ALLELE_TYPES: + return SYMBOLIC_ALLELE_TYPES[upper] + # A subtype the vocabulary does not enumerate still resolves to its + # first-level type, which VCF 4.5 requires to be a reserved code. + head = upper.split(":", 1)[0] + return SYMBOLIC_ALLELE_TYPES.get(head) + + +#: VCF 4.5 allows CHROM to name a breakpoint assembly contig instead of a +#: reference sequence, written in angle brackets. The identifier may not contain +#: brackets, commas or whitespace. +_BRACKETED_CHROM_RE = re.compile(r"^<(?P[^<>,\s]+)>$") + + +def parse_bracketed_chrom(chrom: str) -> str | None: + """Return the assembly-contig identifier of a bracketed CHROM, else None. + + A bracketed CHROM names a contig from the ##assembly FASTA rather than a + declared ##contig, so it links to a vcfc:AssemblyContig and must *not* also + resolve to a contig declaration. + """ + match = _BRACKETED_CHROM_RE.match(chrom or "") + return match.group("identifier") if match else None + + +def parse_alt_alleles(ref: str, alt: str) -> list[ParsedAllele]: + """Split a record's REF and ALT columns into indexed allele resources. + + Returns REF at index 0 followed by each ALT item in source order. An ALT of + ``.`` means the record asserts no alternate allele, so only REF is returned. + """ + alleles = [classify_allele(ref, 0)] if ref else [] + if is_missing(alt): + return alleles + for offset, item in enumerate(alt.split(","), start=1): + alleles.append(classify_allele(item, offset)) + return alleles + + +# --------------------------------------------------------------------------- +# Genotypes +# --------------------------------------------------------------------------- + + +@dataclass(frozen=True) +class ParsedGenotypeCall: + """One allele position within a GT value.""" + + call_index: int + #: The record-global allele index, or None when the position is a no-call. + allele_index: int | None + + @property + def is_no_call(self) -> bool: + return self.allele_index is None + + +@dataclass(frozen=True) +class ParsedGenotype: + """A parsed GT value: its calls, ploidy, and phasing.""" + + genotype_string: str + calls: tuple[ParsedGenotypeCall, ...] + #: True when every separator is ``|``. VCF permits a leading separator for + #: partial phasing, which is treated as phased for the purposes of the + #: vcfc:PhasingStatus individual. + is_phased: bool + + @property + def ploidy(self) -> int: + return len(self.calls) + + +def parse_genotype(value: str) -> ParsedGenotype | None: + """Parse a GT value into ordered allele calls and a phasing status. + + Returns None when the value is absent or not in the GT lexical space, so a + malformed field is preserved as a plain FORMAT value rather than producing + a Genotype resource that would fail vcfc:GenotypeShape. + """ + if is_missing(value): + return None + if not is_genotype_string(value): + return None + body = value + leading_phased = False + if body[0] in "|/": + leading_phased = body[0] == "|" + body = body[1:] + if not body: + return None + + tokens = re.split(r"([|/])", body) + allele_tokens = tokens[0::2] + separators = tokens[1::2] + + calls = [] + for call_index, token in enumerate(allele_tokens): + if token == "." or token == "": + calls.append(ParsedGenotypeCall(call_index, None)) + else: + try: + calls.append(ParsedGenotypeCall(call_index, int(token))) + except ValueError: + return None + + is_phased = bool(separators) and all(sep == "|" for sep in separators) + if not separators: + # A haploid call carries phasing only through the optional leading + # separator; without one there is nothing to phase against. + is_phased = leading_phased + return ParsedGenotype(value, tuple(calls), is_phased) + + +def genotype_index(allele_indices: list[int]) -> int: + """VCF Number=G ordering: Index(k1..kP) = sum over m of C(k_m + m - 1, m). + + Used to place a Number=G value item against the genotype it scores. + """ + from math import comb + + total = 0 + for position, allele in enumerate(sorted(allele_indices), start=1): + total += comb(allele + position - 1, position) + return total + + +# --------------------------------------------------------------------------- +# Structural variation, repeats and base modifications +# --------------------------------------------------------------------------- + +#: INFO keys whose value is a per-ALT confidence interval expressed through +#: FALDO rather than a vcfc:ConfidenceInterval, per the SV module's design. +FALDO_INTERVAL_INFO_KEYS = {"CIPOS": "posConfidenceInterval", "CIEND": "endConfidenceInterval"} + +#: INFO keys whose value is a per-ALT vcfc:ConfidenceInterval, and the property +#: that attaches it. +CONFIDENCE_INTERVAL_INFO_KEYS = { + "CILEN": "lenConfidenceInterval", + "CICN": "copyNumberConfidenceInterval", +} + +#: INFO Flag keys that set a boolean directly on the ALT allele. +SV_FLAG_INFO_KEYS = {"IMPRECISE": "isImprecise", "NOVEL": "isNovel"} + +#: Per-ALT INFO keys that become a datatype property on the allele. +SV_ALLELE_INFO_KEYS = {"SVLEN": "svLength"} + +#: Tandem-repeat INFO keys, in the RN/RUS/RUL/RUC/RB order VCF 4.5 defines, and +#: the vcfc:RepeatSequence property each populates. +REPEAT_SEQUENCE_INFO_KEYS = { + "RUS": "repeatUnitSequence", + "RUL": "repeatUnitLength", + "RUC": "repeatUnitCount", + "RB": "repeatBases", +} + +#: FORMAT keys that carry copy-number information on a sample call. +COPY_NUMBER_FORMAT_KEYS = { + "CN": "copyNumber", + "CNQ": "copyNumberQuality", + "CNL": "copyNumberLikelihood", + "CNP": "copyNumberPosterior", +} + +#: FORMAT keys that carry haplotype identity on a sample call. +HAPLOTYPE_FORMAT_KEYS = {"HAP": "haplotypeId", "AHAP": "ancestralHaplotypeId"} + +#: FORMAT keys that carry phase-set information. +PHASE_SET_FORMAT_KEYS = ("PS", "PSL", "PSO", "PSQ") + +#: VCF 4.5 defines the base-modification FORMAT families by pattern rather than +#: by a single key: M, DPM and ADM followed by a ChEBI id and the modified base. +BASE_MODIFICATION_KEY_RE = re.compile(r"^(?PM|DPM|ADM)(?P[0-9]+)(?P[ACGTUN])$") + +#: The ChEBI namespace the SV module's vcfc:modifiedResidue points into. +CHEBI_NAMESPACE = "http://purl.obolibrary.org/obo/CHEBI_" + +_BASE_MODIFICATION_PROPERTIES = { + "M": "modificationFraction", + "DPM": "modificationDepth", + "ADM": "modificationAlleleDepth", +} + + +@dataclass(frozen=True) +class ParsedBaseModification: + """A FORMAT key from the M/DPM/ADM base-modification families.""" + + family: str + chebi_id: str + base: str + #: The vcfc property that carries this family's value. + value_property: str + + @property + def residue_uri(self) -> str: + return f"{CHEBI_NAMESPACE}{self.chebi_id}" + + @property + def key(self) -> str: + return f"{self.family}{self.chebi_id}{self.base}" + + +def parse_base_modification_key(key: str) -> ParsedBaseModification | None: + """Recognize a base-modification FORMAT key and resolve its ChEBI residue.""" + match = BASE_MODIFICATION_KEY_RE.match(key) + if not match: + return None + family = match.group("family") + return ParsedBaseModification( + family=family, + chebi_id=match.group("chebi"), + base=match.group("base"), + value_property=_BASE_MODIFICATION_PROPERTIES[family], + ) + + +def split_value_items(value: str) -> list[str]: + """Split a comma-separated VCF value payload into its ordered items.""" + if is_missing(value): + return [] + return value.split(",") + + +def parse_local_allele_indices(value: str) -> list[int]: + """Parse an LAA value into the one-based ALT indices it declares.""" + indices = [] + for item in split_value_items(value): + if item.isdigit(): + parsed = int(item) + if parsed >= 1: + indices.append(parsed) + return indices + + +# --------------------------------------------------------------------------- +# Header lines +# --------------------------------------------------------------------------- + +#: '##' key (lower-cased) -> the vocabulary subclass for that line. Every entry +#: is a subclass of either vcfc:StructuredHeaderLine or +#: vcfc:UnstructuredHeaderLine, which decides whether the line needs +#: vcfc:HeaderAttribute resources. +HEADER_LINE_CLASSES = { + "fileformat": "FileFormatHeaderLine", + "filedate": "FileDateHeaderLine", + "source": "SourceHeaderLine", + "reference": "ReferenceHeaderLine", + "assembly": "AssemblyHeaderLine", + "pedigreedb": "PedigreeDBHeaderLine", + "info": "INFOHeaderLine", + "format": "FORMATHeaderLine", + "filter": "FILTERHeaderLine", + "alt": "ALTHeaderLine", + "contig": "ContigHeaderLine", + "meta": "MetaHeaderLine", + "sample": "SampleHeaderLine", + "pedigree": "PedigreeHeaderLine", +} + +#: The subset of HEADER_LINE_CLASSES whose value is an angle-bracketed +#: attribute list. vcfc:StructuredHeaderLineShape requires at least one +#: vcfc:hasAttribute on each of these. +STRUCTURED_HEADER_KEYS = { + "info", + "format", + "filter", + "alt", + "contig", + "meta", + "sample", + "pedigree", +} + +#: contig attribute -> vocabulary predicate, with the datatype each needs. +CONTIG_ATTRIBUTES = { + "length": ("contigLength", XSD_INTEGER_URI), + "md5": ("contigMd5", XSD_STRING_URI), + "assembly": ("contigAssembly", XSD_STRING_URI), + "URL": ("contigUrl", XSD_ANY_URI), +} + +#: ##INFO attributes beyond ID/Number/Type/Description that the vocabulary +#: represents with a dedicated property. +INFO_EXTRA_ATTRIBUTES = {"Source": "fieldSource", "Version": "fieldVersion"} + +#: ##PEDIGREE role attribute -> the vcfc property for that relation. Any other +#: role falls back to vcfc:pedigreeAncestor with a vcfc:ancestorRole literal. +PEDIGREE_ROLE_PROPERTIES = { + "Mother": "pedigreeMother", + "Father": "pedigreeFather", + "Original": "pedigreeOriginal", +} + +#: Maps a declared VCF INFO/FORMAT Type to its vocabulary value-type +#: individual. Since vocabulary 3.0.0 these are owl:NamedIndividual members of +#: vcfc:VCFValueType, not classes, so they are only ever used as the object of +#: vcfc:fieldType. +VCF_VALUE_TYPE_INDIVIDUALS = { + "Integer": "IntegerType", + "Float": "FloatType", + "Flag": "FlagType", + "Character": "CharacterType", + "String": "StringType", +} + + +def is_structured_header_value(value: str) -> bool: + """Return True when a header value is an angle-bracketed attribute list.""" + stripped = (value or "").strip() + return stripped.startswith("<") and stripped.endswith(">") + + +def parse_structured_header_fields(value: str) -> dict[str, str]: + """Parse comma-delimited VCF header attributes while respecting quotes.""" + return dict(parse_structured_header_attributes(value)) + + +def parse_structured_header_attributes(value: str) -> list[tuple[str, str]]: + """Parse a structured header value into ordered (key, value) attributes. + + Order is preserved because vcfc:HeaderAttribute carries a one-based + vcfc:attributeIndex; VCF 4.5 forbids relying on source attribute order for + meaning, but the vocabulary keeps it recoverable. + """ + inner = (value or "").strip() + if inner.startswith("<") and inner.endswith(">"): + inner = inner[1:-1] + + tokens: list[str] = [] + token: list[str] = [] + in_quotes = False + escaped = False + for character in inner: + if escaped: + token.append(character) + escaped = False + elif character == "\\" and in_quotes: + token.append(character) + escaped = True + elif character == '"': + token.append(character) + in_quotes = not in_quotes + elif character == "," and not in_quotes: + tokens.append("".join(token)) + token = [] + else: + token.append(character) + tokens.append("".join(token)) + + attributes: list[tuple[str, str]] = [] + for item in tokens: + if "=" not in item: + continue + key, raw_value = item.split("=", 1) + parsed_value = raw_value.strip() + if len(parsed_value) >= 2 and parsed_value[0] == parsed_value[-1] == '"': + parsed_value = parsed_value[1:-1] + parsed_value = parsed_value.replace('\\"', '"').replace("\\\\", "\\") + attributes.append((key.strip(), parsed_value)) + return attributes + + +def parse_info_entries(info: str) -> list[tuple[str, str | None]]: + """Split an INFO column into ``(key, value)`` pairs. + + An entry without ``=`` is a Flag: a presence assertion with no value, which + the vocabulary models as ``vcfc:fieldValueBoolean true``. + """ + if info in ("", "."): + return [] + entries: list[tuple[str, str | None]] = [] + for item in info.split(";"): + if not item: + continue + key, separator, value = item.partition("=") + entries.append((key, value if separator else None)) + return entries + + +#: ##fileDate has no mandated format. These are the two forms seen in practice +#: that map unambiguously onto xsd:date, which the SHACL shape requires. +FILE_DATE_PATTERNS = ( + (re.compile(r"^(\d{4})(\d{2})(\d{2})$"), "{0}-{1}-{2}"), + (re.compile(r"^(\d{4})-(\d{2})-(\d{2})$"), "{0}-{1}-{2}"), +) + + +def file_date_object(value: str) -> str | None: + """Serialize ##fileDate as xsd:date when its form allows, else lexically. + + Returns None for an absent value so no triple is emitted, matching RML's + behaviour for an empty reference. + """ + value = (value or "").strip() + if not value or value == ".": + return None + for pattern, template in FILE_DATE_PATTERNS: + match = pattern.match(value) + if match: + return ntriples_typed_literal(template.format(*match.groups()), XSD_DATE_URI) + # An unrecognized form is preserved verbatim rather than dropped; the SHACL + # layer reports it as non-conformant. + return ntriples_string_literal(value) + + +def qual_object(value: str) -> str: + """Serialize QUAL the way vcfc:VariantCallShape accepts it. + + The shape is a disjunction over vcfc:VCFFloat, the XSD numeric datatypes + and vcfc:Null, which RML cannot satisfy because the branch depends on the + row. INF/INFINITY/NAN are in the VCF Float lexical space but in no XSD + numeric one, so they take vcfc:VCFFloat; a finite value takes xsd:decimal + in its source lexical form, so no precision is gained or lost. + """ + if is_missing(value): + return ntriples_typed_literal(".", NULL_DATATYPE_URI) + if is_finite_vcf_float(value): + return ntriples_typed_literal(value, XSD_DECIMAL_URI) + if is_vcf_float(value): + return ntriples_typed_literal(value, VCF_FLOAT_DATATYPE_URI) + # A value outside the VCF Float lexical space is kept as a plain literal + # rather than dropped: a non-conformant graph is more useful than a lossy + # one, and the SHACL layer reports it. + return ntriples_string_literal(value) + + +def numeric_literal(value: str) -> str: + """Serialize a VCF numeric value with a datatype a numeric shape accepts. + + vcfc:NumericLiteralShape requires an integer- or decimal-derived datatype, + so a confidence-interval bound cannot be a plain string. A value outside + both lexical spaces is kept verbatim rather than dropped, and the SHACL + layer reports it. + """ + if is_missing(value): + return ntriples_typed_literal(".", NULL_DATATYPE_URI) + stripped = value.strip() + if is_vcf_integer(stripped) and stripped.lstrip("+-").isdigit(): + return ntriples_typed_literal(stripped, XSD_INTEGER_URI) + if is_finite_vcf_float(stripped): + return ntriples_typed_literal(stripped, XSD_DECIMAL_URI) + return ntriples_string_literal(value) + + +def typed_field_object(value: str, declared_type: str) -> tuple[str, str] | None: + """Return ``(property_local_name, literal)`` for a typed single value. + + Only a single, non-missing value gets a typed companion property; a comma + list is represented by vcfc:FieldValueItem resources instead. + """ + if "," in value or is_missing(value): + return None + if declared_type == "Integer": + if is_vcf_integer(value): + return "fieldValueInteger", ntriples_typed_literal(value, XSD_INTEGER_URI) + return None + if declared_type == "Float": + # Serialize the source lexical form rather than a reparsed float, so + # the graph never gains or loses precision relative to the VCF. A + # non-finite Float has no xsd:decimal form and keeps only fieldValue. + if is_finite_vcf_float(value): + return "fieldValueDecimal", ntriples_typed_literal(value, XSD_DECIMAL_URI) + return None + return None From a2e07ff19c05ae2fa6cb662bd3ffb7bbeca556ab Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Tue, 8 Sep 2026 14:55:26 +0200 Subject: [PATCH 2/9] fix six failing CI unit-test jobs: install declared dependencies --- .github/workflows/tests.yml | 21 +++++++++++++++++++++ changelog.md | 29 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 05c8481..47ff643 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,6 +29,16 @@ jobs: with: python-version: "3.11" + - name: Install the package and its declared dependencies + # rdflib is a required runtime dependency (see pyproject.toml) and the + # CLI imports it through the data-linking module while building its + # argument parser, so even `--help` needs it. Installing the project + # editable pulls exactly what pyproject declares and cannot drift from + # it, while tests still run against the checkout. + run: | + python -m pip install --upgrade pip + python -m pip install -e . + - name: Run cross-platform wrapper tests (no real external tools) run: python -m unittest -v test.test_vcf_rdfizer_cross_platform_unit @@ -51,6 +61,16 @@ jobs: with: python-version: "3.11" + - name: Install the package and its declared dependencies + # rdflib is a required runtime dependency (see pyproject.toml) and the + # CLI imports it through the data-linking module while building its + # argument parser, so even `--help` needs it. Installing the project + # editable pulls exactly what pyproject declares and cannot drift from + # it, while tests still run against the checkout. + run: | + python -m pip install --upgrade pip + python -m pip install -e . + - name: Run full unit test suite run: python -m unittest discover -s test -p "test_*_unit.py" -v @@ -72,6 +92,7 @@ jobs: - name: Run coverage run: | python -m pip install --upgrade pip coverage + python -m pip install -e . coverage run -m unittest discover -s test -p "test_*_unit.py" coverage xml -o coverage.xml diff --git a/changelog.md b/changelog.md index 547ebdc..22c09bf 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,34 @@ # Changelog +## 2026-09-08 — Fix the six failing unit-test jobs in CI + +Every `unit-tests` job failed on push: `wrapper-unit` on three OSes and +`shell+pipeline-unit` on three more. All six had one cause. + +### Fixed + +- **`tests.yml` never installed the project's dependencies.** The jobs ran + `setup-python` and went straight to `unittest discover` against a bare + checkout, so `rdflib` was absent. `vcf_rdfizer.main()` imports + `vcf_rdfizer_link` to build its argument parser, that module imports + `vcf_rdfizer_linking.inputs`, and that does a module-level + `from rdflib import …` — so **even `--help` raised `ModuleNotFoundError`**, + and every test that invokes `main()` errored. Locally the same bare-checkout + run produces 66 errors across both job types. + + `rdflib` is a *required* runtime dependency in `pyproject.toml`, not an + optional extra, so a bare checkout was testing a configuration no installed + copy has. The sibling `validation-mutation.yml` workflow already installed it; + `tests.yml` was simply missing the step. + + The three test jobs now run `python -m pip install -e .`, which pulls exactly + what `pyproject.toml` declares and cannot drift from it, while the tests still + execute against the checkout. `package-smoke` was unaffected — it installs a + wheel and gets the dependencies that way. + + Verified by reproducing CI in a clean virtualenv: `pip install -e .` followed + by both job commands. + ## 2026-09-08 — Verify against the published VCF Core 2.0.0 VCF Core is published at **2.0.0**, covering VCF 4.1 through 4.5. This checks From 2183ba9f785ed033d73b69a056d3befe38158b4d Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Tue, 8 Sep 2026 15:39:35 +0200 Subject: [PATCH 3/9] fix rdflib dependency req for linking bug --- changelog.md | 44 ++++++++++++++++++++++++++++ test/test_linking_unit.py | 11 ++++++- vcf_rdfizer_link.py | 23 +++++++++++++++ vcf_rdfizer_linking/inputs.py | 6 ++-- vcf_rdfizer_linking/manifest.py | 49 ++++++++++++++++++++++++++++++-- vcf_rdfizer_linking/reference.py | 7 +++++ vcf_rdfizer_linking/runner.py | 8 ++++-- 7 files changed, 140 insertions(+), 8 deletions(-) diff --git a/changelog.md b/changelog.md index 22c09bf..0861192 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,49 @@ # Changelog +## 2026-09-08 — Run without the data-linking dependency + +Running the tool from a checkout raised `ModuleNotFoundError: No module named +'rdflib'` before it could do anything at all — including print `--help`, or run +a conversion that does no linking. + +`vcf_rdfizer.main()` imports the data-linking CLI to build its argument parser. +That module imported `vcf_rdfizer_linking.{inputs,manifest,runner}`, each of +which imported `rdflib` at module level, so the dependency of one optional +feature gated every mode. The tool is Docker-first and routinely run from a +clone, where nothing installs Python dependencies. + +### Fixed + +- **`rdflib` is now imported where it is used, not where the module loads.** All + of its use was already inside functions: `read_rdf` in `inputs`, + `run_linkers` in `runner`, and `load_manifest` in `manifest`. The imports moved + into those three functions. +- **The linking namespaces build lazily.** `manifest.VCFL` and `manifest.VCFC` + were module-level `rdflib.Namespace` constants, the one genuine module-level + use. `_LazyNamespace` defers construction to the first term lookup and is + otherwise identical: attribute and item access both return a `URIRef`, and + `str()` gives the namespace IRI. +- **Requesting linking without the dependency now explains itself.** Both entry + points — `--link` in full mode and `--mode link` — report + `data linking requires the 'rdflib' package … install with 'pip install -e .'` + through the normal error path, instead of a traceback. + +`DEFAULT_CACHE` moved from `runner` to `reference`, which has no rdflib +dependency, because the argument parser offers it as a default; `runner` +re-exports it so existing importers are unaffected. + +`test_linking_unit.py` now skips when rdflib is absent instead of failing the +whole discovery run, matching the pattern `test_validation_mutation_unit.py` +already used. Those tests exercise linking itself, so they genuinely need it. + +Measured on a bare checkout: **66 errors before, 0 after** (116 skipped). With +rdflib installed the suite is unchanged at 419 passing, so linking itself is +untouched. + +Every non-linking mode now runs from a bare checkout. Linking itself is +unchanged and still requires `rdflib`, which remains a declared runtime +dependency in `pyproject.toml`. + ## 2026-09-08 — Fix the six failing unit-test jobs in CI Every `unit-tests` job failed on push: `wrapper-unit` on three OSes and diff --git a/test/test_linking_unit.py b/test/test_linking_unit.py index 230a736..156764a 100644 --- a/test/test_linking_unit.py +++ b/test/test_linking_unit.py @@ -14,7 +14,15 @@ from unittest import mock from urllib.error import HTTPError -from rdflib import Graph, Literal, RDF, URIRef +# These tests exercise data linking itself, which requires rdflib. The rest of +# the suite runs without it, so this module skips rather than erroring the whole +# discovery run -- the same pattern test_validation_mutation_unit.py uses. +try: + import rdflib + from rdflib import Graph, Literal, RDF, URIRef +except ModuleNotFoundError: # pragma: no cover - exercised only without rdflib + rdflib = None + Graph = Literal = RDF = URIRef = None import vcf_rdfizer import vcf_rdfizer_link @@ -66,6 +74,7 @@ def sleep(self, seconds): self.now += seconds +@unittest.skipIf(rdflib is None, "rdflib is required for the linking tests") class LinkingTests(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory() diff --git a/vcf_rdfizer_link.py b/vcf_rdfizer_link.py index 723ef5d..1fd1901 100644 --- a/vcf_rdfizer_link.py +++ b/vcf_rdfizer_link.py @@ -16,6 +16,25 @@ from vcf_rdfizer_linking.runner import DEFAULT_CACHE, LinkRunError, run_linkers, run_stage +def _require_rdflib(): + """Fail with an actionable message when the linking dependency is absent. + + rdflib is a declared runtime dependency, but the tool is routinely run from + a checkout, where nothing installs it. Every other mode works without it; + this turns the ModuleNotFoundError that only linking would hit into an + instruction. + """ + try: + import rdflib # noqa: F401 + except ModuleNotFoundError: + raise ValueError( + "data linking requires the 'rdflib' package, which is not " + "installed. Install the project's dependencies with " + "'python -m pip install -e .' from the repository, or " + "'python -m pip install rdflib'. Every other mode runs without it." + ) from None + + def add_link_arguments(parser): parser.add_argument("--link", help="Comma-separated linker IDs (full/link modes)") parser.add_argument("--linker-path", action="append", default=[], help="Additional linker search directory (repeatable)") @@ -28,6 +47,7 @@ def add_link_arguments(parser): def selected_linkers(args): import re + _require_rdflib() manifests = select(args.link or "", args.linker_path) if args.links_contact_email: if not re.fullmatch(r"[^\s<>@]+@[^\s<>@]+\.[^\s<>@]+", args.links_contact_email): @@ -46,6 +66,9 @@ def run_posthoc(args): from vcf_rdfizer import (RunTracker, metrics_run_directory, metrics_run_label, write_run_manifest, write_run_summary, rdf_output_basename) try: + # Inside the guard so a missing dependency is reported the same way as + # any other bad invocation, rather than as a traceback. + _require_rdflib() if not args.rdf or not args.link: raise ValueError("--mode link requires --rdf and --link") rdf = Path(args.rdf).expanduser().resolve() diff --git a/vcf_rdfizer_linking/inputs.py b/vcf_rdfizer_linking/inputs.py index df9153b..0ea1540 100644 --- a/vcf_rdfizer_linking/inputs.py +++ b/vcf_rdfizer_linking/inputs.py @@ -7,8 +7,6 @@ import sqlite3 import tempfile -from rdflib import Literal, RDF, URIRef -from rdflib.plugins.parsers.ntriples import W3CNTriplesParser from .manifest import VCFR @@ -96,6 +94,10 @@ def read_rdf(path: Path): Follow hasRecord/hasCall edges rather than guessing a subject from its IRI. Genotype triples are parsed but never retained. RDFLib owns term decoding. """ + # Deferred so the module imports without rdflib: the CLI loads it while + # building its argument parser, long before any linking runs. + from rdflib import Literal, RDF, URIRef + from rdflib.plugins.parsers.ntriples import W3CNTriplesParser if not path.is_file() or not path.name.endswith((".nt", ".nt.gz")): raise ValueError("Link input must be an existing .nt or .nt.gz file") keep = {str(VCFR[name]) for name in ("hasRecord", "hasCall", "referenceGenome", "chrom", "pos", "ref", "alt", "recordId", "infoRaw")} diff --git a/vcf_rdfizer_linking/manifest.py b/vcf_rdfizer_linking/manifest.py index 823c952..1ee64c3 100644 --- a/vcf_rdfizer_linking/manifest.py +++ b/vcf_rdfizer_linking/manifest.py @@ -9,12 +9,51 @@ from string import Formatter from urllib.parse import quote, urlsplit -from rdflib import Graph, Literal, Namespace, RDF, URIRef -VCFL = Namespace("https://w3id.org/vcf-rdfizer/linking#") +class _LazyNamespace: + """An rdflib Namespace that is not built until a term is asked for. + + rdflib is a required dependency of the data-linking feature, but the CLI + imports this module while merely building its argument parser -- so a + checkout without the dependency installed could not print ``--help``, let + alone run a conversion that does no linking at all. Deferring the import to + the first term lookup keeps every non-linking code path working, and makes + the failure land where the feature is actually used. + + Term access behaves exactly as ``rdflib.Namespace``: attribute and item + lookup both return a ``URIRef``, and ``str()`` gives the namespace IRI. + """ + + __slots__ = ("_iri", "_namespace") + + def __init__(self, iri: str): + self._iri = iri + self._namespace = None + + def _resolve(self): + if self._namespace is None: + from rdflib import Namespace + + self._namespace = Namespace(self._iri) + return self._namespace + + def __getattr__(self, name): + return getattr(self._resolve(), name) + + def __getitem__(self, name): + return self._resolve()[name] + + def __str__(self): + return self._iri + + def __repr__(self): + return f"_LazyNamespace({self._iri!r})" + + +VCFL = _LazyNamespace("https://w3id.org/vcf-rdfizer/linking#") # The converter's own linking vocabulary keeps its namespace; only the # conversion target moved to VCF Core. -VCFC = Namespace("https://w3id.org/vcf-core/vocab#") +VCFC = _LazyNamespace("https://w3id.org/vcf-core/vocab#") #: Retained alias: the linking stage reads back converted RDF, so it must #: use whatever namespace the emitters wrote. VCFR = VCFC @@ -69,6 +108,10 @@ def load_manifest(directory: Path) -> Manifest: directory = directory.expanduser().resolve() if directory.is_file(): directory = directory.parent + # rdflib is needed only to read a manifest, which is the point at which the + # data-linking feature is genuinely in use. + from rdflib import Graph, Literal, RDF, URIRef # noqa: F401 + graph = Graph() try: graph.parse(directory / "linker.ttl", format="turtle") diff --git a/vcf_rdfizer_linking/reference.py b/vcf_rdfizer_linking/reference.py index c84efba..796b3ea 100644 --- a/vcf_rdfizer_linking/reference.py +++ b/vcf_rdfizer_linking/reference.py @@ -13,6 +13,13 @@ from .session import NoRedirects +#: Where linker reference downloads and cached HTTP responses live. It sits in +#: this module rather than in ``runner`` because the argument parser needs it as +#: a default, and ``runner`` imports rdflib -- which would make merely printing +#: ``--help`` require the data-linking dependency. +DEFAULT_CACHE = Path.home() / ".cache" / "vcf-rdfizer" / "linkers" + + def digest_file(path): digest = hashlib.sha256() with path.open("rb") as handle: diff --git a/vcf_rdfizer_linking/runner.py b/vcf_rdfizer_linking/runner.py index 011c600..21dc9b0 100644 --- a/vcf_rdfizer_linking/runner.py +++ b/vcf_rdfizer_linking/runner.py @@ -13,7 +13,6 @@ import tempfile import time -from rdflib import Literal, RDF, URIRef, XSD from . import Link, LinkKey, LinkerContext from .inputs import Source @@ -21,7 +20,9 @@ from .reference import IntervalIndex, acquire_reference, check_assembly from .session import CachedSession, NetworkPolicy, atomic_bytes -DEFAULT_CACHE = Path.home() / ".cache" / "vcf-rdfizer" / "linkers" +# Re-exported from .reference, which has no rdflib dependency, so the CLI can +# offer it as an argument default without importing this module. +from .reference import DEFAULT_CACHE # noqa: F401 PROV_TIME = "http://www.w3.org/ns/prov#generatedAtTime" @@ -84,6 +85,9 @@ def run_linkers(records, manifests, output: Path | None, *, cache_dir=DEFAULT_CA Dry-run writes no persistent artifacts, imports no resolver code, and never fetches a reference. It resolves local tiers and reports Tier 3 batch plans. """ + # Deferred so the module imports without rdflib: the CLI loads it while + # building its argument parser, long before any linking runs. + from rdflib import Literal, RDF, URIRef, XSD started = time.monotonic() report = {"status": "running", "records": 0, "triples": 0, "appended_bytes": 0, "output": str(output) if output else None, "dry_run": dry_run, "linkers": [], "preview": []} From ccce691f45271005861e20155f37287d9d7085e0 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Thu, 10 Sep 2026 11:04:25 +0200 Subject: [PATCH 4/9] fixed escape behavior and hdt bug --- docs/architecture.md | 2 +- docs/cli-reference.md | 2 +- docs/limitations.md | 9 +- docs/output-and-metrics.md | 24 +- docs/validation.md | 151 +++++-- src/validation/validation_runner.py | 603 ++++++++++++++++++++----- test/test_validation_benchmark_unit.py | 61 ++- test/test_validation_engines_unit.py | 104 ++++- test/test_vcf_rdfizer_unit.py | 168 +++++++ vcf_rdfizer.py | 242 +++++++++- 10 files changed, 1166 insertions(+), 200 deletions(-) diff --git a/docs/architecture.md b/docs/architecture.md index 2e84081..1115940 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -54,7 +54,7 @@ run entirely on the host. | Docker orchestration | Mounts, user mapping, environment forwarding, permission auto-fix | | Progress rendering | Containers write a JSONL sidecar; the host polls and renders it | | Metrics assembly | Every stage's JSON is collected into one `run_metrics/` tree | -| Interrupt handling | `Ctrl+C` triggers best-effort cleanup of tracked intermediates | +| Interrupt handling | `Ctrl+C` stops this run's labelled containers, then cleans tracked intermediates, then writes a checkpoint | | Optional data linking | Python plug-ins, reference/response caches and an atomic side-graph share one host runner for full and post-hoc mode | ## 3. Container responsibilities diff --git a/docs/cli-reference.md b/docs/cli-reference.md index a2df93b..01ed405 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -170,7 +170,7 @@ volume**, not the output filesystem. | --- | --- | | `0` | Success (possibly with recorded index warnings) | | `1` | One or more inputs failed, including a semantic validation failure | -| `130` | Interrupted with `Ctrl+C`; progress written and tracked intermediates cleaned up | +| `130` | Interrupted with `Ctrl+C`; containers stopped, tracked intermediates cleaned up, `interrupt-checkpoint.json` written | --- diff --git a/docs/limitations.md b/docs/limitations.md index 6615bdb..f2d3f48 100644 --- a/docs/limitations.md +++ b/docs/limitations.md @@ -34,9 +34,12 @@ no distributed execution and no work queue. **No incremental update.** Adding variants to a converted dataset means reconverting the VCF and rebuilding every representation from scratch. -**Interrupt cleanup is best-effort.** `Ctrl+C` exits 130 and removes tracked -intermediates, but a `SIGKILL` or a host crash can leave a partial output -directory that the collision check will then refuse to write into. +**Interrupt cleanup is best-effort.** `Ctrl+C` exits 130, stops this run's +containers, removes tracked intermediates and writes +`interrupt-checkpoint.json`. But `SIGKILL` and a host crash both bypass it +entirely: no handler runs, so containers survive and a partial output directory +is left behind, which the collision check will then refuse to write into. After +an ungraceful kill, check `docker ps --filter label=vcf-rdfizer.run` yourself. ## 2. Input handling diff --git a/docs/output-and-metrics.md b/docs/output-and-metrics.md index ec46d55..6aec8f1 100644 --- a/docs/output-and-metrics.md +++ b/docs/output-and-metrics.md @@ -210,10 +210,26 @@ number, and no progress history is retained in memory. ## 7. Interrupts and exit codes -`Ctrl+C` exits with **130**, writes progress to `logs/progress.log`, and -performs best-effort cleanup of tracked intermediates. Raw RDF cleanup on -interrupt follows `--keep-rmlstreamer-rdf-output`: with it, raw RDF is -preserved; without it, tracked raw RDF files are removed. +`Ctrl+C` exits with **130** and runs cleanup in a fixed order: + +1. **Stop this run's containers.** Every container the wrapper starts carries a + `vcf-rdfizer.run=-` label, and cleanup kills exactly the ones + matching its own label — a concurrent run's containers are never touched. +2. **Remove tracked intermediates.** Raw RDF follows + `--keep-rmlstreamer-rdf-output`: with it, raw RDF is preserved; without it, + tracked raw RDF files are removed. +3. **Write `interrupt-checkpoint.json`** into the run's metrics directory, + recording the stages that completed, the last progress event, how many + containers were stopped, and what was removed. + +The order matters. Killing the wrapper does not kill its containers, and until +this existed an interrupted run deleted files that its own container was still +reading — one such orphan ran for three days after the run had "finished", +holding 17 GB and a core, working against inputs that no longer existed. + +A second `Ctrl+C` during cleanup is ignored, so an impatient operator cannot +abort the step that stops the containers. If cleanup itself fails the wrapper +still exits 130 and records `Interrupt cleanup error` in the progress log. Otherwise the wrapper exits `0` on success and non-zero on failure. In full mode with `--validate`, a validation failure sets a non-zero exit even when the diff --git a/docs/validation.md b/docs/validation.md index 590aced..ba1b45b 100644 --- a/docs/validation.md +++ b/docs/validation.md @@ -26,35 +26,56 @@ only reports are retained. ## Choosing an engine, and what happens when it cannot keep up -**Comunica has no persistent index.** `comunica-sparql-file` parses the whole -source into an in-memory store, answers one query, and exits — so a run pays -that parse **once per query**, 27 times. That is fine for a fixture and -unworkable for a cohort-scale graph, where the parse alone can exceed the -per-query timeout. +**Every engine is now set up once per target**, and all 27 queries reuse that +setup. Setup is timed separately as `setupSeconds` so a benchmark can attribute +it correctly instead of smearing it across 27 query timings. -**QLever builds an index once** and answers every query from it. On a large -graph the index build dominates and the queries are cheap. This is why a graph -can pass with QLever and time out with Comunica: it is a scale property of the -engine, not a disagreement about the data. +| Engine | What is paid once | +| --- | --- | +| `comunica` | one `comunica-sparql-file-http` process: Node startup and engine init | +| `hdt` | one `comunica-sparql-hdt-http` process, holding the memory-mapped `.hdt` | +| `qlever` | an on-disk index build, then its own HTTP server | +| `cottas` | one `COTTASStore`-backed rdflib graph | + +Earlier releases spawned the one-shot `comunica-sparql-file` and +`comunica-sparql-hdt` CLIs **once per query**, paying startup 27 times. +Measured in this image on 1.5M N-Triples, per `SELECT (COUNT(*))`: + +| | per query | +| --- | --- | +| one-shot `comunica-sparql-file` | 26.0s | +| `comunica-sparql-file-http` endpoint | 10.3s | + +**Comunica still has no index, and the endpoint does not change that.** It +streams the source for every query: `LIMIT 1` answers in 0.59s while `COUNT(*)` +takes 10s on every repeat. So a full-scan query still re-reads the whole graph +each time — the endpoint removes per-query *startup*, not per-query *scanning*. + +Materializing the graph into an in-memory store instead was measured and +rejected: an `N3.Store` of the same 1.5M triples cost 2.45 GiB and made `COUNT` +*slower* (15.0s), which extrapolates to roughly 145 GiB for an 88M-triple +cohort graph. Above fixture scale the answer is an engine that indexes, not a +bigger heap. | Graph size | Recommended | | --- | --- | | Fixtures, small VCFs | `--validation-engine comunica` (default; no index build) | | Anything above a few GiB of N-Triples | `--validation-engine qlever`, or validate the indexed artifact with `--validate-artifacts hdt` | -Above 4 GiB the runner warns before it starts, states the worst case at the -current timeout, and names the alternatives. +Above 4 GiB the runner warns before it starts and names the alternatives. ### If validation seems to hang -It is almost certainly an engine that cannot answer the graph inside -`--validation-query-timeout` (default 3600s). Since this is per query and there -are 27 of them, a run that answers none of them used to take 27 hours per engine -per target before reporting anything. +First check `setupSeconds` in the engine report. Slow *setup* is a scale +problem (an index build, or a source the endpoint struggles to read); a slow +*query* is a `--validation-query-timeout` problem (default 3600s). -That no longer happens: the first query to exceed the timeout abandons that -engine's remaining queries, and the report records which query tripped it and -how many were skipped: +**Every query runs, always.** A query that fails, times out, or returns the +wrong answer is recorded and the suite moves on — a validation run is a +coverage report, and "26 of 27 passed, q11 disagreed" is a result while +"stopped at q01" is not. `--validation-stop-after-query-timeout` opts into +abandoning an engine's remaining queries after the first timeout, which caps +the worst case at one timeout per engine rather than one per query: ```json {"status": "EXECUTION_FAILED", @@ -62,10 +83,10 @@ how many were skipped: "queriesRun": 1, "queriesPlanned": 27} ``` -Options from there: +Options for a graph that is genuinely too large: ```bash -# Index once and query from it, instead of re-parsing per query. +# Build an index once and query from it. vcf-rdfizer --mode full -i cohort.vcf.gz --validate --validation-engine qlever -o ./out # Or validate the HDT artifact, which is already indexed. @@ -76,9 +97,20 @@ vcf-rdfizer --mode full -i cohort.vcf.gz --validate \ --validation-query-timeout 14400 --validation-time-budget 86400 -o ./out ``` -`--validation-continue-after-query-timeout` restores the old behaviour of -running every query regardless; it is off by default because the remaining -queries are no easier than the one that just failed. +### A decode that reports success and writes garbage + +Every decode into N-Triples is now checked structurally before anything reads +it: non-empty, newline-terminated, with a parseable first statement. A step +that exits 0 but writes errors to stderr is treated as failed. + +This exists because hdt-cpp's `hdt2rdf` **file** serializer is broken: it emits +`error: :0:0: write error` once per triple, writes truncated subject IRIs with +no terminators and no newlines at all, and still exits 0. Its stdout serializer +is correct, so the decode is taken from stdout and redirected. Left unchecked, +the malformed dump reached `rapper`, which saw one multi-gigabyte "line", +degraded to quadratic parsing, and spent 38 hours reaching 23% of a 4.4 GiB +file — a hang, in every way that matters, produced by a tool that reported +success. Queries run in their own process session, so a timeout kills the engine along with its `/usr/bin/time` wrapper. Before that fix the engine survived the @@ -534,23 +566,62 @@ Results are written to the run's canonical metrics tree: /run_metrics/__/reports/validation// ``` -Detailed results live beneath `reports/validation/`, so they are indexed by -the same `summary.json` used for conversion and compression metrics. - -Important files include `summary.json`, `manifest.json`, `parser.json`, -`rdf-validation.json`, `materialization.json`, `preflight.json`, `sparql.json`, -`comparison.json`, `benchmark.json` and `benchmark.csv`. Raw SPARQL Results -JSON, stderr, and query resource logs are in `raw//`; normalized results -are in `normalized/`. `manifest.json` records the engine that ran (including -QLever's exact argv), the source artifact format and checksum, and every decode -step; `materialization.json` records how a compressed or indexed artifact was -turned into N-Triples and how many triples that yielded. - -A multi-engine run adds `engines//` - one `preflight.json`, -`sparql.json`, `comparison.json` and `query-executions.json` per engine - and -`engine-agreement.json`, which records whether every engine returned the same -normalized results and, if not, which queries differed. The top-level reports -remain those of the primary (first-named) engine. +### The tree + +```text +/run_metrics/__/ +├── summary.json ← start here: a `validation` array indexes every target +├── stages/validation/.json ← one compact stage report per target +└── reports/validation// ← the detail for that target + ├── summary.json verdict, engines, pointers + ├── manifest.json provenance + ├── parser.json what the oracle read from the VCF + ├── sparql.json what the queries got from the graph + ├── comparison.json the two, compared per query + ├── preflight.json graph-integrity gates + ├── rdf-validation.json syntax check and parsed triple count + ├── materialization.json how a compressed artifact was decoded + ├── benchmark.json / benchmark.csv timings + ├── shacl.json / shacl-report.txt only with --shacl-shapes + ├── engine-agreement.json only with several engines + ├── engines// only with several engines + ├── raw// raw engine output + └── normalized/ per-query rows the comparison used +``` + +### What each file answers + +| File | Open it when you want to know | +| --- | --- | +| `summary.json` | The verdict, which engines ran and what each returned, and where the rest is. **Start here.** | +| `comparison.json` | *Why* a run is `MISMATCH`: per query, the rows that were missing, extra, or differing | +| `parser.json` | What the oracle independently computed **from the VCF** — the side of the comparison that does not involve RDF | +| `sparql.json` | What the queries returned **from the graph**, normalized — the other side | +| `preflight.json` | Which integrity gate failed on a `BLOCKED_BY_PREFLIGHT`: blank nodes, empty terms, duplicate statements, record cardinality, missing-token conformance, representation profile | +| `rdf-validation.json` | Whether the N-Triples parsed at all (`rapper -c`), and how many statements it holds | +| `materialization.json` | How an `.hdt`/`.cottas`/`.gz` artifact was turned into N-Triples, and how many triples that yielded — the first place to look when a compressed artifact validates differently from the aggregate | +| `manifest.json` | Provenance for a result you want to reproduce or cite: the engine and its exact argv (including QLever's), the source artifact's format and checksum, every decode step | +| `benchmark.json`, `benchmark.csv` | Timings. The CSV is long-format — one row per engine per query — and is the file to load for analysis | +| `shacl.json`, `shacl-report.txt` | Shape conformance, when `--shacl-shapes` was given. Independent of the VCF: it checks the graph against the vocabulary, not against the source | +| `engine-agreement.json` | Whether every engine returned identical normalized results, and which queries differed if not | +| `engines//` | The same `preflight`/`sparql`/`comparison` for one engine, plus `query-executions.json` with each query's exit code, wall time and error. The top-level reports are the **primary** (first-named) engine's | +| `raw//` | Raw SPARQL Results JSON, stderr, and `/usr/bin/time` resource logs, per query — for debugging an engine rather than the data | +| `normalized/` | The per-query rows the comparison actually used, after normalization | + +### Reading order when something fails + +Take the `status` from `summary.json` and go straight to the file that explains it: + +| Status | Meaning | Go to | +| --- | --- | --- | +| `PASS` | Every required query and invariant matched | — | +| `MISMATCH` | Both sides ran and disagree | `comparison.json` | +| `BLOCKED_BY_PREFLIGHT` | RDF syntax or core graph structure failed, so the comparison never ran | `preflight.json`, then `rdf-validation.json` | +| `EXECUTION_FAILED` | A parser or an engine could not complete | `engines//query-executions.json` | + +An engine that exceeded `--validation-query-timeout` reports `EXECUTION_FAILED` +with an `abandoned` field naming the query that tripped it and how many were +skipped. See [If validation seems to hang](#if-validation-seems-to-hang). When several artifacts are validated in one full run, each gets its own directory: the aggregate keeps `/`, and the representations use diff --git a/src/validation/validation_runner.py b/src/validation/validation_runner.py index 36ed904..78856b5 100644 --- a/src/validation/validation_runner.py +++ b/src/validation/validation_runner.py @@ -56,6 +56,18 @@ VCF = None +def eprint(*args: Any) -> None: + """Print to stderr. + + This runner executes standalone inside the container, so it cannot borrow + the identically named helper from ``vcf_rdfizer.py`` on the host. Both the + oversized-graph advisory and the query-timeout abandon message call this; + before it existed here, either one raised ``NameError`` and killed the run + at the exact moment it was trying to warn the operator. + """ + print(*args, file=sys.stderr, flush=True) + + SCRIPT_DIR = Path(__file__).resolve().parent QUERY_ROOT = SCRIPT_DIR / "queries" CORE_QUERIES = ( @@ -1368,26 +1380,116 @@ def _resolve_binary(env_var: str, *candidates: str) -> str: raise RuntimeError(f"Required binary not found in container: {candidates[0]}") +#: Substrings that mean a decode step failed even though it exited 0. hdt-cpp's +#: ``hdt2rdf`` is the reason this list exists: its raptor file serializer emits +#: ``error: :0:0: write error`` once per triple and still returns success. +STEP_ERROR_MARKERS = ("write error", "error:", "ERROR:") + + def _run_step( - command: list[str], *, label: str, log_dir: Path, env: dict[str, str] | None = None + command: list[str], + *, + label: str, + log_dir: Path, + env: dict[str, str] | None = None, + stdout_path: Path | None = None, + error_markers: tuple[str, ...] = (), ) -> None: - """Run one decode step, preserving its output for diagnosis on failure.""" + """Run one decode step, preserving its output for diagnosis on failure. + + ``stdout_path`` redirects the command's stdout to that file and keeps only + stderr in the log, which is how a tool that can only serialize correctly to + stdout is driven. + + ``error_markers`` are matched against the log after a *successful* exit. An + exit code is only as trustworthy as the tool that returns it, and a decode + step that reports success while writing garbage is worse than one that + fails: the garbage flows downstream and the run dies somewhere unrelated, + hours later. + """ log_dir.mkdir(parents=True, exist_ok=True) log_path = log_dir / f"{label}.log" - with log_path.open("wb") as log: - result = subprocess.run( - command, check=False, stdout=log, stderr=subprocess.STDOUT, env=env - ) + if stdout_path is not None: + stdout_path.parent.mkdir(parents=True, exist_ok=True) + with stdout_path.open("wb") as out, log_path.open("wb") as log: + result = subprocess.run(command, check=False, stdout=out, stderr=log, env=env) + else: + with log_path.open("wb") as log: + result = subprocess.run( + command, check=False, stdout=log, stderr=subprocess.STDOUT, env=env + ) + + tail = "" + try: + tail = log_path.read_text(encoding="utf-8", errors="replace")[-2000:] + except OSError: + pass + if result.returncode != 0: - tail = "" - try: - tail = log_path.read_text(encoding="utf-8", errors="replace")[-2000:] - except OSError: - pass raise RuntimeError( f"{label} failed with exit code {result.returncode}. Output tail: {tail}" ) + if error_markers: + try: + log_text = log_path.read_text(encoding="utf-8", errors="replace") + except OSError: + log_text = tail + hit = next((m for m in error_markers if m in log_text), None) + if hit is not None: + raise RuntimeError( + f"{label} exited 0 but reported errors on stderr " + f"(matched {hit!r}); treating the step as failed because its " + f"output cannot be trusted. Output tail: {tail}" + ) + + +def _verify_ntriples(path: Path, *, label: str) -> int: + """Reject a materialized N-Triples file that is structurally impossible. + + Cheap enough to run on any size (it reads a prefix and a suffix, never the + whole file) and it catches the failure mode that cost this project days: a + 4.4 GiB "N-Triples" file containing no newline at all, whose every line was + a truncated subject IRI. Raptor accepts that as one enormous line and + degrades to quadratic behaviour, so the run does not fail -- it crawls, at + roughly 7 KiB/s, and looks like a hang rather than a bug. + + Returns the size in bytes. Raises RuntimeError with a diagnosis otherwise. + """ + try: + size = path.stat().st_size + except OSError as error: + raise RuntimeError(f"{label} produced no readable output at {path}: {error}") from error + if size == 0: + raise RuntimeError(f"{label} produced an empty N-Triples file at {path}") + + probe = 1024 * 1024 + with path.open("rb") as handle: + head = handle.read(probe) + if b"\n" not in head: + raise RuntimeError( + f"{label} produced {size} bytes with no newline in the first " + f"{min(probe, size)}; this is not N-Triples. First 200 bytes: " + f"{head[:200]!r}" + ) + first_line = head.split(b"\n", 1)[0].strip() + if not (first_line.startswith(b"<") or first_line.startswith(b"_:")): + raise RuntimeError( + f"{label} produced a first line that does not begin a triple: {first_line[:200]!r}" + ) + if not first_line.endswith(b"."): + raise RuntimeError( + f"{label} produced a first line with no statement terminator: " + f"{first_line[:200]!r}" + ) + handle.seek(max(0, size - 4096)) + if not handle.read().endswith(b"\n"): + raise RuntimeError( + f"{label} produced a file not terminated by a newline; it is " + f"most likely truncated ({size} bytes)" + ) + return size + def materialize_ntriples( source: Path, @@ -1412,6 +1514,7 @@ def materialize_ntriples( if rdf_format == "nt.gz": with gzip.open(source, "rb") as handle, target.open("wb") as out: shutil.copyfileobj(handle, out, length=1024 * 1024) + _verify_ntriples(target, label="gzip-decompress") provenance["steps"].append({"tool": "python-gzip", "output": str(target)}) return target, provenance @@ -1419,13 +1522,31 @@ def materialize_ntriples( brotli = _resolve_binary("BROTLI_BIN", "brotli") _run_step([brotli, "-d", "-c", "-o", str(target), str(source)], label="brotli-decompress", log_dir=log_dir) + _verify_ntriples(target, label="brotli-decompress") provenance["steps"].append({"tool": brotli, "output": str(target)}) return target, provenance if rdf_format == "hdt": hdt2rdf = _resolve_binary("HDT2RDF_BIN", "hdt2rdf", "/usr/local/bin/hdt2rdf") - _run_step([hdt2rdf, str(source), str(target)], label="hdt2rdf", log_dir=log_dir) - provenance["steps"].append({"tool": hdt2rdf, "output": str(target)}) + # hdt-cpp's file-output path is broken: for every output format its + # raptor iostream serializer emits "error: :0:0: write error" per + # triple, writes a truncated subject IRI with no terminator and no + # newline, and still exits 0. Its stdout serializer takes a different + # code path and is correct, verified at 200k triples with empty + # stderr, so the dump is taken from stdout and redirected here. + _run_step( + [hdt2rdf, "-f", "ntriples", str(source), "-"], + label="hdt2rdf", + log_dir=log_dir, + stdout_path=target, + error_markers=STEP_ERROR_MARKERS, + ) + _verify_ntriples(target, label="hdt2rdf") + provenance["steps"].append({ + "tool": hdt2rdf, + "output": str(target), + "mode": "stdout-redirect", + }) return target, provenance if rdf_format in {"cottas", "cottas.gz", "cottas.br"}: @@ -1449,6 +1570,7 @@ def materialize_ntriples( label="cottas-decompress", log_dir=log_dir, ) + _verify_ntriples(target, label="cottas-decompress") provenance["steps"].append({"tool": f"{python_bin} cottas_tool.py decompress", "output": str(target)}) if cottas_input != source: @@ -1591,6 +1713,17 @@ def validate_ntriples(source: Path, results_dir: Path) -> dict[str, Any]: DEFAULT_QLEVER_MEMORY_GB = 4 DEFAULT_QLEVER_STARTUP_TIMEOUT = 900 DEFAULT_QUERY_TIMEOUT = 3600 +DEFAULT_COMUNICA_PORT = 7020 +#: Seconds to wait for comunica-sparql-file-http to bind its port. The graph is +#: not read yet at that point, so this is process startup only and stays short. +DEFAULT_COMUNICA_BIND_TIMEOUT = 120 +#: Seconds allowed for the warm-up query that proves the endpoint can read the +#: source before the suite commits to it. Budgeted separately from a normal +#: query because on a large graph even a LIMIT 1 has to start streaming it. +DEFAULT_COMUNICA_WARMUP_TIMEOUT = 3600 +#: The HDT endpoint runs alongside the N-Triples one within a single run, so +#: they must not contend for a port. +DEFAULT_HDT_ENDPOINT_PORT = 7021 QLEVER_STATUS_FILE = Path("/opt/vcf-rdfizer/qlever-status.txt") @@ -1690,9 +1823,10 @@ def _envelope( def engine_advice(engine_name: str, source: Path, query_count: int, timeout: int) -> str | None: """Warn before a run commits to an engine that cannot finish it. - Comunica has no persistent index: every query re-parses the whole source - into memory. On a cohort-scale graph each parse can exceed the per-query - timeout, and the cost is paid again for every remaining query. + Comunica still has no index. The endpoint removes per-query engine startup + but streams the source for every query, so a full-scan query re-reads the + whole graph each time. On a large graph that is the dominant cost and no + amount of tuning fixes it -- only an engine that indexes will. """ if engine_name != "comunica": return None @@ -1703,12 +1837,10 @@ def engine_advice(engine_name: str, source: Path, query_count: int, timeout: int if size < UNINDEXED_ENGINE_ADVICE_BYTES: return None return ( - f"comunica re-parses the whole graph for each of the {query_count} " - f"queries and keeps it in memory; this source is " - f"{size / (1024 ** 3):.1f} GiB. Worst case at the current " - f"--query-timeout is {query_count * timeout / 3600:.0f}h. Prefer " - f"--engine qlever, or validate an indexed artifact " - f"(--validation-targets hdt)." + f"comunica has no index and streams the source for every query, so " + f"each of the {query_count} full-scan queries re-reads all " + f"{size / (1024 ** 3):.1f} GiB. Prefer --engine qlever, or validate an " + f"indexed artifact (--validation-targets hdt)." ) @@ -1757,63 +1889,260 @@ def _terminate_process_group(process: subprocess.Popen) -> None: pass -class ComunicaEngine(QueryEngine): - """Query the N-Triples file directly with comunica-sparql-file. +class ComunicaHttpEndpointMixin: + """One long-lived Comunica endpoint, shared by every query in the suite. + + Comunica's one-shot CLIs (``comunica-sparql-file``, ``comunica-sparql-hdt``) + were spawned once per query, so each of the 27 queries paid Node startup + and engine initialisation again. The matching ``*-http`` binaries pay that + once and answer every query from the running process. + + Measured in this image on 1.5M N-Triples, per ``SELECT (COUNT(*))``: - Comunica has no persistent index: each invocation parses the whole source - into an in-memory store, answers one query, and exits. That is fine for a - fixture and unworkable for a cohort-scale graph, where the parse alone can - exceed the per-query timeout -- and then does so again for every remaining - query. ``engine_advice`` reports that before a run commits to it. + ========================== ======== + one-shot ``comunica-sparql-file`` 26.0s + this endpoint 10.3s + ========================== ======== + + What it does **not** do is materialize the graph. ``LIMIT 1`` answers in + 0.59s while ``COUNT(*)`` takes 10s on every repeat, which is the signature + of a source streamed per query rather than an in-memory store. Loading it + into one instead was measured and rejected: an ``N3.Store`` of the same + 1.5M triples cost 2.45 GiB and made ``COUNT`` *slower* (15.0s), which + extrapolates to roughly 145 GiB for an 88M-triple cohort graph. For a graph + that large the answer is an engine that indexes -- QLever, or the HDT + artifact -- not a bigger heap. + + So the saving here is per-query engine startup, which is real and repeated + 27 times, and the scan cost is unchanged. Per-query worker recycling + (``--freshWorker``) would give the startup cost straight back and is never + passed. The worker count is pinned to 1: workers do not share state, so + each extra one only adds another process reading the same file. """ - name = "comunica" + #: Endpoint binary, e.g. "comunica-sparql-file-http". + endpoint_binary = "" + #: Key in ``options`` holding this endpoint's port. + endpoint_port_option = "comunica_port" + default_endpoint_port = DEFAULT_COMUNICA_PORT + #: Guidance appended when the binary is missing from the image. + endpoint_missing_hint = "rebuild the image or select --engine qlever" + + def _init_endpoint(self, options: dict[str, Any]) -> None: + self.port = int( + options.get(self.endpoint_port_option) or self.default_endpoint_port + ) + self.bind_timeout = int( + options.get("comunica_bind_timeout") or DEFAULT_COMUNICA_BIND_TIMEOUT + ) + self.warmup_timeout = int( + options.get("comunica_warmup_timeout") + or max(DEFAULT_COMUNICA_WARMUP_TIMEOUT, self.query_timeout) + ) + self.server: subprocess.Popen | None = None + self.executable: str | None = None + self.endpoint: str | None = None + self.warmup_seconds: float | None = None + self.command: list[str] = [] - def start(self) -> None: - self.executable = shutil.which("comunica-sparql-file") + def _endpoint_source_argument(self) -> str: + """The source argv entry, in whatever form this engine's binary needs.""" + raise NotImplementedError + + def _candidate_endpoints(self) -> list[str]: + return [ + f"http://127.0.0.1:{self.port}/sparql", + f"http://127.0.0.1:{self.port}/", + ] + + def _require_endpoint_binary(self) -> str: + """Fail before any expensive setup when the binary is missing. + + An engine that cannot possibly run should say so before an artifact is + built for it, not after. + """ + self.executable = shutil.which(self.endpoint_binary) if not self.executable: raise RuntimeError( - "comunica-sparql-file is not installed in this image; rebuild it or " - "select --engine qlever" + f"{self.endpoint_binary} is not installed in this image; " + f"{self.endpoint_missing_hint}" ) + return self.executable - def describe(self) -> dict[str, Any]: + def _start_endpoint(self) -> None: + if not self.executable: + self._require_endpoint_binary() + self.log_dir.mkdir(parents=True, exist_ok=True) + self.command = [ + self.executable, + self._endpoint_source_argument(), + "-p", str(self.port), + # One worker: workers share no state, so extra ones would only add + # more processes reading the same source. + "-w", "1", + # Comunica's own per-query ceiling, aligned with the client side so + # neither silently pre-empts the other. + "-t", str(self.query_timeout), + ] + server_log = self.log_dir / f"{self.name}-server.log" + self.server = subprocess.Popen( + self.command, + stdout=server_log.open("wb"), + stderr=subprocess.STDOUT, + start_new_session=True, + ) + self._await_bind(server_log) + self._await_warm(server_log) + + def _await_bind(self, server_log: Path) -> None: + """Wait for the port to answer at all. The graph is not read yet.""" + deadline = time.monotonic() + self.bind_timeout + last_error = "endpoint never bound" + while time.monotonic() < deadline: + self._assert_alive(server_log) + for endpoint in self._candidate_endpoints(): + try: + self._post(endpoint, "ASK { }", timeout=10) + self.endpoint = endpoint + return + except Exception as error: # noqa: BLE001 - readiness probe + last_error = str(error) + time.sleep(0.5) + raise RuntimeError( + f"comunica endpoint did not bind port {self.port} within " + f"{self.bind_timeout}s: {last_error}" + ) + + def _await_warm(self, server_log: Path) -> None: + """Prove the endpoint can actually read the source, before the suite runs. + + Charged to setup rather than to the first query, so one query is not + billed for readiness that every later query got for free. + """ + assert self.endpoint is not None + started = time.monotonic() + try: + self._post( + self.endpoint, "SELECT * WHERE { ?s ?p ?o } LIMIT 1", + timeout=self.warmup_timeout, + ) + except Exception as error: # noqa: BLE001 - surfaced as engine failure + self._assert_alive(server_log) + raise RuntimeError( + f"{self.name} could not read {self._endpoint_source_argument()} " + f"within {self.warmup_timeout}s (raise --comunica-warmup-timeout, " + f"or use --engine qlever): {error}" + ) from error + self.warmup_seconds = time.monotonic() - started + + def _assert_alive(self, server_log: Path) -> None: + if self.server is not None and self.server.poll() is not None: + tail = "" + try: + tail = server_log.read_text(encoding="utf-8", errors="replace")[-2000:] + except OSError: + pass + raise RuntimeError( + f"{self.name} endpoint exited with code {self.server.returncode}. " + f"Log tail: {tail}" + ) + + def _post(self, endpoint: str, query: str, *, timeout: int) -> bytes: + import urllib.request + + request = urllib.request.Request( + endpoint, + data=urllib.parse.urlencode({"query": query}).encode("utf-8"), + headers={ + "Accept": "application/sparql-results+json", + "Content-Type": "application/x-www-form-urlencoded", + }, + method="POST", + ) + with urllib.request.urlopen(request, timeout=timeout) as response: + return response.read() + + def endpoint_describe(self) -> dict[str, Any]: + """Endpoint-specific report fields, merged by each engine's describe.""" return { - "engine": self.name, - "setupSeconds": self.setup_seconds, "version": tool_version( - ["comunica-sparql-file", "--version"], table_label="Comunica Engine" + [self.endpoint_binary, "--version"], table_label="Comunica Engine" ), - "mode": "in-memory file query", + "mode": "one long-lived endpoint, source streamed per query", + "endpoint": self.endpoint, + "port": self.port, + # Readiness, not a graph load: the source is not materialized. + "warmupSeconds": self.warmup_seconds, + "command": list(self.command), } def execute(self, query_id: str, query_path: Path) -> dict[str, Any]: raw_path = self.raw_dir / f"{query_id}.sparql.json" stderr_path = self.raw_dir / f"{query_id}.stderr.txt" - time_path = self.raw_dir / f"{query_id}.time.txt" - command = [ - self.executable, - str(self.source), - "-f", - str(query_path), - "-t", - "application/sparql-results+json", - ] - timed = ( - ["/usr/bin/time", "-v", "-o", str(time_path), *command] - if tool_version(["/usr/bin/time", "--version"]) - else command - ) started = time.monotonic() - returncode, error = run_query_process( - timed, stdout_path=raw_path, stderr_path=stderr_path, - timeout=self.query_timeout, - ) + if self.endpoint is None: + message = f"{self.name} endpoint is not running" + stderr_path.write_text(message, encoding="utf-8") + raw_path.write_bytes(b"") + return self._envelope( + query_id, query_path, returncode=1, started=started, + raw_path=raw_path, stderr_path=stderr_path, error=message, + ) + try: + payload = self._post( + self.endpoint, query_path.read_text(encoding="utf-8"), + timeout=self.query_timeout, + ) + except Exception as error: # noqa: BLE001 - reported as EXECUTION_FAILED + stderr_path.write_text(str(error), encoding="utf-8") + raw_path.write_bytes(b"") + return self._envelope( + query_id, query_path, returncode=1, started=started, + raw_path=raw_path, stderr_path=stderr_path, error=str(error), + ) + raw_path.write_bytes(payload) + stderr_path.write_bytes(b"") return self._envelope( - query_id, query_path, returncode=returncode, started=started, - raw_path=raw_path, stderr_path=stderr_path, time_path=time_path, error=error, + query_id, query_path, returncode=0, started=started, + raw_path=raw_path, stderr_path=stderr_path, ) + def stop(self) -> None: + if self.server is not None and self.server.poll() is None: + # The endpoint holds the whole graph in memory; a survivor would + # starve everything that runs after it, so the group is signalled + # rather than just the leader. + _terminate_process_group(self.server) + self.server = None + self.endpoint = None + + +class ComunicaEngine(ComunicaHttpEndpointMixin, QueryEngine): + """Serve the N-Triples file from one load via comunica-sparql-file-http.""" + + name = "comunica" + endpoint_binary = "comunica-sparql-file-http" + endpoint_port_option = "comunica_port" + default_endpoint_port = DEFAULT_COMUNICA_PORT + + def __init__(self, source: Path, *, raw_dir: Path, scratch: Path, options: dict[str, Any]): + super().__init__(source, raw_dir=raw_dir, scratch=scratch, options=options) + self.log_dir = raw_dir / "engine" + self._init_endpoint(options) + + def _endpoint_source_argument(self) -> str: + return str(self.source) + + def start(self) -> None: + self._start_endpoint() + + def describe(self) -> dict[str, Any]: + return { + "engine": self.name, + "setupSeconds": self.setup_seconds, + **self.endpoint_describe(), + } + class QleverEngine(QueryEngine): """Build a QLever index over the graph, then answer queries over HTTP. @@ -2080,11 +2409,30 @@ def describe(self) -> dict[str, Any]: } -class HdtEngine(NativeArtifactEngine): - """Query a .hdt artifact in place with Comunica's HDT engine.""" +class HdtEngine(ComunicaHttpEndpointMixin, NativeArtifactEngine): + """Query a .hdt artifact in place, from one load, over Comunica's endpoint. + + The one-shot ``comunica-sparql-hdt`` CLI was previously spawned per query, + so every query re-opened the artifact and re-initialised the engine. HDT is + memory-mapped rather than parsed, so the per-query cost is far smaller than + Comunica's N-Triples reload -- but it is still paid 27 times for nothing, + and it makes the measured query time include engine startup, which is + exactly what a benchmark must not do. + """ name = "hdt" artifact_format = "hdt" + endpoint_binary = "comunica-sparql-hdt-http" + endpoint_port_option = "hdt_port" + default_endpoint_port = DEFAULT_HDT_ENDPOINT_PORT + endpoint_missing_hint = ( + "so HDT cannot be queried natively. Rebuild the image, or validate the " + "HDT artifact by decoding it (--rdf file.hdt --engine comunica)" + ) + + def __init__(self, source: Path, *, raw_dir: Path, scratch: Path, options: dict[str, Any]): + super().__init__(source, raw_dir=raw_dir, scratch=scratch, options=options) + self._init_endpoint(options) def build_artifact(self, target: Path) -> None: rdf2hdt = _resolve_binary("RDF2HDT_BIN", "rdf2hdt", "/usr/local/bin/rdf2hdt") @@ -2093,36 +2441,25 @@ def build_artifact(self, target: Path) -> None: label="hdt-engine-build", log_dir=self.log_dir, ) + def _endpoint_source_argument(self) -> str: + # Comunica needs the source type declared: a bare path is treated as a + # link to dereference and fails with "could not dereference". + return f"hdt@{self.artifact}" + def start(self) -> None: - self.executable = shutil.which("comunica-sparql-hdt") - if not self.executable: - raise RuntimeError( - "comunica-sparql-hdt is not installed in this image, so HDT cannot " - "be queried natively. Rebuild the image, or validate the HDT " - "artifact by decoding it (--rdf file.hdt --engine comunica)" - ) - super().start() + # Check the binary before resolving the artifact: building an HDT for + # an engine that cannot run wastes the most expensive step in the run. + self._require_endpoint_binary() + # Then resolve (or build) the artifact; the endpoint needs its path. + NativeArtifactEngine.start(self) + self._start_endpoint() - def execute(self, query_id: str, query_path: Path) -> dict[str, Any]: - raw_path = self.raw_dir / f"{query_id}.sparql.json" - stderr_path = self.raw_dir / f"{query_id}.stderr.txt" - command = [ - self.executable, - # Comunica needs the source type declared: a bare path is treated - # as a link to dereference and fails with "could not dereference". - f"hdt@{self.artifact}", - "-f", str(query_path), - "-t", "application/sparql-results+json", - ] - started = time.monotonic() - returncode, error = run_query_process( - command, stdout_path=raw_path, stderr_path=stderr_path, - timeout=self.query_timeout, - ) - return self._envelope( - query_id, query_path, returncode=returncode, started=started, - raw_path=raw_path, stderr_path=stderr_path, error=error, - ) + def describe(self) -> dict[str, Any]: + return { + **NativeArtifactEngine.describe(self), + **self.endpoint_describe(), + "mode": "native hdt query, no decode, single load served over HTTP", + } class CottasEngine(NativeArtifactEngine): @@ -2733,7 +3070,7 @@ def build_manifest( "python": platform.python_version(), "cyvcf2": getattr(cyvcf2, "__version__", None), "bcftools": tool_version(["bcftools", "--version"]), "node": tool_version(["node", "--version"]), - "comunicaQuerySparqlFile": tool_version(["comunica-sparql-file", "--version"], table_label="Comunica Engine"), + "comunicaQuerySparqlFile": tool_version(["comunica-sparql-file-http", "--version"], table_label="Comunica Engine"), "rapper": tool_version(["rapper", "--version"]), }, "queries": {path.stem: {"path": str(path), "sha256": sha256_file(path)} for path in query_paths}, @@ -2823,6 +3160,10 @@ def run_validation(args: argparse.Namespace) -> int: "query_timeout": args.query_timeout, "extra_index_args": list(args.qlever_index_arg), "extra_server_args": list(args.qlever_server_arg), + "comunica_port": args.comunica_port, + "hdt_port": args.hdt_port, + "comunica_bind_timeout": args.comunica_bind_timeout, + "comunica_warmup_timeout": args.comunica_warmup_timeout, } engine_options["artifact_path"] = str(args.rdf) engine_options["artifact_format"] = args.rdf_format @@ -2901,13 +3242,18 @@ def run_validation(args: argparse.Namespace) -> int: detail=f"{engine_name}: completed {query_id}", ) - # A query that exceeded the timeout says the engine - # cannot answer this graph in the time allowed, and the - # remaining queries are no easier. Running all of them - # anyway costs one timeout each: with the defaults that - # is 27 hours per engine per target, which is how a - # validation step comes to look like a hang rather than - # a failure. Stop and report instead. + # A query that fails, times out, or returns the wrong + # answer never stops the suite: its verdict is recorded + # and the next query runs. Coverage is the point -- + # "26 of 27 passed, q11 disagreed" is a result, while + # "stopped at q01" is not. + # + # --stop-after-query-timeout opts back into abandoning + # the rest, which caps the worst case at one timeout + # per engine rather than one per query. It is off by + # default now that each engine loads the graph once + # instead of once per query, so the remaining queries + # no longer each re-pay that load. if ( args.stop_after_query_timeout and executions[query_id].get("exitCode") == 124 @@ -3114,16 +3460,27 @@ def build_arg_parser() -> argparse.ArgumentParser: "--stop-after-query-timeout handle the common case." ), ) + parser.add_argument( + "--stop-after-query-timeout", + dest="stop_after_query_timeout", + action="store_true", + default=False, + help=( + "Abandon an engine's remaining queries once one exceeds the " + "per-query timeout. Off by default: a validation suite reports " + "coverage, so a run is worth far more when every query has a " + "recorded verdict than when it stops at the first slow one. Turn " + "this on to cap the worst case at one timeout per engine instead " + "of one per query" + ), + ) parser.add_argument( "--continue-after-query-timeout", dest="stop_after_query_timeout", action="store_false", - default=True, help=( - "Keep running an engine's remaining queries after one exceeds the " - "per-query timeout. Off by default: a timeout means the engine " - "cannot answer this graph in the time allowed, and the remaining " - "queries cost one timeout each" + "Run every query even after one times out. This is now the " + "default; the flag is kept so existing callers keep working" ), ) parser.add_argument( @@ -3144,6 +3501,40 @@ def build_arg_parser() -> argparse.ArgumentParser: default=DEFAULT_QLEVER_PORT, help=f"Container-local QLever port (default: {DEFAULT_QLEVER_PORT})", ) + parser.add_argument( + "--comunica-port", + type=int, + default=DEFAULT_COMUNICA_PORT, + help=f"Container-local Comunica endpoint port (default: {DEFAULT_COMUNICA_PORT})", + ) + parser.add_argument( + "--hdt-port", + type=int, + default=DEFAULT_HDT_ENDPOINT_PORT, + help=( + "Container-local port for the native HDT endpoint " + f"(default: {DEFAULT_HDT_ENDPOINT_PORT})" + ), + ) + parser.add_argument( + "--comunica-bind-timeout", + type=int, + default=DEFAULT_COMUNICA_BIND_TIMEOUT, + help=( + "Seconds to wait for the Comunica endpoint to bind its port, before " + f"the graph is read (default: {DEFAULT_COMUNICA_BIND_TIMEOUT})" + ), + ) + parser.add_argument( + "--comunica-warmup-timeout", + type=int, + default=DEFAULT_COMUNICA_WARMUP_TIMEOUT, + help=( + "Seconds allowed for the Comunica endpoint's warm-up query, which " + "proves it can read the source before the suite starts " + f"(default: {DEFAULT_COMUNICA_WARMUP_TIMEOUT})" + ), + ) parser.add_argument( "--qlever-startup-timeout", type=int, @@ -3280,6 +3671,8 @@ def resolve_args(parser: argparse.ArgumentParser, argv: list[str] | None = None) ("--query-timeout", args.query_timeout), ("--qlever-memory-gb", args.qlever_memory_gb), ("--qlever-startup-timeout", args.qlever_startup_timeout), + ("--comunica-bind-timeout", args.comunica_bind_timeout), + ("--comunica-warmup-timeout", args.comunica_warmup_timeout), ): if value <= 0: parser.error(f"{name} must be a positive integer") @@ -3288,6 +3681,12 @@ def resolve_args(parser: argparse.ArgumentParser, argv: list[str] | None = None) parser.error("--validation-time-budget must be zero or a positive integer") if not 1 <= args.qlever_port <= 65535: parser.error("--qlever-port must be between 1 and 65535") + if not 1 <= args.comunica_port <= 65535: + parser.error("--comunica-port must be between 1 and 65535") + if not 1 <= args.hdt_port <= 65535: + parser.error("--hdt-port must be between 1 and 65535") + if len({args.comunica_port, args.qlever_port, args.hdt_port}) != 3: + parser.error("--comunica-port, --qlever-port and --hdt-port must all differ") if args.shacl_shapes is not None: args.shacl_shapes = args.shacl_shapes.resolve() if not args.shacl_shapes.is_file(): diff --git a/test/test_validation_benchmark_unit.py b/test/test_validation_benchmark_unit.py index d80e4c1..6643e4d 100644 --- a/test/test_validation_benchmark_unit.py +++ b/test/test_validation_benchmark_unit.py @@ -157,27 +157,64 @@ def test_hdt_queries_are_addressed_with_comunicas_typed_source_prefix(self): Verified against comunica-sparql-hdt 5.0.1: '/tmp/g.hdt' reports "Could not dereference", while 'hdt@/tmp/g.hdt' answers the query. + The typed prefix now goes to the endpoint at startup rather than into + each query's argv, but it is no less required. """ with tempfile.TemporaryDirectory() as td: tmp_path = Path(td) raw_dir = tmp_path / "raw" raw_dir.mkdir() - query = tmp_path / "q.rq" - query.write_text("SELECT * WHERE { ?s ?p ?o }", encoding="utf-8") engine = self._engine("hdt", tmp_path) - engine.executable = "/usr/bin/comunica-sparql-hdt" engine.artifact = tmp_path / "cohort.hdt" - recorded = {} - - def fake_run(command, **kwargs): - recorded["command"] = command - return 0, None + self.assertEqual( + engine._endpoint_source_argument(), + f"hdt@{tmp_path / 'cohort.hdt'}", + ) - with mock.patch.object(V, "run_query_process", side_effect=fake_run): - envelope = engine.execute("q01", query) + def test_hdt_loads_the_artifact_once_for_the_whole_query_set(self): + """Every query must be answered from one load, not one process each. - self.assertEqual(recorded["command"][1], f"hdt@{tmp_path / 'cohort.hdt'}") - self.assertIn("application/sparql-results+json", recorded["command"]) + The one-shot CLI was spawned per query, so each of the 27 queries + re-opened the artifact and re-initialised the engine - and every + measured query time silently included that startup. + """ + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + raw_dir = tmp_path / "raw" + raw_dir.mkdir() + query = tmp_path / "q.rq" + query_text = "SELECT * WHERE { ?s ?p ?o }" + query.write_text(query_text, encoding="utf-8") + engine = self._engine("hdt", tmp_path) + engine.artifact = tmp_path / "cohort.hdt" + posted = [] + + def fake_post(self, endpoint, q, *, timeout): + posted.append(q) + return b'{"results": {"bindings": []}}' + + with mock.patch.object( + V.shutil, "which", + return_value="/usr/bin/comunica-sparql-hdt-http", + ), \ + mock.patch.object(V, "tool_version", return_value=None), \ + mock.patch.object( + V.NativeArtifactEngine, "start", lambda self: None + ), \ + mock.patch.object(V.subprocess, "Popen") as popen, \ + mock.patch.object(V.ComunicaHttpEndpointMixin, "_post", fake_post): + popen.return_value.poll.return_value = None + engine.start() + for query_id in ("q01", "q02", "q03"): + envelope = engine.execute(query_id, query) + + # One server process for the whole set. + self.assertEqual(popen.call_count, 1) + command = popen.call_args[0][0] + self.assertIn(f"hdt@{tmp_path / 'cohort.hdt'}", command) + self.assertEqual(command[command.index("-w") + 1], "1") + # Three queries answered from that single load. + self.assertEqual(len([q for q in posted if q == query_text]), 3) self.assertEqual(envelope["status"], "PASS") self.assertEqual(envelope["engine"], "hdt") diff --git a/test/test_validation_engines_unit.py b/test/test_validation_engines_unit.py index 1c0d9d4..9a227da 100644 --- a/test/test_validation_engines_unit.py +++ b/test/test_validation_engines_unit.py @@ -102,9 +102,9 @@ def test_hdt_is_decoded_with_hdt2rdf(self): scratch.mkdir() calls = [] - def fake_run(command, **kwargs): + def fake_run(command, stdout=None, stderr=None, **kwargs): calls.append(command) - Path(command[2]).write_bytes(TRIPLES) + stdout.write(TRIPLES) return subprocess.CompletedProcess(command, 0) with mock.patch.object(V, "_resolve_binary", return_value="/usr/local/bin/hdt2rdf"), \ @@ -113,9 +113,65 @@ def fake_run(command, **kwargs): source, "hdt", scratch, log_dir=tmp_path / "log" ) self.assertEqual(calls[0][0], "/usr/local/bin/hdt2rdf") - self.assertEqual(calls[0][1], str(source)) + self.assertIn(str(source), calls[0]) + # hdt-cpp's file-output serializer is broken, so the dump is taken + # from stdout: the target must never appear as an argv entry. + self.assertEqual(calls[0][-1], "-") + self.assertNotIn(str(decoded), calls[0]) self.assertEqual(decoded.read_bytes(), TRIPLES) self.assertTrue(provenance["materialized"]) + self.assertEqual(provenance["steps"][0]["mode"], "stdout-redirect") + + def test_hdt2rdf_write_errors_fail_even_when_it_exits_zero(self): + """hdt-cpp reports write errors on stderr and still returns success. + + That is how a 4.4 GiB file of truncated subject IRIs with no newline in + it reached rapper, which spent 38 hours on 23% of it before anyone + noticed. An exit code is only as trustworthy as the tool returning it. + """ + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + source = tmp_path / "cohort.hdt" + source.write_bytes(b"fake-hdt") + scratch = tmp_path / "scratch" + scratch.mkdir() + + def fake_run(command, stdout=None, stderr=None, **kwargs): + stdout.write(b"

.\n

None: + """Fold the run id into the container label once it is known. + + Purely for legibility: `docker ps --filter label=vcf-rdfizer.run` should + show which run a stray container belongs to. + """ + global _DOCKER_RUN_LABEL_VALUE + _DOCKER_RUN_LABEL_VALUE = f"{run_id}-{os.getpid()}" + + +def docker_run_label_filter() -> str: + return f"label={DOCKER_RUN_LABEL_KEY}={_DOCKER_RUN_LABEL_VALUE}" + + def docker_run_base(*, as_user: bool = True): """Return base args for `docker run`, optionally mapped to host UID/GID.""" - base = [*docker_cmd_prefix(), "run", "--rm"] + base = [ + *docker_cmd_prefix(), "run", "--rm", + "--label", f"{DOCKER_RUN_LABEL_KEY}={_DOCKER_RUN_LABEL_VALUE}", + ] if not as_user: return base as_user = os.environ.get("VCF_RDFIZER_DOCKER_AS_USER", "1").strip().lower() @@ -1624,6 +1658,98 @@ def remove_path_with_docker_fallback( return True +def kill_run_containers(*, run_tracker: RunTracker | None = None) -> tuple[int, int]: + """Stop every container this wrapper started. Returns ``(killed, failed)``. + + Killing the wrapper does not kill its containers. ``docker run`` forwards a + SIGINT it receives itself, but a wrapper that dies without forwarding -- + SIGTERM, a closed terminal, an exception unwinding past the wait -- leaves + the container running and reparented to init. One such orphan ran for three + days after its run had "finished", holding 17 GB and a core the whole time. + + Worse, cleanup then deleted files the orphan was still reading, so the + container spent those days working against inputs that no longer existed. + That is why this runs *before* any temporary file is removed. + + Best effort by construction: an interrupt path must never raise. Every + failure is counted and reported, never propagated. + """ + killed = 0 + failed = 0 + try: + listing = subprocess.run( + [*docker_cmd_prefix(), "ps", "-q", "--filter", docker_run_label_filter()], + check=False, capture_output=True, text=True, timeout=30, + ) + except (OSError, subprocess.SubprocessError) as error: + if run_tracker is not None: + run_tracker.mark(f"Interrupt cleanup: could not list containers ({error})") + return 0, 0 + + container_ids = [line.strip() for line in listing.stdout.splitlines() if line.strip()] + if not container_ids: + return 0, 0 + + for container_id in container_ids: + try: + result = subprocess.run( + [*docker_cmd_prefix(), "kill", container_id], + check=False, capture_output=True, text=True, timeout=60, + ) + if result.returncode == 0: + killed += 1 + else: + failed += 1 + except (OSError, subprocess.SubprocessError): + failed += 1 + + if run_tracker is not None: + run_tracker.mark( + f"Interrupt cleanup: stopped containers killed={killed}, failed={failed}" + ) + return killed, failed + + +def write_interrupt_checkpoint( + *, + run_tracker: RunTracker, + metrics_dir: Path, + run_id: str, + mode: str, + containers_killed: int, + containers_failed: int, + removed: int | None, + failed: int | None, +) -> Path | None: + """Record where an interrupted run stopped, so it can be resumed or read. + + A run that is killed mid-flight still produced real measurements for every + stage it finished. Without a checkpoint those are only recoverable by + reading the progress log by eye, and nothing records *why* the run ended. + """ + checkpoint = { + "run_id": run_id, + "mode": mode, + "status": "interrupted", + "exit_code": 130, + "interrupted_at": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), + "containers": {"killed": containers_killed, "failed": containers_failed}, + "temporaries": {"removed": removed, "failed": failed}, + "stages_completed": list(run_tracker.completed_stages), + "last_event": run_tracker.events[-1] if run_tracker.events else None, + "tracked_intermediates": sorted(str(p) for p in run_tracker.intermediate_paths), + } + try: + path = metrics_dir / "interrupt-checkpoint.json" + path.parent.mkdir(parents=True, exist_ok=True) + path.write_text(json.dumps(checkpoint, indent=2) + "\n", encoding="utf-8") + run_tracker.mark(f"Interrupt checkpoint written: {path}") + return path + except OSError as error: + run_tracker.mark(f"Interrupt checkpoint could not be written: {error}") + return None + + def cleanup_interrupted_full_run( *, run_tracker: RunTracker, @@ -7969,12 +8095,17 @@ def run_validation_mode( ("--qlever-memory-gb", "qlever_memory_gb"), ("--qlever-port", "qlever_port"), ("--qlever-startup-timeout", "qlever_startup_timeout"), + ("--comunica-port", "comunica_port"), + ("--hdt-port", "hdt_port"), + ("--comunica-warmup-timeout", "comunica_warmup_timeout"), ): value = options.get(key) if value is not None: engine_args.extend([flag, str(value)]) - if options.get("continue_after_query_timeout"): - engine_args.append("--continue-after-query-timeout") + # Running every query is the default; the runner still accepts the old + # continue flag, and stopping early is now the thing you opt into. + if options.get("stop_after_query_timeout"): + engine_args.append("--stop-after-query-timeout") for flag, key in ( ("--qlever-index-arg", "qlever_index_args"), ("--qlever-server-arg", "qlever_server_args"), @@ -8495,10 +8626,17 @@ def main(): "--validation-continue-after-query-timeout", action="store_true", help=( - "Keep running an engine's remaining validation queries after one " - "exceeds the per-query timeout. Off by default: a timeout means " - "the engine cannot answer this graph in the time allowed, and each " - "remaining query costs another full timeout" + "Run every validation query even after one times out. This is now " + "the default; the flag is kept so existing callers keep working" + ), + ) + parser.add_argument( + "--validation-stop-after-query-timeout", + action="store_true", + help=( + "Abandon an engine's remaining validation queries once one exceeds " + "the per-query timeout. Off by default: every query gets a " + "recorded verdict, which is what makes a validation run reportable" ), ) parser.add_argument( @@ -8608,8 +8746,13 @@ def main(): "--validation-time-budget must be zero or a positive integer" ) validation_engine_options["validation_time_budget"] = budget - if args.validation_continue_after_query_timeout: - validation_engine_options["continue_after_query_timeout"] = True + if args.validation_stop_after_query_timeout: + if args.validation_continue_after_query_timeout: + raise ValueError( + "--validation-continue-after-query-timeout and " + "--validation-stop-after-query-timeout are mutually exclusive" + ) + validation_engine_options["stop_after_query_timeout"] = True if args.qlever_index_arg: validation_engine_options["qlever_index_args"] = list(args.qlever_index_arg) if args.qlever_server_arg: @@ -9002,6 +9145,9 @@ def main(): wrapper_log_path = metrics_dir / "logs" / "wrapper.log" progress_log_path = metrics_dir / "logs" / "progress.log" execution_started = time.perf_counter() + # Stamp containers with this run before any of them start, so an interrupt + # can identify exactly the ones it owns. + set_docker_run_label(run_id) global _COMMAND_LOGGER _COMMAND_LOGGER = CommandLogger(wrapper_log_path) run_tracker = RunTracker(progress_log_path) @@ -9247,21 +9393,73 @@ def _interrupt_handler(_signum, _frame): result_code = 130 eprint("Run interrupted by user signal; starting best-effort cleanup.") run_tracker.mark("Run interrupted by user signal") - if mode == "full": - removed, failed = cleanup_interrupted_full_run( - run_tracker=run_tracker, - out_root=out_root, - image_ref=resolved_image_ref, - keep_rmlstreamer_rdf_output=args.keep_rmlstreamer_rdf_output, - wrapper_log_path=wrapper_log_path, + + # Ignore a second interrupt for the duration of cleanup. Ctrl-C twice + # is exactly what an impatient operator does, and it used to abort the + # cleanup halfway -- leaving behind the containers this is here to + # stop. Cleanup is bounded and short; let it finish. + previous_sigint = signal.getsignal(signal.SIGINT) + try: + signal.signal(signal.SIGINT, signal.SIG_IGN) + except (OSError, ValueError): # not the main thread, or unsupported + previous_sigint = None + + removed = failed = None + containers_killed = containers_failed = 0 + try: + # Containers first, and for every mode -- validation, compress and + # index all start containers too, and every one of them outlives + # the wrapper unless it is killed here. This must precede the file + # removal below: deleting inputs from under a live container is + # how an orphaned run spent three days reading files that no + # longer existed. + containers_killed, containers_failed = kill_run_containers( + run_tracker=run_tracker ) - eprint( - "Interrupt cleanup summary: " - "removed=" - f"{removed}, failed={failed}, " - "keep_rmlstreamer_rdf_output=" - f"{str(args.keep_rmlstreamer_rdf_output).lower()}" + if containers_killed or containers_failed: + eprint( + "Interrupt cleanup: stopped containers " + f"killed={containers_killed}, failed={containers_failed}" + ) + + if mode == "full": + removed, failed = cleanup_interrupted_full_run( + run_tracker=run_tracker, + out_root=out_root, + image_ref=resolved_image_ref, + keep_rmlstreamer_rdf_output=args.keep_rmlstreamer_rdf_output, + wrapper_log_path=wrapper_log_path, + ) + eprint( + "Interrupt cleanup summary: " + "removed=" + f"{removed}, failed={failed}, " + "keep_rmlstreamer_rdf_output=" + f"{str(args.keep_rmlstreamer_rdf_output).lower()}" + ) + + checkpoint_path = write_interrupt_checkpoint( + run_tracker=run_tracker, + metrics_dir=metrics_dir, + run_id=run_id, + mode=mode, + containers_killed=containers_killed, + containers_failed=containers_failed, + removed=removed, + failed=failed, ) + if checkpoint_path is not None: + eprint(f"Interrupt checkpoint: {checkpoint_path}") + except Exception as cleanup_error: # noqa: BLE001 - never mask the interrupt + eprint(f"Interrupt cleanup did not complete: {cleanup_error}") + run_tracker.mark(f"Interrupt cleanup error: {cleanup_error}") + finally: + if previous_sigint is not None: + try: + signal.signal(signal.SIGINT, previous_sigint) + except (OSError, ValueError): + pass + eprint(f"Progress log: {progress_log_path}") finally: if hasattr(signal, "SIGTERM") and original_sigterm is not None: From 4eb88e1ce54b809a3f815843f111ef1515500fdd Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Thu, 10 Sep 2026 14:44:50 +0200 Subject: [PATCH 5/9] small behavior changes and optimizaitons --- .gitignore | 1 + README.md | 2 +- changelog.md | 55 +++++++ docs/cli-reference.md | 16 +- docs/representations.md | 38 ++++- test/README.md | 44 ++++++ .../test-larger-multisample.vcf.gz | Bin 0 -> 1362251 bytes test/test_vcf_rdfizer_unit.py | 99 +++++++++++- vcf-rdfizer-v1.0.0.tar.gz | Bin 147956 -> 0 bytes vcf-rdfizer-v1.1.0.tar.gz | Bin 284630 -> 0 bytes vcf_rdfizer.py | 141 +++++++++++++----- 11 files changed, 342 insertions(+), 54 deletions(-) create mode 100644 test/test_vcf_files/test-larger-multisample.vcf.gz delete mode 100644 vcf-rdfizer-v1.0.0.tar.gz delete mode 100644 vcf-rdfizer-v1.1.0.tar.gz diff --git a/.gitignore b/.gitignore index 0b1216f..4638a62 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ test/test_vcf_files/* !test/test_vcf_files/test-1k.vcf !test/test_vcf_files/test-10k.vcf !test/test_vcf_files/test-larger.vcf.gz +!test/test_vcf_files/test-larger-multisample.vcf.gz RMLStreamer-v2.5.0-standalone.jar out/ diff --git a/README.md b/README.md index 5a3dbcb..bdd5c31 100644 --- a/README.md +++ b/README.md @@ -262,7 +262,7 @@ host filesystem. - `--filter-oracle {auto,bcftools,cyvcf2}` FILTER oracle for `--validate` - `--quiet` suppress terminal progress and validation query chatter while retaining logs/metrics - `--no-progress` disable progress sidecars and terminal progress displays -- `--rdf-storage-mode {plain,space-optimized}` required full-mode aggregate storage policy +- `--rdf-storage-mode {plain,space-optimized}` full-mode aggregate storage policy (default: `space-optimized`) - `plain`: merge RMLStreamer parts into one uncompressed `.nt` - `space-optimized`: gzip each part into one `.nt.gz` aggregate and delete the source part immediately - `--rdf-compression {gzip,brotli,none}` raw RDF artifacts to retain diff --git a/changelog.md b/changelog.md index 0861192..474c4de 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,60 @@ # Changelog +## 2026-09-10 — Space-optimized by default, and `--hdt-strategy single` stops lying + +Benchmarking the two aggregate storage modes as a paired comparison showed +`space-optimized` reaches the same triples as `plain` at a much smaller peak +workspace footprint, with no practically important change in wall time, CPU +time, or peak memory. A flag with an answer that good should not be mandatory. + +The same experiment exposed that `--hdt-strategy single` was being silently +ignored in the most common configuration anyone would pass it in. + +### Changed + +- **`--rdf-storage-mode` now defaults to `space-optimized`** instead of being + required in full mode. `plain` remains available and is unchanged; it is what + `--hdt-strategy single` needs, and what to pass when one uncompressed `.nt` + aggregate on disk is the point. The new `DEFAULT_RDF_STORAGE_MODE` constant + carries the value. +- **`--hdt-strategy single` is documented as a verification path, not a faster + alternative.** There is no size regime where it wins: below + `--chunk-min-bytes` the partitioned path emits one chunk and its merge is + trivial, so the two converge, and above it partitioned is the only one that + survives cohort scale. What `single` is for is producing a one-shot HDT of the + same graph so the chunk-and-merge result can be checked against it — which is + what justifies partitioned generation being the default rather than merely + convenient. + +### Fixed + +- **`--hdt-strategy single` is no longer silently ignored when COTTAS is + selected.** COTTAS always needs bounded chunks, and both dispatch sites gate + partitioning on one boolean, so `--representations hdt,cottas --hdt-strategy + single` ran the partitioned path for both representations with the strategy + having no effect. Benchmark runs using that combination were measuring + partitioned HDT under a `single` label. It is now refused with a message + naming the remedy. +- **The two `single` refusals share one implementation.** `hdt_strategy_rejection` + replaces three separately worded inline checks across full-mode validation, + compress-mode validation, and the compress-mode runtime guard. The gzip-aggregate + message now also names `--rdf-storage-mode plain`, which matters more than it + did: with `space-optimized` the default, `single` needs that flag explicitly. + +### Tests + +- `test_main_full_mode_requires_storage_mode_argument` is replaced by + `test_main_full_mode_defaults_to_space_optimized_storage`, which asserts the + resolved value reaching `run_full_mode`. +- Added `test_main_full_mode_rejects_single_hdt_strategy_with_cottas` and + `test_main_full_mode_rejects_single_hdt_strategy_with_space_optimized`. +- The mocked RMLStreamer runner now reads `RDF_STORAGE_MODE` from the container + command and writes a real gzip aggregate for `space-optimized`, so the + default path is exercisable end to end rather than only under `plain`. + +Suite: **436 passing, 147 skipped** (all skips are the pre-existing `rdflib` +gates on the mutation and linking harnesses). + ## 2026-09-08 — Run without the data-linking dependency Running the tool from a checkout raised `ModuleNotFoundError: No module named diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 01ed405..f760610 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -77,7 +77,7 @@ See [Data linking](datalinking.md) for commands and current limits. There is no | Flag | Values | Default | | --- | --- | --- | -| `--rdf-storage-mode` | `plain`, `space-optimized` | **required in full mode** | +| `--rdf-storage-mode` | `plain`, `space-optimized` | `space-optimized` | | `--rdf-compression` | `gzip`, `brotli`, `none` | `gzip,brotli` | | `--representations` | `hdt`, `cottas`, `none` | `hdt` | | `--artifact-compression` | `gzip`, `brotli`, `none` | `none` | @@ -86,11 +86,23 @@ See [Data linking](datalinking.md) for commands and current limits. There is no | `--chunk-min-bytes` | bytes | 128 MiB | | `--chunk-max-bytes` | bytes | 1 GiB | +`--rdf-storage-mode` defaults to `space-optimized`: it reaches the same triples +as `plain` at a much smaller peak workspace footprint and no practically +important compute penalty, so the low-disk path is what a caller gets without +having to ask for it. Pass `plain` when you want one uncompressed `.nt` +aggregate on disk, which is also what `--hdt-strategy single` requires. + Constraints that are enforced rather than documented-and-hoped: - Each selector takes a comma-separated list; `none` must appear alone. - `--artifact-compression` requires at least one selected representation. -- `--hdt-strategy single` cannot consume a `space-optimized` gzip stream. +- `--hdt-strategy single` cannot consume a `space-optimized` gzip stream, and + is rejected rather than silently downgraded. Since `space-optimized` is now + the default, `single` needs an explicit `--rdf-storage-mode plain`. +- `--hdt-strategy single` is also rejected when `cottas` is among the + `--representations`. COTTAS always needs bounded chunks, so the partitioned + path would run for both representations and the strategy would have no + effect; earlier releases ignored the flag silently in this case. `-c, --compression` is a hidden legacy alias retained for backward compatibility. Use the three explicit selectors. diff --git a/docs/representations.md b/docs/representations.md index 9938280..676a774 100644 --- a/docs/representations.md +++ b/docs/representations.md @@ -11,7 +11,7 @@ Compression is deliberately not one option. It is three: | Decision | Flag | Values | Default | | --- | --- | --- | --- | -| How the aggregate is staged | `--rdf-storage-mode` | `plain`, `space-optimized` | *(required in full mode)* | +| How the aggregate is staged | `--rdf-storage-mode` | `plain`, `space-optimized` | `space-optimized` | | Which raw RDF artifacts to keep | `--rdf-compression` | `gzip`, `brotli`, `none` | `gzip,brotli` | | Which queryable representations to build | `--representations` | `hdt`, `cottas`, `none` | `hdt` | | How to package those representations | `--artifact-compression` | `gzip`, `brotli`, `none` | `none` | @@ -54,9 +54,36 @@ usable without ever expanding a second full raw copy. | `--chunk-max-bytes` | hard ceiling; boundaries stay on complete lines | 1 GiB | `--hdt-strategy` chooses the policy: `auto` (build chunks and merge with native -`hdtc`), `partitioned` (always chunk), `single` (one `rdf2hdt` run). `single` -cannot consume a gzip stream without expanding it, so it is incompatible with -`space-optimized`. +`hdtc`), `partitioned` (always chunk), `single` (one `rdf2hdt` run). + +**`single` is a verification path, not a faster alternative.** There is no size +regime in which it wins: below `--chunk-min-bytes` the partitioned path emits +one chunk and its merge is trivial, so the two converge, and above it +partitioned is the only one that survives cohort scale. What `single` is for is +producing a one-shot HDT of the same graph so the chunk-and-merge result can be +checked against it — identical triple counts and identical query answers are +what justify partitioned generation being the default, rather than it merely +being convenient. + +It applies only to an HDT-only run over an uncompressed aggregate, and both +other cases are refused rather than silently downgraded: + +- a gzip aggregate cannot be read in one pass without expanding a second full + uncompressed copy, so `single` is incompatible with `space-optimized` and + needs an explicit `--rdf-storage-mode plain`; +- `cottas` among the `--representations` always needs bounded chunks, so the + partitioned path would run for both representations and the strategy would + have no effect. Earlier releases ignored the flag silently here, which meant a + `--representations hdt,cottas --hdt-strategy single` run measured partitioned + HDT under a `single` label. + +So the one configuration where `single` does what it says is: + +```bash +vcf-rdfizer --mode full --input cohort.vcf.gz \ + --rdf-storage-mode plain --representations hdt \ + --rdf-compression none --hdt-strategy single --out results +``` The whole partitioned stage runs in an **ephemeral Docker-managed volume**. Chunks, scratch, and merge files never reach the output directory, and the @@ -154,7 +181,8 @@ unwrapped file never appears on the host. | Queryable, single artifact, smallest footprint | `--representations hdt --rdf-compression none --remove-rdf-storage-output` | | Comparing HDT against COTTAS | `--representations hdt,cottas` | | Archival transfer | `--artifact-compression brotli` on top of the chosen representation | -| Memory-constrained host | `space-optimized` + `partitioned` + lower `--chunk-*-bytes` | +| Memory-constrained host | `space-optimized` + `partitioned` (both default) + lower `--chunk-*-bytes` | +| Verifying the partitioned merge | `plain` + `--representations hdt` + `single`, compared against `partitioned` | ## 10. Limitations diff --git a/test/README.md b/test/README.md index 4fb422f..4b6fa46 100644 --- a/test/README.md +++ b/test/README.md @@ -91,6 +91,50 @@ This repository uses `unittest` (Python standard library) to isolate orchestrati - Verifies that an unresolvable file falls back rather than reporting a wrong size, including the 32-bit `ISIZE` wrap and multi-member trailers. +## VCF fixtures (`test/test_vcf_files/`) + +`test/test_vcf_files/*` is gitignored with an explicit `!` exception per file, +so a new fixture is invisible to git until `.gitignore` names it. + +| File | Records | Samples | Uncompressed | Purpose | +| --- | --- | --- | --- | --- | +| `test-100.vcf` | 100 | 1 | 6 KB | Fast unit-test input; mapping smoke tests | +| `test-1k.vcf` | 1,000 | 1 | 60 KB | Small end-to-end runs | +| `test-10k.vcf` | 10,000 | 1 | 612 KB | Larger end-to-end runs still fast enough for CI | +| `test-larger.vcf.gz` | 1,155,741 | 1 | 296 MB | **Many records**, one sample: the record-scaling axis | +| `test-larger-multisample.vcf.gz` | 10,000 | 2,504 | 97 MB | **Many samples**, few records: the sample-scaling axis | + +The two `test-larger*` fixtures are deliberately complementary. Conversion cost +is driven by *record count x sample count*, and each isolates one factor: + +- `test-larger.vcf.gz` — 1.16M records x 1 sample = **1.16M sample calls** +- `test-larger-multisample.vcf.gz` — 10k records x 2,504 samples = **25.0M sample calls** + +A single-sample fixture cannot exercise the per-sample fan-out at all, which in +the expanded representation is where the triple count actually comes from. Use +both, and never generalise a scaling result from one to the other. + +### Provenance of `test-larger-multisample.vcf.gz` + +Derived from the 1000 Genomes Project phase 3 chromosome 20 call set (b37, +2,504 samples, 1,812,841 records) by taking **20 contiguous blocks of 500 +records at even intervals** across the source, keeping all 2,504 sample columns +and the original header unmodified. Blocks rather than a random sample, so +neighbouring-variant structure survives; spread across the whole chromosome, so +the allele-frequency spectrum and variant mix are representative rather than +whatever happens to sit at the start of the file. + +The result spans chr20 positions 60,343-60,416,754 and contains 9,575 SNPs, 428 +indels, 5 structural variants and 58 multi-allelic sites. It is +`##fileformat=VCFv4.1` (the source's own version — `test-larger.vcf.gz` is +VCFv4.2, so the pair also covers both header versions), POS-ascending, +single-contig, and verified to parse cleanly with both `bcftools stats` and +`cyvcf2` — the two readers the validation oracle itself uses. Three `##` lines +record its derivation inside the file. + +1000 Genomes is open-consent, freely redistributable data, so the fixture +carries no access restrictions. + ## CI matrix behavior - Windows runners execute: diff --git a/test/test_vcf_files/test-larger-multisample.vcf.gz b/test/test_vcf_files/test-larger-multisample.vcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..bb8db380e67718d6628f135ca927ddd7981ea0e5 GIT binary patch literal 1362251 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

S_SX}&qJxr*{=N?3#XK7dJ|HY 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�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�!&TtHg~ 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

+A+@ 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

%VhTstQZS8G~A0A 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%0DsGt4+q`h9`nZqXZh=#{X5$S`c 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

~i;-vd3BfFLv<($tx1CO#3go`?)^{ad?8X{mV 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
XWk-T`xn?m<`)RZsTZ5rx+-eqQ(!FP8z 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 literal 0 HcmV?d00001 diff --git a/test/test_vcf_rdfizer_unit.py b/test/test_vcf_rdfizer_unit.py index 874d2d8..85bbcd1 100644 --- a/test/test_vcf_rdfizer_unit.py +++ b/test/test_vcf_rdfizer_unit.py @@ -167,11 +167,25 @@ def run_with_default_aggregate(cmd, cwd=None, env=None): ), "rdf", ) + storage_mode = next( + ( + part.split("=", 1)[1] + for part in cmd + if isinstance(part, str) and part.startswith("RDF_STORAGE_MODE=") + ), + "plain", + ) if out_mount is not None: output_dir = out_mount / output_name output_dir.mkdir(parents=True, exist_ok=True) if not any(output_dir.glob("*.nt")) and not any(output_dir.glob("*.nt.gz")): - (output_dir / f"{output_name}.nt").write_text("

.\n") + # Match the aggregate the wrapper plans for this storage mode: + # space-optimized expects one .nt.gz assembled from the parts. + if storage_mode == "space-optimized": + with gzip.open(output_dir / f"{output_name}.nt.gz", "wt") as handle: + handle.write("

.\n") + else: + (output_dir / f"{output_name}.nt").write_text("

.\n") if result == 0: rendered = str(cmd[-1]) if cmd else "" work_mount = next( @@ -3093,16 +3107,87 @@ def test_main_full_mode_requires_input_argument(self): rc = invoke_main(["--mode", "full"]) self.assertEqual(rc, 2) - def test_main_full_mode_requires_storage_mode_argument(self): - """Full mode fails validation when --rdf-storage-mode is omitted.""" + def test_main_full_mode_defaults_to_space_optimized_storage(self): + """Full mode without --rdf-storage-mode resolves to the space-optimized aggregate.""" + self.assertEqual(vcf_rdfizer.DEFAULT_RDF_STORAGE_MODE, "space-optimized") with tempfile.TemporaryDirectory() as td: tmp_path = Path(td) input_dir, rules_path = prepare_inputs(tmp_path) - rc = invoke_main( - ["--mode", "full", "--input", str(input_dir), "--rules", str(rules_path)], - auto_storage=False, - ) + observed = {} + + def capture_full_mode(**kwargs): + observed.update(kwargs) + return 0 + + old_cwd = os.getcwd() + os.chdir(tmp_path) + try: + with mock.patch.object(vcf_rdfizer, "check_docker", return_value=True), \ + mock.patch.object(vcf_rdfizer, "docker_image_exists", return_value=True), \ + mock.patch.object( + vcf_rdfizer, "run_full_mode", side_effect=capture_full_mode + ): + rc = invoke_main( + [ + "--mode", "full", + "--input", str(input_dir), + "--rules", str(rules_path), + "--out", str(tmp_path / "out"), + ], + auto_storage=False, + ) + finally: + os.chdir(old_cwd) + + self.assertEqual(rc, 0) + self.assertEqual(observed.get("rdf_storage_mode"), "space-optimized") + + def test_main_full_mode_rejects_single_hdt_strategy_with_cottas(self): + """`single` is refused, not silently ignored, when COTTAS forces chunking.""" + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + input_dir, rules_path = prepare_inputs(tmp_path) + stderr = StringIO() + with redirect_stderr(stderr): + rc = invoke_main( + [ + "--mode", "full", + "--input", str(input_dir), + "--rules", str(rules_path), + "--rdf-storage-mode", "plain", + "--representations", "hdt,cottas", + "--rdf-compression", "none", + "--hdt-strategy", "single", + "--out", str(tmp_path / "out"), + ], + auto_storage=False, + ) + self.assertEqual(rc, 2) + self.assertIn("HDT-only run", stderr.getvalue()) + + def test_main_full_mode_rejects_single_hdt_strategy_with_space_optimized(self): + """`single` cannot read the now-default gzip aggregate.""" + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + input_dir, rules_path = prepare_inputs(tmp_path) + stderr = StringIO() + with redirect_stderr(stderr): + rc = invoke_main( + [ + "--mode", "full", + "--input", str(input_dir), + "--rules", str(rules_path), + "--representations", "hdt", + "--rdf-compression", "none", + "--hdt-strategy", "single", + "--out", str(tmp_path / "out"), + ], + auto_storage=False, + ) self.assertEqual(rc, 2) + message = stderr.getvalue() + self.assertIn("gzip aggregate", message) + self.assertIn("--rdf-storage-mode plain", message) def test_removed_legacy_cli_options_are_rejected(self): """Removed layout and compatibility aliases are not accepted by the CLI.""" diff --git a/vcf-rdfizer-v1.0.0.tar.gz b/vcf-rdfizer-v1.0.0.tar.gz deleted file mode 100644 index e5d37697365d1728c8b73579fa3621c4cc796bf1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147956 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 z 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

2}>eCe@`v!>qK4)^pW1=*6~b0 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 O&;JJ(B?G|#U=skiq?XG7 diff --git a/vcf_rdfizer.py b/vcf_rdfizer.py index 00d8031..92a6277 100644 --- a/vcf_rdfizer.py +++ b/vcf_rdfizer.py @@ -286,6 +286,12 @@ HDT_STRATEGY_CHOICES = {"auto", "single", "partitioned"} DEFAULT_HDT_STRATEGY = "auto" RDF_STORAGE_MODES = {"space-optimized", "plain"} +#: Full mode defaults to the space-optimized aggregate. Benchmarking showed it +#: reaches the same triples as `plain` at a much smaller peak workspace +#: footprint and no practically important compute penalty, so the low-disk +#: path is the one a caller gets without having to ask. `plain` remains +#: available and is required for `--hdt-strategy single`. +DEFAULT_RDF_STORAGE_MODE = "space-optimized" DEFAULT_CHUNK_TARGET_BYTES = 512 * 1024 * 1024 DEFAULT_CHUNK_MIN_BYTES = 128 * 1024 * 1024 DEFAULT_CHUNK_MAX_BYTES = 1024 * 1024 * 1024 @@ -4483,6 +4489,46 @@ def should_use_partitioned_hdt( return mode == "full" and rdf_storage_mode in RDF_STORAGE_MODES +def hdt_strategy_rejection( + *, + hdt_strategy: str, + methods: list[str], + gzip_aggregate: bool, + gzip_remedy: str, +) -> str | None: + """Return why `--hdt-strategy single` cannot be honoured here, or None. + + `single` is a verification path rather than a performance alternative: it + exists so one `rdf2hdt` pass can be compared against the chunked `hdtc` + merge on the same graph. It applies only to an HDT-only run over an + uncompressed aggregate. + + Two requests cannot be honoured, and both are refused rather than silently + downgraded to the partitioned path under a `single` label: + + * a gzip aggregate, which one pass could only read by materializing a + second full uncompressed copy; and + * a run that also selects COTTAS, which always needs bounded chunks, so the + partitioned path would run for both representations regardless. + """ + if hdt_strategy != "single" or not compression_uses_hdt(methods): + return None + if gzip_aggregate: + return ( + "--hdt-strategy single cannot read a gzip aggregate: one rdf2hdt pass " + "would have to materialize a second full uncompressed copy. " + + gzip_remedy + ) + if any(method in COTTAS_COMPRESSION_METHODS for method in methods): + return ( + "--hdt-strategy single applies only to an HDT-only run. COTTAS always " + "requires chunked generation, so the partitioned path would run for " + "both representations and the strategy would have no effect. Drop " + "cottas from --representations, or use --hdt-strategy partitioned." + ) + return None + + # --------------------------------------------------------------------------- # Run metrics layout: naming, manifest, and summary # --------------------------------------------------------------------------- @@ -7541,11 +7587,17 @@ def run_compress_mode( print("No compression methods selected (`none`). Nothing to do.") return 0 - if rdf_path.name.endswith(".gz") and compression_uses_hdt(methods) and hdt_strategy == "single": - eprint( - "Error: --hdt-strategy single cannot read a gzip aggregate without materializing " - "an uncompressed RDF file; use --hdt-strategy partitioned." - ) + hdt_strategy_error = hdt_strategy_rejection( + hdt_strategy=hdt_strategy, + methods=methods, + gzip_aggregate=rdf_path.name.endswith(".gz"), + gzip_remedy=( + "Use --hdt-strategy partitioned, or supply an uncompressed .nt if you " + "specifically need a single-pass HDT for verification." + ), + ) + if hdt_strategy_error is not None: + eprint(f"Error: {hdt_strategy_error}") return 2 if any(method in HDT_COMPRESSION_METHODS for method in methods): @@ -8283,29 +8335,32 @@ def main(): formatter_class=argparse.RawTextHelpFormatter, epilog=( "Examples:\n" - " Full pipeline (plain aggregate):\n" + " Full pipeline (space-optimized aggregate is the default):\n" + " vcf_rdfizer.py -m full -i ./vcf_files --representations hdt,cottas " + "--rdf-compression none -o ./results\n" + " Full pipeline keeping one uncompressed .nt aggregate:\n" " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode plain " "--representations hdt -o ./results\n" - " Full pipeline (space-optimized aggregate):\n" - " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode space-optimized " - "--representations hdt,cottas --rdf-compression none -o ./results\n" " Full pipeline with semantic validation:\n" - " vcf_rdfizer.py -m full -i ./cohort.vcf.gz --rdf-storage-mode plain " + " vcf_rdfizer.py -m full -i ./cohort.vcf.gz " "--representations none --rdf-compression none --validate -o ./results\n" " Condensed multi-sample representation:\n" " vcf_rdfizer.py -m full -i ./cohort.vcf.gz --sample-representation condensed " - "--rdf-storage-mode space-optimized --representations hdt -o ./results\n" - " Space-optimized full pipeline with shared HDT/COTTAS chunks:\n" - " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode space-optimized " + "--representations hdt -o ./results\n" + " Full pipeline with shared HDT/COTTAS chunks:\n" + " vcf_rdfizer.py -m full -i ./vcf_files " "--representations hdt,cottas --rdf-compression none " "--chunk-target-bytes 536870912 -o ./results\n" " Ultra-small full pipeline (remove aggregate RDF after compression):\n" - " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode space-optimized " + " vcf_rdfizer.py -m full -i ./vcf_files " "--representations hdt --rdf-compression none --hdt-strategy partitioned " "--remove-rdf-storage-output -o ./results\n" " Queryable HDT plus gzip-packaged HDT:\n" - " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode space-optimized " + " vcf_rdfizer.py -m full -i ./vcf_files " "--rdf-compression none --representations hdt --artifact-compression gzip -o ./results\n" + " Single-pass HDT for verification against the partitioned merge:\n" + " vcf_rdfizer.py -m full -i ./vcf_files --rdf-storage-mode plain " + "--representations hdt --rdf-compression none --hdt-strategy single -o ./results\n" " TSV-only benchmark:\n" " vcf_rdfizer.py -m tsv -i ./vcf_files -o ./results\n" " Compression-only:\n" @@ -8434,10 +8489,12 @@ def main(): parser.add_argument( "--rdf-storage-mode", choices=sorted(RDF_STORAGE_MODES), - default=None, + default=DEFAULT_RDF_STORAGE_MODE, help=( "Full-mode aggregate storage: plain keeps one .nt; space-optimized builds one .nt.gz " - "from RMLStreamer parts before record-safe HDT/COTTAS chunking" + "from RMLStreamer parts before record-safe HDT/COTTAS chunking " + f"(default: {DEFAULT_RDF_STORAGE_MODE}). plain is required by " + "--hdt-strategy single, which cannot read a gzip aggregate" ), ) parser.add_argument( @@ -8516,8 +8573,12 @@ def main(): choices=sorted(HDT_STRATEGY_CHOICES), default=DEFAULT_HDT_STRATEGY, help=( - "HDT generation strategy: auto uses partitioned HDT+hdtc merge for full-mode aggregate storage, " - "single uses one rdf2hdt run, partitioned forces chunked HDT generation" + "HDT generation strategy. auto uses partitioned HDT+hdtc merge for full-mode " + "aggregate storage; partitioned forces chunked generation and is the setting to " + "pin for reproducible runs. single uses one rdf2hdt run and is a verification " + "path, not a faster alternative: it exists so a one-shot conversion can be " + "compared against the chunked merge, and it requires an HDT-only run over an " + "uncompressed aggregate (--rdf-storage-mode plain, no cottas)" ), ) parser.add_argument( @@ -8784,8 +8845,6 @@ def main(): if mode == "full": if args.input is None: raise ValueError("--input is required in --mode full") - if args.rdf_storage_mode is None: - raise ValueError("--rdf-storage-mode is required in --mode full") input_path = Path(args.input).expanduser().resolve() ( input_mount_dir, @@ -8828,15 +8887,17 @@ def main(): representations=args.representations, artifact_compression=args.artifact_compression, ) - if ( - args.rdf_storage_mode == "space-optimized" - and args.hdt_strategy == "single" - and compression_uses_hdt(full_methods) - ): - raise ValueError( - "--hdt-strategy single cannot be used with space-optimized HDT input; " - "use --hdt-strategy partitioned" - ) + hdt_strategy_error = hdt_strategy_rejection( + hdt_strategy=args.hdt_strategy, + methods=full_methods, + gzip_aggregate=args.rdf_storage_mode == "space-optimized", + gzip_remedy=( + "Use --hdt-strategy partitioned, or --rdf-storage-mode plain if you " + "specifically need a single-pass HDT for verification." + ), + ) + if hdt_strategy_error is not None: + raise ValueError(hdt_strategy_error) if args.spark_partitions is not None: spark_partitions = parse_positive_int( args.spark_partitions, name="--spark-partitions" @@ -8938,15 +8999,17 @@ def main(): representations=args.representations, artifact_compression=args.artifact_compression, ) - if ( - rdf_path.name.endswith(".gz") - and args.hdt_strategy == "single" - and compression_uses_hdt(methods) - ): - raise ValueError( - "--hdt-strategy single cannot be used with a .nt.gz HDT input; " - "use --hdt-strategy partitioned" - ) + hdt_strategy_error = hdt_strategy_rejection( + hdt_strategy=args.hdt_strategy, + methods=methods, + gzip_aggregate=rdf_path.name.endswith(".gz"), + gzip_remedy=( + "Use --hdt-strategy partitioned, or supply an uncompressed .nt if you " + "specifically need a single-pass HDT for verification." + ), + ) + if hdt_strategy_error is not None: + raise ValueError(hdt_strategy_error) validate_mode_dirs([out_root, out_dir, metrics_root]) compression_uses_partitioning_for_input = compression_uses_partitioning(methods) and ( any(method in COTTAS_COMPRESSION_METHODS for method in methods) From f806f700dcd9fec1df00bdb24658cafe131d2c00 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Thu, 10 Sep 2026 15:10:49 +0200 Subject: [PATCH 6/9] benchmark prep --- src/validation/validation_runner.py | 134 ++++++++++++++++++++++++- test/test_validation_benchmark_unit.py | 94 +++++++++++++++++ 2 files changed, 224 insertions(+), 4 deletions(-) diff --git a/src/validation/validation_runner.py b/src/validation/validation_runner.py index 78856b5..ff9c381 100644 --- a/src/validation/validation_runner.py +++ b/src/validation/validation_runner.py @@ -85,6 +85,31 @@ def eprint(*args: Any) -> None: "q12_info_value_digest", "q13_format_value_digest", ) +#: Which oracle phases a query would actually have paid for, had it been the +#: only question asked. The oracle is one pass that fills every query's +#: counters together, so there is no measured per-query slice of it; this is the +#: explicit statement of what a one-question cyvcf2 script would have cost. +#: +#: Every query pays to open the file, scan the records, and assemble its answer. +#: Only the sample-level queries pay for the per-sample genotype/AC-AN block, +#: which is the part whose cost scales with cohort size. Measured on the +#: shipped fixtures, the block is 15.5% of the scan at one sample and 73.5% at +#: 2,504 -- which is the whole reason per-query oracle numbers are worth having. +#: +#: Known coarseness: `assemblySeconds` is charged to every query equally, and on +#: a cohort file it is not small (149 s against a 181 s scan on the 2,504-sample +#: fixture) because it sorts the per-sample counters. Most of that work belongs +#: to the sample-level queries, so this attribution OVER-charges record-level +#: queries on multi-sample inputs -- i.e. it understates the gap it is measuring. +#: Splitting it would mean restructuring the post-loop assembly into per-query +#: builders; until then the bias is in the conservative direction and is stated +#: rather than hidden. +ORACLE_SAMPLE_LEVEL_QUERIES = frozenset({ + "q05_sample_genotype_counts", + "q06_ac_an_distribution", + "q13_format_value_digest", +}) + #: Queries that must return exactly one row, normalized to a dict rather than #: a list so the comparison reads as a field-by-field check. SINGLE_ROW_QUERIES = frozenset({"q03_titv", "q07_file_metadata"}) @@ -1054,7 +1079,35 @@ def attach_census_expectations( return parser -def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: +def parse_vcf( + vcf_path: Path, *, filter_oracle: str, timing: dict[str, float] | None = None +) -> dict[str, Any]: + """Compute every query's expected value in ONE pass over the VCF. + + ``timing``, when supplied, is filled with the phase breakdown below. It is + opt-in because the sample-block measurement costs two clock reads per + record, which is negligible next to a real parse but pointless when nobody + is going to read it. + + readerOpenSeconds open the file and parse the header + scanSeconds the record loop, in total + sampleBlockSeconds the per-sample genotype/AC-AN portion INSIDE the + scan -- the only part of the pass whose cost + depends on which queries you want + assemblySeconds building the per-query expected structures after + the loop + + Why phases and not per-query totals: this is a single pass that accumulates + every query's counters together, so there is no per-query slice of it to + measure. Attributing the shared scan to individual queries is a decision + about what a one-question script would have paid, not a measurement, so it + is made explicitly in the analysis (see ORACLE_QUERY_PHASES) rather than + silently here. + + Gating the pass per query was considered and rejected: the accumulators in + the sample block feed the expected values, so a gate left on in a + correctness run would corrupt the oracle every equality claim rests on. + """ if VCF is None: raise RuntimeError( "cyvcf2 is unavailable; the validator must run inside the " @@ -1066,9 +1119,16 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: if filter_oracle == "bcftools" and not shutil.which("bcftools"): raise RuntimeError("--filter-oracle=bcftools requested but bcftools is unavailable") filters = filters_with_bcftools(vcf_path) if use_bcftools else Counter() + _open_started = time.monotonic() reader = VCF(str(vcf_path), strict_gt=True) samples = list(reader.samples) header_metadata = parse_header_metadata(read_vcf_header_text(vcf_path)) + if timing is not None: + timing["readerOpenSeconds"] = time.monotonic() - _open_started + # Hoisted out of the loop: a per-record attribute lookup on `timing` would + # be measuring the measurement. + _time_samples = timing is not None + _sample_block_seconds = 0.0 density: Counter[tuple[str, int]] = Counter() shapes: Counter[str] = Counter() genotypes: Counter[tuple[str, str]] = Counter() @@ -1090,6 +1150,7 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: records_with_format_column = records_with_format_keys = 0 format_key_occurrences = format_value_slots = non_empty_format_values = 0 distinct_format_keys: set[str] = set() + _scan_started = time.monotonic() try: for variant in reader: total_records += 1 @@ -1209,6 +1270,7 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: condensed_format_digest[ record_digest_bucket([vector_iri, encoded]) ] += 1 + _sample_started = time.monotonic() if _time_samples else 0.0 alleles = [None] * len(samples) if samples and has_gt: raw_genotypes = list(variant.genotypes) @@ -1232,15 +1294,21 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: if an: ac_an[(an, ac)] += 1 q06_eligible += 1 + if _time_samples: + _sample_block_seconds += time.monotonic() - _sample_started finally: reader.close() + if timing is not None: + timing["scanSeconds"] = time.monotonic() - _scan_started + timing["sampleBlockSeconds"] = _sample_block_seconds + _assembly_started = time.monotonic() if sum(filters.values()) != total_records: raise ValueError("FILTER oracle record count differs from the VCF record count") q05 = [ {"sampleId": sample, "genotypeClass": genotype_class, "callCount": int(count)} for (sample, genotype_class), count in sorted(genotypes.items()) ] - return { + result = { "source": str(vcf_path), "sourceSha256": sha256_file(vcf_path), "filterOracle": "bcftools" if use_bcftools else "cyvcf2-serialization", @@ -1330,6 +1398,9 @@ def parse_vcf(vcf_path: Path, *, filter_oracle: str) -> dict[str, Any]: for (an, ac), count in sorted(ac_an.items()) ], } + if timing is not None: + timing["assemblySeconds"] = time.monotonic() - _assembly_started + return result # --------------------------------------------------------------------------- @@ -2906,12 +2977,46 @@ def evaluate_validation( "query_id", "status", "wall_seconds", + # The parser's cost for THIS query, comparable row-wise against + # `wall_seconds`. Empty unless the oracle recorded its phase breakdown. + "oracle_query_seconds", + # The parser's total for ALL queries, repeated on every row so the file + # needs no join. NOT comparable row-wise against `wall_seconds`. "oracle_wall_seconds", "engine_setup_seconds", "artifact_origin", ] +def oracle_query_seconds( + phases: dict[str, float] | None, query_ids: tuple[str, ...] +) -> dict[str, float]: + """Attribute the oracle's measured phases to individual queries. + + Not a measurement of each query in isolation -- see + :data:`ORACLE_SAMPLE_LEVEL_QUERIES` for why that does not exist -- but the + cost a one-question script would have paid, composed from phases that were + each measured directly. + """ + if not phases: + return {} + reader_open = phases.get("readerOpenSeconds") or 0.0 + scan = phases.get("scanSeconds") or 0.0 + sample_block = phases.get("sampleBlockSeconds") or 0.0 + assembly = phases.get("assemblySeconds") or 0.0 + record_level_scan = max(scan - sample_block, 0.0) + + out: dict[str, float] = {} + for query_id in query_ids: + pays_sample_block = query_id in ORACLE_SAMPLE_LEVEL_QUERIES + out[query_id] = ( + reader_open + + (scan if pays_sample_block else record_level_scan) + + assembly + ) + return out + + def build_benchmark( per_engine: dict[str, dict[str, Any]], engine_descriptions: dict[str, Any], @@ -2951,6 +3056,8 @@ def build_benchmark( "queries": queries, } + oracle_phases = oracle_seconds.get("phases") or {} + per_query_oracle = oracle_query_seconds(oracle_phases, query_ids) return { "oracle": { # The parser side of the comparison: what it costs to compute the @@ -2958,6 +3065,16 @@ def build_benchmark( "totalSeconds": oracle_seconds.get("total"), "vcfParseSeconds": oracle_seconds.get("parse"), "censusSeconds": oracle_seconds.get("census"), + # Directly measured phases of the single pass. + "phases": oracle_phases or None, + # Per-query cost a one-question script would have paid, composed + # from those phases. `sampleLevelQueries` names the ones that pay + # for the per-sample block, so the attribution is auditable rather + # than implicit. + "perQuerySeconds": per_query_oracle or None, + "sampleLevelQueries": sorted( + q for q in query_ids if q in ORACLE_SAMPLE_LEVEL_QUERIES + ) or None, }, "preparation": { "materializationSeconds": materialization_seconds, @@ -2981,6 +3098,7 @@ def write_benchmark_csv(path: Path, benchmark: dict[str, Any]) -> Path: """Write one row per engine and query, for direct analysis.""" path.parent.mkdir(parents=True, exist_ok=True) oracle_total = benchmark["oracle"]["totalSeconds"] + per_query = benchmark["oracle"].get("perQuerySeconds") or {} with path.open("w", newline="", encoding="utf-8") as handle: writer = csv.DictWriter(handle, fieldnames=BENCHMARK_CSV_HEADER) writer.writeheader() @@ -2991,6 +3109,7 @@ def write_benchmark_csv(path: Path, benchmark: dict[str, Any]) -> Path: "query_id": query_id, "status": entry["status"], "wall_seconds": entry["wallSeconds"], + "oracle_query_seconds": per_query.get(query_id), # Repeated on each row so the CSV is usable without a join. "oracle_wall_seconds": oracle_total, "engine_setup_seconds": engine["setupSeconds"], @@ -3129,14 +3248,21 @@ def run_validation(args: argparse.Namespace) -> int: detail="parsing source VCF", ) oracle_started = time.monotonic() - parser = parse_vcf(args.vcf, filter_oracle=args.filter_oracle) + oracle_phases: dict[str, float] = {} + parser = parse_vcf( + args.vcf, filter_oracle=args.filter_oracle, timing=oracle_phases + ) parse_seconds = time.monotonic() - oracle_started census_started = time.monotonic() parser = attach_census_expectations(parser, args.representation) + oracle_phases["censusSeconds"] = time.monotonic() - census_started oracle_seconds = { "parse": parse_seconds, - "census": time.monotonic() - census_started, + "census": oracle_phases["censusSeconds"], "total": time.monotonic() - oracle_started, + # Phase breakdown, so per-query oracle cost can be attributed + # from measured parts rather than guessed. + "phases": dict(oracle_phases), } parser["oracleSeconds"] = oracle_seconds write_json(results_dir / "parser.json", parser) diff --git a/test/test_validation_benchmark_unit.py b/test/test_validation_benchmark_unit.py index 6643e4d..5e2989a 100644 --- a/test/test_validation_benchmark_unit.py +++ b/test/test_validation_benchmark_unit.py @@ -333,6 +333,100 @@ def test_the_csv_carries_one_row_per_engine_and_query(self): self.assertEqual({row["oracle_wall_seconds"] for row in rows}, {"0.4"}) +class OracleQuerySecondsTests(VerboseTestCase): + """Per-query oracle cost, attributed from directly measured phases.""" + + PHASES = { + "readerOpenSeconds": 1.0, + "scanSeconds": 100.0, + "sampleBlockSeconds": 90.0, + "assemblySeconds": 2.0, + } + + def test_a_record_level_query_does_not_pay_for_the_sample_block(self): + """The per-sample block is the only phase a query can avoid.""" + per_query = V.oracle_query_seconds(self.PHASES, ("q01_record_density_1mb",)) + # 1.0 open + (100 scan - 90 sample block) + 2.0 assembly + self.assertAlmostEqual(per_query["q01_record_density_1mb"], 13.0) + + def test_a_sample_level_query_pays_for_the_whole_scan(self): + per_query = V.oracle_query_seconds(self.PHASES, ("q05_sample_genotype_counts",)) + # 1.0 open + 100 scan + 2.0 assembly + self.assertAlmostEqual(per_query["q05_sample_genotype_counts"], 103.0) + + def test_the_sample_level_set_is_the_three_genotype_queries(self): + """Q5/Q6/Q13 traverse the sample layer; nothing else does.""" + self.assertEqual( + V.ORACLE_SAMPLE_LEVEL_QUERIES, + frozenset({"q05_sample_genotype_counts", "q06_ac_an_distribution", + "q13_format_value_digest"}), + ) + + def test_no_phases_means_no_per_query_attribution(self): + """Without a measured breakdown there is nothing to attribute.""" + self.assertEqual(V.oracle_query_seconds(None, ("q01",)), {}) + self.assertEqual(V.oracle_query_seconds({}, ("q01",)), {}) + + def test_a_sample_block_longer_than_the_scan_cannot_go_negative(self): + """Clock jitter on a fast scan must not produce a negative cost.""" + per_query = V.oracle_query_seconds( + {"readerOpenSeconds": 0.0, "scanSeconds": 1.0, + "sampleBlockSeconds": 1.5, "assemblySeconds": 0.0}, + ("q01_record_density_1mb",), + ) + self.assertEqual(per_query["q01_record_density_1mb"], 0.0) + + def test_the_benchmark_carries_phases_and_per_query_seconds(self): + benchmark = V.build_benchmark( + {"qlever": _verdict("PASS", {"q01_record_density_1mb": 0.2, + "q05_sample_genotype_counts": 0.3})}, + {"qlever": {"setupSeconds": 0.1}}, + oracle_seconds={"total": 103.0, "parse": 101.0, "census": 2.0, + "phases": dict(self.PHASES)}, + materialization_seconds=None, + shacl_seconds=None, + query_ids=("q01_record_density_1mb", "q05_sample_genotype_counts"), + ) + self.assertEqual(benchmark["oracle"]["phases"], self.PHASES) + self.assertAlmostEqual( + benchmark["oracle"]["perQuerySeconds"]["q01_record_density_1mb"], 13.0) + self.assertAlmostEqual( + benchmark["oracle"]["perQuerySeconds"]["q05_sample_genotype_counts"], 103.0) + # The attribution is auditable: the payload names which queries pay. + self.assertEqual(benchmark["oracle"]["sampleLevelQueries"], + ["q05_sample_genotype_counts"]) + + def test_an_oracle_without_phases_reports_none_not_an_empty_dict(self): + """A run made before phase timing existed must not look like zero cost.""" + benchmark = V.build_benchmark( + {"qlever": _verdict("PASS", {"q01": 0.2})}, + {"qlever": {"setupSeconds": 0.1}}, + oracle_seconds={"total": 0.4, "parse": 0.3, "census": 0.1}, + materialization_seconds=None, shacl_seconds=None, query_ids=("q01",), + ) + self.assertIsNone(benchmark["oracle"]["phases"]) + self.assertIsNone(benchmark["oracle"]["perQuerySeconds"]) + + def test_the_csv_carries_a_per_query_oracle_column(self): + """`oracle_query_seconds` IS row-wise comparable; the total is not.""" + benchmark = V.build_benchmark( + {"qlever": _verdict("PASS", {"q01_record_density_1mb": 0.2, + "q05_sample_genotype_counts": 0.3})}, + {"qlever": {"setupSeconds": 0.1}}, + oracle_seconds={"total": 103.0, "parse": 101.0, "census": 2.0, + "phases": dict(self.PHASES)}, + materialization_seconds=None, shacl_seconds=None, + query_ids=("q01_record_density_1mb", "q05_sample_genotype_counts"), + ) + with tempfile.TemporaryDirectory() as td: + path = V.write_benchmark_csv(Path(td) / "benchmark.csv", benchmark) + rows = {r["query_id"]: r for r in csv.DictReader(path.open(encoding="utf-8"))} + self.assertEqual(rows["q01_record_density_1mb"]["oracle_query_seconds"], "13.0") + self.assertEqual(rows["q05_sample_genotype_counts"]["oracle_query_seconds"], "103.0") + # The whole-run total is still there, and still the same on every row. + self.assertEqual({r["oracle_wall_seconds"] for r in rows.values()}, {"103.0"}) + + class EngineAgreementTests(VerboseTestCase): def test_engines_returning_the_same_rows_agree(self): result = V.compare_engines({ From 8b1b4a8f582bb1c3a0920d3c8bb71f26627c0528 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Thu, 10 Sep 2026 20:29:06 +0200 Subject: [PATCH 7/9] remove this run's temporary Docker volumes on interrupt Partitioned compression works in a named volume and removes it in its own `finally`. That is enough on the normal path but not on an interrupt: the `finally` runs as the exception unwinds, which is before the handler kills the containers, and Docker refuses to remove a volume a live container still holds. Removal failed there, warned once, and nothing retried -- leaking roughly 700 MB per interrupted run. Three had accumulated on the benchmark VM. Volumes are now registered when created and swept by the interrupt path after the containers are stopped, retrying while a just-killed container releases its hold. A volume whose removal fails stays registered rather than being forgotten, and `main`'s `finally` makes a last attempt so a failure on the normal path is not left behind either. The checkpoint records the counts. Co-Authored-By: Claude Opus 5 --- docs/output-and-metrics.md | 25 ++++++--- test/test_vcf_rdfizer_unit.py | 98 +++++++++++++++++++++++++++++++++++ vcf_rdfizer.py | 96 +++++++++++++++++++++++++++++++--- 3 files changed, 204 insertions(+), 15 deletions(-) diff --git a/docs/output-and-metrics.md b/docs/output-and-metrics.md index 6aec8f1..fb10cad 100644 --- a/docs/output-and-metrics.md +++ b/docs/output-and-metrics.md @@ -215,17 +215,26 @@ number, and no progress history is retained in memory. 1. **Stop this run's containers.** Every container the wrapper starts carries a `vcf-rdfizer.run=-` label, and cleanup kills exactly the ones matching its own label — a concurrent run's containers are never touched. -2. **Remove tracked intermediates.** Raw RDF follows +2. **Remove this run's temporary Docker volumes.** Partitioned compression + works in a named volume, and Docker refuses to remove one while a container + still holds it — so this can only happen after step 1, and retries a few + times while the killed container releases it. +3. **Remove tracked intermediates.** Raw RDF follows `--keep-rmlstreamer-rdf-output`: with it, raw RDF is preserved; without it, tracked raw RDF files are removed. -3. **Write `interrupt-checkpoint.json`** into the run's metrics directory, +4. **Write `interrupt-checkpoint.json`** into the run's metrics directory, recording the stages that completed, the last progress event, how many - containers were stopped, and what was removed. - -The order matters. Killing the wrapper does not kill its containers, and until -this existed an interrupted run deleted files that its own container was still -reading — one such orphan ran for three days after the run had "finished", -holding 17 GB and a core, working against inputs that no longer existed. + containers were stopped, how many volumes were removed, and what else was + deleted. + +The order matters, twice over. Killing the wrapper does not kill its +containers, and until this existed an interrupted run deleted files that its +own container was still reading — one such orphan ran for three days after the +run had "finished", holding 17 GB and a core, working against inputs that no +longer existed. And a volume cannot be removed before the container using it +stops: each volume's own `finally` ran as the exception unwound, *before* the +containers were killed, so it warned and gave up — leaking roughly 700 MB per +interrupted run, which nothing retried. A second `Ctrl+C` during cleanup is ignored, so an impatient operator cannot abort the step that stops the containers. If cleanup itself fails the wrapper diff --git a/test/test_vcf_rdfizer_unit.py b/test/test_vcf_rdfizer_unit.py index 85bbcd1..db87992 100644 --- a/test/test_vcf_rdfizer_unit.py +++ b/test/test_vcf_rdfizer_unit.py @@ -3321,6 +3321,104 @@ def fake_subprocess_run(cmd, **kwargs): ) tracker.close() + def test_temp_volume_removal_retries_while_a_container_holds_it(self): + """A container killed a moment ago has not released its volume yet.""" + vcf_rdfizer._TEMP_DOCKER_VOLUMES.clear() + vcf_rdfizer.register_temp_volume("vol-a") + attempts = [] + + # Fail twice (volume still in use), then succeed. + def fake_run(cmd, cwd=None, env=None): + attempts.append(cmd) + return 0 if len(attempts) >= 3 else 1 + + with mock.patch.object(vcf_rdfizer, "run", side_effect=fake_run), \ + mock.patch.object(vcf_rdfizer.time, "sleep"): + self.assertTrue(vcf_rdfizer.remove_temp_volume("vol-a", delay=0)) + self.assertEqual(len(attempts), 3) + self.assertEqual(attempts[0][-4:], ["volume", "rm", "-f", "vol-a"]) + # Success deregisters it, so the later sweep does not retry it. + self.assertNotIn("vol-a", vcf_rdfizer._TEMP_DOCKER_VOLUMES) + + def test_a_volume_that_cannot_be_removed_stays_registered(self): + """It must remain for the interrupt sweep, not be silently forgotten.""" + vcf_rdfizer._TEMP_DOCKER_VOLUMES.clear() + vcf_rdfizer.register_temp_volume("vol-stuck") + with mock.patch.object(vcf_rdfizer, "run", return_value=1), \ + mock.patch.object(vcf_rdfizer.time, "sleep"): + self.assertFalse(vcf_rdfizer.remove_temp_volume("vol-stuck", attempts=2, delay=0)) + self.assertIn("vol-stuck", vcf_rdfizer._TEMP_DOCKER_VOLUMES) + + def test_remove_tracked_volumes_counts_and_never_raises(self): + """Cleanup that raises leaves exactly the leak it exists to prevent.""" + with tempfile.TemporaryDirectory() as td: + tracker = vcf_rdfizer.RunTracker(Path(td) / "progress.log") + vcf_rdfizer._TEMP_DOCKER_VOLUMES.clear() + for name in ("vol-ok", "vol-bad"): + vcf_rdfizer.register_temp_volume(name) + + def fake_remove(name, **kwargs): + if name == "vol-bad": + raise RuntimeError("docker daemon gone") + vcf_rdfizer._TEMP_DOCKER_VOLUMES.discard(name) + return True + + with mock.patch.object(vcf_rdfizer, "remove_temp_volume", side_effect=fake_remove): + removed, failed = vcf_rdfizer.remove_tracked_volumes(run_tracker=tracker) + self.assertEqual((removed, failed), (1, 1)) + self.assertIn("temporary volumes removed=1, failed=1", tracker.log_path.read_text()) + tracker.close() + vcf_rdfizer._TEMP_DOCKER_VOLUMES.clear() + + def test_interrupt_removes_volumes_only_after_stopping_containers(self): + """Docker refuses to remove a volume a live container still holds. + + That is the whole bug: each volume's own `finally` ran as the exception + unwound, before the containers were killed, so removal failed there and + nothing retried -- leaking ~700 MB per interrupted run. + """ + with tempfile.TemporaryDirectory() as td: + tmp_path = Path(td) + input_dir, rules_path = prepare_inputs(tmp_path) + out_dir = tmp_path / "out" + order = [] + + old_cwd = os.getcwd() + os.chdir(tmp_path) + try: + with mock.patch.object(vcf_rdfizer, "check_docker", return_value=True), \ + mock.patch.object(vcf_rdfizer, "docker_image_exists", return_value=True), \ + mock.patch.object(vcf_rdfizer, "run_full_mode", side_effect=KeyboardInterrupt()), \ + mock.patch.object( + vcf_rdfizer, "kill_run_containers", + side_effect=lambda **k: (order.append("kill-containers"), (1, 0))[1], + ), \ + mock.patch.object( + vcf_rdfizer, "remove_tracked_volumes", + side_effect=lambda **k: (order.append("remove-volumes"), (2, 0))[1], + ), \ + mock.patch.object( + vcf_rdfizer, "cleanup_interrupted_full_run", + side_effect=lambda **k: (order.append("remove-temporaries"), (4, 0))[1], + ): + rc = invoke_main([ + "--mode", "full", + "--input", str(input_dir), + "--rules", str(rules_path), + "--rdf-storage-mode", "plain", + "--out", str(out_dir), + ]) + finally: + os.chdir(old_cwd) + + self.assertEqual(rc, 130) + # Containers first, then the volumes they were holding. + self.assertLess(order.index("kill-containers"), order.index("remove-volumes")) + + run_metrics_dir = latest_metrics_run_dir(out_dir / "run_metrics") + data = json.loads((run_metrics_dir / "interrupt-checkpoint.json").read_text()) + self.assertEqual(data["volumes"], {"removed": 2, "failed": 0}) + def test_interrupt_stops_containers_before_deleting_their_inputs(self): """Order is the bug: temps were deleted from under a live container. diff --git a/vcf_rdfizer.py b/vcf_rdfizer.py index 92a6277..91b56e3 100644 --- a/vcf_rdfizer.py +++ b/vcf_rdfizer.py @@ -1664,6 +1664,60 @@ def remove_path_with_docker_fallback( return True +#: Temporary Docker volumes this process created and has not yet removed. +#: +#: Each volume is already removed in its own `finally`, which is enough on the +#: normal path. On an interrupt it is not: that `finally` runs as the exception +#: unwinds, which is *before* the handler kills the containers, and Docker +#: refuses to remove a volume a container still holds. The removal failed +#: there, warned, and nothing ever retried -- leaking ~700 MB per interrupted +#: run. Registering them here lets the interrupt path sweep once the +#: containers are actually gone. +_TEMP_DOCKER_VOLUMES: set[str] = set() + + +def register_temp_volume(name: str) -> None: + _TEMP_DOCKER_VOLUMES.add(name) + + +def remove_temp_volume(name: str, *, attempts: int = 3, delay: float = 1.0) -> bool: + """Remove one temporary volume, retrying while a container still holds it. + + A container killed a moment ago may not have released the volume yet, so a + single attempt is not enough on the interrupt path. + """ + for attempt in range(max(1, attempts)): + if run([*docker_cmd_prefix(), "volume", "rm", "-f", name]) == 0: + _TEMP_DOCKER_VOLUMES.discard(name) + return True + if attempt + 1 < attempts: + time.sleep(delay) + return False + + +def remove_tracked_volumes(*, run_tracker: RunTracker | None = None) -> tuple[int, int]: + """Remove every temporary volume still outstanding. Returns ``(removed, failed)``. + + Must run *after* the containers are stopped. Best effort by construction: + an interrupt path must never raise. + """ + removed = 0 + failed = 0 + for name in sorted(_TEMP_DOCKER_VOLUMES): + try: + if remove_temp_volume(name): + removed += 1 + else: + failed += 1 + except Exception: # noqa: BLE001 - cleanup must not raise + failed += 1 + if (removed or failed) and run_tracker is not None: + run_tracker.mark( + f"Interrupt cleanup: temporary volumes removed={removed}, failed={failed}" + ) + return removed, failed + + def kill_run_containers(*, run_tracker: RunTracker | None = None) -> tuple[int, int]: """Stop every container this wrapper started. Returns ``(killed, failed)``. @@ -1726,6 +1780,8 @@ def write_interrupt_checkpoint( containers_failed: int, removed: int | None, failed: int | None, + volumes_removed: int = 0, + volumes_failed: int = 0, ) -> Path | None: """Record where an interrupted run stopped, so it can be resumed or read. @@ -1740,6 +1796,7 @@ def write_interrupt_checkpoint( "exit_code": 130, "interrupted_at": datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), "containers": {"killed": containers_killed, "failed": containers_failed}, + "volumes": {"removed": volumes_removed, "failed": volumes_failed}, "temporaries": {"removed": removed, "failed": failed}, "stages_completed": list(run_tracker.completed_stages), "last_event": run_tracker.events[-1] if run_tracker.events else None, @@ -6331,6 +6388,9 @@ def run_containerized_partitioned_representation_methods( eprint(f"Error: unable to create temporary Docker volume '{volume_name}'. See log: {wrapper_log_path}") return False, {} volume_created = True + # Track it from the moment it exists, so an interrupt can still find it + # if this function's own cleanup cannot remove it. + register_temp_volume(volume_name) # A named volume is normally initialized by Docker as root. Make its # workspace writable for the mapped host user before running COTTAS. @@ -6487,13 +6547,13 @@ def run_containerized_partitioned_representation_methods( result_path.unlink() except OSError: pass - if volume_created: - cleanup_exit_code = run([*docker_cmd_prefix(), "volume", "rm", "-f", volume_name]) - if cleanup_exit_code != 0: - eprint( - f"Warning: failed to remove temporary Docker volume '{volume_name}'. " - f"See log: {wrapper_log_path}" - ) + if volume_created and not remove_temp_volume(volume_name): + # Still registered, so the interrupt sweep retries after the + # containers holding it are stopped. + eprint( + f"Warning: failed to remove temporary Docker volume '{volume_name}' " + f"for now; it will be retried during cleanup. See log: {wrapper_log_path}" + ) def run_partitioned_representation_methods_for_rdf_files( @@ -9469,6 +9529,7 @@ def _interrupt_handler(_signum, _frame): removed = failed = None containers_killed = containers_failed = 0 + volumes_removed = volumes_failed = 0 try: # Containers first, and for every mode -- validation, compress and # index all start containers too, and every one of them outlives @@ -9485,6 +9546,18 @@ def _interrupt_handler(_signum, _frame): f"killed={containers_killed}, failed={containers_failed}" ) + # Only now can a temporary volume be removed: Docker refuses while + # a container still holds it, which is why each volume's own + # `finally` could not do this during an interrupt. + volumes_removed, volumes_failed = remove_tracked_volumes( + run_tracker=run_tracker + ) + if volumes_removed or volumes_failed: + eprint( + "Interrupt cleanup: temporary volumes " + f"removed={volumes_removed}, failed={volumes_failed}" + ) + if mode == "full": removed, failed = cleanup_interrupted_full_run( run_tracker=run_tracker, @@ -9510,6 +9583,8 @@ def _interrupt_handler(_signum, _frame): containers_failed=containers_failed, removed=removed, failed=failed, + volumes_removed=volumes_removed, + volumes_failed=volumes_failed, ) if checkpoint_path is not None: eprint(f"Interrupt checkpoint: {checkpoint_path}") @@ -9525,6 +9600,13 @@ def _interrupt_handler(_signum, _frame): eprint(f"Progress log: {progress_log_path}") finally: + # Last chance for any temporary volume still outstanding. On the normal + # path each is already gone; this catches the one whose own removal + # failed and which would otherwise be left behind on a clean exit too. + try: + remove_tracked_volumes(run_tracker=run_tracker) + except Exception: # noqa: BLE001 - teardown must not mask a result + pass if hasattr(signal, "SIGTERM") and original_sigterm is not None: signal.signal(signal.SIGTERM, original_sigterm) # Always report/record wrapper runtime, even on failure paths. From 683abbdcdcd6c76372d8ac3a44a75f02d57e45e5 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Fri, 11 Sep 2026 19:55:34 +0200 Subject: [PATCH 8/9] v3.0.0 release --- .gitignore | 29 +++++++++++++++++------------ CITATION.cff | 2 +- README.md | 20 +++++++++++--------- conda-recipe/README.md | 4 ++-- conda-recipe/meta.yaml | 9 ++++++--- pyproject.toml | 4 ++-- 6 files changed, 39 insertions(+), 29 deletions(-) diff --git a/.gitignore b/.gitignore index 4638a62..2367bba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ -!docker/configuration.properties -scripts/node_modules +# Run outputs and intermediates +run_output/ +run_metrics/ +out/ +tsv/ -!time-* +# Downloaded toolchain +RMLStreamer-*-standalone.jar -run_output/ +# Test inputs: large VCFs are generated locally; only the small fixtures are tracked test/test_vcf_files/* !test/test_vcf_files/test-100.vcf !test/test_vcf_files/test-1k.vcf @@ -11,17 +15,18 @@ test/test_vcf_files/* !test/test_vcf_files/test-larger.vcf.gz !test/test_vcf_files/test-larger-multisample.vcf.gz -RMLStreamer-v2.5.0-standalone.jar -out/ -tsv/ -run_metrics/ +# Python build and cache artifacts __pycache__/ *.py[cod] .venv/ -.DS_Store -*.cover -test/*.cover -vcf_rdfizer.cover dist/ build/ *.egg-info/ + +# Coverage +*.cover +test/*.cover +vcf_rdfizer.cover + +# OS +.DS_Store diff --git a/CITATION.cff b/CITATION.cff index 8ad11d2..cc199c6 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -2,7 +2,7 @@ cff-version: 1.2.0 message: "If you use VCF-RDFizer in your research, please cite it using the metadata below." title: "VCF-RDFizer" type: software -version: "2.1.0" +version: "3.0.0" authors: - name: "VCF-RDFizer maintainers" repository-code: "https://github.com/ecrum19/VCF-RDFizer" diff --git a/README.md b/README.md index bdd5c31..8ad5f6d 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ VCF-RDFizer is a Docker-first CLI wrapper for: 1. VCF -> RDF (N-Triples) with RMLStreamer -2. Optional RDF compression/decompression +2. Optional RDF compression/decompression, into queryable HDT and COTTAS artifacts 3. Semantic validation of a compressed RDF graph against its source VCF +4. Data linking, which writes a provenance-tracked side-graph of external links The conversion targets the **VCF Core vocabulary**, published at [https://w3id.org/vcf-core/vocab#](https://w3id.org/vcf-core/vocab#) (prefix @@ -26,11 +27,12 @@ Core is a semantic target any conversion system can adopt, and its version line is independent of this converter's — the emitted IRIs reference the namespace, not a pinned version. -This README is the task-oriented reference. For how the tool works, why it is -built that way, and where it stops working, see the documentation set in -**[`docs/`](docs/README.md)** - starting with -[Architecture](docs/architecture.md) and, before you rely on the output, -[Limitations](docs/limitations.md). +This README covers day-to-day use: installation, the CLI flags, and worked +commands. The documentation set in **[`docs/`](docs/README.md)** covers +everything else — how the tool works internally, why it is designed that way, +and where it stops working. Start with +[Architecture](docs/architecture.md), and read +[Limitations](docs/limitations.md) before you rely on the output. ## Requirements @@ -103,7 +105,7 @@ In `full` mode with multiple VCF inputs, failures are isolated per input: ## Main Flags (Most Used) -- `-m, --mode {full,compress,decompress,tsv,validation,index}` +- `-m, --mode {full,compress,decompress,tsv,index,validation,link}` - `-o, --out` required output root directory - `--rdf-compression` final raw RDF codecs: `gzip`, `brotli`, or `none` - `--representations` queryable RDF outputs: `hdt`, `cottas`, or `none` @@ -1078,7 +1080,7 @@ Safe termination: If you use VCF-RDFizer in a publication, please cite: -VCF-RDFizer maintainers. (2026). *VCF-RDFizer* (Version 2.1.0) [Computer software]. GitHub. https://github.com/ecrum19/VCF-RDFizer +VCF-RDFizer maintainers. (2026). *VCF-RDFizer* (Version 3.0.0) [Computer software]. GitHub. https://github.com/ecrum19/VCF-RDFizer BibTeX: @@ -1087,7 +1089,7 @@ BibTeX: author = {{VCF-RDFizer maintainers}}, title = {VCF-RDFizer}, year = {2026}, - version = {2.1.0}, + version = {3.0.0}, url = {https://github.com/ecrum19/VCF-RDFizer}, note = {Computer software} } diff --git a/conda-recipe/README.md b/conda-recipe/README.md index dfd9a3f..9986fde 100644 --- a/conda-recipe/README.md +++ b/conda-recipe/README.md @@ -7,11 +7,11 @@ do not submit this package to `staged-recipes`. ## Before submitting to conda-forge -1. Commit the version bump, then create and push a Git tag (for example `v2.1.0`). +1. Commit the version bump, then create and push a Git tag (for example `v3.0.0`). 2. Download the source tarball and compute sha256: ```bash curl -L -o vcf-rdfizer.tar.gz \ - https://github.com/ecrum19/VCF-RDFizer/archive/refs/tags/v2.1.0.tar.gz + https://github.com/ecrum19/VCF-RDFizer/archive/refs/tags/v3.0.0.tar.gz shasum -a 256 vcf-rdfizer.tar.gz ``` 3. Replace `version` and `sha256` in the feedstock's `recipe/meta.yaml`. diff --git a/conda-recipe/meta.yaml b/conda-recipe/meta.yaml index 5a8aaf6..3af2ed0 100644 --- a/conda-recipe/meta.yaml +++ b/conda-recipe/meta.yaml @@ -1,5 +1,5 @@ {% set name = "vcf-rdfizer" %} -{% set version = "2.1.0" %} +{% set version = "3.0.0" %} package: name: {{ name|lower }} @@ -43,13 +43,16 @@ test: about: home: https://github.com/ecrum19/VCF-RDFizer - summary: Docker-first VCF to RDF conversion wrapper with compression and decompression modes + summary: Docker-first VCF to RDF conversion targeting the VCF Core vocabulary, with compressed queryable representations (HDT, COTTAS), semantic validation, and data linking license: MIT license_family: MIT license_file: LICENSE description: | VCF-RDFizer provides a Python CLI wrapper around a Dockerized VCF to RDF conversion pipeline. - It requires a working Docker installation at runtime for conversion/compression commands. + It converts VCF files into RDF in the VCF Core vocabulary, optionally into compressed and + queryable representations (HDT, COTTAS), and can validate that the result still reproduces + the source VCF's semantics. It requires a working Docker installation at runtime for + conversion, compression, indexing and validation commands. doc_url: https://github.com/ecrum19/VCF-RDFizer/blob/main/README.md extra: diff --git a/pyproject.toml b/pyproject.toml index 203ed88..539a99a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta" [project] name = "vcf-rdfizer" -version = "2.1.0" -description = "Docker-first VCF to RDF conversion wrapper with compression/decompression modes" +version = "3.0.0" +description = "Docker-first VCF to RDF conversion targeting the VCF Core vocabulary, with compressed queryable representations (HDT, COTTAS), semantic validation, and data linking" readme = "README.md" requires-python = ">=3.10" license = "MIT" From 005c3e5667cc9f98c95935bf0eb3b50e72c2b329 Mon Sep 17 00:00:00 2001 From: ecrum19 Date: Fri, 11 Sep 2026 21:04:49 +0200 Subject: [PATCH 9/9] added tests and META fix --- .gitignore | 4 + MANIFEST.in | 13 + README.md | 2 +- changelog.md | 1509 ----------------- docs/README.md | 5 +- docs/roadmap.md | 2 +- src/validate_compression.py | 12 +- ...st_partitioned_compression_helpers_unit.py | 434 +++++ test/test_validate_compression_unit.py | 314 ++++ test/test_validation_oracle_unit.py | 652 +++++++ test/test_validation_results_unit.py | 373 ++++ test/test_vcf_rdfizer_unit.py | 45 + vcf_rdfizer_vocab.py | 50 +- 13 files changed, 1887 insertions(+), 1528 deletions(-) create mode 100644 MANIFEST.in delete mode 100644 changelog.md create mode 100644 test/test_partitioned_compression_helpers_unit.py create mode 100644 test/test_validate_compression_unit.py create mode 100644 test/test_validation_oracle_unit.py create mode 100644 test/test_validation_results_unit.py diff --git a/.gitignore b/.gitignore index 2367bba..ab99cfc 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,10 @@ build/ *.cover test/*.cover vcf_rdfizer.cover +.coverage +.coverage.* +coverage.xml +htmlcov/ # OS .DS_Store diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..74ec6c5 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,13 @@ +# The sdist ships the installable package, not the development tree. +# +# setuptools' default sdist walk picks up `test/*.py`, but not the support files +# those modules import (`test/__init__.py`, `helpers.py`, `validation_fixtures.py`, +# `validation_mutations.py`), nor the fixtures and container scripts they read +# from `src/`, `rules/`, `examples/` and `test/test_vcf_files/`. The result was a +# published archive whose test suite could not run at all. Shipping no tests is +# honest; shipping a suite that fails on arrival is not. +# +# The full suite runs from a git checkout, which is what CONTRIBUTING and +# `.github/workflows/tests.yml` both assume: +# python3 -m unittest discover -s test -p "test_*_unit.py" +prune test diff --git a/README.md b/README.md index 8ad5f6d..936ad48 100644 --- a/README.md +++ b/README.md @@ -1028,8 +1028,8 @@ how each part of the tool works, why, and where it stops working. | [Data linking design](docs/datalinking-design.md) | Broader proposal and remaining work | | [Privacy policy design](docs/privacy-policy-design.md) | Proposal: ODRL-based granular disclosure control over the graph | -- [`changelog.md`](changelog.md) - dated change history - [`ACKNOWLEDGEMENTS.md`](ACKNOWLEDGEMENTS.md) - funding and attribution +- [Releases](https://github.com/ecrum19/VCF-RDFizer/releases) - release notes per version ## Troubleshooting diff --git a/changelog.md b/changelog.md deleted file mode 100644 index 474c4de..0000000 --- a/changelog.md +++ /dev/null @@ -1,1509 +0,0 @@ -# Changelog - -## 2026-09-10 — Space-optimized by default, and `--hdt-strategy single` stops lying - -Benchmarking the two aggregate storage modes as a paired comparison showed -`space-optimized` reaches the same triples as `plain` at a much smaller peak -workspace footprint, with no practically important change in wall time, CPU -time, or peak memory. A flag with an answer that good should not be mandatory. - -The same experiment exposed that `--hdt-strategy single` was being silently -ignored in the most common configuration anyone would pass it in. - -### Changed - -- **`--rdf-storage-mode` now defaults to `space-optimized`** instead of being - required in full mode. `plain` remains available and is unchanged; it is what - `--hdt-strategy single` needs, and what to pass when one uncompressed `.nt` - aggregate on disk is the point. The new `DEFAULT_RDF_STORAGE_MODE` constant - carries the value. -- **`--hdt-strategy single` is documented as a verification path, not a faster - alternative.** There is no size regime where it wins: below - `--chunk-min-bytes` the partitioned path emits one chunk and its merge is - trivial, so the two converge, and above it partitioned is the only one that - survives cohort scale. What `single` is for is producing a one-shot HDT of the - same graph so the chunk-and-merge result can be checked against it — which is - what justifies partitioned generation being the default rather than merely - convenient. - -### Fixed - -- **`--hdt-strategy single` is no longer silently ignored when COTTAS is - selected.** COTTAS always needs bounded chunks, and both dispatch sites gate - partitioning on one boolean, so `--representations hdt,cottas --hdt-strategy - single` ran the partitioned path for both representations with the strategy - having no effect. Benchmark runs using that combination were measuring - partitioned HDT under a `single` label. It is now refused with a message - naming the remedy. -- **The two `single` refusals share one implementation.** `hdt_strategy_rejection` - replaces three separately worded inline checks across full-mode validation, - compress-mode validation, and the compress-mode runtime guard. The gzip-aggregate - message now also names `--rdf-storage-mode plain`, which matters more than it - did: with `space-optimized` the default, `single` needs that flag explicitly. - -### Tests - -- `test_main_full_mode_requires_storage_mode_argument` is replaced by - `test_main_full_mode_defaults_to_space_optimized_storage`, which asserts the - resolved value reaching `run_full_mode`. -- Added `test_main_full_mode_rejects_single_hdt_strategy_with_cottas` and - `test_main_full_mode_rejects_single_hdt_strategy_with_space_optimized`. -- The mocked RMLStreamer runner now reads `RDF_STORAGE_MODE` from the container - command and writes a real gzip aggregate for `space-optimized`, so the - default path is exercisable end to end rather than only under `plain`. - -Suite: **436 passing, 147 skipped** (all skips are the pre-existing `rdflib` -gates on the mutation and linking harnesses). - -## 2026-09-08 — Run without the data-linking dependency - -Running the tool from a checkout raised `ModuleNotFoundError: No module named -'rdflib'` before it could do anything at all — including print `--help`, or run -a conversion that does no linking. - -`vcf_rdfizer.main()` imports the data-linking CLI to build its argument parser. -That module imported `vcf_rdfizer_linking.{inputs,manifest,runner}`, each of -which imported `rdflib` at module level, so the dependency of one optional -feature gated every mode. The tool is Docker-first and routinely run from a -clone, where nothing installs Python dependencies. - -### Fixed - -- **`rdflib` is now imported where it is used, not where the module loads.** All - of its use was already inside functions: `read_rdf` in `inputs`, - `run_linkers` in `runner`, and `load_manifest` in `manifest`. The imports moved - into those three functions. -- **The linking namespaces build lazily.** `manifest.VCFL` and `manifest.VCFC` - were module-level `rdflib.Namespace` constants, the one genuine module-level - use. `_LazyNamespace` defers construction to the first term lookup and is - otherwise identical: attribute and item access both return a `URIRef`, and - `str()` gives the namespace IRI. -- **Requesting linking without the dependency now explains itself.** Both entry - points — `--link` in full mode and `--mode link` — report - `data linking requires the 'rdflib' package … install with 'pip install -e .'` - through the normal error path, instead of a traceback. - -`DEFAULT_CACHE` moved from `runner` to `reference`, which has no rdflib -dependency, because the argument parser offers it as a default; `runner` -re-exports it so existing importers are unaffected. - -`test_linking_unit.py` now skips when rdflib is absent instead of failing the -whole discovery run, matching the pattern `test_validation_mutation_unit.py` -already used. Those tests exercise linking itself, so they genuinely need it. - -Measured on a bare checkout: **66 errors before, 0 after** (116 skipped). With -rdflib installed the suite is unchanged at 419 passing, so linking itself is -untouched. - -Every non-linking mode now runs from a bare checkout. Linking itself is -unchanged and still requires `rdflib`, which remains a declared runtime -dependency in `pyproject.toml`. - -## 2026-09-08 — Fix the six failing unit-test jobs in CI - -Every `unit-tests` job failed on push: `wrapper-unit` on three OSes and -`shell+pipeline-unit` on three more. All six had one cause. - -### Fixed - -- **`tests.yml` never installed the project's dependencies.** The jobs ran - `setup-python` and went straight to `unittest discover` against a bare - checkout, so `rdflib` was absent. `vcf_rdfizer.main()` imports - `vcf_rdfizer_link` to build its argument parser, that module imports - `vcf_rdfizer_linking.inputs`, and that does a module-level - `from rdflib import …` — so **even `--help` raised `ModuleNotFoundError`**, - and every test that invokes `main()` errored. Locally the same bare-checkout - run produces 66 errors across both job types. - - `rdflib` is a *required* runtime dependency in `pyproject.toml`, not an - optional extra, so a bare checkout was testing a configuration no installed - copy has. The sibling `validation-mutation.yml` workflow already installed it; - `tests.yml` was simply missing the step. - - The three test jobs now run `python -m pip install -e .`, which pulls exactly - what `pyproject.toml` declares and cannot drift from it, while the tests still - execute against the checkout. `package-smoke` was unaffected — it installs a - wheel and gets the dependencies that way. - - Verified by reproducing CI in a clean virtualenv: `pip install -e .` followed - by both job commands. - -## 2026-09-08 — Verify against the published VCF Core 2.0.0 - -VCF Core is published at **2.0.0**, covering VCF 4.1 through 4.5. This checks -the converter against the released artifacts and closes the gap that made the -version model a private assumption. - -### Fixed - -- **A bracketed CHROM now links to its assembly contig.** VCF 4.5 lets CHROM - name a breakpoint-assembly contig in angle brackets (``) instead of a - declared reference sequence. The converter emitted only the raw `vcfc:chrom` - literal, which the published consistency profile rejects: a bracketed CHROM - must resolve to a `vcfc:AssemblyContig` whose `vcfc:assemblyContigId` matches - the bracketed text, and must *not* also name a declared `##contig`. The - record now carries `vcfc:chromAssemblyContig`, and the contig resource cites - the `##assembly` header line with `vcfc:declaredInAssembly`. - - Found by validating against the vocabulary's new `example-vcf45-boundaries` - fixture; the emitted IRIs and properties match its reference graph exactly. - -### Added - -- **The version model is cross-checked against the vocabulary's own registry.** - VCF Core publishes `ontology/versions/registry.json` as the single source of - truth for its version-scoped artifacts — the SHACL overlays, the reserved-key - snapshots and the `VCF4xFile` classes are generated from it. The converter - keeps a dependency-free copy of the same facts so it runs without the - vocabulary checked out; - `test_version_model_matches_the_published_registry` now pins the two together, - field by field: supported versions, `code`, `className`, - `leadingPhaseIndicator`, `svTupleScope`, the INFO/FORMAT `numberCodes`, and - the flattened-tuple keys and widths. It skips when no vocabulary checkout is - present; `VCF_CORE_VOCABULARY_DIR` points it at one. - - The two agree exactly as published — no drift to fix — but a new VCF version - or a corrected arity can no longer land on one side alone. - -- **`vcf_version` and `vcf_version_source` in the conversion metrics**, in both - `metrics.csv` and `stages/conversion/*.json`. The source is `declared`, - `forced` or `fallback`. Benchmarks need these to group runs: the version - selects the SHACL overlay, the tuple semantics and which FORMAT families - exist, so cost and graph size are not comparable across versions without - them. `metrics_layout_version` is now `3`. - -### Verified - -- Every VCF version resolves end to end: detection from `##fileformat`, the - correct `vcfc:VCF4xFile` on the file subject, the sentinel never left - unresolved, TSV paths rewritten, and `--vcf-version` overriding cleanly. - VCF 4.0, a missing declaration and a malformed one all fall back to the - newest supported rules with no version class, and say so. -- `--vcf-version` accepts exactly the versions the registry declares. -- The vocabulary's own example VCFs now include `example-vcf45-boundaries`, and - `example-condensed-cohort` declares VCFv4.1; both convert correctly. - -### Documentation - -- **`vcf-coverage.md` records the term-coverage delta.** VCF Core 2.0.0 defines - 338 terms; ten families are entirely unemitted — parsed FILTER, padding - semantics, parsed FORMAT keys, parsed record IDs, repeat units, breakend - mates, local-allele membership, mixed phasing, reference-block links, and - raw/decoded value pairs. None is required for conformance, and the table says - which kinds of benchmark the gap does and does not affect. -- `limitations.md` no longer lists the condensed terms, the `ALT=.` shape - contradiction or the ordinal datatype disagreement: all three are resolved in - the published release. What remains is VCF 4.0 having no overlay, and the - version table being a checked copy rather than the original. - -## 2026-09-07 — Stop a slow validation engine from looking like a hang - -A full run with `--validate` on a real cohort VCF spent 62 hours on its first -validation step. The cause was not a deadlock: it was three defects that -compound into one. - -### Fixed - -- **A timed-out query no longer costs one timeout for every remaining query.** - The per-query timeout defaults to 3600s and there are 27 queries per engine - per target, so one engine that cannot answer the graph burned **27 hours per - target** — the loop ran every query and only checked for failures afterwards. - It now stops at the first timeout, records which query tripped it and how many - were skipped, and moves on to the next engine. `--validation-continue-after-` - `query-timeout` restores the old behaviour. -- **A timed-out query no longer orphans its engine process.** Queries are - wrapped in `/usr/bin/time`, which forks the real engine. - `subprocess.run(timeout=)` signals only the process it started, so killing the - wrapper left the engine running — holding the entire graph in memory, because - that is what an in-memory SPARQL engine does. Twenty-seven of those is enough - to push a host into swap, which is what turned a slow step into an apparent - hang. Queries now run in their own session and the whole process group is - signalled, SIGTERM then SIGKILL. -- **The validation results mount is resolved.** Docker reads a relative bind - source as a *named volume*, so an unresolved path would have sent the reports - into a volume instead of onto the host. Every other mount in that command was - already resolved. - -### Added - -- **`--validation-time-budget`** (seconds, 0 = no ceiling, the default): a - wall-clock ceiling for one engine's whole query set. A backstop for queries - that are slow but never individually time out. -- **An up-front warning when an unindexed engine meets a large graph.** Comunica - has no persistent index: every query re-parses the whole source into memory, - so the cost is paid 27 times. Above 4 GiB the run now says so before - committing, states the worst-case hours at the current timeout, and points at - `--engine qlever` or `--validation-targets hdt`. This is the asymmetry behind - "QLever passed, Comunica did not": QLever builds an index once and answers - from it. -- **`summary.json` now carries a `validation` index.** Each target's stage - report, results directory, summary, benchmark JSON/CSV and the engines that - ran are named explicitly, with status, engine and wall time, instead of being - left to find among the report globs. - -## 2026-09-07 — Migrate the validation suite to VCF Core - -The conversion moved to VCF Core and became version-aware; the validation suite -still described the previous graph, so 31 of its tests failed. It now passes, -with its design intact: one declarative fixture deriving three artifacts, -coverage measured by mutation rather than asserted, and expectations derived -from the VCF rather than from the mapping. - -**415 tests pass.** Mutation score: **96/113 (85%)** across 60 mutations, up -from 42. - -### Fixed - -- **Every declared INFO and FORMAT definition was emitted twice.** The header - emitter produced a declaration's `fieldId`/`fieldNumber`/`fieldType`/ - `fieldDescription` from the `##` line, and the value emitters produced the - same four triples at the same header-line IRI when the key was first used. - The header emitter now owns any declaration derived from a `##` line; the - value emitters cite it with `vcfc:declaredBy` and invent a definition only for - a key no header declared. - - This is worth noting for what caught it: `preflight_duplicate_triples`, which - compares the parsed triple count against the distinct count. No SHACL shape - can express that — a duplicate triple is not a distinct RDF statement, so the - graph validated cleanly with the duplicates present. - -### Changed - -- **The runner and the wrapper share one vocabulary module.** - `validation_runner.py` carried its own copies of `HEADER_LINE_CLASSES`, - `rml_uri_component`, `parse_structured_header_fields` and - `parse_info_entries`, with unit tests asserting the copies stayed identical. - Both now import `vcf_rdfizer_vocab`, which the `Dockerfile` copies next to the - runner. The drift the tests policed is removed rather than policed. -- **The census derives every new resource family from the VCF.** Two shared - functions, `emitted_header_counters` and `emitted_record_counters`, are called - by the container's `parse_vcf` and by the fixture's `parser_summary`, so the - two oracles cannot disagree. They cover the header attributes, the allele - layer, the `vcfc:FieldValueItem` decomposition, the breakend components and - the parsed genotype layer. `parse_vcf` stays representation-independent; the - genotype counters are reported separately and merged for the expanded profile - only. -- **`base_triples()` tracks the new mapping**: the version class, the - `#CHROM` column-header line, `vcfc:lineIndex` and `vcfc:recordIndex` in, and - `ID`/`ALT`/`FILTER`/`infoRaw` out — those moved to the wrapper's emitter - because each may be the VCF missing token. -- **The fixture derives its expected version class** from its own declared - `FILE_FORMAT`, so changing that changes the expected graph with it. - -### Added - -- **18 mutations** for the layers VCF Core introduced: the version class, header - attributes, the allele layer, indexed values, reusable sample identity, the - parsed genotype layer and field-declaration ownership. Ten are recorded as - undetected, each naming what would close it — the score fell from 97% to 85% - because the denominator grew, which is the methodology working rather than a - regression. -- **`corrupt_sample_index` is split by profile**, because the same corruption is - detected in the condensed profile and not the expanded one. In the condensed - profile the ordinal associates a vector position with a sample, so corrupting - it moves genotypes between samples; in the expanded profile each `SampleCall` - carries its own `vcfc:sampleId` and nothing reads the ordinal. A real - difference in what the two profiles depend on, now recorded as such. -- Census tests asserting that every new family is in the inventory, and that the - genotype layer appears in the expanded census and *not* in the condensed one. - -## 2026-09-07 — Version-aware conversion for VCF 4.1 through 4.5 - -VCF Core gained a SHACL overlay per VCF version, each scoped by the file's -`vcfc:fileFormat`, plus optional `vcfc:VCF41File`…`vcfc:VCF45File` classes that -activate those gates. Three things the converter emits genuinely differ between -versions, so the conversion now follows the version of each input instead of -assuming 4.5. - -### Added - -- **Automatic version detection, per input.** `##fileformat` is required to be - the first line of a conforming VCF and `src/vcf_as_tsv.sh` already lifts it - into `file_metadata.tsv`, so detection costs one small read and needs nothing - from the user. It is per input rather than per run, so a directory of mixed - versions converts correctly. The run log states the version and how it was - chosen. -- **`--vcf-version {auto,4.1,…,4.5}`**, defaulting to `auto`. An explicit - version is an override for a file whose declaration is missing or wrong, and - the log says when the file's own declaration was overridden. -- **A version sentinel in the RML mapping.** `<#VCFFileMap>`'s subject map - carries `rr:class vcfc:VCFVersionFile`, which `render_rules_for_triplet` - rewrites per input — the same mechanism that already rewrites the five - `csvw:url` paths — to the `vcfc:VCF4xFile` subclass for that input's version. - One mapping stays the single source of truth for all five versions instead of - five near-identical copies that would drift apart. `vcf-rdfizer-rules check` - reports whether a custom mapping has the sentinel. -- **A `VCFVersion` model** in `vcf_rdfizer_vocab.py` carrying, per version, the - permitted Number codes, the flattened-tuple keys and their widths, whether - tuples repeat per ALT allele, and whether the local-allele, base-modification, - EVENTTYPE and leading-phase-indicator features exist. - -### Changed - -- **`CIPOS`/`CIEND` tuple semantics follow the version.** Before VCF 4.4 the - list is one pair describing the record, so its `vcfc:FieldValueItem`s carry an - index and a `vcfc:tupleArity` but no `vcfc:forAllele`, and every ALT allele of - a multi-allelic record shares the interval. From 4.4 the list repeats per ALT - and each item joins its own allele. `CILEN` and `CICN` are only tuple keys - from 4.4. -- **`EVENT` follows the version.** It is `Number=1` before 4.4 — one event for - the record — and `Number=A` from 4.4, one per ALT allele, so the `vcfc:inEvent` - link moved onto the allele there. `EVENTTYPE` does not exist before 4.4, and - `vcfc:VariantEventShape` requires an event type, so a pre-4.4 EVENT stays an - ordinary INFO value. -- **Families a version does not define are no longer invented.** A `LAA` column - in a 4.4 file, or an `M27551C` column in a 4.3 file, keeps its raw - `vcfc:fieldValue` and gets no `vcfc:LocalAlleleSet` or `vcfc:BaseModification` - resource. -- **VCF 4.0 is reported as unrecognized.** VCF Core claims no 4.0 overlay, so a - 4.0 file converts with the newest supported rules — nothing representable is - dropped — but emits no version class, so the graph never claims a gate that - cannot be checked. A missing or malformed `##fileformat` line behaves the - same. All three are reported, never assumed silently. - -Parsing leniency is deliberately unchanged: a GT with a leading phase indicator -in a 4.1 file is still parsed, and the version overlay reports it. The converter -transcribes; the validator judges. - -### Fixed - -Two defects found by validating against the new complete profile set: - -- **Flattened tuple keys were never decomposed.** `CIPOS` and friends are - declared `Number=.` in 4.4/4.5, which on its own says "no positional - meaning", so no `vcfc:FieldValueItem`s were emitted — but the version overlays - count those items against the ALT count. Tuple keys are now positional by - virtue of being tuple keys, whatever their declared Number. -- **Confidence-interval bounds were plain strings.** `vcfc:ciLower`/`ciUpper` - and the FALDO `begin`/`end` go through `vcfc:NumericLiteralShape`, which - requires an integer- or decimal-derived datatype. -- **A sites-only VCF got no representation profile.** Both sample emitters - returned early when the file declared no sample columns, so a VCF with only - the eight fixed columns violated `vcfc:RepresentationProfileShape`, which - requires exactly one profile on every `vcfc:VCFFile`. The profile is now - emitted regardless; the `vcfc:SampleSet` is still omitted, because - `vcfc:SampleSetShape` requires at least one member. - -### Verified - -Zero violations across 19 graphs against the **complete** profile set — the -portable, SPARQL and consistency profiles plus all five version overlays — run -with pySHACL using the bundled ontology plus every `ontology/versions/*.ttl` -and RDFS inference, which is the configuration the vocabulary's own -`tests/validate_shacl.py` uses. Inputs were all ten of the vocabulary -repository's example VCFs (4.1 through 4.5, including the breakend, gVCF, repeat -and condensed-cohort fixtures) and a hand-written stress file rendered for every -version plus a 4.0 variant, in both representation profiles. - -### Note on the vocabulary's own version number - -The vocabulary is now `owl:versionInfo "2.0.0"` with -`owl:versionIRI `, which matches the -v2.0.0 originally requested — it read 4.0.0 when the migration started. This -converter pins no version IRI, referencing only the namespace, so nothing here -needed changing and nothing goes stale. - -## 2026-09-07 — Retarget the conversion to the VCF Core vocabulary - -The conversion produced RDF in `https://w3id.org/vcf-rdfizer/vocab#`. That -namespace is retired: the vocabulary was renamed **VCF Core** and moved to -`https://w3id.org/vcf-core/vocab#` (prefix `vcfc:`), because it is a semantic -target any conversion system can adopt and its name should not carry the name of -one converter. The old namespace is **not** redirected — it serves a deprecation -document linking every former term to its successor — so this is a breaking -change to the emitted graph. - -VCF Core also models considerably more of VCF 4.5 than its predecessor. The -mapping rules and the wrapper's emitters were rewritten to cover it rather than -only re-prefixed. - -### Changed - -- **Namespace.** Every emitted IRI moves from `vcfr:` to `vcfc:`. One term was - renamed rather than re-namespaced: `vcfr:DenseRepresentation` is now - `vcfc:ExpandedRepresentation`. No version IRI is pinned anywhere — the - converter targets the namespace, and the vocabulary's release line is - independent of this one's. -- **The RML/wrapper split is now one rule**, stated in the mapping's header and - in [`architecture.md`](docs/architecture.md#4-where-the-split-leaks-and-why): - *RML carries every field whose RDF datatype is the same for every row; the - wrapper carries everything else.* Accordingly `ID`, `ALT`, `FILTER` and - `infoRaw` moved out of the mapping and into `emit_record_detail`, joining - `QUAL` and `fileDate`. Each may be the VCF missing token, which the vocabulary - requires as `"."^^vcfc:Null`, and RML cannot switch an object's datatype per - row. `CHROM`, `POS` and `REF` stay in the mapping precisely because VCF 4.5 - forbids them from being missing. -- **Ordinals are serialized `xsd:integer`, not `xsd:positiveInteger`.** The - SHACL profiles constrain every ordinal with `sh:datatype xsd:integer` and that - constraint compares the datatype IRI exactly, so an `xsd:positiveInteger` - literal fails the shape while an `xsd:integer` literal satisfies both the shape - and the ontology's declared range. This affects `vcfc:sampleIndex`, which the - condensed emitter previously typed `xsd:positiveInteger`. -- **`--header-representation basic` no longer produces a conformant graph.** - `vcfc:StructuredHeaderLineShape` requires at least one `vcfc:hasAttribute` on - every structured header line, and `basic` emits no subclass and no attributes. - It remains available as the smallest, fastest header form. -- **QUAL accepts the full VCF Float lexical space.** `INF`, `INFINITY` and `NAN` - in any case are emitted as `vcfc:VCFFloat` rather than coerced or flattened to - a plain literal; a finite value still takes `xsd:decimal` in its source lexical - form. - -### Added - -- **`vcf_rdfizer_vocab.py`** — the vocabulary terms and the VCF 4.5 parsers, as - pure functions so they are testable without producing RDF: allele - classification, breakend parsing, GT parsing, `Number` arity resolution, value- - item indexing, and base-modification key recognition. -- **Header layer.** Ordered `vcfc:HeaderAttribute` resources on every structured - line; `##assembly`, `##pedigreeDB`, `##META`, `##SAMPLE` and `##PEDIGREE` typed - and decomposed; `vcfc:ColumnHeaderLine` for `#CHROM` with - `vcfc:hasGenotypeColumns`; `vcfc:lineIndex` and `vcfc:recordIndex` for the - ordering constraints the SPARQL SHACL profile checks; `vcfc:fieldArity` and - `vcfc:fieldNumberInteger`; `fieldSource`/`fieldVersion`; typed contig `length` - and `URL`. An unrecognised `##` key is now typed as structured or unstructured - by the form of its value rather than left bare. -- **Allele layer.** `REF` and each `ALT` item become ordered - `vcfc:ReferenceAllele`/`vcfc:AltAllele` resources with `alleleIndex`, - `alleleValue` and `alleleKind`; symbolic alleles are linked to their `##ALT` - declaration and given a `vcfc:svType` where the ID is a reserved code; - breakends are parsed into orientation, replacement string and mate position; - records are linked to their contig declaration with `vcfc:chromosome`. -- **Value items.** `Number=A/R/LA/LR/G/LG/P` values are decomposed into ordered - `vcfc:FieldValueItem` resources joined to their allele with `vcfc:forAllele`, - with `vcfc:tupleArity` for the keys that flatten fixed-width tuples. This - closes the multi-valued-INFO gap previously recorded in `limitations.md`. -- **Structural variation.** `SVLEN`, `SVCLAIM`, `IMPRECISE`, `NOVEL`, `END`, - `EVENT`+`EVENTTYPE`, the `CI*` confidence intervals (FALDO `InRangePosition` - for `CIPOS`/`CIEND`), the `RN`/`RUS`/`RUL`/`RUC`/`RB` tandem-repeat structure, - and gVCF `<*>` reference blocks. -- **Genotype layer, expanded profile only.** `GT` parsed into a `vcfc:Genotype` - with `genotypeString`, `ploidy`, an explicit `vcfc:phasingStatus` and one - `vcfc:GenotypeAlleleCall` per position; plus `FT`, `PS`/`PSL`/`PSO`/`PSQ`, - `LAA`, the copy-number and haplotype keys, and the `M`/`DPM`/`ADM` - base-modification families with their ChEBI residue. The condensed profile - deliberately keeps these inside its vectors — deriving them per sample is the - materialization that profile exists to avoid. -- **Reusable sample identity in both profiles.** `vcfc:SampleSet` and its ordered - `vcfc:VCFSample` members are emitted in expanded mode too, and a `SampleCall` - links to its column with `vcfc:forSample`. It costs one resource per sample - column for the whole file. -- `docs/validation-migration-notes.md` — what the migration leaves to do in the - validation suite, and how the converter's SHACL conformance was verified. - -### Fixed - -- The condensed emitter omitted `vcfc:fieldType` on its `FormatFieldDefinition` - resources, which `vcfc:FormatFieldDefinitionShape` requires. Condensed graphs - were therefore non-conformant. -- Four modelling bugs found by running the vocabulary's SHACL profiles against - the output, all the same shape: a resource typed into a class whose shape - requires a property the record did not supply. `<*>` was typed - `vcfc:ReferenceBlock` without `referenceBlockLength`; `` was typed - `vcfc:TandemRepeatAllele` without `repeatSequenceCount`; `EVENT` minted a - `vcfc:VariantEvent` without `eventType`; and emitting `vcfc:endPosition` on a - symbolic SV allele made RDFS infer `vcfc:ReferenceBlock` for it. Each carrier - is now emitted only when the record supplies everything its shape needs. - -### Verified - -The output validates against both published SHACL profiles — -`vcf-core-vocabulary.shacl.ttl` and `vcf-core-vocabulary-sparql.shacl.ttl` — -with **zero violations**, in both representation profiles, run with pySHACL -using the bundled ontology and RDFS inference. Inputs were the vocabulary's own -`examples/example.vcf` and a VCF 4.5 stress file covering structured headers, -symbolic and breakend ALTs, tandem repeats, a gVCF reference block, -`Number=A/R/G` fields, phased GT with a phase set, `LAA`, `FT`, `CN` and a base -modification. - -### Known broken - -The validation suite was migrated separately; see the entry above it. At the -time of this change 31 of its tests failed because they asserted against the -retired namespace and the previous emitted shape. - -## 2026-09-06 — Runnable examples of all three data-linking tiers - -### Added - -- `rsid-dbsnp` declarative token links, `gene-demo` with a digest-pinned - synthetic GFF3 bundle, and a batched `rsid-ensembl` live resolver. -- A shared host-side runner with Turtle manifests, directory/entry-point - discovery, disk-backed key deduplication, interval joins, assembly refusal, - atomic side-graphs, provenance and per-linker run metrics. -- `--link` in full mode; Docker-free `--mode link --rdf`; and - `vcf-rdfizer-link list|keys|init|check|dry-run|run` authoring commands. -- Cached HTTPS sessions with per-host pacing, per-run request ceilings, - retries respecting `Retry-After`, offline replay and contact headers. -- Known-answer and failure tests for the three examples and their shared - runtime. The live resolver is tested using fake HTTP, not a public API. - -### Changed - -- RDFLib is now a runtime dependency for Turtle/N-Triples parsing. -- The [implementation guide](docs/datalinking.md) documents commands and - limitations; the original proposal is marked partially implemented. Allele - normalization, link merging and plug-in validation discovery remain planned. -## 2026-09-05 — Fix a unit test that inverted under CI - -`shell+pipeline-unit` failed on all three OS matrix legs of the `dev` -> `main` -merge (ubuntu-latest, ubuntu-22.04, macos-latest) while passing on developer -machines. One test, three red checks. - -### Fixed - -- `test_validation_forwards_progress_sidecar_and_quiet_flag` asserted that - `run_validation_mode` forwards `--progress-path` to the container. It does — - but `progress_events_enabled()` returns `False` whenever `CI` is set, and - GitHub Actions sets `CI=true`, so the sidecar is deliberately not requested - there. The test pinned `_PROGRESS_ALLOWED`, `_PROGRESS_EVENTS_ALLOWED` and - `_QUIET` but not the environment, so it tested a different code path in CI - than the one it was written for. Reproducible locally with - `CI=true python -m unittest discover -s test -p "test_*_unit.py"`. - - The tool's behaviour is correct and unchanged: the sidecar exists only to - drive the terminal display and `ProgressSession.__exit__` unlinks it, so - suppressing it where nothing renders costs nothing. - -### Changed - -- `stable_progress_env()` replaces the `{"VCF_RDFIZER_NO_PROGRESS": "", "CI": ""}` - dict that two sibling progress tests already carried inline. The third test - omitted it, which is how this happened; a named helper with the reason in its - docstring makes the requirement visible to the next test author. -- The validation-command setup is factored into - `_run_validation_mode_capturing_commands()`, shared by both sides of the - contract. - -### Added - -- `test_validation_omits_progress_sidecar_under_ci` pins the CI behaviour that - was previously only implicit: no `--progress-path` is requested, and `--quiet` - still is. Verified as a real guard by removing the `CI` check from - `progress_events_enabled()` and confirming the test fails. - -## 2026-09-05 — Vocabulary alignment for the condensed representation (upstream) - -The two open items in [`docs/roadmap.md`](docs/roadmap.md) under "Blocking -publication" are closed. Both were work in the -[vocabulary repository](https://github.com/ecrum19/VCF-RDFizer-vocabulary), -released there as **v1.1.0**; **no change was needed in this repository**, and -this entry records what the conversion may now rely on. - -### Condensed graphs are ontology-backed - -The conversion emitted 17 terms the vocabulary did not define — `SampleSet`, -`VCFSample`, `CohortCallMatrix`, `FormatValueVector`, `representationProfile`, -`sampleIndex`, `encodedValues` and the rest — so a condensed graph could not be -dereferenced or meaningfully SHACL-checked. All 17 are now defined, with two -superclasses (`RepresentationProfile`, `VectorEncoding`) giving the enumerations -a range, plus SHACL shapes for the profile and a worked example that is the -expanded example's own record in the other profile. - -The condensed shapes constrain what positional decoding depends on: exactly one -`sampleIndex` per sample, a sample set on every matrix, and an encoding and -FORMAT declaration on every vector. Ten targeted corruptions of a condensed -graph are each reported as a violation, so the shapes are load-bearing. - -`--shacl-shapes` therefore now covers `--sample-representation condensed`, which -it previously could not. - -### The missing-value contradiction is resolved - -`vcfr:missingValuePolicy` required `"."^^vcfr:Null` for a missing token while -`VCFRecordShape` constrained `vcfr:alt` to `sh:datatype xsd:string`, so a record -with `ALT=.` could satisfy neither and the tool could not be conformant on any -VCF containing one. - -The fix draws the boundary the policy was missing rather than relaxing every -field: ALT and ID admit the missing token in VCF 4.5, so their shapes now accept -`xsd:string` or `vcfr:Null` as `qual` already did; CHROM, POS and REF are -required and have no missing form, so their shapes stay exact — a `.` there is -malformed input and should still be reported. The policy also now states that a -missing value inside a `FormatValueVector` stays a `.` character at its sample's -position, rather than becoming a typed literal that would break alignment. - -The conversion already followed the policy, so it needs no change. Reproduced -against the 1.0.1 shapes before the fix and confirmed gone after. - -### Caveat - -The terms only dereference for a third-party consumer once vocabulary v1.1.0 is -published to `https://w3id.org/vcf-rdfizer/vocab#`. Until then the definitions -exist but are not yet live, which is why the docs below say "pending release" -rather than "done". - -### Documentation - -- [`docs/vcf-coverage.md`](docs/vcf-coverage.md) — the "Vocabulary alignment" - section now records both gaps as closed, with what was verified. -- [`docs/roadmap.md`](docs/roadmap.md) — both publication blockers marked done. -- [`docs/limitations.md`](docs/limitations.md), - [`docs/conversion.md`](docs/conversion.md), - [`docs/validation.md`](docs/validation.md) updated to match. - -## 2026-09-04 — Multi-engine validation, native HDT/COTTAS querying, and benchmarking - -Validation was one engine against one N-Triples file. It is now up to four -engines against the artifact each of them reads best, in a single run, timed -and cross-checked. - -### Added - -- **Several SPARQL engines in one run.** `--validation-engine` accepts a - comma-separated list or `all`. Every requested engine answers the whole query - set; the first is the primary and keeps the existing single-engine report - layout, while each engine additionally gets `engines//` with its own - preflight, SPARQL, comparison and execution reports. The run's `status` is - `PASS` only if every engine passed, and `summary.json` carries - `engineStatuses`. -- **Cross-engine agreement on the real graph.** Every engine's normalized - results are compared against each other and written to - `engine-agreement.json`, naming the queries that differ. This is not - theoretical: QLever's literal canonicalisation had already been caught this - way in the test harness. -- **Native HDT and COTTAS querying** (`--validation-engine hdt` / `cottas`). - `--validation-target hdt,cottas` validates those artifacts by *decoding* them - first, which proves the decode is faithful and says nothing about querying - them — and measures the wrong thing entirely in a performance comparison. The - new engines query the artifact in place: HDT through `comunica-sparql-hdt`, - COTTAS in-process through `pycottas.COTTASStore`, an rdflib `Store` over the - Parquet artifact. When the run's own artifact is already in the engine's - format it is used directly; otherwise one is built in container scratch and - that build is timed as **setup**, kept out of the query total. Each report - records which happened, in `artifactOrigin`. -- **`@comunica/query-sparql-hdt` in the image**, installed alongside - `build-essential` (needed for its native bindings) which is purged in the same - layer. -- **Timings for everything, and a comparison against the parser.** Every run - writes `benchmark.json` and a long-format `benchmark.csv` — one row per engine - and query, ready to plot without reshaping. `benchmark.json` adds per-engine - setup and query totals, the slowest query per engine, materialization and - SHACL time, and the **oracle**: what it costs to compute the same answers - directly from the VCF with cyvcf2, split into parse and census. The suite - already computes every expected value twice, once by parsing and once by - querying, so those two costs are for identical work on identical input — the - performance comparison the reports were missing. -- **Benchmark columns in the run's `metrics.csv`**: `validation_engines`, - `validation_oracle_seconds`, `validation_engine_query_seconds` and - `validation_engine_setup_seconds`, the last two as `engine=seconds` pairs. - -### Fixed - -- **Comunica could not query an HDT file by path.** A bare path is treated as a - link to dereference and failed with "Could not dereference". The source is now - addressed as `hdt@`. Found by the first real four-engine run, not by - inspection. -- **The parser oracle was reading htslib's header, not the file's.** cyvcf2's - `raw_header` is normalised: htslib injects - `##FILTER=` into files that never - declared it. The oracle therefore expected a `FilterDefinition` resource the - graph could not contain, and every header check failed. `read_vcf_header_text` - now reads the header block from the file itself — the same text the conversion - reads — for both plain and gzipped VCFs. - -### Verified - -- A four-engine run over the fixture: all four `PASS`, all four agree, and the - benchmark records per-query timings for each. -- `test/cross_engine_agreement.py` extended from two engines to all four, - across both representations, with per-run scratch so the native engines cannot - read each other's artifacts. All queries agree and every engine agrees with - the Python oracle. -- 347 host tests pass (24 new); mutation score unchanged at **76/78**. - -### Documentation - -- [`docs/validation.md`](docs/validation.md) — rewritten engine section covering - all four engines, multi-engine runs, native artifact querying, and the - benchmark report. Its "What is *not* tested" section was stale — it predated - the census, the identity digests, and the QUAL/INFO coverage work, and - contradicted [`docs/vcf-coverage.md`](docs/vcf-coverage.md) — and now states - the gaps that actually remain. -- [`docs/validation-methodology.md`](docs/validation-methodology.md) — "Two - engines" became "Four engines", with the two new cross-engine findings and a - section on why a multi-engine run is a controlled benchmark rather than an - incidental one. -- [`README.md`](README.md), [`docs/cli-reference.md`](docs/cli-reference.md), - [`test/README.md`](test/README.md) updated; the README's stale mutation score - (36 mutations, 64/66) corrected to 42 and 76/78. - -## 2026-09-04 — Design proposal: granular privacy policies over the VCF graph - -[`docs/privacy-policy-design.md`](docs/privacy-policy-design.md) — **design -proposal, not implemented.** A system for governed, partial release of a VCF -graph: which participants, which regions, which fields, at what resolution, to -whom, for what purpose — declared in ODRL and enforced by the pipeline. - -### Added - -- **An ODRL profile whose assets are graph selectors.** ODRL's `odrl:target` - addresses an Asset IRI and has no notion of "these triples", so the profile - supplies `ClassSelector`, `PredicateSelector`, `SampleSelector`, - `RegionSelector`, `FieldSelector`, `HeaderSelector` and a SPARQL - `PatternSelector` escape hatch. It also pins the conflict semantics ODRL - leaves informative: deny-overrides, default-deny, most-restrictive-first - composition. -- **Effects beyond permit/prohibit**, because the useful answer for genomic data - is usually less resolution rather than nothing: `drop`, `pseudonymize`, - `generalize`, `threshold`, `aggregateOnly`, and `maskVectorPositions`. -- **Three enforcement tiers derived from the existing pipeline** — TSV - pre-filtering before RMLStreamer (cheapest, covers RML-produced triples), - emitter-time filtering inside `_append_rdf_atomically` (full record context, - no second pass), and a post-hoc `--mode redact` (needs two passes for region - rules, since an N-Triples stream has no ordering guarantee). The compiler - assigns each rule to the cheapest tier that can express it, and **aborts** on - any rule no tier can enforce rather than warning. -- **GA4GH DUO consent codes as `odrl:purpose` right operands**, so a policy is - reviewable by the data access committees that already speak DUO. -- **Release manifests and policy conformance verification**: prohibitions - compile to `ASK` preflights that must return zero, with mutation-catalogue - entries that break the redactor and assert the checks catch it — the same - "measured, not asserted" standard as - [`validation-methodology.md`](docs/validation-methodology.md). - -### Findings that affect work outside the proposal - -- **`ParsedSampleRecord` carries no `CHROM` or `POS`.** `_parse_row` reads - columns 0, 1, 7, 9, 10 and −1, skipping 2 and 3. Any region-scoped feature - evaluated at emission time needs both; adding them is two dataclass fields and - two index reads. -- **Condensed mode cannot express per-sample protection by triple filtering.** - One `FormatValueVector` literal holds every participant's value for a FORMAT - key, so the unit of protection is finer than the unit of storage. Redaction - must rewrite the literal in place (replacing a position with `.` to preserve - `sampleIndex` alignment), and a single masked position is itself disclosive. -- **IRIs and header lines leak independently of genotypes.** Sample names, the - source filename and a monotonic row counter are all embedded in IRIs, and - `##source` / `##SAMPLE` / `##PEDIGREE` / free-text `Description` fields are - transcribed verbatim. Recorded in - [`docs/limitations.md`](docs/limitations.md). - -### Framing kept throughout - -The document is explicit that this is **governed release, not anonymization**. -Genotypes are identifiers — a few dozen independent common variants single out -an individual — so an access-control layer governs who receives what and creates -an audit trail; it does not make released data non-identifying. Differential -privacy is discussed and explicitly **not** proposed, because without a -persistent per-recipient budget ledger it provides no protection. - -## 2026-09-04 — Documentation set, and a data-linking design proposal - -`docs/` becomes an in-depth explanation of the whole tool rather than four -validation-focused documents. Every part of the pipeline is now described, with -its limitations stated next to its capabilities rather than in a footnote. - -### Added - -- [`docs/README.md`](docs/README.md) — index, reading paths per audience, and - the conventions the documentation set follows. -- [`docs/architecture.md`](docs/architecture.md) — the host/container split, - what runs where, the **three places that split deliberately leaks** (genotype, - header and QUAL/INFO emission happen on the host because RML cannot choose a - datatype or class per row), the three-way failure policy, and the pinned - toolchain versions. -- [`docs/conversion.md`](docs/conversion.md) — VCF -> TSV -> RDF stage by stage, - including what the single-`awk`-pass parser can and cannot see, the complete - IRI template table, and the datatype and missing-value decisions. -- [`docs/representations.md`](docs/representations.md) — the compression plan's - three independent decisions, record-safe chunking, the `hdtc` and PyArrow - rationales, and what the round-trip check does *not* prove. -- [`docs/output-and-metrics.md`](docs/output-and-metrics.md) — output layout, - the `run_metrics/` tree, input size accounting, progress, interrupts, exit - codes. -- [`docs/rml-mappings.md`](docs/rml-mappings.md) — the `--rules` contract in - full, plus what a custom mapping does *not* control and what it costs in - validation. -- [`docs/cli-reference.md`](docs/cli-reference.md) — every flag, grouped, with - enforced constraints, environment variables, and exit codes. -- [`docs/limitations.md`](docs/limitations.md) — one consolidated, honest - account: operational, input handling, modelling, extension points, - compression, validation, vocabulary, and scope. -- [`docs/roadmap.md`](docs/roadmap.md) — planned work, known defects, and - options that were assessed and deliberately rejected. -- [`docs/datalinking-design.md`](docs/datalinking-design.md) — **design - proposal, not implemented.** A plug-in architecture for linking the graph to - external resources, built on the observation that rsID, gene and clinical - linking are all one of three joins (`token`, `interval`, `allele`). Three - plugin tiers (declarative template, local reference bundle, live service), - enforced network safeguards, side-graph output with provenance, and a build - order that freezes the extension contract before capability is added. - -### Fixed - -- **Documented behaviour that did not match the code.** `README.md` and - `docs/validation.md` both stated that the wrapper switches `q09`-`q13` to - report-only under a custom `--rules`. It does not: `--mapping-policy` exists - in `validation_runner.py` but `vcf_rdfizer.py` never forwards it, so the - runner always executes `strict` and a *correct* custom-mapping conversion is - reported as `MISMATCH`. The claim is corrected in both places, recorded in - [`docs/limitations.md`](docs/limitations.md), and tracked as a defect in - [`docs/roadmap.md`](docs/roadmap.md). No code change yet. - -### Changed - -- Existing documents gained consistent navigation headers and "See also" - footers, and `README.md` now points at `docs/README.md` as the documentation - entry point rather than listing two files. - -## 2026-09-04 — Graph integrity: blank nodes, empty terms, duplicate statements - -Three checks that verify the N-Triples graph itself, independently of what the -VCF contains. Mutation score **64/66 -> 76/78**, catalogue 36 -> 42 mutations. - -### Added - -- `preflight_blank_nodes` — any blank node, in subject or object position. Every - class in the vocabulary declares an `vcfc:iriTemplate`, so a blank node means - a term map produced no IRI; the record and value digests could not address - such a node, and neither could anything that later merges the graph. A - predicate cannot be blank in RDF, so it is not examined. -- `preflight_empty_values` — empty or whitespace-only literals and IRIs, each - labelled `EMPTY_LITERAL` or `EMPTY_IRI` in the sample. An empty literal means - a value was lost rather than marked missing (the pipeline writes - `"."^^vcfc:Null` for a genuine missing token); an empty IRI means a template - substitution collapsed. Whitespace-only counts as empty: it carries no more - information and is just as certainly a defect. -- `preflight_duplicate_triples` — the same statement emitted more than once. - -Both anomaly checks have exact-count companions, so severity is measured rather -than saturating at the 100-row diagnostic sample. - -### How duplicates are detected, and why it could not be a query - -A SPARQL store holds a **set**. A repeated line is collapsed on load, so it is -invisible to every other check here — `COUNT(*)` over `?s ?p ?o` returns the -distinct total on Comunica, QLever and rdflib alike. Verified before building -anything: a three-line file with one repeat reports 2. - -The detector compares the statements the parser read against the distinct -triples the store holds. Raptor supplies the first (`rapper -c` counts parsed -statements including repeats — confirmed in the image: it reports 3 where the -store reports 2), `preflight_distinct_triple_count` the second, and the -difference is exactly the number of redundant statements. Duplicating the whole -fixture graph reports `parsed=624, distinct=312, duplicates=312`. - -This is worth having because duplicated RDF parts are a known failure mode of -the conversion — `run_conversion.sh` already carries a defensive dedupe for it — -and a duplicated aggregate costs twice the storage for no added information. - -### Behaviour - -- All three are blocking: a graph that fails one is not worth comparing. -- When an input a check needs is unavailable, it reports `NOT_EVALUATED` rather - than `PASS`, and `NOT_EVALUATED` never fails a run. A check that could not run - must not be mistaken for a clean result in either direction. - -### Verified - -- All 22 queries (13 core, 9 preflight/count) return identical values under - Comunica and QLever for both representations, and both engines produce `PASS` - against the Python oracle — including the new `ISBLANK`, `ISIRI` and - `REGEX`-based checks. -- 317 tests pass. Six new mutations (`introduce_blank_node`, - `blank_node_object`, `empty_literal`, `whitespace_only_literal`, - `duplicate_triple`, `duplicate_whole_graph`) are all detected. - -### Documentation - -- `docs/validation.md` gained a "Graph integrity" section explaining why - duplicates cannot be found by a query. -- `docs/vcf-coverage.md` lists the three under graph-level properties. -- `docs/validation-methodology.md` now describes four independent layers rather - than three. - -## 2026-09-04 — Full VCF coverage: census, identity digests, INFO, headers, SHACL - -Phases 2-6 of the validation-coverage plan. Mutation score **29/45 -> 64/66** -(64% -> 97%), across a catalogue that grew from 21 to 36 distinct mutations. - -### Fixed — silent data loss - -- **QUAL was extracted from every VCF and never mapped into RDF.** It is now - emitted, typed `xsd:decimal` or `"."^^vcfc:Null` as the published SHACL shape - requires. RML cannot choose a datatype per row, so it comes from a new - record-detail emitter rather than `default_rules.ttl`. -- **`##fileDate` was never mapped.** Now emitted as `vcfc:fileDate`, typed - `xsd:date` when the value's form allows and lexically otherwise. - -### Added — completeness (Phase 2) - -- `q09_predicate_census` and `q10_class_census` compare the graph's predicate - and class inventory against counts derived from the VCF. One comparison - catches three things: a predicate missing, one with the wrong cardinality, and - one that should not be in the graph at all. Expectations are derived from the - VCF and the emitters' documented shapes, never from `default_rules.ttl` - - deriving them from the mapping is how QUAL stayed invisible. -- `--mapping-policy {strict,report-only}`: a custom `--rules` changes the - inventory and IRI templates by design, so these checks become report-only. - -### Added — record and value identity (Phases 3-4) - -- `q11_record_digest`, `q12_info_value_digest`, `q13_format_value_digest` hash - each record, INFO value and FORMAT value **together with its own IRI** and - bucket the result. Binding identity into the hash is what catches a - permutation; bucketing keeps the result at most 256 rows for any graph size - and needs no ordering guarantee, which `GROUP_CONCAT` could not have given - portably. Fields are separated by U+001F, which cannot occur in a VCF field. -- These close the two largest gaps: values permuted between records, and non-GT - FORMAT values (a mangled DP, GQ or AD previously passed). - -### Added — structured INFO (Phase 4) - -- `--info-representation {structured,raw}`, default `structured`: one - `vcfc:InfoFieldValue` per record and key at the vocabulary's declared IRI - template, linked by `vcfc:declaredBy` to an `InfoFieldDefinition` carrying - `fieldId`/`fieldNumber`/`fieldType`/`fieldDescription`. Single-valued - Integer/Float fields also get `fieldValueInteger`/`fieldValueDecimal`; a Flag - gets `fieldValueBoolean true`. `vcfc:infoRaw` is retained. -- The model was already fully defined in the vocabulary and simply unused. - -### Added — header section (Phase 5) - -- `--header-representation {structured,basic}`, default `structured`: each `##` - line is typed with its vocabulary subclass, and FILTER, ALT and contig - declarations get `filterId`, `altId`, `contigId`, `contigLength`, - `contigMd5`, `contigAssembly` and `contigCount`. An unrecognized key keeps - only the base `HeaderLine` type rather than inventing an undefined term. - -### Added — SHACL (Phase 6) - -- `--shacl-shapes PATH` validates the graph against a SHACL shapes file with - `pyshacl`, inside the container, as a layer independent of the VCF entirely. - Off by default because `pyshacl` loads the graph into memory. A violation - blocks the run; a missing `pyshacl` is reported as `EXECUTION_FAILED`, never - as a conformance failure. -- It found three violations the other layers could not see. Two are fixed above. - The third is a **contradiction inside the published vocabulary**: - `vcfc:missingValuePolicy` says a missing token SHOULD be `"."^^vcfc:Null`, - while `VCFRecordShape` constrains `vcfc:alt` to `xsd:string`, so a record with - `ALT=.` cannot satisfy both. Recorded in `docs/vcf-coverage.md` for a decision - in the vocabulary repository. - -### Changed - -- `evaluate_validation()` is the single place the PASS/MISMATCH/BLOCKED decision - is made, used by real runs and the mutation harness alike. -- `test_validation_logic_unit.py` now shares the canonical fixture instead of - maintaining a second description of the same data. - -### Verified - -- All 13 core queries plus 4 exact-count preflights return **identical values - under Comunica and QLever**, for both representations, and both engines - produce `PASS` against the Python oracle end to end. The agreement script now - checks that last part too: engines agreeing with each other is not enough when - the digests are compared against values Python computes. -- 297 tests pass; the suite still passes without `rdflib` (those tests skip). - -### Documentation - -- `docs/vcf-coverage.md` rewritten: every VCF element with separate - "represented" and "validated" columns, each validated claim backed by a named - mutation, the remaining gaps, and the vocabulary alignment problem. -- `docs/validation-methodology.md`: the three independent layers, why identity - digests are histograms, and how to reproduce the score. -- README gained a "VCF Coverage" section for the three representation options. - -## 2026-09-04 — Validation mutation harness, and the first coverage gaps closed - -### Added — measurement (Phase 0) - -- A mutation-testing harness for the semantic validation suite. A correct graph - is corrupted in ~25 named ways and the validator is asked for a verdict; the - proportion detected is a reproducible **mutation score**. Before this, the - suite's coverage was prose, and that prose was wrong: `QUAL` is extracted from - every VCF and then never mapped into RDF, and no check could have noticed. - - `test/validation_fixtures.py` derives the VCF, the RDF graph and the parser - oracle from one declarative specification, so they cannot drift apart. The - genotype triples come from the project's own emitters. - - `test/validation_mutations.py` is the catalogue: each entry names the VCF - element it targets, the check expected to catch it, and — for a recorded - gap — why it is not caught. - - `test/test_validation_mutation_unit.py` evaluates queries in-process with - rdflib (test-only dependency, tests skip without it) and routes every - verdict through the shipped `evaluate_validation()`, so the harness measures - real code rather than a reimplementation. - - **Known gaps are assertions.** A mutation marked `known_undetected` is - asserted to still be undetected, so closing a gap fails a test and forces - the catalogue and `docs/vcf-coverage.md` to be updated. -- `test/cross_engine_agreement.py` plus a CI job asserting every validation - query returns identical values under Comunica and QLever. Verified: all 34 - executions across both representations agree. -- `.github/workflows/validation-mutation.yml` publishes `mutation-score.json` - as a build artifact. - -### Added — coverage (Phase 1) - -- **Exact anomaly counts.** Each structural anomaly preflight now has a - companion aggregate returning the true count alongside the `LIMIT 100` - diagnostic sample. Reports carry `anomalyCount`, `anomalyCountReturned` and - `sampleTruncated`, so ten million anomalies is no longer indistinguishable - from a hundred. Verified against a graph with 250 anomalies: exact count 250, - sample 100, truncated true. -- **`--strict-conformance`** (runner and wrapper) promotes a missing-token - conformance failure from a report-only observation to a validation failure. -- **File metadata and header coverage.** New `q07_file_metadata` compares the - `##fileformat` / `##reference` / `##source` declarations, and - `q08_header_line_census` compares how many `##` lines carry each header key. - `parse_vcf` gained `parse_header_metadata` to compute the oracle side. These - close the two entirely uncovered triples maps. - -Mutation score: **23/45 → 29/45 (51% → 64%)**. - -### Changed - -- The PASS / MISMATCH / BLOCKED_BY_PREFLIGHT decision is extracted into - `evaluate_validation()`, the single place real runs and the mutation harness - both use. -- `normalize()` generalises its single-row handling beyond `q03_titv` via - `SINGLE_ROW_QUERIES`. -- `rdflib>=7.0.0` added to the `dev` extra. It is not a runtime dependency and - the test suite passes without it. - -### Documentation - -- **`docs/vcf-coverage.md`** — the coverage matrix: one row per VCF element, - with separate "represented" and "validated" columns, each validated claim - backed by a named mutation. Includes the vocabulary alignment gap (17 emitted - terms the vocabulary does not define, all condensed-representation) and the - open gaps in priority order. This is the table intended for publication. -- **`docs/validation-methodology.md`** — the mutation-testing method, why - self-reported coverage failed, the two-engine two-layer design, and how to - reproduce the score. -- `docs/validation.md` — Q7/Q8 documented, the exact-count behaviour and - `--strict-conformance` described, and the "What is *not* tested" section - narrowed to what is still true. - -## 2026-09-04 — QLever integration verified against a live container - -Everything below came out of actually running the integration, and each item -was wrong or missing beforehand. - -### Fixed - -- **`preflight_position_datatype` would have failed every QLever run.** QLever - canonicalises numeric literals at index time, so `"100"^^xsd:integer` is - reported by `DATATYPE()` as `xsd:int`. The query required exactly - `xsd:integer`, so on QLever it flagged every record and the run ended as - `BLOCKED_BY_PREFLIGHT`, while passing on Comunica. It now accepts the XSD - integer family, which is what the check means; a plain-string or - `xsd:decimal` POS is still reported as an anomaly on both engines (verified). -- **QLever's binaries are not called `IndexBuilderMain`/`ServerMain`, and are - not in `/usr/bin`.** They are `/qlever/qlever-index` and - `/qlever/qlever-server`. The Dockerfile COPY paths and the default argv were - both wrong and would have failed the build. -- **Copying the binaries alone does not work.** The upstream image is Ubuntu - 24.04 and this base is Ubuntu 26.04; the binaries need Boost 1.83, ICU 74, - jemalloc and io_uring sonames that do not exist here and cannot be - apt-installed (the sonames are release-pinned). Those nine libraries are now - copied into `/opt/qlever/lib`, and `LD_LIBRARY_PATH` is set for QLever's own - processes only, so they cannot shadow anything else in the image. glibc is - deliberately not copied - it is backward compatible and this base is newer. -- **`qlever-server` defaults to a 30-second query timeout**, far below what the - aggregate queries need. The server is now started with `-s` matching - `--validation-query-timeout`. -- Index/server flags corrected against the real CLI: `-m` is `--stxxl-memory` - for the indexer and `--memory-max-size` for the server (`--stxxl-memory` is - not a server flag). - -### Verified - -- Both binaries link and run in the target image (`qlever-index --version` - reports build `bfd5741`). -- A real index build, server start, readiness poll, HTTP query, SPARQL Results - JSON parse and `normalize()` round-trip, driven through the shipped - `QleverEngine` code rather than a reimplementation. -- **Engine equivalence**: all eleven validation queries run under both Comunica - and QLever against the same expanded and condensed graphs — graphs built with - the project's own sample emitters — produce identical normalized results, and - the values are independently correct. - -### Tests - -- `QleverEnvironmentTests`: the private library path is prepended for QLever - only, and the POS datatype preflight accepts the integer family while still - rejecting string/decimal/double. -- The QLever lifecycle test now asserts the verified binary names and flags, - including the explicit server-side query timeout. - -### Still unverified - -- The HDT and COTTAS decode paths, and a full `docker build .` of the real - image. Those need hdt-cpp and the pycottas venv; the QLever work above was - done against a minimal probe image that isolates the integration. - -## 2026-09-04 — Validation: QLever engine, HDT/COTTAS artifacts, coverage audit - -### Added - -- `--validation-engine {comunica,qlever}`. Comunica remains the default and - queries the graph in memory; [QLever](https://github.com/ad-freiburg/qlever) - builds an on-disk index inside the container, serves it on a container-local - port, answers the queries over HTTP, and tears both down. Both engines answer - identical queries and feed the same comparison layer, so the choice is a scale - decision, never a semantic one, and every report records which engine ran. - Tunable with `--qlever-memory-gb`, `--qlever-port`, - `--qlever-startup-timeout`, and `--validation-query-timeout`. -- QLever binaries are copied into the image from the upstream - `adfreiburg/qlever` image; pin a version with - `--build-arg QLEVER_IMAGE=adfreiburg/qlever:`. A build-time linkage - check records whether they resolve against this base, and the validator - surfaces that note if the engine cannot start. -- QLever's CLI has changed across releases, so both command lines are - overridable without code changes: repeatable `--qlever-index-arg` / - `--qlever-server-arg`, or full replacement via `QLEVER_INDEX_COMMAND` / - `QLEVER_SERVER_COMMAND` with `{index}`, `{input}`, `{memory}`, `{port}` - placeholders. The exact argv that ran is recorded in `manifest.json`. -- Validation of compressed and indexed artifacts. `--rdf` now accepts `.nt`, - `.nt.gz`, `.nt.br`, `.hdt`, `.cottas`, `.cottas.gz`, and `.cottas.br`; - `--rdf-format` overrides filename detection. Anything that is not already - plain N-Triples is decoded in container scratch (`hdt2rdf`, - `cottas_tool.py decompress`, gzip/brotli) and then put through the full - semantic suite. That is strictly stronger than the triple-count round-trip - `validate_compression.py` performs during compression: it proves the artifact - decodes to a graph that still reproduces every VCF summary. Nothing decoded - is written beneath `--out`. -- `--validate-artifacts {aggregate,hdt,cottas,all}` for full mode. Each - requested artifact is validated independently with its own report directory - (``, `__hdt`, `__cottas`), so one run can prove the aggregate and - both representations agree with the VCF. A representation that was not - selected, or whose artifact is missing after a recoverable index warning, is - skipped rather than reported as a failure. Default is `aggregate`, which - preserves the previous behaviour. -- `materialization.json` per validation run, recording how the artifact was - decoded and how many triples that yielded; `manifest.json` gained `engine` - and a format-tagged `sourceRdf`. Rapper's parsed triple count is now captured - rather than discarded. - -### Changed - -- The validator's cyvcf2 import is lazy, so the pure normalization/comparison - layer is importable and testable on the host without the container. -- `--mode validation` no longer requires `.nt.gz`; any supported artifact works. - `--rdf-nt` / `--rdf-gz` remain accepted as aliases. - -### Tests - -- `test/test_validation_logic_unit.py` (16 tests): mutation tests that drive the - comparison layer directly and record what it detects — dropped records, - misclassified shapes, flipped genotypes, corrupted FILTER lexicals, Ti/Tv - swaps, allele-count errors, spurious records, impossible AC/AN — **and** what - it does not: record permutation, and the entirely unvalidated `ID`, `QUAL`, - `INFO`, non-`GT` `FORMAT`, and header/metadata columns. The blind-spot tests - are deliberate, so closing a gap fails a test instead of passing unnoticed. -- `test/test_validation_engines_unit.py` (25 tests): artifact format detection - and host/container agreement, each decode path, decode-failure reporting, - engine registry, Comunica command construction, QLever index/serve/teardown, - crashed-server diagnostics, command-line overrides, CLI argument validation, - and the wrapper's target resolution and docker argv. - -### Documentation - -- `docs/validation.md`: new "Which artifact is validated", "Which SPARQL engine - runs the queries", and — importantly — "What is *not* tested", which states - the coverage limits plainly: aggregate-only comparison with no per-record - identity, unvalidated VCF columns, no completeness bound, saturating preflight - anomaly counts. -- README: validation artifacts/engines subsection with a short note on what a - `PASS` does and does not mean. - -## 2026-09-04 — Custom-mapping tooling, cheap gzip sizing, dead-script removal - -### Added - -- `vcf-rdfizer-rules`, a second console script (`vcf_rdfizer_rules.py`) for - authoring custom RML mappings. It replaces the `update_rules.sh` sed script - with something that serves the actual need: - - `columns` documents the five generated TSV sources and every column each - one provides, including why `records.tsv`'s final column has no fixed name. - - `init` writes an annotated copy of the default mapping to start from. - - `check` validates a mapping against the wrapper contract *before* a long - run: logical-source paths the wrapper cannot rewrite per input, referenced - columns no TSV provides, which `--sample-representation` values remain - usable, and whether the mapping forces the large sample helper tables to be - materialized. Exits 1 on a contract violation; `--json` for scripting. - The old script rewrote a rules file *in place* to point at fixed TSV paths, - which the pipeline has not needed since `render_rules_for_triplet` began - rendering a per-input copy - and which silently broke the per-input rewrite - it was supposed to help with. -- `vcf_rdfizer_gzip.py`: uncompressed size of a gzip/BGZF file without - decompressing it. Three tiers, and the method used is recorded next to the - size so the metric stays auditable: - - `bgzf` - sums the per-block `ISIZE` trailers of a `bgzip` file by walking - block headers. Exact, no inflate, and immune to the 32-bit wrap. This is - what `bcftools`/`tabix`/`htslib` produce, so it covers the usual case. - - `gzip-sample` / `gzip-trailer` - single-member gzip: measured outright when - it fits the sampling budget, otherwise the 32-bit `ISIZE` trailer resolved - against a compression ratio sampled from the file's own prefix. - - `inflate` - full pass, used whenever the structure cannot settle the - answer. Concatenated non-BGZF members are detected and routed here rather - than trusting a trailer that describes only the final member. - -### Changed - -- `run_conversion.sh` uses that helper for `input_vcf_size_bytes`, which - previously always cost a full `gzip -dc | wc -c` pass over the source VCF. - On the repository's 52 MB test fixture this is 1.115s -> 0.066s (17x); on a - 634 MB gzip whose uncompressed size exceeds 4 GiB, 13.6s -> 0.029s (470x), - where a naive trailer read would have been 93% wrong. The shell keeps its - `gzip -dc` fallback if the helper is unavailable. -- `stages/conversion/*.json` gains `input_vcf_size_method` recording how the - size was obtained. -- `--estimate-size` now uses the real uncompressed input size when the file's - structure can supply it, instead of always assuming a 5x expansion, and says - so when it had to fall back to the assumption. - -### Removed - -- `src/compression.sh` and `test/test_compression_unit.py`. The wrapper issues - its own gzip/brotli/rdf2hdt commands and delegates chunked work to - `partitioned_compression.py`; nothing had called this script for some time, - and it wrote a stale flat `metrics.csv` schema. -- `src/update_rules.sh` and `test/test_update_rules_unit.py`, superseded by - `vcf-rdfizer-rules` above. - -### Documentation - -- README: new "Custom RML Mappings" section with the three-point contract, the - logical-source table, and the `vcf-rdfizer-rules` workflow; a metrics table - explaining each `input_vcf_size_method`; repository-layout and test-suite - entries for the two new modules. -- `rules/README.md` points at the new CLI as the way to author a mapping. - -### Tests - -- `test/test_rules_helper_unit.py` (12 tests), including a drift guard that - runs `src/vcf_as_tsv.sh` and asserts the documented column lists still match - the headers it writes. -- `test/test_gzip_size_unit.py` (13 tests), each checking a measured size - against a full-inflate ground truth across BGZF, plain, concatenated, and - optional-header-field gzip layouts. - -## 2026-09-04 — Code review: cleanup, hot-path performance, and bug fixes - -Behaviour-preserving unless noted. Emitted RDF was verified byte-identical -(SHA-256) against the previous implementation for both sample representations -and for both `run_conversion.sh` storage modes. - -### Fixed - -- `run_compression_methods_for_rdf`: an existing `.hdt` that failed validation - during a full run recorded a **COTTAS** index warning (wrong format, wrong - artifact path, wrong message) via a copy-pasted block whose assignment also - never propagated, because `cottas_failure_warning` was not `nonlocal` there. - The block is removed; `validate_container_artifact` already downgrades a - recoverable HDT index problem to a warning, so reaching that point means the - artifact is genuinely unusable. -- `--mode validation` raised an uncaught `ValueError` traceback when the - results directory already existed and was non-empty, because that check sits - after the argument-validation `try/except`. It now prints `Error: ...` and - exits 2 like every other input error. Covered by a new regression test. -- `count_triples_in_nt_files` (the host-side fallback triple count) used a - slightly different rule than the container-side counters in - `validate_compression.py` / `partitioned_compression.py`, so a fallback count - could disagree with the authoritative one. The predicate is now shared as - `is_triple_line` with identical semantics. - -### Performance - -- Sample RDF emission (`append_expanded_sample_rdf`, - `append_condensed_sample_rdf`) no longer percent-encodes the same values on - every record: sample-column URI components and `sampleId` literals are - computed once per file, and FORMAT-key components are memoized. Previously - these ran `variants x samples` and `variants x samples x FORMAT keys` times. - ~1.6x faster at 50 samples, with the gain growing with cohort width. -- `_rml_uri_component` and `_ntriples_string_literal` short-circuit values that - need no encoding/escaping (~2.7x and ~1.3x on typical VCF tokens). -- `SampleRecordStream` caches the derived FORMAT-key tuple and its - duplicate-key check per distinct `FORMAT` string instead of rebuilding both - for every record. -- `count_triples_in_nt_files` scans bytes instead of decoding to `str`, and - reads gzip aggregates through a `BufferedReader` rather than `GzipFile` - line-by-line. -- `run()` discards subprocess output at the file-descriptor level instead of - buffering a whole container's output in memory only to drop it. -- `run_conversion.sh`: the `"."` -> `"."^^vcfc:Null` rewrite is now applied to - each RMLStreamer part while it is streamed into the aggregate, instead of as - a separate pass over the finished aggregate. This removes one full read and - one full write of the complete RDF output, and removes the transient - full-size temporary copy (which previously required 2x the aggregate size in - free disk at the end of a plain-storage run). -- `run_conversion.sh`: triple counting uses one `LC_ALL=C grep -c` instead of - `awk` / `grep | wc -l`. On a 228 MB gzip aggregate this is ~5x faster - (6.5s -> 1.2s); it is the last unavoidable full pass over the RDF output. -- `run_conversion.sh`: the `stat` dialect is detected once instead of probed on - every call, and the per-second progress heartbeat does one directory walk - with no `basename` subprocess per part. - -### Changed - -- Space-optimized aggregates are ~14 bytes per RMLStreamer part smaller, - because gzip members are now produced from a pipe and therefore no longer - embed the temporary part filename and mtime. Decompressed content is - unchanged and the output is more reproducible. - -### Removed - -- Dead host-side code: `resolve_input` (superseded by - `resolve_input_snapshot`), and the host chunk planners - `plan_record_safe_rdf_chunks`, `plan_partitioned_hdt_chunks`, - `split_nt_file_for_hdt`, `write_nt_chunk`, `iter_rdf_binary_lines`. Chunking - has been the container runner's job (`src/partitioned_compression.py`) since - partitioned compression moved into an ephemeral Docker volume; keeping a - second host-side implementation was exactly what - `run_partitioned_representation_methods_for_rdf_files` documents against. - Their two tests were removed with them. -- An unreachable `else:` arm in `run_full_mode`'s output summary (it iterated a - list the guard had just proved empty), the unused `input_metrics_target` - parameter of `run_full_mode`, an always-true `is not None` guard, and two - unused local assignments. - -### Documentation - -- `vcf_rdfizer.py` gained a module-level division-of-labour note and section - map, plus section banners for the previously unmarked regions (triple - counting, artifact naming, destructive filesystem operations, preflight - estimation, genotype representations, compression-plan parsing, metrics - layout). -- `README.md`: new "Repository Layout" section explaining the host/container - split and what each file does; fixed the broken `RELEASING.md` link - (`scripts/RELEASING.md`); added links to `docs/`, `changelog.md`, and - `ACKNOWLEDGEMENTS.md`. -- `src/compression.sh` and `src/update_rules.sh` headers now state that they - are standalone utilities the pipeline does not call, and what supersedes - each. `compression.sh` previously claimed the Python wrapper was its primary - caller, which has not been true since compression moved inline. -- Added `ACKNOWLEDGEMENTS.md` with funding/attribution and a paper - acknowledgement template. - -## 2026-09-04 — Validation progress and quiet mode - -- Integrated semantic validation with the existing JSONL progress sidecar and - host `ProgressSession`; validation now reports its preflight/core query - progress using the same terminal UI as conversion and compression. -- Added `--quiet` to suppress terminal progress displays and validation query - chatter while retaining progress bookkeeping, command logs, and metrics. -- Kept `--no-progress` as the stronger opt-out that disables sidecar creation - and progress rendering entirely. - -## 2026-09-04 — Full-run semantic validation - -- Added `--validate`/`--run-validation` to run the semantic VCF/RDF validator - once per input as the final stage of a `--mode full` run. -- Full-mode validation accepts the generated plain `.nt` or gzip `.nt.gz` - aggregate, and retains the validator's container-local temporary-file - guarantees. -- Validation timing, status, exit code, input RDF, and report paths are now - included in the run's `metrics.csv`, compression JSON, stage reports, and - recursive `summary.json` report index. - -## 2026-09-04 — Expanded sample representation naming - -- Renamed the default per-sample genotype graph strategy to `expanded`, while - retaining `condensed` as the alternative strategy. -- Updated the CLI default and accepted values, internal workflow/emitter names, - tests, RML comments, and user documentation. -- The emitted profile IRI is now - `vcfc:representationProfile vcfc:ExpandedRepresentation`. - -## 2026-09-04 — Input-labelled, container-complete metrics layout - -- Replaced timestamp-only run-metrics directories with - `run_metrics/__/`. A single VCF/RDF/representation input - uses its source stem (for example, `1000G_phase3_chr20`); a directory input - with multiple VCFs receives a deterministic batch label. -- Added `run.json` and `summary.json` as the stable entry points for every - mode. The manifest records inputs, requested configuration, output root, and - resolved image; the summary records final status, wrapper runtime, tabular - rows, and an index of stage reports and logs. -- Organized metrics by purpose: `logs/`, `timings/`, `stages/`, and `reports/`. - TSV, RML conversion, compression, decompression, indexing, and warnings now - have predictable locations instead of unrelated `raw_metrics`, - `*_metrics`, and timestamp-nested directories. -- Compression-only, decompression, and standalone index modes now persist - container wall/CPU/system time, peak RSS, exit code, input/output sizes, and - structured stage reports. Full and TSV modes retain the same detail. -- Preserved the complete partitioned-compression runner handoff under - `stages/partitioned/`, including every chunk build, merge, validation, - temporary-workspace free-space sample, timing, peak RSS, and bounded stderr - diagnostic. The report is retained on both successful and failed runs before - the temporary Docker volume is removed. - -## 2026-09-03 — Streaming COTTAS merge for condensed cohorts - -- Replaced the final COTTAS merge/reindex implementation with a PyArrow k-way - merge of the already `spo`-sorted Parquet chunks. It keeps one configurable - batch per input (`COTTAS_MERGE_BATCH_ROWS`, default `2048`), deduplicates - adjacent equal triples, and writes the final COTTAS artifact incrementally. - It preserves RDF set semantics and the embedded COTTAS index without a - graph-wide DuckDB hash table or external-sort spill area. -- This supersedes the prior DuckDB merge variants. A 52-chunk, 36-million-triple - cohort exhausted 41.4 GiB of Docker workspace while DuckDB attempted an - external sort; the streaming merge has no proportional temporary-sort file. -- Added PyArrow 22.0.0 to the image and third-party notices for deterministic - Parquet reader/writer support. -- COTTAS merge progress now reports source triples processed and distinct - triples written. Rich interactive displays remain available, and redirected - terminals receive compact line-based progress updates. -- Retained the bounded stderr tail in failures so malformed COTTAS input, - incompatible index metadata, output disk errors, and other code-1 failures - remain actionable after the ephemeral workspace is removed. - -### Rerun guidance - -Build an image from this revision before retrying. The preserved raw `.nt.gz` -can be retried with `--mode compress`, avoiding another RDF run. The merge -requires normal space for the COTTAS chunks and final artifact, but no longer -requires a large DuckDB spill directory. - -## 2026-09-03 — COTTAS SIGKILL/OOM handling - -- Classified `exit_code=-9` in partitioned index warnings as a child process - killed by `SIGKILL` (normally the Linux kernel/Docker OOM killer). Shell - wrappers can surface the same condition as exit code `137`. -- Initially changed the production COTTAS merge to a bounded pairwise tree. - This reduced input fan-in but did not bound the final graph-wide - `DISTINCT`/`ORDER BY`; the disk-backed replacement above supersedes it. -- Added the failing stage's `max_rss_kb` to `index_warnings.json`, alongside - exit code, stderr tail, and workspace free-space samples, so OOM diagnosis - can be compared directly with the container memory limit. -- The `merge-many` adapter remains available for explicit experiments, but is - no longer selected by the default large-file workflow. - -### Rerun guidance - -Rebuild the image and rerun the full conversion (or use `--mode compress` with -the retained raw `.nt.gz`). The current streaming k-way merge supersedes this -earlier pairwise guidance. - -When COTTAS is optional, `--representations hdt` avoids the COTTAS merge -resource requirement while retaining a queryable representation. - -## 2026-09-02 — COTTAS large-input merge reliability - -- Diagnosed the previous generic `COTTAS merge/index creation failed` warning: - the warning is emitted only after per-chunk COTTAS conversion succeeds and - the final indexed merge returns a non-zero status. HDT generation/indexing - is independent and is not implicated by that warning. -- Added a multi-input `pycottas.cat` adapter for explicit use. The production - workflow now uses the bounded pairwise strategy documented in the 2026-09-03 - entry because the merge API can require substantial in-memory buffers. -- Added cleanup of all COTTAS chunks and merge outputs after a failed COTTAS - attempt so stale intermediates cannot consume the Docker workspace. -- Preserved a bounded stderr tail and exit code for every partitioned stage. - Full-run `index_warnings.json` entries now identify resource/OOM signals, - include before/after Docker-workspace free-space samples, and retain the - underlying COTTAS/DuckDB diagnostic when available. -- Pinned the Docker image to `pycottas==1.1.0` for reproducible behavior. -- Added regression tests for the multi-input merge command, stage diagnostics, - and isolated COTTAS scratch cleanup. - -### Rerun guidance - -Rebuild the image and rerun the same full command. If the COTTAS stage still -fails, inspect `stages/partitioned/.json` and the wrapper log for the -failing `cottas-merge-r*` stage and its -`stderr_tail`. For a resource error, lower `--chunk-target-bytes` and -`--chunk-max-bytes`, or enlarge the Docker data-volume allocation. The raw -`.nt.gz` retained by the failed run is a valid recovery source. diff --git a/docs/README.md b/docs/README.md index 070c10d..8d6e44d 100644 --- a/docs/README.md +++ b/docs/README.md @@ -134,5 +134,6 @@ Three conventions, kept deliberately: Related files outside `docs/`: [`rules/README.md`](../rules/README.md) (the mapping directory), [`test/README.md`](../test/README.md) (the test suite), -[`changelog.md`](../changelog.md), [`scripts/RELEASING.md`](../scripts/RELEASING.md), -and [`ACKNOWLEDGEMENTS.md`](../ACKNOWLEDGEMENTS.md). +[`scripts/RELEASING.md`](../scripts/RELEASING.md), and +[`ACKNOWLEDGEMENTS.md`](../ACKNOWLEDGEMENTS.md). Per-version release notes are +published on the [releases page](https://github.com/ecrum19/VCF-RDFizer/releases). diff --git a/docs/roadmap.md b/docs/roadmap.md index 69115dc..6b73f65 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -181,4 +181,4 @@ Stated so the absence reads as a decision rather than an oversight. - [Data linking design](datalinking-design.md) — the largest planned addition - [Privacy policy design](privacy-policy-design.md) — governed release over parts of the graph - [Validation methodology](validation-methodology.md) — how coverage is measured, so gaps stay falsifiable -- [`changelog.md`](../changelog.md) — what has actually shipped +- [Releases](https://github.com/ecrum19/VCF-RDFizer/releases) — what has actually shipped diff --git a/src/validate_compression.py b/src/validate_compression.py index dd46b6d..ca833e9 100644 --- a/src/validate_compression.py +++ b/src/validate_compression.py @@ -32,14 +32,16 @@ def count_nt(path: Path) -> int: def count_decoded(command: list[str]) -> int: """Run an RDF exporter and count its streamed N-Triples output.""" - process = subprocess.Popen( + # The context manager closes the stdout pipe even when counting raises, so a + # failed decode cannot leak a file descriptor into the rest of the run. + with subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, - ) - assert process.stdout is not None - count = sum(1 for line in process.stdout if is_triple_line(line)) - return_code = process.wait() + ) as process: + assert process.stdout is not None + count = sum(1 for line in process.stdout if is_triple_line(line)) + return_code = process.wait() if return_code != 0: raise RuntimeError(f"decoder exited with status {return_code}: {' '.join(command)}") return count diff --git a/test/test_partitioned_compression_helpers_unit.py b/test/test_partitioned_compression_helpers_unit.py new file mode 100644 index 0000000..7ed6a04 --- /dev/null +++ b/test/test_partitioned_compression_helpers_unit.py @@ -0,0 +1,434 @@ +"""The partitioned compressor's planning, accounting, and reporting helpers. + +``src/partitioned_compression.py`` splits an aggregate into record-safe chunks, +converts each one, and merges the results pairwise. The existing +``test_partitioned_compression_unit`` covers the merge command lines and the +streaming contract; this file covers the surrounding layer - chunk planning, +progress events, resource accounting, and the failure text the operator +actually sees. + +That reporting layer matters more than its size suggests: once the container +exits, its ephemeral volume is gone, so anything ``failure_message`` drops is +lost for good. Every test here runs on the host with no hdtc, pycottas, or +Docker. +""" + +from __future__ import annotations + +import gzip +import importlib.util +import json +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from test.helpers import VerboseTestCase + +MODULE_PATH = Path(__file__).resolve().parents[1] / "src" / "partitioned_compression.py" + + +def load_module(): + spec = importlib.util.spec_from_file_location("partitioned_compression_helpers", MODULE_PATH) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +P = load_module() + + +def empty_totals() -> dict: + return { + "exit_code": 0, "wall_seconds": 0.0, "user_seconds": 0.0, "sys_seconds": 0.0, + "max_rss_kb": 0, "has_user": False, "has_sys": False, "has_rss": False, + } + + +class ProgressDescriptorTests(VerboseTestCase): + def test_a_chunk_stage_carries_its_chunk_number(self): + """Per-chunk stages drive a counted progress bar, so the index is parsed.""" + self.assertEqual(P.progress_descriptor("hdt-build-7"), ("hdt-chunks", "chunks", 7)) + self.assertEqual(P.progress_descriptor("cottas-build-12"), ("cottas-chunks", "chunks", 12)) + + def test_a_malformed_chunk_number_degrades_to_the_plain_stage(self): + """An unparsable suffix must not crash the run for a progress label.""" + self.assertEqual(P.progress_descriptor("hdt-build-x"), ("hdt", "stage", None)) + + def test_merge_stages_are_reported_separately_from_builds(self): + """Merging is the long tail of a partitioned run and gets its own task.""" + self.assertEqual(P.progress_descriptor("hdt-merge-3"), ("hdt-merge", "stage", None)) + self.assertEqual(P.progress_descriptor("cottas-merge-many"), ("cottas-merge", "stage", None)) + + def test_remaining_stages_fall_back_to_their_representation(self): + """Indexing and other stages still group under the right representation.""" + self.assertEqual(P.progress_descriptor("hdt-index"), ("hdt", "stage", None)) + self.assertEqual(P.progress_descriptor("cottas-index"), ("cottas", "stage", None)) + + def test_an_unrecognised_stage_keeps_its_own_name(self): + """A new stage name is reported verbatim rather than mislabelled.""" + self.assertEqual(P.progress_descriptor("verify"), ("verify", "stage", None)) + + +class ProgressSidecarTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def test_the_sidecar_directory_is_created_on_demand(self): + """The host mount may not exist yet when the container starts writing.""" + path = self.root / "nested" / "progress.jsonl" + P.prepare_progress_path(path) + self.assertTrue(path.parent.is_dir()) + + def test_preparing_no_sidecar_is_a_no_op(self): + """Progress is optional, so None must be accepted everywhere.""" + self.assertIsNone(P.prepare_progress_path(None)) + + def test_an_unwritable_sidecar_location_is_swallowed(self): + """Progress must never break a conversion that is otherwise fine.""" + with mock.patch.object(P.Path, "mkdir", side_effect=OSError("read-only")): + P.prepare_progress_path(self.root / "nested" / "progress.jsonl") + + def test_each_event_is_one_json_object_per_line(self): + """The host tails this file, so every line must parse on its own.""" + path = self.root / "progress.jsonl" + P.emit_progress(path, "hdt", "chunks", completed=1, total=5, unit="chunk") + P.emit_progress(path, "hdt", "stage") + events = [json.loads(line) for line in path.read_text(encoding="utf-8").splitlines()] + self.assertEqual(events[0], { + "stage": "hdt", "phase": "chunks", "completed": 1, "total": 5, "unit": "chunk", + }) + self.assertEqual(events[1], {"stage": "hdt", "phase": "stage"}) + + def test_absent_fields_are_omitted_rather_than_written_as_null(self): + """A null total would render as a progress bar of unknown length.""" + path = self.root / "progress.jsonl" + P.emit_progress(path, "cottas", "stage", detail="merging") + event = json.loads(path.read_text(encoding="utf-8").strip()) + self.assertEqual(set(event), {"stage", "phase", "detail"}) + + def test_emitting_without_a_sidecar_is_a_no_op(self): + """The common case is no progress path at all.""" + self.assertIsNone(P.emit_progress(None, "hdt", "stage")) + + def test_a_failing_write_never_propagates(self): + """A full or read-only mount must not abort the conversion.""" + with mock.patch.object(P.Path, "open", side_effect=OSError("no space")): + P.emit_progress(self.root / "progress.jsonl", "hdt", "stage") + + +class ChunkPlanningTests(VerboseTestCase): + RECORD = b" .\n" + + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.source = self.root / "graph.nt" + self.source.write_bytes(b"".join(self.RECORD % index for index in range(40))) + + def test_chunk_sizes_must_be_positive(self): + """A zero or negative bound would produce an unbounded chunk loop.""" + with self.assertRaises(ValueError) as raised: + P.stream_chunks(self.source, self.root / "c", target_bytes=0, min_bytes=1, max_bytes=2) + self.assertIn("must be positive", str(raised.exception)) + + def test_chunk_sizes_must_be_ordered(self): + """min <= target <= max is what makes a record-safe chunk reachable.""" + for target, minimum, maximum in ((10, 20, 30), (10, 5, 8)): + with self.subTest(target=target, minimum=minimum, maximum=maximum): + with self.assertRaises(ValueError) as raised: + P.stream_chunks( + self.source, self.root / "c", + target_bytes=target, min_bytes=minimum, max_bytes=maximum, + ) + self.assertIn("min <= target <= max", str(raised.exception)) + + def test_every_record_survives_the_split(self): + """Chunking is a partition: no record may be lost, split, or duplicated.""" + paths, plan = P.plan_chunks( + self.source, self.root / "chunks", + target_bytes=200, min_bytes=100, max_bytes=400, + ) + self.assertGreater(len(paths), 1) + self.assertEqual(plan["record_count"], 40) + rejoined = b"".join(path.read_bytes() for path in paths) + self.assertEqual(rejoined, self.source.read_bytes()) + + def test_the_plan_counts_what_it_wrote(self): + """The plan is the run's record of the split and must agree with the files.""" + paths, plan = P.plan_chunks( + self.source, self.root / "chunks", + target_bytes=200, min_bytes=100, max_bytes=400, + ) + self.assertEqual(plan["chunk_count"], len(paths)) + self.assertEqual(len(plan["chunks"]), len(paths)) + self.assertEqual(plan["chunk_input_bytes"], self.source.stat().st_size) + + def test_chunk_metadata_spans_the_source_without_gaps(self): + """Record and byte ranges must be contiguous across consecutive chunks.""" + _paths, plan = P.plan_chunks( + self.source, self.root / "chunks", + target_bytes=200, min_bytes=100, max_bytes=400, + ) + for previous, current in zip(plan["chunks"], plan["chunks"][1:]): + self.assertEqual(previous["end_record"], current["start_record"]) + self.assertEqual( + previous["end_uncompressed_byte"], current["start_uncompressed_byte"] + ) + self.assertEqual(plan["chunks"][0]["start_record"], 0) + self.assertEqual(plan["chunks"][-1]["end_record"], plan["record_count"]) + + def test_a_source_smaller_than_the_target_yields_one_chunk(self): + """Below the minimum, partitioning converges on the single-file case.""" + paths, plan = P.plan_chunks( + self.source, self.root / "chunks-single", + target_bytes=10_000_000, min_bytes=1_000_000, max_bytes=100_000_000, + ) + self.assertEqual(len(paths), 1) + self.assertEqual(plan["record_count"], 40) + + def test_a_gzip_source_partitions_identically_to_a_plain_one(self): + """Aggregate compression is a storage choice, not a chunking one.""" + gzipped = self.root / "graph.nt.gz" + gzipped.write_bytes(gzip.compress(self.source.read_bytes())) + plain_paths, plain_plan = P.plan_chunks( + self.source, self.root / "plain", target_bytes=200, min_bytes=100, max_bytes=400) + gz_paths, gz_plan = P.plan_chunks( + gzipped, self.root / "gz", target_bytes=200, min_bytes=100, max_bytes=400) + self.assertEqual(len(gz_paths), len(plain_paths)) + self.assertEqual(gz_plan["record_count"], plain_plan["record_count"]) + self.assertEqual( + [chunk["record_count"] for chunk in gz_plan["chunks"]], + [chunk["record_count"] for chunk in plain_plan["chunks"]], + ) + + def test_comments_and_blank_lines_are_not_counted_as_records(self): + """The record count feeds the round-trip check and must match the graph.""" + noisy = self.root / "noisy.nt" + noisy.write_bytes(b"# generated\n\n .\n\n# trailing\n") + _paths, plan = P.plan_chunks( + noisy, self.root / "noisy-chunks", + target_bytes=1000, min_bytes=100, max_bytes=10_000, + ) + self.assertEqual(plan["record_count"], 1) + + +class BinaryAndSidecarResolutionTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def test_an_executable_on_the_path_is_resolved_to_its_absolute_location(self): + """Stage commands are logged, so the resolved path must be concrete.""" + resolved = P.resolve_executable(("sh",), "shell") + self.assertTrue(Path(resolved).is_absolute()) + self.assertTrue(Path(resolved).is_file()) + + def test_the_first_available_candidate_wins(self): + """Candidate order encodes preference between builds of the same tool.""" + self.assertEqual( + P.resolve_executable(("definitely-absent-xyz", "sh"), "shell"), + P.resolve_executable(("sh",), "shell"), + ) + + def test_a_missing_tool_names_what_is_missing(self): + """A container build problem must be distinguishable from a data problem.""" + with self.assertRaises(RuntimeError) as raised: + P.resolve_executable(("definitely-absent-xyz",), "hdtc") + self.assertIn("Missing hdtc in container", str(raised.exception)) + + def test_no_index_sidecar_reports_none(self): + """An unindexed HDT is a state to handle, not an error to raise.""" + artifact = self.root / "graph.hdt" + artifact.write_bytes(b"hdt") + self.assertIsNone(P.find_hdt_index_sidecar(artifact)) + + def test_an_empty_index_sidecar_is_not_accepted(self): + """A zero-byte index is a failed index run, not a usable one.""" + artifact = self.root / "graph.hdt" + artifact.write_bytes(b"hdt") + (self.root / "graph.hdt.index.v1-1").write_bytes(b"") + self.assertIsNone(P.find_hdt_index_sidecar(artifact)) + + def test_a_populated_index_sidecar_is_found(self): + """The canonical versioned sidecar is what makes the HDT queryable.""" + artifact = self.root / "graph.hdt" + artifact.write_bytes(b"hdt") + (self.root / "graph.hdt.index.v1-1").write_bytes(b"") + (self.root / "graph.hdt.index.v1-2").write_bytes(b"index") + found = P.find_hdt_index_sidecar(artifact) + self.assertIsNotNone(found) + self.assertEqual(found.name, "graph.hdt.index.v1-2") + + def test_each_merge_gets_an_isolated_workspace(self): + """Concurrent merges must not share a spill directory.""" + left = P.hdtc_merge_temp_dir(self.root, self.root / "merge-a.hdt") + right = P.hdtc_merge_temp_dir(self.root, self.root / "merge-b.hdt") + self.assertNotEqual(left, right) + self.assertEqual(left.parent, self.root) + + +class TimeLogTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def test_a_missing_log_reports_unknown_rather_than_zero(self): + """Zero CPU seconds is a measurement; a missing log is not.""" + self.assertEqual( + P.parse_time_log(self.root / "absent.txt"), + {"user_seconds": None, "sys_seconds": None, "max_rss_kb": None}, + ) + + def test_a_complete_log_yields_every_measurement(self): + """The three fields feed the run's metrics row.""" + log = self.root / "time.txt" + log.write_text( + "\tUser time (seconds): 1.25\n" + "\tSystem time (seconds): 0.50\n" + "\tMaximum resident set size (kbytes): 20480\n", + encoding="utf-8", + ) + self.assertEqual( + P.parse_time_log(log), + {"user_seconds": 1.25, "sys_seconds": 0.5, "max_rss_kb": 20480}, + ) + + def test_an_unrecognised_log_yields_no_measurements(self): + """A truncated or foreign log must not be parsed into plausible numbers.""" + log = self.root / "time.txt" + log.write_text("nothing useful here\n", encoding="utf-8") + self.assertEqual( + P.parse_time_log(log), + {"user_seconds": None, "sys_seconds": None, "max_rss_kb": None}, + ) + + def test_a_partial_log_keeps_what_it_can(self): + """One missing field must not discard the others.""" + log = self.root / "time.txt" + log.write_text("\tUser time (seconds): 2\n", encoding="utf-8") + parsed = P.parse_time_log(log) + self.assertEqual(parsed["user_seconds"], 2.0) + self.assertIsNone(parsed["max_rss_kb"]) + + def test_the_resident_set_size_is_an_integer(self): + """The metrics column is integral kilobytes, not a float.""" + log = self.root / "time.txt" + log.write_text("\tMaximum resident set size (kbytes): 1024\n", encoding="utf-8") + self.assertIsInstance(P.parse_time_log(log)["max_rss_kb"], int) + + +class TotalsTests(VerboseTestCase): + def test_no_stages_report_unknown_rather_than_zero(self): + """A run with nothing measured must not claim zero CPU seconds.""" + self.assertEqual(P.finalize_totals(empty_totals()), { + "exit_code": 0, "wall_seconds": 0.0, + "user_seconds": None, "sys_seconds": None, "max_rss_kb": None, + }) + + def test_wall_and_cpu_time_accumulate_across_stages(self): + """Stage times sum; the run's cost is the whole pipeline's.""" + totals = empty_totals() + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 1.5, "user_seconds": 0.5}) + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 2.0, "user_seconds": 0.25}) + finalized = P.finalize_totals(totals) + self.assertEqual(finalized["wall_seconds"], 3.5) + self.assertEqual(finalized["user_seconds"], 0.75) + + def test_peak_memory_is_a_maximum_not_a_sum(self): + """Stages run sequentially, so the peak is the largest, not the total.""" + totals = empty_totals() + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 0, "max_rss_kb": 100}) + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 0, "max_rss_kb": 50}) + self.assertEqual(P.finalize_totals(totals)["max_rss_kb"], 100) + + def test_the_worst_exit_code_survives(self): + """One failed stage must fail the run even when later stages succeed.""" + totals = empty_totals() + P.add_totals(totals, {"exit_code": 2, "wall_seconds": 0}) + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 0}) + self.assertEqual(P.finalize_totals(totals)["exit_code"], 2) + + def test_a_stage_missing_a_measurement_does_not_zero_the_total(self): + """An unmeasured stage leaves the others' measurements intact.""" + totals = empty_totals() + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 1.0, "user_seconds": 0.5}) + P.add_totals(totals, {"exit_code": 0, "wall_seconds": 1.0}) + finalized = P.finalize_totals(totals) + self.assertEqual(finalized["user_seconds"], 0.5) + self.assertIsNone(finalized["sys_seconds"]) + + def test_absent_numbers_are_treated_as_zero_contributions(self): + """A stage result with null timings must not raise.""" + totals = empty_totals() + P.add_totals(totals, {"exit_code": None, "wall_seconds": None}) + self.assertEqual(P.finalize_totals(totals)["wall_seconds"], 0.0) + + +class FailureMessageTests(VerboseTestCase): + def test_no_stage_result_leaves_the_fallback_untouched(self): + """A failure with no captured result still reports something useful.""" + self.assertEqual(P.failure_message(None, "hdt merge failed"), "hdt merge failed") + self.assertEqual(P.failure_message({}, "hdt merge failed"), "hdt merge failed") + + def test_the_exit_code_is_always_reported(self): + """The numeric code is the one thing every failed stage has.""" + self.assertIn("exit_code=1", P.failure_message({"exit_code": 1}, "failed")) + + def test_an_oom_kill_is_named_rather_than_left_as_a_number(self): + """-9 and 137 both mean the kernel or Docker killed the process.""" + self.assertIn("SIGKILL", P.failure_message({"exit_code": -9}, "failed")) + self.assertIn("OOM", P.failure_message({"exit_code": 137}, "failed")) + + def test_a_termination_is_distinguished_from_a_kill(self): + """SIGTERM is an orderly stop and should not be reported as OOM.""" + message = P.failure_message({"exit_code": 143}, "failed") + self.assertIn("SIGTERM", message) + self.assertNotIn("OOM", message) + + def test_the_stderr_tail_is_preserved_and_whitespace_normalised(self): + """The container's volume is gone by the time this is read.""" + message = P.failure_message( + {"exit_code": 1, "stderr_tail": " DuckDB error:\n no space left "}, "failed") + self.assertIn("stderr=DuckDB error: no space left", message) + + def test_the_stderr_tail_is_bounded(self): + """Top-level CLI output must stay readable however large the traceback.""" + message = P.failure_message( + {"exit_code": 1, "stderr_tail": "x" * 5000}, "failed") + self.assertLess(len(message), 2500) + self.assertIn("x" * 100, message) + + def test_a_non_numeric_exit_code_is_reported_without_interpretation(self): + """An unexpected payload must not raise while building an error message.""" + message = P.failure_message({"exit_code": "weird"}, "failed") + self.assertIn("exit_code=weird", message) + self.assertNotIn("SIGKILL", message) + + def test_an_empty_stderr_tail_adds_no_stderr_clause(self): + """An empty tail should not render as 'stderr='.""" + self.assertNotIn("stderr=", P.failure_message( + {"exit_code": 1, "stderr_tail": " "}, "failed")) + + +class TripleLineTests(VerboseTestCase): + def test_statements_are_recognised_regardless_of_whitespace(self): + """Record counting must not depend on the writer's formatting.""" + self.assertTrue(P.is_triple_line(b" .")) + self.assertTrue(P.is_triple_line(b" . \n")) + + def test_comments_blanks_and_fragments_are_not_statements(self): + """Only terminated, non-comment lines count toward the record total.""" + for line in (b"", b" \n", b"# comment .", b" "): + with self.subTest(line=line): + self.assertFalse(P.is_triple_line(line)) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_validate_compression_unit.py b/test/test_validate_compression_unit.py new file mode 100644 index 0000000..8f14fac --- /dev/null +++ b/test/test_validate_compression_unit.py @@ -0,0 +1,314 @@ +"""The compression validator's triple-count round trip. + +``src/validate_compression.py`` is the cheap check that runs during conversion: +it counts N-Triples statements in the source and compares them against what the +generated HDT or COTTAS artifact decodes back to. It is weaker than the semantic +suite in ``src/validation/`` - a graph can survive this check and still be wrong - +so what matters here is that it never reports success it did not establish. + +These tests run on the host: the decoder binaries and ``pycottas`` exist only +inside the image, so every test either stubs them or asserts the behaviour when +they are absent. +""" + +from __future__ import annotations + +import argparse +import gzip +import importlib.util +import json +import sys +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from test.helpers import VerboseTestCase + +MODULE_PATH = Path(__file__).resolve().parents[1] / "src" / "validate_compression.py" + + +def load_module(): + spec = importlib.util.spec_from_file_location("validate_compression_unit", MODULE_PATH) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +M = load_module() + + +def emitter(*lines: str) -> list[str]: + """A command that prints *lines*, standing in for a decoder binary.""" + payload = "".join(f"{line}\n" for line in lines) + return [sys.executable, "-c", "import sys; sys.stdout.write(sys.argv[1])", payload] + + +class TripleLineTests(VerboseTestCase): + def test_a_statement_terminated_by_a_period_counts(self): + """The terminating '.' is what distinguishes a statement from a fragment.""" + self.assertTrue(M.is_triple_line(b" .")) + + def test_surrounding_whitespace_does_not_change_the_verdict(self): + """Decoders differ in indentation; the count must not.""" + self.assertTrue(M.is_triple_line(b" . \n")) + + def test_blank_and_comment_lines_are_not_statements(self): + """N-Triples comments and blank lines carry no triple.""" + for line in (b"", b" ", b"\n", b"# a comment .", b" # indented ."): + with self.subTest(line=line): + self.assertFalse(M.is_triple_line(line)) + + def test_an_unterminated_line_is_not_a_statement(self): + """A line without the terminator is a truncated write, not a triple.""" + self.assertFalse(M.is_triple_line(b" ")) + + +class SourceCountTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def test_plain_ntriples_are_counted(self): + """Only statement lines contribute to the source count.""" + path = self.root / "graph.nt" + path.write_bytes(b"# header\n .\n\n .\n") + self.assertEqual(M.count_nt(path), 2) + + def test_a_gzipped_source_counts_the_same_as_a_plain_one(self): + """.nt.gz is read transparently, so compression is not a semantic choice.""" + plain = self.root / "graph.nt" + plain.write_bytes(b" .\n .\n") + gzipped = self.root / "graph.nt.gz" + gzipped.write_bytes(gzip.compress(plain.read_bytes())) + self.assertEqual(M.count_nt(gzipped), M.count_nt(plain)) + + def test_an_empty_graph_counts_zero(self): + """An empty source is a count, not an error, at this layer.""" + path = self.root / "empty.nt" + path.write_bytes(b"") + self.assertEqual(M.count_nt(path), 0) + + +class DecodedCountTests(VerboseTestCase): + def test_streamed_statements_are_counted(self): + """The decoder's stdout is counted without materializing a file.""" + self.assertEqual(M.count_decoded(emitter(" .")), 1) + + def test_decoder_noise_is_excluded_from_the_count(self): + """Comments and blank lines in the decode must not inflate the count.""" + command = emitter("# generated", "", " .") + self.assertEqual(M.count_decoded(command), 1) + + def test_a_failing_decoder_raises_rather_than_returning_a_count(self): + """A non-zero exit means the count is unusable, not merely low.""" + command = [sys.executable, "-c", "import sys; print(' .'); sys.exit(3)"] + with self.assertRaises(RuntimeError) as raised: + M.count_decoded(command) + self.assertIn("status 3", str(raised.exception)) + + +class BinaryResolutionTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def make_executable(self, name: str) -> Path: + path = self.root / name + path.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8") + path.chmod(0o755) + return path + + def test_the_environment_override_wins(self): + """HDT2RDF_BIN lets the image pin a build without editing the script.""" + binary = self.make_executable("hdt2rdf") + with mock.patch.dict(M.os.environ, {"HDT2RDF_BIN": str(binary)}, clear=False): + self.assertEqual(M.resolve_hdt2rdf(), str(binary)) + + def test_a_non_executable_override_is_not_accepted(self): + """A path that cannot be run is skipped rather than reported as found.""" + path = self.root / "not-executable" + path.write_text("", encoding="utf-8") + path.chmod(0o644) + with mock.patch.dict(M.os.environ, {"HDT2RDF_BIN": str(path)}, clear=False): + with self.assertRaises(RuntimeError): + M.resolve_hdt2rdf() + + def test_an_absent_binary_is_refused_with_a_clear_message(self): + """Missing hdt2rdf is a container build problem, and says so.""" + with mock.patch.dict(M.os.environ, {"HDT2RDF_BIN": str(self.root / "absent")}, clear=False): + with mock.patch.object(M.Path, "is_file", return_value=False): + with self.assertRaises(RuntimeError) as raised: + M.resolve_hdt2rdf() + self.assertIn("Missing hdt2rdf binary", str(raised.exception)) + + +class ValidateTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.source = self.root / "graph.nt" + self.source.write_bytes(b" .\n .\n") + self.artifact = self.root / "graph.hdt" + self.artifact.write_bytes(b"not-really-hdt") + + def args(self, **overrides): + values = { + "source": str(self.source), "artifact": str(self.artifact), "format": "hdt", + "expected_triples": None, "source_triples": None, "skip_index_check": True, + } + values.update(overrides) + return argparse.Namespace(**values) + + def decoding_to(self, count: int): + """Stand in for hdt2rdf, which exists only inside the image.""" + return mock.patch.multiple( + M, resolve_hdt2rdf=mock.Mock(return_value="/usr/local/bin/hdt2rdf"), + count_decoded=mock.Mock(return_value=count), + ) + + def test_a_matching_round_trip_is_valid(self): + """Equal source and decoded counts is the success case.""" + with self.decoding_to(2): + result = M.validate(self.args()) + self.assertTrue(result["valid"]) + self.assertTrue(result["count_match"]) + self.assertEqual(result["validator"], "hdt2rdf") + self.assertNotIn("error", result) + + def test_a_count_mismatch_reports_both_numbers(self): + """A failure must name what was compared, not only that it failed.""" + with self.decoding_to(1): + result = M.validate(self.args()) + self.assertFalse(result["count_match"]) + self.assertIn("source=2", result["error"]) + self.assertIn("decoded=1", result["error"]) + + def test_a_precounted_source_is_trusted_instead_of_rereading(self): + """The conversion already streamed the source, so it is not read twice.""" + with self.decoding_to(7): + result = M.validate(self.args(source_triples=7)) + self.assertEqual(result["source_triples"], 7) + self.assertTrue(result["count_match"]) + + def test_a_source_disagreeing_with_the_conversion_stops_before_decoding(self): + """If the source already lost triples, decoding it proves nothing.""" + decoder = mock.Mock() + with mock.patch.object(M, "count_decoded", decoder): + result = M.validate(self.args(expected_triples=99)) + self.assertFalse(result["valid"]) + self.assertIsNone(result["decoded_triples"]) + self.assertIn("does not match the upstream conversion count", result["error"]) + decoder.assert_not_called() + + def test_an_agreeing_expected_count_proceeds_to_the_decode(self): + """The upstream count is a precondition, not a substitute for decoding.""" + with self.decoding_to(2): + result = M.validate(self.args(expected_triples=2)) + self.assertTrue(result["valid"]) + self.assertTrue(result["count_match"]) + + def test_a_missing_source_is_refused(self): + """Validation cannot proceed without the graph it is validating.""" + with self.assertRaises(FileNotFoundError): + M.validate(self.args(source=str(self.root / "absent.nt"))) + + def test_a_missing_or_empty_artifact_is_refused(self): + """A zero-byte artifact is a failed compression, not a valid empty graph.""" + empty = self.root / "empty.hdt" + empty.write_bytes(b"") + with self.assertRaises(FileNotFoundError): + M.validate(self.args(artifact=str(empty))) + with self.assertRaises(FileNotFoundError): + M.validate(self.args(artifact=str(self.root / "absent.hdt"))) + + def test_the_index_check_is_required_unless_explicitly_skipped(self): + """The helper lives in the image; its absence must fail loudly.""" + with self.assertRaises(RuntimeError) as raised: + M.validate(self.args(skip_index_check=False)) + self.assertIn("HDT index helper", str(raised.exception)) + + def test_a_failing_index_check_stops_the_validation(self): + """An unreadable index is a failure even when the decode would succeed.""" + with mock.patch.object(M.Path, "is_file", return_value=True), \ + mock.patch.object(M.subprocess, "run", return_value=mock.Mock(returncode=4)): + with self.assertRaises(RuntimeError) as raised: + M.validate(self.args(skip_index_check=False)) + self.assertIn("status 4", str(raised.exception)) + + def test_a_missing_cottas_dependency_is_reported_as_such(self): + """pycottas is container-only; its absence must not look like a bad graph.""" + with mock.patch.dict(sys.modules, {"pycottas": None}): + with self.assertRaises(RuntimeError) as raised: + M.validate(self.args(format="cottas")) + self.assertIn("COTTAS dependency is unavailable", str(raised.exception)) + + def test_the_cottas_path_names_its_own_validator(self): + """Reports record which decoder established the count.""" + with mock.patch.dict(sys.modules, {"pycottas": mock.Mock()}), \ + mock.patch.object(M, "count_decoded", return_value=2): + result = M.validate(self.args(format="cottas")) + self.assertEqual(result["validator"], "pycottas.cottas2rdf") + self.assertTrue(result["count_match"]) + + +class MainTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.source = self.root / "graph.nt" + self.source.write_bytes(b" .\n") + self.artifact = self.root / "graph.hdt" + self.artifact.write_bytes(b"not-really-hdt") + self.result_path = self.root / "reports" / "compression.json" + + def run_main(self, *extra): + argv = [ + "validate_compression.py", "--source", str(self.source), + "--artifact", str(self.artifact), "--format", "hdt", + "--skip-index-check", "--result-path", str(self.result_path), *extra, + ] + with mock.patch.object(sys, "argv", argv): + return M.main() + + def test_a_successful_validation_exits_zero_and_writes_its_result(self): + """The JSON sidecar is the record; the exit code is only its summary.""" + with mock.patch.object(M, "resolve_hdt2rdf", return_value="/bin/true"), \ + mock.patch.object(M, "count_decoded", return_value=1): + self.assertEqual(self.run_main(), 0) + result = json.loads(self.result_path.read_text(encoding="utf-8")) + self.assertTrue(result["valid"]) + self.assertTrue(result["count_match"]) + + def test_the_result_directory_is_created_when_absent(self): + """The caller should not have to prepare the reports tree first.""" + self.assertFalse(self.result_path.parent.exists()) + with mock.patch.object(M, "resolve_hdt2rdf", return_value="/bin/true"), \ + mock.patch.object(M, "count_decoded", return_value=1): + self.run_main() + self.assertTrue(self.result_path.is_file()) + + def test_a_mismatch_exits_non_zero(self): + """A decoded count that disagrees fails the run.""" + with mock.patch.object(M, "resolve_hdt2rdf", return_value="/bin/true"), \ + mock.patch.object(M, "count_decoded", return_value=0): + self.assertEqual(self.run_main(), 1) + self.assertFalse(json.loads(self.result_path.read_text())["count_match"]) + + def test_an_exception_is_recorded_in_the_sidecar_rather_than_escaping(self): + """A crashed decoder still leaves a machine-readable explanation behind.""" + with mock.patch.object(M, "resolve_hdt2rdf", side_effect=RuntimeError("no hdt2rdf here")): + self.assertEqual(self.run_main(), 1) + result = json.loads(self.result_path.read_text(encoding="utf-8")) + self.assertFalse(result["valid"]) + self.assertIsNone(result["source_triples"]) + self.assertEqual(result["error"], "no hdt2rdf here") + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_validation_oracle_unit.py b/test/test_validation_oracle_unit.py new file mode 100644 index 0000000..1b9cc70 --- /dev/null +++ b/test/test_validation_oracle_unit.py @@ -0,0 +1,652 @@ +"""The validator's oracle layer: how a VCF is summarised before SPARQL runs. + +These tests drive the pure classification and header-parsing functions that +produce the parser-side expectation every SPARQL result is compared against. A +defect here is invisible in the comparison tests, because both sides of the +comparison are derived from a fixture rather than from these functions - so the +oracle would agree with itself while disagreeing with the VCF. + +Everything here runs on the host with no cyvcf2, bcftools, Comunica, or Docker: +each function is fed the plain values those tools would have produced. That is +deliberate - the container-only dependencies are absent in CI, and a test that +skips there measures nothing. + +The ``test_known_gap_*`` cases record behaviour that is currently wrong, in the +style the mutation harness uses: the gap is an assertion, so closing it fails +here and prompts an update rather than passing unnoticed. +""" + +from __future__ import annotations + +import argparse +import contextlib +import importlib.util +import io +import json +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from test.helpers import VerboseTestCase + +RUNNER_PATH = Path(__file__).resolve().parents[1] / "src" / "validation" / "validation_runner.py" + + +def load_runner(): + spec = importlib.util.spec_from_file_location("validation_runner_oracle", RUNNER_PATH) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +V = load_runner() + + +class FakeVariant: + """The two attributes the lexical helpers read off a cyvcf2 variant.""" + + def __init__(self, alt=None, filters=None, line=""): + self.ALT = alt + self.FILTERS = filters + self._line = line + + def __str__(self) -> str: + return self._line + + +class VariantShapeTests(VerboseTestCase): + def test_every_shape_class_is_reachable(self): + """Each q02 shape bucket is produced by a representative REF/ALT pair.""" + cases = { + ("A", "."): "NO_ALT", + ("A", "G,T"): "MULTIALLELIC", + ("A", "*"): "SYMBOLIC_OR_BREAKEND", + ("A", ""): "SYMBOLIC_OR_BREAKEND", + ("A", "A[2:321682["): "SYMBOLIC_OR_BREAKEND", + ("A", "]2:321682]A"): "SYMBOLIC_OR_BREAKEND", + ("A", "G"): "SNV", + ("AT", "GC"): "MNV_OR_EQUAL_LENGTH_SUBSTITUTION", + ("A", "AT"): "INSERTION_SHAPE", + ("AT", "A"): "DELETION_SHAPE", + ("A", "R"): "OTHER", + } + for (ref, alt), expected in cases.items(): + with self.subTest(ref=ref, alt=alt): + self.assertEqual(V.classify_variant_shape(ref, alt), expected) + + def test_classification_is_case_insensitive(self): + """Lower-case bases classify identically to upper-case ones.""" + self.assertEqual(V.classify_variant_shape("a", "g"), "SNV") + self.assertEqual(V.classify_variant_shape("at", "a"), "DELETION_SHAPE") + + def test_no_alt_is_decided_before_the_base_alphabet(self): + """'.' is NO_ALT rather than OTHER, whatever REF contains.""" + self.assertEqual(V.classify_variant_shape("N", "."), "NO_ALT") + + def test_multiallelic_wins_over_the_shape_of_its_members(self): + """A comma makes the record MULTIALLELIC even when every allele is an SNV.""" + self.assertEqual(V.classify_variant_shape("A", "G,T"), "MULTIALLELIC") + + def test_a_non_iupac_base_is_other_not_a_length_comparison(self): + """An unexpected alphabet is refused before insertion/deletion sizing.""" + self.assertEqual(V.classify_variant_shape("A", "GX"), "OTHER") + self.assertEqual(V.classify_variant_shape("XY", "A"), "OTHER") + + def test_an_empty_alt_is_other(self): + """An empty ALT matches no base pattern, so it is not sized as a deletion.""" + self.assertEqual(V.classify_variant_shape("AT", ""), "OTHER") + + +class AltLexicalTests(VerboseTestCase): + def test_an_absent_alt_list_renders_as_the_missing_token(self): + """No ALT and an empty ALT both render '.', which is what the graph carries.""" + self.assertEqual(V.alt_lexical(FakeVariant(alt=None)), ".") + self.assertEqual(V.alt_lexical(FakeVariant(alt=[])), ".") + + def test_multiple_alleles_join_on_comma_in_source_order(self): + """The lexical form is the VCF column, not a normalised set.""" + self.assertEqual(V.alt_lexical(FakeVariant(alt=["G", "T"])), "G,T") + + def test_a_none_member_becomes_the_missing_token(self): + """A null allele inside the list renders '.' rather than 'None'.""" + self.assertEqual(V.alt_lexical(FakeVariant(alt=[None, "G"])), ".,G") + + +class FilterLexicalTests(VerboseTestCase): + def test_filter_status_has_three_buckets(self): + """PASS, the missing token, and everything else are distinguished.""" + self.assertEqual(V.filter_status("PASS"), "PASS") + self.assertEqual(V.filter_status("."), "NOT_APPLIED") + self.assertEqual(V.filter_status("q10"), "FAILED") + + def test_filter_status_is_case_sensitive(self): + """Only the exact token 'PASS' is a pass; VCF does not define 'pass'.""" + self.assertEqual(V.filter_status("pass"), "FAILED") + + def test_an_empty_filter_is_not_treated_as_a_pass(self): + """An empty string is a failure bucket, never silently a PASS.""" + self.assertEqual(V.filter_status(""), "FAILED") + + def test_the_filters_list_is_joined_with_semicolons(self): + """Multiple filters reproduce the VCF column's own separator.""" + self.assertEqual(V.exact_filter_lexical(FakeVariant(filters=["q10", "s50"])), "q10;s50") + + def test_an_empty_filters_list_falls_back_to_the_serialized_record(self): + """cyvcf2 reports no FILTERS for '.', so column 7 is read verbatim.""" + record = "1\t100\t.\tA\tG\t50\t.\tDP=3\tGT\t0/1\n" + self.assertEqual(V.exact_filter_lexical(FakeVariant(filters=[], line=record)), ".") + + def test_the_fallback_recovers_a_real_filter_string(self): + """The fallback reads the same value the FILTERS list would have given.""" + record = "1\t100\t.\tA\tG\t50\tq10;s50\tDP=3\n" + self.assertEqual(V.exact_filter_lexical(FakeVariant(filters=None, line=record)), "q10;s50") + + def test_a_truncated_record_is_refused_rather_than_guessed(self): + """Too few columns raises instead of silently reporting a wrong FILTER.""" + with self.assertRaises(ValueError): + V.exact_filter_lexical(FakeVariant(filters=[], line="1\t100\t.\tA\tG\n")) + + +class GenotypeClassificationTests(VerboseTestCase): + def test_the_phase_flag_is_dropped_from_the_allele_tuple(self): + """cyvcf2 appends a phase boolean, which is not an allele.""" + self.assertEqual(V.genotype_alleles([0, 1, True]), (0, 1)) + self.assertEqual(V.genotype_alleles([0, False]), (0,)) + + def test_a_negative_allele_index_becomes_none(self): + """htslib encodes a missing allele as -1; the oracle records it as unknown.""" + self.assertEqual(V.genotype_alleles([0, -1, False]), (0, None)) + self.assertEqual(V.genotype_alleles([-1, -1, True]), (None, None)) + + def test_no_genotype_array_stays_none(self): + """A record with no GT array yields no allele tuple at all.""" + self.assertIsNone(V.genotype_alleles(None)) + + def test_every_genotype_class_is_reachable(self): + """Each q05 genotype bucket is produced by a representative allele tuple.""" + cases = { + ((0,), True): "HAPLOID_REF", + ((1,), True): "HAPLOID_ALT", + ((0, 0), True): "HOM_REF", + ((2, 2), True): "HOM_ALT", + ((0, 1), True): "HET", + ((0, 1, 1), True): "OTHER_PLOIDY", + } + for (alleles, has_gt), expected in cases.items(): + with self.subTest(alleles=alleles): + self.assertEqual(V.classify_genotype(alleles, has_gt=has_gt), expected) + + def test_a_file_without_a_gt_field_is_distinguished_from_a_missing_call(self): + """NO_GT_FIELD and MISSING are separate buckets, and must not collapse.""" + self.assertEqual(V.classify_genotype((0, 1), has_gt=False), "NO_GT_FIELD") + self.assertEqual(V.classify_genotype(None, has_gt=True), "MISSING") + + def test_a_partially_missing_genotype_is_missing_not_haploid(self): + """'./1' must not be counted as a haploid call by dropping the unknown half.""" + self.assertEqual(V.classify_genotype((None, 1), has_gt=True), "MISSING") + + def test_an_empty_allele_tuple_is_missing(self): + """No alleles at all is a missing call rather than an unclassified record.""" + self.assertEqual(V.classify_genotype((), has_gt=True), "MISSING") + + +class InfoDeclaredTypeTests(VerboseTestCase): + def test_each_declared_info_key_maps_to_its_type(self): + """The INFO Type drives typed-value counting, so it is read per key.""" + header = "\n".join([ + '##INFO=', + '##INFO=', + '##INFO=', + ]) + self.assertEqual( + V.info_declared_types(header), + {"DP": "Integer", "AF": "Float", "SOMATIC": "Flag"}, + ) + + def test_a_description_containing_commas_does_not_split_the_declaration(self): + """A quoted Description is one field, so Type is still recovered.""" + header = '##INFO=' + self.assertEqual(V.info_declared_types(header), {"DP": "Integer"}) + + def test_a_declaration_without_a_type_defaults_to_string(self): + """A malformed declaration is typed rather than dropped.""" + header = '##INFO=' + self.assertEqual(V.info_declared_types(header), {"NOTYPE": "String"}) + + def test_the_first_declaration_of_a_repeated_key_wins(self): + """A duplicate INFO key keeps the first Type, matching the awk parser.""" + header = "\n".join([ + '##INFO=', + '##INFO=', + ]) + self.assertEqual(V.info_declared_types(header), {"DP": "Integer"}) + + def test_non_info_lines_are_ignored(self): + """FORMAT and the column line contribute no INFO types.""" + header = "\n".join([ + "##fileformat=VCFv4.3", + '##FORMAT=', + "#CHROM\tPOS\tID", + ]) + self.assertEqual(V.info_declared_types(header), {}) + + +class HeaderMetadataTests(VerboseTestCase): + HEADER = "\n".join([ + "##fileformat=VCFv4.3", + "##fileDate=20260101", + "##fileDate=20260202", + "##reference=file:///ref/GRCh38.fa", + "##source=myCaller", + "##assembly=GRCh38", + "##contig=", + "##contig=", + '##ALT=', + '##INFO=', + '##FORMAT=', + '##FILTER=', + "#CHROM\tPOS\tID", + ]) + + def test_file_metadata_is_lifted_from_its_declarations(self): + """The four file-level metadata fields are read off the header block.""" + metadata = V.parse_header_metadata(self.HEADER) + self.assertEqual(metadata["fileFormat"], "VCFv4.3") + self.assertEqual(metadata["referenceGenome"], "file:///ref/GRCh38.fa") + self.assertEqual(metadata["sourceSoftware"], "myCaller") + + def test_a_repeated_metadata_declaration_keeps_the_first(self): + """Two ##fileDate lines resolve to the first, matching the awk parser.""" + self.assertEqual(V.parse_header_metadata(self.HEADER)["fileDate"], "20260101") + + def test_an_undeclared_metadata_field_is_explicitly_absent(self): + """A missing field carries the absent sentinel, never an empty string.""" + metadata = V.parse_header_metadata("##contig=\n#CHROM\tPOS") + self.assertEqual(metadata["fileFormat"], V.METADATA_ABSENT) + self.assertEqual(metadata["fileDate"], V.METADATA_ABSENT) + self.assertEqual(metadata["sourceSoftware"], V.METADATA_ABSENT) + + def test_the_column_line_is_excluded_from_every_count(self): + """'#CHROM' is not a meta-information line and emits no HeaderLine.""" + metadata = V.parse_header_metadata(self.HEADER) + self.assertEqual(metadata["headerLineCount"], 12) + self.assertEqual(len(metadata["headerLines"]), 12) + self.assertNotIn( + "CHROM", {key for key, _ in metadata["headerLines"]} + ) + + def test_structured_declarations_are_indexed_by_id(self): + """Contig, ALT, INFO and FORMAT identifiers are collected for the census.""" + metadata = V.parse_header_metadata(self.HEADER) + self.assertEqual(metadata["contigIds"], ["chr1", "chr2"]) + self.assertEqual(metadata["contigCount"], 2) + self.assertEqual(metadata["altDeclarationIds"], ["DEL"]) + self.assertEqual(metadata["infoKeyNumbers"], {"DP": "1"}) + self.assertEqual(metadata["formatKeyNumbers"], {"GT": "1"}) + + def test_an_assembly_line_is_detected_only_when_it_carries_a_value(self): + """A bare '##assembly' declares nothing to link a contig to.""" + self.assertTrue(V.parse_header_metadata(self.HEADER)["hasAssemblyLine"]) + self.assertFalse(V.parse_header_metadata("##assembly=\n#CHROM")["hasAssemblyLine"]) + + def test_valueless_lines_are_counted_separately_from_all_lines(self): + """A bare flag line is a header line but carries no value.""" + metadata = V.parse_header_metadata("##fileformat=VCFv4.3\n##bareflag\n#CHROM") + self.assertEqual(metadata["headerLineCount"], 2) + self.assertEqual(metadata["headerValueCount"], 1) + + def test_the_header_census_is_grouped_by_key_and_sorted(self): + """q08 compares against a deterministic, key-sorted census.""" + census = V.parse_header_metadata(self.HEADER)["q08_header_line_census"] + self.assertEqual(census, sorted(census, key=lambda row: row["headerKey"])) + self.assertIn({"headerKey": "contig", "lineCount": 2}, census) + self.assertIn({"headerKey": "fileDate", "lineCount": 2}, census) + + def test_a_structured_declaration_without_an_id_is_skipped(self): + """An ID-less contig cannot be addressed by IRI, so it is not counted.""" + metadata = V.parse_header_metadata("##contig=\n#CHROM") + self.assertEqual(metadata["contigIds"], []) + self.assertEqual(metadata["contigCount"], 0) + + +class EmittedHeaderCounterTests(VerboseTestCase): + def test_a_sample_declared_twice_yields_one_declaration_resource(self): + """SampleDeclaration is identity-scoped, so a repeat adds no new resource.""" + counters = V.emitted_header_counters([ + ("SAMPLE", ''), + ("SAMPLE", ''), + ]) + self.assertEqual(counters["emittedHeaderClasses"]["SampleDeclaration"], 1) + self.assertEqual(counters["emittedHeaderPredicates"]["declaresSample"], 2) + + def test_a_pedigree_ancestor_declares_the_sample_it_names(self): + """An ancestor mentioned only in a PEDIGREE line still needs a resource.""" + counters = V.emitted_header_counters([("PEDIGREE", "")]) + predicates = counters["emittedHeaderPredicates"] + self.assertEqual(predicates["pedigreeFather"], 1) + self.assertEqual(predicates["pedigreeMother"], 1) + self.assertEqual(predicates["ancestorRole"], 2) + self.assertEqual(counters["emittedHeaderClasses"]["SampleDeclaration"], 2) + + def test_the_pedigree_id_is_not_counted_as_its_own_ancestor(self): + """ID names the subject of the pedigree line, not a parent of it.""" + counters = V.emitted_header_counters([("PEDIGREE", "")]) + self.assertEqual(counters["emittedHeaderPredicates"]["ancestorRole"], 1) + + def test_the_contig_count_resource_is_emitted_once_for_any_number_of_contigs(self): + """contigCount summarises the file, so it is one statement, not one per contig.""" + counters = V.emitted_header_counters([ + ("contig", ""), + ("contig", ""), + ]) + self.assertEqual(counters["emittedHeaderPredicates"]["contigId"], 2) + self.assertEqual(counters["emittedHeaderPredicates"]["contigCount"], 1) + + def test_no_contigs_means_no_contig_count_statement(self): + """An absent contig block emits no summary statement at all.""" + counters = V.emitted_header_counters([("fileformat", "VCFv4.3")]) + self.assertNotIn("contigCount", counters["emittedHeaderPredicates"]) + + def test_a_meta_values_list_splits_into_its_members(self): + """##META Values=[a, b, c] declares three allowed values.""" + self.assertEqual(V._meta_values("[WholeGenome, Exome, Panel]"), + ["WholeGenome", "Exome", "Panel"]) + + def test_meta_values_tolerates_an_absent_or_unbracketed_list(self): + """A missing list is empty, and a bare comma list still splits.""" + self.assertEqual(V._meta_values(None), []) + self.assertEqual(V._meta_values(""), []) + self.assertEqual(V._meta_values("a,b"), ["a", "b"]) + + def test_every_member_of_a_multi_value_meta_list_is_counted(self): + """A ##META ``Values=[a, b]`` list declares one allowed value per member. + + The commas inside the bracketed list separate members, not attributes. + Splitting on them used to drop every member after the first - the + fragments carry no '=', so they were discarded as non-attributes, and the + surviving value kept its opening bracket. + """ + counters = V.emitted_header_counters([ + ("META", ""), + ]) + self.assertEqual(counters["emittedHeaderPredicates"]["metaAllowedValue"], 2) + + def test_a_single_value_meta_list_is_parsed_correctly(self): + """The bracket stripping works whenever the list has no internal comma.""" + counters = V.emitted_header_counters([ + ("META", ""), + ]) + self.assertEqual(counters["emittedHeaderPredicates"]["metaAllowedValue"], 1) + + def test_an_attribute_after_the_values_list_is_not_swallowed(self): + """The list ends at its closing bracket; later attributes still parse.""" + counters = V.emitted_header_counters([ + ("META", ''), + ]) + predicates = counters["emittedHeaderPredicates"] + self.assertEqual(predicates["metaAllowedValue"], 2) + self.assertEqual(predicates["fieldDescription"], 1) + + def test_the_bracketed_list_does_not_change_the_attribute_count(self): + """Values is one HeaderAttribute however many members it carries.""" + one = V.emitted_header_counters([ + ("META", "")]) + many = V.emitted_header_counters([ + ("META", "")]) + self.assertEqual( + one["emittedHeaderClasses"]["HeaderAttribute"], + many["emittedHeaderClasses"]["HeaderAttribute"], + ) + + +class ToolVersionTests(VerboseTestCase): + def test_a_missing_binary_reports_none_rather_than_raising(self): + """Manifest construction must not fail because an optional tool is absent.""" + self.assertIsNone(V.tool_version(["definitely-not-a-real-binary-xyz", "--version"])) + + def test_the_first_output_line_is_the_version(self): + """Multi-line version banners are reduced to their first line.""" + completed = mock.Mock(stdout="tool 1.2.3\nbuilt from source\n") + with mock.patch.object(V.subprocess, "run", return_value=completed): + self.assertEqual(V.tool_version(["tool", "--version"]), "tool 1.2.3") + + def test_empty_output_reports_none(self): + """A tool that prints nothing yields no version string.""" + with mock.patch.object(V.subprocess, "run", return_value=mock.Mock(stdout=" \n")): + self.assertIsNone(V.tool_version(["tool", "--version"])) + + def test_a_labelled_table_row_is_read_by_its_label(self): + """Comunica prints a markdown table; the version is the labelled cell.""" + banner = "| Package | Version |\n| Comunica Engine | 5.3.0 |\n" + with mock.patch.object(V.subprocess, "run", return_value=mock.Mock(stdout=banner)): + self.assertEqual( + V.tool_version(["comunica", "--version"], table_label="Comunica Engine"), + "5.3.0", + ) + + def test_a_label_that_never_appears_falls_back_to_the_first_line(self): + """An unexpected banner shape still records something rather than nothing.""" + with mock.patch.object(V.subprocess, "run", return_value=mock.Mock(stdout="5.3.0\n")): + self.assertEqual( + V.tool_version(["comunica", "--version"], table_label="Comunica Engine"), + "5.3.0", + ) + + def test_a_hanging_tool_is_abandoned_rather_than_blocking_the_run(self): + """A timeout is absorbed, because a version banner is never load-bearing.""" + with mock.patch.object( + V.subprocess, "run", + side_effect=V.subprocess.TimeoutExpired(cmd="tool", timeout=20), + ): + self.assertIsNone(V.tool_version(["tool", "--version"])) + + +class ManifestTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.vcf = self.root / "cohort.vcf" + self.vcf.write_text("##fileformat=VCFv4.3\n#CHROM\tPOS\n", encoding="utf-8") + self.rdf = self.root / "cohort.nt" + self.rdf.write_text(" .\n", encoding="utf-8") + + def build(self, rdf_format="nt", materialized=False): + args = argparse.Namespace( + vcf=self.vcf, rdf=self.rdf, rdf_format=rdf_format, + dataset_id="cohort-1", representation="expanded", + ) + # Version probes shell out to container-only binaries; the manifest's + # shape is what is under test, not which tools this host happens to have. + with mock.patch.object(V, "tool_version", return_value=None): + return V.build_manifest( + args, V.QUERY_ROOT / "expanded", {"sourceSha256": "deadbeef"}, + engine_description={"engine": "comunica"}, + materialization={"materialized": materialized}, + ) + + def test_the_manifest_records_both_inputs_by_digest(self): + """A manifest must identify exactly which bytes were validated.""" + manifest = self.build() + self.assertEqual(manifest["sourceVcf"]["sha256"], "deadbeef") + self.assertEqual(manifest["sourceRdf"]["sha256"], V.sha256_file(self.rdf)) + self.assertEqual(manifest["sourceRdf"]["format"], "nt") + + def test_every_executed_query_is_pinned_by_digest(self): + """A changed query must be visible in the manifest, not silently rerun.""" + queries = self.build()["queries"] + self.assertEqual(len(queries), len(set(V.PREFLIGHT_QUERIES + V.CORE_QUERIES))) + for query_id, entry in queries.items(): + with self.subTest(query=query_id): + self.assertEqual(len(entry["sha256"]), 64) + + def test_a_plain_ntriples_source_declares_no_decode(self): + """Reading .nt in place must not claim a temporary decode happened.""" + manifest = self.build(materialized=False) + self.assertFalse(manifest["temporaryRdf"]["decompressedInsideContainer"]) + self.assertTrue(manifest["temporaryRdf"]["cleanupConfirmed"]) + + def test_a_materialized_source_records_the_decode(self): + """Anything decoded into scratch is declared as such.""" + manifest = self.build(rdf_format="hdt", materialized=True) + self.assertTrue(manifest["temporaryRdf"]["decompressedInsideContainer"]) + + def test_the_legacy_gzip_key_appears_only_for_a_gzip_source(self): + """sourceRdfGzip is a compatibility alias, not a field of every manifest.""" + self.assertNotIn("sourceRdfGzip", self.build(rdf_format="nt")) + gzip_manifest = self.build(rdf_format="nt.gz") + self.assertEqual(gzip_manifest["sourceRdfGzip"], gzip_manifest["sourceRdf"]) + + def test_the_manifest_serializes_as_json(self): + """The manifest is written to disk, so every value must be encodable.""" + json.dumps(self.build()) + + +class ResolvedArgumentTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.vcf = self.root / "cohort.vcf" + self.vcf.write_text("##fileformat=VCFv4.3\n#CHROM\tPOS\n", encoding="utf-8") + self.rdf = self.root / "cohort.nt" + self.rdf.write_text("", encoding="utf-8") + + def base(self, **overrides): + argv = { + "--vcf": str(self.vcf), "--rdf": str(self.rdf), + "--scratch-dir": str(self.root), "--results-dir": str(self.root), + "--representation": "expanded", "--dataset-id": "cohort-1", + } + argv.update(overrides) + return [item for pair in argv.items() for item in pair] + + def resolve(self, argv): + return V.resolve_args(V.build_arg_parser(), argv) + + def rejection(self, argv): + """Return the message argparse exits with, for a rejected argument set.""" + captured = io.StringIO() + with self.assertRaises(SystemExit), contextlib.redirect_stderr(captured): + self.resolve(argv) + return captured.getvalue() + + def test_a_valid_invocation_resolves_paths_and_the_primary_engine(self): + """The default run resolves to one absolute source and one engine.""" + args = self.resolve(self.base()) + self.assertEqual(args.engines, ["comunica"]) + self.assertEqual(args.engine, "comunica") + self.assertTrue(args.vcf.is_absolute()) + self.assertTrue(args.rdf.is_absolute()) + + def test_the_format_is_inferred_from_the_artifact_suffix(self): + """A recognised extension means --rdf-format is optional.""" + self.assertEqual(self.resolve(self.base()).rdf_format, "nt") + + def test_an_unrecognised_suffix_names_the_supported_formats(self): + """An inference failure must tell the operator what to pass instead.""" + artifact = self.root / "cohort.xyz" + artifact.write_text("", encoding="utf-8") + message = self.rejection(self.base(**{"--rdf": str(artifact)})) + self.assertIn("Could not infer an RDF format", message) + for fmt in V.RDF_FORMATS: + self.assertIn(fmt, message) + + def test_the_gzip_alias_selects_its_format_and_collapses_into_rdf(self): + """--rdf-gz is a spelling of --rdf, and implies the gzip format.""" + gzipped = self.root / "cohort.nt.gz" + gzipped.write_text("", encoding="utf-8") + argv = self.base() + argv[argv.index("--rdf")] = "--rdf-gz" + argv[argv.index(str(self.rdf))] = str(gzipped) + args = self.resolve(argv) + self.assertEqual(args.rdf_format, "nt.gz") + self.assertEqual(args.rdf.name, "cohort.nt.gz") + + def test_an_explicit_format_is_not_overridden_by_the_suffix(self): + """A deliberate --rdf-format survives a misleading filename.""" + self.assertEqual(self.resolve(self.base(**{"--rdf-format": "nt.gz"})).rdf_format, "nt.gz") + + def test_all_expands_to_every_supported_engine_in_registry_order(self): + """'all' is a shorthand, and the first engine stays the primary.""" + args = self.resolve(self.base(**{"--engine": "all"})) + self.assertEqual(args.engines, list(V.SPARQL_ENGINES)) + self.assertEqual(args.engine, V.SPARQL_ENGINES[0]) + + def test_an_unknown_engine_is_rejected_with_the_supported_set(self): + """A typo must name the alternatives rather than failing opaquely.""" + message = self.rejection(self.base(**{"--engine": "comunca"})) + self.assertIn("unknown SPARQL engine", message) + self.assertIn("comunica", message) + + def test_a_missing_input_is_named(self): + """Both inputs are checked before any container work starts.""" + self.assertIn("VCF does not exist", self.rejection( + self.base(**{"--vcf": str(self.root / "absent.vcf")}))) + self.assertIn("RDF artifact does not exist", self.rejection( + self.base(**{"--rdf": str(self.root / "absent.nt")}))) + + def test_a_missing_scratch_directory_is_named(self): + """Scratch is a mount point; a missing one is a configuration error.""" + self.assertIn("Scratch directory does not exist", self.rejection( + self.base(**{"--scratch-dir": str(self.root / "absent")}))) + + def test_the_dataset_id_is_restricted_to_iri_safe_characters(self): + """The dataset id reaches IRIs and filenames, so it is constrained.""" + self.assertIn("--dataset-id may contain only", self.rejection( + self.base(**{"--dataset-id": "bad id!"}))) + self.assertEqual(self.resolve(self.base(**{"--dataset-id": "a.b_c-1"})).dataset_id, "a.b_c-1") + + def test_every_duration_must_be_positive(self): + """A zero timeout would abandon a query before it started.""" + for flag in ("--query-timeout", "--qlever-memory-gb", "--qlever-startup-timeout", + "--comunica-bind-timeout", "--comunica-warmup-timeout"): + with self.subTest(flag=flag): + self.assertIn(f"{flag} must be a positive integer", + self.rejection(self.base(**{flag: "0"}))) + + def test_the_time_budget_treats_zero_as_no_ceiling(self): + """Zero is meaningful here, so only a negative budget is refused.""" + self.assertEqual(self.resolve( + self.base(**{"--validation-time-budget": "0"})).validation_time_budget, 0) + self.assertIn("must be zero or a positive integer", + self.rejection(self.base(**{"--validation-time-budget": "-1"}))) + + def test_every_port_must_be_in_range(self): + """An out-of-range port fails here rather than when the server binds.""" + for flag in ("--qlever-port", "--comunica-port", "--hdt-port"): + with self.subTest(flag=flag): + self.assertIn(f"{flag} must be between 1 and 65535", + self.rejection(self.base(**{flag: "0"}))) + self.assertIn(f"{flag} must be between 1 and 65535", + self.rejection(self.base(**{flag: "70000"}))) + + def test_the_three_engine_ports_must_differ(self): + """Two engines sharing a port would silently query the wrong server.""" + message = self.rejection(self.base(**{"--comunica-port": "7100", "--qlever-port": "7100"})) + self.assertIn("must all differ", message) + + def test_a_missing_shacl_shapes_file_is_named(self): + """Requesting conformance against shapes that do not exist is refused.""" + self.assertIn("SHACL shapes file does not exist", self.rejection( + self.base(**{"--shacl-shapes": str(self.root / "absent.ttl")}))) + + def test_supplied_shapes_and_progress_paths_are_resolved(self): + """Both optional paths become absolute for the container's benefit.""" + shapes = self.root / "shapes.ttl" + shapes.write_text("", encoding="utf-8") + args = self.resolve(self.base(**{ + "--shacl-shapes": str(shapes), "--progress-path": str(self.root / "progress.json"), + })) + self.assertTrue(args.shacl_shapes.is_absolute()) + self.assertTrue(args.progress_path.is_absolute()) + + def test_no_progress_path_stays_none(self): + """Progress reporting is opt-in and must not be invented.""" + self.assertIsNone(self.resolve(self.base()).progress_path) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_validation_results_unit.py b/test/test_validation_results_unit.py new file mode 100644 index 0000000..56d3049 --- /dev/null +++ b/test/test_validation_results_unit.py @@ -0,0 +1,373 @@ +"""Reading engine output, and refusing to trust it when it is unreadable. + +Between a SPARQL engine writing its result and the comparison layer declaring a +verdict sits a thin reading layer: parse SPARQL Results JSON, recover an exact +anomaly total, reconcile parsed statements against distinct triples, and reject a +materialized N-Triples file that cannot be what it claims to be. + +Every failure here has the same shape, and it is the one that matters most in a +validator: a result that could not be read must never be reported as clean. The +tests below drive each of those paths directly, with no engine, decoder, or +Docker involved - the container-only binaries are stubbed, because they are +absent in CI and a skipped test measures nothing. +""" + +from __future__ import annotations + +import importlib.util +import json +import tempfile +import unittest +from pathlib import Path +from unittest import mock + +from test.helpers import VerboseTestCase + +RUNNER_PATH = Path(__file__).resolve().parents[1] / "src" / "validation" / "validation_runner.py" + + +def load_runner(): + spec = importlib.util.spec_from_file_location("validation_runner_results", RUNNER_PATH) + module = importlib.util.module_from_spec(spec) + assert spec.loader is not None + spec.loader.exec_module(module) + return module + + +V = load_runner() + + +class BindingsTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def write(self, payload) -> Path: + path = self.root / "result.json" + path.write_text(json.dumps(payload), encoding="utf-8") + return path + + def test_well_formed_results_are_returned_as_rows(self): + """The happy path is the SPARQL Results JSON bindings array.""" + path = self.write({"results": {"bindings": [{"n": {"value": "1"}}]}}) + self.assertEqual(V.bindings(path), [{"n": {"value": "1"}}]) + + def test_an_empty_result_set_is_valid(self): + """No rows is an answer, not a malformed document.""" + self.assertEqual(V.bindings(self.write({"results": {"bindings": []}})), []) + + def test_a_document_without_bindings_is_rejected(self): + """A response shaped like an error must not read as zero rows.""" + with self.assertRaises(ValueError) as raised: + V.bindings(self.write({"results": {}})) + self.assertIn("Invalid SPARQL Results JSON", str(raised.exception)) + + def test_a_non_list_bindings_value_is_rejected(self): + """An object where an array belongs is refused rather than iterated.""" + with self.assertRaises(ValueError) as raised: + V.bindings(self.write({"results": {"bindings": {}}})) + self.assertIn("not a list", str(raised.exception)) + + def test_a_completely_wrong_document_is_rejected(self): + """A bare list or string is not a results document.""" + with self.assertRaises(ValueError): + V.bindings(self.write([1, 2, 3])) + + def test_an_integer_binding_is_read_from_its_value(self): + """SPARQL wraps every term in an object; the lexical form is what counts.""" + self.assertEqual(V.binding_int({"n": {"value": "42"}}, "n"), 42) + + +class AnomalyCountTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def execution(self, payload, status="PASS") -> dict: + path = self.root / "count.json" + path.write_text(json.dumps(payload), encoding="utf-8") + return {"preflight_blank_nodes_count": {"status": status, "rawResult": str(path)}} + + def test_the_exact_total_is_read_from_the_companion_aggregate(self): + """The sampled query is truncated; the count query is not.""" + executions = self.execution( + {"results": {"bindings": [{"anomalyCount": {"value": "17"}}]}}) + self.assertEqual(V.anomaly_count(executions, "preflight_blank_nodes"), 17) + + def test_an_absent_companion_reports_none_not_zero(self): + """A missing exact count must not be presented as 'no anomalies'.""" + self.assertIsNone(V.anomaly_count({}, "preflight_blank_nodes")) + + def test_a_failed_companion_reports_none(self): + """A query that did not pass cannot supply a trustworthy total.""" + executions = self.execution( + {"results": {"bindings": [{"anomalyCount": {"value": "17"}}]}}, status="FAIL") + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + def test_an_unreadable_companion_result_reports_none(self): + """Corrupt output degrades to 'unknown' rather than raising.""" + path = self.root / "count.json" + path.write_text("{not json", encoding="utf-8") + executions = {"preflight_blank_nodes_count": {"status": "PASS", "rawResult": str(path)}} + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + def test_a_missing_result_file_reports_none(self): + """A result path that does not exist is unknown, not zero.""" + executions = {"preflight_blank_nodes_count": { + "status": "PASS", "rawResult": str(self.root / "absent.json")}} + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + def test_an_aggregate_returning_several_rows_reports_none(self): + """A count query must return exactly one row to be an exact total.""" + executions = self.execution({"results": {"bindings": [ + {"anomalyCount": {"value": "1"}}, {"anomalyCount": {"value": "2"}}, + ]}}) + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + def test_a_row_without_the_count_variable_reports_none(self): + """A projection change must not be read as a valid total.""" + executions = self.execution({"results": {"bindings": [{"other": {"value": "1"}}]}}) + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + def test_a_non_numeric_count_reports_none(self): + """A malformed literal is unknown rather than an exception.""" + executions = self.execution( + {"results": {"bindings": [{"anomalyCount": {"value": "many"}}]}}) + self.assertIsNone(V.anomaly_count(executions, "preflight_blank_nodes")) + + +class DuplicateTripleReportTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def executions(self, distinct, status="PASS") -> dict: + path = self.root / "distinct.json" + path.write_text(json.dumps( + {"results": {"bindings": [{"distinctTripleCount": {"value": str(distinct)}}]}}), + encoding="utf-8") + return {"preflight_distinct_triple_count": {"status": status, "rawResult": str(path)}} + + def test_equal_counts_pass_with_no_duplicates(self): + """A store that deduplicated nothing means the source had no repeats.""" + report = V.duplicate_triple_report(self.executions(100), 100) + self.assertEqual(report["status"], "PASS") + self.assertEqual(report["duplicateTripleCount"], 0) + + def test_the_difference_is_the_duplicate_count(self): + """Parsed minus distinct is exactly the number of redundant statements.""" + report = V.duplicate_triple_report(self.executions(90), 100) + self.assertEqual(report["status"], "FAIL") + self.assertEqual(report["parsedTripleCount"], 100) + self.assertEqual(report["distinctTripleCount"], 90) + self.assertEqual(report["duplicateTripleCount"], 10) + + def test_a_missing_parsed_count_is_not_evaluated(self): + """Without the parser's total there is nothing to compare against.""" + report = V.duplicate_triple_report(self.executions(90), None) + self.assertEqual(report["status"], "NOT_EVALUATED") + self.assertIn("statement count", report["reason"]) + + def test_a_query_that_did_not_run_is_not_evaluated(self): + """An absent or failed query cannot establish a clean result.""" + self.assertEqual( + V.duplicate_triple_report({}, 100)["status"], "NOT_EVALUATED") + self.assertEqual( + V.duplicate_triple_report(self.executions(90, status="FAIL"), 100)["status"], + "NOT_EVALUATED") + + def test_an_unreadable_result_is_not_evaluated_and_says_why(self): + """A corrupt result is reported as unknown with its cause attached.""" + path = self.root / "distinct.json" + path.write_text("{not json", encoding="utf-8") + report = V.duplicate_triple_report( + {"preflight_distinct_triple_count": {"status": "PASS", "rawResult": str(path)}}, 100) + self.assertEqual(report["status"], "NOT_EVALUATED") + self.assertIn("unreadable result", report["reason"]) + + def test_an_empty_result_set_is_not_evaluated(self): + """No row means no distinct count, which is not the same as zero.""" + path = self.root / "distinct.json" + path.write_text(json.dumps({"results": {"bindings": []}}), encoding="utf-8") + report = V.duplicate_triple_report( + {"preflight_distinct_triple_count": {"status": "PASS", "rawResult": str(path)}}, 100) + self.assertEqual(report["status"], "NOT_EVALUATED") + + +class MaterializedGraphVerificationTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + + def verify(self, data: bytes) -> int: + path = self.root / "decoded.nt" + path.write_bytes(data) + return V._verify_ntriples(path, label="hdt2rdf") + + def test_a_well_formed_decode_returns_its_size(self): + """The size is reused for reporting, so it is returned rather than discarded.""" + payload = b" .\n" + self.assertEqual(self.verify(payload), len(payload)) + + def test_a_leading_blank_node_is_accepted(self): + """A graph may legitimately begin with a blank-node subject.""" + self.assertGreater(self.verify(b"_:b1 .\n"), 0) + + def test_an_unreadable_path_is_diagnosed(self): + """A decoder that wrote nothing at all must be named as the cause.""" + with self.assertRaises(RuntimeError) as raised: + V._verify_ntriples(self.root / "absent.nt", label="hdt2rdf") + self.assertIn("produced no readable output", str(raised.exception)) + + def test_an_empty_file_is_rejected(self): + """A zero-byte decode is a failure even when the exit code was zero.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b"") + self.assertIn("empty N-Triples file", str(raised.exception)) + + def test_a_file_with_no_newline_is_rejected_immediately(self): + """This is the failure that looked like a hang: one enormous line.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b" .") + self.assertIn("no newline", str(raised.exception)) + + def test_a_first_line_that_does_not_begin_a_triple_is_rejected(self): + """A subject must be an IRI or a blank node, not arbitrary text.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b"oops .\n") + self.assertIn("does not begin a triple", str(raised.exception)) + + def test_a_first_line_without_a_terminator_is_rejected(self): + """A missing '.' means the line was truncated mid-statement.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b" \n") + self.assertIn("no statement terminator", str(raised.exception)) + + def test_a_file_not_ending_in_a_newline_is_reported_as_truncated(self): + """The tail check catches a decode that stopped partway through.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b" .\n .") + self.assertIn("most likely truncated", str(raised.exception)) + + def test_the_diagnosis_quotes_the_offending_bytes(self): + """An operator needs to see what was produced, not only that it was wrong.""" + with self.assertRaises(RuntimeError) as raised: + self.verify(b"garbage line here\n") + self.assertIn("garbage line here", str(raised.exception)) + + +class BinaryResolutionTests(VerboseTestCase): + def test_an_environment_override_wins_when_it_resolves(self): + """The image pins decoder builds through environment variables.""" + with mock.patch.dict(V.os.environ, {"HDT2RDF_BIN": "/bin/sh"}, clear=False): + self.assertEqual(V._resolve_binary("HDT2RDF_BIN", "hdt2rdf"), "/bin/sh") + + def test_an_unresolvable_override_falls_through_to_the_candidates(self): + """A stale override must not mask a working binary on PATH.""" + with mock.patch.dict(V.os.environ, {"HDT2RDF_BIN": "not-a-real-binary-xyz"}, clear=False): + self.assertEqual( + V._resolve_binary("HDT2RDF_BIN", "sh"), V.shutil.which("sh")) + + def test_a_blank_override_is_ignored(self): + """An empty variable is 'unset', not a path to the empty string.""" + with mock.patch.dict(V.os.environ, {"HDT2RDF_BIN": " "}, clear=False): + self.assertEqual(V._resolve_binary("HDT2RDF_BIN", "sh"), V.shutil.which("sh")) + + def test_a_missing_binary_names_the_primary_candidate(self): + """The error must say which tool the image is missing.""" + with mock.patch.dict(V.os.environ, {}, clear=True): + with self.assertRaises(RuntimeError) as raised: + V._resolve_binary("HDT2RDF_BIN", "hdt2rdf-absent-xyz", "also-absent-xyz") + self.assertIn("hdt2rdf-absent-xyz", str(raised.exception)) + + +class EngineAdviceTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.source = self.root / "graph.nt" + self.source.write_bytes(b"x" * 4096) + + def test_an_indexing_engine_needs_no_warning(self): + """The advisory is specifically about comunica's lack of an index.""" + self.assertIsNone(V.engine_advice("qlever", self.source, 13, 600)) + + def test_a_small_graph_needs_no_warning(self): + """Below the threshold, streaming per query is perfectly reasonable.""" + self.assertIsNone(V.engine_advice("comunica", self.source, 13, 600)) + + def test_a_large_graph_warns_and_names_the_alternatives(self): + """The warning must be actionable, not merely alarming.""" + with mock.patch.object(V, "UNINDEXED_ENGINE_ADVICE_BYTES", 1024): + advice = V.engine_advice("comunica", self.source, 13, 600) + self.assertIsNotNone(advice) + self.assertIn("13", advice) + self.assertIn("--engine qlever", advice) + + def test_an_unreadable_source_produces_no_advice(self): + """A missing file is a different error, reported elsewhere.""" + self.assertIsNone(V.engine_advice("comunica", self.root / "absent.nt", 13, 600)) + + +class NtriplesSyntaxCheckTests(VerboseTestCase): + def setUp(self): + self._tmp = tempfile.TemporaryDirectory() + self.root = Path(self._tmp.name) + self.addCleanup(self._tmp.cleanup) + self.source = self.root / "graph.nt" + self.source.write_bytes(b" .\n") + + def test_an_absent_rapper_is_an_execution_failure_not_a_conformance_failure(self): + """A missing tool must never be reported as an invalid graph.""" + with mock.patch.object(V.shutil, "which", return_value=None): + result = V.validate_ntriples(self.source, self.root) + self.assertEqual(result["status"], "EXECUTION_FAILED") + self.assertIn("rapper", result["error"]) + + def test_a_clean_parse_passes_and_records_the_triple_count(self): + """The count makes a decoded artifact comparable against its source.""" + completed = mock.Mock( + returncode=0, stdout="", stderr="rapper: Parsing returned 5 triples\n") + with mock.patch.object(V.shutil, "which", return_value="/usr/bin/rapper"), \ + mock.patch.object(V.subprocess, "run", return_value=completed): + result = V.validate_ntriples(self.source, self.root) + self.assertEqual(result["status"], "PASS") + self.assertEqual(result["tripleCount"], 5) + self.assertEqual(result["exitCode"], 0) + + def test_a_non_zero_exit_fails(self): + """A syntax error in the graph is a conformance failure.""" + completed = mock.Mock(returncode=1, stdout="", stderr="rapper: Error - syntax\n") + with mock.patch.object(V.shutil, "which", return_value="/usr/bin/rapper"), \ + mock.patch.object(V.subprocess, "run", return_value=completed): + result = V.validate_ntriples(self.source, self.root) + self.assertEqual(result["status"], "FAIL") + self.assertEqual(result["exitCode"], 1) + + def test_an_unparsable_banner_leaves_the_count_unknown(self): + """A missing count is None rather than a fabricated zero.""" + completed = mock.Mock(returncode=0, stdout="", stderr="done\n") + with mock.patch.object(V.shutil, "which", return_value="/usr/bin/rapper"), \ + mock.patch.object(V.subprocess, "run", return_value=completed): + result = V.validate_ntriples(self.source, self.root) + self.assertIsNone(result["tripleCount"]) + + def test_the_tool_output_is_written_beside_the_report(self): + """The log is the evidence for the verdict and must survive the run.""" + completed = mock.Mock(returncode=0, stdout="out\n", stderr="err\n") + with mock.patch.object(V.shutil, "which", return_value="/usr/bin/rapper"), \ + mock.patch.object(V.subprocess, "run", return_value=completed): + result = V.validate_ntriples(self.source, self.root) + log = Path(result["log"]) + self.assertTrue(log.is_file()) + self.assertIn("out", log.read_text(encoding="utf-8")) + self.assertIn("err", log.read_text(encoding="utf-8")) + + +if __name__ == "__main__": + unittest.main() diff --git a/test/test_vcf_rdfizer_unit.py b/test/test_vcf_rdfizer_unit.py index db87992..a6c4f2b 100644 --- a/test/test_vcf_rdfizer_unit.py +++ b/test/test_vcf_rdfizer_unit.py @@ -2214,6 +2214,51 @@ def test_structured_format_header_parser_preserves_quoted_commas(self): self.assertEqual(fields["Number"], "1") self.assertEqual(fields["Description"], 'Genotype, with "quoted" text') + def test_structured_header_parser_keeps_a_bracketed_values_list_whole(self): + """A ##META ``Values=[a, b, c]`` list is one attribute, not three fragments. + + The commas inside the brackets separate allowed values, not attributes. + Splitting on them dropped every member after the first, because the + fragments carry no '=' and were discarded, leaving a value that still + held its opening bracket. + """ + fields = vcf_rdfizer._parse_structured_header_fields( + "" + ) + + self.assertEqual(fields["Values"], "[WholeGenome, Exome, Panel]") + self.assertEqual( + vcf_rdfizer._parse_meta_values(fields["Values"]), + ["WholeGenome", "Exome", "Panel"], + ) + + def test_structured_header_parser_resumes_after_a_bracketed_list(self): + """An attribute following the Values list is still parsed.""" + fields = vcf_rdfizer._parse_structured_header_fields( + '' + ) + + self.assertEqual(fields["Type"], "String") + self.assertEqual(fields["Description"], "an assay, described") + + def test_structured_header_parser_survives_an_unbalanced_bracket(self): + """Malformed brackets must not swallow every remaining attribute.""" + fields = vcf_rdfizer._parse_structured_header_fields( + "" + ) + + self.assertEqual(fields["ID"], "Broken") + self.assertEqual(fields["Type"], "String") + + def test_structured_header_parser_ignores_a_bracket_inside_quotes(self): + """A '[' in a description is text, not the start of a values list.""" + fields = vcf_rdfizer._parse_structured_header_fields( + '' + ) + + self.assertEqual(fields["Description"], "depth [reads], per sample") + self.assertEqual(fields["Number"], "1") + def test_condensed_sample_emitter_rolls_back_on_sample_count_mismatch(self): """Malformed sample alignment fails atomically without a partial condensed graph.""" with tempfile.TemporaryDirectory() as td: diff --git a/vcf_rdfizer_vocab.py b/vcf_rdfizer_vocab.py index ec76c37..20c25b3 100644 --- a/vcf_rdfizer_vocab.py +++ b/vcf_rdfizer_vocab.py @@ -977,21 +977,23 @@ def parse_structured_header_fields(value: str) -> dict[str, str]: return dict(parse_structured_header_attributes(value)) -def parse_structured_header_attributes(value: str) -> list[tuple[str, str]]: - """Parse a structured header value into ordered (key, value) attributes. +def _split_header_attributes(inner: str, *, bracket_aware: bool) -> tuple[list[str], int]: + """Split a structured header body on its attribute-separating commas. - Order is preserved because vcfc:HeaderAttribute carries a one-based - vcfc:attributeIndex; VCF 4.5 forbids relying on source attribute order for - meaning, but the vocabulary keeps it recoverable. - """ - inner = (value or "").strip() - if inner.startswith("<") and inner.endswith(">"): - inner = inner[1:-1] + A comma separates attributes only outside quotes and, when *bracket_aware*, + outside a bracketed list. VCF 4.5 writes a ``##META`` allowed-value set as + ``Values=[a, b, c]``, whose internal commas are part of one attribute; + splitting on them drops every member after the first, because the fragments + carry no ``=`` and are discarded as non-attributes. + Returns the tokens and the final bracket depth, which is non-zero only when + the input's brackets are unbalanced. + """ tokens: list[str] = [] token: list[str] = [] in_quotes = False escaped = False + depth = 0 for character in inner: if escaped: token.append(character) @@ -1002,12 +1004,40 @@ def parse_structured_header_attributes(value: str) -> list[tuple[str, str]]: elif character == '"': token.append(character) in_quotes = not in_quotes - elif character == "," and not in_quotes: + elif bracket_aware and character == "[" and not in_quotes: + depth += 1 + token.append(character) + elif bracket_aware and character == "]" and not in_quotes: + # Clamped, so a stray ']' cannot make the depth negative and turn a + # later, genuine '[' into a no-op. + depth = max(0, depth - 1) + token.append(character) + elif character == "," and not in_quotes and depth == 0: tokens.append("".join(token)) token = [] else: token.append(character) tokens.append("".join(token)) + return tokens, depth + + +def parse_structured_header_attributes(value: str) -> list[tuple[str, str]]: + """Parse a structured header value into ordered (key, value) attributes. + + Order is preserved because vcfc:HeaderAttribute carries a one-based + vcfc:attributeIndex; VCF 4.5 forbids relying on source attribute order for + meaning, but the vocabulary keeps it recoverable. + """ + inner = (value or "").strip() + if inner.startswith("<") and inner.endswith(">"): + inner = inner[1:-1] + + tokens, depth = _split_header_attributes(inner, bracket_aware=True) + if depth: + # Unbalanced brackets are malformed. Bracket-aware splitting would treat + # the rest of the line as one token and silently drop every attribute + # after the stray '[', so fall back to splitting on commas alone. + tokens, _ = _split_header_attributes(inner, bracket_aware=False) attributes: list[tuple[str, str]] = [] for item in tokens: