transfering classes, restrictions, etc. from one ontology to another one

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

transfering classes, restrictions, etc. from one ontology to another one

gp
Hello!

I have tried lately to make some transfer some data from one ontology to another one.  I first mireoted some terms from one ontology to include them in another one and now I would like to transfer some more properties, especially restrictions and the corresponding properties.

While handling different ontologies is easy, I was wondering how exactly to perform the transfer. Here is some toy code where I was trying to simply transfer some class, and then the associated restrictions.
from owlready2 import *

onto = get_ontology("http://test.org/onto.owl")
with onto:
     class Drug(Thing):
        pass
     class ActivePrinciple(Thing):
        pass
     class has_for_active_principle(Drug >> ActivePrinciple):
        pass
class NonPlaceboDrug(Drug):
    equivalent_to = [Drug & has_for_active_principle.some(ActivePrinciple)]
class someActivePrinciple(ActivePrinciple):
    pass
class MyDrug(Drug):
    has_for_active_principle = [someActivePrinciple]

# make onto2
onto2 = get_ontology("http://test.org/onto2.owl")
with onto2:
     class Drug2(Thing):
        pass
     class ActivePrinciple2(Thing):
        pass
     class has_for_active_principle2(Drug >> ActivePrinciple):
        pass

# Try to merge things
MyDrug = onto.MyDrug
onto2.MyDrug = MyDrug

onto.save(file = r"c:\temp\owlready.rdf", format = "rdfxml")
onto2.save(file = r"c:\temp\owlready2.rdf", format = "rdfxml")

The #Try to merge things is where things break. I tried several other approaches but had no luck. Any idea on how to transfer onto.MyDrug into onto2, and then its property restriction ?

BTW, I find the handling of these property restrictions (i.e. owl:equivalentClass, rdfs:subClassOf/owl:Restriction) especially elegant in owlready2!

Cheers,
Guillaume
gp
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

gp
Answering your own message looks lame but I came to the following solution which I would like to submit here for review, as it feels like the script is somehow abusing the system, in particular
owlready2.Restriction
 does not seem documented and I wonder if I make a proper use of it. Here is the script:

from owlready2 import *

world = World()
onto = world.get_ontology("http://test.org/onto.owl")

with onto:
    class Drug(Thing):
        pass
    class ActivePrinciple(Thing):
        pass
    class has_for_active_principle(Drug >> ActivePrinciple):
        pass
    class someActivePrinciple(ActivePrinciple):
        pass
    class MyDrug(Drug):
        has_for_active_principle = [someActivePrinciple] #this one has some property restriction

# let's separate the worlds
world2 = World()
onto2 = world2.get_ontology("http://test.org/onto.owl")

with onto2:
    class Drug(Thing):
        pass
    class ActivePrinciple(Thing):
        pass
    class has_for_active_principle(Drug >> ActivePrinciple):
        pass
    class someActivePrinciple(ActivePrinciple):
        pass
    class MyDrug(Thing): # not a subClass of Drug
        pass  # missing the has_for_active_principle restriction


# get the restriction we want to extract
restriction = onto.MyDrug.is_a.pop(1)

myRestriction = Restriction(Property=world2.search_one(iri=restriction.property.iri),
                            type=restriction.type,
                            value=world2.search_one(iri=restriction.value.iri))
MyDrugOnto2 = world2.search_one(iri='*MyDrug')
MyDrugOnto2.is_a.append(myRestriction)


onto.save(file=r"c:\temp\owlready.rdf", format="rdfxml")
onto2.save(file=r"c:\temp\owlready2.rdf", format="rdfxml")


Any thought ?
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Richard
In reply to this post by gp
Interestingly, nothing "broke" when I ran this. Nice work! It is amusing to rip assertions from ontology to another this way with

restriction = *onto.MyDrug.is_a.pop(1)* # Removes the existential restriction from MyDrug in first ontology
myRestriction = Restriction(Property=world2.search_one(iri=restriction.property.iri),
                            type=restriction.type,
                            value=world2.search_one(iri=restriction.value.iri))
MyDrugOnto2 = world2.search_one(iri='*MyDrug')
MyDrugOnto2.is_a.append(myRestriction)


Although it's probably better to just retrieve a copy:

restriction = onto.MyDrug.is_a[1]

Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Richard
https://owlready2.readthedocs.io/en/latest/onto.html#importing-other-ontologies 

provides a means to import another ontology. I tried it, and when I opened *onto2* in protege, it showed *onto* was an imported ontology, but it didn't seem to change anything, even after reasoning with Pellet.
gp
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

gp
Well the pop command is an artifact, just because it was quick to get the restriction this way.

As of
restriction = onto.MyDrug.is_a[1]
are you sure this works in the general case? The purpose of reconstructing the restriction object was to avoid mixing up things, especially if the same "world" is used.

In this case importing the ontology (i.e. an owl:importXXX entry) is not an option as there would be too much pollution. The attempt here is more some sort of extended mireoting. Or did I miss your point here?
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Jiba
Administrator
Hello,

Transfering entities from an ontology to another is not so easy, especially for some constructs like AllDisjoint (if an AllDisjoint includes the transfered classes, should it be transferred or not ?).

I think the better way to do that is at the RDF level in the quadstore.
Adding a .set_ontology() method would be great, but I'm very short in time currently :-(

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

Re: transfering classes, restrictions, etc. from one ontology to another one

gp
I actually wondered the same thing and I guess this should be left to the programmer to decide on this.

In my case I indeed only want to transfer a closure axiom if everything is in place in the target ontology (i.e. every iri involved in the closure axiom is already defined/used in the target ontology).

It is indeed not trivial to iterate in an elegant manner across the cascade of axioms when dealing with complex restrictions of the likes of
owl:equivalentClass [ owl:intersectionOf ( XX:YYYYY [ rdf:type owl:Restriction ... 
Maybe a few helper functions to

1) iterate over all involved iris (one can then check them, do whatever is needed)
2) given a certain "subject" (be it the equivalent of a blank node) get all involved "properties", and also the same for any given "property" and the involved "objects", so one can navigate through the various elements in an iterative fashion? I understand the S P O description is not ideal to depict some ontology, but I found it convenient here.

My idea is to navigate through the various closure axioms in a fashion similar to traversing a graph (like you would do using a SPARQL query for instance) but in a programmatic manner (and which one cannot do using SPARQL without predefining the structure).

These functionalities might already exist and I might well have missed them completely.

Just my two c...
Guillaume
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Jiba
Administrator
Hi,

Owlready has graph function: you can access them with e.g. default_world.graph.get_triples(subject_or_none, predicate_or_none, object_or_none),...

I still need to document that part !

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

Re: transfering classes, restrictions, etc. from one ontology to another one

gp
Yes I think this will make it, mixing sparql queries with python code is probably a good approach to do the work!
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Mark L.
In reply to this post by Jiba
I was thinking/hoping I would be able to transfer classes from one ontology to another, but it seems it's a much more complicated operation than I realized (due to recursion, etc.). How would one do this "at the RDF level in the quadstore" as suggested above?   Is that something I could leverage owlready2 for, or perhaps rdflib (or rdflib through owlready2)?  All these tools (and rdf/owl/sparql/ontologies) are pretty new to me but I'm diving in deep.

I'm not looking for specific instructions, just a potential general approach.  I understand there may be some tools that might help, like Ontofox, but I would like to transfer thousands of entities and select annotations and properties...so I'm looking for a programmatic strategy I could implement myself.  
Reply | Threaded
Open this post in threaded view
|

Re: transfering classes, restrictions, etc. from one ontology to another one

Jiba
Administrator
Hi,

Indeed, recursion is the problem: how "deep" the copy should be? If it is not deep, the interest is limited. But if it is "fully" deep, everything will be copied...

Here is how I would approach the problem: I would create a "Copier" class, with a "copy(entity)" method. The method would
(1) retain the information that the given entity has been copied, (2) perform a shallow copy of the entity and (3) also copy any relation/restriction that involves only entities that have been copied previously.

For example, let's consider two classes A and B, with A a subclass of B. If we copy first A, then a new class A' will be created in the new ontology. Then, If we copy B, a new class B' will be created and A' sublcass of B' will also be copied.

Comments are welcome :)

Jiba