diff --git a/config/schemes/ontology_submission.yml b/config/schemes/ontology_submission.yml index 75020204..944c6a3b 100644 --- a/config/schemes/ontology_submission.yml +++ b/config/schemes/ontology_submission.yml @@ -1410,6 +1410,17 @@ translationOfWork: extractedMetadata: true metadataMappings: [ "adms:translation", "schema:translationOfWork" ] +#Ontology root term(s) +hasOntologyRootTerm: + display: "relations" + label: "Ontology root term(s)" + helpText: "Class(es) the ontology declares as its display roots, used to start the class hierarchy below owl:Thing and upper-ontology terms." + example: 'http://purl.obolibrary.org/obo/CL_0000000' + description: [ + "IAO: Relates an ontology to a term that is a designated root term of the ontology; display tools can use these as the starting point when rendering the class hierarchy. There can be more than one." ] + extractedMetadata: true + metadataMappings: [ "obo_purl:IAO_0000700" ] + ### Content #Identifier pattern diff --git a/lib/ontologies_linked_data/models/ontology_submission.rb b/lib/ontologies_linked_data/models/ontology_submission.rb index f43ba5a8..3c35400b 100644 --- a/lib/ontologies_linked_data/models/ontology_submission.rb +++ b/lib/ontologies_linked_data/models/ontology_submission.rb @@ -147,6 +147,12 @@ class OntologySubmission < LinkedData::Models::Base attribute :usedBy, namespace: :voaf, type: %i[uri list] attribute :workTranslation, namespace: :schema, type: %i[uri list] attribute :translationOfWork, namespace: :schema, type: %i[uri list] + # Class(es) the ontology declares as display roots via IAO:0000700. No + # namespace: the source property has a numeric local name (IAO_0000700), so + # it is stored under the default :metadata namespace and read from the source + # IRI via metadataMappings in config/schemes/ontology_submission.yml (same + # pattern as obsoleteParent). + attribute :hasOntologyRootTerm, type: %i[list uri] # Content metadata attribute :uriRegexPattern, namespace: :void diff --git a/test/data/ontology_files/custom_root_terms.owl b/test/data/ontology_files/custom_root_terms.owl new file mode 100644 index 00000000..698958fa --- /dev/null +++ b/test/data/ontology_files/custom_root_terms.owl @@ -0,0 +1,48 @@ + + + + + + + + + +]> + + + + + + + + + + + + + + + class 1 + + + + + class 2 + + + + + class 3 + + diff --git a/test/models/test_ontology_submission.rb b/test/models/test_ontology_submission.rb index 3749b14b..9a35a7d9 100644 --- a/test/models/test_ontology_submission.rb +++ b/test/models/test_ontology_submission.rb @@ -308,6 +308,37 @@ def test_submission_parse assert_equal ['La première ontologie déddiée aux concepts de la médecine associée'], sub.notes end + # IAO:0000700 ("has ontology root term") declared on the ontology is extracted + # into the submission's hasOntologyRootTerm attribute (a list of class URIs). + def test_extract_ontology_root_terms + submission_parse("ROOTTERMS", "Root terms TEST", + "./test/data/ontology_files/custom_root_terms.owl", 1, + process_rdf: true, extract_metadata: true) + + sub = LinkedData::Models::OntologySubmission + .where(ontology: [acronym: "ROOTTERMS"], submissionId: 1) + .include(:hasOntologyRootTerm).first + refute_nil sub + + roots = Array(sub.hasOntologyRootTerm).map(&:to_s).sort + assert_equal ["http://bioportal.bioontology.org/ontologies/msotes#class1", + "http://bioportal.bioontology.org/ontologies/msotes#class2"], + roots + end + + # An ontology without IAO:0000700 leaves hasOntologyRootTerm empty (not an error). + def test_extract_ontology_root_terms_absent + submission_parse("NOROOTTERMS", "No root terms TEST", + "./test/data/ontology_files/custom_properties.owl", 1, + process_rdf: true, extract_metadata: true) + + sub = LinkedData::Models::OntologySubmission + .where(ontology: [acronym: "NOROOTTERMS"], submissionId: 1) + .include(:hasOntologyRootTerm).first + refute_nil sub + assert_empty Array(sub.hasOntologyRootTerm) + end + def test_generate_language_preflabels submission_parse("D3OTEST", "DSMZ Digital Diversity Ontology Test", "./test/data/ontology_files/d3o.owl", 1,