ontodev / robot

ROBOT is an OBO Tool
http://robot.obolibrary.org
BSD 3-Clause "New" or "Revised" License
260 stars 74 forks source link

Bug?: Obographs: Complex~ axiom restriction converted to `null` #1079

Closed joeflack4 closed 1 year ago

joeflack4 commented 1 year ago

Overview

I am converting an OWL file to Obographs JSON. I was then using that JSON for something else, and I encountered an error because null was not anticipated. I'm not sure if this is (a) a bug, (b) a case of something in OWL that is not supported by Obographs / intended not to be serialized, and therefore null is intended here, (c) intended by robot for some other reason.

Command

robot convert -i INPUT_OWL_PATH -o OUTPUT_OBOGRAPHS_PATH --format json

Input

Snippet of the hpo.owl where the source of null came from. Namely, it is a case of an owl:Restriction within another owl:Restriction.

Sub-snippet:

                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
                        <owl:someValuesFrom>
                            <owl:Restriction>
                                <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000050"/>
                                <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0009768"/>
                            </owl:Restriction>
                        </owl:someValuesFrom>
                    </owl:Restriction>

The full axiom:

    <owl:Axiom>
        <owl:annotatedSource rdf:resource="http://purl.obolibrary.org/obo/UBERON_0009551"/>
        <owl:annotatedProperty rdf:resource="http://www.w3.org/2002/07/owl#equivalentClass"/>
        <owl:annotatedTarget>
            <owl:Class>
                <owl:intersectionOf rdf:parseType="Collection">
                    <rdf:Description rdf:about="http://purl.obolibrary.org/obo/UBERON_0002529"/>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000050"/>
                        <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0002544"/>
                    </owl:Restriction>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
                        <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0004300"/>
                    </owl:Restriction>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
                        <owl:someValuesFrom>
                            <owl:Restriction>
                                <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000050"/>
                                <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0009768"/>
                            </owl:Restriction>
                        </owl:someValuesFrom>
                    </owl:Restriction>
                </owl:intersectionOf>
            </owl:Class>
        </owl:annotatedTarget>
        <oboInOwl:source>cjm</oboInOwl:source>
    </owl:Axiom>

Output

Within logicalDefinitionAxioms. The case of owl:Restriction within another owl:Restriction is null here:

    {
      "definedClassId" : "http://purl.obolibrary.org/obo/UBERON_0009551",
      "genusIds" : [ "http://purl.obolibrary.org/obo/UBERON_0002529" ],
      "restrictions" : [ {
        "propertyId" : "http://purl.obolibrary.org/obo/BFO_0000050",
        "fillerId" : "http://purl.obolibrary.org/obo/UBERON_0002544"
      }, {
        "propertyId" : "http://purl.obolibrary.org/obo/BFO_0000051",
        "fillerId" : "http://purl.obolibrary.org/obo/UBERON_0004300"
      }, null ]
    }

Related

matentzn commented 1 year ago

Not a ROBOT issue, can you post the comment here instead? The issue is not identifical but closely related. When you moved your comment, please close this issue here. :)

joeflack4 commented 1 year ago

@matentzn Thanks Nico! Assuming the nested owl:Restrictions issue is fixed, I don't have any problem with the rest of the genusId information. But excluding it from Obographs would fix my problem as well. It's a little lossy, but I honestly don't know if people will ever notice that when consuming this content in FHIR, which is my ultimate goal.

julesjacobsen commented 1 year ago

@joeflack4 what version of robot is this happening with?

Testing using obographs 0.3.0:

Given

<?xml version="1.0"?>
<rdf:RDF xmlns="http://purl.obolibrary.org/obo/uberon.owl#"
     xml:base="http://purl.obolibrary.org/obo/uberon.owl"
     xmlns:obo="http://purl.obolibrary.org/obo/"
     xmlns:oboInOwl="http://www.geneontology.org/formats/oboInOwl#"
     xmlns:owl="http://www.w3.org/2002/07/owl#"
     xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
    <owl:Ontology rdf:about="http://purl.obolibrary.org/obo/uberon.owl">
        <owl:versionIRI rdf:resource="http://purl.obolibrary.org/obo/uberon/releases/2022-12-13/uberon.owl"/>
    </owl:Ontology>

<owl:Axiom>
        <owl:annotatedSource rdf:resource="http://purl.obolibrary.org/obo/UBERON_0009551"/>
        <owl:annotatedProperty rdf:resource="http://www.w3.org/2002/07/owl#equivalentClass"/>
        <owl:annotatedTarget>
            <owl:Class>
                <owl:intersectionOf rdf:parseType="Collection">
                    <rdf:Description rdf:about="http://purl.obolibrary.org/obo/UBERON_0002529"/>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000050"/>
                        <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0002544"/>
                    </owl:Restriction>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
                        <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0004300"/>
                    </owl:Restriction>
                    <owl:Restriction>
                        <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000051"/>
                        <owl:someValuesFrom>
                            <owl:Restriction>
                                <owl:onProperty rdf:resource="http://purl.obolibrary.org/obo/BFO_0000050"/>
                                <owl:someValuesFrom rdf:resource="http://purl.obolibrary.org/obo/UBERON_0009768"/>
                            </owl:Restriction>
                        </owl:someValuesFrom>
                    </owl:Restriction>
                </owl:intersectionOf>
            </owl:Class>
        </owl:annotatedTarget>
        <oboInOwl:source>cjm</oboInOwl:source>
    </owl:Axiom>
</rdf:RDF>

when converted to JSON using

OWLOntologyManager m = OWLManager.createOWLOntologyManager();
OWLOntology ontology = m.loadOntologyFromOntologyDocument(new ByteArrayInputStream(axiom.getBytes(StandardCharsets.UTF_8)));
GraphDocument graphDocument = new FromOwl().generateGraphDocument(ontology);
System.out.println(OgJsonGenerator.render(graphDocument));

gives me

{
  "graphs" : [ {
    "id" : "http://purl.obolibrary.org/obo/uberon.owl",
    "meta" : {
      "version" : "http://purl.obolibrary.org/obo/uberon/releases/2022-12-13/uberon.owl"
    },
    "logicalDefinitionAxioms" : [ {
      "definedClassId" : "http://purl.obolibrary.org/obo/UBERON_0009551",
      "genusIds" : [ "http://purl.obolibrary.org/obo/UBERON_0002529" ],
      "restrictions" : [ {
        "propertyId" : "http://purl.obolibrary.org/obo/BFO_0000050",
        "fillerId" : "http://purl.obolibrary.org/obo/UBERON_0002544"
      }, {
        "propertyId" : "http://purl.obolibrary.org/obo/BFO_0000051",
        "fillerId" : "http://purl.obolibrary.org/obo/UBERON_0004300"
      } ]
    } ]
  } ]
}
joeflack4 commented 1 year ago

Thanks for looking at this. I have ROBOT version 1.8.1. I thought I grabbed the newest version but looks like I did not. But I did this both in my CLI and bioontologies as well, I think. I could try this with the newer version, but we've sort of patched around this for now and I'm not sure if I'll get to it, but I'll add to my backlog.

I think Nico thought this was more a case of genusId restrictions than what I was initially saying.