Utilizing OWL ontologies with imports

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

Utilizing OWL ontologies with imports

Tiffany Callahan
Hi-

This is a really great library! I would like to use it to build a knowledge graph. To do this, I need to merge several OWL ontologies. Specifically, I need to be able to load in the version of the OWL ontologies with imports (I have obtained this version of the ontology from OWLTools). While I can load in an OWL file and specify a namespace without any problem, I am unable to access or manipulate any of the classes of that ontology. For example, when trying to return the number of classes in the hp.owl (+imports) file I get the following error:

"Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-17-e5414e93c0a7>", line 1, in <module>
    len(list(hp.classes()))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 130, in classes
    if not s.startswith("_"): yield self.world._get_by_storid(s)
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in _get_by_storid
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in <genexpr>
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 662, in _parse_bnode
    raise ValueError("Cannot parse blank node %s: unknown node type!" % bnode)
ValueError: Cannot parse blank node _Ai: unknown node type!"


When trying to return the number of classes in the doid.owl (+imports) file I get the following error:
"Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-18-9b22e22cd56e>", line 1, in <module>
    len(list(doid.classes()))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 130, in classes
    if not s.startswith("_"): yield self.world._get_by_storid(s)
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  [Previous line repeated 2981 more times]
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 297, in _get_by_storid
    with LOADING:
RecursionError: maximum recursion depth exceeded"


I searched the documentation as well as Google, but am unable to find a good solution. I apologize in advance if I missed something obvious. Has anyone else experienced this issue before? Is there solution for getting around this issue?

Thank you very much for your help!

-Tiffany
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Jiba
Administrator
Hi,

Could you send me the ontology (or an extract of it) in order to try ?

The first error (Cannot parse blank node) means that Owlready has encountered a type of blank node that it does not know (but it does not say what type). The second error is probably caused by the first one.

Best regards,
Jean-Baptiste Lamy
MCF, LIMICS, Université Paris 13

> Hi-
>
> This is a really great library! I would like to use it to build a knowledge
> graph. To do this, I need to merge several OWL ontologies. Specifically, I
> need to be able to load in the version of the OWL ontologies with imports (I
> have obtained this version of the ontology from OWLTools). While I can load
> in an OWL file and specify a namespace without any problem, I am unable to
> access or manipulate any of the classes of that ontology. For example, when
> trying to return the number of classes in the hp.owl (+imports) file I get
> the following error:
>
> "Traceback (most recent call last):
>   File
> "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py",
> line 2910, in run_code
>     exec(code_obj, self.user_global_ns, self.user_ns)
>   File "<ipython-input-17-e5414e93c0a7>", line 1, in <module>
>     len(list(hp.classes()))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 130, in classes
>     if not s.startswith("_"): yield self.world._get_by_storid(s)
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 321, in _get_by_storid
>     else:                   is_a_entities.append(self._get_by_storid(obj,
> None, ThingClass, main_onto))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 368, in _get_by_storid
>     list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in
> is_a_bnodes))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 368, in <genexpr>
>     list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in
> is_a_bnodes))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 662, in _parse_bnode
>     raise ValueError("Cannot parse blank node %s: unknown node type!" %
> bnode)
> ValueError: Cannot parse blank node _Ai: unknown node type!"
>
>
> When trying to return the number of classes in the doid.owl (+imports) file
> I get the following error:
> "Traceback (most recent call last):
>   File
> "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py",
> line 2910, in run_code
>     exec(code_obj, self.user_global_ns, self.user_ns)
>   File "<ipython-input-18-9b22e22cd56e>", line 1, in <module>
>     len(list(doid.classes()))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 130, in classes
>     if not s.startswith("_"): yield self.world._get_by_storid(s)
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 321, in _get_by_storid
>     else:                   is_a_entities.append(self._get_by_storid(obj,
> None, ThingClass, main_onto))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 321, in _get_by_storid
>     else:                   is_a_entities.append(self._get_by_storid(obj,
> None, ThingClass, main_onto))
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 321, in _get_by_storid
>     else:                   is_a_entities.append(self._get_by_storid(obj,
> None, ThingClass, main_onto))
>   [Previous line repeated 2981 more times]
>   File
> "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py",
> line 297, in _get_by_storid
>     with LOADING:
> RecursionError: maximum recursion depth exceeded"
>
>
> I searched the documentation as well as Google, but am unable to find a good
> solution. I apologize in advance if I missed something obvious. Has anyone
> else experienced this issue before? Is there solution for getting around
> this issue?
>
> Thank you very much for your help!
>
> -Tiffany
>
>
>
> _______________________________________________
> If you reply to this email, your message will be added to the discussion below:
> http://owlready.8326.n8.nabble.com/Utilizing-OWL-ontologies-with-imports-tp32.html
> To start a new topic under Owlready, email [hidden email]
> To unsubscribe from Owlready, visit
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Tiffany Callahan
Jiba-

Thank you very much for your quick response and willingness to help me solve this problem. I have sent you the two ontologies that I referenced in my initial post to the email address that you have listed in the OWLready2 documentation. If there is a better place I should send it to, please let me know.


Best-

Tiffany
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Jiba
Administrator
Hi,

I have investigated the two files you sent me. For doid_with_imports.owl, I managed to load all classes without problem.

Fof hp_with_imports.owl I got a "RecursionError". The error is caused by the two classes NCIT_C3263 and NCIT_C3431, which are a subclass of each other (= NCIT_C3263 is a subclass of NCIT_C3431, and NCIT_C3431 is a subclass of NCIT_C3263). See the following OWL extracts:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/NCIT_C3263">
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3262"/>
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3431"/>
  [...]
  <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Neoplasm by Site</rdfs:label>
</owl:Class>


<owl:Class rdf:about="http://purl.obolibrary.org/obo/NCIT_C3431">
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3263"/>
  <obo:IAO_0000115 rdf:datatype="http://www.w3.org/2001/XMLSchema#string">
    A benign or malignant, primary or metastatic neoplasm involving the urinary system. --2003
  </obo:IAO_0000115>
  [...]
  <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Urinary System Neoplasm</rdfs:label>
</owl:Class>

This is clearly an error in the ontology: Neoplasm by Site (NCIT_C3263) should not be a subclass of Urinary System Neoplasm (NCIT_C3431).
I'm not sure whether the error is present in the original ontology (NCBI thesaurus, I believe) or caused by OWLTools when adding imports.

By the way, if the imported ontologies are declared in OWL files, Owlready is normally able to resolve them, either from Internet or from a local cache directory.

Currently, Owlready does not support recursive subclass of, because it is not supported by Python classes. I a wondering whether I should add some mechanism for detecting those recursive subclass of and ignore them, or not...

Best regards,
Jean-Baptiste Lamy
MCF, LIMICS, Université Paris 13
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Tiffany Callahan
Hi Jiba-

That’s a very interesting finding about the HP ontology. In the original hp.owl file (without imports, snippet shown below), NCIT_C3263 is shown as a subClassOf NCIT_C3431, but NCIT_C3431 is not listed as having any subclasses:


    <rdf:Description rdf:about="http://purl.obolibrary.org/obo/NCIT_C3263">
        <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3431"/>
    </rdf:Description> 


I then went and looked into the NCIT ontology (http://www.ontobee.org/ontology/NCIT) and found the following:

Class Hierarchy
• Thing
• + Disease, Disorder or Finding
• + Disease or Disorder
• + Neoplasm —> NCIT_C3262
• + Neoplasm by Morphology
• + Neoplasm by Special Category
• - Neoplasm by Site —> NCIT_C3263
• + Breast Neoplasm
• + Endocrine Neoplasm
• + Eye Neoplasm
• + Digestive System Neoplasm
• + Head and Neck Neoplasm
• + Nervous System Neoplasm
• + Respiratory Tract Neoplasm
• + Skin Neoplasm
• + Thoracic Neoplasm
• + Urinary System Neoplasm —> NCIT_C3431
• + Hematopoietic and Lymphoid System Neoplasm


So here, we see that NCIT_C3263 is subClassOf NCIT_C3262 and NCIT_C3431 is subClassOf NCIT_C3263. Assuming that Ontobee is correct, then it would appear that the error is in the HP ontology (NCIT_C3263 is NOT a subClassOf NCIT_C3431), just like you suggested and the second entry you showed of NCIT_C3431 being the subClassOf NCIT_C3263, is actually correct. I am happy to report this error to the HP repo, essentially providing this information to them. Is that OK with you if I mention our conversation in finding the error?

I also can now read in the classes for DOID. However, if I first had read in the hp+imports, inspect the classes, and produced the RecursionError, I have to restart my Python console. If I don’t restart it, I get the RecursionError when inspecting the classes of doid and go, ontologies that worked fine before running into the hp problem. Should a restart be required in this case? Just in case it is helpful, here is the code that I use when reading in the ontologies:

# set path to directory storing OWL files
onto_path.append("./resources/ontologies/")

# read in ontologies
hp = get_ontology("hp_with_imports.owl").load()

go = get_ontology("go_with_imports.owl").load()
doid = get_ontology("doid_with_imports.owl").load()

# specify namespace for ontologies
obo = hp.get_namespace("http://purl.obolibrary.org/obo/")
obo = go.get_namespace("http://purl.obolibrary.org/obo/")
obo = doid.get_namespace("http://purl.obolibrary.org/obo/")

I was not aware Python classes did not support recursive subclass of functionality, could it not be done using something like this (taken from: https://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-class-given-its-name)?:

def get_all_subclasses(cls):
    all_subclasses = []

    for subclass in cls.__subclasses__():
        all_subclasses.append(subclass)
        all_subclasses.extend(get_all_subclasses(subclass))

    return all_subclasses

I have played around with the other ways of reading in the ontologies and was using the method that read them in from the URL until I decided that I also wanted to include the imports. 


Best-

Tiffany



On Nov 3, 2017, at 4:37 PM, Jiba [via Owlready] <[hidden email]> wrote:

Hi,

I have investigated the two files you sent me. For doid_with_imports.owl, I managed to load all classes without problem.

Fof hp_with_imports.owl I got a "RecursionError". The error is caused by the two classes NCIT_C3263 and NCIT_C3431, which are a subclass of each other (= NCIT_C3263 is a subclass of NCIT_C3431, and NCIT_C3431 is a subclass of NCIT_C3263). See the following OWL extracts:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/NCIT_C3263">
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3262"/>
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3431"/>
  [...]
  <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Neoplasm by Site</rdfs:label>
</owl:Class>


<owl:Class rdf:about="http://purl.obolibrary.org/obo/NCIT_C3431">
  <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/NCIT_C3263"/>
  <obo:IAO_0000115 rdf:datatype="http://www.w3.org/2001/XMLSchema#string">
    A benign or malignant, primary or metastatic neoplasm involving the urinary system. --2003
  </obo:IAO_0000115>
  [...]
  <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Urinary System Neoplasm</rdfs:label>
</owl:Class>

This is clearly an error in the ontology: Neoplasm by Site (NCIT_C3263) should not be a subclass of Urinary System Neoplasm (NCIT_C3431).
I'm not sure whether the error is present in the original ontology (NCBI thesaurus, I believe) or caused by OWLTools when adding imports.

By the way, if the imported ontologies are declared in OWL files, Owlready is normally able to resolve them, either from Internet or from a local cache directory.

Currently, Owlready does not support recursive subclass of, because it is not supported by Python classes. I a wondering whether I should add some mechanism for detecting those recursive subclass of and ignore them, or not...

Best regards,
Jean-Baptiste Lamy
MCF, LIMICS, Université Paris 13



If you reply to this email, your message will be added to the discussion below:
http://owlready.8326.n8.nabble.com/Utilizing-OWL-ontologies-with-imports-tp32p35.html
To unsubscribe from Utilizing OWL ontologies with imports, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Jiba
Administrator
Hi Tiffany,

> I am happy to report this error to the HP repo, essentially providing this information to them. Is that OK with you if I mention our conversation in finding the error?

Yes, no problem!


> I also can now read in the classes for DOID. However, if I first had read in the hp+imports, inspect the classes, and produced the RecursionError, I have to restart my Python console. If I don’t restart it, I get the RecursionError when inspecting the classes of doid and go, ontologies that worked fine before running into the hp problem. Should a restart be required in this case? Just in case it is helpful, here is the code that I use when reading in the ontologies:
>
> # set path to directory storing OWL files
> onto_path.append("./resources/ontologies/")
>
> # read in ontologies
> hp = get_ontology("hp_with_imports.owl").load()
> go = get_ontology("go_with_imports.owl").load()
> doid = get_ontology("doid_with_imports.owl").load()
>
> # specify namespace for ontologies
> obo = hp.get_namespace("http://purl.obolibrary.org/obo/")
> obo = go.get_namespace("http://purl.obolibrary.org/obo/")
> obo = doid.get_namespace("http://purl.obolibrary.org/obo/")

I have fixed manually the NCIT_C3263 - NCIT_C3431 problem (by removing one of the subclass of), and then I have loaded both ontologies. I also get a RecursionError, for the same reason: there are two classes that are a subclass of each other: HP_0000140 and HP_0000858.
This time, the problem is more complex because one of the "subclass of" relation is in the HP ontology, and the other in the DOID ontology. Thus, you can load one of them without problem, but is you load both, you obtain the RecursionError.

In hp_without_imports.owl we have:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/HP_0000140">
        <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/HP_0000858"/>
        <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Abnormality of the menstrual cycle</rdfs:label>
        [...]
</owl:Class>

and in doid_with_imports.owl:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/HP_0000858">
        <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/HP_0000140"/>
        <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Menstrual irregularities</rdfs:label>
        [...]
</owl:Class>

In this case, I am not sure whether it is an error or whether it should be interpreter as an equivalence. Abnormality might be considered as more general than irregularities (e.g. an abnormally long period is not timely irregular).

You are not the first one to report difficulties for loading ontologies with cyclic subclass of. I think I will include some kind of support for that in Owlready, and I will display some warning in those situations.


> I was not aware Python classes did not support recursive subclass of functionality, could it not be done using something like this (taken from: https://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-class-given-its-name <https://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-class-given-its-name>)?:
>
> def get_all_subclasses(cls):
>     all_subclasses = []
>
>     for subclass in cls.__subclasses__():
>         all_subclasses.append(subclass)
>         all_subclasses.extend(get_all_subclasses(subclass))
>
>     return all_subclasses

You're right for listing subclasses recursively. But I was not clear when speaking about "recursive subclass"; cyclic subclasses is a better wording. What I mean is a class A that is a subclass of B, while at the same time, B is a subclass of A. No object oriented programming language supports that.

Best regards,
Jiba
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Tiffany Callahan
Hi Jiba-

I now understand what you mean about python not being able to handle cyclical subclassing, tI am sorry I misunderstood your original email. I think adding a mechanism to check for this is a great idea! Will your change to the code just ignore the subclasses that are wrong or will it print the erroneous subclass so that the user could fix the ontology? I know this is unsolicited, but from my perspective, if there was a way to be altered of these cyclical subclasses so that we could make changes to the ontology, that would be great! I would hate to loose any potential class, or connections between them.

Last small question, I am still getting a warning about a blank node in hp_with_imports.owl. If I run the same command three times I can eventually get the number of classes to be returned. See code below. How do I identify what nodes are blank? I looked at the ontology in Protégé and am unable to find any blank nodes. I am not sure what I am missing.

onto_path.append("./resources/ontologies/") #go
hp = get_ontology("hp_with_imports.owl").load()
obo = hp.get_namespace("http://purl.obolibrary.org/obo/")
len(list(hp.classes()))

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-6-e5414e93c0a7>", line 1, in <module>
    len(list(hp.classes()))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 130, in classes
    if not s.startswith("_"): yield self.world._get_by_storid(s)
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in _get_by_storid
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in <genexpr>
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 662, in _parse_bnode
    raise ValueError("Cannot parse blank node %s: unknown node type!" % bnode)
ValueError: Cannot parse blank node _jxa: unknown node type!

len(list(hp.classes()))

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/IPython/core/interactiveshell.py", line 2910, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-7-e5414e93c0a7>", line 1, in <module>
    len(list(hp.classes()))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 130, in classes
    if not s.startswith("_"): yield self.world._get_by_storid(s)
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 321, in _get_by_storid
    else:                   is_a_entities.append(self._get_by_storid(obj, None, ThingClass, main_onto))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in _get_by_storid
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 368, in <genexpr>
    list.extend(entity.is_a, (onto._parse_bnode(bnode) for onto, bnode in is_a_bnodes))
  File "/Users/tiffanycallahan/Library/Python/3.6/lib/python/site-packages/owlready2/namespace.py", line 662, in _parse_bnode
    raise ValueError("Cannot parse blank node %s: unknown node type!" % bnode)
ValueError: Cannot parse blank node _B4: unknown node type!

len(list(hp.classes()))
Out[8]: 32044

In investigating the second issue that you identified, I still think that the error still might be occurring in the hp, but you are right, it is a bit more complicated. To get by now, I can adjust the doid_with_imports.owl file so that it includes the correct parent for HP_0000858, which is HP_0008373, not HP_0000140 as currently shown. Making this change fixes the recursion error and I am able to use the ontology. How were you able to identify which classes were causing the recursion problem? I would love to be able to detect these kinds of things on my own in the future and/or to be able to verify the ontologies. I will submit an issue listing both of the errors we sorted through to the HP and will let them know what we are seeing with the doid file when importing ontologies form OWLTools. I will be sure to list you in this error report so you are tied and get credit for this as well. 

I was really excited when I found your library. The OWLAPI is great, but I prefer to use Python when given a choice, over Java. Thank you for building this and for being so helpful and responsive. I hope to make your library an integral part of my system architecture and will be presenting about it in my lab this week as well as at a conference in early December.


Best-

Tiffany



On Nov 4, 2017, at 3:07 AM, Jiba [via Owlready] <[hidden email]> wrote:

Hi Tiffany,

> I am happy to report this error to the HP repo, essentially providing this information to them. Is that OK with you if I mention our conversation in finding the error?

Yes, no problem!


> I also can now read in the classes for DOID. However, if I first had read in the hp+imports, inspect the classes, and produced the RecursionError, I have to restart my Python console. If I don’t restart it, I get the RecursionError when inspecting the classes of doid and go, ontologies that worked fine before running into the hp problem. Should a restart be required in this case? Just in case it is helpful, here is the code that I use when reading in the ontologies:
>
> # set path to directory storing OWL files
> onto_path.append("./resources/ontologies/")
>
> # read in ontologies
> hp = get_ontology("hp_with_imports.owl").load()
> go = get_ontology("go_with_imports.owl").load()
> doid = get_ontology("doid_with_imports.owl").load()
>
> # specify namespace for ontologies
> obo = hp.get_namespace("http://purl.obolibrary.org/obo/")
> obo = go.get_namespace("http://purl.obolibrary.org/obo/")
> obo = doid.get_namespace("http://purl.obolibrary.org/obo/")
I have fixed manually the NCIT_C3263 - NCIT_C3431 problem (by removing one of the subclass of), and then I have loaded both ontologies. I also get a RecursionError, for the same reason: there are two classes that are a subclass of each other: HP_0000140 and HP_0000858.
This time, the problem is more complex because one of the "subclass of" relation is in the HP ontology, and the other in the DOID ontology. Thus, you can load one of them without problem, but is you load both, you obtain the RecursionError.

In hp_without_imports.owl we have:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/HP_0000140">
        <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/HP_0000858"/>
        <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Abnormality of the menstrual cycle</rdfs:label>
        [...]
</owl:Class>

and in doid_with_imports.owl:

<owl:Class rdf:about="http://purl.obolibrary.org/obo/HP_0000858">
        <rdfs:subClassOf rdf:resource="http://purl.obolibrary.org/obo/HP_0000140"/>
        <rdfs:label rdf:datatype="http://www.w3.org/2001/XMLSchema#string">Menstrual irregularities</rdfs:label>
        [...]
</owl:Class>

In this case, I am not sure whether it is an error or whether it should be interpreter as an equivalence. Abnormality might be considered as more general than irregularities (e.g. an abnormally long period is not timely irregular).

You are not the first one to report difficulties for loading ontologies with cyclic subclass of. I think I will include some kind of support for that in Owlready, and I will display some warning in those situations.


> I was not aware Python classes did not support recursive subclass of functionality, could it not be done using something like this (taken from: https://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-class-given-its-name <https://stackoverflow.com/questions/3862310/how-can-i-find-all-subclasses-of-a-class-given-its-name>)?:
>
> def get_all_subclasses(cls):
>     all_subclasses = []
>
>     for subclass in cls.__subclasses__():
>         all_subclasses.append(subclass)
>         all_subclasses.extend(get_all_subclasses(subclass))
>
>     return all_subclasses
You're right for listing subclasses recursively. But I was not clear when speaking about "recursive subclass"; cyclic subclasses is a better wording. What I mean is a class A that is a subclass of B, while at the same time, B is a subclass of A. No object oriented programming language supports that.

Best regards,
Jiba



If you reply to this email, your message will be added to the discussion below:
http://owlready.8326.n8.nabble.com/Utilizing-OWL-ontologies-with-imports-tp32p37.html
To unsubscribe from Utilizing OWL ontologies with imports, click here.
NAML

Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Jiba
Administrator
Hi Tiffany,

To detect the problems and show the name of the classes involved, I add some prints in Owlready source code. This is not easy to do. I've now added in Bitbucket a warning mechanism for cyclic subclasses, and Owlready now ignores them. When tested on DOID, several cyclic subclasses are detected. I've also improved the error message for the "unknown blank node" error; it now shows the RDF triples involving the blank node.

Thank you for your support on Owlready,

Best regards,
Jiba
Reply | Threaded
Open this post in threaded view
|

Re: Utilizing OWL ontologies with imports

Tiffany Callahan
Hi Jiba-

Sorry to not respond sooner. Thank you for the clarification and the update. I really appreciate all of your help again.


Best-

Tiffany

On Nov 6, 2017, at 4:26 AM, Jiba [via Owlready] <[hidden email]> wrote:

Hi Tiffany,

To detect the problems and show the name of the classes involved, I add some prints in Owlready source code. This is not easy to do. I've now added in Bitbucket a warning mechanism for cyclic subclasses, and Owlready now ignores them. When tested on DOID, several cyclic subclasses are detected. I've also improved the error message for the "unknown blank node" error; it now shows the RDF triples involving the blank node.

Thank you for your support on Owlready,

Best regards,
Jiba


If you reply to this email, your message will be added to the discussion below:
http://owlready.8326.n8.nabble.com/Utilizing-OWL-ontologies-with-imports-tp32p39.html
To unsubscribe from Utilizing OWL ontologies with imports, click here.
NAML