Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintain correct set of in_taxon model annotations. #504

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@
import org.semanticweb.owlapi.rio.RioMemoryTripleSource;
import org.semanticweb.owlapi.rio.RioRenderer;

import javax.annotation.Nonnull;
import java.io.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import static org.geneontology.minerva.BlazegraphOntologyManager.in_taxon;

public class BlazegraphMolecularModelManager<METADATA> extends CoreMolecularModelManager<METADATA> {

private static Logger LOG = Logger
Expand Down Expand Up @@ -179,21 +182,15 @@ public void saveAllModels()
* @throws RepositoryException
* @throws UnknownIdentifierException
*/
public void saveModel(ModelContainer m)
throws OWLOntologyStorageException, OWLOntologyCreationException,
IOException, RepositoryException, UnknownIdentifierException {
public void saveModel(ModelContainer m) throws IOException, RepositoryException, UnknownIdentifierException {
IRI modelId = m.getModelId();
OWLOntology ont2save = m.getAboxOntology();
Set<String> taxa = getTaxonsForModel(modelId.toString());
if (taxa != null) {
for (String taxon : taxa) {
ont2save = getGolego_repo().addTaxonModelMetaData(ont2save, IRI.create(taxon));
}
}
final OWLOntology ont = ont2save;
final OWLOntology ont = m.getAboxOntology();
final OWLOntologyManager manager = ont.getOWLOntologyManager();
List<OWLOntologyChange> changes = preSaveFileHandler(ont);
synchronized (ont) {
// This handler is not in the preSaveFileHandler list, because changes by those
// handlers are rolled back after save.
new ModelTaxonSaveHandler().handle(ont);
List<OWLOntologyChange> changes = preSaveFileHandler(ont);
try {
this.writeModelToDatabase(ont, modelId);
// reset modified flag for abox after successful save
Expand Down Expand Up @@ -250,6 +247,11 @@ private List<OWLOntologyChange> preSaveFileHandler(OWLOntology model) throws Unk
return allChanges;
}

/**
* A PreFileSaveHandler may make changes to a model,
* returning the list of changes it made. Callers will
* assume that changes have been applied.
*/
public static interface PreFileSaveHandler {

public List<OWLOntologyChange> handle(OWLOntology model) throws UnknownIdentifierException;
Expand All @@ -262,6 +264,40 @@ public void addPreFileSaveHandler(PreFileSaveHandler handler) {
}
}

private final class ModelTaxonSaveHandler implements PreFileSaveHandler {

@Override
public List<OWLOntologyChange> handle(OWLOntology model) throws UnknownIdentifierException {
OWLDataFactory factory = OWLManager.getOWLDataFactory();
final Set<OWLAnnotation> existingTaxonAnnotations = model.getAnnotations().stream()
.filter(ann -> ann.getProperty().equals(in_taxon))
.collect(Collectors.toSet());
final Set<IRI> existingTaxa = existingTaxonAnnotations.stream()
.map(OWLAnnotation::getValue)
.filter(OWLObject::isIRI)
.map(v -> v.asIRI().get())
.collect(Collectors.toSet());
Set<IRI> taxa = getTaxaForModel(model);
final Set<OWLAnnotation> annotationsToRemove = existingTaxonAnnotations.stream()
.filter(ann -> !taxa.contains(ann.getValue()))
.collect(Collectors.toSet());
final Set<IRI> taxaToAdd = taxa.stream()
.filter(t -> !existingTaxa.contains(t))
.collect(Collectors.toSet());
final Set<OWLOntologyChange> removals = annotationsToRemove.stream()
.map(ann -> new RemoveOntologyAnnotation(model, ann))
.collect(Collectors.toSet());
final Set<OWLOntologyChange> additions = taxaToAdd.stream()
.map(t -> new AddOntologyAnnotation(model, factory.getOWLAnnotation(in_taxon, t)))
.collect(Collectors.toSet());
final List<OWLOntologyChange> changes = new ArrayList<>();
changes.addAll(removals);
changes.addAll(additions);
model.getOWLOntologyManager().applyChanges(changes);
return changes;
}
}

/**
* Export the ABox for the given modelId in the default
* {@link OWLDocumentFormat}.
Expand Down Expand Up @@ -838,13 +874,13 @@ public void dispose() {
}
}

public Map<String, Set<String>> buildTaxonModelMap() throws IOException {
public Map<IRI, Set<String>> buildTaxonModelMap() throws IOException {
Map<String, Set<String>> model_genes = buildModelGeneMap();
Map<String, Set<String>> taxon_models = new HashMap<String, Set<String>>();
Map<IRI, Set<String>> taxon_models = new HashMap<IRI, Set<String>>();
for (String model : model_genes.keySet()) {
Set<String> genes = model_genes.get(model);
Set<String> taxa = this.getGolego_repo().getTaxaByGenes(genes);
for (String taxon : taxa) {
Set<IRI> taxa = this.getGolego_repo().getTaxaByGenes(genes);
for (IRI taxon : taxa) {
Set<String> models = taxon_models.get(taxon);
if (models == null) {
models = new HashSet<String>();
Expand Down Expand Up @@ -895,14 +931,20 @@ public Map<String, Set<String>> buildModelGeneMap() {
return model_genes;
}

public Set<String> getTaxonsForModel(String model_id) throws IOException {
Set<String> genes = getModelGenes(model_id);
@Nonnull
public Set<IRI> getTaxaForModel(OWLOntology model) {
String modelID = model.getOntologyID().getOntologyIRI().get().toString();
Set<String> genes = getModelGenes(modelID);
if (genes.isEmpty()) {
return null;
return Collections.emptySet();
} else {
try {
return this.getGolego_repo().getTaxaByGenes(genes);
} catch (IOException e) {
LOG.error("Error querying ontology Blazegraph", e);
return Collections.emptySet();
}
}
Set<String> taxa = this.getGolego_repo().getTaxaByGenes(genes);
return taxa;

}

public Set<String> getModelGenes(String model_id) {
Expand Down Expand Up @@ -942,16 +984,16 @@ public Set<String> getModelGenes(String model_id) {


public void addTaxonMetadata() throws IOException {
Map<String, Set<String>> taxon_models = buildTaxonModelMap();
Map<IRI, Set<String>> taxon_models = buildTaxonModelMap();
LOG.info("Ready to update " + taxon_models.keySet().size() + " " + taxon_models.keySet());
for (String taxon : taxon_models.keySet()) {
for (IRI taxon : taxon_models.keySet()) {
LOG.info("Updating models in taxon " + taxon);
Set<String> models = taxon_models.get(taxon);
models.stream().parallel().forEach(model -> {
//fine for a few thousand models, but ends up eating massive ram for many
//addTaxonWithOWL(IRI.create(model), IRI.create(taxon));
try {
addTaxonToDatabaseWithSparql(IRI.create(model), IRI.create(taxon));
addTaxonToDatabaseWithSparql(IRI.create(model), taxon);
} catch (RepositoryException | UpdateExecutionException | MalformedQueryException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,6 @@ public BigdataSailRepository getGo_lego_repo() {
return go_lego_repo;
}

public OWLOntology addTaxonModelMetaData(OWLOntology model, IRI taxon_iri) {
OWLOntologyManager ontman = model.getOWLOntologyManager();
OWLDataFactory df = ontman.getOWLDataFactory();
OWLAnnotation taxon_anno = df.getOWLAnnotation(in_taxon, taxon_iri);
OWLAxiom taxonannoaxiom = df.getOWLAnnotationAssertionAxiom(model.getOntologyID().getOntologyIRI().get(), taxon_anno);
ontman.addAxiom(model, taxonannoaxiom);
return model;
}

public void unGunzipFile(String compressedFile, String decompressedFile) {
byte[] buffer = new byte[1024];
try {
Expand Down Expand Up @@ -621,13 +612,13 @@ public void dispose() {
}
}

public Set<String> getTaxaByGenes(Set<String> genes) throws IOException {
public Set<IRI> getTaxaByGenes(Set<String> genes) throws IOException {
String expansion = "VALUES ?gene { ";
for (String gene : genes) {
expansion += "<" + gene + "> \n";
}
expansion += " } . \n";
Set<String> taxa = new HashSet<String>();
Set<IRI> taxa = new HashSet<>();
try {
BigdataSailRepositoryConnection connection = go_lego_repo.getReadOnlyConnection();
try {
Expand All @@ -647,13 +638,11 @@ public Set<String> getTaxaByGenes(Set<String> genes) throws IOException {
Value v = binding.getValue("taxon");
//ignore anonymous sub classes
if (v instanceof URI) {
String taxon = binding.getValue("taxon").stringValue();
IRI taxon = IRI.create(binding.getValue("taxon").stringValue());
taxa.add(taxon);
}
}
} catch (MalformedQueryException e) {
throw new IOException(e);
} catch (QueryEvaluationException e) {
} catch (MalformedQueryException | QueryEvaluationException e) {
throw new IOException(e);
} finally {
connection.close();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

import static org.geneontology.minerva.BlazegraphOntologyManager.in_taxon;
import static org.junit.Assert.*;

public class BlazegraphMolecularModelManagerTest {
Expand Down Expand Up @@ -56,6 +58,30 @@ public void testImportDump() throws Exception {
m3.dispose();
}

@Test
public void testTaxonAnnotationMaintenance() throws Exception {
IRI human = IRI.create("http://purl.obolibrary.org/obo/NCBITaxon_9606");
IRI boar = IRI.create("http://purl.obolibrary.org/obo/NCBITaxon_9823");
String sourceModelPath = "src/test/resources/test-model-taxon-annotations.ttl";
IRI modelIRI = IRI.create("http://model.geneontology.org/62183af000000536");
BlazegraphMolecularModelManager<Void> m3 = createBlazegraphMolecularModelManager();
m3.importModelToDatabase(new File(sourceModelPath), false);
ModelContainer model = m3.getModel(modelIRI);
Set<IRI> previousTaxonIRIs = model.getAboxOntology().getAnnotations().stream()
.filter(a -> a.getProperty().equals(in_taxon))
.map(a -> a.getValue().asIRI().get())
.collect(Collectors.toSet());
assertTrue(previousTaxonIRIs.contains(human));
assertTrue(previousTaxonIRIs.contains(boar));
m3.saveModel(model);
Set<IRI> newTaxonIRIs = model.getAboxOntology().getAnnotations().stream()
.filter(a -> a.getProperty().equals(in_taxon))
.map(a -> a.getValue().asIRI().get())
.collect(Collectors.toSet());
assertTrue(newTaxonIRIs.contains(human));
assertFalse(newTaxonIRIs.contains(boar));
}

@Test
public void testRemoveImportsDuringImport() throws Exception {
String sourceModelPath = "src/test/resources/dummy-noctua-modelwith-import.ttl";
Expand Down
Loading