diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/Ontology.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/Ontology.java index 4d68dc0..b2fa0f3 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/Ontology.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/Ontology.java @@ -1,272 +1,319 @@ package org.monarchinitiative.owlsim.io; -import org.apache.commons.validator.routines.UrlValidator; -import org.apache.log4j.Logger; -import org.prefixcommons.CurieUtil; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.model.*; -import org.semanticweb.owlapi.model.parameters.ChangeApplied; -import uk.ac.manchester.cs.owl.owlapi.concurrent.Concurrency; - -import java.io.*; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; import java.util.Map; +import java.util.Map.Entry; import java.util.Objects; import java.util.Set; import java.util.function.BiConsumer; import java.util.zip.GZIPInputStream; +import org.apache.commons.validator.routines.UrlValidator; +import org.apache.log4j.Logger; +import org.prefixcommons.CurieUtil; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.parameters.ChangeApplied; + +import uk.ac.manchester.cs.owl.owlapi.concurrent.Concurrency; + /** - * OWL API wrapper to facilitate building OWLOntology objects to load into the {@link org.monarchinitiative.owlsim.kb.impl.BMKnowledgeBaseOWLAPIImpl} + * OWL API wrapper to facilitate building OWLOntology objects to load into the + * {@link org.monarchinitiative.owlsim.kb.impl.BMKnowledgeBaseOWLAPIImpl} * * @author Jules Jacobsen */ public class Ontology { - private static final Logger logger = Logger.getLogger(Ontology.class); - - //OWLOntology is a mutable object - private final OntologySourceData sourceData; - private final CurieUtil curieUtil; - private final OWLOntology owlOntology; - - private final OWLOntologyManager ontologyManager; - private final OWLDataFactory owlDataFactory; - - private Ontology(OntologySourceData sourceData, Concurrency concurrency) { - Objects.requireNonNull(sourceData, "Unable to create Ontology without data sources."); - this.sourceData = sourceData; - this.curieUtil = new CurieUtil(sourceData.getCuries()); - this.ontologyManager = createOntologyManager(concurrency); - this.owlOntology = createEmptyOntology(ontologyManager); - this.owlDataFactory = ontologyManager.getOWLDataFactory(); - loadOwlOntology(); - } - - /** - * Loads an ontology using a concurrent OWLOntologyManager. - * - * @param sourceData - * @return An Ontology created from the source data provided. - */ - public static Ontology load(OntologySourceData sourceData) { - return new Ontology(sourceData, Concurrency.CONCURRENT); - } - - /** - * Loads an ontology using an OWLOntologyManager using the concurrency type specified. - * - * @param sourceData - * @param concurrency - * @return An Ontology created from the source data provided. - */ - public static Ontology load(OntologySourceData sourceData, Concurrency concurrency) { - return new Ontology(sourceData, useConcurrentIfNull(concurrency)); - } - - private static Concurrency useConcurrentIfNull(Concurrency concurrency) { - return concurrency == null ? Concurrency.CONCURRENT : concurrency; - } - - public OWLOntology getOwlOntology() { - return owlOntology; - } - - public OntologySourceData getSourceData() { - return sourceData; - } - - public CurieUtil getCurieUtil() { - return curieUtil; - } - - /** - * @param curie - * @return - */ - public OWLClass getOWLClass(String curie) { - return owlDataFactory.getOWLClass(toIri(curie)); - } - - public OWLNamedIndividual getOWLNamedIndividual(String curie) { - return owlDataFactory.getOWLNamedIndividual(toIri(curie)); - } - - public String toCurie(IRI iri) { - String iriString = iri.toString(); - return curieUtil.getCurie(iriString).orElse(iriString); - } - - private void loadOwlOntology() { - //Order matters here - don't change it. - mergeOntologies(sourceData.getOntologies()); - mergeOntologies(sourceData.getDataOntologies()); - loadIndividualAssociationsFromTsv(sourceData.getIndividualAssociationTsvs()); - loadIndividualAssociationsFromMap(sourceData.getIndividualAssociations()); - logger.info("Ontology loaded"); - } - - private OWLOntologyManager createOntologyManager(Concurrency concurrencyType) { - if (concurrencyType == Concurrency.NON_CONCURRENT) { - logger.info("Using non-concurrent OWL ontology manager"); - return OWLManager.createOWLOntologyManager(); - } - logger.info("Using concurrent OWL ontology manager"); - return OWLManager.createConcurrentOWLOntologyManager(); - } - - private OWLOntology createEmptyOntology(OWLOntologyManager ontologyManager) { - try { - return ontologyManager.createOntology(); - } catch (OWLOntologyCreationException e) { - throw new OntologyLoadException(e); - } - } - - private OWLOntology mergeOntology(String uri) { - OWLOntology loadedOntology = loadOwlOntology(uri); - addAxioms(loadedOntology.getAxioms()); - return owlOntology; - } - - private OWLOntology mergeOntologies(Collection uris) { - uris.forEach(uri -> mergeOntology(uri)); - return owlOntology; - } - - private ChangeApplied addAxioms(Set axioms) { - return ontologyManager.addAxioms(owlOntology, axioms); - } - - private OWLOntology loadOwlOntology(String uri) { - UrlValidator urlValidator = UrlValidator.getInstance(); - if (urlValidator.isValid(uri)) { - return loadRemoteOntology(IRI.create(uri)); - } else if (uri.endsWith(".gz")) { - return loadGzippedOntology(Paths.get(uri)); - } else { - return loadOwlOntologyFromDocument(Paths.get(uri)); - } - } - - private OWLOntology loadRemoteOntology(IRI iri) { - return loadOwlOntology(iri); - } - - private OWLOntology loadGzippedOntology(Path path) { - logger.info("Loading gzipped ontology from " + path); - try (InputStream is = new GZIPInputStream(new FileInputStream(path.toFile()))) { - return loadOwlOntologyFromDocument(is); - } catch (IOException e) { - throw new OntologyLoadException(e); - } - } - - private OWLOntology loadOwlOntology(IRI iri) { - try { - logger.info("Loading ontology from IRI" + iri.getShortForm()); - return ontologyManager.loadOntology(iri); - } catch (OWLOntologyCreationException e) { - throw new OntologyLoadException(e); - } - } - - private OWLOntology loadIndividualAssociationsFromTsv(Collection paths) { - paths.forEach(this::loadIndividualAssociationsFromTsv); - return owlOntology; - } - - private OWLOntology loadIndividualAssociationsFromTsv(String path) { - if (path.endsWith(".gz")) { - return loadDataFromTsvGzip(path); - } - Path file = Paths.get(path); - logger.info("Reading tsv data from " + path); - try { - Files.lines(file).forEach(line -> loadLineIntoDataOntology(line)); - } catch (IOException e) { - throw new OntologyLoadException(e); - } - return owlOntology; - } - - private OWLOntology loadDataFromTsvGzip(String path) { - Path file = Paths.get(path); - logger.info("Reading gzipped tsv data from " + file); - try (GZIPInputStream gis = new GZIPInputStream(new FileInputStream(file.toFile())); - BufferedReader bf = new BufferedReader(new InputStreamReader(gis, Charset.forName("UTF-8"))) - ) { - bf.lines().forEach(line -> loadLineIntoDataOntology(line)); - } catch (IOException e) { - throw new OntologyLoadException(e); - } - return owlOntology; - } - - private void loadIndividualAssociationsFromMap(Map> individuals) { - if(!individuals.isEmpty()){ - logger.info("Loading individuals from map"); - } - //e.g. 'ORPHA:710': ['HP:0000194','HP:0000218','HP:0000262','HP:0000303','HP:0000316'] - individuals.forEach(addIndividual()); - } - - private BiConsumer> addIndividual() { - return (individual, annotations) -> { - for (String curie : annotations) { - addInstanceOf(individual, curie); - } - }; - } - - private void loadLineIntoDataOntology(String line) { - String[] vals = line.split("\t", 2); - String[] terms = vals[1].split(";"); - for (String t : terms) { - addInstanceOf(vals[0], t); - } - } - - private void addInstanceOf(String individual, String ontologyClass) { - Objects.requireNonNull(individual, "Individual identifier cannot be null. Check your input."); - Objects.requireNonNull(ontologyClass, "Class identifier(s) cannot be null. Check your input."); - if (!ontologyClass.isEmpty()) { -// logger.info("Adding axiom " + individual + ": " + ontologyClass); - OWLClass owlClass = getOWLClass(ontologyClass); - OWLNamedIndividual owlNamedIndividual = getOWLNamedIndividual(individual); - OWLClassAssertionAxiom axiom = owlDataFactory.getOWLClassAssertionAxiom(owlClass, owlNamedIndividual); - addAxiom(axiom); - } - } - - private ChangeApplied addAxiom(OWLAxiom axiom) { - return ontologyManager.addAxiom(owlOntology, axiom); - } - - IRI toIri(String id) { - return IRI.create(curieUtil.getIri(id).orElse(id)); - } - - private OWLOntology loadOwlOntologyFromDocument(Path path) { - try { - logger.info("Loading ontology from document " + path); - return ontologyManager.loadOntologyFromOntologyDocument(path.toFile()); - } catch (OWLOntologyCreationException e) { - throw new OntologyLoadException(e); - } - } - - private OWLOntology loadOwlOntologyFromDocument(InputStream is) { - try { - return ontologyManager.loadOntologyFromOntologyDocument(is); - } catch (OWLOntologyCreationException e) { - logger.error("Unable to create ontology" + e); - throw new OntologyLoadException(e); - } - } + private static final Logger logger = Logger.getLogger(Ontology.class); + + // OWLOntology is a mutable object + private final OntologySourceData sourceData; + private final CurieUtil curieUtil; + private final OWLOntology owlOntology; + + private final OWLOntologyManager ontologyManager; + private final OWLDataFactory owlDataFactory; + + private Ontology(OntologySourceData sourceData, Concurrency concurrency) { + Objects.requireNonNull(sourceData, "Unable to create Ontology without data sources."); + this.sourceData = sourceData; + this.curieUtil = new CurieUtil(sourceData.getCuries()); + this.ontologyManager = createOntologyManager(concurrency); + this.owlOntology = createEmptyOntology(ontologyManager); + this.owlDataFactory = ontologyManager.getOWLDataFactory(); + loadOwlOntology(); + } + + /** + * Loads an ontology using a concurrent OWLOntologyManager. + * + * @param sourceData + * @return An Ontology created from the source data provided. + */ + public static Ontology load(OntologySourceData sourceData) { + return new Ontology(sourceData, Concurrency.CONCURRENT); + } + + /** + * Loads an ontology using an OWLOntologyManager using the concurrency type + * specified. + * + * @param sourceData + * @param concurrency + * @return An Ontology created from the source data provided. + */ + public static Ontology load(OntologySourceData sourceData, Concurrency concurrency) { + return new Ontology(sourceData, useConcurrentIfNull(concurrency)); + } + + private static Concurrency useConcurrentIfNull(Concurrency concurrency) { + return concurrency == null ? Concurrency.CONCURRENT : concurrency; + } + + public OWLOntology getOwlOntology() { + return owlOntology; + } + + public OntologySourceData getSourceData() { + return sourceData; + } + + public CurieUtil getCurieUtil() { + return curieUtil; + } + + /** + * @param curie + * @return + */ + public OWLClass getOWLClass(String curie) { + return owlDataFactory.getOWLClass(toIri(curie)); + } + + public OWLNamedIndividual getOWLNamedIndividual(String curie) { + return owlDataFactory.getOWLNamedIndividual(toIri(curie)); + } + + public String toCurie(IRI iri) { + String iriString = iri.toString(); + return curieUtil.getCurie(iriString).orElse(iriString); + } + + private void loadOwlOntology() { + // Order matters here - don't change it. + mergeOntologies(sourceData.getOntologies()); + mergeOntologies(sourceData.getDataOntologies()); + loadIndividualAssociationsFromTsv(sourceData.getIndividualAssociationTsvs()); + loadIndividualAssociationsFromMap(sourceData.getIndividualAssociations()); + loadLabelFromTsv(sourceData.getLabelTsvs()); + logger.info("Ontology loaded"); + } + + private OWLOntologyManager createOntologyManager(Concurrency concurrencyType) { + if (concurrencyType == Concurrency.NON_CONCURRENT) { + logger.info("Using non-concurrent OWL ontology manager"); + return OWLManager.createOWLOntologyManager(); + } + logger.info("Using concurrent OWL ontology manager"); + return OWLManager.createConcurrentOWLOntologyManager(); + } + + private OWLOntology createEmptyOntology(OWLOntologyManager ontologyManager) { + try { + return ontologyManager.createOntology(); + } catch (OWLOntologyCreationException e) { + throw new OntologyLoadException(e); + } + } + + private OWLOntology mergeOntology(String uri) { + OWLOntology loadedOntology = loadOwlOntology(uri); + addAxioms(loadedOntology.getAxioms()); + return owlOntology; + } + + private OWLOntology mergeOntologies(Collection uris) { + uris.forEach(uri -> mergeOntology(uri)); + return owlOntology; + } + + private ChangeApplied addAxioms(Set axioms) { + return ontologyManager.addAxioms(owlOntology, axioms); + } + + private OWLOntology loadOwlOntology(String uri) { + UrlValidator urlValidator = UrlValidator.getInstance(); + if (urlValidator.isValid(uri)) { + return loadRemoteOntology(IRI.create(uri)); + } else if (uri.endsWith(".gz")) { + return loadGzippedOntology(Paths.get(uri)); + } else { + return loadOwlOntologyFromDocument(Paths.get(uri)); + } + } + + private OWLOntology loadRemoteOntology(IRI iri) { + return loadOwlOntology(iri); + } + + private OWLOntology loadGzippedOntology(Path path) { + logger.info("Loading gzipped ontology from " + path); + try (InputStream is = new GZIPInputStream(new FileInputStream(path.toFile()))) { + return loadOwlOntologyFromDocument(is); + } catch (IOException e) { + throw new OntologyLoadException(e); + } + } + + private OWLOntology loadOwlOntology(IRI iri) { + try { + logger.info("Loading ontology from IRI" + iri.getShortForm()); + return ontologyManager.loadOntology(iri); + } catch (OWLOntologyCreationException e) { + throw new OntologyLoadException(e); + } + } + + private OWLOntology loadIndividualAssociationsFromTsv(Collection paths) { + paths.forEach(this::loadIndividualAssociationsFromTsv); + return owlOntology; + } + + private OWLOntology loadIndividualAssociationsFromTsv(String path) { + if (path.endsWith(".gz")) { + return loadDataFromTsvGzip(path); + } + Path file = Paths.get(path); + logger.info("Reading tsv data from " + path); + try { + Files.lines(file).forEach(line -> loadLineIntoDataOntology(line)); + } catch (IOException e) { + throw new OntologyLoadException(e); + } + return owlOntology; + } + + private OWLOntology loadDataFromTsvGzip(String path) { + Path file = Paths.get(path); + logger.info("Reading gzipped tsv data from " + file); + try (GZIPInputStream gis = new GZIPInputStream(new FileInputStream(file.toFile())); + BufferedReader bf = new BufferedReader(new InputStreamReader(gis, Charset.forName("UTF-8")))) { + bf.lines().forEach(line -> loadLineIntoDataOntology(line)); + } catch (IOException e) { + throw new OntologyLoadException(e); + } + return owlOntology; + } + + private void loadIndividualAssociationsFromMap(Map> individuals) { + if (!individuals.isEmpty()) { + logger.info("Loading individuals from map"); + } + // e.g. 'ORPHA:710': + // ['HP:0000194','HP:0000218','HP:0000262','HP:0000303','HP:0000316'] + individuals.forEach(addIndividual()); + } + + private BiConsumer> addIndividual() { + return (individual, annotations) -> { + for (String curie : annotations) { + addInstanceOf(individual, curie); + } + }; + } + + private void loadLineIntoDataOntology(String line) { + String[] vals = line.split("\t", 2); + String[] terms = vals[1].split(";"); + for (String t : terms) { + addInstanceOf(vals[0], t); + } + } + + private void addInstanceOf(String individual, String ontologyClass) { + Objects.requireNonNull(individual, "Individual identifier cannot be null. Check your input."); + Objects.requireNonNull(ontologyClass, "Class identifier(s) cannot be null. Check your input."); + if (!ontologyClass.isEmpty()) { + // logger.info("Adding axiom " + individual + ": " + ontologyClass); + OWLClass owlClass = getOWLClass(ontologyClass); + OWLNamedIndividual owlNamedIndividual = getOWLNamedIndividual(individual); + OWLClassAssertionAxiom axiom = owlDataFactory.getOWLClassAssertionAxiom(owlClass, owlNamedIndividual); + addAxiom(axiom); + } + } + + private ChangeApplied addAxiom(OWLAxiom axiom) { + return ontologyManager.addAxiom(owlOntology, axiom); + } + + IRI toIri(String id) { + return IRI.create(curieUtil.getIri(id).orElse(id)); + } + + private OWLOntology loadOwlOntologyFromDocument(Path path) { + try { + logger.info("Loading ontology from document " + path); + return ontologyManager.loadOntologyFromOntologyDocument(path.toFile()); + } catch (OWLOntologyCreationException e) { + throw new OntologyLoadException(e); + } + } + + private OWLOntology loadOwlOntologyFromDocument(InputStream is) { + try { + return ontologyManager.loadOntologyFromOntologyDocument(is); + } catch (OWLOntologyCreationException e) { + logger.error("Unable to create ontology" + e); + throw new OntologyLoadException(e); + } + } + + private void loadLabelFromTsv(Set labelTsvs) { + for (String labelsTsv : labelTsvs) { + Path file = Paths.get(labelsTsv); + logger.info("Reading tsv data from " + labelsTsv); + try { + Files.lines(file).forEach(line -> { + System.out.println(line); + String[] vals = line.split("\t", 2); + addLabel(vals[0], vals[1]); + }); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + // we may want to load labels directly from memory + private void loadLabelFromMap(Map labelMap) { + for (Entry entry : labelMap.entrySet()) { + addLabel(entry.getKey(), entry.getValue()); + } + } + + private void addLabel(String s, String l) { + OWLAnnotationAssertionAxiom axiom = owlDataFactory.getOWLAnnotationAssertionAxiom(owlDataFactory.getRDFSLabel(), + IRI.create(curieUtil.getIri(s).orElse(s)), owlDataFactory.getOWLLiteral(l)); + ontologyManager.addAxiom(owlOntology, axiom); + + } } - diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OntologySourceData.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OntologySourceData.java index e9773a1..0a03acc 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OntologySourceData.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OntologySourceData.java @@ -2,6 +2,8 @@ import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; + import org.monarchinitiative.owlsim.kb.BMKnowledgeBase; import org.semanticweb.owlapi.model.OWLOntology; @@ -22,7 +24,7 @@ private final Map curies; private final List individualAssociationTsvs; private final Map> individualAssociations; - //TODO - labels? + private final Set labelTsvs; private OntologySourceData(Builder builder) { this.ontologies = distinctImmutableListOf(builder.ontologies); @@ -30,6 +32,7 @@ private OntologySourceData(Builder builder) { this.curies = ImmutableMap.copyOf(builder.curies); this.individualAssociationTsvs = distinctImmutableListOf(builder.individualAssociationTsvs); this.individualAssociations = ImmutableMap.copyOf(builder.individualAssociations); + this.labelTsvs = ImmutableSet.copyOf(builder.labelTsvs); } private ImmutableList distinctImmutableListOf(List list) { @@ -48,6 +51,10 @@ private OntologySourceData(Builder builder) { return curies; } + public Set getLabelTsvs() { + return labelTsvs; + } + public List getIndividualAssociationTsvs() { return individualAssociationTsvs; } @@ -65,7 +72,8 @@ public boolean equals(Object o) { Objects.equals(dataOntologies, that.dataOntologies) && Objects.equals(curies, that.curies) && Objects.equals(individualAssociationTsvs, that.individualAssociationTsvs) && - Objects.equals(individualAssociations, that.individualAssociations); + Objects.equals(individualAssociations, that.individualAssociations) && + Objects.equals(labelTsvs, that.labelTsvs); } @Override @@ -81,6 +89,7 @@ public String toString() { ", curies=" + curies + ", individualAssociationTsvs=" + individualAssociationTsvs + ", individualAssociations=" + individualAssociations + + ", labelTsvs=" + labelTsvs + '}'; } @@ -95,6 +104,7 @@ public static Builder builder() { private Map curies = Collections.emptyMap(); private List individualAssociationTsvs = new ArrayList<>(); private Map> individualAssociations = new HashMap<>(); + private Set labelTsvs = Collections.emptySet(); private Builder(){ //use the static method. @@ -180,6 +190,11 @@ public Builder individualAssociations(Map> individualAssociations.putAll(mappings); return this; } + + public Builder labelTsvs(Set labelTsvs) { + this.labelTsvs = labelTsvs; + return this; + } public OntologySourceData build() { if(ontologies.isEmpty()) { diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBase.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBase.java index 7251aae..fb38e85 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBase.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBase.java @@ -11,6 +11,7 @@ import java.io.File; import java.util.Collection; import java.util.Map; +import java.util.Set; /** * A convenience wrapper to enable easy loading of a {@link BMKnowledgeBase} from OWL ontologies and data files. @@ -52,6 +53,15 @@ public Loader loadCuries(Map curies) { } /** + * @param labelTsvs + * @return + */ + public Loader loadLabelsFromTsv(Set labelTsvs) { + sourceDataBuilder.labelTsvs(labelTsvs); + return this; + } + + /** * Loads an OWL/OBO ontology from a file. * * @param file diff --git a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologyTest.java b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologyTest.java index 8fcd0a2..0ba633a 100644 --- a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologyTest.java +++ b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologyTest.java @@ -1,171 +1,205 @@ package org.monarchinitiative.owlsim.io; -import com.google.common.collect.ImmutableSet; -import org.junit.Test; -import org.semanticweb.owlapi.model.*; -import org.semanticweb.owlapi.model.parameters.Imports; +import static org.junit.Assert.assertEquals; +import java.io.File; +import java.io.IOException; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Set; -import static org.junit.Assert.assertEquals; +import org.apache.commons.io.FileUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLIndividualAxiom; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.parameters.Imports; + +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Sets; /** * @author Jules Jacobsen */ public class OntologyTest { - private Map getHpAndNameCurieMap() { - Map curies = new HashMap<>(); - curies.put("HP", "http://purl.obolibrary.org/obo/HP_"); - curies.put("MINION", "http://despicableme.wikia.com/wiki/"); - return curies; - } - - private Ontology getBobOnlyOntology() { - Map curies = getHpAndNameCurieMap(); - - Map> data = new HashMap<>(); - data.put("MINION:Bob", toSet("HP:0000952;HP:0001090;HP:0008857;HP:0001006;HP:0006101;HP:0001100")); - - OntologySourceData sourceData = OntologySourceData.builder() - .ontology("src/test/resources/species-no-individuals.owl") - .curies(curies) - .individualAssociations(data) - .build(); - - return Ontology.load(sourceData); - } - - private Set toSet(String input) { - return Arrays.stream(input.split("[,;]")).map(String::trim).collect(ImmutableSet.toImmutableSet()); - } - - private Set getAxiomsForIndividual(Ontology ontology, String individual) { - OWLOntology owlOntology = ontology.getOwlOntology(); - OWLOntologyManager manager = owlOntology.getOWLOntologyManager(); - OWLDataFactory owlDataFactory = manager.getOWLDataFactory(); - OWLNamedIndividual owlNamedIndividual = owlDataFactory.getOWLNamedIndividual(ontology.toIri(individual)); - return owlOntology.getAxioms(owlNamedIndividual, Imports.INCLUDED); - } - - @Test(expected = NullPointerException.class) - public void testAddNullIndividuals() { - Map curies = getHpAndNameCurieMap(); - - Map> data = new HashMap<>(); - data.put(null, toSet("HP:0000952,HP:0001090,HP:0004322,HP:0001006,HP:0006101")); - - OntologySourceData sourceData = OntologySourceData.builder() - .ontology("src/test/resources/species-no-individuals.owl") - .curies(curies) - .individualAssociations(data) - .build(); - - Ontology.load(sourceData); - } - - @Test(expected = NullPointerException.class) - public void testAddNullClasses() { - Map curies = getHpAndNameCurieMap(); - - Map> data = new HashMap<>(); - data.put("MINION:Kevin", null); - - OntologySourceData sourceData = OntologySourceData.builder() - .ontology("src/test/resources/species-no-individuals.owl") - .curies(curies) - .individualAssociations(data) - .build(); - - Ontology.load(sourceData); - } - - @Test - public void testAddIndividuals() { - Map curies = getHpAndNameCurieMap(); - - Map> data = new HashMap<>(); - //Concatenated - should be able to parse TSV, CSV and trim whitespace - data.put("MINION:Kevin", toSet("HP:0000952,HP:0001090,HP:0004322,HP:0001006,HP:0006101")); - data.put("MINION:Bob", toSet("HP:0000952;HP:0001090;HP:0008857;HP:0001006;HP:0006101;HP:0001100")); - //mixed - data.put("MINION:Stuart", toSet("HP:0000952; HP:0001090;HP:0008857 ;HP:0001006, HP:0006101,HP:0100754, HP:0009914 ")); - - OntologySourceData sourceData = OntologySourceData.builder() - .ontology("src/test/resources/species-no-individuals.owl") - .curies(curies) - .individualAssociations(data) - .build(); - - Ontology ontology = Ontology.load(sourceData); - - Set kevinAxioms = getAxiomsForIndividual(ontology, "MINION:Kevin"); - kevinAxioms.forEach(axiom -> { - Set classes = axiom.getClassesInSignature(); - classes.forEach(ontologyClass -> System.out.printf("Individual: %s Class: %s%n", axiom.getIndividualsInSignature(), ontologyClass)); - }); - - assertEquals(5, kevinAxioms.size()); - Set bobAxioms = getAxiomsForIndividual(ontology, "MINION:Bob"); - assertEquals(6, bobAxioms.size()); - Set stuartAxioms = getAxiomsForIndividual(ontology, "MINION:Stuart"); - assertEquals(7, stuartAxioms.size()); - } - - @Test - public void testIriConversion() { - Map curies = getHpAndNameCurieMap(); - - OntologySourceData sourceData = OntologySourceData.builder() - .ontology("src/test/resources/species-no-individuals.owl") - .curies(curies) - .build(); - - Ontology ontology = Ontology.load(sourceData); - - IRI bobNotFound = ontology.toIri("Bob"); - System.out.println(bobNotFound); - assertEquals("Bob", bobNotFound.toString()); - assertEquals(ontology.toCurie(bobNotFound), "Bob"); - - IRI bobFound = ontology.toIri("MINION:Bob"); - System.out.println(bobFound); - assertEquals("http://despicableme.wikia.com/wiki/Bob", bobFound.toString()); - assertEquals(ontology.toCurie(bobFound), "MINION:Bob"); - - } - - @Test - public void testGetOwlClass() { - Ontology ontology = getBobOnlyOntology(); - - OWLClass hpClass = ontology.getOWLClass("HP:0000952"); - System.out.println(hpClass); - assertEquals(hpClass.toString(), ""); - - OWLClass bobFound = ontology.getOWLClass("MINION:Bob"); - System.out.println(bobFound); - assertEquals(bobFound.toString(), ""); - } - - @Test - public void testGetOwlNamedIndividual() { - Ontology ontology = getBobOnlyOntology(); - - OWLNamedIndividual notFound = ontology.getOWLNamedIndividual("wibble"); - System.out.println(notFound); - assertEquals(notFound.toString(), ""); - - OWLNamedIndividual hpTerm = ontology.getOWLNamedIndividual("HP:0000952"); - System.out.println(hpTerm); - assertEquals(hpTerm.toString(), ""); - - OWLNamedIndividual bob = ontology.getOWLNamedIndividual("MINION:Bob"); - System.out.println(bob); - assertEquals(bob.toString(), ""); - } + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + private Map getHpAndNameCurieMap() { + Map curies = new HashMap<>(); + curies.put("HP", "http://purl.obolibrary.org/obo/HP_"); + curies.put("MINION", "http://despicableme.wikia.com/wiki/"); + return curies; + } + + private Ontology getBobOnlyOntology() { + Map curies = getHpAndNameCurieMap(); + + Map> data = new HashMap<>(); + data.put("MINION:Bob", toSet("HP:0000952;HP:0001090;HP:0008857;HP:0001006;HP:0006101;HP:0001100")); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies).individualAssociations(data) + .build(); + + return Ontology.load(sourceData); + } + + private Set toSet(String input) { + return Arrays.stream(input.split("[,;]")).map(String::trim).collect(ImmutableSet.toImmutableSet()); + } + + private Set getAxiomsForIndividual(Ontology ontology, String individual) { + OWLOntology owlOntology = ontology.getOwlOntology(); + OWLOntologyManager manager = owlOntology.getOWLOntologyManager(); + OWLDataFactory owlDataFactory = manager.getOWLDataFactory(); + OWLNamedIndividual owlNamedIndividual = owlDataFactory.getOWLNamedIndividual(ontology.toIri(individual)); + return owlOntology.getAxioms(owlNamedIndividual, Imports.INCLUDED); + } + + @Test(expected = NullPointerException.class) + public void testAddNullIndividuals() { + Map curies = getHpAndNameCurieMap(); + + Map> data = new HashMap<>(); + data.put(null, toSet("HP:0000952,HP:0001090,HP:0004322,HP:0001006,HP:0006101")); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies).individualAssociations(data) + .build(); + + Ontology.load(sourceData); + } + + @Test(expected = NullPointerException.class) + public void testAddNullClasses() { + Map curies = getHpAndNameCurieMap(); + + Map> data = new HashMap<>(); + data.put("MINION:Kevin", null); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies).individualAssociations(data) + .build(); + + Ontology.load(sourceData); + } + + @Test + public void testAddIndividuals() { + Map curies = getHpAndNameCurieMap(); + + Map> data = new HashMap<>(); + // Concatenated - should be able to parse TSV, CSV and trim whitespace + data.put("MINION:Kevin", toSet("HP:0000952,HP:0001090,HP:0004322,HP:0001006,HP:0006101")); + data.put("MINION:Bob", toSet("HP:0000952;HP:0001090;HP:0008857;HP:0001006;HP:0006101;HP:0001100")); + // mixed + data.put("MINION:Stuart", + toSet("HP:0000952; HP:0001090;HP:0008857 ;HP:0001006, HP:0006101,HP:0100754, HP:0009914 ")); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies).individualAssociations(data) + .build(); + + Ontology ontology = Ontology.load(sourceData); + + Set kevinAxioms = getAxiomsForIndividual(ontology, "MINION:Kevin"); + kevinAxioms.forEach(axiom -> { + Set classes = axiom.getClassesInSignature(); + classes.forEach(ontologyClass -> System.out.printf("Individual: %s Class: %s%n", + axiom.getIndividualsInSignature(), ontologyClass)); + }); + + assertEquals(5, kevinAxioms.size()); + Set bobAxioms = getAxiomsForIndividual(ontology, "MINION:Bob"); + assertEquals(6, bobAxioms.size()); + Set stuartAxioms = getAxiomsForIndividual(ontology, "MINION:Stuart"); + assertEquals(7, stuartAxioms.size()); + } + + @Test + public void testIriConversion() { + Map curies = getHpAndNameCurieMap(); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies).build(); + + Ontology ontology = Ontology.load(sourceData); + + IRI bobNotFound = ontology.toIri("Bob"); + System.out.println(bobNotFound); + assertEquals("Bob", bobNotFound.toString()); + assertEquals(ontology.toCurie(bobNotFound), "Bob"); + + IRI bobFound = ontology.toIri("MINION:Bob"); + System.out.println(bobFound); + assertEquals("http://despicableme.wikia.com/wiki/Bob", bobFound.toString()); + assertEquals(ontology.toCurie(bobFound), "MINION:Bob"); + + } + + @Test + public void testGetOwlClass() { + Ontology ontology = getBobOnlyOntology(); + + OWLClass hpClass = ontology.getOWLClass("HP:0000952"); + System.out.println(hpClass); + assertEquals(hpClass.toString(), ""); + + OWLClass bobFound = ontology.getOWLClass("MINION:Bob"); + System.out.println(bobFound); + assertEquals(bobFound.toString(), ""); + } + + @Test + public void testGetOwlNamedIndividual() { + Ontology ontology = getBobOnlyOntology(); + + OWLNamedIndividual notFound = ontology.getOWLNamedIndividual("wibble"); + System.out.println(notFound); + assertEquals(notFound.toString(), ""); + + OWLNamedIndividual hpTerm = ontology.getOWLNamedIndividual("HP:0000952"); + System.out.println(hpTerm); + assertEquals(hpTerm.toString(), ""); + + OWLNamedIndividual bob = ontology.getOWLNamedIndividual("MINION:Bob"); + System.out.println(bob); + assertEquals(bob.toString(), ""); + } + + @Test + public void testLabels() throws IOException { + String target = "MINION:Bob"; + String label = "Bobby bob"; + + File tmpFile = folder.newFile("labels.tsv"); + FileUtils.writeStringToFile(tmpFile, target + "\t" + label, "UTF-8"); + + Map curies = getHpAndNameCurieMap(); + + OntologySourceData sourceData = OntologySourceData.builder() + .ontology("src/test/resources/species-no-individuals.owl").curies(curies) + .labelTsvs(Sets.newHashSet(tmpFile.getAbsolutePath())).build(); + + Ontology ontology = Ontology.load(sourceData); + OWLNamedIndividual individual = ontology.getOWLNamedIndividual(target); + + Set annotations = ontology.getOwlOntology() + .getAnnotationAssertionAxioms(individual.getIRI()); + assertEquals(annotations.size(), 1); + String extractedProperty = annotations.iterator().next().getValue().asLiteral().get().getLiteral(); + assertEquals(extractedProperty, label); + + } } \ No newline at end of file diff --git a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/OwlSimServiceApplication.java b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/OwlSimServiceApplication.java index 47f3bfd..90f193f 100644 --- a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/OwlSimServiceApplication.java +++ b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/OwlSimServiceApplication.java @@ -15,34 +15,37 @@ */ package org.monarchinitiative.owlsim.services; +import java.util.EnumSet; +import java.util.Set; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration; + +import org.apache.log4j.Logger; +import org.eclipse.jetty.servlets.CrossOriginFilter; +import org.monarchinitiative.owlsim.services.configuration.ApplicationConfiguration; +import org.monarchinitiative.owlsim.services.modules.EnrichmentMapModule; +import org.monarchinitiative.owlsim.services.modules.KnowledgeBaseModule; +import org.monarchinitiative.owlsim.services.modules.MatcherMapModule; +import org.semanticweb.owlapi.OWLAPIParsersModule; +import org.semanticweb.owlapi.OWLAPIServiceLoaderModule; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.databind.SerializationFeature; import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath.ClassInfo; import com.google.inject.Guice; import com.google.inject.Injector; + import io.dropwizard.Application; import io.dropwizard.assets.AssetsBundle; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import io.swagger.jaxrs.config.BeanConfig; import io.swagger.jaxrs.listing.ApiListingResource; -import org.apache.log4j.Logger; -import org.eclipse.jetty.servlets.CrossOriginFilter; -import org.monarchinitiative.owlsim.services.configuration.ApplicationConfiguration; -import org.monarchinitiative.owlsim.services.modules.EnrichmentMapModule; -import org.monarchinitiative.owlsim.services.modules.KnowledgeBaseModule; -import org.monarchinitiative.owlsim.services.modules.MatcherMapModule; -import org.semanticweb.owlapi.OWLAPIParsersModule; -import org.semanticweb.owlapi.OWLAPIServiceLoaderModule; import uk.ac.manchester.cs.owl.owlapi.OWLAPIImplModule; import uk.ac.manchester.cs.owl.owlapi.concurrent.Concurrency; -import javax.servlet.DispatcherType; -import javax.servlet.FilterRegistration; -import java.util.EnumSet; -import java.util.Set; - public class OwlSimServiceApplication extends Application { private Logger LOG = Logger.getLogger(OwlSimServiceApplication.class); @@ -141,9 +144,10 @@ public void run(ApplicationConfiguration configuration, Environment environment) Injector i = Guice.createInjector(new OWLAPIImplModule(concurrency), new OWLAPIParsersModule(), new OWLAPIServiceLoaderModule(), new KnowledgeBaseModule(configuration.getOntologyUris(), configuration.getOntologyDataUris(), - configuration.getDataTsvs(), configuration.getCuries()), + configuration.getDataTsvs(), configuration.getLabelTsvs(), configuration.getCuries()), new EnrichmentMapModule(), new MatcherMapModule()); - //removed binding info as this caused things to explode. Wasn't helpful. + // removed binding info as this caused things to explode. Wasn't + // helpful. // Add resources Set resourceClasses = ClassPath.from(getClass().getClassLoader()) .getTopLevelClasses("org.monarchinitiative.owlsim.services.resources"); @@ -153,5 +157,4 @@ public void run(ApplicationConfiguration configuration, Environment environment) } } - } diff --git a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/configuration/ApplicationConfiguration.java b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/configuration/ApplicationConfiguration.java index 7cb7cd1..fe72be5 100644 --- a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/configuration/ApplicationConfiguration.java +++ b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/configuration/ApplicationConfiguration.java @@ -23,6 +23,8 @@ import javax.validation.constraints.NotNull; +import com.google.monitoring.runtime.instrumentation.common.com.google.common.collect.Sets; + public class ApplicationConfiguration extends Configuration { @NotNull @@ -35,8 +37,10 @@ private Set dataTsvs; private Map curies = new HashMap(); + + private Set labelTsvs = Sets.newHashSet(); - public Set getOntologyUris() { + public Set getOntologyUris() { return ontologyUris; } @@ -52,4 +56,8 @@ return curies; } + public Set getLabelTsvs() { + return labelTsvs; + } + } diff --git a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/modules/KnowledgeBaseModule.java b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/modules/KnowledgeBaseModule.java index dde9e3b..0b3b2a9 100644 --- a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/modules/KnowledgeBaseModule.java +++ b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/modules/KnowledgeBaseModule.java @@ -22,7 +22,7 @@ private final BMKnowledgeBase bmKnowledgeBase; - public KnowledgeBaseModule(Collection ontologyUris, Collection ontologyDataUris, Set dataTsvs, Map curies) { + public KnowledgeBaseModule(Collection ontologyUris, Collection ontologyDataUris, Set dataTsvs, Set labelTsvs, Map curies) { logger.info("Loading ontologyUris:"); ontologyUris.forEach(logger::info); @@ -32,6 +32,8 @@ public KnowledgeBaseModule(Collection ontologyUris, Collection o dataTsvs.forEach(logger::info); logger.info("Loading curies:"); curies.entrySet().forEach(logger::info); + logger.info("Loading labels:"); + //labels.entrySet().forEach(logger::info); //The OwlKnowledgeBase.Loader uses the ELKReasonerFactory and Concurrency.CONCURRENT as defaults. this.bmKnowledgeBase = OwlKnowledgeBase.loader() @@ -39,6 +41,7 @@ public KnowledgeBaseModule(Collection ontologyUris, Collection o .loadDataFromOntologies(ontologyDataUris) .loadIndividualAssociationsFromTsv(dataTsvs) .loadCuries(curies) + .loadLabelsFromTsv(labelTsvs) .createKnowledgeBase(); logger.info("Created BMKnowledgebase"); diff --git a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/resources/OntologyMatchResource.java b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/resources/OntologyMatchResource.java index 9847eea..5f40bc0 100644 --- a/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/resources/OntologyMatchResource.java +++ b/owlsim-services/src/main/java/org/monarchinitiative/owlsim/services/resources/OntologyMatchResource.java @@ -15,7 +15,6 @@ import org.monarchinitiative.owlsim.compute.cpt.IncoherentStateException; import org.monarchinitiative.owlsim.kb.filter.UnknownFilterException; import org.monarchinitiative.owlsim.model.match.MatchSet; -import org.prefixcommons.CurieUtil; import com.codahale.metrics.annotation.Timed;