Skip to content

Relationship extraction is limited to a hard-coded set of OBO properties in one axiom shape #38

Description

@matthewhorridge

Summary

The wrapper only extracts class relationships for a hard-coded set of OBO properties in a single flat axiom shape. Relationships on any other property, and those stated in other (equivalent) ways, are silently dropped, so they never appear in a class's property listing (the Details view). Users have asked why some relationships show up on a class and others do not; this is the cause.

What "relationship extraction" is

The wrapper parses an ontology and emits a normalized RDF/XML export for BioPortal. Part of that job is deriving binary relationships between a named class A and a filler B from the logical axioms that mention A — chiefly SubClassOf and EquivalentClasses axioms whose right-hand side is (or contains) an existential restriction such as p some B. Each derived relationship is re-expressed as a ground triple A p B: an owl:AnnotationAssertion whose predicate is the object property's IRI (punned as an annotation property) and whose subject and object are the two class IRIs. BioPortal's backend reads these annotation assertions off each class, which is what makes a relationship appear in a class's property listing (the Details view) and, for OBO ontologies via a treeView predicate, in its tree hierarchy. This logic lives in OntologyParser.generateGroundTriplesForAxioms.

What the current code does

A relationship is emitted only if all of these hold:

  1. the axiom is exactly SubClassOf(NamedClass, ObjectSomeValuesFrom(P, D)) — no intersections, no equivalences, no hasValue, no cardinality;
  2. P and D are named;
  3. P's IRI contains the substring "obo".

Among those, three fates:

  • Whitelisted (part_of/BFO_0000050, contains/RO_0001019, develops_from/RO_0002202) → a special metadata/obo/* annotation plus a treeView hierarchy edge.
  • OBO but not whitelisted → a plain annotation under the property's own IRI, no treeView.
  • Everything else — non-OBO property, anonymous filler, or any shape other than the flat SubClassOf + someValuesFrom — silently dropped.

Why relationships go missing in the Details view

The Details view is driven by Class#properties in ontologies_linked_data, which surfaces essentially all predicate→value assertions on a class (it is not gated on OBO). So a class shows whatever relationship triples the wrapper emitted for it — and the wrapper only emits for OBO-namespace properties in the one flat shape. Two consequences:

  • Non-OBO properties are entirely invisible. EDAM has 580 someValuesFrom relationships on has_topic, has_output, has_input, etc. (under edamontology.org, not OBO). Parsing EDAM with the current code emits zero relationship triples (0 metadata/obo/*, 0 treeView). None appear in the Details view.
  • Even within OBO, coverage is uneven. On UBERON the current code exposes ~3 relation types (part_of, develops_from, contains) and drops the rest — because they either are not whitelisted or are stated in a shape the extractor does not recognize (nested in an intersection, via an equivalence, etc.).

That unevenness — the same modelling construct getting a different fate, decided by a substring check and a hard-coded list — is exactly "why does relationship X show up but not Y?"

History (for context)

All formative work is by msalvadores; the timeline below is taken from the commits.

  • Only part_of was handled, and it was turned into a subclass edge. If a class had part_of some D (matched by the substring part_of), the code synthesized a real SubClassOf(A, D) axiom and added a metadata/part_of annotation. One property; part_of was effectively flattened into the class hierarchy. (5fee83e, 2013-09-14, NCBO-120)
  • The property set was fixed and the matching tightened. Substring matching was replaced by exact endsWith on a whitelist; contains/RO_0001019 and develops_from/RO_0002202 were added; the emitted IRIs moved into the metadata/obo/… namespace still used today. (356b573, 2013-09-27)
  • BFO's part_of IRI was added as a synonym for the shorthand. BFO_0000050 was matched alongside part_of. (e4dc494, 2013-09-27)
  • A treeView annotation was tried in place of the synthetic subclass, then abandoned. Three commits introduced it, then all three were reverted two weeks later (Dec 2, 2013).
  • The current form was settled: the logic was extracted into its own method and treeView reinstated. Each whitelisted relation emits an obo/* annotation plus a paired treeView edge; the synthetic subclass was dropped. (d6b43b2, 2015-01-09, NCBO-1152)
  • No change to the logic since, only a 2022 package rename. It has not changed in a decade.

It is worth remembering the context. In 2013–2015 the relationship between the OBO format and OWL was still being pinned down — the shorthand relation names (part_of), their full IRIs (BFO_0000050), and how OBO stanzas map onto OWL axioms were not as cleanly and consistently defined as they are today. The IRI substring checks and the shorthand-versus-IRI matching read as reasonable pragmatism against that moving target. That mapping is now well specified and stable, so those heuristics are no longer necessary — the relationships can be read directly from the OWL axioms.

Proposed fix

Extract relationships uniformly, for any object property, by walking the class expression:

  • No privilege: drop the contains("obo") gate and the hard-coded whitelist; emit each relationship under the property's own IRI.
  • Walk both SubClassOf(A, …) and EquivalentClasses(A, …) of named classes, descending into intersection operands, and emit A --p--> filler for someValuesFrom(p, namedClass), hasValue(p, individual), and min/exact cardinality (n ≥ 1). Also expand an intersection filler, so p some (B and C) yields A p B and A p C.
  • Do not descend into unions or complements (their operands are not entailed for every instance of A), and do not emit allValuesFrom (a constraint, not an existential relationship).
  • Once the above is in place, the legacy metadata/obo/* relationship annotations become redundant duplicates and can be removed, keeping only the treeView edges that drive the OBO hierarchy.

Impact, measured

Ontology Before After
EDAM has_topic / has_output / has_input: 0 207 / 147 / 56
UBERON ~3 relation types ~180 relation types (tens of thousands of assertions)

UBERON now surfaces has part, regulates / positively / negatively regulates, occurs in, in taxon, capable of, the BSPO spatial relations, and UBERON's own connectivity relations (channel_for, extends_fibers_into, subdivision_of, sexually_homologous_to, …). Parse time is unchanged (~13s on the 96 MB file).

Still open / follow-ups

  • The treeView / hierarchy path is still OBO-only and whitelist-based. Broadening it changes the class tree and is deferred pending a decision plus downstream tree testing.
  • Removing the legacy metadata/obo/* relationship annotations requires a coordinated update to the ontologies_linked_data test test_obo_part_of, which asserts obo/part_of (the treeView assertion is unchanged); no production code reads those predicates.
  • The BioPortal Details view should be revisited once the extraction change is merged: a sensible ordering for the now-larger relationship set (see When displaying properties of a class, sort them alphabetically  bioportal_web_ui#123), and confirming no duplicate rendering.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions