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 35f6b72..4d68dc0 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 @@ -17,6 +17,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.BiConsumer; import java.util.zip.GZIPInputStream; /** @@ -34,6 +35,7 @@ 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."); @@ -41,6 +43,7 @@ private Ontology(OntologySourceData sourceData, Concurrency concurrency) { this.curieUtil = new CurieUtil(sourceData.getCuries()); this.ontologyManager = createOntologyManager(concurrency); this.owlOntology = createEmptyOntology(ontologyManager); + this.owlDataFactory = ontologyManager.getOWLDataFactory(); loadOwlOntology(); } @@ -81,12 +84,29 @@ 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()); - loadDataFromTsv(sourceData.getDataTsvs()); - loadDataFromPairwiseMappings(sourceData.getPairwiseMappings()); + loadIndividualAssociationsFromTsv(sourceData.getIndividualAssociationTsvs()); + loadIndividualAssociationsFromMap(sourceData.getIndividualAssociations()); logger.info("Ontology loaded"); } @@ -118,10 +138,6 @@ private OWLOntology mergeOntologies(Collection uris) { return owlOntology; } - private ChangeApplied addAxiom(OWLAxiom axiom) { - return ontologyManager.addAxiom(owlOntology, axiom); - } - private ChangeApplied addAxioms(Set axioms) { return ontologyManager.addAxioms(owlOntology, axioms); } @@ -159,12 +175,12 @@ private OWLOntology loadOwlOntology(IRI iri) { } } - private OWLOntology loadDataFromTsv(Collection paths) { - paths.forEach(this::loadDataFromTsv); + private OWLOntology loadIndividualAssociationsFromTsv(Collection paths) { + paths.forEach(this::loadIndividualAssociationsFromTsv); return owlOntology; } - private OWLOntology loadDataFromTsv(String path) { + private OWLOntology loadIndividualAssociationsFromTsv(String path) { if (path.endsWith(".gz")) { return loadDataFromTsvGzip(path); } @@ -191,8 +207,20 @@ private OWLOntology loadDataFromTsvGzip(String path) { return owlOntology; } - private void loadDataFromPairwiseMappings(Map pairwiseMappings) { - pairwiseMappings.forEach(this::addInstanceOf); + 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) { @@ -204,15 +232,22 @@ private void loadLineIntoDataOntology(String line) { } private void addInstanceOf(String individual, String ontologyClass) { -// logger.info("Adding axiom " + individual + ": " + ontologyClass); - OWLDataFactory owlDataFactory = ontologyManager.getOWLDataFactory(); - OWLClass owlClass = owlDataFactory.getOWLClass(toIri(ontologyClass)); - OWLNamedIndividual owlNamedIndividual = owlDataFactory.getOWLNamedIndividual(toIri(individual)); - OWLClassAssertionAxiom axiom = owlDataFactory.getOWLClassAssertionAxiom(owlClass, owlNamedIndividual); - addAxiom(axiom); + 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); } - private IRI toIri(String id) { + IRI toIri(String id) { return IRI.create(curieUtil.getIri(id).orElse(id)); } 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 8e47937..e9773a1 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 @@ -20,16 +20,16 @@ private final List dataOntologies; private final Map curies; - private final List dataTsvs; - //TODO: add these so people can programmatically add individual assertions - private final Map pairwiseMappings; + private final List individualAssociationTsvs; + private final Map> individualAssociations; + //TODO - labels? private OntologySourceData(Builder builder) { this.ontologies = distinctImmutableListOf(builder.ontologies); this.dataOntologies = distinctImmutableListOf(builder.dataOntologies); this.curies = ImmutableMap.copyOf(builder.curies); - this.dataTsvs = distinctImmutableListOf(builder.dataTsvs); - this.pairwiseMappings = ImmutableMap.copyOf(builder.pairwiseMappings); + this.individualAssociationTsvs = distinctImmutableListOf(builder.individualAssociationTsvs); + this.individualAssociations = ImmutableMap.copyOf(builder.individualAssociations); } private ImmutableList distinctImmutableListOf(List list) { @@ -48,12 +48,12 @@ private OntologySourceData(Builder builder) { return curies; } - public List getDataTsvs() { - return dataTsvs; + public List getIndividualAssociationTsvs() { + return individualAssociationTsvs; } - public Map getPairwiseMappings() { - return pairwiseMappings; + public Map> getIndividualAssociations() { + return individualAssociations; } @Override @@ -64,13 +64,13 @@ public boolean equals(Object o) { return Objects.equals(ontologies, that.ontologies) && Objects.equals(dataOntologies, that.dataOntologies) && Objects.equals(curies, that.curies) && - Objects.equals(dataTsvs, that.dataTsvs) && - Objects.equals(pairwiseMappings, that.pairwiseMappings); + Objects.equals(individualAssociationTsvs, that.individualAssociationTsvs) && + Objects.equals(individualAssociations, that.individualAssociations); } @Override public int hashCode() { - return Objects.hash(ontologies, dataOntologies, curies, dataTsvs, pairwiseMappings); + return Objects.hash(ontologies, dataOntologies, curies, individualAssociationTsvs, individualAssociations); } @Override @@ -79,8 +79,8 @@ public String toString() { "ontologies=" + ontologies + ", dataOntologies=" + dataOntologies + ", curies=" + curies + - ", dataTsvs=" + dataTsvs + - ", pairwiseMappings=" + pairwiseMappings + + ", individualAssociationTsvs=" + individualAssociationTsvs + + ", individualAssociations=" + individualAssociations + '}'; } @@ -93,8 +93,8 @@ public static Builder builder() { private List dataOntologies = new ArrayList<>(); //Curies need to be supplied if people are adding data using TSV files or pairwise mappings using curies. private Map curies = Collections.emptyMap(); - private List dataTsvs = new ArrayList<>(); - private Map pairwiseMappings = Collections.emptyMap(); + private List individualAssociationTsvs = new ArrayList<>(); + private Map> individualAssociations = new HashMap<>(); private Builder(){ //use the static method. @@ -161,18 +161,23 @@ public Builder dataOntologies(Collection paths) { return this; } - public Builder dataTsv(String path) { - dataTsvs.add(path); + public Builder individualAssociationsTsv(String path) { + individualAssociationTsvs.add(path); return this; } - public Builder dataTsv(String... paths) { - dataTsvs.addAll(Arrays.asList(paths)); + public Builder individualAssociationsTsv(String... paths) { + individualAssociationTsvs.addAll(Arrays.asList(paths)); return this; } - public Builder dataTsv(Collection paths) { - dataTsvs.addAll(paths); + public Builder individualAssociationsTsv(Collection paths) { + individualAssociationTsvs.addAll(paths); + return this; + } + + public Builder individualAssociations(Map> mappings) { + individualAssociations.putAll(mappings); return this; } @@ -180,14 +185,14 @@ public OntologySourceData build() { if(ontologies.isEmpty()) { throw new OntologyLoadException("No ontology defined."); } - if (curies.isEmpty() && hasNonOntologyData()) { - throw new OntologyLoadException("Cannot load TSV data sources or pairwise mappings when curies have not been defined."); + if (curies.isEmpty() && hasIndividualAssociationData()) { + throw new OntologyLoadException("Cannot load individual class associations when curies have not been defined."); } return new OntologySourceData(this); } - private boolean hasNonOntologyData() { - return !dataTsvs.isEmpty() || !pairwiseMappings.isEmpty(); + private boolean hasIndividualAssociationData() { + return !individualAssociationTsvs.isEmpty() || !individualAssociations.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 cf206de..7251aae 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 @@ -57,7 +57,6 @@ public Loader loadCuries(Map curies) { * @param file */ public Loader loadOntology(File file) { - Math.random(); sourceDataBuilder.ontology(file); return this; } @@ -103,18 +102,23 @@ public Loader loadDataFromOntologies(Collection paths) { return this; } - public Loader loadDataFromTsv(String path) { - sourceDataBuilder.dataTsv(path); + public Loader loadIndividualAssociationsFromTsv(String path) { + sourceDataBuilder.individualAssociationsTsv(path); return this; } - public Loader loadDataFromTsv(String... paths) { - sourceDataBuilder.dataTsv(paths); + public Loader loadIndividualAssociationsFromTsv(String... paths) { + sourceDataBuilder.individualAssociationsTsv(paths); return this; } - public Loader loadDataFromTsv(Collection paths) { - sourceDataBuilder.dataTsv(paths); + public Loader loadIndividualAssociationsFromTsv(Collection paths) { + sourceDataBuilder.individualAssociationsTsv(paths); + return this; + } + + public Loader loadIndividualAssociations(Map> data) { + sourceDataBuilder.individualAssociations(data); return this; } diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/BMKnowledgeBase.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/BMKnowledgeBase.java index c360197..8e36cee 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/BMKnowledgeBase.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/BMKnowledgeBase.java @@ -1,13 +1,13 @@ package org.monarchinitiative.owlsim.kb; -import java.util.Map; -import java.util.Set; - +import com.googlecode.javaewah.EWAHCompressedBitmap; +import org.monarchinitiative.owlsim.io.OwlKnowledgeBase; import org.monarchinitiative.owlsim.kb.impl.BMKnowledgeBaseOWLAPIImpl; import org.monarchinitiative.owlsim.model.kb.Attribute; import org.monarchinitiative.owlsim.model.kb.Entity; -import com.googlecode.javaewah.EWAHCompressedBitmap; +import java.util.Map; +import java.util.Set; /** * An interface to an ontology in which the fundamental unit of representation of @@ -358,5 +358,10 @@ */ public String resolveIri(String entity); + + + public static OwlKnowledgeBase.Loader owlLoader() { + return OwlKnowledgeBase.loader(); + } } diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/impl/BMKnowledgeBaseOWLAPIImpl.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/impl/BMKnowledgeBaseOWLAPIImpl.java index 3bb84df..444f212 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/impl/BMKnowledgeBaseOWLAPIImpl.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/kb/impl/BMKnowledgeBaseOWLAPIImpl.java @@ -1,10 +1,12 @@ package org.monarchinitiative.owlsim.kb.impl; -import java.time.Duration; -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - +import com.google.common.base.Preconditions; +import com.googlecode.javaewah.EWAHCompressedBitmap; +import com.hp.hpl.jena.query.*; +import com.hp.hpl.jena.rdf.model.Literal; +import com.hp.hpl.jena.rdf.model.Model; +import com.hp.hpl.jena.rdf.model.RDFNode; +import com.hp.hpl.jena.rdf.model.Resource; import org.apache.log4j.Logger; import org.monarchinitiative.owlsim.io.OWLLoader; import org.monarchinitiative.owlsim.io.Ontology; @@ -16,49 +18,16 @@ import org.monarchinitiative.owlsim.model.kb.Entity; import org.monarchinitiative.owlsim.model.kb.KBMetadata; import org.prefixcommons.CurieUtil; -import org.semanticweb.owlapi.model.AxiomType; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotation; -import org.semanticweb.owlapi.model.OWLAnnotationAssertionAxiom; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLAnnotationValue; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLDataProperty; -import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLDisjointClassesAxiom; -import org.semanticweb.owlapi.model.OWLIndividual; -import org.semanticweb.owlapi.model.OWLIndividualAxiom; -import org.semanticweb.owlapi.model.OWLLiteral; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLNamedObject; -import org.semanticweb.owlapi.model.OWLObjectComplementOf; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLPropertyAssertionAxiom; -import org.semanticweb.owlapi.model.OWLPropertyAssertionObject; -import org.semanticweb.owlapi.model.OWLPropertyExpression; +import org.semanticweb.owlapi.model.*; import org.semanticweb.owlapi.reasoner.Node; import org.semanticweb.owlapi.reasoner.NodeSet; import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; -import com.google.common.base.Preconditions; -import com.googlecode.javaewah.EWAHCompressedBitmap; -import com.hp.hpl.jena.query.Query; -import com.hp.hpl.jena.query.QueryExecution; -import com.hp.hpl.jena.query.QueryExecutionFactory; -import com.hp.hpl.jena.query.QueryFactory; -import com.hp.hpl.jena.query.QuerySolution; -import com.hp.hpl.jena.query.ResultSet; -import com.hp.hpl.jena.rdf.model.Literal; -import com.hp.hpl.jena.rdf.model.Model; -import com.hp.hpl.jena.rdf.model.RDFNode; -import com.hp.hpl.jena.rdf.model.Resource; +import java.time.Duration; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; /** * Implementation of {@link BMKnowledgeBase} that uses the OWLAPI. @@ -431,7 +400,7 @@ private void addOpposingClassPairAsym(OWLClass c, OWLClassExpression d) { } private void storeInferences() { - + LOG.info("Storing inferences..."); // Note: if there are any nodes containing >1 class or individual, then // the store method is called redundantly. This is unlikely to affect performance, // and the semantics are unchanged @@ -1057,7 +1026,7 @@ private OWLNamedIndividual getOWLNamedIndividual(IRI iri) { * CURIE-style * @return OWLAPI Class object */ - public OWLNamedIndividual getOWLNamedIndividual(String id) { + private OWLNamedIndividual getOWLNamedIndividual(String id) { Preconditions.checkNotNull(id); return getOWLNamedIndividual(IRI.create(curieUtil.getIri(id).orElse(id))); } diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Attribute.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Attribute.java index 2082020..6eec94f 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Attribute.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Attribute.java @@ -1,26 +1,50 @@ package org.monarchinitiative.owlsim.model.kb; +import java.util.Objects; + /** * @author cjm * */ public class Attribute implements SimpleObject { - private String id; - private String label; + private final String id; + private final String label; public Attribute(String id, String label) { - super(); this.id = id; this.label = label; } + @Override public String getId() { return id; } + @Override public String getLabel() { return label; } - + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Attribute attribute = (Attribute) o; + return Objects.equals(id, attribute.id) && + Objects.equals(label, attribute.label); + } + + @Override + public int hashCode() { + return Objects.hash(id, label); + } + + @Override + public String toString() { + return "Attribute{" + + "id='" + id + '\'' + + ", label='" + label + '\'' + + '}'; + } } diff --git a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Entity.java b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Entity.java index af32f80..06a5b2c 100644 --- a/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Entity.java +++ b/owlsim-core/src/main/java/org/monarchinitiative/owlsim/model/kb/Entity.java @@ -1,34 +1,50 @@ package org.monarchinitiative.owlsim.model.kb; +import java.util.Objects; + /** * @author cjm * */ public class Entity implements SimpleObject { - private String id; - private String label; + private final String id; + private final String label; public Entity(String id, String label) { - super(); this.id = id; this.label = label; } - public void setId(String id) { - this.id = id; - } - - public void setLabel(String label) { - this.label = label; - } - + @Override public String getId() { return id; } + @Override public String getLabel() { return label; } - + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Entity entity = (Entity) o; + return Objects.equals(id, entity.id) && + Objects.equals(label, entity.label); + } + + @Override + public int hashCode() { + return Objects.hash(id, label); + } + + @Override + public String toString() { + return "Entity{" + + "id='" + id + '\'' + + ", label='" + label + '\'' + + '}'; + } } diff --git a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/compute/matcher/perf/HomologyPhenoPerfIT.java b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/compute/matcher/perf/HomologyPhenoPerfIT.java index e8e4270..0cb9276 100644 --- a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/compute/matcher/perf/HomologyPhenoPerfIT.java +++ b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/compute/matcher/perf/HomologyPhenoPerfIT.java @@ -127,7 +127,7 @@ private void load() throws OWLOntologyCreationException, IOException { kb = OwlKnowledgeBase.loader() .loadCuries(curies) .loadOntology("src/test/resources/ontologies/mammal.obo.gz") - .loadDataFromTsv( + .loadIndividualAssociationsFromTsv( "src/test/resources/data/gene2taxon.tsv.gz", "src/test/resources/data/mouse-pheno.assocs.gz", "src/test/resources/data/human-pheno.assocs.gz") diff --git a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologySourceDataTest.java b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologySourceDataTest.java index c01b275..3ccd0ff 100644 --- a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologySourceDataTest.java +++ b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologySourceDataTest.java @@ -2,7 +2,9 @@ import org.junit.Test; +import java.util.Arrays; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -18,12 +20,37 @@ public void testItAll() { curies.put("MP", "http://purl.obolibrary.org/obo/MP_"); curies.put("NCBITaxon", "http://purl.obolibrary.org/obo/NCBITaxon_"); + Map> individuals = new LinkedHashMap<>(); + individuals.put("ORPHA:710", Arrays.asList("HP:0000194", + "HP:0000218", + "HP:0000262", + "HP:0000303", + "HP:0000316", + "HP:0000322", + "HP:0000324", + "HP:0000348", + "HP:0000431", + "HP:0000470", + "HP:0000508", + "HP:0001156", + "HP:0001385", + "HP:0003307", + "HP:0004209", + "HP:0004322", + "HP:0005048", + "HP:0006101", + "HP:0009773", + "HP:0010669", + "HP:0011304", + "HP:0012368", "")); + OntologySourceData sourceData = OntologySourceData.builder() .curies(curies) .ontology("src/test/resources/ontologies/mammal.obo.gz") - .dataTsv("src/test/resources/data/gene2taxon.tsv.gz") - .dataTsv("src/test/resources/data/mouse-pheno.assocs.gz") - .dataTsv("src/test/resources/data/human-pheno.assocs.gz") + .individualAssociationsTsv("src/test/resources/data/gene2taxon.tsv.gz") + .individualAssociationsTsv("src/test/resources/data/mouse-pheno.assocs.gz") + .individualAssociationsTsv("src/test/resources/data/human-pheno.assocs.gz") + .individualAssociations(individuals) .build(); System.out.println(sourceData); @@ -33,7 +60,7 @@ public void testItAll() { public void testThrowsExceptionWhenCuriesEmptyAndDataIncludedFromTsv() { OntologySourceData sourceData = OntologySourceData.builder() - .dataTsv("src/test/resources/data/gene2taxon.tsv.gz") + .individualAssociationsTsv("src/test/resources/data/gene2taxon.tsv.gz") .build(); System.out.println(sourceData); 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 new file mode 100644 index 0000000..8fcd0a2 --- /dev/null +++ b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OntologyTest.java @@ -0,0 +1,171 @@ +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 java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import static org.junit.Assert.assertEquals; + +/** + * @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(), ""); + } + +} \ No newline at end of file diff --git a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBaseTest.java b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBaseTest.java index 57fa1ec..484f9ba 100644 --- a/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBaseTest.java +++ b/owlsim-core/src/test/java/org/monarchinitiative/owlsim/io/OwlKnowledgeBaseTest.java @@ -1,13 +1,12 @@ package org.monarchinitiative.owlsim.io; +import com.google.common.collect.Sets; import org.junit.Test; import org.monarchinitiative.owlsim.kb.BMKnowledgeBase; import uk.ac.manchester.cs.jfact.JFactFactory; import java.io.File; -import java.util.Arrays; -import java.util.LinkedHashMap; -import java.util.Map; +import java.util.*; import static org.junit.Assert.assertEquals; @@ -77,7 +76,7 @@ public void testLoadRemoteOntology() { @Test(expected = OntologyLoadException.class) public void testLoadGzippedDataFileNoOntology() { BMKnowledgeBase bmKnowledgeBase = OwlKnowledgeBase.loader() - .loadDataFromTsv("src/test/resources/data/human-pheno.assocs.gz") + .loadIndividualAssociationsFromTsv("src/test/resources/data/human-pheno.assocs.gz") .createKnowledgeBase(); } @@ -103,8 +102,9 @@ public void loadDataFromOntologies() { public void loadDataFromTsv() { BMKnowledgeBase bmKnowledgeBase = OwlKnowledgeBase.loader() .loadCuries(curies()) - .loadOntology("src/test/resources/ontologies/mammal.obo.gz") - .loadDataFromTsv("src/test/resources/data/human-pheno.assocs.gz") +// .loadOntology("src/test/resources/species-no-individuals.owl") + .loadOntology("src/test/resources/species.owl") + .loadIndividualAssociationsFromTsv("src/test/resources/data/species-individuals.tsv") .createKnowledgeBase(); } @@ -113,7 +113,7 @@ public void loadDataFromGzippedTsv() { BMKnowledgeBase bmKnowledgeBase = OwlKnowledgeBase.loader() .loadCuries(curies()) .loadOntology("src/test/resources/ontologies/mammal.obo.gz") - .loadDataFromTsv("src/test/resources/data/human-pheno.assocs.gz") + .loadIndividualAssociationsFromTsv("src/test/resources/data/human-pheno.assocs.gz") .createKnowledgeBase(); } @@ -122,7 +122,7 @@ public void loadDataFromTsvCollection() { BMKnowledgeBase bmKnowledgeBase = OwlKnowledgeBase.loader() .loadCuries(curies()) .loadOntology("src/test/resources/ontologies/mammal.obo.gz") - .loadDataFromTsv(Arrays.asList( + .loadIndividualAssociationsFromTsv(Arrays.asList( "src/test/resources/data/gene2taxon.tsv.gz", "src/test/resources/data/mouse-pheno.assocs.gz", "src/test/resources/data/human-pheno.assocs.gz")) @@ -142,6 +142,28 @@ public void loadDataFromTsvCollection() { } @Test + public void loadDataFromMap() { + Map curies = new HashMap<>(); + curies.put("HP", "http://purl.obolibrary.org/obo/HP_"); + curies.put("NAME:", "http://x.org/NAME_"); + + Map> data = new HashMap<>(); + data.put("NAME:Kevin", Arrays.asList("HP:0000952","HP:0001090","HP:0004322","HP:0001006","HP:0006101","HP:0009914")); + data.put("NAME:Bob", Arrays.asList("HP:0000952","HP:0001090","HP:0004322","HP:0001006","HP:0006101","HP:0001100")); + data.put("NAME:Stuart", Arrays.asList("HP:0000952","HP:0001090","HP:0004322","HP:0001006","HP:0006101","HP:0100754")); + + BMKnowledgeBase knowledgeBase = BMKnowledgeBase.owlLoader() + .loadOntology("src/test/resources/species-no-individuals.owl") + .loadCuries(curies) + .loadIndividualAssociations(data) + .createKnowledgeBase(); + + System.out.println("knowledgebase individuals are: " + knowledgeBase.getIndividualIdsInSignature()); + System.out.println(knowledgeBase.getEntity("NAME:Kevin")); + assertEquals(Sets.newHashSet("NAME:Kevin", "NAME:Bob", "NAME:Stuart"), knowledgeBase.getIndividualIdsInSignature()); + } + + @Test public void testLoadOwlFromFileLocationWithStandardOntologyManager() throws Exception { BMKnowledgeBase bmKnowledgeBase = OwlKnowledgeBase.loader() .useStandardOntologyManager() diff --git a/owlsim-core/src/test/resources/data/species-individuals.tsv b/owlsim-core/src/test/resources/data/species-individuals.tsv new file mode 100644 index 0000000..6faf0c4 --- /dev/null +++ b/owlsim-core/src/test/resources/data/species-individuals.tsv @@ -0,0 +1,24 @@ +Sharktopus shark, octopus +SquidMan squid, human +SpiderMan spider, human +DolphinCat dolphin, cat +DogMouse dog, mouse +SpongeBob poriferan, human +JellyChimp jelly, chimp +GreatOldOne amphibian, cephalopod, human +PorpoiseMarmosetFly porpoise, marmoset, fruitfly +SuperMammal human, dolphin, chimp, dog, cat, rat, mouse +ProtoSpider spider +ProtoHuman human +ProtoChimp chimp +ProtoWhale cetacean +ProtoMammal mammal +ProtoShark shark +TranslucentTrait jelly, salp +CuteTrait cat, dolphin, koala +WeirdTrait platypus, cephalopod, hammerhead +ScaryTrait tarantula, octopus, shark +BigTrait blueWhale, greatWhiteShark +SmallTrait rat, mouse, insect, xenopus +SwimmingTrait shark, cetacean, teleost +StupidTrait poriferan, tunicate, jelly diff --git a/owlsim-core/src/test/resources/species-no-individuals.owl b/owlsim-core/src/test/resources/species-no-individuals.owl new file mode 100644 index 0000000..2e08973 --- /dev/null +++ b/owlsim-core/src/test/resources/species-no-individuals.owl @@ -0,0 +1,165 @@ +Prefix: : + +Ontology: + +Class: organism +Class: animal + SubClassOf: organism + Class: bilaterian + SubClassOf: animal + + Class: protostome + SubClassOf: bilaterian + Class: arthropod + SubClassOf: protostome + Class: spider + SubClassOf: arthropod + Class: tarantula + SubClassOf: spider + + Class: insect + SubClassOf: arthropod + Class: dipteran + SubClassOf: insect + Class: fruitfly + SubClassOf: dipteran + Class: hymenopteran + SubClassOf: insect + Class: bee + SubClassOf: hymenopteran + Class: ant + SubClassOf: hymenopteran + + Class: cephalopod + SubClassOf: protostome + Class: squid + SubClassOf: cephalopod + Class: octopus + SubClassOf: cephalopod + Class: nautilus + SubClassOf: cephalopod + Class: cuttlefish + SubClassOf: cephalopod + + Class: deuterostome + SubClassOf: bilaterian + Class: echinoderm + SubClassOf: deuterostome + Class: starfish + SubClassOf: echinoderm + Class: urchin + SubClassOf: echinoderm + Class: chordate + SubClassOf: deuterostome + Class: vertebrate + SubClassOf: chordate + Class: cartilaginousFish + SubClassOf: vertebrate + Class: shark + SubClassOf: cartilaginousFish + Class: hammerhead + SubClassOf: shark + Class: greatWhiteShark + SubClassOf: shark + Class: ray + SubClassOf: cartilaginousFish + Class: teleost + SubClassOf: vertebrate + Class: zebrafish + SubClassOf: teleost + Class: tetrapod + SubClassOf: vertebrate + Class: anamniote + SubClassOf: tetrapod + Class: amphibian + SubClassOf: anamniote + Class: xenopus + SubClassOf: amphibian + Class: amniote + SubClassOf: tetrapod + Class: reptile + SubClassOf: amniote + Class: bird + SubClassOf: amniote + Class: chicken + SubClassOf: bird + Class: pigeon + SubClassOf: bird + Class: parrot + SubClassOf: bird + Class: mammal + SubClassOf: amniote + Class: monotreme + SubClassOf: mammal + Class: platypus + SubClassOf: monotreme + Class: therian + SubClassOf: mammal + Class: metatherian + SubClassOf: therian + Class: kangaroo + SubClassOf: metatherian + Class: koala + SubClassOf: metatherian + Class: eutherian + SubClassOf: therian + Class: carnivore + SubClassOf: eutherian + Class: cat + SubClassOf: carnivore + Class: dog + SubClassOf: carnivore + Class: euarchontoglires + SubClassOf: eutherian + Class: rodent + SubClassOf: euarchontoglires + Class: rat + SubClassOf: rodent + Class: mouse + SubClassOf: rodent + Class: primate + SubClassOf: euarchontoglires + Class: ape + SubClassOf: primate + Class: human + SubClassOf: ape + Class: chimp + SubClassOf: ape + Class: orangutan + SubClassOf: ape + Class: platyrrhine + SubClassOf: primate + Class: marmoset + SubClassOf: platyrrhine + Class: howler + SubClassOf: platyrrhine + + Class: cetacean + SubClassOf: eutherian + Class: baleenWhale + SubClassOf: cetacean + Class: blueWhale + SubClassOf: baleenWhale + Class: toothedWhale + SubClassOf: cetacean + Class: dolphin + SubClassOf: toothedWhale + Class: porpoise + SubClassOf: toothedWhale + SubClassOf: cetacean + + Class: tunicate + SubClassOf: chordate + Class: squirt + SubClassOf: tunicate + Class: salp + SubClassOf: tunicate + + Class: cnidarian + SubClassOf: animal + Class: jelly + SubClassOf: cnidarian + Class: coral + SubClassOf: cnidarian + Class: poriferan + SubClassOf: animal \ No newline at end of file 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 8a19ef4..dde9e3b 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 @@ -28,7 +28,7 @@ public KnowledgeBaseModule(Collection ontologyUris, Collection o ontologyUris.forEach(logger::info); logger.info("Loading ontologyDataUris:"); ontologyDataUris.forEach(logger::info); - logger.info("Loading dataTsvs:"); + logger.info("Loading individual associations Tsvs:"); dataTsvs.forEach(logger::info); logger.info("Loading curies:"); curies.entrySet().forEach(logger::info); @@ -37,7 +37,7 @@ public KnowledgeBaseModule(Collection ontologyUris, Collection o this.bmKnowledgeBase = OwlKnowledgeBase.loader() .loadOntologies(ontologyUris) .loadDataFromOntologies(ontologyDataUris) - .loadDataFromTsv(dataTsvs) + .loadIndividualAssociationsFromTsv(dataTsvs) .loadCuries(curies) .createKnowledgeBase();