Skip to content

Support self-declared ontology roots#1330

Closed
gouttegd wants to merge 7 commits intomasterfrom
support-ontology-roots
Closed

Support self-declared ontology roots#1330
gouttegd wants to merge 7 commits intomasterfrom
support-ontology-roots

Conversation

@gouttegd
Copy link
Copy Markdown
Collaborator

@gouttegd gouttegd commented Mar 1, 2026

This PR adds support for ”self-declared” ontology roots: when an ontology contains http://purl.obolibrary.org/obo/IAO_0000700 annotations, the classes pointed by these annotations are used as the roots of the class hierarchy, instead of owl:Thing.

closes #1184

gouttegd added 3 commits March 1, 2026 18:50
Add a menu item, along with the corresponding support in the
ClassHierarchyPreferences, to display only the classes below the
ontology roots (if any) in the class hierarchy.
Even though the AssertedClassHierarchyProvider has a public `getRoots()`
method returning a set of OWL classes (suggesting there can be several
roots), the private code of the provider assumes that there can be only
one root (`owl:Thing`).

This will no longer always be the case when the "display from ontology
roots" option will be enabled, because an ontology may very well declare
more than one root (Uberon, for example, declares two roots). So we must
update the hierarchy provider so that it is ready to deal with a _set_
of roots instead of a single root.
Add a `setDisplayFromOntologyRoots(boolean)` method to the class
hierarchy provider. If called with true, it will attempt to find
self-declared roots in the ontology sets (declared with the IAO:0000700
annotation) and, in the presence of such roots, will use them as the
roots of the hierarchy.

All the DisplayHierarchyFromOntologyRootsAction then has to do is to
call this method whenever the action is performed.

closes #1184
@gouttegd gouttegd self-assigned this Mar 1, 2026
@cthoyt
Copy link
Copy Markdown
Contributor

cthoyt commented Mar 1, 2026

confirming this is working as expected for HGNC

before:

Screenshot 2026-03-01 at 22 03 05

after:

Screenshot 2026-03-01 at 22 02 28

@cthoyt
Copy link
Copy Markdown
Contributor

cthoyt commented Mar 1, 2026

I found some unexpected/surprising behavior. I was browsing a gene, then tried to navigate to a class that was declared as a child of something that isn't in any of the hierarchies of the roots, then I get an unexpected window

e.g., in HGNC, navigate to any gene, then click on the taxon (homo sapiens) or the chromosome in the "subclass of" logical axioms. Both the Homo sapiens class and all of the chromosome classes are not under any of the roots.

Screenshot 2026-03-01 at 22 10 17

then, it seems to get confused and doesn't show anything

Screenshot 2026-03-01 at 22 10 21

if I turn off the "Display from ontology roots" then the behavior returns to normal

@gouttegd
Copy link
Copy Markdown
Collaborator Author

gouttegd commented Mar 2, 2026

From @matentzn :

if you

  1. Load an ontology; select the feature
  2. Then load another ontology in the same window
  3. You still have the roots selected of the original ontology

I confirm the issue, and that’s definitely a bug.

Whenever the set of ontologies used by the ClassHierarchyProvider is
changed, the current set of roots should be refreshed, because we cannot
expect that the new set will always have the same roots as the previous
set -- that was the case previously when the only possible root was
`owl:Thing`, but now that we allow ontologies to declare their own
roots, the roots may be ontology-dependent.

Also fix a typo on the name of the `setDisplayFromOntologyRoots` method.
Copy link
Copy Markdown

@matentzn matentzn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the implementation looks great. My main concern at the moment (which is sort of also my problem why I did not ship faster) is thread safety - do we need to make the roots and displayFromOntologyRoots variables volatile so that all threads can see the variable in the exact same state at each time, or is this not a relevant issue for Protege architecture?

gouttegd added 3 commits March 3, 2026 14:35
`getOntologyRoots` does not, in fact, return the roots -- it fills the
given set object and returns a boolean indicating whether it found
self-declared roots or not. So we rename it to `findOntologyRoots` to
avoid needless confusion.
The `getRoots()` method used to return an _unmodifiable_ set containing
the roots used by the class hierarchy provider. It should still be doing
that.

To be clear: this is _not_ about thread-safety. This is about preserving
the existing contract of the `getRoots()` method. Callers of that method
expected to get an unmodifiable copy of the set of roots, so that's what
they should still get.
Wrap all the code within `setDisplayFromOntologyRoots` within a write
lock, to ensure that any thread trying to access either the `roots` set
or the `displayFromOntologyRoots` variable (from elsewhere in the class
hierarchy provider, where such access are already wrapped within a read
lock) would be blocked until we are done finding the roots.
@gouttegd
Copy link
Copy Markdown
Collaborator Author

gouttegd commented Mar 3, 2026

Closed in favour of #1332

@gouttegd gouttegd closed this Mar 3, 2026
@gouttegd gouttegd deleted the support-ontology-roots branch March 3, 2026 16:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for ontology hierarchy roots. (IAO:0000700)

3 participants