Add direct HPOA, OMIM, and Orphanet ingests - #417
Conversation
- Add HPOA disease-phenotype and disease-conditioned gene-phenotype parsing from HPO release files. - Add direct OMIM and Orphanet gene-condition parsers with source-specific filters and provenance. - Remove replaced HPOA-mediated phenotype content from MonarchKG while leaving MonarchKGFull unchanged. - Register new sources in Baseline and add comparison/test coverage for the rationalized ingest.
- Pass raw Monarch edge metadata into the curated MonarchKG filter. - Drop MonarchKG causes edges from provided_by=omim_gene_to_disease_edges now superseded by direct OMIM ingest. - Keep MonarchKGFull unfiltered and cover both behaviors with tests.
# Conflicts: # graph_specs/automat-graph-spec.yaml # tests/test_graph_spec.py
|
While reviewing example edges from the HPOA parser, found several properties that were redundant or dead weight:
Also reviewed and kept:
|
|
|
Dropping properties:
Bug in pmids_from_validation: the regex required exact-case "PMID" , so it silently dropped real PMIDs from malformed source strings actually present in the live feed — a typo'd "...[PMId]" and a truncated "...[PMID" with no closing bracket. Fixed with case-insensitive matching and an optional closing bracket. Also reviewed and kept:
|
eKathleenCarter
left a comment
There was a problem hiding this comment.
Reviewed the PR
Summary:
Confirmed: All the filtering/predicate logic described for HPOA/OMIM/Orphanet, Baseline-only registration verified. The MonarchKG filtering behavior and the structural reasoning in "why the direct ingest adds edges" also verified.
Two things of note:
- Orphanet's predicate description says it emits
ORPHA:<OrphaCode>. Fixed it toOrphanet:<OrphaCode>. - The "HPOA preserves raw fields including... reference... aspect..." sentence is stale. I dropped several fields that were redundant or always-constant and moved others onto biolink's own qualifiers instead of raw properties.
Exact edge/overlap counts in the PR won't reproduce against a fresh pull; new versions were introduced during review, but the structural claims hold.
Current edge counts from a fresh build against live data just now:
| Source | Predicate | Edge family | Edges |
|---|---|---|---|
| HPOA | has_phenotype |
disease→phenotype (OMIM) | 143,558 |
| HPOA | has_phenotype |
disease→phenotype (Orphanet) | 114,470 |
| HPOA | has_phenotype |
gene→phenotype (disease-conditioned) | 311,724 |
| HPOA | — | total | 569,752 |
| OMIM | gene_associated_with_condition |
gene→condition | 7,508 |
| Orphanet | gene_associated_with_condition |
gene→condition | 7,659 |
Note on DECIPHER edges: DECIPHER-attributed HPOA rows aren't in this table. That prefix isn't registered in Babel/node-normalization at all, so those edges are dropped during normalization.
|
scripts/compare_hpoa_rationalization.py — this looks like a one-off analysis tool you used while building this PR (it's also the only file in scripts/, so this PR introduces that directory). It's not referenced by any tests, docs, or CI. Was this meant to stick around, or is it fine to drop before merge? If it's useful to keep as a diagnostic for future rationalization work, might be worth a one-line docstring/README note explaining when to reach for it — otherwise happy to see it go. |
Summary
HPOAparser forphenotype.hpoadisease-phenotype edges andgenes_to_phenotype.txtdisease-conditioned gene-phenotype edges.OMIMparser formim2gene_medgengene-condition edges.Orphanetparser foren_product6.xmlassessed gene-condition edges.HPOA,OMIM, andOrphanetin ORION source metadata and theBaselinegraph.RobokopKGandRoboMouseKGinherit these throughBaseline; no Automat graph is added.MonarchKGwhile leavingMonarchKGFullunchanged.Parser semantics
disease biolink:has_phenotype phenotypewithprimary_knowledge_source=infores:hpo-annotations.aspect == P, empty qualifier, and non-zero frequency. It skips course, inheritance, modifier, clinical modifier/history rows,NOT,0/N, and0%rows.gene biolink:has_phenotype phenotypeonly when the(disease_id, hpo_id)pair survived the disease-phenotype filter. These edges preservedisease_context_qualifierso they remain disease-conditioned.supporting_data_sourcesuch asinfores:omim,infores:orphanet, orinfores:decipher.type == phenotyperows with a GeneID and emitsNCBIGene:<GeneID> biolink:gene_associated_with_condition OMIM:<MIM>withprimary_knowledge_source=infores:omim.DisorderGeneAssociationStatus == Assessed, skipsCandidate gene tested inandBiomarker tested in, requires an HGNC external reference, and emitsHGNC:<id> biolink:gene_associated_with_condition ORPHA:<OrphaCode>withprimary_knowledge_source=infores:orphanet.Data DAGs
Current / old path into Baseline
flowchart LR OMIM["OMIM\nGene-Disease assertions"] ORPHA["Orphadata / Orphanet\nGene-Disease assertions"] DECIPHER["DECIPHER\nDisease-Phenotype assertions"] PHENO["phenotype.hpoa\nCurated Disease-Phenotype table"] G2P["genes_to_phenotype.txt\nDerived disease-conditioned Gene-Phenotype table"] MONARCH["Monarch KG\nHPOA-derived Disease-Phenotype edges\nHPOA-derived Gene-Phenotype edges\nOMIM Gene-Disease edges"] BASE["ORION Baseline\nHPOA Disease-Phenotype edges\nHPOA Gene-Phenotype edges\nOMIM Gene-Disease edges"] DECIPHER --> PHENO PHENO --> G2P OMIM --> G2P ORPHA --> G2P OMIM --> MONARCH PHENO --> MONARCH G2P --> MONARCH MONARCH --> BASENew path into Baseline
flowchart LR OMIM["OMIM\nGene-Disease assertions"] ORPHA["Orphadata / Orphanet\nGene-Disease assertions"] DECIPHER["DECIPHER\nDisease-Phenotype assertions"] PHENO["phenotype.hpoa\nCurated Disease-Phenotype table"] G2P["genes_to_phenotype.txt\nDerived disease-conditioned Gene-Phenotype table"] BASE["ORION Baseline\nHPOA Disease-Phenotype edges\nHPOA Gene-Phenotype edges\nOMIM Gene-Disease edges\nOrphanet Gene-Disease edges"] DECIPHER --> PHENO PHENO --> G2P OMIM --> G2P ORPHA --> G2P PHENO --> BASE G2P --> BASE OMIM --> BASE ORPHA --> BASEInterpretation:
phenotype.hpoais the curated HPOA Disease-Phenotype table. It includes disease-phenotype rows whose disease identifiers include OMIM, Orphanet, and DECIPHER records.genes_to_phenotype.txtis a derived HPOA Gene-Phenotype table, conditioned on disease context.mim2gene_medgen, and receives Orphanet Gene-Disease edges directly fromen_product6.xml.primary_knowledge_source=infores:monarchinitiativeandprovided_by=omim_gene_to_disease_edges.Why the direct ingest adds edges relative to Monarch
This is a semantic replacement of Monarch-mediated HPOA/OMIM/Orphanet content, not a count-preserving replay of Monarch's projected edges.
311,865gene-phenotype rows but only255,797unique gene/HP pairs. The additional56,068rows are the same gene/phenotype association under different disease contexts. We keep those distinct withdisease_context_qualifier, and ORION's merge key treats qualifiers as part of edge identity.187,560HPOA-primary gene-ishhas_phenotypeedges; direct HPOA has311,865disease-conditioned gene-phenotype rows. Even after ignoring disease-context multiplicity, direct HPOA has about68kmore unique raw gene/HP pairs.OMIM/ORPHA/DECIPHER -> HP; the current built graph has many of those normalized through Monarch asMONDO -> HPorMONDO -> MONDO. Exact raw-CURIE overlap therefore overstates novelty.6,550biolink:causesedges and601biolink:contributes_toedges withprimary=infores:monarchinitiativeandprovided_by=omim_gene_to_disease_edges. After mapping direct OMIM disease IDs through current graph node equivalences,6,846of7,129unique Monarch OMIM-derived pairs overlap with the new direct OMIM output.6,352 / 6,550for Monarchbiolink:causesand514 / 601for Monarchbiolink:contributes_to. Both predicate blocks are filtered fromMonarchKGin this PR.7,661NCBIGene -> OMIMedges frommim2gene_medgenand7,940HGNC -> ORPHAedges from Orphadata. These replace/supersede Monarch projections where present, rather than preserving Monarch's stronger or inconsistent predicates.Expected Baseline effect
Current graph aggregate counts for HPOA-mediated Monarch content were:
187,560biolink:has_phenotypeedges withprimary=infores:hpo-annotations; this included132,495gene-phenotype-ish edges plus54,998NCBIGene -> MONDOand small HGNC/UMLS cases.139,314disease-phenotype-ishbiolink:has_phenotypeedges withprimary=infores:omimand HPOA/Monarch aggregation.113,944disease-phenotype-ishbiolink:has_phenotypeedges withprimary=infores:orphanetand HPOA/Monarch aggregation.6,550OMIM Gene-Diseasebiolink:causesedges withprimary=infores:monarchinitiativeandprovided_by=omim_gene_to_disease_edges.601OMIM Gene-Diseasebiolink:contributes_toedges withprimary=infores:monarchinitiativeandprovided_by=omim_gene_to_disease_edges.Current-source smoke parses from the direct loaders produce:
575,345biolink:has_phenotypeedges total.263,480edges by raw prefix pairOMIM->HP,ORPHA->HP, andDECIPHER->HP.311,865NCBIGene->HProws;255,797uniqueNCBIGene/HPpairs before preserving disease context.7,661NCBIGene->OMIMbiolink:gene_associated_with_conditionedges.7,940HGNC->ORPHAbiolink:gene_associated_with_conditionedges.590,946edges.Relative to the inspected current aggregate Monarch/HPOA counts, this replaces about
440,818Monarch-mediated phenotype edges with575,345direct HPOA phenotype edges, replaces7,151Monarch-projected OMIM Gene-Disease edges with7,661direct OMIM Gene-Disease edges, and adds7,940direct Orphanet Gene-Disease edges before graph merge/normalization effects.Validation
uv run pytestpassed:162 passed.scripts/compare_hpoa_rationalization.pywas run against the smoke outputs and reports counts by source, predicate, primary source, supporting source, aggregator source, prefix pair, and edge family.Notes
MONDOPropertiescompatibility fix for the installedpyoxigraphAPI so default graph-spec loading can import all registered source classes during tests.