Skip to content

Commit

Permalink
implemented option to write output ontology in RDF/XML
Browse files Browse the repository at this point in the history
  • Loading branch information
drseb committed Apr 15, 2015
1 parent 261efe4 commit f8f53c4
Showing 1 changed file with 86 additions and 42 deletions.
128 changes: 86 additions & 42 deletions zpgen/src/main/java/de/charite/zpgen/ZPGen.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Map.Entry;
import java.util.Set;
Expand All @@ -17,6 +19,7 @@
import org.coode.owlapi.obo12.parser.OBOVocabulary;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.io.OWLFunctionalSyntaxOntologyFormat;
import org.semanticweb.owlapi.io.RDFXMLOntologyFormat;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLAnnotation;
import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom;
Expand All @@ -31,17 +34,20 @@
import org.semanticweb.owlapi.model.OWLObjectProperty;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyID;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.model.OWLOntologyStorageException;
import org.semanticweb.owlapi.model.SetOntologyID;

import com.beust.jcommander.JCommander;
import com.google.common.collect.ImmutableSetMultimap;

/**
* Main class for ZP which constructs an zebrafish phenotype ontology from decomposed phenotype - gene associations.
* Main class for ZP which constructs an zebrafish phenotype ontology from
* decomposed phenotype - gene associations.
*
* The purpose of this tool is to create an ontology from the definitions that can be found in this file (source
* http://zfin.org/downloads/pheno.txt).
* The purpose of this tool is to create an ontology from the definitions that
* can be found in this file (source http://zfin.org/downloads/pheno.txt).
*
* @author Sebastian Bauer
* @author Sebastian Koehler
Expand All @@ -68,35 +74,44 @@ public static void main(String[] args) throws OWLOntologyCreationException, IOEx
final String annotFilePath = zpCLIConfig.annotFilePath;
final boolean keepIds = zpCLIConfig.keepIds;
final boolean useInheresInPartOf = zpCLIConfig.useInheresInPartOf;
final boolean useOwlRdfSyntax = zpCLIConfig.useOwlRdfSyntax;

final boolean addZfaUberonEquivalencies = zpCLIConfig.addZfaUberonEquivalencies;
final String uberonOboFilePath = zpCLIConfig.uberonOboFilePath;

/* Create ontology manager and IRIs */
final OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
final IRI zpIRI = IRI.create("http://purl.obolibrary.org/obo/");
final IRI zpIRI = IRI.create("http://purl.obolibrary.org/obo/upheno/zp.owl");

/* Load the previous zp, if requested */
final OWLOntology zp;
if (keepIds) {
File ontoFile = new File(previousOntologyFilePath);
if (ontoFile.exists()) {
zp = manager.loadOntologyFromOntologyDocument(ontoFile);
}
else {
// log.info("Ignoring non-existent file \"" + ontologyOutputFilePath + "\" for keeping the ids");
} else {
// log.info("Ignoring non-existent file \"" +
// ontologyOutputFilePath + "\" for keeping the ids");
// zp = manager.createOntology(zpIRI);
log.severe("Could not find file \"" + previousOntologyFilePath + "\" for keeping the ids");
throw new IllegalArgumentException("Keeping IDs was requested, but no previous file \"" + previousOntologyFilePath
+ "\" was found! Prefer to stop here...");
}
}
else {
} else {
zp = manager.createOntology(zpIRI);
}

/*
* If user wants to have equivalence axioms between ZFA-classes and UBERON-classes we need the uberon.obo to create a mapping here.
* Add version IRI
*/
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
IRI versionIRI = IRI.create("http://purl.obolibrary.org/obo/upheno/releases/" + sdf.format(date) + "/zp.owl");
manager.applyChange(new SetOntologyID(zp, new OWLOntologyID(zpIRI, versionIRI)));

/*
* If user wants to have equivalence axioms between ZFA-classes and
* UBERON-classes we need the uberon.obo to create a mapping here.
*/
ImmutableSetMultimap<String, String> zfa2uberon = null;
if (addZfaUberonEquivalencies) {
Expand Down Expand Up @@ -149,18 +164,19 @@ public static void main(String[] args) throws OWLOntologyCreationException, IOEx
if (useInheresInPartOf) {
// inheres in part of
inheresProperty = factory.getOWLObjectProperty(IRI.create(zpIRI + "RO_0002314"));
}
else {
} else {
// inheres in
inheresProperty = factory.getOWLObjectProperty(IRI.create(zpIRI + "RO_0000052"));
// inheresProperty = factory.getOWLObjectProperty(IRI.create(zpIRI + "BFO_0000052"));
// inheresProperty = factory.getOWLObjectProperty(IRI.create(zpIRI +
// "BFO_0000052"));
}

final OWLObjectProperty hasPart = factory.getOWLObjectProperty(IRI.create(zpIRI + "BFO_0000051"));

/* RO_0002180 = "has qualifier" (previously used) */
/* RO_0002573 = "has modifier" (used in most recent version) */
// final OWLObjectProperty has_qualifier = factory.getOWLObjectProperty(IRI.create(zpIRI + "RO_0002180"));
// final OWLObjectProperty has_qualifier =
// factory.getOWLObjectProperty(IRI.create(zpIRI + "RO_0002180"));
final OWLObjectProperty has_modifier = factory.getOWLObjectProperty(IRI.create(zpIRI + "RO_0002573"));
final OWLClass abnormal = factory.getOWLClass(IRI.create(zpIRI + "PATO_0000460"));

Expand All @@ -182,19 +198,22 @@ public static void main(String[] args) throws OWLOntologyCreationException, IOEx
}
} catch (IOException ex) {
/*
* We did not succeed in open the file and reading in a byte. We assume that the file is not compressed.
* We did not succeed in open the file and reading in a byte. We
* assume that the file is not compressed.
*/
is = new FileInputStream(f);
}

/*
* Constructs an OWLClass and Axioms for each zfin entry. We expect the reasoner to collate the classes properly. We also emit
* the annotations here.
* Constructs an OWLClass and Axioms for each zfin entry. We expect
* the reasoner to collate the classes properly. We also emit the
* annotations here.
*/
class ZFIN implements ZFINVisitor {
/**
* Returns an entity class for the given obo id. This is a simple wrapper for OBOVocabulary.ID2IRI(id) but checks whether
* the term stems from a supported ontology.
* Returns an entity class for the given obo id. This is a
* simple wrapper for OBOVocabulary.ID2IRI(id) but checks
* whether the term stems from a supported ontology.
*
* @param id
* @return
Expand All @@ -207,8 +226,9 @@ private OWLClass getEntityClassForOBOID(String id) {
}

/**
* Returns an quality class for the given obo id. This is a simple wrapper for OBOVocabulary.ID2IRI(id) but checks whether
* the term stems from a supported ontology.
* Returns an quality class for the given obo id. This is a
* simple wrapper for OBOVocabulary.ID2IRI(id) but checks
* whether the term stems from a supported ontology.
*
* @param id
* @return
Expand All @@ -226,7 +246,8 @@ public boolean visit(ZFINEntry entry) {
return true;

/*
* Important: exclude useless annotation that look like this ...ZFA:0001439|anatomical
* Important: exclude useless annotation that look like this
* ...ZFA:0001439|anatomical
* system|||||||PATO:0000001|quality|abnormal|
*/
if (entry.entity1SupertermId.equals("ZFA:0001439") && entry.patoID.equals("PATO:0000001") && entry.entity1SubtermId.equals("")
Expand All @@ -246,20 +267,28 @@ public boolean visit(ZFINEntry entry) {

/* Entity 1: Create intersections */
if (entry.entity1SubtermId != null && entry.entity1SubtermId.length() > 0) {
/* Pattern is (all-some interpretation): <pato> inheres_in (<cl2> part of <cl1>) AND qualifier abnormal */
/*
* Pattern is (all-some interpretation): <pato>
* inheres_in (<cl2> part of <cl1>) AND qualifier
* abnormal
*/
OWLClass cl2 = getEntityClassForOBOID(entry.entity1SubtermId);

intersectionList.add(factory.getOWLObjectSomeValuesFrom(inheresProperty,
factory.getOWLObjectIntersectionOf(cl2, factory.getOWLObjectSomeValuesFrom(partOf, cl1))));

/*
* Note that is language the last word is the more specific part of the composition, i.e., we say swim bladder
* epithelium, which is the epithelium of the swim bladder
* Note that is language the last word is the more
* specific part of the composition, i.e., we say swim
* bladder epithelium, which is the epithelium of the
* swim bladder
*/
label = "abnormal(ly) " + entry.patoName + " " + entry.entity1SupertermName + " " + entry.entity1SubtermName;
}
else {
/* Pattern is (all-some interpretation): <pato> inheres_in <cl1> AND qualifier abnormal */
} else {
/*
* Pattern is (all-some interpretation): <pato>
* inheres_in <cl1> AND qualifier abnormal
*/
intersectionList.add(factory.getOWLObjectSomeValuesFrom(inheresProperty, cl1));
label = "abnormal(ly) " + entry.patoName + " " + entry.entity1SupertermName;
}
Expand All @@ -270,20 +299,25 @@ public boolean visit(ZFINEntry entry) {
OWLClass cl3 = getEntityClassForOBOID(entry.entity2SupertermId);

if (entry.entity2SubtermId != null && entry.entity2SubtermId.length() > 0) {
/* Pattern is (all-some interpretation): <pato> inheres_in (<cl2> part of <cl1>) AND qualifier abnormal */
/*
* Pattern is (all-some interpretation): <pato>
* inheres_in (<cl2> part of <cl1>) AND qualifier
* abnormal
*/
OWLClass cl4 = getEntityClassForOBOID(entry.entity2SubtermId);

intersectionList.add(factory.getOWLObjectSomeValuesFrom(towards,
factory.getOWLObjectIntersectionOf(cl4, factory.getOWLObjectSomeValuesFrom(partOf, cl3))));

/*
* Note that is language the last word is the more specific part of the composition, i.e., we say swim bladder
* epithelium, which is the epithelium of the swim bladder
* Note that is language the last word is the more
* specific part of the composition, i.e., we say
* swim bladder epithelium, which is the epithelium
* of the swim bladder
*/
label += " towards " + entry.entity2SupertermName + " " + entry.entity2SubtermName;

}
else {
} else {
intersectionList.add(factory.getOWLObjectSomeValuesFrom(towards, cl3));
label += " towards " + entry.entity2SupertermName;
}
Expand Down Expand Up @@ -340,7 +374,8 @@ public boolean visit(ZFINEntry entry) {

ZFINWalker.walk(is, zfinVisitor);

// if requested, add the equivalence axioms between ZFA-class and UBERON-classes
// if requested, add the equivalence axioms between ZFA-class and
// UBERON-classes
if (zfa2uberon != null && zfa2uberon.keySet().size() > 0) {
for (Entry<String, String> zfa2uberonEntry : zfa2uberon.entries()) {

Expand All @@ -357,9 +392,16 @@ public boolean visit(ZFINEntry entry) {

/* Write output files */
File of = new File(ontologyOutputFilePath);
// save in manchester functional syntax
manager.saveOntology(zp, new OWLFunctionalSyntaxOntologyFormat(), new FileOutputStream(of));
log.info("Wrote \"" + of.toString() + "\"");
if (useOwlRdfSyntax) {
// save in owl/rdf syntax
manager.saveOntology(zp, new RDFXMLOntologyFormat(), new FileOutputStream(of));
log.info("Wrote \"" + of.toString() + "\" in OWL/RDF syntax");
} else {
// save in manchester functional syntax
manager.saveOntology(zp, new OWLFunctionalSyntaxOntologyFormat(), new FileOutputStream(of));
log.info("Wrote \"" + of.toString() + "\" in Manchester function syntax");
}

annotationOut.close();
if (zpCLIConfig.sourceInformationFile != null) {
saveSourceInformation(zp, zpCLIConfig.sourceInformationFile);
Expand All @@ -374,12 +416,14 @@ public boolean visit(ZFINEntry entry) {
}

/**
* Custom IRI for the annotation property for the definition of the class expression.
* Custom IRI for the annotation property for the definition of the class
* expression.
*/
static final IRI definitionSourcePropertyIRI = IRI.create("http://zfin/definition/source_information");

/**
* Add the source information for the definition of the equivalent class expression for the given ZP class.
* Add the source information for the definition of the equivalent class
* expression for the given ZP class.
*
* @param cls
* @param entry
Expand Down Expand Up @@ -410,7 +454,8 @@ private static void addSourceInformation(OWLClass cls, ZFINEntry entry, OWLOntol
source.append('\t');
source.append(entry.patoID); // phenotype_keyword_id
source.append('\t');
source.append("PATO:0000460"); // phenotype_modifier, currently always abnormal
source.append("PATO:0000460"); // phenotype_modifier, currently
// always abnormal
source.append('\t');
if (entry.entity2SupertermId != null) {
source.append(entry.entity2SupertermId);// affected_structure_or_process_2_superterm_id
Expand Down Expand Up @@ -458,8 +503,7 @@ private static void saveSourceInformation(OWLOntology zp, String fileName) {
source = ((OWLLiteral) value).getLiteral();
}
break;
}
else if (rdfsLabel.equals(prop)) {
} else if (rdfsLabel.equals(prop)) {
OWLAnnotationValue value = ann.getValue();
if (value instanceof OWLLiteral) {
label = ((OWLLiteral) value).getLiteral();
Expand Down

0 comments on commit f8f53c4

Please sign in to comment.