Skip to content

Commit

Permalink
Merge pull request #71 from julesjacobsen/master
Browse files Browse the repository at this point in the history
Adding ability to load individuals from in-memory data as well as off-disk.
  • Loading branch information
julesjacobsen committed Mar 20, 2017
2 parents 84ce6cb + 75bf89f commit 933184c
Show file tree
Hide file tree
Showing 14 changed files with 596 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -34,13 +35,15 @@ public class Ontology {
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();
}

Expand Down Expand Up @@ -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");
}

Expand Down Expand Up @@ -118,10 +138,6 @@ private OWLOntology mergeOntologies(Collection<String> uris) {
return owlOntology;
}

private ChangeApplied addAxiom(OWLAxiom axiom) {
return ontologyManager.addAxiom(owlOntology, axiom);
}

private ChangeApplied addAxioms(Set<OWLAxiom> axioms) {
return ontologyManager.addAxioms(owlOntology, axioms);
}
Expand Down Expand Up @@ -159,12 +175,12 @@ private OWLOntology loadOwlOntology(IRI iri) {
}
}

private OWLOntology loadDataFromTsv(Collection<String> paths) {
paths.forEach(this::loadDataFromTsv);
private OWLOntology loadIndividualAssociationsFromTsv(Collection<String> paths) {
paths.forEach(this::loadIndividualAssociationsFromTsv);
return owlOntology;
}

private OWLOntology loadDataFromTsv(String path) {
private OWLOntology loadIndividualAssociationsFromTsv(String path) {
if (path.endsWith(".gz")) {
return loadDataFromTsvGzip(path);
}
Expand All @@ -191,8 +207,20 @@ private OWLOntology loadDataFromTsvGzip(String path) {
return owlOntology;
}

private void loadDataFromPairwiseMappings(Map<String, String> pairwiseMappings) {
pairwiseMappings.forEach(this::addInstanceOf);
private void loadIndividualAssociationsFromMap(Map<String, Collection<String>> 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<String, Collection<String>> addIndividual() {
return (individual, annotations) -> {
for (String curie : annotations) {
addInstanceOf(individual, curie);
}
};
}

private void loadLineIntoDataOntology(String line) {
Expand All @@ -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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ public class OntologySourceData {
private final List<String> dataOntologies;

private final Map<String, String> curies;
private final List<String> dataTsvs;
//TODO: add these so people can programmatically add individual assertions
private final Map<String, String> pairwiseMappings;
private final List<String> individualAssociationTsvs;
private final Map<String, Collection<String>> 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<String> distinctImmutableListOf(List<String> list) {
Expand All @@ -48,12 +48,12 @@ public Map<String, String> getCuries() {
return curies;
}

public List<String> getDataTsvs() {
return dataTsvs;
public List<String> getIndividualAssociationTsvs() {
return individualAssociationTsvs;
}

public Map<String, String> getPairwiseMappings() {
return pairwiseMappings;
public Map<String, Collection<String>> getIndividualAssociations() {
return individualAssociations;
}

@Override
Expand All @@ -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
Expand All @@ -79,8 +79,8 @@ public String toString() {
"ontologies=" + ontologies +
", dataOntologies=" + dataOntologies +
", curies=" + curies +
", dataTsvs=" + dataTsvs +
", pairwiseMappings=" + pairwiseMappings +
", individualAssociationTsvs=" + individualAssociationTsvs +
", individualAssociations=" + individualAssociations +
'}';
}

Expand All @@ -93,8 +93,8 @@ public static class Builder {
private List<String> dataOntologies = new ArrayList<>();
//Curies need to be supplied if people are adding data using TSV files or pairwise mappings using curies.
private Map<String, String> curies = Collections.emptyMap();
private List<String> dataTsvs = new ArrayList<>();
private Map<String, String> pairwiseMappings = Collections.emptyMap();
private List<String> individualAssociationTsvs = new ArrayList<>();
private Map<String, Collection<String>> individualAssociations = new HashMap<>();

private Builder(){
//use the static method.
Expand Down Expand Up @@ -161,33 +161,38 @@ public Builder dataOntologies(Collection<String> 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<String> paths) {
dataTsvs.addAll(paths);
public Builder individualAssociationsTsv(Collection<String> paths) {
individualAssociationTsvs.addAll(paths);
return this;
}

public Builder individualAssociations(Map<String, ? extends Collection<String>> mappings) {
individualAssociations.putAll(mappings);
return this;
}

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();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ public Loader loadCuries(Map<String, String> curies) {
* @param file
*/
public Loader loadOntology(File file) {
Math.random();
sourceDataBuilder.ontology(file);
return this;
}
Expand Down Expand Up @@ -103,18 +102,23 @@ public Loader loadDataFromOntologies(Collection<String> 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<String> paths) {
sourceDataBuilder.dataTsv(paths);
public Loader loadIndividualAssociationsFromTsv(Collection<String> paths) {
sourceDataBuilder.individualAssociationsTsv(paths);
return this;
}

public Loader loadIndividualAssociations(Map<String, ? extends Collection<String>> data) {
sourceDataBuilder.individualAssociations(data);
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -351,7 +351,9 @@ public interface BMKnowledgeBase {
public int getRootIndex();



public static OwlKnowledgeBase.Loader owlLoader() {
return OwlKnowledgeBase.loader();
}



Expand Down
Loading

0 comments on commit 933184c

Please sign in to comment.