Showing posts with label owl. Show all posts
Showing posts with label owl. Show all posts

27 August 2012

Reasoning with the Variation Ontology using Apache Jena #OWL #RDF

The Variation Ontology (VariO), "is an ontology for standardized, systematic description of effects, consequences and mechanisms of variations".
In this post I will use the Apache Jena library for RDF to load this ontology. It will then be used to extract a set of variations that are a sub-class of a given class of Variation.

Loading the ontology

The OWL ontology is available for download here: http://www.variationontology.org/download/VariO_0.979.owl. A new RDF model for an OWL ontology is created and the owl file is loaded.
OntModel ontModel = ModelFactory.createOntologyModel();
InputStream in = FileManager.get().open(VO_OWL_URL);
ontModel.read(in, "");
in.close();

Creating a Reasoner

A OWL Reasoner is then created and associated to the previous model:
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner=this.reasoner.bindSchema(ontModel);

Creating a random set of variations

A new RDF model is created to hold a few instances of random Variations. For each instance, we add a random property 'my:chromosome', a random property 'my:position' and we associated one of the following type:
  • vo:VariO_0000029 "modified amino acid", a sub-Class of vo:VariO_0000028 ("post translationally modified protein")
  • vo:VariO_0000030 "spliced protein", a sub-Class of vo:VariO_0000028 ("post translationally modified protein")
  • vo:VariO_0000033 "effect on protein subcellular localization". It is NOT a sub-class of vo:VariO_0000028
Random rand=new Random();
com.hp.hpl.jena.rdf.model.Model instances = ModelFactory.createDefaultModel();
instances.setNsPrefix("vo",VO_PREFIX);
instances.setNsPrefix("my",MY_URI);

for(int i=0;i< 10;++i)
 {
 Resource subject= null;
 Resource rdftype=null;
 switch(i%3)
    {
    case 0:
       {
       //modified amino acid
       subject=instances.createResource(AnonId.create("modaa_"+i));
       rdftype=instances.createResource(VO_PREFIX+"VariO_0000029");
       break;
       }
    case 1:
       {
       //spliced protein
       subject=instances.createResource(AnonId.create("spliced_"+i));
       rdftype=instances.createResource(VO_PREFIX+"VariO_0000030");
       break;
       }
    default:
       {
       //effect on protein subcellular localization
       subject=instances.createResource(AnonId.create("subcell_"+i));
       rdftype=instances.createResource(VO_PREFIX+"VariO_0000033");
       break;
       }
    }
 instances.add(subject, RDF.type, rdftype);
 instances.add(subject, hasChromosome, instances.createLiteral("chr"+(1+rand.nextInt(22))));
 instances.add(subject, hasPosition, instances.createTypedLiteral(rand.nextInt(1000000)));
 }

Reasoning

A new inference model is created using the reasoner and the instances of variation. An iterator is used to only list the variations being a subclasses of vo:VariO_0000028 and having a property "my:chromosome" and a property "my:position".
InfModel model = ModelFactory.createInfModel (reasoner, instances);
ExtendedIterator<Statement> sti = model.listStatements(
        null, null, model.createResource(VO_PREFIX+"VariO_0000028"));
sti=sti.filterKeep(new Filter<Statement>()
      {
      @Override
      public boolean accept(Statement stmt)
         {
         return   stmt.getSubject().getProperty(hasChromosome)!=null &&
               stmt.getSubject().getProperty(hasPosition)!=null
               ;
         }
      });
Loop over the iterator and print the result:
while(sti.hasNext() )
         {
         Statement stmt = sti.next();
         System.out.println("\t+ " + PrintUtil.print(stmt));
         Statement val=stmt.getSubject().getProperty(hasChromosome);
         System.out.println("\t\tChromosome:\t"+val.getObject());
         val=stmt.getSubject().getProperty(hasPosition);
         System.out.println("\t\tPosition:\t"+val.getObject());
         }

Result

   + (spliced_7 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr7
      Position:   134172^^http://www.w3.org/2001/XMLSchema#int
   + (spliced_4 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr13
      Position:   674316^^http://www.w3.org/2001/XMLSchema#int
   + (spliced_1 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr22
      Position:   457596^^http://www.w3.org/2001/XMLSchema#int
   + (modaa_9 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr12
      Position:   803303^^http://www.w3.org/2001/XMLSchema#int
   + (modaa_6 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr15
      Position:   794137^^http://www.w3.org/2001/XMLSchema#int
   + (modaa_3 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr14
      Position:   34487^^http://www.w3.org/2001/XMLSchema#int
   + (modaa_0 rdf:type http://purl.obolibrary.org/obo/VariO_0000028)
      Chromosome:   chr15
      Position:   536371^^http://www.w3.org/2001/XMLSchema#int

Full source code

import java.io.IOException;
import java.io.InputStream;
import java.util.Random;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hp.hpl.jena.ontology.OntModel;
import com.hp.hpl.jena.ontology.OntModelSpec;
import com.hp.hpl.jena.rdf.model.AnonId;
import com.hp.hpl.jena.rdf.model.InfModel;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.rdf.model.Statement;
import com.hp.hpl.jena.reasoner.Reasoner;
import com.hp.hpl.jena.reasoner.ReasonerRegistry;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.util.PrintUtil;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;
import com.hp.hpl.jena.util.iterator.Filter;
import com.hp.hpl.jena.vocabulary.RDF;

public class VariationOntologyReasoner
  {
  private static final String VO_PREFIX="http://purl.obolibrary.org/obo/";
  private static final String MY_URI="urn:my:ontology";
  private static final String VO_OWL_URL="http://www.variationontology.org/download/VariO_0.979.owl";
  private Reasoner reasoner;
  static final private Property hasChromosome=ModelFactory.createDefaultModel().createProperty(MY_URI,"chromosome");
  static final private Property hasPosition=ModelFactory.createDefaultModel().createProperty(MY_URI,"position");
  
  private VariationOntologyReasoner() throws IOException
    {
    OntModel ontModel = ModelFactory.createOntologyModel();
     InputStream in = FileManager.get().open(VO_OWL_URL);
    ontModel.read(in, "");
    in.close();
    this.reasoner = ReasonerRegistry.getOWLReasoner();
    this.reasoner=this.reasoner.bindSchema(ontModel);
    }
  
  private void run()
    {
    Random rand=new Random();
    com.hp.hpl.jena.rdf.model.Model instances = ModelFactory.createDefaultModel();
    instances.setNsPrefix("vo",VO_PREFIX);
    instances.setNsPrefix("my",MY_URI);

    for(int i=0;i< 10;++i)
      {
      Resource subject= null;
      Resource rdftype=null;
      switch(i%3)
        {
        case 0:
          {
          //modified amino acid
          subject=instances.createResource(AnonId.create("modaa_"+i));
          rdftype=instances.createResource(VO_PREFIX+"VariO_0000029");
          break;
          }
        case 1:
          {
          subject=instances.createResource(AnonId.create("spliced_"+i));
          rdftype=instances.createResource(VO_PREFIX+"VariO_0000030");
          break;
          }
        default:
          {
          //effect on protein subcellular localization
          subject=instances.createResource(AnonId.create("subcell_"+i));
          rdftype=instances.createResource(VO_PREFIX+"VariO_0000033");
          break;
          }
        }
      instances.add(subject, RDF.type, rdftype);
      instances.add(subject, hasChromosome, instances.createLiteral("chr"+(1+rand.nextInt(22))));
      instances.add(subject, hasPosition, instances.createTypedLiteral(rand.nextInt(1000000)));
      }
    
    InfModel model = ModelFactory.createInfModel (reasoner, instances);
    ExtendedIterator<Statement> sti = model.listStatements(null, null, model.createResource(VO_PREFIX+"VariO_0000028"));
    sti=sti.filterKeep(new Filter<Statement>()
        {
        @Override
        public boolean accept(Statement stmt)
          {
          return  stmt.getSubject().getProperty(hasChromosome)!=null &&
              stmt.getSubject().getProperty(hasPosition)!=null
              ;
          }
        });
    while(sti.hasNext() )
      {
      Statement stmt = sti.next();
      System.out.println("\t+ " + PrintUtil.print(stmt));
      Statement val=stmt.getSubject().getProperty(hasChromosome);
      System.out.println("\t\tChromosome:\t"+val.getObject());
      val=stmt.getSubject().getProperty(hasPosition);
      System.out.println("\t\tPosition:\t"+val.getObject());
      }
    }
  
  public static void main(String[] args) throws Exception
    {
    VariationOntologyReasoner app=new VariationOntologyReasoner();
    app.run();
  }
}

That's it,

Pierre






15 February 2010

Semantic Web Services with the SADI Framework: my notebook.

At Biohackathon2010 , Mark Wilkinson and Luke McCarthy introduced The SADI Framework. From sadiframework.org:SADI is a framework for discovery of, and interoperability between, distributed data and analytical resources. It combines simple, stateless, GET/POST-based Web Services with standards from the W3C Semantic Web initiative. The objective of SADI is to make it easy for data and analytical tool providers to quickly make their resources available on the Semantic Web with minimal disruption to their usual practices.(...)

  • SADI Services consume and provide data via simple HTTP POST and GET
  • SADI Services consume and produce data in RDF format. This allows SADI Services to exploit existing OWL reasoners and SPARQL query engines to enhance interoperability between Services and the interpretation of the data being passed between them
  • Service interfaces (i.e., Inputs and Outputs) are defined in terms of OWL-DL classes; the property restrictions on these OWL classes define what specific data elements are required by the Service and what data will be provided by the Service, respectively
  • Input RDF data - data that is compliant with the Input OWL Class - is “decorated” or “annotated” by the service provider to include new properties. These properties will (of course) be a function of the lookup/analytical operations performed by the Web Service.
  • Importantly, discovery of SADI Services can include searches for the properties the user wants to add to their data. This contrasts with other Semantic Web Service standards which attempt only to define the computational process by which input data is analysed, rather than the properties that process generates between the input and output data. This is KEY to the semantic behaviours of SADI.
  • SADI Web Services are stateless and atomic.


In the current post, I just want to understand how SADI invokes the services.

The classical Web Services are described using WSDL (Web Services Description Language) and the messages are transported with SOAP.
Your browser does not support the <CANVAS> element !
In Sadi, as far as I understand it, the description of the services, the operations, the inputs, the ouputs and the transport of the messages use a RDF/OWL format.
Your browser does not support the <CANVAS> element !


http://sadiframework.org/registry/ contains all the services handled by the SADI framework. For example calling http://sadiframework.org/services/getPubMedReferencesForPDB returns the following XML document describing the service:
<rdf:RDF
xmlns="http://www.w3.org/2002/07/owl#"
xmlns:a="http://www.mygrid.org.uk/mygrid-moby-service#"
xmlns:b="http://protege.stanford.edu/plugins/owl/dc/protege-dc.owl#"
xml:base="http://bioinfo.icapture.ubc.ca/SADI"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:databases="http://sadiframework.org/ontologies/Databases.owl#"
xmlns:misc="http://sadiframework.org/ontologies/miscellaneousObjects.owl#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">

<rdf:Description rdf:about="http://sadiframework.org/services/getPubMedReferencesForPDB">
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#serviceDescription"/>
<b:format>sadi</b:format>
<b:identifier>urn:lsid:myservices:getPubMedReferencesForPDB</b:identifier>
<a:locationURI>http://sadiframework.org/services/getPubMedReferencesForPDB</a:locationURI>
<a:hasServiceDescriptionText>A implementation of the 'getPubMedReferencesForPDB' service</a:hasServiceDescriptionText>
<a:hasServiceDescriptionLocation>http://sadiframework.org/services/getPubMedReferencesForPDB</a:hasServiceDescriptionLocation>
<a:hasServiceNameText>getPubMedReferencesForPDB</a:hasServiceNameText>
<a:providedBy>
<rdf:Description rdf:about="getPubMedReferencesForPDB_mark.ubic.ca_0">
<a:authoritative>0</a:authoritative>
<b:creator>markw@illuminae.com</b:creator>
<b:publisher>mark.ubic.ca</b:publisher>
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#organisation"/>
</rdf:Description>
</a:providedBy>
<a:hasOperation>
<rdf:Description rdf:about="getPubMedReferencesForPDB_mark.ubic.ca_1">
<a:hasOperationNameText>getPubMedReferencesForPDB</a:hasOperationNameText>
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#operation"/>
<a:performsTask>
<rdf:Description rdf:about="getPubMedReferencesForPDB_mark.ubic.ca_2">
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#operationTask"/>
<rdf:type rdf:resource="http://mygrid.org.uk/sometype"/>
</rdf:Description>
</a:performsTask>
<a:inputParameter>
<rdf:Description rdf:about="getPubMedReferencesForPDB_mark.ubic.ca_3">
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#parameter"/>
<a:objectType>
<rdf:Description rdf:about="http://purl.oclc.org/SADI/LSRN/PDB_Thing"/>
</a:objectType>
</rdf:Description>
</a:inputParameter>
<a:outputParameter>
<rdf:Description rdf:about="getPubMedReferencesForPDB_mark.ubic.ca_4">
<rdf:type rdf:resource="http://www.mygrid.org.uk/mygrid-moby-service#parameter"/>
<a:objectType>
<rdf:Description rdf:about="http://sadiframework.org/ontologies/pdb_2_pmid.owl#getPubMedReferencesForPDB_Output"/>
</a:objectType>
</rdf:Description>
</a:outputParameter>
</rdf:Description>
</a:hasOperation>
</rdf:Description>
</rdf:RDF>

A part of this service can be visualized as a graph:
Your browser does not support the <CANVAS> element !
So, the service getPubMedReferencesForPDB takes as input a parameter of type http://purl.oclc.org/SADI/LSRN/PDB_Thing and returns an object of type http://sadiframework.org/ontologies/pdb_2_pmid.owl#getPubMedReferencesForPDB_Output. Ok, let's try this service: I'm going to invoke the service getPubMedReferencesForPDB with two structures of type http://purl.oclc.org/SADI/LSRN/PDB_Thing (Many thanks to Mark for helping me via Twitter ...:-P ): 1KNZ and 1LJ2.

File: input.rdf
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:lsrn="http://purl.oclc.org/SADI/LSRN/">

<lsrn:PDB_Thing rdf:about="http://lsrn.org/PDB:1KNZ"/>
<lsrn:PDB_Thing rdf:about="http://lsrn.org/PDB:1LJ2"/>
</rdf:RDF>

Calling curl with this file for the service getPubMedReferencesForPDB:
curl -d @input.rdf http://sadiframework.org/services/getPubMedReferencesForPDB

Result:
<rdf:RDF>
<rdf:Description rdf:about="http://lsrn.org/PDB:1LJ2">
<a:hasReference>
<rdf:Description rdf:about="http://lsrn.org/PMID:12086624">
<rdf:type rdf:resource="http://purl.oclc.org/SADI/LSRN/PMID_Thing"/>
</rdf:Description>
</a:hasReference>
<rdf:type rdf:resource="http://sadiframework.org/ontologies/pdb_2_pmid.owl#getPubMedReferencesForPDB_Output"/>
</rdf:Description>
<rdf:Description rdf:about="http://lsrn.org/PDB:1KNZ">
<a:hasReference>
<rdf:Description rdf:about="http://lsrn.org/PMID:11792322">
<rdf:type rdf:resource="http://purl.oclc.org/SADI/LSRN/PMID_Thing"/>
</rdf:Description>
</a:hasReference>
<rdf:type rdf:resource="http://sadiframework.org/ontologies/pdb_2_pmid.owl#getPubMedReferencesForPDB_Output"/>
</rdf:Description>
</rdf:RDF>
Here, for each PDB entry (input), we were returned a Pubmed Identifier (output).


That's it !
Pierre

11 June 2009

Learning OWL: a simple Ontology for contributions

This post is a simple reminder for creating a simple OWL ontology, I know RDFS (RDF schema) but I'm not at all an expert with the OWL language, so feel free to make any comment about the following ontology.

OK...

at the beginning there is an empty RDF document:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
]>
<rdf:RDF xmlns:rdf="&rdf;">
</rdf:RDF>


We're going to use a few more namespaces:
  • DC: the Dublin core provides the basic metadata to describe a resource (title, author...)
  • RDFS: the namespace for the simpliest RDF ontology
  • OWL a more precise language for describing an ontology extendings RDFs
  • FOAF. defines the People, the Images, the Documents, etc...
  • biogang: this will be the prefix for our ontology


<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY dc "http://purl.org/dc/elements/1.1/">
<!ENTITY biogang "urn:biogang/ontology/contribution#">
<!ENTITY foaf "http://xmlns.com/foaf/0.1/">
]>
<rdf:RDF xmlns:rdf="&rdf;"
xmlns:rdfs="&rdfs;"
xmlns:owl="&owl;"
xmlns:foaf="&foaf;"
xmlns:dc="&dc;"
xmlns:biogang="&biogang;">

</rdf:RDF>


In a first statement We describe our Ontology (label, comment,...)
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE rdf:RDF [
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#">
<!ENTITY owl "http://www.w3.org/2002/07/owl#">
<!ENTITY dc "http://purl.org/dc/elements/1.1/">
<!ENTITY foaf "http://xmlns.com/foaf/0.1/">
<!ENTITY biogang "urn:biogang/ontology/contribution#">
]>
<rdf:RDF xmlns:rdf="&rdf;" xmlns:rdfs="&rdfs;" xmlns:owl="&owl;" xmlns:dc="&dc;" xmlns:foaf="&foaf;" xmlns:biogang="&biogang;">

<owl:Ontology rdf:about="">
<dc:date>2009-06-11</dc:date>
<dc:creator>Pierre Lindenbaum</dc:creator>
<rdfs:label>The Attribution Ontology</rdfs:label>
<rdfs:comment>
An ontology used to provide a quantitative citation
for every unique author of a document
</rdfs:comment>
</owl:Ontology>
</rdf:RDF>

Let's declare our main class, an Attribution:
<owl:Class rdf:about="&biogang;Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
</owl:Class>

An attribution is a link between an author and a document.
An author is a foaf:Person as defined in the FOAF ontology.
A document is a foaf:Document as defined in the FOAF ontology (this could be an article but also a picture, a song, a web site, etc...).
So, an Attribution is a Class with two properties: contributor and contributedTo.
The domain of both contributor and contributedTo is an object of type Contribution.
The range of a "contributor" is NOT the name of the author (aka a Literal, aka a DataTypeProperty) but it is a link to a resource describing the Person. So its range is an ObjectProperty pointing to a foaf:Person. Also contributedTo extends the Dublin-Core property dc:creator
<owl:ObjectProperty rdf:about="&biogang;contributor">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&foaf;Person"/>
<rdfs:label>contributor</rdfs:label>
<rdfs:subPropertyOf rdf:resource="&dc;creator"/>
</owl:ObjectProperty>

The range of contributedTo" is NOT the literal description of the document but it is a link to a resource describing the Document. So its range is an ObjectProperty pointing to a foaf:Document.
<owl:ObjectProperty rdf:about="&biogang;contributedTo">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&foaf;Document"/>
<rdfs:label>contributed to</rdfs:label>
</owl:ObjectProperty>


We can also add a Literal property to describe the nature of the contribution.
<owl:DatatypeProperty rdf:about="&biogang;comment">
<rdfs:domain rdf:resource="&biogang;Contribution"/>
<rdfs:range rdf:resource="&rdfs;Literal"/>
<rdfs:label>description of this contribution</rdfs:label>
<rdfs:subPropertyOf rdf:resource="&dc;description"/>
</owl:DatatypeProperty>


But a Contribution should contain one 'contributor' and one 'contributedTo', so we add a restriction on the cardinality of those properties:


<owl:Class rdf:about="&biogang;Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="&biogang;contributor"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="&biogang;contributedTo"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>

We can also create a set of sub-Classes to extend the Class Contribution to give a quantifiable view of the contribution.
<owl:Class rdf:about="&biogang;MajorContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Major contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="&biogang;MediumContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Medium contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="&biogang;MicroContribution">
<rdfs:subClassOf rdf:resource="&biogang;Contribution"/>
<rdfs:label>Micro contribution</rdfs:label>
</owl:Class>

It would be also nice, to extends this ontology to describe the 'nature' of the contribution (drawing figures, useful discussions, writing the paper). This would allow to easily find the person who are good with a given task.
Anyway, at the end, here is the full ontology:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl="http://www.w3.org/2002/07/owl#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:biogang="urn:biogang/ontology/contribution#">

<owl:Ontology rdf:about="">
<dc:date>2009-06-11</dc:date>
<dc:creator>Pierre Lindenbaum</dc:creator>
<rdfs:label>The Attribution Ontology</rdfs:label>
<rdfs:comment>
An ontology used to provide a quantitative citation
for every unique author of a document
</rdfs:comment>
</owl:Ontology>

<owl:Class rdf:about="urn:biogang/ontology/contribution#Contribution">
<rdfs:label xml:lang="en">Contribution</rdfs:label>
<rdfs:label xml:lang="fr">Contribution</rdfs:label>
<rdfs:comment xml:lang="en">A contribution</rdfs:comment>
<rdfs:comment xml:lang="fr">Une contribution</rdfs:comment>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="urn:biogang/ontology/contribution#contributor"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
<rdfs:subClassOf>
<owl:Restriction>
<owl:onProperty rdf:resource="urn:biogang/ontology/contribution#contributedTo"/>
<owl:cardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger">1</owl:cardinality>
</owl:Restriction>
</rdfs:subClassOf>
</owl:Class>


<owl:ObjectProperty rdf:about="urn:biogang/ontology/contribution#contributor">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
<rdfs:label>contributor</rdfs:label>
<rdfs:subPropertyOf rdf:resource="http://purl.org/dc/elements/1.1/creator"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:about="urn:biogang/ontology/contribution#contributedTo">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://xmlns.com/foaf/0.1/Document"/>
<rdfs:label>contributed to</rdfs:label>
</owl:ObjectProperty>

<owl:DatatypeProperty rdf:about="urn:biogang/ontology/contribution#comment">
<rdfs:domain rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:range rdf:resource="http://www.w3.org/2000/01/rdf-schema#Literal"/>
<rdfs:label>description of this contribution</rdfs:label>
<rdfs:subPropertyOf rdf:resource="http://purl.org/dc/elements/1.1/description"/>
</owl:DatatypeProperty>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MajorContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Major contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MediumContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Medium contribution</rdfs:label>
</owl:Class>

<owl:Class rdf:about="urn:biogang/ontology/contribution#MicroContribution">
<rdfs:subClassOf rdf:resource="urn:biogang/ontology/contribution#Contribution"/>
<rdfs:label>Micro contribution</rdfs:label>
</owl:Class>

</rdf:RDF>


At the end, we can create some new instances of contributions just like this:
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:biogang="urn:biogang/ontology/contribution#" (...) >
<biogang:MajorContribution>
<biogang:comment>Made the Y2H experiments</biogang:comment>
<biogang:contributor rdf:resource="mailto:plindenbaum@yahoo.fr"/>
<biogang:contributedTo rdf:resource="http://www.ncbi.nlm.nih.gov/pubmed/8985320"/>
</biogang:MajorContribution>

<foaf:Person rdf:about="mailto:plindenbaum@yahoo.fr">
<foaf:name>Pierre</foaf:name>
</foaf:Person>

<foaf:Document rdf:about="http://www.ncbi.nlm.nih.gov/pubmed/8985320">
<dc:title>In vivo and in vitro phosphorylation of rotavirus NSP5 correlates with its localization in viroplasms</dc:title>
</foaf:Document>
</rdf:RDF>


That's it
Pierre