diff --git a/minerva-cli/pom.xml b/minerva-cli/pom.xml index 82e14143..8a27afb8 100644 --- a/minerva-cli/pom.xml +++ b/minerva-cli/pom.xml @@ -73,7 +73,7 @@ - + org.geneontology minerva-converter ${project.parent.version} @@ -83,10 +83,7 @@ minerva-server ${project.parent.version} - - org.bbop - OWLTools-Runner - + diff --git a/minerva-cli/src/main/java/org/geneontology/minerva/cli/CommandLineInterface.java b/minerva-cli/src/main/java/org/geneontology/minerva/cli/CommandLineInterface.java index c5d59002..33031489 100644 --- a/minerva-cli/src/main/java/org/geneontology/minerva/cli/CommandLineInterface.java +++ b/minerva-cli/src/main/java/org/geneontology/minerva/cli/CommandLineInterface.java @@ -1,11 +1,715 @@ package org.geneontology.minerva.cli; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; -public class CommandLineInterface { +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.DefaultParser; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionGroup; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.jena.rdf.model.Model; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.geneontology.minerva.BlazegraphMolecularModelManager; +import org.geneontology.minerva.ModelContainer; +import org.geneontology.minerva.UndoAwareMolecularModelManager; +import org.geneontology.minerva.curie.CurieHandler; +import org.geneontology.minerva.curie.CurieMappings; +import org.geneontology.minerva.curie.DefaultCurieHandler; +import org.geneontology.minerva.curie.MappedCurieHandler; +import org.geneontology.minerva.json.InferenceProvider; +import org.geneontology.minerva.json.JsonModel; +import org.geneontology.minerva.json.MolecularModelJsonRenderer; +import org.geneontology.minerva.legacy.sparql.GPADSPARQLExport; +import org.geneontology.minerva.server.StartUpTool; +import org.geneontology.minerva.server.inferences.InferenceProviderCreator; +import org.geneontology.minerva.server.validation.MinervaShexValidator; +import org.geneontology.minerva.util.BlazegraphMutationCounter; +import org.geneontology.minerva.validation.Enricher; +import org.geneontology.minerva.validation.ShexValidationReport; +import org.geneontology.minerva.validation.ShexValidator; +import org.geneontology.minerva.validation.ValidationResultSet; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.UpdateExecutionException; +import org.openrdf.repository.RepositoryException; +import org.openrdf.rio.RDFHandlerException; +import org.openrdf.rio.RDFParseException; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.reasoner.InconsistentOntologyException; +import org.semanticweb.owlapi.reasoner.OWLReasoner; +import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; +import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory; + +import com.bigdata.rdf.sail.BigdataSail; +import com.bigdata.rdf.sail.BigdataSailRepository; +import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; +import com.google.common.base.Optional; +import com.google.common.collect.Sets; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import owltools.cli.Opts; +import owltools.io.ParserWrapper; + +public class CommandLineInterface { + private static final Logger LOGGER = Logger.getLogger(CommandLineInterface.class); + public static void main(String[] args) throws Exception { - MinervaCommandRunner cr = new MinervaCommandRunner(); - cr.run(args); + //MinervaCommandRunner cr = new MinervaCommandRunner(); + //cr.run(args); + Options main_options = new Options(); + OptionGroup methods = new OptionGroup(); + methods.setRequired(true); + Option dump = Option.builder() + .longOpt("dump-owl-models") + .desc("export OWL GO-CAM models from journal") + .hasArg(false) + .build(); + methods.addOption(dump); + Option import_owl = Option.builder() + .longOpt("import-owl-models") + .desc("import OWL GO-CAM models into journal") + .hasArg(false) + .build(); + methods.addOption(import_owl); + Option sparql = Option.builder() + .longOpt("sparql-update") + .desc("update the blazegraph journal with the given sparql statement") + .hasArg(false) + .build(); + methods.addOption(sparql); + Option json = Option.builder() + .longOpt("owl-lego-to-json") + .desc("Given a GO-CAM OWL file, make its minerva json represention") + .hasArg(false) + .build(); + methods.addOption(json); + Option gpad = Option.builder() + .longOpt("lego-to-gpad-sparql") + .desc("Given a GO-CAM journal, export GPAD representation for all the go-cams") + .hasArg(false) + .build(); + methods.addOption(gpad); + Option version = Option.builder() + .longOpt("version") + .desc("Print the version of the minerva stack used here. Extracts this from JAR file.") + .hasArg(false) + .build(); + methods.addOption(version); + Option validate = Option.builder("v") + .longOpt("validate-go-cams") + .desc("Check a collection of go-cam files or a journal for valid semantics (owl) and structure (shex)") + .hasArg(false) + .build(); + methods.addOption(validate); + main_options.addOptionGroup(methods); + + CommandLineParser parser = new DefaultParser(); + try { + CommandLine cmd = parser.parse( main_options, args, true); + + if(cmd.hasOption("dump-owl-models")) { + Options dump_options = new Options(); + dump_options.addOption(dump); + dump_options.addOption("j", "journal", true, "Sets the Blazegraph journal file for the database"); + dump_options.addOption("f", "folder", true, "Sets the output folder the GO-CAM model files"); + dump_options.addOption("p", "model-id-prefix", true, "prefix for GO-CAM model ids"); + cmd = parser.parse( dump_options, args, false); + String journalFilePath = cmd.getOptionValue("j"); //--journal + String outputFolder = cmd.getOptionValue("f"); //--folder + String modelIdPrefix = cmd.getOptionValue("p"); //--prefix + modelsToOWL(journalFilePath, outputFolder, modelIdPrefix); + }else if(cmd.hasOption("import-owl-models")) { + Options import_options = new Options(); + import_options.addOption(import_owl); + import_options.addOption("j", "journal", true, "Sets the Blazegraph journal file for the database"); + import_options.addOption("f", "folder", true, "Sets the input folder the GO-CAM model files"); + cmd = parser.parse( import_options, args, false); + String journalFilePath = cmd.getOptionValue("j"); //--journal + String outputFolder = cmd.getOptionValue("f"); //--folder + importOWLModels(journalFilePath, outputFolder); + }else if(cmd.hasOption("sparql-update")) { + Options sparql_options = new Options(); + sparql_options.addOption(sparql); + sparql_options.addOption("j", "journal", true, "Sets the Blazegraph journal file for the database"); + sparql_options.addOption("f", "file", true, "Sets the file containing a SPARQL update"); + cmd = parser.parse( sparql_options, args, false); + String journalFilePath = cmd.getOptionValue("j"); //--journal + String file = cmd.getOptionValue("f"); + sparqlUpdate(journalFilePath, file); + }else if(cmd.hasOption("owl-lego-to-json")) { + Options json_options = new Options(); + json_options.addOption(json); + json_options.addOption("i", "OWLFile", true, "Input GO-CAM OWL file"); + json_options.addOption("o", "JSONFILE", true, "Output JSON file"); + OptionGroup format = new OptionGroup(); + Option pretty = Option.builder() + .longOpt("pretty-json") + .desc("pretty json format") + .hasArg(false) + .build(); + format.addOption(pretty); + Option compact = Option.builder() + .longOpt("compact-json") + .desc("compact json format") + .hasArg(false) + .build(); + format.addOption(compact); + json_options.addOptionGroup(format); + cmd = parser.parse( json_options, args, false); + String input = cmd.getOptionValue("i"); + String output = cmd.getOptionValue("o"); + boolean usePretty = true; + if(cmd.hasOption("compact-json")) { + usePretty = false; + } + owl2LegoJson(input, output, usePretty); + }else if(cmd.hasOption("lego-to-gpad-sparql")) { + Options gpad_options = new Options(); + gpad_options.addOption(gpad); + gpad_options.addOption("i", "input", true, "Sets the Blazegraph journal file for the database"); + gpad_options.addOption("o", "gpad-output", true, "Sets the output location for the GPAD"); + gpad_options.addOption("p", "model-id-prefix", true, "prefix for GO-CAM model ids"); + gpad_options.addOption("c", "model-id-curie", true, "prefix for GO-CAM curies"); + gpad_options.addOption("ont", "ontology", true, "IRI of tbox ontology for classification - usually default go-lego.owl"); + gpad_options.addOption("cat", "catalog", true, "Catalog file for tbox ontology. " + + "Use this to specify local copies of the ontology and or its imports to " + + "speed and control the process. If not used, will download the tbox and all its imports."); + cmd = parser.parse(gpad_options, args, false); + String inputDB = cmd.getOptionValue("input"); + String gpadOutputFolder = cmd.getOptionValue("gpad-output"); + String modelIdPrefix = cmd.getOptionValue("model-id-prefix"); + String modelIdcurie = cmd.getOptionValue("model-id-curie"); + String ontologyIRI = cmd.getOptionValue("ontology"); + String catalog = cmd.getOptionValue("catalog"); + legoToAnnotationsSPARQL(modelIdPrefix, modelIdcurie, inputDB, gpadOutputFolder, ontologyIRI, catalog); + }else if(cmd.hasOption("version")) { + printVersion(); + }else if(cmd.hasOption("validate-go-cams")) { + Options validate_options = new Options(); + validate_options.addOption(validate); + validate_options.addOption("i", "input", true, "Either a blazegrpah journal or a folder with go-cams in it"); + validate_options.addOption("shex", "shex", false, "If present, will execute shex validation"); + validate_options.addOption("owl", "owl", false, "If present, will execute shex validation"); + validate_options.addOption("r", "report-file", true, "Main output file for the validation"); + validate_options.addOption("e", "explanation-output-file", true, "Explanations for failed validations"); + validate_options.addOption("p", "model-id-prefix", true, "prefix for GO-CAM model ids"); + validate_options.addOption("cu", "model-id-curie", true, "prefix for GO-CAM curies"); + validate_options.addOption("ont", "ontology", true, "IRI of tbox ontology - usually default go-lego.owl"); + validate_options.addOption("c", "catalog", true, "Catalog file for tbox ontology. " + + "Use this to specify local copies of the ontology and or its imports to " + + "speed and control the process. If not used, will download the tbox and all its imports."); + validate_options.addOption("shouldfail", "shouldfail", false, "When used in travis mode for tests, shouldfail " + + "parameter will allow a successful run on a folder that only contains incorrect models."); + validate_options.addOption("t", "travis", false, "If travis, then the program will stop upon a failed " + + "validation and report an error. Otherwise it will continue to test all the models."); + validate_options.addOption("m", "shapemap", true, "Specify a shapemap file. Otherwise will download from go_shapes repo."); + validate_options.addOption("s", "shexpath", true, "Specify a shex schema file. Otherwise will download from go_shapes repo."); + + cmd = parser.parse(validate_options, args, false); + String input = cmd.getOptionValue("input"); + String basicOutputFile = cmd.getOptionValue("report-file"); + String shexpath = cmd.getOptionValue("s"); + String shapemappath = cmd.getOptionValue("shapemap"); + + String explanationOutputFile = cmd.getOptionValue("explanation-output-file"); + String ontologyIRI = "http://purl.obolibrary.org/obo/go/extensions/go-lego.owl"; + if(cmd.hasOption("ontology")) { + ontologyIRI = cmd.getOptionValue("ontology"); + } + String catalog = cmd.getOptionValue("catalog"); + String modelIdPrefix = "http://model.geneontology.org/"; + if(cmd.hasOption("model-id-prefix")) { + modelIdPrefix = cmd.getOptionValue("model-id-prefix"); + } + String modelIdcurie = "gomodel"; + if(cmd.hasOption("model-id-curie")) { + modelIdcurie = cmd.getOptionValue("model-id-curie"); + } + boolean travisMode = false; + if(cmd.hasOption("travis")) { + travisMode = true; + } + boolean shouldFail = false; + if(cmd.hasOption("shouldfail")) { + shouldFail = true; + } + boolean checkShex = false; + if(cmd.hasOption("shex")) { + checkShex = true; + } + validateGoCams(input, basicOutputFile, explanationOutputFile, ontologyIRI, catalog, modelIdPrefix, modelIdcurie, shexpath, shapemappath, travisMode, shouldFail, checkShex); + } + }catch( ParseException exp ) { + System.out.println( "Unexpected exception:" + exp.getMessage() ); + } + } + + /** + * Given a blazegraph journal with go-cams in it, write them all out as OWL files. + * cli --dump-owl-models + * @param journalFilePath + * @param outputFolder + * @param modelIdPrefix + * @throws Exception + */ + public static void modelsToOWL(String journalFilePath, String outputFolder, String modelIdPrefix) throws Exception { + if(modelIdPrefix==null) { + modelIdPrefix = "http://model.geneontology.org/"; + } + + // minimal inputs + if (journalFilePath == null) { + System.err.println("No journal file was configured."); + System.exit(-1); + return; + } + if (outputFolder == null) { + System.err.println("No output folder was configured."); + System.exit(-1); + return; + } + + OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); + CurieHandler curieHandler = new MappedCurieHandler(); + BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, journalFilePath, outputFolder); + m3.dumpAllStoredModels(); + m3.dispose(); + } + + /** + * Load the go-cam files in the input folder into the journal + * cli import-owl-models + * @param journalFilePath + * @param inputFolder + * @throws Exception + */ + public static void importOWLModels(String journalFilePath, String inputFolder) throws Exception { + // minimal inputs + if (journalFilePath == null) { + System.err.println("No journal file was configured."); + System.exit(-1); + return; + } + if (inputFolder == null) { + System.err.println("No input folder was configured."); + System.exit(-1); + return; + } + + OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); + String modelIdPrefix = "http://model.geneontology.org/"; // this will not be used for anything + CurieHandler curieHandler = new MappedCurieHandler(); + BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, journalFilePath, null); + for (File file : FileUtils.listFiles(new File(inputFolder), null, true)) { + LOGGER.info("Loading " + file); + if(file.getName().endsWith("ttl")||file.getName().endsWith("owl")) { + m3.importModelToDatabase(file, true); + }else { + LOGGER.info("Ignored for not ending with .ttl or .owl " + file); + } + } + m3.dispose(); + } + + /** + * Updates the journal with the provided update sparql statement. + * cli parameter --sparql-update + * @param journalFilePath + * @param updateFile + * @throws OWLOntologyCreationException + * @throws IOException + * @throws RepositoryException + * @throws MalformedQueryException + * @throws UpdateExecutionException + */ + public static void sparqlUpdate(String journalFilePath, String updateFile) throws OWLOntologyCreationException, IOException, RepositoryException, MalformedQueryException, UpdateExecutionException { + // minimal inputs + if (journalFilePath == null) { + System.err.println("No journal file was configured."); + System.exit(-1); + return; + } + if (updateFile == null) { + System.err.println("No update file was configured."); + System.exit(-1); + return; + } + + String update = FileUtils.readFileToString(new File(updateFile), StandardCharsets.UTF_8); + Properties properties = new Properties(); + properties.load(CommandLineInterface.class.getResourceAsStream("/org/geneontology/minerva/blazegraph.properties")); + properties.setProperty(com.bigdata.journal.Options.FILE, journalFilePath); + + BigdataSail sail = new BigdataSail(properties); + BigdataSailRepository repository = new BigdataSailRepository(sail); + repository.initialize(); + BigdataSailRepositoryConnection conn = repository.getUnisolatedConnection(); + BlazegraphMutationCounter counter = new BlazegraphMutationCounter(); + conn.addChangeLog(counter); + conn.prepareUpdate(QueryLanguage.SPARQL, update).execute(); + int changes = counter.mutationCount(); + conn.removeChangeLog(counter); + System.out.println("\nApplied " + changes + " changes"); + conn.close(); + } + + /** + * Convert a GO-CAM owl file to a minerva json structure + * --owl-lego-to-json + * @param input + * @param output + * @param usePretty + * @throws Exception + */ + public static void owl2LegoJson(String input, String output, boolean usePretty) throws Exception { + + // minimal inputs + if (input == null) { + System.err.println("No input model was configured."); + System.exit(-1); + return; + } + if (output == null) { + System.err.println("No output file was configured."); + System.exit(-1); + return; + } + + // configuration + CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); + GsonBuilder gsonBuilder = new GsonBuilder(); + if (usePretty) { + gsonBuilder.setPrettyPrinting(); + } + Gson gson = gsonBuilder.create(); + + // process each model + if (LOGGER.isInfoEnabled()) { + LOGGER.info("Loading model from file: "+input); + } + OWLOntology model = null; + final JsonModel jsonModel; + ParserWrapper pw = new ParserWrapper(); + try { + + // load model + model = pw.parseOWL(IRI.create(new File(input).getCanonicalFile())); + InferenceProvider inferenceProvider = null; // TODO decide if we need reasoning + String modelId = null; + Optional ontologyIRI = model.getOntologyID().getOntologyIRI(); + if (ontologyIRI.isPresent()) { + modelId = curieHandler.getCuri(ontologyIRI.get()); + } + + // render json + final MolecularModelJsonRenderer renderer = new MolecularModelJsonRenderer(modelId, model, inferenceProvider, curieHandler); + jsonModel = renderer.renderModel(); + } + finally { + if (model != null) { + pw.getManager().removeOntology(model); + model = null; + } + } + + // save as json string + final String json = gson.toJson(jsonModel); + final File outputFile = new File(output).getCanonicalFile(); + try (OutputStream outputStream = new FileOutputStream(outputFile)) { + if (LOGGER.isInfoEnabled()) { + LOGGER.info("Saving json to file: "+outputFile); + } + IOUtils.write(json, outputStream); + } + } + + /** + * Output GPAD files via inference+SPARQL + * cli --lego-to-gpad-sparql + * @param modelIdPrefix + * @param modelIdcurie + * @param inputDB + * @param gpadOutputFolder + * @param ontologyIRI + * @throws Exception + */ + public static void legoToAnnotationsSPARQL(String modelIdPrefix, String modelIdcurie, String inputDB, String gpadOutputFolder, String ontologyIRI, String catalog) throws Exception { + if(modelIdPrefix==null) { + modelIdPrefix = "http://model.geneontology.org/"; + } + if(modelIdcurie==null) { + modelIdcurie = "gomodel"; + } + if(inputDB==null) { + inputDB = "blazegraph.jnl"; + } + if(gpadOutputFolder==null) { + gpadOutputFolder = null; + } + if(ontologyIRI==null) { + ontologyIRI = "http://purl.obolibrary.org/obo/go/extensions/go-lego.owl"; + } + OWLOntologyManager ontman = OWLManager.createOWLOntologyManager(); + if(catalog!=null) { + LOGGER.info("using catalog: "+catalog); + ontman.setIRIMappers(Sets.newHashSet(new owltools.io.CatalogXmlIRIMapper(catalog))); + }else { + LOGGER.info("no catalog, resolving all ontology uris directly"); + } + + OWLOntology ontology = ontman.loadOntology(IRI.create(ontologyIRI)); + CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); + CurieHandler curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); + BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(ontology, curieHandler, modelIdPrefix, inputDB, null); + final String immutableModelIdPrefix = modelIdPrefix; + final String immutableGpadOutputFolder = gpadOutputFolder; + m3.getAvailableModelIds().stream().parallel().forEach(modelIRI -> { + try { + String gpad = new GPADSPARQLExport(curieHandler, m3.getLegacyRelationShorthandIndex(), m3.getTboxShorthandIndex(), m3.getDoNotAnnotateSubset()).exportGPAD(m3.createInferredModel(modelIRI)); + String fileName = StringUtils.replaceOnce(modelIRI.toString(), immutableModelIdPrefix, "") + ".gpad"; + Writer writer = new OutputStreamWriter(new FileOutputStream(Paths.get(immutableGpadOutputFolder, fileName).toFile()), StandardCharsets.UTF_8); + writer.write(gpad); + writer.close(); + } catch (InconsistentOntologyException e) { + LOGGER.error("Inconsistent ontology: " + modelIRI); + } catch (IOException e) { + LOGGER.error("Couldn't export GPAD for: " + modelIRI, e); + } + }); + m3.dispose(); + } + + + /** + * --validate-go-cams + * -i /GitHub/GO_Shapes/test_ttl/go_cams/should_pass/ + * -c ./catalog-no-import.xml + * @param input + * @param basicOutputFile + * @param explanationOutputFile + * @param ontologyIRI + * @param catalog + * @param modelIdPrefix + * @param modelIdcurie + * @param shexpath + * @param shapemappath + * @param travisMode + * @param shouldPass + * @throws Exception + */ + public static void validateGoCams(String input, String basicOutputFile, String explanationOutputFile, + String ontologyIRI, String catalog, String modelIdPrefix, String modelIdcurie, + String shexpath, String shapemappath, boolean travisMode, boolean shouldFail, boolean checkShex) throws Exception { + Logger LOG = Logger.getLogger(BlazegraphMolecularModelManager.class); + LOG.setLevel(Level.ERROR); + LOGGER.setLevel(Level.INFO); + String inputDB = "blazegraph.jnl"; + String shexFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shex"; + String goshapemapFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shapeMap"; + + Map modelid_filename = new HashMap(); + + if(basicOutputFile==null) { + LOGGER.error("please specify an output file with --output-file "); + System.exit(-1); + } + if(input==null) { + LOGGER.error("please provide an input file - either a directory of ttl files or a blazegraph journal"); + System.exit(-1); + } + if(input.endsWith(".jnl")) { + inputDB = input; + LOGGER.info("loaded blazegraph journal: "+input); + }else { + LOGGER.info("no journal found, trying as directory: "+input); + File i = new File(input); + if(i.exists()) { + //remove anything that existed earlier + File bgdb = new File(inputDB); + if(bgdb.exists()) { + bgdb.delete(); + } + //load everything into a bg journal + OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); + CurieHandler curieHandler = new MappedCurieHandler(); + BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, inputDB, null); + if(i.isDirectory()) { + FileUtils.listFiles(i, null, true).parallelStream().parallel().forEach(file-> { + //for (File file : + //m3.getAvailableModelIds().stream().parallel().forEach(modelIRI -> { + if(file.getName().endsWith(".ttl")||file.getName().endsWith("owl")) { + LOGGER.info("Loading " + file); + try { + String modeluri = m3.importModelToDatabase(file, true); + modelid_filename.put(modeluri, file.getName()); + } catch (OWLOntologyCreationException | RepositoryException | RDFParseException + | RDFHandlerException | IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }); + }else { + LOGGER.info("Loading " + i); + m3.importModelToDatabase(i, true); + } + LOGGER.info("loaded files into blazegraph journal: "+input); + m3.dispose(); + } + } + LOGGER.info("loading tbox ontology: "+ontologyIRI); + OWLOntologyManager ontman = OWLManager.createOWLOntologyManager(); + if(catalog!=null) { + LOGGER.info("using catalog: "+catalog); + ontman.setIRIMappers(Sets.newHashSet(new owltools.io.CatalogXmlIRIMapper(catalog))); + }else { + LOGGER.info("no catalog, resolving all ontology uris directly"); + } + OWLOntology tbox_ontology = ontman.loadOntology(IRI.create(ontologyIRI)); + tbox_ontology = StartUpTool.forceMergeImports(tbox_ontology, tbox_ontology.getImports()); + LOGGER.info("ontology axioms loaded: "+tbox_ontology.getAxiomCount()); + LOGGER.info("building model manager and structural reasoner"); + CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); + CurieHandler curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); + UndoAwareMolecularModelManager m3 = new UndoAwareMolecularModelManager(tbox_ontology, curieHandler, modelIdPrefix, inputDB, null); + String reasonerOpt = "arachne"; + LOGGER.info("tbox reasoner for shex "+m3.getTbox_reasoner().getReasonerName()); + if(shexpath==null) { + //fall back on downloading from shapes repo + URL shex_schema_url = new URL(shexFileUrl); + shexpath = "./go-cam-schema.shex"; + File shex_schema_file = new File(shexpath); + org.apache.commons.io.FileUtils.copyURLToFile(shex_schema_url, shex_schema_file); + System.err.println("-s .No shex schema provided, using: "+shexFileUrl); + } + if(shapemappath==null) { + URL shex_map_url = new URL(goshapemapFileUrl); + shapemappath = "./go-cam-shapes.shapeMap"; + File shex_map_file = new File(shapemappath); + org.apache.commons.io.FileUtils.copyURLToFile(shex_map_url, shex_map_file); + System.err.println("-m .No shape map file provided, using: "+goshapemapFileUrl); + } + MinervaShexValidator shex = new MinervaShexValidator(shexpath, shapemappath, curieHandler, m3.getTbox_reasoner()); + if(checkShex) { + if(checkShex) { + shex.setActive(true); + }else { + shex.setActive(false); + } + } + LOGGER.info("Building OWL inference provider: "+reasonerOpt); + InferenceProviderCreator ipc = StartUpTool.createInferenceProviderCreator(reasonerOpt, m3, shex); + LOGGER.info("Validating models: "+reasonerOpt); + + FileWriter basic_output = new FileWriter(basicOutputFile); + if(explanationOutputFile!=null) { + FileWriter explanations = new FileWriter(explanationOutputFile, false); + explanations.write("Explanations of invalid models.\n"); + explanations.close(); + } + try { + basic_output.write("filename\tmodel_id\tOWL_consistent\tshex_valid\n"); + final boolean shex_output = checkShex; + m3.getAvailableModelIds().stream().forEach(modelIRI -> { + try { + String filename = modelid_filename.get(modelIRI.toString()); + boolean isConsistent = true; + boolean isConformant = true; + LOGGER.info("processing "+filename+"\t"+modelIRI); + ModelContainer mc = m3.getModel(modelIRI); + InferenceProvider ip = ipc.create(mc); + isConsistent = ip.isConsistent(); + if(!isConsistent&&explanationOutputFile!=null) { + FileWriter explanations = new FileWriter(explanationOutputFile, true); + explanations.write(filename+"\t"+modelIRI+"\n\tOWL fail explanation: "+ip.getValidation_results().getOwlvalidation().getAsText()+"\n"); + explanations.close(); + } + if(travisMode&&!isConsistent) { + if(!shouldFail) { + LOGGER.error(filename+"\t"+modelIRI+"\tOWL:is inconsistent, quitting"); + System.exit(-1); + } + }else if(travisMode&&isConsistent&&shouldFail) { + LOGGER.error(filename+"\t"+modelIRI+"\tOWL:is consistent, but it should not be, quitting"); + System.exit(-1); + } + if(shex_output) { + ValidationResultSet validations = ip.getValidation_results(); + isConformant = validations.allConformant(); + if(!isConformant&&explanationOutputFile!=null) { + FileWriter explanations = new FileWriter(explanationOutputFile, true); + explanations.write(filename+"\t"+modelIRI+"\n\tSHEX fail explanation: "+ip.getValidation_results().getShexvalidation().getAsText()+"\n"); + explanations.close(); + } + if(travisMode) { + if(!isConformant&&!shouldFail) { + LOGGER.error(filename+"\t"+modelIRI+"\tshex is nonconformant, quitting, explanation:\n"+ip.getValidation_results().getShexvalidation().getAsText()); + System.exit(-1); + }else if(isConformant&&shouldFail) { + LOGGER.error(filename+"\t"+modelIRI+"\tshex validates, but it should not be, quitting"); + System.exit(-1); + } + } + LOGGER.info(filename+"\t"+modelIRI+"\tOWL:"+isConsistent+"\tshex:"+isConformant); + basic_output.write(filename+"\t"+modelIRI+"\t"+isConsistent+"\t"+isConformant+"\n"); + }else { + LOGGER.info(filename+"\t"+modelIRI+"\tOWL:"+isConsistent+"\tshex:not checked"); + basic_output.write(filename+"\t"+modelIRI+"\t"+isConsistent+"\tnot checked\n"); + } + } catch (InconsistentOntologyException e) { + LOGGER.error("Inconsistent model: " + modelIRI); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + }); + m3.dispose(); + }finally{ + basic_output.close(); + } + } + + + public static void printVersion() throws Exception { + printManifestEntry("git-revision-sha1", "UNKNOWN"); + printManifestEntry("git-revision-url", "UNKNOWN"); + printManifestEntry("git-branch", "UNKNOWN"); + printManifestEntry("git-dirty", "UNKNOWN"); + } + + private static String printManifestEntry(String key, String defaultValue) { + String value = owltools.version.VersionInfo.getManifestVersion(key); + if (value == null || value.isEmpty()) { + value = defaultValue; + } + System.out.println(key+"\t"+value); + return value; } } diff --git a/minerva-cli/src/main/java/org/geneontology/minerva/cli/MinervaCommandRunner.java b/minerva-cli/src/main/java/org/geneontology/minerva/cli/MinervaCommandRunner.java deleted file mode 100644 index 4198fa0a..00000000 --- a/minerva-cli/src/main/java/org/geneontology/minerva/cli/MinervaCommandRunner.java +++ /dev/null @@ -1,987 +0,0 @@ -package org.geneontology.minerva.cli; - -import com.bigdata.journal.Options; -import com.bigdata.rdf.sail.BigdataSail; -import com.bigdata.rdf.sail.BigdataSailRepository; -import com.bigdata.rdf.sail.BigdataSailRepositoryConnection; -import com.google.common.base.Optional; -import com.google.common.collect.Sets; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.jena.rdf.model.Model; -import org.apache.jena.rdf.model.ModelFactory; -import org.apache.log4j.Level; -import org.apache.log4j.Logger; -import org.geneontology.minerva.BlazegraphMolecularModelManager; -import org.geneontology.minerva.GafToLegoIndividualTranslator; -import org.geneontology.minerva.ModelContainer; -import org.geneontology.minerva.UndoAwareMolecularModelManager; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.curie.CurieMappings; -import org.geneontology.minerva.curie.DefaultCurieHandler; -import org.geneontology.minerva.curie.MappedCurieHandler; -import org.geneontology.minerva.json.InferenceProvider; -import org.geneontology.minerva.json.JsonModel; -import org.geneontology.minerva.json.MolecularModelJsonRenderer; -import org.geneontology.minerva.legacy.GroupingTranslator; -import org.geneontology.minerva.legacy.LegoToGeneAnnotationTranslator; -import org.geneontology.minerva.legacy.sparql.GPADSPARQLExport; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.geneontology.minerva.server.StartUpTool; -import org.geneontology.minerva.server.inferences.InferenceProviderCreator; -import org.geneontology.minerva.server.validation.MinervaShexValidator; -import org.geneontology.minerva.util.BlazegraphMutationCounter; -import org.geneontology.minerva.validation.Enricher; -import org.geneontology.minerva.validation.ShexValidationReport; -import org.geneontology.minerva.validation.ShexValidator; -import org.geneontology.minerva.validation.ValidationResultSet; -import org.geneontology.rules.engine.WorkingMemory; -import org.geneontology.rules.util.Bridge; -import org.openrdf.query.MalformedQueryException; -import org.openrdf.query.QueryLanguage; -import org.openrdf.query.UpdateExecutionException; -import org.openrdf.repository.RepositoryException; -import org.openrdf.rio.RDFHandlerException; -import org.openrdf.rio.RDFParseException; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.formats.FunctionalSyntaxDocumentFormat; -import org.semanticweb.owlapi.formats.ManchesterSyntaxDocumentFormat; -import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; -import org.semanticweb.owlapi.formats.TurtleDocumentFormat; -import org.semanticweb.owlapi.model.*; -import org.semanticweb.owlapi.reasoner.InconsistentOntologyException; -import org.semanticweb.owlapi.reasoner.OWLReasoner; -import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; -import org.semanticweb.owlapi.reasoner.structural.StructuralReasonerFactory; - -import owltools.cli.JsCommandRunner; -import owltools.cli.Opts; -import owltools.cli.tools.CLIMethod; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.gaf.eco.EcoMapperFactory; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.gaf.io.GafWriter; -import owltools.gaf.io.GpadWriter; -import owltools.graph.OWLGraphWrapper; -import scala.collection.JavaConverters; -import uk.ac.manchester.cs.owlapi.modularity.ModuleType; -import uk.ac.manchester.cs.owlapi.modularity.SyntacticLocalityModuleExtractor; - -import java.io.*; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; - -public class MinervaCommandRunner extends JsCommandRunner { - - private static final Logger LOGGER = Logger.getLogger(MinervaCommandRunner.class); - - @CLIMethod("--dump-owl-models") - public void modelsToOWL(Opts opts) throws Exception { - opts.info("[-j|--journal JOURNALFILE] [-f|--folder OWLFILESFOLDER] [-p|--prefix MODELIDPREFIX]", - "dumps all LEGO models to OWL Turtle files"); - // parameters - String journalFilePath = null; - String outputFolder = null; - String modelIdPrefix = "http://model.geneontology.org/"; - - // parse opts - while (opts.hasOpts()) { - if (opts.nextEq("-j|--journal")) { - opts.info("journal file", "Sets the Blazegraph journal file for the database"); - journalFilePath = opts.nextOpt(); - } - else if (opts.nextEq("-f|--folder")) { - opts.info("OWL folder", "Sets the output folder the LEGO model files"); - outputFolder = opts.nextOpt(); - } - else if (opts.nextEq("-p|--prefix")) { - opts.info("model ID prefix", "Sets the URI prefix for model IDs"); - modelIdPrefix = opts.nextOpt(); - } - else { - break; - } - } - - // minimal inputs - if (journalFilePath == null) { - System.err.println("No journal file was configured."); - exit(-1); - return; - } - if (outputFolder == null) { - System.err.println("No output folder was configured."); - exit(-1); - return; - } - - OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); - CurieHandler curieHandler = new MappedCurieHandler(); - BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, journalFilePath, outputFolder); - m3.dumpAllStoredModels(); - m3.dispose(); - } - - @CLIMethod("--import-owl-models") - public void importOWLModels(Opts opts) throws Exception { - opts.info("[-j|--journal JOURNALFILE] [-f|--folder OWLFILESFOLDER]", - "import all files in folder to database"); - // parameters - String journalFilePath = null; - String inputFolder = null; - - // parse opts - while (opts.hasOpts()) { - if (opts.nextEq("-j|--journal")) { - opts.info("journal file", "Sets the Blazegraph journal file for the database"); - journalFilePath = opts.nextOpt(); - } - else if (opts.nextEq("-f|--folder")) { - opts.info("OWL folder", "Sets the folder containing the LEGO model files"); - inputFolder = opts.nextOpt(); - } - else { - break; - } - } - - // minimal inputs - if (journalFilePath == null) { - System.err.println("No journal file was configured."); - exit(-1); - return; - } - if (inputFolder == null) { - System.err.println("No input folder was configured."); - exit(-1); - return; - } - - OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); - String modelIdPrefix = "http://model.geneontology.org/"; // this will not be used for anything - CurieHandler curieHandler = new MappedCurieHandler(); - BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, journalFilePath, null); - for (File file : FileUtils.listFiles(new File(inputFolder), null, true)) { - LOGGER.info("Loading " + file); - m3.importModelToDatabase(file, true); - } - m3.dispose(); - } - - @CLIMethod("--sparql-update") - public void sparqlUpdate(Opts opts) throws OWLOntologyCreationException, IOException, RepositoryException, MalformedQueryException, UpdateExecutionException { - opts.info("[-j|--journal JOURNALFILE] [-f|--file SPARQL UPDATE FILE]", - "apply SPARQL update to database"); - String journalFilePath = null; - String updateFile = null; - - // parse opts - while (opts.hasOpts()) { - if (opts.nextEq("-j|--journal")) { - opts.info("journal file", "Sets the Blazegraph journal file for the database"); - journalFilePath = opts.nextOpt(); - } - else if (opts.nextEq("-f|--file")) { - opts.info("OWL folder", "Sets the file containing a SPARQL update"); - updateFile = opts.nextOpt(); - } - else { - break; - } - } - - // minimal inputs - if (journalFilePath == null) { - System.err.println("No journal file was configured."); - exit(-1); - return; - } - if (updateFile == null) { - System.err.println("No update file was configured."); - exit(-1); - return; - } - - String update = FileUtils.readFileToString(new File(updateFile), StandardCharsets.UTF_8); - Properties properties = new Properties(); - properties.load(this.getClass().getResourceAsStream("/org/geneontology/minerva/blazegraph.properties")); - properties.setProperty(Options.FILE, journalFilePath); - BigdataSail sail = new BigdataSail(properties); - BigdataSailRepository repository = new BigdataSailRepository(sail); - repository.initialize(); - BigdataSailRepositoryConnection conn = repository.getUnisolatedConnection(); - BlazegraphMutationCounter counter = new BlazegraphMutationCounter(); - conn.addChangeLog(counter); - conn.prepareUpdate(QueryLanguage.SPARQL, update).execute(); - int changes = counter.mutationCount(); - conn.removeChangeLog(counter); - System.out.println("\nApplied " + changes + " changes"); - conn.close(); - } - - @CLIMethod("--owl-lego-to-json") - public void owl2LegoJson(Opts opts) throws Exception { - opts.info("[-o JSONFILE] [-i OWLFILE] [--pretty-json] [--compact-json]", - "converts the LEGO subset of OWL to Minerva-JSON"); - // parameters - String input = null; - String output = null; - boolean usePretty = true; - - // parse opts - while (opts.hasOpts()) { - if (opts.nextEq("-o|--output")) { - opts.info("output", "Sets the output file for the json"); - output = opts.nextOpt(); - } - else if (opts.nextEq("-i|--input")) { - opts.info("input", "Sets the input file for the model"); - input = opts.nextOpt(); - } - else if (opts.nextEq("--pretty-json")) { - opts.info("", "pretty print the output json"); - usePretty = true; - } - else if (opts.nextEq("--compact-json")) { - opts.info("", "compact print the output json"); - usePretty = false; - } - else { - break; - } - } - - // minimal inputs - if (input == null) { - System.err.println("No input model was configured."); - exit(-1); - return; - } - if (output == null) { - System.err.println("No output file was configured."); - exit(-1); - return; - } - - // configuration - CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); - GsonBuilder gsonBuilder = new GsonBuilder(); - if (usePretty) { - gsonBuilder.setPrettyPrinting(); - } - Gson gson = gsonBuilder.create(); - - // process each model - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Loading model from file: "+input); - } - OWLOntology model = null; - final JsonModel jsonModel; - try { - // load model - model = pw.parseOWL(IRI.create(new File(input).getCanonicalFile())); - InferenceProvider inferenceProvider = null; // TODO decide if we need reasoning - String modelId = null; - Optional ontologyIRI = model.getOntologyID().getOntologyIRI(); - if (ontologyIRI.isPresent()) { - modelId = curieHandler.getCuri(ontologyIRI.get()); - } - - // render json - final MolecularModelJsonRenderer renderer = new MolecularModelJsonRenderer(modelId, model, inferenceProvider, curieHandler); - jsonModel = renderer.renderModel(); - } - finally { - if (model != null) { - pw.getManager().removeOntology(model); - model = null; - } - } - - // save as json string - final String json = gson.toJson(jsonModel); - final File outputFile = new File(output).getCanonicalFile(); - try (OutputStream outputStream = new FileOutputStream(outputFile)) { - if (LOGGER.isInfoEnabled()) { - LOGGER.info("Saving json to file: "+outputFile); - } - IOUtils.write(json, outputStream); - } - } - - /** - * Translate the GeneAnnotations into a lego all individual OWL representation. - * - * Will merge the source ontology into the graph by default - * - * @param opts - * @throws Exception - */ - @CLIMethod("--gaf-lego-individuals") - public void gaf2LegoIndivduals(Opts opts) throws Exception { - boolean addLineNumber = false; - boolean merge = true; - boolean minimize = false; - String output = null; - CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); - OWLDocumentFormat format = new RDFXMLDocumentFormat(); - while (opts.hasOpts()) { - if (opts.nextEq("-o|--output")) { - output = opts.nextOpt(); - } - else if (opts.nextEq("--format")) { - String formatString = opts.nextOpt(); - if ("manchester".equalsIgnoreCase(formatString)) { - format = new ManchesterSyntaxDocumentFormat(); - } else if ("turtle".equalsIgnoreCase(formatString)) { - format = new TurtleDocumentFormat(); - } - else if ("functional".equalsIgnoreCase(formatString)) { - format = new FunctionalSyntaxDocumentFormat(); - } - } - else if (opts.nextEq("--add-line-number")) { - addLineNumber = true; - } - else if (opts.nextEq("--skip-merge")) { - merge = false; - } - else if (opts.nextEq("-m|--minimize")) { - opts.info("", "use module extraction to include module of ontology"); - minimize = true; - } - else { - break; - } - } - if (g != null && gafdoc != null && output != null) { - GafToLegoIndividualTranslator tr = new GafToLegoIndividualTranslator(g, curieHandler, addLineNumber); - OWLOntology lego = tr.translate(gafdoc); - - if (merge) { - new OWLGraphWrapper(lego).mergeImportClosure(true); - } - if (minimize) { - final OWLOntologyManager m = lego.getOWLOntologyManager(); - - SyntacticLocalityModuleExtractor sme = new SyntacticLocalityModuleExtractor(m, lego, ModuleType.BOT); - Set sig = new HashSet(lego.getIndividualsInSignature()); - Set moduleAxioms = sme.extract(sig); - - OWLOntology module = m.createOntology(IRI.generateDocumentIRI()); - m.addAxioms(module, moduleAxioms); - lego = module; - } - - OWLOntologyManager manager = lego.getOWLOntologyManager(); - OutputStream outputStream = null; - try { - outputStream = new FileOutputStream(output); - manager.saveOntology(lego, format, outputStream); - } - finally { - IOUtils.closeQuietly(outputStream); - } - } - else { - if (output == null) { - System.err.println("No output file was specified."); - } - if (g == null) { - System.err.println("No graph available for gaf-run-check."); - } - if (gafdoc == null) { - System.err.println("No loaded gaf available for gaf-run-check."); - } - exit(-1); - return; - } - } - - - /** - * Output GPAD files via inference+SPARQL, for testing only - * @param opts - * @throws Exception - */ - @CLIMethod("--lego-to-gpad-sparql") - public void legoToAnnotationsSPARQL(Opts opts) throws Exception { - String modelIdPrefix = "http://model.geneontology.org/"; - String modelIdcurie = "gomodel"; - String inputDB = "blazegraph.jnl"; - String gpadOutputFolder = null; - String ontologyIRI = "http://purl.obolibrary.org/obo/go/extensions/go-lego.owl"; - while (opts.hasOpts()) { - if (opts.nextEq("-i|--input")) { - inputDB = opts.nextOpt(); - } - else if (opts.nextEq("--gpad-output")) { - gpadOutputFolder = opts.nextOpt(); - } - else if (opts.nextEq("--model-id-prefix")) { - modelIdPrefix = opts.nextOpt(); - } - else if (opts.nextEq("--model-id-curie")) { - modelIdcurie = opts.nextOpt(); - } - else if (opts.nextEq("--ontology")) { - ontologyIRI = opts.nextOpt(); - } - else { - break; - } - } - OWLOntology ontology = OWLManager.createOWLOntologyManager().loadOntology(IRI.create(ontologyIRI)); - CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); - CurieHandler curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); - BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(ontology, curieHandler, modelIdPrefix, inputDB, null); - final String immutableModelIdPrefix = modelIdPrefix; - final String immutableGpadOutputFolder = gpadOutputFolder; - m3.getAvailableModelIds().stream().parallel().forEach(modelIRI -> { - try { - String gpad = new GPADSPARQLExport(curieHandler, m3.getLegacyRelationShorthandIndex(), m3.getTboxShorthandIndex(), m3.getDoNotAnnotateSubset()).exportGPAD(m3.createInferredModel(modelIRI)); - String fileName = StringUtils.replaceOnce(modelIRI.toString(), immutableModelIdPrefix, "") + ".gpad"; - Writer writer = new OutputStreamWriter(new FileOutputStream(Paths.get(immutableGpadOutputFolder, fileName).toFile()), StandardCharsets.UTF_8); - writer.write(gpad); - writer.close(); - } catch (InconsistentOntologyException e) { - LOGGER.error("Inconsistent ontology: " + modelIRI); - } catch (IOException e) { - LOGGER.error("Couldn't export GPAD for: " + modelIRI, e); - } - }); - m3.dispose(); - } - - @CLIMethod("--lego-to-gpad") - public void legoToAnnotations(Opts opts) throws Exception { - String modelIdPrefix = "http://model.geneontology.org/"; - String modelIdcurie = "gomodel"; - String inputFolder = null; - String singleFile = null; - String gpadOutputFolder = null; - String gafOutputFolder = null; - Map taxonGroups = null; - String defaultTaxonGroup = "other"; - boolean addLegoModelId = true; - String fileSuffix = "ttl"; - while (opts.hasOpts()) { - if (opts.nextEq("-i|--input")) { - inputFolder = opts.nextOpt(); - } - else if (opts.nextEq("--input-single-file")) { - singleFile = opts.nextOpt(); - } - else if (opts.nextEq("--gpad-output")) { - gpadOutputFolder = opts.nextOpt(); - } - else if (opts.nextEq("--gaf-output")) { - gafOutputFolder = opts.nextOpt(); - } - else if (opts.nextEq("--remove-lego-model-ids")) { - addLegoModelId = false; - } - else if (opts.nextEq("--model-id-prefix")) { - modelIdPrefix = opts.nextOpt(); - } - else if (opts.nextEq("-s|--input-file-suffix")) { - opts.info("SUFFIX", "if a directory is specified, use only files with this suffix. Default is 'ttl'"); - fileSuffix = opts.nextOpt(); - } - else if (opts.nextEq("--model-id-curie")) { - modelIdcurie = opts.nextOpt(); - } - else if (opts.nextEq("--group-by-model-organisms")) { - if (taxonGroups == null) { - taxonGroups = new HashMap<>(); - } - // get the pre-defined groups from the model-organism-groups.tsv resource - List lines = IOUtils.readLines(MinervaCommandRunner.class.getResourceAsStream("/model-organism-groups.tsv")); - for (String line : lines) { - line = StringUtils.trimToEmpty(line); - if (line.isEmpty() == false && line.charAt(0) != '#') { - String[] split = StringUtils.splitByWholeSeparator(line, "\t"); - if (split.length > 1) { - String group = split[0]; - Set taxonIds = new HashSet<>(); - for (int i = 1; i < split.length; i++) { - taxonIds.add(split[i]); - } - for(String taxonId : taxonIds) { - taxonGroups.put(taxonId, group); - } - } - } - - } - } - else if (opts.nextEq("--add-model-organism-group")) { - if (taxonGroups == null) { - taxonGroups = new HashMap<>(); - } - String group = opts.nextOpt(); - String taxon = opts.nextOpt(); - taxonGroups.put(taxon, group); - } - else if (opts.nextEq("--set-default-model-group")) { - defaultTaxonGroup = opts.nextOpt(); - } - else { - break; - } - } - // create curie handler - CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); - CurieHandler curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); - - ExternalLookupService lookup= null; - - SimpleEcoMapper mapper = EcoMapperFactory.createSimple(); - LegoToGeneAnnotationTranslator translator = new LegoToGeneAnnotationTranslator(g.getSourceOntology(), curieHandler, mapper); - GroupingTranslator groupingTranslator = new GroupingTranslator(translator, lookup, taxonGroups, defaultTaxonGroup, addLegoModelId); - - final OWLOntologyManager m = g.getManager(); - if (singleFile != null) { - File file = new File(singleFile).getCanonicalFile(); - OWLOntology model = m.loadOntology(IRI.create(file)); - groupingTranslator.translate(model); - } - else if (inputFolder != null) { - final String fileSuffixFinal = fileSuffix; - File inputFile = new File(inputFolder).getCanonicalFile(); - if (inputFile.isDirectory()) { - File[] files = inputFile.listFiles(new FilenameFilter() { - - @Override - public boolean accept(File dir, String name) { - if (fileSuffixFinal != null && fileSuffixFinal.length() > 0) - return name.endsWith("."+fileSuffixFinal); - else - return StringUtils.isAlphanumeric(name); - } - }); - for (File file : files) { - OWLOntology model = m.loadOntology(IRI.create(file)); - groupingTranslator.translate(model); - } - } - } - - // by state - for(String modelState : groupingTranslator.getModelStates()) { - GafDocument annotations = groupingTranslator.getAnnotationsByState(modelState); - sortAnnotations(annotations); - if (annotations != null) { - if (gpadOutputFolder != null) { - writeGpad(annotations, gpadOutputFolder, "all-"+modelState); - } - if (gafOutputFolder != null) { - writeGaf(annotations, gafOutputFolder, "all-"+modelState); - } - } - } - - // by organism - if (taxonGroups != null) { - for(String group : groupingTranslator.getTaxonGroups()) { - GafDocument filtered = groupingTranslator.getAnnotationsByGroup(group); - sortAnnotations(filtered); - if (gpadOutputFolder != null) { - writeGpad(filtered, gpadOutputFolder, group); - } - if (gafOutputFolder != null) { - writeGaf(filtered, gafOutputFolder, group); - } - } - } - - // production only by organism - if (taxonGroups != null) { - for(String group : groupingTranslator.getProductionTaxonGroups()) { - GafDocument filtered = groupingTranslator.getProductionAnnotationsByGroup(group); - sortAnnotations(filtered); - if (gpadOutputFolder != null) { - String productionFolder = new File(gpadOutputFolder, "production").getAbsolutePath(); - writeGpad(filtered, productionFolder+"", group); - } - if (gafOutputFolder != null) { - String productionFolder = new File(gafOutputFolder, "production").getAbsolutePath(); - writeGaf(filtered, productionFolder, group); - } - } - } - } - - static void sortAnnotations(GafDocument annotations) { - Collections.sort(annotations.getGeneAnnotations(), new Comparator() { - @Override - public int compare(GeneAnnotation a1, GeneAnnotation a2) { - return a1.toString().compareTo(a2.toString()); - } - }); - } - - private void writeGaf(GafDocument annotations, String outputFolder, String fileName) { - File outputFile = new File(outputFolder, fileName+".gaf"); - GafWriter writer = new GafWriter(); - try { - outputFile.getParentFile().mkdirs(); - writer.setStream(outputFile); - writer.write(annotations); - } - finally { - IOUtils.closeQuietly(writer); - } - } - - private void writeGpad(GafDocument annotations, String outputFolder, String fileName) throws FileNotFoundException { - PrintWriter fileWriter = null; - File outputFile = new File(outputFolder, fileName+".gpad"); - try { - outputFile.getParentFile().mkdirs(); - fileWriter = new PrintWriter(outputFile); - GpadWriter writer = new GpadWriter(fileWriter, 1.2d); - writer.write(annotations); - } - finally { - IOUtils.closeQuietly(fileWriter); - } - } - - /** - * Output whether each model provided is logically consistent or not - * example parameters for invocation: - * --owlcheck-go-cams -i /GitHub/GO_Shapes/test_ttl/go_cams/should_pass/ -c ./catalog-no-import.xml - * @param opts - * @throws Exception - */ - @CLIMethod("--owlcheck-go-cams") - public void owlCheckGoCams(Opts opts) throws Exception { - Logger LOG = Logger.getLogger(BlazegraphMolecularModelManager.class); - LOG.setLevel(Level.ERROR); - LOGGER.setLevel(Level.INFO); - String catalog = null; - String modelIdPrefix = "http://model.geneontology.org/"; - String modelIdcurie = "gomodel"; - String inputDB = "blazegraph.jnl"; - String explanationOutputFile = null; - String basicOutputFile = null; - String ontologyIRI = "http://purl.obolibrary.org/obo/go/extensions/go-lego.owl"; - String shexFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shex"; - String goshapemapFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shapeMap"; - String shexpath = null; - String shapemappath = null; - String input = null; - boolean checkShex = false; - Map modelid_filename = new HashMap(); - while (opts.hasOpts()) { - if (opts.nextEq("-i|--input")) { - input = opts.nextOpt(); - } - else if (opts.nextEq("--shex")) { - checkShex = true; - } - else if (opts.nextEq("--output-file")) { - basicOutputFile = opts.nextOpt(); - } - else if (opts.nextEq("--explanation-output-file")) { - explanationOutputFile = opts.nextOpt(); - } - else if (opts.nextEq("--model-id-prefix")) { - modelIdPrefix = opts.nextOpt(); - } - else if (opts.nextEq("--model-id-curie")) { - modelIdcurie = opts.nextOpt(); - } - else if (opts.nextEq("--ontology")) { - ontologyIRI = opts.nextOpt(); - } - else if (opts.nextEq("-c|--catalog")) { - catalog = opts.nextOpt(); - } - else { - break; - } - } - if(basicOutputFile==null) { - LOGGER.error("please specific an output file with --output-file "); - System.exit(-1); - } - if(input==null) { - LOGGER.error("please provide an input file - either a directory of ttl files or a blazegraph journal"); - System.exit(-1); - } - if(input.endsWith(".jnl")) { - inputDB = input; - LOGGER.info("loaded blazegraph journal: "+input); - }else { - LOGGER.info("no journal found, trying as directory: "+input); - File i = new File(input); - if(i.exists()) { - //remove anything that existed earlier - File bgdb = new File(inputDB); - if(bgdb.exists()) { - bgdb.delete(); - } - //load everything into a bg journal - OWLOntology dummy = OWLManager.createOWLOntologyManager().createOntology(IRI.create("http://example.org/dummy")); - CurieHandler curieHandler = new MappedCurieHandler(); - BlazegraphMolecularModelManager m3 = new BlazegraphMolecularModelManager<>(dummy, curieHandler, modelIdPrefix, inputDB, null); - if(i.isDirectory()) { - FileUtils.listFiles(i, null, true).parallelStream().parallel().forEach(file-> { - //for (File file : - //m3.getAvailableModelIds().stream().parallel().forEach(modelIRI -> { - if(file.getName().endsWith(".ttl")||file.getName().endsWith("owl")) { - LOGGER.info("Loading " + file); - try { - String modeluri = m3.importModelToDatabase(file, true); - modelid_filename.put(modeluri, file.getName()); - } catch (OWLOntologyCreationException | RepositoryException | RDFParseException - | RDFHandlerException | IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }); - }else { - LOGGER.info("Loading " + i); - m3.importModelToDatabase(i, true); - } - LOGGER.info("loaded files into blazegraph journal: "+input); - m3.dispose(); - } - } - LOGGER.info("loading tbox ontology: "+ontologyIRI); - OWLOntologyManager ontman = OWLManager.createOWLOntologyManager(); - if(catalog!=null) { - LOGGER.info("using catalog: "+catalog); - ontman.setIRIMappers(Sets.newHashSet(new owltools.io.CatalogXmlIRIMapper(catalog))); - }else { - LOGGER.info("no catalog, resolving all ontology uris directly"); - } - OWLOntology tbox_ontology = ontman.loadOntology(IRI.create(ontologyIRI)); - tbox_ontology = StartUpTool.forceMergeImports(tbox_ontology, tbox_ontology.getImports()); - LOGGER.info("ontology axioms loaded: "+tbox_ontology.getAxiomCount()); - LOGGER.info("building model manager and structural reasoner"); - CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); - CurieHandler curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); - UndoAwareMolecularModelManager m3 = new UndoAwareMolecularModelManager(tbox_ontology, curieHandler, modelIdPrefix, inputDB, null); - String reasonerOpt = "arachne"; - LOGGER.info("tbox reasoner for shex "+m3.getTbox_reasoner().getReasonerName()); - if(shexpath==null) { - //fall back on downloading from shapes repo - URL shex_schema_url = new URL(shexFileUrl); - shexpath = "./go-cam-schema.shex"; - File shex_schema_file = new File(shexpath); - org.apache.commons.io.FileUtils.copyURLToFile(shex_schema_url, shex_schema_file); - System.err.println("-s .No shex schema provided, using: "+shexFileUrl); - } - if(shapemappath==null) { - URL shex_map_url = new URL(goshapemapFileUrl); - shapemappath = "./go-cam-shapes.shapeMap"; - File shex_map_file = new File(shapemappath); - org.apache.commons.io.FileUtils.copyURLToFile(shex_map_url, shex_map_file); - System.err.println("-m .No shape map file provided, using: "+goshapemapFileUrl); - } - MinervaShexValidator shex = new MinervaShexValidator(shexpath, shapemappath, curieHandler, m3.getTbox_reasoner()); - if(checkShex) { - if(checkShex) { - shex.setActive(true); - }else { - shex.setActive(false); - } - } - LOGGER.info("Building OWL inference provider: "+reasonerOpt); - InferenceProviderCreator ipc = StartUpTool.createInferenceProviderCreator(reasonerOpt, m3, shex); - LOGGER.info("Validating models: "+reasonerOpt); - - FileWriter basic_output = new FileWriter(basicOutputFile); - try { - basic_output.write("filename\tmodel_id\tOWL_consistent\tshex_valid\n"); - final boolean shex_output = checkShex; - m3.getAvailableModelIds().stream().forEach(modelIRI -> { - try { - String filename = modelid_filename.get(modelIRI.toString()); - boolean isConsistent = true; - boolean isConformant = true; - LOGGER.info("processing "+filename+"\t"+modelIRI); - ModelContainer mc = m3.getModel(modelIRI); - //not reporting OWL errors ? - InferenceProvider ip = ipc.create(mc); - isConsistent = ip.isConsistent(); - if(shex_output) { - ValidationResultSet validations = ip.getValidation_results(); - isConformant = validations.allConformant(); - LOGGER.info(filename+"\t"+modelIRI+"\tOWL:"+isConsistent+"\tshex:"+isConformant); - basic_output.write(filename+"\t"+modelIRI+"\t"+isConsistent+"\t"+isConformant+"\n"); - }else { - LOGGER.info(filename+"\t"+modelIRI+"\tOWL:"+isConsistent+"\tshex:not checked"); - basic_output.write(filename+"\t"+modelIRI+"\t"+isConsistent+"\tnot checked\n"); - } - } catch (InconsistentOntologyException e) { - LOGGER.error("Inconsistent model: " + modelIRI); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - }); - m3.dispose(); - }finally{ - basic_output.close(); - } - } - - - /** - * Will test a go-cam model or directory of models against a shex schema and shape map to test conformance - * Example invocation: --validate-go-cams -s /Users/bgood/Documents/GitHub/GO_Shapes/shapes/go-cam-shapes.shex -m /Users/bgood/Documents/GitHub/GO_Shapes/shapes/go-cam-shapes.shapeMap -f /Users/bgood/Documents/GitHub/GO_Shapes/test_ttl/go_cams/should_pass/ -e -r /Users/bgood/Desktop/shapely_report.txt - * @param opts - * @throws Exception - */ - @CLIMethod("--validate-go-cams") - public void validateGoCams(Opts opts) throws Exception { - String url_for_tbox = "http://purl.obolibrary.org/obo/go/extensions/go-lego.owl"; - String shexFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shex"; - String goshapemapFileUrl = "https://raw.githubusercontent.com/geneontology/go-shapes/master/shapes/go-cam-shapes.shapeMap"; - - ShexValidator validator = null; - String shexpath = null;//"../shapes/go-cam-shapes.shex"; - String shapemappath = null; - String model_file = null;//"../test_ttl/go_cams/should_pass/typed_reactome-homosapiens-Acetylation.ttl"; - String report_file = null; - boolean addSuperClasses = true;//this always needs to be on unless we have a major shex refactor - boolean addSuperClassesLocal = false; - boolean travisMode = false; - boolean shouldPass = true; - String extra_endpoint = null; - String catalog = null; - Map name_model = new HashMap(); - - while (opts.hasOpts()) { - if(opts.nextEq("-travis")) { - travisMode = true; - } - else if (opts.nextEq("-f|--file")) { - model_file = opts.nextOpt(); - name_model = Enricher.loadRDF(model_file); - } - else if (opts.nextEq("-shouldfail")) { - shouldPass = false; - } - else if (opts.nextEq("-s|--shexpath")) { - shexpath = opts.nextOpt(); - } - else if(opts.nextEq("-m|--shapemap")) { - shapemappath = opts.nextOpt(); - } - else if(opts.nextEq("-r|--report")) { - report_file = opts.nextOpt(); - } - else if(opts.nextEq("-localtbox")) { - addSuperClassesLocal = true; //this will download the beast unless there is a catalogue file - } - else if(opts.nextEq("-extra_endpoint")) { - extra_endpoint = opts.nextOpt(); - } - else if (opts.nextEq("-c|--catalog")) { - catalog = opts.nextOpt(); - } - else { - break; - } - } - if(shexpath==null) { - //fall back on downloading from shapes repo - URL shex_schema_url = new URL(shexFileUrl); - shexpath = "./go-cam-schema.shex"; - File shex_schema_file = new File(shexpath); - org.apache.commons.io.FileUtils.copyURLToFile(shex_schema_url, shex_schema_file); - System.err.println("-s .No shex schema provided, using: "+shexFileUrl); - } - if(shapemappath==null) { - URL shex_map_url = new URL(goshapemapFileUrl); - shapemappath = "./go-cam-shapes.shapeMap"; - File shex_map_file = new File(shapemappath); - org.apache.commons.io.FileUtils.copyURLToFile(shex_map_url, shex_map_file); - System.err.println("-m .No shape map file provided, using: "+goshapemapFileUrl); - } - if(report_file==null) { - report_file = "./shex_report.txt"; - System.err.println("-r .No report file specified, using "+report_file); - } - if(!addSuperClassesLocal) { - System.out.println("Using RDF endpoint for super class expansion: "+Enricher.go_endpoint); - System.out.println("add -localtbox to retrieve the ontology from http://purl.obolibrary.org/obo/go/extensions/go-lego.owl " - + "and do the inferences locally. This is slower and uses much more memory, but at least you know what you are getting. " - + "You can use a catalog file by adding -c yourcatalog.xml " - + "- catalog files allow you to map URIs to local files to change " - + "what they resolve to and to reduce network traffic time."); - } - //requirements - if(model_file==null) { - System.err.println("-f .No go-cam file or directory provided to validate."); - exit(-1); - }else { - FileWriter w = new FileWriter(report_file); - int good = 0; int bad = 0; - Enricher enrich = new Enricher(extra_endpoint, null); - if(addSuperClassesLocal) { - OWLOntologyManager ontman = OWLManager.createOWLOntologyManager(); - if(catalog!=null) { - System.out.println("using catalog: "+catalog); - ontman.setIRIMappers(Sets.newHashSet(new owltools.io.CatalogXmlIRIMapper(catalog))); - }else { - System.out.println("no catalog, resolving all import ontology uris directly, be patient..."); - } - OWLOntology tbox_ontology = ontman.loadOntology(IRI.create(url_for_tbox)); - tbox_ontology = StartUpTool.forceMergeImports(tbox_ontology, tbox_ontology.getImports()); - System.out.println("ontology axioms loaded: "+tbox_ontology.getAxiomCount()); - System.out.println("building model manager"); - - System.out.println("done loading, building structural reasoner"); - OWLReasonerFactory reasonerFactory = new StructuralReasonerFactory(); - OWLReasoner tbox_reasoner = reasonerFactory.createReasoner(tbox_ontology); - validator = new ShexValidator(shexpath, shapemappath, tbox_reasoner); - enrich = new Enricher(null, tbox_reasoner); - }else { - validator = new ShexValidator(shexpath, shapemappath, null); - } - for(String name : name_model.keySet()) { - Model test_model = name_model.get(name); - if(addSuperClasses) { - test_model = enrich.enrichSuperClasses(test_model); - } - if(validator.GoQueryMap!=null){ - boolean stream_output = false; - ShexValidationReport r = validator.runShapeMapValidation(test_model, stream_output); - System.out.println(name+" conformant:"+r.isConformant()); - w.write(name+"\t"); - if(!r.isConformant()) { - w.write("invalid\n"); - bad++; - if(travisMode&&(shouldPass)) { - System.out.println(name+" should have validated but did not "+r.getAsText()); - System.exit(-1); - } - }else { - good++; - w.write("valid\n"); - if(travisMode&&(!shouldPass)) { - System.out.println(name+" should NOT have validated but did "); - System.exit(-1); - } - } - } - } - w.close(); - System.out.println("input: "+model_file+" total:"+name_model.size()+" Good:"+good+" Bad:"+bad); - } - } -} diff --git a/minerva-converter/pom.xml b/minerva-converter/pom.xml index 004e5dc2..9210761e 100644 --- a/minerva-converter/pom.xml +++ b/minerva-converter/pom.xml @@ -21,11 +21,9 @@ ${project.parent.version} test - - org.bbop - OWLTools-Core - test-jar - test + + com.google.code.gson + gson diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoIndividualTranslator.java b/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoIndividualTranslator.java deleted file mode 100644 index f869a64d..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoIndividualTranslator.java +++ /dev/null @@ -1,394 +0,0 @@ -package org.geneontology.minerva; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.apache.commons.lang3.StringUtils; -import org.apache.log4j.Logger; -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.semanticweb.owlapi.model.AddImport; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotation; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLAxiom; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLException; -import org.semanticweb.owlapi.model.OWLImportsDeclaration; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObject; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyID; -import org.semanticweb.owlapi.model.OWLOntologyManager; - -import com.google.common.base.Optional; - -import owltools.gaf.Bioentity; -import owltools.gaf.ExtensionExpression; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.graph.OWLGraphWrapper; -import owltools.vocab.OBOUpperVocabulary; - - -/** - * Simple translation of {@link GeneAnnotation} to the all individual lego annotation model. - * - */ -public class GafToLegoIndividualTranslator { - - private static Logger logger = Logger.getLogger(GafToLegoIndividualTranslator.class); - - private final OWLGraphWrapper graph; - private final CurieHandler curieHandler; - private final OWLObjectProperty partOf; - private final OWLObjectProperty occursIn; - private final OWLObjectProperty inTaxon; - private OWLClass mf; - private OWLObjectProperty enabledBy; - - private Map allOWLObjectsByAltId; - - private final boolean addLineNumber; - - public GafToLegoIndividualTranslator(OWLGraphWrapper graph, CurieHandler curieHandler, boolean addLineNumber) { - this.graph = graph; - this.curieHandler = curieHandler; - this.addLineNumber = addLineNumber; - allOWLObjectsByAltId = graph.getAllOWLObjectsByAltId(); - OWLDataFactory df = graph.getDataFactory(); - partOf = OBOUpperVocabulary.BFO_part_of.getObjectProperty(df); - occursIn = OBOUpperVocabulary.BFO_occurs_in.getObjectProperty(df); - - mf = OBOUpperVocabulary.GO_molecular_function.getOWLClass(df); - enabledBy = OBOUpperVocabulary.GOREL_enabled_by.getObjectProperty(df); - inTaxon = graph.getOWLObjectPropertyByIdentifier("RO:0002162"); // in taxon - } - - protected void reportError(String error, GeneAnnotation annotation) { - logger.error(error+" \t Annotation: "+annotation.toString()); - } - - protected void reportWarn(String warning, GeneAnnotation annotation) { - logger.warn(warning+" \t Annotation: "+annotation.toString()); - } - - /** - * Translate the given {@link GafDocument} into an OWL representation of the LEGO model. - * - * @param gaf - * @return lego ontology - * @throws OWLException - * @throws UnknownIdentifierException - */ - public OWLOntology translate(GafDocument gaf) throws OWLException, UnknownIdentifierException { - final OWLOntologyManager m = graph.getManager(); - OWLOntology lego = m.createOntology(IRI.generateDocumentIRI()); - OWLOntology sourceOntology = graph.getSourceOntology(); - OWLOntologyID ontologyID = sourceOntology.getOntologyID(); - if (ontologyID != null) { - Optional ontologyIRI = ontologyID.getOntologyIRI(); - if (ontologyIRI.isPresent()) { - OWLDataFactory f = m.getOWLDataFactory(); - OWLImportsDeclaration importDeclaration = f.getOWLImportsDeclaration(ontologyIRI.get()); - m.applyChange(new AddImport(lego, importDeclaration )); - } - } - translate(gaf.getGeneAnnotations(), lego); - return lego; - } - - /** - * Translate the given annotations ({@link GeneAnnotation}) into an OWL representation of the LEGO model. - * - * @param annotations - * @param lego - * @throws OWLException - * @throws UnknownIdentifierException - */ - public void translate(Collection annotations, final OWLOntology lego) throws OWLException, UnknownIdentifierException { - final OWLOntologyManager m = graph.getManager(); - - Set axioms = new HashSet(); - for(GeneAnnotation annotation : annotations) { - translate(annotation, axioms); - } - m.addAxioms(lego, axioms); - } - - /** - * Translate theGeneAnnotation into an OWL representation of the LEGO model. - * - * @param annotation - * @param axioms - * @throws OWLException - * @throws UnknownIdentifierException - */ - public void translate(GeneAnnotation annotation, Set axioms) throws OWLException, UnknownIdentifierException { - // skip ND annotations - if ("ND".equals(annotation.getShortEvidence())) { - reportWarn("Skipping ND annotation", annotation); - return; - } - // skip annotation using a qualifier - String rel = StringUtils.trimToNull(annotation.getRelation()); - if (rel != null) { - if ("enables".equals(rel) == false && "part_of".equals(rel) == false && "involved_in".equals(rel) == false) { - reportWarn("Skipping annotation with unsupported relation: "+annotation.getRelation(), annotation); - return; - } - } - - final OWLDataFactory f = graph.getDataFactory(); - - - final String annotationClsString = annotation.getCls(); - final OWLClass c = getOwlClass(annotationClsString); - if (c == null) { - reportError("Could not find a class for the given identifier: "+annotationClsString, annotation); - return; - } - - List> extensionExpressionGroups = annotation.getExtensionExpressions(); - if (extensionExpressionGroups != null && !extensionExpressionGroups.isEmpty()) { - Set parsedGroups = new HashSet(); - for(List group : extensionExpressionGroups) { - Set operands = new HashSet(); - for(ExtensionExpression extension : group) { - final String extensionClsString = extension.getCls(); - final String extensionRelationString = extension.getRelation(); - OWLClass extensionCls = getOwlClass(extensionClsString); - if (extensionCls == null) { - try { - IRI extensionIRI = curieHandler.getIRI(extensionClsString); - extensionCls = f.getOWLClass(extensionIRI); - } catch (UnknownIdentifierException e) { - reportError("Could not find the extension class IRI: " + extensionClsString, annotation); - return; - } - } - final OWLObjectProperty extensionRelation = graph.getOWLObjectPropertyByIdentifier(extensionRelationString); - if (extensionRelation == null) { - reportError("Could not find a class for the given extension relation identifier: "+extensionRelationString, annotation); - continue; - } - operands.add(f.getOWLObjectSomeValuesFrom(extensionRelation, extensionCls)); - } - operands.add(c); - parsedGroups.add(f.getOWLObjectIntersectionOf(operands)); - } - if (annotation.isNegated()) { - OWLClassExpression union = f.getOWLObjectUnionOf(parsedGroups); - translate(annotation, union, axioms); - } - else { - for(OWLClassExpression ce : parsedGroups) { - translate(annotation, ce, axioms); - } - } - } - else { - translate(annotation, c, axioms); - } - } - - - private void translate(GeneAnnotation annotation, OWLClassExpression ce, Set axioms) throws OWLException, UnknownIdentifierException { - final OWLDataFactory f = graph.getDataFactory(); - - // # STEP 1 - Bioentity instance - final Bioentity bioentity = annotation.getBioentityObject(); - final String isoForm = StringUtils.trimToNull(annotation.getGeneProductForm()); - - final OWLClass bioentityClass; - if (isoForm == null) { - // option #1: default bioentity id - try { - bioentityClass = addBioentityCls(bioentity.getId(), bioentity.getSymbol(), bioentity.getNcbiTaxonId(), axioms, f); - } catch (UnknownIdentifierException e) { - reportError("Could not find a class for the Bioentity: " + bioentity, annotation); - return; - } - } - else { - // option #2: ISO-form as subclass of bioentity - try { - bioentityClass = addBioentityCls(isoForm, bioentity.getSymbol()+" ISO Form "+isoForm, bioentity.getNcbiTaxonId(), axioms, f); - } catch (UnknownIdentifierException e) { - reportError("Could not find a class for the Bioentity: " + bioentity, annotation); - return; - } - try { - OWLClass bioentityClassSuper = addBioentityCls(bioentity.getId(), bioentity.getSymbol(), bioentity.getNcbiTaxonId(), axioms, f); - - axioms.add(f.getOWLDeclarationAxiom(bioentityClassSuper)); - axioms.add(f.getOWLSubClassOfAxiom(bioentityClass, bioentityClassSuper)); - } catch (UnknownIdentifierException e) { - reportError("Could not find a class for the Bioentity: " + bioentity, annotation); - return; - } - } - - IRI bioentityInstanceIRI = generateNewIRI("bioentity", bioentityClass); - OWLNamedIndividual bioentityInstance = f.getOWLNamedIndividual(bioentityInstanceIRI); - axioms.add(f.getOWLDeclarationAxiom(bioentityInstance)); - axioms.add(f.getOWLClassAssertionAxiom(bioentityClass, bioentityInstance)); - - // # STEP 2 - create instance: - - // use Aspect to switch between the three options: P == BP, C == CC, F = MF - String aspect = annotation.getAspect(); - if (aspect == null) { - reportError("Error, no aspect defined.", annotation); - return; - } - - // TODO evidence - Set annotations = Collections.emptySet(); - if (addLineNumber) { - int lineNumber = annotation.getSource().getLineNumber(); - OWLAnnotation source = f.getOWLAnnotation(getLineNumberProperty(axioms, f), f.getOWLLiteral(lineNumber)); - annotations = Collections.singleton(source); - } - boolean negated = annotation.isNegated(); - if (negated) { - handleNegated(bioentityClass, aspect, annotations, ce, axioms, f); - return; - } - - //List sources = annotation.getReferenceIds(); - if ("F".equals(aspect)) { - // create individual - OWLNamedIndividual individual = f.getOWLNamedIndividual(generateNewIRI("mf", ce)); - axioms.add(f.getOWLDeclarationAxiom(individual)); - - // types - axioms.add(f.getOWLClassAssertionAxiom(ce, individual)); - - // link instances - - axioms.add(f.getOWLObjectPropertyAssertionAxiom(enabledBy, individual, bioentityInstance, annotations)); - } - else if ("C".equals(aspect)) { - // generic mf instance - OWLNamedIndividual mfIndividual = f.getOWLNamedIndividual(generateNewIRI("mf", mf)); - axioms.add(f.getOWLDeclarationAxiom(mfIndividual)); - - // generic mf type - axioms.add(f.getOWLClassAssertionAxiom(mf, mfIndividual)); - - // link mf to bioentity - axioms.add(f.getOWLObjectPropertyAssertionAxiom(enabledBy, mfIndividual, bioentityInstance)); - - // cc instance - OWLNamedIndividual ccIndividual = f.getOWLNamedIndividual(generateNewIRI("cc", ce)); - axioms.add(f.getOWLDeclarationAxiom(ccIndividual)); - - // cc type - axioms.add(f.getOWLClassAssertionAxiom(ce, ccIndividual)); - - // link cc and mf - axioms.add(f.getOWLObjectPropertyAssertionAxiom(occursIn, ccIndividual, mfIndividual, annotations)); - - - } - else if ("P".equals(aspect)) { - // generic mf instance - OWLNamedIndividual mfIndividual = f.getOWLNamedIndividual(generateNewIRI("mf", mf)); - axioms.add(f.getOWLDeclarationAxiom(mfIndividual)); - - // generic mf type - axioms.add(f.getOWLClassAssertionAxiom(mf, mfIndividual)); - - // link mf to bioentity - axioms.add(f.getOWLObjectPropertyAssertionAxiom(enabledBy, mfIndividual, bioentityInstance)); - - // cc instance - OWLNamedIndividual bpIndividual = f.getOWLNamedIndividual(generateNewIRI("bp", ce)); - axioms.add(f.getOWLDeclarationAxiom(bpIndividual)); - - // cc type - axioms.add(f.getOWLClassAssertionAxiom(ce, bpIndividual)); - - // link cc and mf - axioms.add(f.getOWLObjectPropertyAssertionAxiom(partOf, bpIndividual, mfIndividual, annotations)); - } - } - - private void handleNegated(OWLClass bioentityClass, String aspect, Set annotations, - OWLClassExpression ce, Set axioms, OWLDataFactory f) { - if ("F".equals(aspect)) { - OWLClassExpression notCE = f.getOWLObjectComplementOf(f.getOWLObjectSomeValuesFrom(enabledBy, ce)); - axioms.add(f.getOWLSubClassOfAxiom(bioentityClass, notCE, annotations)); - } - else if ("C".equals(aspect)) { - OWLClassExpression notCE = f.getOWLObjectComplementOf(f.getOWLObjectSomeValuesFrom(occursIn, ce)); - axioms.add(f.getOWLSubClassOfAxiom(bioentityClass, notCE, annotations)); - } - else if ("P".equals(aspect)) { - OWLClassExpression notCE = f.getOWLObjectComplementOf(f.getOWLObjectSomeValuesFrom(partOf, ce)); - axioms.add(f.getOWLSubClassOfAxiom(bioentityClass, notCE, annotations)); - } - } - - private OWLClass addBioentityCls(String id, String lbl, String taxon, Set axioms, OWLDataFactory f) throws UnknownIdentifierException { - IRI iri = curieHandler.getIRI(id); - OWLClass cls = f.getOWLClass(iri); - boolean add = axioms.add(f.getOWLDeclarationAxiom(cls)); - if (add) { - OWLAnnotation annotation = f.getOWLAnnotation(f.getRDFSLabel(), f.getOWLLiteral(lbl)); - axioms.add(f.getOWLAnnotationAssertionAxiom(iri, annotation)); - if (taxon != null) { - OWLClass taxonClass = f.getOWLClass(curieHandler.getIRI(taxon)); - axioms.add(f.getOWLDeclarationAxiom(taxonClass)); - axioms.add(f.getOWLSubClassOfAxiom(cls, - f.getOWLObjectSomeValuesFrom(inTaxon, taxonClass))); - } - } - return cls; - } - - /** - * @param id - * @return cls or null - */ - private OWLClass getOwlClass(String id) { - OWLClass cls = graph.getOWLClassByIdentifier(id); - if (cls == null) { - // check alt ids - OWLObject owlObject = allOWLObjectsByAltId.get(id); - if (owlObject != null && owlObject instanceof OWLClass) { - cls = (OWLClass) owlObject; - } - } - return cls; - } - - - private static final IRI GAF_LINE_NUMBER = IRI.create("http://gaf/line_number"); - - private OWLAnnotationProperty getLineNumberProperty(Set axioms, OWLDataFactory f) { - OWLAnnotationProperty p = f.getOWLAnnotationProperty(GAF_LINE_NUMBER); - axioms.add(f.getOWLDeclarationAxiom(p)); - return p; - } - - private IRI generateNewIRI(String type, OWLClassExpression ce) { - if( ce.isAnonymous() == false) { - OWLClass c = ce.asOWLClass(); - String id = StringUtils.replace(curieHandler.getCuri(c), ":", "_"); - type = type + "-" + id; - } - return IRI.create("http://geneontology.org/lego/"+type+"-"+UUID.randomUUID().toString()); - - } - -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoTranslator.java b/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoTranslator.java deleted file mode 100644 index bb569394..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/GafToLegoTranslator.java +++ /dev/null @@ -1,496 +0,0 @@ -package org.geneontology.minerva; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import org.apache.log4j.Logger; -import org.obolibrary.obo2owl.Obo2OWLConstants; -import org.semanticweb.owlapi.model.AddImport; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLAxiom; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLDeclarationAxiom; -import org.semanticweb.owlapi.model.OWLEntity; -import org.semanticweb.owlapi.model.OWLException; -import org.semanticweb.owlapi.model.OWLImportsDeclaration; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObject; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyManager; -import org.semanticweb.owlapi.vocab.OWLRDFVocabulary; - -import com.google.common.base.Optional; - -import owltools.gaf.Bioentity; -import owltools.gaf.ExtensionExpression; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.graph.OWLGraphWrapper; -import owltools.vocab.OBOUpperVocabulary; -import uk.ac.manchester.cs.owlapi.modularity.ModuleType; -import uk.ac.manchester.cs.owlapi.modularity.SyntacticLocalityModuleExtractor; - -/** - *
-Given a set of gene associations, this procedure will generate LEGO individuals.
-
-The set of associations can be specified by a user query. Includes:
-
- * grepping a GAF and feeding results
- * selecting all associations for all genes that are involved with some process
-
-# STEP 0 - map GeneAssociation in GAF model
-
-GeneAssociation(
- bioentity:
- class:
- ext:
- reference:
- evidence: # TODO
-)
-
-==>
-
-# STEP 1 - calculate class expression
-
-IF 
- THEN let  = IntersectionOf( )
- ELSE let  = 
-
-# STEP 2 - map to protein ID
-
-IF .IRI startsWith "uniProtKB"
- THEN let  = 
- ELSE let  = SELECT  WHERE  SubClassOf encoded_by some   ### requires Omeo
-
-# STEP 3 - create instance:
-
-IF  SubClassOf MF THEN:
-
- NamedIndividual( 
-   Types: 
-     ,
-     enabled_by SOME 
-   Facts:
-     source 
-
-ELSE IF  SubClassOf CC THEN:
-
- NamedIndividual( 
-   Types: 
-     'molecular_function', occurs_in some  
-     enabled_by SOME 
-   Facts:
-     source 
-
-ELSE IF  SubClassOf BP THEN:
-
-  # note we create two individuals here
-
- NamedIndividual( 
-   Types: 
-     
-   Facts:
-     source 
-
-
- NamedIndividual( 
-   Types: 
-     'molecular_function'
-     enabled_by SOME 
-  Facts:
-    part_of ,
-    source 
-
-
-# VARIANT OF ABOVE STEP
-
-(optional)
-
-keep a map of Refs -> generated Ids 
-
-when performing , first check map. If an individual Id has already been generated for this , then re-use the existing id from the map.
-
-Note this may result in multiple classification of individuals (MCI). The user can rectify these in Protege.
-
-One variant of this strategy may be to retain the original Id,
-generate new Ids for the collapsed aggregate MF individual, and
-include evidence links back to the atomic MF individuals.
-
-
- -@see lego-from-gaf.txt - */ -@Deprecated -public class GafToLegoTranslator { - - private static Logger logger = Logger.getLogger(GafToLegoTranslator.class); - - private final OWLGraphWrapper graph; - private final Map gp2protein; - private OWLObjectProperty partOf; - private OWLObjectProperty occursIn; - private OWLClass mf; - private OWLObjectProperty enabledBy; - private OWLObjectProperty geneProductOf; - - private Map allOWLObjectsByAltId; - - public GafToLegoTranslator(OWLGraphWrapper graph, Map gp2protein) { - this.graph = graph; - allOWLObjectsByAltId = graph.getAllOWLObjectsByAltId(); - this.gp2protein = gp2protein; - OWLDataFactory df = graph.getDataFactory(); - partOf = OBOUpperVocabulary.BFO_part_of.getObjectProperty(df); - occursIn = OBOUpperVocabulary.BFO_occurs_in.getObjectProperty(df); - - mf = OBOUpperVocabulary.GO_molecular_function.getOWLClass(df); - enabledBy = OBOUpperVocabulary.GOREL_enabled_by.getObjectProperty(df); - geneProductOf = OBOUpperVocabulary.RO_gene_product_of.getObjectProperty(df); - } - - protected void reportError(String error, GeneAnnotation annotation) { - logger.error(error+" \t Annotation: "+annotation.toString()); - } - - protected void reportWarn(String warning, GeneAnnotation annotation) { - logger.warn(warning+" \t Annotation: "+annotation.toString()); - } - - /** - * Translate the given {@link GafDocument} into an OWL representation of the LEGO model. - * - * @param gaf - * @return lego ontology - */ - public OWLOntology translate(GafDocument gaf) { - return translate(gaf.getGeneAnnotations()); - } - - /** - * Translate the given annotations ({@link GeneAnnotation}) into an OWL representation of the LEGO model. - * - * @param annotations - * @return lego ontology - */ - public OWLOntology translate(Collection annotations) { - final OWLDataFactory f = graph.getDataFactory(); - final OWLOntologyManager m = graph.getManager(); - try { - OWLOntology lego = m.createOntology(IRI.generateDocumentIRI()); - // add all ontologies from the graph wrapper as import to the new ontology - Set allOntologies = graph.getAllOntologies(); - for (OWLOntology importOntology : allOntologies) { - Optional importIRI = importOntology.getOntologyID().getOntologyIRI(); - if (importIRI.isPresent()) { - OWLImportsDeclaration importDeclaration = f.getOWLImportsDeclaration(importIRI.get()); - m.applyChange(new AddImport(lego, importDeclaration)); - } - } - - for(GeneAnnotation annotation : annotations) { - /* - * GeneAssociation( - * bioentity: - * class: - * ext: - * reference: - * evidence: # TODO - * ) - */ - final String annotationClsString = annotation.getCls(); - final OWLClass c = getOwlClass(annotationClsString); - String classLabel = graph.getLabel(c); - if (c == null) { - reportError("Could not find a class for the given identifier: "+annotationClsString, annotation); - continue; - } - - // STEP 1 - calculate class expression - // - // IF - // THEN let = IntersectionOf( ) - // ELSE let = - - final Set ceSet; - List> extensionExpressionGroups = annotation.getExtensionExpressions(); - if (extensionExpressionGroups != null && !extensionExpressionGroups.isEmpty()) { - ceSet = new HashSet(); - for(List group : extensionExpressionGroups) { - Set operands = new HashSet(); - for(ExtensionExpression extension : group) { - final String extensionClsString = extension.getCls(); - final String extensionRelationString = extension.getRelation(); - OWLClass extensionCls = getOwlClass(extensionClsString); - if (extensionCls == null && extensionClsString.startsWith("UniProtKB:")) { - IRI iri = IRI.create(Obo2OWLConstants.DEFAULT_IRI_PREFIX+"pr/"+extensionClsString.substring(10)); - extensionCls = f.getOWLClass(iri); - } - if (extensionCls == null) { - reportError("Could not find a class for the given extension cls identifier: "+extensionClsString, annotation); - continue; - } - final OWLObjectProperty extensionRelation = graph.getOWLObjectPropertyByIdentifier(extensionRelationString); - if (extensionRelation == null) { - reportError("Could not find a class for the given extension relation identifier: "+extensionRelationString, annotation); - continue; - } - operands.add(f.getOWLObjectSomeValuesFrom(extensionRelation, extensionCls)); - } - // if (operands.size() != extensionExpressions.size()) { - // reportError("Problems during the translation of the annotation extensions.", annotation); - // continue; - // } - operands.add(c); - ceSet.add(f.getOWLObjectIntersectionOf(operands)); - } - } - else { - ceSet = Collections.singleton(c); - } - - // # STEP 2 - map to protein ID - Bioentity bioentity = annotation.getBioentityObject(); - String dbprefix = bioentity.getDb(); - String annLabel = bioentity.getSymbol() + " " + classLabel; - - // TODO use ISO form information - // IF .IRI startsWith "uniProtKB" - // THEN let = - OWLClassExpression enabler; - if (dbprefix.equalsIgnoreCase("uniProtKB")) { - OWLClass pr = f.getOWLClass(IRI.create(Obo2OWLConstants.DEFAULT_IRI_PREFIX+"pr/"+bioentity.getDBID())); - addBioEntity(pr, lego, bioentity); - enabler = pr; - } - else { - // TODO use gp2protein - OWLClass gene = f.getOWLClass(graph.getIRIByIdentifier(bioentity.getId())); - OWLClassExpression pr = f.getOWLObjectSomeValuesFrom(geneProductOf, gene); - addBioEntity(gene, lego, bioentity); - enabler = pr; - //reportWarn("Skipping non-uniProtKB bioentity: "+bioentity.getId(), annotation); - //continue; - } - - // # STEP 3 - create instance: - - // use Aspect to switch between the three options: P == BP, C == CC, F = MF - String aspect = annotation.getAspect(); - if (aspect == null) { - reportError("Error, no aspect defined.", annotation); - continue; - } - - Set axioms = new HashSet(); - List sources = annotation.getReferenceIds(); - OWLNamedIndividual annIndividual = null; - // IF SubClassOf MF THEN: - if ("F".equals(aspect)) { - // NamedIndividual( - // Types: - // , - // enabled_by SOME - // Facts: - // source - - for(OWLClassExpression ce : ceSet) { - // create individual - OWLNamedIndividual individual = f.getOWLNamedIndividual(generateNewIRI(lego, "mf")); - axioms.add(f.getOWLDeclarationAxiom(individual)); - - // facts - OWLAnnotationProperty dcsource = getDcSourceProperty(lego, f); - for(String source : sources) { - axioms.add(f.getOWLAnnotationAssertionAxiom(dcsource, individual.getIRI(), f.getOWLLiteral(source))); - } - - // types - axioms.add(f.getOWLClassAssertionAxiom(ce, individual)); - axioms.add(f.getOWLClassAssertionAxiom(f.getOWLObjectSomeValuesFrom(enabledBy, enabler), individual)); - - axioms.add(labelAxiom(f, individual, annLabel)); - } - } - // ELSE IF SubClassOf CC THEN: - else if ("C".equals(aspect)) { - // NamedIndividual( - // Types: - // 'molecular_function', occurs_in some - // enabled_by SOME - // Facts: - // source - - for(OWLClassExpression ce : ceSet) { - OWLNamedIndividual individual = f.getOWLNamedIndividual(generateNewIRI(lego, "cc")); - axioms.add(f.getOWLDeclarationAxiom(individual)); - - // facts - OWLAnnotationProperty dcsource = getDcSourceProperty(lego, f); - for(String source : sources) { - axioms.add(f.getOWLAnnotationAssertionAxiom(dcsource, individual.getIRI(), f.getOWLLiteral(source))); - } - - // types - axioms.add(f.getOWLClassAssertionAxiom(mf, individual)); - axioms.add(f.getOWLClassAssertionAxiom(f.getOWLObjectSomeValuesFrom(occursIn, ce), individual)); - axioms.add(f.getOWLClassAssertionAxiom(f.getOWLObjectSomeValuesFrom(enabledBy, enabler), individual)); - - axioms.add(labelAxiom(f, individual, annLabel)); - - } - } - //ELSE IF SubClassOf BP THEN: - else if ("P".equals(aspect)) { - // # note we create two individuals here - - for(OWLClassExpression ce : ceSet) { - // NamedIndividual( - // Types: - // - // Facts: - // source - // create individual - OWLNamedIndividual individualX = f.getOWLNamedIndividual(generateNewIRI(lego, "bp")); - axioms.add(f.getOWLDeclarationAxiom(individualX)); - - // facts - OWLAnnotationProperty dcsource = getDcSourceProperty(lego, f); - for(String source : sources) { - axioms.add(f.getOWLAnnotationAssertionAxiom(dcsource, individualX.getIRI(), f.getOWLLiteral(source))); - } - - // types - axioms.add(f.getOWLClassAssertionAxiom(ce, individualX)); - axioms.add(labelAxiom(f, individualX, classLabel+" "+individualX.getIRI().getFragment())); - - - // NamedIndividual( - // Types: - // 'molecular_function' - // enabled_by SOME - // Facts: - // part_of , - // source - OWLNamedIndividual individual = f.getOWLNamedIndividual(generateNewIRI(lego, "bp")); - axioms.add(f.getOWLDeclarationAxiom(individual)); - - axioms.add(labelAxiom(f, individual, annLabel)); - - // facts - for(String source : sources) { - axioms.add(f.getOWLAnnotationAssertionAxiom(dcsource, individual.getIRI(), f.getOWLLiteral(source))); - } - axioms.add(f.getOWLObjectPropertyAssertionAxiom(partOf, individual, individualX)); - - // types - axioms.add(f.getOWLClassAssertionAxiom(mf, individual)); - axioms.add(f.getOWLClassAssertionAxiom(f.getOWLObjectSomeValuesFrom(enabledBy, enabler), individual)); - } - } - else { - reportError("Error, unknown aspect: "+aspect, annotation); - continue; - } - - m.addAxioms(lego, axioms); - } - - return lego; - } - catch (OWLException e) { - throw new RuntimeException("Could not create lego model.", e); - } - } - - private OWLAxiom labelAxiom(OWLDataFactory f, OWLNamedIndividual individual, String annLabel) { - return - f.getOWLAnnotationAssertionAxiom( - f.getOWLAnnotationProperty(OWLRDFVocabulary.RDFS_LABEL.getIRI()), - individual.getIRI(), - f.getOWLLiteral(annLabel)); - } - - /** - * @param id - * @return cls or null - */ - private OWLClass getOwlClass(String id) { - OWLClass cls = graph.getOWLClassByIdentifier(id); - if (cls == null) { - // check alt ids - OWLObject owlObject = allOWLObjectsByAltId.get(id); - if (owlObject != null && owlObject instanceof OWLClass) { - cls = (OWLClass) owlObject; - } - } - return cls; - } - - private void addBioEntity(OWLClass pr, OWLOntology lego, Bioentity bioentity) { - Set declarationAxioms = lego.getDeclarationAxioms(pr); - if (declarationAxioms == null || declarationAxioms.isEmpty()) { - // add class declaration and add label - OWLOntologyManager m = lego.getOWLOntologyManager(); - OWLDataFactory f = m.getOWLDataFactory(); - - Set axioms = new HashSet(); - axioms.add(f.getOWLDeclarationAxiom(pr)); - - String label = bioentity.getSymbol()+" - "+bioentity.getFullName(); - - axioms.add(f.getOWLAnnotationAssertionAxiom(f.getRDFSLabel(), pr.getIRI(), f.getOWLLiteral(label))); - - m.addAxioms(lego, axioms); - } - } - - private static final IRI DC_SOURCE = IRI.create("http://purl.org/dc/terms/source"); - - private OWLAnnotationProperty getDcSourceProperty(OWLOntology lego, OWLDataFactory f) { - OWLAnnotationProperty p = f.getOWLAnnotationProperty(DC_SOURCE); - Set declarationAxioms = lego.getDeclarationAxioms(p); - if (declarationAxioms == null || declarationAxioms.isEmpty()) { - OWLOntologyManager m = lego.getOWLOntologyManager(); - m.addAxiom(lego, f.getOWLDeclarationAxiom(p)); - } - return p; - } - - private IRI generateNewIRI(OWLOntology ont, String type) { - return IRI.create("http://geneontology.org/lego/"+type+"/"+UUID.randomUUID().toString()); - } - - /** - * Translate the given {@link GafDocument} into an OWL representation of the LEGO model. - * Additionally minimize the lego model and imports into one ontology module. - * - * @param gaf - * @return minimized lego ontology - */ - public OWLOntology minimizedTranslate(GafDocument gaf) { - OWLOntology all = translate(gaf); - final OWLOntologyManager m = all.getOWLOntologyManager(); - - SyntacticLocalityModuleExtractor sme = new SyntacticLocalityModuleExtractor(m, all, ModuleType.BOT); - Set sig = new HashSet(all.getIndividualsInSignature()); - Set moduleAxioms = sme.extract(sig); - - try { - OWLOntology module = m.createOntology(IRI.generateDocumentIRI()); - m.addAxioms(module, moduleAxioms); - return module; - } catch (OWLException e) { - throw new RuntimeException("Could not create minimized lego model.", e); - } - } -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/AbstractLegoTranslator.java b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/AbstractLegoTranslator.java deleted file mode 100644 index 38efe764..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/AbstractLegoTranslator.java +++ /dev/null @@ -1,534 +0,0 @@ -package org.geneontology.minerva.legacy; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.evidence.FindGoCodes; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.geneontology.minerva.lookup.ExternalLookupService.LookupEntry; -import org.geneontology.minerva.taxon.FindTaxonTool; -import org.obolibrary.obo2owl.Obo2Owl; -import org.obolibrary.obo2owl.Owl2Obo; -import org.obolibrary.oboformat.parser.OBOFormatConstants.OboFormatTag; -import org.semanticweb.elk.owlapi.ElkReasonerFactory; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotation; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLAnnotationValueVisitorEx; -import org.semanticweb.owlapi.model.OWLAnonymousIndividual; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLLiteral; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; -import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.parameters.Imports; -import org.semanticweb.owlapi.reasoner.OWLReasoner; - -import owltools.gaf.Bioentity; -import owltools.gaf.ExtensionExpression; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.graph.OWLGraphWrapper; -import owltools.util.OwlHelper; -import owltools.vocab.OBOUpperVocabulary; - -abstract class AbstractLegoTranslator extends LegoModelWalker { - - protected final OWLClass mf; - protected final Set mfSet; - - protected final OWLClass cc; - protected final Set ccSet; - - protected final OWLClass bp; - protected final Set bpSet; - - protected final FindGoCodes goCodes; - protected final CurieHandler curieHandler; - - protected String assignedByDefault; - - protected AbstractLegoTranslator(OWLOntology model, CurieHandler curieHandler, SimpleEcoMapper mapper) { - super(model.getOWLOntologyManager().getOWLDataFactory()); - this.curieHandler = curieHandler; - goCodes = new FindGoCodes(mapper, curieHandler); - - mf = OBOUpperVocabulary.GO_molecular_function.getOWLClass(f); - cc = f.getOWLClass(IRI.create("http://purl.obolibrary.org/obo/GO_0005575")); - bp = OBOUpperVocabulary.GO_biological_process.getOWLClass(f); - - bpSet = new HashSet<>(); - mfSet = new HashSet<>(); - ccSet = new HashSet<>(); - - ElkReasonerFactory rf = new ElkReasonerFactory(); - OWLReasoner reasoner = rf.createReasoner(model); - fillAspects(model, reasoner, curieHandler, bpSet, mfSet, ccSet, bp, mf, cc); - reasoner.dispose(); - - assignedByDefault = "GO_Noctua"; - } - - static void fillAspects(OWLOntology model, OWLReasoner reasoner, CurieHandler curieHandler, Set bpSet, Set mfSet, Set ccSet, - OWLClass bp, OWLClass mf, OWLClass cc) { - final IRI namespaceIRI = Obo2Owl.trTagToIRI(OboFormatTag.TAG_NAMESPACE.getTag()); - final OWLDataFactory df = model.getOWLOntologyManager().getOWLDataFactory(); - final OWLAnnotationProperty namespaceProperty = df.getOWLAnnotationProperty(namespaceIRI); - final Set ontologies = model.getImportsClosure(); - for(OWLClass cls : model.getClassesInSignature(Imports.INCLUDED)) { - if (cls.isBuiltIn()) { - continue; - } - String id = curieHandler.getCuri(cls); - if (id.startsWith("GO:") == false) { - continue; - } - - // if a reasoner object is passed, use inference to populate - // the 3 subset - if (reasoner != null) { - if (reasoner.getSuperClasses(cls, false).containsEntity(mf) || - reasoner.getEquivalentClasses(cls).contains(mf)) { - mfSet.add(cls); - } - if (reasoner.getSuperClasses(cls, false).containsEntity(bp) || - reasoner.getEquivalentClasses(cls).contains(bp)) { - bpSet.add(cls); - } - if (reasoner.getSuperClasses(cls, false).containsEntity(cc) || - reasoner.getEquivalentClasses(cls).contains(cc)) { - ccSet.add(cls); - } - } - - - for (OWLAnnotation annotation : OwlHelper.getAnnotations(cls, ontologies)) { - if (annotation.getProperty().equals(namespaceProperty)) { - String value = annotation.getValue().accept(new OWLAnnotationValueVisitorEx() { - - @Override - public String visit(IRI iri) { - return null; - } - - @Override - public String visit(OWLAnonymousIndividual individual) { - return null; - } - - @Override - public String visit(OWLLiteral literal) { - return literal.getLiteral(); - } - }); - if (value != null) { - if ("molecular_function".equals(value)) { - mfSet.add(cls); - } - else if ("biological_process".equals(value)) { - bpSet.add(cls); - } - else if ("cellular_component".equals(value)) { - ccSet.add(cls); - } - } - } - } - } - } - - protected static Set getAllSubClasses(OWLClass cls, OWLReasoner r, boolean reflexive, String idSpace, CurieHandler curieHandler) { - Set allSubClasses = r.getSubClasses(cls, false).getFlattened(); - Iterator it = allSubClasses.iterator(); - while (it.hasNext()) { - OWLClass current = it.next(); - if (current.isBuiltIn()) { - it.remove(); - continue; - } - String id = curieHandler.getCuri(current); - if (id.startsWith(idSpace) == false) { - it.remove(); - continue; - } - } - if (reflexive) { - allSubClasses.add(cls); - } - return allSubClasses; - } - - protected class Summary { - - Set> activities = null; - Set> locations = null; - Set> processes = null; - OWLClass entity = null; - String entityType = null; - String entityTaxon = null; - - boolean addMf(OWLClass cls, Metadata metadata, Set evidences, Set expressions) { - if (isMf(cls)) { - activities = addAnnotation(cls, metadata, evidences, expressions, activities); - return true; - } - return false; - } - - boolean addBp(OWLClass cls, Metadata metadata, Set evidences, Set expressions) { - if (isBp(cls)) { - processes = addAnnotation(cls, metadata, evidences, expressions, processes); - return true; - } - return false; - } - - boolean addCc(OWLClass cls, Metadata metadata, Set evidences, Set expressions) { - if (isCc(cls)) { - locations = addAnnotation(cls, metadata, evidences, expressions, locations); - return true; - } - return false; - } - - private Set> addAnnotation(T cls, Metadata metadata, Set evidences, Set expressions, Set> set) { - if (set == null) { - set = new HashSet>(); - } - Entry entry = new Entry(); - entry.value = cls; - entry.metadata = metadata; - entry.evidences = new ArrayList<>(evidences); - if (expressions != null) { - entry.expressions = expressions; - } - set.add(entry); - return set; - } - - void addProcesses(Set> processes, Metadata metadata) { - if (processes != null) { - if (this.processes == null) { - this.processes = new HashSet>(processes); - } - else { - this.processes.addAll(processes); - } - } - } - - void addLocations(Set> locations) { - if (locations != null) { - if (this.locations == null) { - this.locations = new HashSet>(locations); - } - else { - this.locations.addAll(locations); - } - } - } - } - - protected boolean isMf(OWLClass cls) { - return mfSet.contains(cls); - } - - protected boolean isBp(OWLClass cls) { - return bpSet.contains(cls); - } - - protected boolean isCc(OWLClass cls) { - return ccSet.contains(cls); - } - - @Override - protected String getShortHand(IRI iri) { - return curieHandler.getCuri(iri); - } - - @Override - protected boolean isAnnotationIndividual(OWLNamedIndividual i, Set types) { - boolean isGoAnnotation = false; - Iterator typeIterator = types.iterator(); - while (typeIterator.hasNext() && isGoAnnotation == false) { - OWLClass cls = typeIterator.next(); - isGoAnnotation = mfSet.contains(cls) || bpSet.contains(cls) || ccSet.contains(cls); - } - return isGoAnnotation; - } - - public abstract void translate(OWLOntology modelAbox, ExternalLookupService lookup, GafDocument annotations, List additionalRefs) throws UnknownIdentifierException; - - /** - * Get the type of an enabled by entity, e.g. gene, protein - * - * @param modelGraph - * @param entity - * @param individual - * @param lookup - * @return type - */ - protected String getEntityType(OWLClass entity, OWLNamedIndividual individual, OWLGraphWrapper modelGraph, ExternalLookupService lookup) { - if (lookup != null) { - List result = lookup.lookup(entity.getIRI()); - if ((result != null) && (result.isEmpty() == false)) { - LookupEntry entry = result.get(0); - if ("protein".equalsIgnoreCase(entry.type)) { - return "protein"; - } - else if ("gene".equalsIgnoreCase(entry.type)) { - return "gene"; - } - } - } - return "gene"; - } - - protected String getEntityTaxon(OWLClass entity, OWLOntology model) throws UnknownIdentifierException { - if (entity == null) { - return null; - } - FindTaxonTool tool = new FindTaxonTool(curieHandler, model.getOWLOntologyManager().getOWLDataFactory()); - return tool.getEntityTaxon(curieHandler.getCuri(entity), model); - } - - public GafDocument translate(String id, OWLOntology modelAbox, ExternalLookupService lookup, List additionalReferences) throws UnknownIdentifierException { - final GafDocument annotations = new GafDocument(id, null); - translate(modelAbox, lookup, annotations, additionalReferences); - return annotations; - } - - protected List createAnnotations(Entry entry, Bioentity entity, String aspect, - List additionalReferences, - OWLGraphWrapper g, Collection c16) { - List result = new ArrayList<>(); - if (entry.evidences != null) { - for(Evidence evidence : entry.evidences) { - GeneAnnotation ann = createAnnotation(entry.value, entry.metadata, evidence, entity, aspect, additionalReferences, g, c16); - result.add(ann); - } - } - return result; - } - - protected GeneAnnotation createAnnotation(OWLClass cls, Metadata meta, Evidence evidence, Bioentity entity, String aspect, - List additionalReferences, - OWLGraphWrapper g, Collection c16) { - GeneAnnotation annotation = new GeneAnnotation(); - annotation.setBioentityObject(entity); - annotation.setBioentity(entity.getId()); - annotation.setAspect(aspect); - - String assignedBy = assignedByDefault; - if (meta.groups != null) { - if (meta.groups.size() == 1) { - assignedBy = meta.groups.iterator().next(); - } - for(String group : meta.groups) { - annotation.addProperty("group", group); - } - } - annotation.setAssignedBy(assignedBy); - - annotation.setCls(curieHandler.getCuri(cls)); - - if (meta.modelId != null) { - annotation.addProperty("lego-model-id", meta.modelId); - } - if (meta.contributors != null) { - for(String contributor : meta.contributors) { - annotation.addProperty("contributor", contributor); - } - } - if (meta.individualIds != null) { - for(IRI individual : meta.individualIds) { - annotation.addProperty("individual", individual.toString()); - } - } - - if (evidence != null) { - String ecoId = curieHandler.getCuri(evidence.evidenceCls); - if (ecoId != null) { - String goCode = null; - Pair pair = goCodes.findShortEvidence(evidence.evidenceCls, ecoId, g.getSourceOntology()); - if (pair != null) { - goCode = pair.getLeft(); - String goRef = pair.getRight(); - if (goRef != null) { - if (additionalReferences == null) { - additionalReferences = Collections.singletonList(goRef); - } - else { - additionalReferences = new ArrayList(additionalReferences); - additionalReferences.add(goRef); - } - } - } - annotation.setEvidence(goCode, ecoId); - } - } - if (meta.date != null) { - // assumes that the date is YYYY-MM-DD - // gene annotations require YYYYMMDD - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < meta.date.length(); i++) { - char c = meta.date.charAt(i); - if (Character.isDigit(c)) { - sb.append(c); - } - } - annotation.setLastUpdateDate(sb.toString()); - } - - if (evidence.with != null) { - List withInfos = Collections.singletonList(evidence.with); - annotation.setWithInfos(withInfos); - } - - String relation = "enables"; - if ("C".equals(aspect)) { - relation = "part_of"; - } - else if ("P".equals(aspect)) { - relation = "involved_in"; - } - annotation.setRelation(relation); - if (evidence.source != null) { - annotation.addReferenceId(evidence.source); - } - if (additionalReferences != null) { - for (String ref : additionalReferences) { - annotation.addReferenceId(ref); - } - } - - if (c16 != null && !c16.isEmpty()) { - List expressions = new ArrayList(); - for (OWLObjectSomeValuesFrom svf : c16) { - OWLObjectPropertyExpression property = svf.getProperty(); - OWLClassExpression filler = svf.getFiller(); - if (property instanceof OWLObjectProperty && filler instanceof OWLClass) { - String rel = getRelId(property, g); - String objectId = curieHandler.getCuri((OWLClass) filler); - ExtensionExpression expr = new ExtensionExpression(rel, objectId); - expressions.add(expr); - } - } - annotation.setExtensionExpressions(Collections.singletonList(expressions)); - } - - return annotation; - } - - protected String getRelId(OWLObjectPropertyExpression p, OWLGraphWrapper graph) { - String relId = null; - for(OWLOntology ont : graph.getAllOntologies()) { - relId = Owl2Obo.getIdentifierFromObject(p, ont, null); - if (relId != null && relId.indexOf(':') < 0) { - return relId; - } - } - return relId; - } - - protected Bioentity createBioentity(OWLClass entityCls, String entityType, String taxon, OWLGraphWrapper g, ExternalLookupService lookup) { - Bioentity bioentity = new Bioentity(); - BioentityStrings strings = getBioentityStrings(entityCls, entityType, taxon, g, lookup); - String id = strings.id; - bioentity.setId(id); - if (strings.db != null) { - bioentity.setDb(strings.db); - } - bioentity.setSymbol(strings.symbol); - bioentity.setTypeCls(strings.type); - if (taxon != null) { - bioentity.setNcbiTaxonId(taxon); - } - return bioentity; - } - - protected static class BioentityStrings { - String id; - String db; - String symbol; - String type; - } - - protected BioentityStrings getBioentityStrings(OWLClass entityCls, String entityType, String taxon, OWLGraphWrapper g, ExternalLookupService lookup) { - BioentityStrings strings = new BioentityStrings(); - strings.id = curieHandler.getCuri(entityCls); - strings.db = null; - String[] split = StringUtils.split(strings.id, ":", 2); - if (split.length == 2) { - strings.db = split[0]; - } - strings.symbol = getLabelForBioentity(entityCls, entityType, taxon, g, lookup); - strings.type = entityType; - return strings; - } - - private String getLabelForBioentity(OWLClass entityCls, String entityType, String taxon, OWLGraphWrapper g, ExternalLookupService lookup) { - String lbl = g.getLabel(entityCls); - if (lbl == null && lookup != null) { - List result = lookup.lookup(entityCls.getIRI()); - if (!result.isEmpty()) { - LookupEntry entry = result.get(0); - lbl = entry.label; - } - } - return lbl; - } - - protected void addAnnotations(OWLGraphWrapper modelGraph, ExternalLookupService lookup, - Summary summary, List additionalRefs, - GafDocument annotations) - { - Bioentity entity = createBioentity(summary.entity, summary.entityType, summary.entityTaxon , modelGraph, lookup); - entity = annotations.addBioentity(entity); - - if (summary.activities != null) { - for (Entry e: summary.activities) { - if (isMf(e.value) && !mf.equals(e.value)) { - List current = createAnnotations(e, entity, "F", additionalRefs, modelGraph, e.expressions); - for (GeneAnnotation annotation : current) { - annotations.addGeneAnnotation(annotation); - } - } - } - } - if (summary.processes != null) { - for (Entry e : summary.processes) { - if (isBp(e.value) && !bp.equals(e.value)) { - List current = createAnnotations(e, entity, "P", additionalRefs, modelGraph, e.expressions); - for (GeneAnnotation annotation : current) { - annotations.addGeneAnnotation(annotation); - } - } - } - } - if (summary.locations != null) { - for (Entry e : summary.locations) { - if (isCc(e.value) && !cc.equals(e.value)) { - List current = createAnnotations(e, entity, "C", additionalRefs, modelGraph, e.expressions); - for (GeneAnnotation annotation : current) { - annotations.addGeneAnnotation(annotation); - } - } - } - } - } -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GafExportTool.java b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GafExportTool.java deleted file mode 100644 index 45e94528..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GafExportTool.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.geneontology.minerva.legacy; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.io.PrintWriter; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.io.IOUtils; -import org.geneontology.minerva.ModelContainer; -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyCreationException; - -import owltools.gaf.GafDocument; -import owltools.gaf.eco.EcoMapperFactory; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.gaf.io.GafWriter; -import owltools.gaf.io.GpadWriter; - -public class GafExportTool { - - private static volatile GafExportTool INSTANCE = null; - - private final SimpleEcoMapper ecoMapper; - - private GafExportTool(SimpleEcoMapper mapper) { - this.ecoMapper = mapper; - } - - public static synchronized GafExportTool getInstance() throws IOException { - if (INSTANCE == null) { - INSTANCE = new GafExportTool(EcoMapperFactory.createSimple()); - } - return INSTANCE; - } - - /** - * Export the model (ABox) in a legacy format, such as GAF or GPAD. - * - * @param model - * @param curieHandler - * @param lookup - * @param formats set of format names - * @return modelContent - * @throws OWLOntologyCreationException - * @throws UnknownIdentifierException - */ - public Map exportModelLegacy(ModelContainer model, CurieHandler curieHandler, ExternalLookupService lookup, Set formats) throws OWLOntologyCreationException, UnknownIdentifierException { - final OWLOntology aBox = model.getAboxOntology(); - - LegoToGeneAnnotationTranslator translator = new LegoToGeneAnnotationTranslator(aBox, curieHandler, ecoMapper); - GafDocument gafdoc = translator.translate(model.getModelId().toString(), aBox, lookup, null); - Map exportResults = new HashMap(); - for(String format : formats) { - ByteArrayOutputStream outputStream = null; - try { - outputStream = new ByteArrayOutputStream(); - if ("gaf".equalsIgnoreCase(format)) { - // GAF - GafWriter writer = new GafWriter(); - try { - writer.setStream(new PrintStream(outputStream)); - writer.write(gafdoc); - } - finally { - IOUtils.closeQuietly(writer); - } - - } - else if ("gpad".equalsIgnoreCase(format)) { - // GPAD version 1.2 - GpadWriter writer = new GpadWriter(new PrintWriter(outputStream) , 1.2); - writer.write(gafdoc); - } - else { - continue; - } - String exported = outputStream.toString(); - exportResults.put(format, exported); - } - finally { - IOUtils.closeQuietly(outputStream); - } - } - return exportResults; - } -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GroupingTranslator.java b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GroupingTranslator.java deleted file mode 100644 index d1c7c132..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/GroupingTranslator.java +++ /dev/null @@ -1,251 +0,0 @@ -package org.geneontology.minerva.legacy; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.geneontology.minerva.util.AnnotationShorthand; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotation; -import org.semanticweb.owlapi.model.OWLAnnotationValueVisitorEx; -import org.semanticweb.owlapi.model.OWLAnonymousIndividual; -import org.semanticweb.owlapi.model.OWLLiteral; -import org.semanticweb.owlapi.model.OWLOntology; - -import com.google.common.base.Optional; - -import owltools.gaf.Bioentity; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; - -/** - * Tool for grouping translated lego models, by model state or taxon group. - */ -public class GroupingTranslator { - - final Set modelStates = new HashSet<>(); - - private String defaultState = "unknown"; - private String productionState = "production"; - - final Map> typedAnnotations = new HashMap<>(); - final Map> typedEntities = new HashMap<>(); - - final TaxonGroupContent modelGroups = new TaxonGroupContent(); - final TaxonGroupContent productionModelGroups = new TaxonGroupContent(); - - private final Map taxonGroups; - private final String defaultTaxonGroup; - - private final LegoToGeneAnnotationTranslator translator; - private final ExternalLookupService lookup; - private final CurieHandler curieHandler; - - private final boolean addLegoModelId; - - private static class TaxonGroupContent { - - final Map> annotations = new HashMap<>(); - final Map> entities = new HashMap<>(); - - void addAnnotations(GafDocument input, Bioentity entity, String taxonGroup) { - List groupDocument = annotations.get(taxonGroup); - if (groupDocument == null) { - groupDocument = new ArrayList<>(); - annotations.put(taxonGroup, groupDocument); - } - List groupEntities = entities.get(taxonGroup); - if (groupEntities == null) { - groupEntities = new ArrayList<>(); - entities.put(taxonGroup, groupEntities); - } - if (!groupEntities.contains(entity)) { - groupEntities.add(entity); - } - for (GeneAnnotation ann : input.getGeneAnnotations()) { - if (ann.getBioentity().equals(entity.getId())) { - groupDocument.add(ann); - } - } - } - - GafDocument getAnnotationsByGroup(String taxonGroup) { - GafDocument result = new GafDocument(null, null); - List annotations = this.annotations.get(taxonGroup); - List entities = this.entities.get(taxonGroup); - if (annotations != null && entities != null) { - for(Bioentity entity : entities) { - result.addBioentity(entity); - } - for(GeneAnnotation annotation : annotations) { - result.addGeneAnnotation(annotation); - } - } - return result; - } - - Set getGroups() { - return Collections.unmodifiableSet(annotations.keySet()); - } - } - - public GroupingTranslator(LegoToGeneAnnotationTranslator translator, ExternalLookupService lookup, - Map taxonGroups, String defaultTaxonGroup, boolean addLegoModelId) - { - this.translator = translator; - this.lookup = lookup; - this.curieHandler = translator.curieHandler; - - this.taxonGroups = taxonGroups; - this.defaultTaxonGroup = defaultTaxonGroup; - - this.addLegoModelId = addLegoModelId; - } - - public void translate(OWLOntology model) throws UnknownIdentifierException { - // get curie - String modelCurie = getModelCurie(model, curieHandler, null); - - List addtitionalRefs = handleRefs(addLegoModelId, modelCurie); - - // get state - final String modelState = getModelState(model, defaultState); - modelStates.add(modelState); - - // create containers - GafDocument annotations = new GafDocument(null, null); - - // translate - translator.translate(model, lookup, annotations, addtitionalRefs); - - // append to appropriate model state containers - List modelStateAnnotations = typedAnnotations.get(modelState); - if (modelStateAnnotations == null) { - modelStateAnnotations = new ArrayList<>(); - typedAnnotations.put(modelState, modelStateAnnotations); - } - for(GeneAnnotation annotation : annotations.getGeneAnnotations()) { - modelStateAnnotations.add(annotation); - } - List modelStateEntities = typedEntities.get(modelState); - if (modelStateEntities == null) { - modelStateEntities = new ArrayList<>(); - typedEntities.put(modelState, modelStateEntities); - } - for(Bioentity entity : annotations.getBioentities()) { - if (!modelStateEntities.contains(entity)) { - modelStateEntities.add(entity); - } - } - - // sort into model organism groups - if (taxonGroups != null) { - for (Bioentity entity : annotations.getBioentities()) { - String ncbiTaxonId = entity.getNcbiTaxonId(); - if (ncbiTaxonId != null) { - ncbiTaxonId = ncbiTaxonId.replace("taxon", "NCBITaxon"); - } - String group = taxonGroups.get(ncbiTaxonId); - if (group == null) { - group = defaultTaxonGroup; - } - modelGroups.addAnnotations(annotations, entity, group); - - if (productionState.equals(modelState)) { - productionModelGroups.addAnnotations(annotations, entity, group); - } - } - } - } - - public Set getModelStates() { - return Collections.unmodifiableSet(modelStates); - } - - public GafDocument getAnnotationsByState(String modelState) { - GafDocument result = new GafDocument(null, null); - List annotations = typedAnnotations.get(modelState); - List entities = typedEntities.get(modelState); - if (annotations != null && entities != null) { - for(Bioentity entity : entities) { - result.addBioentity(entity); - } - for(GeneAnnotation annotation : annotations) { - result.addGeneAnnotation(annotation); - } - } - return result; - } - - public GafDocument getAnnotationsByGroup(String taxonGroup) { - return modelGroups.getAnnotationsByGroup(taxonGroup); - } - - public Set getTaxonGroups() { - return modelGroups.getGroups(); - } - - public GafDocument getProductionAnnotationsByGroup(String taxonGroup) { - return productionModelGroups.getAnnotationsByGroup(taxonGroup); - } - - public Set getProductionTaxonGroups() { - return productionModelGroups.getGroups(); - } - - List handleRefs(boolean addLegoModelId, String modelCurie) { - List addtitionalRefs = null; - if (addLegoModelId && modelCurie != null) { - addtitionalRefs = Collections.singletonList(modelCurie); - } - return addtitionalRefs; - } - - public static String getModelState(OWLOntology model, String defaultValue) { - String modelState = defaultValue; - Set modelAnnotations = model.getAnnotations(); - for (OWLAnnotation modelAnnotation : modelAnnotations) { - IRI propIRI = modelAnnotation.getProperty().getIRI(); - if (AnnotationShorthand.modelstate.getAnnotationProperty().equals(propIRI)) { - String value = modelAnnotation.getValue().accept(new OWLAnnotationValueVisitorEx() { - - @Override - public String visit(IRI iri) { - return null; - } - - @Override - public String visit(OWLAnonymousIndividual individual) { - return null; - } - - @Override - public String visit(OWLLiteral literal) { - return literal.getLiteral(); - } - }); - if (value != null) { - modelState = value; - } - } - } - return modelState; - } - - public static String getModelCurie(OWLOntology model, CurieHandler curieHandler, String defaultValue) { - // get model curie from ontology IRI - String modelCurie = defaultValue; - Optional ontologyIRI = model.getOntologyID().getOntologyIRI(); - if (ontologyIRI.isPresent()) { - modelCurie = curieHandler.getCuri(ontologyIRI.get()); - } - return modelCurie; - } -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoModelWalker.java b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoModelWalker.java index 49103e32..fcefd33e 100644 --- a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoModelWalker.java +++ b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoModelWalker.java @@ -7,6 +7,7 @@ import java.util.Map; import java.util.Set; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; import org.geneontology.minerva.lookup.ExternalLookupService; import org.geneontology.minerva.util.AnnotationShorthand; @@ -33,7 +34,6 @@ import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.util.OWLClassExpressionVisitorAdapter; -import owltools.graph.OWLGraphWrapper; import owltools.vocab.OBOUpperVocabulary; abstract class LegoModelWalker { @@ -111,7 +111,7 @@ protected static class Metadata { } public void walkModel(OWLOntology model, ExternalLookupService lookup, Collection allPayloads) throws UnknownIdentifierException { - final OWLGraphWrapper modelGraph = new OWLGraphWrapper(model); + final MinervaOWLGraphWrapper modelGraph = new MinervaOWLGraphWrapper(model); String modelId = null; for(OWLAnnotation modelAnnotation : model.getAnnotations()) { @@ -378,7 +378,7 @@ private Set getExpressions(OWLNamedIndividual i, OWLOnt return result; } - protected abstract PAYLOAD initPayload(OWLNamedIndividual object, OWLClass objectType, OWLOntology model, OWLGraphWrapper modelGraph, ExternalLookupService lookup) throws UnknownIdentifierException; + protected abstract PAYLOAD initPayload(OWLNamedIndividual object, OWLClass objectType, OWLOntology model, MinervaOWLGraphWrapper modelGraph, ExternalLookupService lookup) throws UnknownIdentifierException; protected abstract boolean handleCC(PAYLOAD payload, OWLClass cls, Metadata metadata, Set evidences, Set expressions); @@ -392,7 +392,7 @@ private OWLObjectSomeValuesFrom createSvf(OWLObjectPropertyExpression p, OWLClas return f.getOWLObjectSomeValuesFrom(p, c); } - private Metadata extractMetadata(OWLNamedIndividual individual, OWLGraphWrapper modelGraph, String modelId) { + private Metadata extractMetadata(OWLNamedIndividual individual, MinervaOWLGraphWrapper modelGraph, String modelId) { Metadata metadata = new Metadata(); metadata.modelId = modelId; metadata.individualIds = new HashSet(); @@ -432,7 +432,7 @@ else if (this.group.equals(p)) { } } - private Metadata extractMetadata(Collection annotations, OWLGraphWrapper modelGraph, String modelId) { + private Metadata extractMetadata(Collection annotations, MinervaOWLGraphWrapper modelGraph, String modelId) { Metadata metadata = new Metadata(); metadata.modelId = modelId; if (annotations != null && !annotations.isEmpty()) { diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslator.java b/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslator.java deleted file mode 100644 index 98b72c74..00000000 --- a/minerva-converter/src/main/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslator.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.geneontology.minerva.legacy; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; -import org.semanticweb.owlapi.model.OWLOntology; - -import owltools.gaf.GafDocument; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.graph.OWLGraphWrapper; - -public class LegoToGeneAnnotationTranslator extends AbstractLegoTranslator { - - public LegoToGeneAnnotationTranslator(OWLOntology model, CurieHandler curieHandler, SimpleEcoMapper mapper) { - super(model, curieHandler, mapper); - } - - @Override - protected boolean isEco(OWLClass cls) { - String identifier = curieHandler.getCuri(cls); - return identifier != null && identifier.startsWith("ECO:"); - } - - @Override - public void translate(OWLOntology modelAbox, ExternalLookupService lookup, GafDocument annotations, List additionalRefs) throws UnknownIdentifierException { - Set summaries = new HashSet(); - walkModel(modelAbox, lookup, summaries); - - final OWLGraphWrapper modelGraph = new OWLGraphWrapper(modelAbox); - for(Summary summary : summaries) { - if (summary.entity != null) { - addAnnotations(modelGraph, lookup, summary, additionalRefs, annotations); - } - } - } - - @Override - protected Summary initPayload(OWLNamedIndividual object, - OWLClass objectType, OWLOntology model, OWLGraphWrapper modelGraph, ExternalLookupService lookup) throws UnknownIdentifierException { - Summary summary = new Summary(); - summary.entity = objectType; - summary.entityTaxon = getEntityTaxon(objectType, model); - summary.entityType = getEntityType(objectType, object, modelGraph, lookup); - return summary; - } - - @Override - protected boolean handleCC(Summary payload, OWLClass cls, - Metadata metadata, Set evidences, - Set expressions) { - boolean added = false; - if (isCc(cls)) { - added = payload.addCc(cls, metadata, evidences, expressions); - } - return added; - } - - @Override - protected boolean handleMF(Summary payload, OWLClass cls, - Metadata metadata, Set evidences, - Set expressions) { - if (isMf(cls)) { - payload.addMf(cls, metadata, evidences, expressions); - } - return true; - } - - @Override - protected boolean handleBP(Summary payload, OWLClass cls, - Metadata metadata, Set evidences, - Set expressions) { - boolean added = false; - if (isBp(cls)) { - added = payload.addBp(cls, metadata, evidences, expressions); - } - return added; - } - -} diff --git a/minerva-converter/src/main/java/org/geneontology/minerva/taxon/FindTaxonTool.java b/minerva-converter/src/main/java/org/geneontology/minerva/taxon/FindTaxonTool.java index e8cb9500..f3e8c850 100644 --- a/minerva-converter/src/main/java/org/geneontology/minerva/taxon/FindTaxonTool.java +++ b/minerva-converter/src/main/java/org/geneontology/minerva/taxon/FindTaxonTool.java @@ -4,6 +4,7 @@ import java.util.Set; import org.apache.commons.io.IOUtils; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; import org.geneontology.minerva.curie.CurieHandler; import org.obolibrary.obo2owl.Obo2OWLConstants; @@ -19,8 +20,6 @@ import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; import org.semanticweb.owlapi.util.OWLClassExpressionVisitorExAdapter; -import owltools.graph.OWLGraphWrapper; - public class FindTaxonTool { public static final IRI IN_TAXON_IRI = IRI.create(Obo2OWLConstants.DEFAULT_IRI_PREFIX+"RO_0002162"); @@ -41,7 +40,7 @@ public String getEntityTaxon(String curie, OWLOntology model) throws UnknownIden OWLClass cls = df.getOWLClass(curieHandler.getIRI(curie)); String taxon = getEntityTaxon(cls, model); if (taxon == null) { - OWLGraphWrapper g = new OWLGraphWrapper(model); + MinervaOWLGraphWrapper g = new MinervaOWLGraphWrapper(model); cls = g.getOWLClassByIdentifier(curie); if (cls != null) { taxon = getEntityTaxon(cls, model); diff --git a/minerva-converter/src/test/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslatorTest.java b/minerva-converter/src/test/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslatorTest.java deleted file mode 100644 index ea6f689d..00000000 --- a/minerva-converter/src/test/java/org/geneontology/minerva/legacy/LegoToGeneAnnotationTranslatorTest.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.geneontology.minerva.legacy; - -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.curie.DefaultCurieHandler; -import org.geneontology.minerva.lookup.ExternalLookupService; -import org.geneontology.minerva.lookup.ExternalLookupService.LookupEntry; -import org.geneontology.minerva.lookup.TableLookupService; -import org.junit.BeforeClass; -import org.junit.Test; -import org.semanticweb.elk.owlapi.ElkReasonerFactory; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLOntology; -import org.semanticweb.owlapi.model.OWLOntologyManager; -import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; -import owltools.gaf.Bioentity; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.gaf.eco.EcoMapperFactory; -import owltools.gaf.eco.SimpleEcoMapper; - -import java.io.File; -import java.util.*; - -import static org.junit.Assert.*; - - -public class LegoToGeneAnnotationTranslatorTest { - - public static CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); - public static OWLReasonerFactory rf = new ElkReasonerFactory(); - public static SimpleEcoMapper mapper; - - @BeforeClass - public static void beforeClass() throws Exception { - mapper = EcoMapperFactory.createSimple(); - } - - @Test - public void testZfinExample() throws Exception { - OWLOntology model = loadModel("gomodel-1.owl"); - List entities = new ArrayList<>(); - entities.add(new LookupEntry(IRI.create("http://identifiers.org/zfin/ZDB-GENE-991124-7"), "tbx5a", "gene", "NCBITaxon:7955")); - // is actually a gene, but made a protein for this test case - entities.add(new LookupEntry(IRI.create("http://identifiers.org/zfin/ZDB-GENE-040426-2843"), "kctd10", "protein", "NCBITaxon:7955")); - GafDocument gafDocument = translate(model, "gomodel-1", entities); - List allAnnotations = gafDocument.getGeneAnnotations(); - assertFalse(allAnnotations.isEmpty()); - - // check that all annotations have evidence info - List noEvidence = new ArrayList<>(); - List noShortEvidence = new ArrayList<>(); - List invalidDates = new ArrayList<>(); - Set unmappedEco = new HashSet<>(); - - for(GeneAnnotation ann : allAnnotations) { - - String ecoEvidenceCls = ann.getEcoEvidenceCls(); - String shortEvidence = ann.getShortEvidence(); - if (ecoEvidenceCls == null) { - noEvidence.add(ann); - } - else if (shortEvidence == null) { - unmappedEco.add(ecoEvidenceCls); - noShortEvidence.add(ann); - } - String date = ann.getLastUpdateDate(); - if (date == null || date.matches("^\\d{8}$") == false) { - invalidDates.add(ann); - } - } - assertTrue(invalidDates.isEmpty()); - - // expect two entities - Collection bioentities = gafDocument.getBioentities(); - assertEquals(2, bioentities.size()); - - // check that all entities have a taxon id - List noTaxon = new ArrayList<>(); - List noSymbol = new ArrayList<>(); - - for (Bioentity entity : bioentities) { - System.out.println("ENTITY: " + entity); - if (entity.getNcbiTaxonId() == null) { - noTaxon.add(entity); - } - if (entity.getSymbol() == null) { - noSymbol.add(entity); - } - if ("ZFIN:ZDB-GENE-040426-2843".equals(entity.getId())) { - assertEquals("protein", entity.getTypeCls()); - } - else { - assertEquals("gene", entity.getTypeCls()); - } - } - assertTrue(noTaxon.isEmpty()); - - assertTrue(noEvidence.isEmpty()); - assertEquals(2, unmappedEco.size()); - assertTrue(unmappedEco.contains("ECO:0000302")); - assertTrue(unmappedEco.contains("ECO:0000011")); - assertEquals(2, noShortEvidence.size()); - - assertTrue(noSymbol.isEmpty()); - } - - @Test - public void testWithField() throws Exception { - OWLOntology model = loadModel("gomodel-2.owl"); - List entities = new ArrayList<>(); - entities.add(new LookupEntry(IRI.create("http://flybase.org/reports/FBgn0263395"), "hppy", "gene", "NCBITaxon:7227")); - entities.add(new LookupEntry(IRI.create("http://v2.pseudomonas.com/getAnnotation.do?locusID=PA1528"), "zipA", "gene", "NCBITaxon:208964")); - entities.add(new LookupEntry(IRI.create("http://www.aspergillusgenome.org/cgi-bin/locus.pl?dbid=ASPL0000098579"), "zipA", "gene", "NCBITaxon:162425")); - GafDocument gafdoc = translate(model, "gomodel-2", entities); - - // expect two entities - Collection bioentities = gafdoc.getBioentities(); - assertEquals(2, bioentities.size()); - - List noSymbol = new ArrayList<>(); - - for (Bioentity entity : bioentities) { - if (entity.getSymbol() == null) { - noSymbol.add(entity); - } - } - assertTrue(noSymbol.isEmpty()); - - // expect three annotations, one providing with infos - List allAnnotations = gafdoc.getGeneAnnotations(); - List withAnnotations = new ArrayList(); - assertEquals(3, allAnnotations.size()); - for(GeneAnnotation ann : allAnnotations) { - Collection withInfos = ann.getWithInfos(); - if (withInfos != null && !withInfos.isEmpty()) { - withAnnotations.add(ann); - } - } - assertEquals(1, withAnnotations.size()); - } - - @Test - public void testExtendedEvidence1() throws Exception { - OWLOntology model = loadModel("a1a2a3a401"); - List entities = new ArrayList<>(); - GafDocument gafdoc = translate(model, "a1a2a3a401", entities); - List allAnnotations = gafdoc.getGeneAnnotations(); - assertEquals(1, allAnnotations.size()); - GeneAnnotation ann = allAnnotations.get(0); - List referenceIds = ann.getReferenceIds(); - assertTrue(referenceIds.contains("PMID:19797081")); - } - - @Test - public void testExtendedEvidence2() throws Exception { - OWLOntology model = loadModel("a1a2a3a402"); - List entities = new ArrayList<>(); - GafDocument gafdoc = translate(model, "a1a2a3a402", entities); - List allAnnotations = gafdoc.getGeneAnnotations(); - assertEquals(1, allAnnotations.size()); - GeneAnnotation ann = allAnnotations.get(0); - List referenceIds = ann.getReferenceIds(); - assertTrue(referenceIds.contains("PMID:19797081")); - } - - private OWLOntology loadModel(String name) throws Exception { - OWLOntologyManager manager = OWLManager.createOWLOntologyManager(); - manager.loadOntology(IRI.create(new File("src/test/resources/go-lego-module.omn"))); - return manager.loadOntology((IRI.create(new File("src/test/resources/"+name).getCanonicalFile()))); - } - - private GafDocument translate(OWLOntology model, String id, List entities) throws UnknownIdentifierException { - LegoToGeneAnnotationTranslator t = new LegoToGeneAnnotationTranslator(model, curieHandler, mapper); - ExternalLookupService lookup = null; - if (entities != null) { - lookup = new TableLookupService(entities); - } - return t.translate(id, model, lookup, null); - } - -} diff --git a/minerva-core/pom.xml b/minerva-core/pom.xml index 2341fa3f..620fed15 100644 --- a/minerva-core/pom.xml +++ b/minerva-core/pom.xml @@ -29,16 +29,6 @@ minerva-json ${project.parent.version} - - org.bbop - OWLTools-Annotation - - - org.bbop - OWLTools-Core - test-jar - test - com.blazegraph bigdata-core @@ -81,5 +71,10 @@ + + org.semanticweb.elk + elk-owlapi + 0.4.3 + diff --git a/minerva-core/src/main/java/org/geneontology/minerva/BlazegraphMolecularModelManager.java b/minerva-core/src/main/java/org/geneontology/minerva/BlazegraphMolecularModelManager.java index 080034e9..90107968 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/BlazegraphMolecularModelManager.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/BlazegraphMolecularModelManager.java @@ -72,8 +72,6 @@ import com.google.common.base.Optional; import info.aduna.iteration.Iterations; -import owltools.gaf.parser.GafObjectsBuilder; -import owltools.graph.OWLGraphWrapper; public class BlazegraphMolecularModelManager extends CoreMolecularModelManager { @@ -89,7 +87,6 @@ public class BlazegraphMolecularModelManager extends CoreMolecularMode private final String modelIdPrefix; - GafObjectsBuilder builder = new GafObjectsBuilder(); OWLDocumentFormat ontologyFormat = new TurtleDocumentFormat(); private final List preFileSaveHandlers = new ArrayList(); diff --git a/minerva-core/src/main/java/org/geneontology/minerva/CoreMolecularModelManager.java b/minerva-core/src/main/java/org/geneontology/minerva/CoreMolecularModelManager.java index fa91cd19..6c2d3ce2 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/CoreMolecularModelManager.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/CoreMolecularModelManager.java @@ -83,7 +83,6 @@ import com.google.common.base.Optional; -import owltools.graph.OWLGraphWrapper; import owltools.vocab.OBOUpperVocabulary; import scala.collection.JavaConverters; diff --git a/minerva-core/src/main/java/org/geneontology/minerva/MinervaOWLGraphWrapper.java b/minerva-core/src/main/java/org/geneontology/minerva/MinervaOWLGraphWrapper.java new file mode 100644 index 00000000..d2bf26ff --- /dev/null +++ b/minerva-core/src/main/java/org/geneontology/minerva/MinervaOWLGraphWrapper.java @@ -0,0 +1,749 @@ +package org.geneontology.minerva; + + +import java.io.Closeable; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang.SerializationUtils; +import org.apache.log4j.Logger; +import org.obolibrary.obo2owl.Obo2OWLConstants; +import org.obolibrary.obo2owl.Obo2OWLConstants.Obo2OWLVocabulary; +import org.obolibrary.oboformat.parser.OBOFormatConstants.OboFormatTag; +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.OWLAnnotationSubject; +import org.semanticweb.owlapi.model.OWLAnnotationValue; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLDeclarationAxiom; +import org.semanticweb.owlapi.model.OWLEntity; +import org.semanticweb.owlapi.model.OWLLiteral; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLNamedObject; +import org.semanticweb.owlapi.model.OWLObject; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.vocab.OWLRDFVocabulary; + +import com.google.common.collect.Sets; + +import gnu.trove.set.hash.THashSet; +import owltools.io.ParserWrapper; +import owltools.util.OwlHelper; + + +/** + * Consolidation of methods actually used in Minerva from the OWLTools OWLGraphWrapper class + */ +public class MinervaOWLGraphWrapper implements Closeable { + + private static final Logger LOG = Logger.getLogger(MinervaOWLGraphWrapper.class); + private Map altIdMap = null; + private String defaultIDSpace = ""; + final Map idSpaceMap; + public OWLOntology sourceOntology; // graph is seeded from this ontology. + public static Map annotationPropertyMap = initAnnotationPropertyMap(); + public Set supportOntologySet = new HashSet(); + + public MinervaOWLGraphWrapper(OWLOntology ontology) { + super(); + idSpaceMap = new HashMap(); + sourceOntology = ontology; + } + + public MinervaOWLGraphWrapper(String iri) throws OWLOntologyCreationException { + super(); + idSpaceMap = new HashMap(); + ParserWrapper pw = new ParserWrapper(); + OWLOntologyManager manager = pw.getManager(); + sourceOntology = manager.createOntology(IRI.create(iri)); + } + + public static final String DEFAULT_IRI_PREFIX = Obo2OWLConstants.DEFAULT_IRI_PREFIX; + + /** + * Table 5.8 Translation of Annotation Vocabulary. + * + * @return property map + */ + private static HashMap initAnnotationPropertyMap() { + + HashMap map = new HashMap(); + map.put(OboFormatTag.TAG_IS_OBSELETE.getTag(),OWLRDFVocabulary.OWL_DEPRECATED.getIRI()); + map.put(OboFormatTag.TAG_NAME.getTag(),OWLRDFVocabulary.RDFS_LABEL.getIRI()); + map.put(OboFormatTag.TAG_COMMENT.getTag(),OWLRDFVocabulary.RDFS_COMMENT.getIRI()); + + for(Obo2OWLVocabulary vac: Obo2OWLVocabulary.values()){ + map.put(vac.getMappedTag(), vac.getIRI()); + } + + /* map.put("expand_expression_to",Obo2OWLVocabulary.IRI_IAO_0000424.getIRI()); + map.put("expand_assertion_to",Obo2OWLVocabulary.IRI_IAO_0000425.getIRI()); + map.put("def",Obo2OWLVocabulary.IRI_IAO_0000115.getIRI()); + map.put("synonym",Obo2OWLVocabulary.IRI_IAO_0000118.getIRI()); + map.put("is_anti_symmetric",Obo2OWLVocabulary.IRI_IAO_0000427.getIRI()); + map.put("replaced_by", Obo2OWLVocabulary.IRI_IAO_0100001.getIRI());*/ + + return map; + } + + /** + * Returns an OWLClass given an IRI + *

+ * the class must be declared in either the source ontology, or in a support ontology, + * otherwise null is returned + * + * @param iri + * @return {@link OWLClass} + */ + public OWLClass getOWLClass(IRI iri) { + OWLClass c = getDataFactory().getOWLClass(iri); + for (OWLOntology o : getAllOntologies()) { + if (o.getDeclarationAxioms(c).size() > 0) { + return c; + } + } + return null; + } + + + /** + * Returns the OWLObjectProperty with this IRI + *

+ * Must have been declared in one of the ontologies + * + * @param iri + * @return {@link OWLObjectProperty} + */ + public OWLObjectProperty getOWLObjectProperty(String iri) { + return getOWLObjectProperty(IRI.create(iri)); + } + + public OWLObjectProperty getOWLObjectProperty(IRI iri) { + OWLObjectProperty p = getDataFactory().getOWLObjectProperty(iri); + for (OWLOntology o : getAllOntologies()) { + if (o.getDeclarationAxioms(p).size() > 0) { + return p; + } + } + return null; + } + + /** + * fetches the rdfs:label for an OWLObject + *

+ * assumes zero or one rdfs:label + * + * @param c + * @return label + */ + public String getLabel(OWLObject c) { + return getAnnotationValue(c, getDataFactory().getRDFSLabel()); + } + + /** + * fetches the value of a single-valued annotation property for an OWLObject + *

+ * TODO: provide a flag that determines behavior in the case of >1 value + * + * @param c + * @param lap + * @return value + */ + public String getAnnotationValue(OWLObject c, OWLAnnotationProperty lap) { + Setanns = new HashSet(); + if (c instanceof OWLEntity) { + for (OWLOntology ont : getAllOntologies()) { + anns.addAll(OwlHelper.getAnnotations((OWLEntity) c, lap, ont)); + } + } + else { + return null; + } + for (OWLAnnotation a : anns) { + if (a.getValue() instanceof OWLLiteral) { + OWLLiteral val = (OWLLiteral) a.getValue(); + return (String) SerializationUtils.clone(val.getLiteral()); // return first - TODO - check zero or one + } + } + + return null; + } + + /** + * Every OWLGraphWrapper objects wraps zero or one source ontologies. + * + * @return ontology + */ + public OWLOntology getSourceOntology() { + return sourceOntology; + } + + public void setSourceOntology(OWLOntology sourceOntology) { + this.sourceOntology = sourceOntology; + } + + + public OWLOntologyManager getManager() { + return sourceOntology.getOWLOntologyManager(); + } + + + public void addSupportOntology(OWLOntology o) { + this.supportOntologySet.add(o); + } + public void removeSupportOntology(OWLOntology o) { + this.supportOntologySet.remove(o); + } + + + /** + * in general application code need not call this - it is mostly used internally + * + * @return union of source ontology plus all supporting ontologies plus their import closures + */ + public Set getAllOntologies() { + Set all = new HashSet(getSupportOntologySet()); + for (OWLOntology o : getSupportOntologySet()) { + all.addAll(o.getImportsClosure()); + } + all.add(getSourceOntology()); + all.addAll(getSourceOntology().getImportsClosure()); + return all; + } + + /** + * all operations are over a set of ontologies - the source ontology plus + * any number of supporting ontologies. The supporting ontologies may be drawn + * from the imports closure of the source ontology, although this need not be the case. + * + * @return set of support ontologies + */ + public Set getSupportOntologySet() { + return supportOntologySet; + } + +// @Override + public synchronized void close() throws IOException { +// if (reasoner != null) { +// reasoner.dispose(); +// reasoner = null; +// isSynchronized = false; +// } +// neighborAxioms = null; + } + + + /** + * Fetch all {@link OWLClass} objects from all ontologies. + * This set is a copy. Changes are not reflected in the ontologies. + * + * @return set of all {@link OWLClass} + */ + public Set getAllOWLClasses() { + Set owlClasses = new THashSet(); + for (OWLOntology o : getAllOntologies()) { + owlClasses.addAll(o.getClassesInSignature()); + } + return owlClasses; + } + + + /** + * Given an OBO-style ID, return the corresponding OWLClass, if it is declared - otherwise null + * + * @param id - e.g. GO:0008150 + * @return OWLClass with id or null + */ + public OWLClass getOWLClassByIdentifier(String id) { + return getOWLClassByIdentifier(id, false); + } + + /** + * + * As {@link #getOWLClassByIdentifier(String)} but include pre-resolution step + * using altId map. + * + * Currently this additional boolean option is obo-format specific; in OBO, + * when a class A is merged into B, the OBO-ID of A is preserved with an hasAlternateId + * annotation on the IRI of B. Using this method, with isAutoResolve=true, a query for + * the OBO ID of A will return class B. + * + * In future, analogous options will be added to IRI-based access to classes. + * + * @param id + * @param isAutoResolve + * @return OWLClass with id or null + */ + public OWLClass getOWLClassByIdentifier(String id, boolean isAutoResolve) { + IRI iri = getIRIByIdentifier(id, isAutoResolve); + if (iri != null) + return getOWLClass(iri); + return null; + } + + public IRI getIRIByIdentifier(String id, boolean isAutoResolve) { + if (isAutoResolve) { + OWLObject obj = this.getObjectByAltId(id); + if (obj != null) { + return ((OWLNamedObject) obj).getIRI(); + } + } + + // special magic for finding IRIs from a non-standard identifier + // This is the case for relations (OWLObject properties) with a short hand + // or for relations with a non identifiers with-out a colon, e.g. negative_regulation + // we first collect all candidate matching properties in candIRISet. + Set candIRISet = Sets.newHashSet(); + if (!id.contains(":")) { + final OWLAnnotationProperty shortHand = getDataFactory().getOWLAnnotationProperty(Obo2OWLVocabulary.IRI_OIO_shorthand.getIRI()); + final OWLAnnotationProperty oboIdInOwl = getDataFactory().getOWLAnnotationProperty(trTagToIRI(OboFormatTag.TAG_ID.getTag())); + for (OWLOntology o : getAllOntologies()) { + for(OWLObjectProperty p : o.getObjectPropertiesInSignature()) { + // check for short hand or obo ID in owl + Set annotations = OwlHelper.getAnnotations(p, o); + if (annotations != null) { + for (OWLAnnotation owlAnnotation : annotations) { + OWLAnnotationProperty property = owlAnnotation.getProperty(); + if ((shortHand != null && shortHand.equals(property)) + || (oboIdInOwl != null && oboIdInOwl.equals(property))) + { + OWLAnnotationValue value = owlAnnotation.getValue(); + if (value != null && value instanceof OWLLiteral) { + OWLLiteral literal = (OWLLiteral) value; + String shortHandLabel = literal.getLiteral(); + if (id.equals(shortHandLabel)) { + candIRISet.add(p.getIRI()); + } + } + } + } + } + } + } + } + + // In the case where we find multiple candidate IRIs, we give priorities for IRIs from BFO or RO ontologies. + IRI returnIRI = null; + for (IRI iri: candIRISet) { + String iriStr = iri.toString(); + if (iriStr.contains("BFO") || iriStr.contains("RO")) { + returnIRI = iri; + } + } + + // If we were not able to find RO/BFO candidate IRIs for id + if (returnIRI == null) { + // We return it only if we have only one candidate. + if (candIRISet.size() == 1) + return new ArrayList(candIRISet).get(0); + // This is the unexpected case. Multiple non-RO/BPO properties are mapped to given id and it's not clear what to return. + else if (candIRISet.size() > 1) + throw new RuntimeException("Multiple candidate IRIs are found for id: " + id + ". None of them are from BFO or RO."); + } + // If we were able to find the property from RO/BFO, just return it. + else { + return returnIRI; + } + + // otherwise use the obo2owl method + //Obo2Owl b = new Obo2Owl(getManager()); // re-use manager, creating a new one can be expensive as this is a highly used code path + //b.setObodoc(new OBODoc()); + return oboIdToIRI(id); + } + + public static IRI trTagToIRI(String tag){ + IRI iri = null; + if (annotationPropertyMap.containsKey(tag)) { + iri = annotationPropertyMap.get(tag); + } + else { + //iri = IRI.create(Obo2OWLConstants.DEFAULT_IRI_PREFIX+"IAO_"+tag); + iri = IRI.create(Obo2OWLConstants.OIOVOCAB_IRI_PREFIX+tag); + + } + + return iri; + + } + + public IRI oboIdToIRI(String id) { + if (id.contains(" ")) { + LOG.error("id contains space: \""+id+"\""); + //throw new UnsupportedEncodingException(); + return null; + } + + // No conversion is required if this is already an IRI (ID-as-URI rule) + if (id.startsWith("http:")) { // TODO - roundtrip from other schemes + return IRI.create(id); + } + else if (id.startsWith("https:")) { // TODO - roundtrip from other schemes + return IRI.create(id); + } + else if (id.startsWith("ftp:")) { // TODO - roundtrip from other schemes + return IRI.create(id); + } + else if (id.startsWith("urn:")) { // TODO - roundtrip from other schemes + return IRI.create(id); + } + + // TODO - treat_xrefs_as_equivalent + // special case rule for relation xrefs: + // 5.9.3. Special Rules for Relations + if (!id.contains(":")) { + String xid = translateShorthandIdToExpandedId(id); + if (!xid.equals(id)) + return oboIdToIRI(xid); + } + + String[] idParts = id.split(":", 2); + String db; + String localId; + if (idParts.length > 1) { + db = idParts[0]; + localId = idParts[1]; + if(localId.contains("_")){ + db += "#_"; // NonCanonical-Prefixed-ID + }else + db += "_"; + } + else if (idParts.length == 0) { + db = getDefaultIDSpace()+"#"; + localId = id; + } + else { // == 1 + // todo use owlOntology IRI + db = getDefaultIDSpace()+"#"; + // if(id.contains("_")) + // db += "_"; + + localId = idParts[0]; // Unprefixed-ID + } + + + String uriPrefix = Obo2OWLConstants.DEFAULT_IRI_PREFIX+db; + if (idSpaceMap.containsKey(db)) { + uriPrefix = idSpaceMap.get(db); + } + + String safeId; + try { + safeId = java.net.URLEncoder.encode(localId,"US-ASCII"); + } catch (UnsupportedEncodingException e1) { + // TODO Auto-generated catch block + return null; + } + + if (safeId.contains(" ")) + safeId = safeId.replace(" ", "_"); + IRI iri = null; + try { + iri = IRI.create(uriPrefix + safeId); + } catch (IllegalArgumentException e) { + // TODO - define new exception class for this + // throw new UnsupportedEncodingException(); + return null; + } + + return iri; + } + + // 5.9.3. Special Rules for Relations + private String translateShorthandIdToExpandedId(String id) { + if (id.contains(":")) { + return id; + }else { + System.err.println("line 467 translateShorthandIdToExpandedId fail on need for obo"); + System.exit(-1); + } + return null; +/* Frame tdf = obodoc.getTypedefFrame(id); + if (tdf == null) + return id; + Collection xrefs = tdf.getTagValues(OboFormatTag.TAG_XREF, Xref.class); + String matchingExpandedId = null; + for (Xref xref : xrefs) { + //System.err.println("ID:"+id+" xref:"+xref); + + if (xref != null) { + String xid = xref.getIdref(); + //System.err.println(" ID:"+id+" xid:"+xid); + if (xid.equals(id)) + continue; + if (matchingExpandedId == null) { + matchingExpandedId = xid; + } + else { + // RO and BFO take precedence over others + if ((xid.startsWith("RO") || + xid.startsWith("BFO"))) { + matchingExpandedId = xid; + } + } + } + } + if (matchingExpandedId == null) + return id; + //System.err.println(" ID:"+id+" matching:"+matchingExpandedId); + return matchingExpandedId; + */ + } + + private String getDefaultIDSpace() { + return defaultIDSpace; + } + + /** + * @param altId + * @return OWLObject that has matching altId, or null if not found + */ + public OWLObject getObjectByAltId(String altId) { + Map m = getAltIdMap(false); + if (m.containsKey(altId)) + return m.get(altId); + else + return null; + } + + private Map getAltIdMap(boolean isReset) { + if (isReset) + altIdMap = null; + if (altIdMap == null) { + altIdMap = getAllOWLObjectsByAltId(); + } + return altIdMap; + } + + /** + * Given an OBO-style ID, return the corresponding OWLObject, if it is declared - otherwise null + * + * @param id - e.g. GO:0008150 + * @return object with id or null + */ + public OWLObject getOWLObjectByIdentifier(String id) { + IRI iri = getIRIByIdentifier(id); + if (iri != null) + return getOWLObject(iri); + return null; + } + + /** + * Returns the OWLObject with this IRI + *

+ * Must have been declared in one of the ontologies + *

+ * Currently OWLObject must be one of OWLClass, OWLObjectProperty or OWLNamedIndividual + *

+ * If the ontology employs punning and there different entities with the same IRI, then + * the order of precedence is OWLClass then OWLObjectProperty then OWLNamedIndividual + * + * @param s entity IRI + * @return {@link OWLObject} + */ + public OWLObject getOWLObject(IRI s) { + OWLObject o; + o = getOWLClass(s); + if (o == null) { + o = getOWLIndividual(s); + } + if (o == null) { + o = getOWLObjectProperty(s); + } + if (o == null) { + o = getOWLAnnotationProperty(s); + } + return o; + } + + public OWLAnnotationProperty getOWLAnnotationProperty(IRI iri) { + OWLAnnotationProperty p = getDataFactory().getOWLAnnotationProperty(iri); + for (OWLOntology o : getAllOntologies()) { + if (o.getDeclarationAxioms(p).size() > 0) { + return p; + } + } + return null; + } + + /** + * Returns an OWLNamedIndividual with this IRI if it has been declared + * in the source or support ontologies. Returns null otherwise. + * + * @param iri + * @return {@link OWLNamedIndividual} + */ + public OWLNamedIndividual getOWLIndividual(IRI iri) { + OWLNamedIndividual c = getDataFactory().getOWLNamedIndividual(iri); + for (OWLOntology o : getAllOntologies()) { + for (OWLDeclarationAxiom da : o.getDeclarationAxioms(c)) { + if (da.getEntity() instanceof OWLNamedIndividual) { + return (OWLNamedIndividual) da.getEntity(); + } + } + } + return null; + } + + public OWLDataFactory getDataFactory() { + return getManager().getOWLDataFactory(); + } + + + /** + * Given an OBO-style ID, return the corresponding OWLObjectProperty, if it is declared - otherwise null + * + * @param id - e.g. GO:0008150 + * @return OWLObjectProperty with id or null + */ + public OWLObjectProperty getOWLObjectPropertyByIdentifier(String id) { + IRI iri = getIRIByIdentifier(id); + if (iri != null) + return getOWLObjectProperty(iri); + return null; + } + + +// public void mergeImportClosure(boolean b) { +// // TODO Auto-generated method stub +// +// } + + + /** + * Find all corresponding {@link OWLObject}s with an OBO-style alternate identifier. + *

+ * WARNING: This methods scans all object annotations in all ontologies. + * This is an expensive method. + * + * @return map of altId to OWLObject (never null) + */ + public Map getAllOWLObjectsByAltId() { + final Map results = new HashMap(); + final OWLAnnotationProperty altIdProperty = getAnnotationProperty(OboFormatTag.TAG_ALT_ID.getTag()); + if (altIdProperty == null) { + return Collections.emptyMap(); + } + for (OWLOntology o : getAllOntologies()) { + Set aas = o.getAxioms(AxiomType.ANNOTATION_ASSERTION); + for (OWLAnnotationAssertionAxiom aa : aas) { + OWLAnnotationValue v = aa.getValue(); + OWLAnnotationProperty property = aa.getProperty(); + if (altIdProperty.equals(property) && v instanceof OWLLiteral) { + String altId = ((OWLLiteral)v).getLiteral(); + OWLAnnotationSubject subject = aa.getSubject(); + if (subject instanceof IRI) { + OWLObject obj = getOWLObject((IRI) subject); + if (obj != null) { + results.put(altId, obj); + } + } + } + } + } + return results; + } + + /** + * It translates a oboformat tag into an OWL annotation property + * + * @param tag + * @return {@link OWLAnnotationProperty} + */ + public OWLAnnotationProperty getAnnotationProperty(String tag){ + return getDataFactory().getOWLAnnotationProperty(trTagToIRI(tag)); + } + + /** + * fetches an OWL Object by rdfs:label + *

+ * if there is >1 match, return the first one encountered + * + * @param label + * @return object or null + */ + public OWLObject getOWLObjectByLabel(String label) { + IRI iri = getIRIByLabel(label); + if (iri != null) + return getOWLObject(iri); + return null; + } + + /** + * fetches an OWL IRI by rdfs:label + * + * @param label + * @return IRI or null + */ + public IRI getIRIByLabel(String label) { + try { + return getIRIByLabel(label, false); + } catch (Exception e) { + // note that it should be impossible to reach this point + // if getIRIByLabel is called with isEnforceUnivocal = false + e.printStackTrace(); + return null; + } + } + + /** + * fetches an OWL IRI by rdfs:label, optionally testing for uniqueness + *

+ * TODO: index labels. This currently scans all labels in the ontology, which is expensive + * + * @param label + * @param isEnforceUnivocal + * @return IRI or null + * @throws SharedLabelException if >1 IRI shares input label + */ + public IRI getIRIByLabel(String label, boolean isEnforceUnivocal) throws Exception { + IRI iri = null; + for (OWLOntology o : getAllOntologies()) { + Set aas = o.getAxioms(AxiomType.ANNOTATION_ASSERTION); + for (OWLAnnotationAssertionAxiom aa : aas) { + OWLAnnotationValue v = aa.getValue(); + OWLAnnotationProperty property = aa.getProperty(); + if (property.isLabel() && v instanceof OWLLiteral) { + if (label.equals( ((OWLLiteral)v).getLiteral())) { + OWLAnnotationSubject subject = aa.getSubject(); + if (subject instanceof IRI) { + if (isEnforceUnivocal) { + if (iri != null && !iri.equals((IRI)subject)) { + throw new Exception(); + } + iri = (IRI)subject; + } + else { + return (IRI)subject; + } + } + else { + //return null; + } + } + } + } + } + return iri; + } + + public IRI getIRIByIdentifier(String id) { + return getIRIByIdentifier(id, false); + } + + +} + diff --git a/minerva-core/src/main/java/org/geneontology/minerva/MolecularModelManager.java b/minerva-core/src/main/java/org/geneontology/minerva/MolecularModelManager.java index fff4a812..0c4c9c7a 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/MolecularModelManager.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/MolecularModelManager.java @@ -24,7 +24,7 @@ import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyCreationException; -import owltools.graph.OWLGraphWrapper; +//import owltools.graph.OWLGraphWrapper; import owltools.vocab.OBOUpperVocabulary; /** @@ -291,15 +291,15 @@ public OWLNamedIndividual getIndividual(IRI iri, ModelContainer model) { return individual; } private OWLClass getClass(String cid, ModelContainer model) throws UnknownIdentifierException { - OWLGraphWrapper graph = new OWLGraphWrapper(model.getAboxOntology()); - return getClass(cid, graph); + MinervaOWLGraphWrapper graph = new MinervaOWLGraphWrapper(model.getAboxOntology()); + return getClass(cid, graph); } - private OWLClass getClass(String cid, OWLGraphWrapper graph) throws UnknownIdentifierException { + private OWLClass getClass(String cid, MinervaOWLGraphWrapper graph) throws UnknownIdentifierException { IRI iri = getCuriHandler().getIRI(cid); return graph.getOWLClass(iri); } public OWLObjectProperty getObjectProperty(String pid, ModelContainer model) throws UnknownIdentifierException { - OWLGraphWrapper graph = new OWLGraphWrapper(model.getAboxOntology()); + MinervaOWLGraphWrapper graph = new MinervaOWLGraphWrapper(model.getAboxOntology()); IRI iri = getCuriHandler().getIRI(pid); return graph.getOWLObjectProperty(iri); } diff --git a/minerva-core/src/main/java/org/geneontology/minerva/UndoAwareMolecularModelManager.java b/minerva-core/src/main/java/org/geneontology/minerva/UndoAwareMolecularModelManager.java index 051e0f1e..f8ca354b 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/UndoAwareMolecularModelManager.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/UndoAwareMolecularModelManager.java @@ -20,8 +20,6 @@ import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyManager; -import owltools.graph.OWLGraphWrapper; - /** * Provide undo and redo operations for the {@link MolecularModelManager}. */ diff --git a/minerva-core/src/main/java/org/geneontology/minerva/json/MolecularModelJsonRenderer.java b/minerva-core/src/main/java/org/geneontology/minerva/json/MolecularModelJsonRenderer.java index 47dec5dd..13de176b 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/json/MolecularModelJsonRenderer.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/json/MolecularModelJsonRenderer.java @@ -15,6 +15,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.tuple.Pair; import org.apache.log4j.Logger; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.ModelContainer; import org.geneontology.minerva.MolecularModelManager; import org.geneontology.minerva.curie.CurieHandler; @@ -52,7 +53,6 @@ import owltools.gaf.eco.EcoMapper; import owltools.gaf.eco.EcoMapperFactory; import owltools.gaf.eco.EcoMapperFactory.OntologyMapperPair; -import owltools.graph.OWLGraphWrapper; import owltools.util.OwlHelper; /** @@ -67,7 +67,7 @@ public class MolecularModelJsonRenderer { private final String modelId; private final OWLOntology ont; - private final OWLGraphWrapper graph; + private final MinervaOWLGraphWrapper graph; private final CurieHandler curieHandler; private final InferenceProvider inferenceProvider; @@ -83,19 +83,19 @@ protected DateFormat initialValue() { public MolecularModelJsonRenderer(ModelContainer model, InferenceProvider inferenceProvider, CurieHandler curieHandler) { this(curieHandler.getCuri(model.getModelId()), model.getAboxOntology(), - new OWLGraphWrapper(model.getAboxOntology()), + new MinervaOWLGraphWrapper(model.getAboxOntology()), inferenceProvider, curieHandler); } public MolecularModelJsonRenderer(String modelId, OWLOntology ontology, InferenceProvider inferenceProvider, CurieHandler curieHandler) { - this(modelId, ontology, new OWLGraphWrapper(ontology), inferenceProvider, curieHandler); + this(modelId, ontology, new MinervaOWLGraphWrapper(ontology), inferenceProvider, curieHandler); } - public MolecularModelJsonRenderer(String modelId, OWLGraphWrapper graph, InferenceProvider inferenceProvider, CurieHandler curieHandler) { + public MolecularModelJsonRenderer(String modelId, MinervaOWLGraphWrapper graph, InferenceProvider inferenceProvider, CurieHandler curieHandler) { this(modelId, graph.getSourceOntology(), graph, inferenceProvider, curieHandler); } - private MolecularModelJsonRenderer(String modelId, OWLOntology ont, OWLGraphWrapper graph, InferenceProvider inferenceProvider, CurieHandler curieHandler) { + private MolecularModelJsonRenderer(String modelId, OWLOntology ont, MinervaOWLGraphWrapper graph, InferenceProvider inferenceProvider, CurieHandler curieHandler) { super(); this.modelId = modelId; this.ont = ont; @@ -370,7 +370,7 @@ public static Pair,List> renderProperti */ // retrieve (or load) all ontologies // put in a new wrapper - OWLGraphWrapper wrapper = new OWLGraphWrapper(mmm.getOntology()); + MinervaOWLGraphWrapper wrapper = new MinervaOWLGraphWrapper(mmm.getOntology()); Collection imports = mmm.getImports(); OWLOntologyManager manager = wrapper.getManager(); for (IRI iri : imports) { @@ -460,7 +460,7 @@ public static List renderEvidences(OWLOntologyManager manager, } pair = eco; } - final OWLGraphWrapper graph = pair.getGraph(); + final MinervaOWLGraphWrapper graph = pair.getGraph(); final EcoMapper mapper = pair.getMapper(); Set ecoClasses = graph.getAllOWLClasses(); Map codesForEcoClasses = mapper.getCodesForEcoClasses(); diff --git a/minerva-core/src/main/java/org/geneontology/minerva/util/ManchesterSyntaxTool.java b/minerva-core/src/main/java/org/geneontology/minerva/util/ManchesterSyntaxTool.java deleted file mode 100644 index 8fc8b306..00000000 --- a/minerva-core/src/main/java/org/geneontology/minerva/util/ManchesterSyntaxTool.java +++ /dev/null @@ -1,198 +0,0 @@ -package org.geneontology.minerva.util; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.semanticweb.owlapi.OWLAPIConfigProvider; -import org.semanticweb.owlapi.expression.OWLEntityChecker; -import org.semanticweb.owlapi.manchestersyntax.parser.ManchesterOWLSyntaxParserImpl; -import org.semanticweb.owlapi.manchestersyntax.renderer.ParserException; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLDataProperty; -import org.semanticweb.owlapi.model.OWLDatatype; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObject; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.util.mansyntax.ManchesterOWLSyntaxParser; - -import owltools.graph.OWLGraphWrapper; - - -/** - * Wrapper for parsing OWL Manchester Syntax using a {@link OWLGraphWrapper}. - * This is a simplified re-implementation. - */ -public class ManchesterSyntaxTool { - - private static final OWLAPIConfigProvider CONFIGURATION_PROVIDER = new OWLAPIConfigProvider(); - - private final OWLDataFactory dataFactory; - private final OWLEntityChecker entityChecker; - private final Map createdClassesMap; - - /** - * Create new instance. - * - * @param graph - * @param createClasses if set to true, classes are generated even if they are not declared. - */ - public ManchesterSyntaxTool(OWLGraphWrapper graph, boolean createClasses) { - super(); - this.dataFactory = graph.getDataFactory(); - createdClassesMap = new HashMap(); - entityChecker = new AdvancedEntityChecker(graph, createClasses, createdClassesMap); - } - - /** - * @return the createdClasses - */ - public Map getCreatedClasses() { - return Collections.unmodifiableMap(createdClassesMap); - } - - /** - * Parse a class expression in Manchester syntax. - * - * @param expression - * @return {@link OWLClassExpression} - * @throws ParserException - */ - public OWLClassExpression parseManchesterExpression(String expression) throws ParserException { - ManchesterOWLSyntaxParser parser = createParser(); - OWLClassExpression ce = parser.parseClassExpression(expression); - return ce; - } - - - private ManchesterOWLSyntaxParser createParser() { - ManchesterOWLSyntaxParserImpl parser = new ManchesterOWLSyntaxParserImpl(CONFIGURATION_PROVIDER, dataFactory); - parser.setOWLEntityChecker(entityChecker); - return parser; - } - - static class AdvancedEntityChecker implements OWLEntityChecker { - - private final OWLGraphWrapper graph; - private final boolean createClasses; - private final Map createdClassesMap; - - AdvancedEntityChecker(OWLGraphWrapper graph, boolean createClasses, - Map createdClassesMap) { - super(); - this.graph = graph; - this.createClasses = createClasses; - this.createdClassesMap = createdClassesMap; - } - - public OWLClass getOWLClass(String name) { - if (name.length() < 2) { - return null; - } - OWLObject owlObject; - if (name.charAt(0) == '\'') { - name = trimQuotes(name); - owlObject = graph.getOWLObjectByLabel(name); - } - else { - owlObject = graph.getOWLObjectByIdentifier(name); - if (owlObject == null) { - owlObject = graph.getOWLObjectByLabel(name); - } - } - if (owlObject != null) { - if (owlObject instanceof OWLClass) { - return (OWLClass) owlObject; - } - return null; - } - if (name.startsWith("http:")) { - IRI iri = IRI.create(name); - owlObject = graph.getOWLObject(iri); - if (owlObject != null) { - if (owlObject instanceof OWLClass) { - return (OWLClass) owlObject; - } - return null; - } - OWLClass c = null; - if (createClasses) { - String id = graph.getIdentifier(iri); - c = createdClassesMap.get(id); - if (c == null) { - c = graph.getDataFactory().getOWLClass(iri); - createdClassesMap.put(name, c); - } - } - return c; - } - else { - if (createClasses && !StringUtils.contains(name, ' ')) { - OWLClass c = createdClassesMap.get(name); - if (c == null) { - IRI iri = graph.getIRIByIdentifier(name); - c = graph.getDataFactory().getOWLClass(iri); - createdClassesMap.put(name, c); - } - return c; - } - } - return null; - } - - public OWLObjectProperty getOWLObjectProperty(String name) { - if (name.length() < 2) { - return null; - } - name = trimQuotes(name); - OWLObjectProperty p = null; - if (StringUtils.contains(name, ' ') == false) { - p = graph.getOWLObjectPropertyByIdentifier(name); - if (p == null) { - p = graph.getOWLObjectProperty(name); - } - } - if (p == null) { - graph.getIRIByLabel(name); - OWLObject owlObject = graph.getOWLObjectByLabel(name); - if (owlObject != null && owlObject instanceof OWLObjectProperty) { - p = (OWLObjectProperty) owlObject; - } - } - return p; - } - - private String trimQuotes(String s) { - if (s.startsWith("'") && s.endsWith("'")) { - s = s.substring(1, s.length() - 1); - } - return s; - } - - public OWLDataProperty getOWLDataProperty(String name) { - return null; - } - - public OWLNamedIndividual getOWLIndividual(String name) { - OWLNamedIndividual i = graph.getOWLIndividualByIdentifier(name); - if (i == null) { - i = graph.getOWLIndividual(name); - } - return i; - } - - public OWLDatatype getOWLDatatype(String name) { - return null; - } - - public OWLAnnotationProperty getOWLAnnotationProperty(String name) { - return null; - } - - } -} diff --git a/minerva-core/src/main/java/org/geneontology/minerva/validation/OWLValidationReport.java b/minerva-core/src/main/java/org/geneontology/minerva/validation/OWLValidationReport.java index 20c3d48e..86d15721 100644 --- a/minerva-core/src/main/java/org/geneontology/minerva/validation/OWLValidationReport.java +++ b/minerva-core/src/main/java/org/geneontology/minerva/validation/OWLValidationReport.java @@ -12,4 +12,11 @@ public OWLValidationReport() { super(report_type_id, tracker, rulefile); } + + + public String getAsText() { + String e = "A human readable explanation of any OWL inconsistencies ought to go here."; + return e; + } + } diff --git a/minerva-core/src/main/java/owltools/cli/Opts.java b/minerva-core/src/main/java/owltools/cli/Opts.java new file mode 100644 index 00000000..50135c18 --- /dev/null +++ b/minerva-core/src/main/java/owltools/cli/Opts.java @@ -0,0 +1,178 @@ +package owltools.cli; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.io.FileUtils; + +/** + * Helper for easy handling of command line parameters and input. + */ +public class Opts { + + private int i = 0; + private String[] args; + private boolean helpMode = false; + + /** + * Create a new instance for the given command-line parameters. + * + * @param args command-line parameter array + */ + public Opts(String[] args) { + super(); + this.i = 0; + this.args = args; + } + + /** + * Create a new instance for the given command-line parameters. + * + * @param args list of command-line parameters + */ + public Opts(List args) { + this(args.toArray(new String[args.size()])); + } + + /** + * @param helpMode the helpMode to set + */ + public void setHelpMode(boolean helpMode) { + this.helpMode = helpMode; + } + + /** + * @return the helpMode + */ + public boolean isHelpMode() { + return helpMode; + } + + /** + * @return true, if there are further parameters to handle. + */ + public boolean hasArgs() { + return i < args.length; + } + + /** + * @return if there is a next parameter, which is an option flag + */ + public boolean hasOpts() { + return hasArgs() && args[i].startsWith("-"); + } + + /** + * Check if the option flag is in the remaining parameters + * + * @param opt + * @return true, if one of the remaining parameters equals the given string. + */ + public boolean hasOpt(String opt) { + for (int j=i; j eqs) { + for (String eq : eqs) { + if (nextEq(eq)) + return true; + } + return false; + } + public List nextList() { + ArrayList sl = new ArrayList(); + while (hasArgs()) { + if (args[i].equals("//")) { + i++; + break; + } + if (args[i].startsWith("-")) + break; + sl.add(args[i]); + i++; + } + return sl; + } + public String nextOpt() { + String opt = args[i]; + i++; + return opt; + } + public File nextFile() { + String opt = args[i]; + i++; + File f = FileUtils.getFile(opt); + return f; + } + public String peekArg() { + if (hasArgs()) + return args[i]; + return null; + } + public boolean nextArgIsHelp() { + if (hasArgs() && (args[i].equals("-h") + || args[i].equals("--help"))) { + nextOpt(); + return true; + } + return false; + } + + /** + * Send a fail. WARNING: This will terminate the VM. + * Do NOT use in a framework. + * + * Uses System.err to print the error message. + */ + public void fail() { + System.err.println("cannot process: "+args[i]); + System.exit(1); + + } + + /** + * Write an info. WARNING: This will terminate the VM. + * Do NOT use in a framework. + * + * Uses System.out to print the message. + * + * @param params + * @param desc + */ + public void info(String params, String desc) { + if (this.nextArgIsHelp()) { + System.out.println(args[i-2]+" "+params+"\t "+desc); + System.exit(0); + } + } +} \ No newline at end of file diff --git a/minerva-core/src/main/java/owltools/gaf/eco/EcoMapper.java b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapper.java new file mode 100644 index 00000000..1c727678 --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapper.java @@ -0,0 +1,66 @@ +package owltools.gaf.eco; + +import java.util.Map; +import java.util.Set; + +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLClass; + +public interface EcoMapper { + + /** + * Permanent URL for the evidence code ontology (ECO) owl file. + */ + public static final String ECO_PURL = "http://purl.obolibrary.org/obo/eco.owl"; + + /** + * IRI for the evidence code ontology (ECO) owl file. + */ + public static final IRI ECO_PURL_IRI = IRI.create(ECO_PURL); + + /** + * Permanent URL for the mapping of GO evidence codes to ECO classes + */ + public static final String ECO_MAPPING_PURL = "http://purl.obolibrary.org/obo/eco/gaf-eco-mapping.txt"; + + /** + * Retrieve the equivalent ECO class for the given GO evidence code. Assume, that the reference is 'default'. + * + * @param code + * @return {@link OWLClass} or null + */ + public OWLClass getEcoClassForCode(String code); + + /** + * Retrieve the ECO classes for the given GO evidence code. Include the classes to be used with more specific references. + * + * @param code + * @return set of classes, never null + */ + public Set getAllEcoClassesForCode(String code); + + /** + * Retrieve the ECO class for the given GO evidence code and reference. If reference is null, assume default. + * + * @param code + * @param refCode + * @return {@link OWLClass} or null + */ + public OWLClass getEcoClassForCode(String code, String refCode); + + + /** + * Check that the given GO code is a valid code with an existing mapping to ECO + * + * @param code + * @return true if the code is a valid + */ + public boolean isGoEvidenceCode(String code); + + /** + * Retrieve the mapping from ECO classes to GO evidence codes. + * + * @return mapping + */ + public Map getCodesForEcoClasses(); +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperFactory.java b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperFactory.java new file mode 100644 index 00000000..0b6e95ca --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperFactory.java @@ -0,0 +1,575 @@ +package owltools.gaf.eco; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.geneontology.minerva.MinervaOWLGraphWrapper; +import org.semanticweb.elk.owlapi.ElkReasonerFactory; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLException; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyID; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.reasoner.OWLReasoner; +import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; + +import com.google.common.base.Optional; + +import owltools.io.ParserWrapper; + +/** + * Factory to create instances of {@link EcoMapper} and {@link TraversingEcoMapper}. + */ +public class EcoMapperFactory { + + private static final OWLReasonerFactory reasonerFactor = new ElkReasonerFactory(); + + private EcoMapperFactory() { + // private constructor, no instances allowed + } + + public static class OntologyMapperPair { + + private final MinervaOWLGraphWrapper graph; + private final MAPPER mapper; + + /** + * @param graph + * @param mapper + */ + OntologyMapperPair(MinervaOWLGraphWrapper graph, MAPPER mapper) { + this.graph = graph; + this.mapper = mapper; + } + + /** + * @return the graph + */ + public MinervaOWLGraphWrapper getGraph() { + return graph; + } + + /** + * @return the mapper + */ + public MAPPER getMapper() { + return mapper; + } + } + + /** + * Create a new {@link SimpleEcoMapper} with from the mapping loaded from + * the PURL. + * + * @return mapper + * @throws IOException + * + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static SimpleEcoMapper createSimple() throws IOException { + return createSimple(EcoMapper.ECO_MAPPING_PURL); + } + + /** + * Create a new {@link SimpleEcoMapper} with from the mapping loaded from + * the given source. + * + * @param source + * @return mapper + * @throws IOException + */ + public static SimpleEcoMapper createSimple(String source) throws IOException { + return createSimpleMapper(createReader(source)); + } + + /** + * Create an instance of a {@link EcoMapper}. Uses a separate parser. Load + * the ECO and mappings using their PURLs. + * + * @return mapper pair + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_PURL + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createEcoMapper() throws OWLException, IOException { + return createEcoMapper(new ParserWrapper()); + } + + /** + * Create an instance of a {@link EcoMapper}. Uses a the manager to load ECO via the + * PURL. Load mappings using the PURL. + * @param m + * + * @return mapper pair + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_PURL + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createEcoMapper(OWLOntologyManager m) throws OWLException, IOException { + ParserWrapper p = new ParserWrapper(); + p.setManager(m); + return createEcoMapper(p); + } + + /** + * Create an instance of a {@link EcoMapper}. Uses the given + * {@link ParserWrapper} to load the ontology. Retrieves ECO and the + * mappings using their PURLs. + * + * @param p + * @return mapper pair + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_PURL + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createEcoMapper(ParserWrapper p) throws OWLException, IOException { + return createEcoMapper(p, EcoMapper.ECO_PURL); + } + + /** + * Create an instance of a {@link EcoMapper}. Uses the given + * {@link ParserWrapper} to load the ontology. Retrieves ECO from the given location and the + * mapping from the PURL. + * + * @param p + * @param location + * @return mapper pair + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createEcoMapper(ParserWrapper p, String location) throws OWLException, IOException { + final OWLOntology eco = p.parseOWL(location); + final MinervaOWLGraphWrapper graph = new MinervaOWLGraphWrapper(eco); + final EcoMapper mapper = createEcoMapper(graph); + final OntologyMapperPair pair = new OntologyMapperPair(graph, mapper); + return pair ; + } + + /** + * Create an instance of a {@link EcoMapper}. Retrieves the mappings using + * the PURL. + * + * @param graph graph containing ECO + * @return mapper + * @throws IOException + * + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static EcoMapper createEcoMapper(MinervaOWLGraphWrapper graph) throws IOException { + Reader reader = null; + try { + reader = createReader(EcoMapper.ECO_MAPPING_PURL); + EcoMappings mappings = loadEcoMappings(reader, graph); + return createEcoMapper(mappings); + } + finally { + IOUtils.closeQuietly(reader); + } + } + + static EcoMapper createEcoMapper(EcoMappings mappings) { + return new EcoMapperImpl(mappings); + } + + /** + * Create a {@link TraversingEcoMapper} instance using a new + * {@link ParserWrapper} to load ECO. ECO and the mappings are retrieved + * using their PURLs. + *

+ * Creates an ELK reasoner to be used in the traversal methods. Use + * {@link TraversingEcoMapper#dispose()} to ensure proper cleanup of the ELK + * worker thread pool. + * + * @return mapper pair + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_PURL + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createTraversingEcoMapper() throws OWLException, IOException { + return createTraversingEcoMapper(new ParserWrapper()); + } + + /** + * Create a {@link TraversingEcoMapper} instance using the given + * {@link ParserWrapper} to load ECO. ECO and the mappings are retrieved + * using their PURLs. + *

+ * Creates an ELK reasoner to be used in the traversal methods. Use + * {@link TraversingEcoMapper#dispose()} to ensure proper cleanup of the ELK + * worker thread pool. + * + * @param p + * @return mapper + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_PURL + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createTraversingEcoMapper(ParserWrapper p) throws OWLException, IOException { + return createTraversingEcoMapper(p, EcoMapper.ECO_PURL); + } + + /** + * Create a {@link TraversingEcoMapper} instance using the given + * {@link ParserWrapper} to load ECO from the given location. The mappings + * are retrieved using the PURL. + *

+ * Creates an ELK reasoner to be used in the traversal methods. Use + * {@link TraversingEcoMapper#dispose()} to ensure proper cleanup of the ELK + * worker thread pool. + * + * @param p + * @param location + * @return mapper + * @throws OWLException + * @throws IOException + * + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static OntologyMapperPair createTraversingEcoMapper(ParserWrapper p, String location) throws OWLException, IOException { + OWLOntology eco = p.parseOWL(EcoMapper.ECO_PURL_IRI); + OWLReasoner reasoner = reasonerFactor.createReasoner(eco); + Reader reader = null; + try { + MinervaOWLGraphWrapper ecoGraph = new MinervaOWLGraphWrapper(eco); + reader = createReader(EcoMapper.ECO_MAPPING_PURL); + final TraversingEcoMapper mapper = createTraversingEcoMapper(reader, ecoGraph, reasoner, true); + return new OntologyMapperPair(ecoGraph, mapper); + } + finally { + IOUtils.closeQuietly(reader); + } + } + + /** + * Create a {@link TraversingEcoMapper} instance using the given + * {@link MinervaOWLGraphWrapper}. It is assumed that ECO can be retrieved from the + * graph using its default IRI. The mappings are retrieved using the PURL. + *

+ * Uses the given reasoner in the traversal methods. If disposeReasoner is + * set to true, dispose also the reasoner, while calling + * {@link TraversingEcoMapper#dispose()}. + * + * @param all + * graph containing all ontologies, including ECO + * @param reasoner + * reasoner capable of traversing ECO + * @param disposeReasoner + * set to true if the reasoner should be disposed, when calling + * {@link TraversingEcoMapper#dispose()} + * @return mapper + * @throws IOException + * @throws OWLException + * @throws IllegalArgumentException + * throw when the reasoner is null, or the + * {@link MinervaOWLGraphWrapper} does not contain ECO. + * + * @see EcoMapper#ECO_PURL_IRI + * @see EcoMapper#ECO_MAPPING_PURL + */ + public static TraversingEcoMapper createTraversingEcoMapper(MinervaOWLGraphWrapper all, OWLReasoner reasoner, boolean disposeReasoner) throws IOException, OWLException { + + // This has bitten me, so let's try and be specific... + if( reasoner == null ) { + throw new IllegalArgumentException("No reasoner was specified for use with the EcoTools. Add a reasoner for the command line"); + } + + OWLOntology eco = null; + + // assume the graph wrapper is more than eco + // try to find ECO by its purl + Set allOntologies = all.getAllOntologies(); + for (OWLOntology owlOntology : allOntologies) { + OWLOntologyID id = owlOntology.getOntologyID(); + Optional ontologyIRI = id.getOntologyIRI(); + if (ontologyIRI.isPresent()) { + if (EcoMapper.ECO_PURL_IRI.equals(ontologyIRI.get())) { + eco = owlOntology; + } + } + } + if (eco == null) { + throw new IllegalArgumentException("The specified graph did not contain ECO with the IRI: "+EcoMapper.ECO_PURL_IRI); + } + + MinervaOWLGraphWrapper ecoGraph = new MinervaOWLGraphWrapper(eco); + Reader reader = null; + try { + reader = createReader(EcoMapper.ECO_MAPPING_PURL); + EcoMappings mappings = loadEcoMappings(reader, ecoGraph); + return new TraversingEcoMapperImpl(mappings, reasoner, disposeReasoner); + } + finally { + IOUtils.closeQuietly(reader); + } + } + + static Reader createReader(String src) throws IOException { + if (src.indexOf(':') > 0) { + // assume its an url + URL url = new URL(src); + return loadUrl(url); + } + + // treat as file + File file = new File(src); + return new FileReader(file); + } + + private static Reader loadUrl(URL url) throws IOException { + final HttpURLConnection connection; + InputStream response = null; + // setup and open (actual connection) + try { + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(true); // warning does not follow redirects from http to https + response = connection.getInputStream(); // opens the connection to the server + } + catch (IOException e) { + IOUtils.closeQuietly(response); + throw e; + } + // check status code + final int status; + try { + status = connection.getResponseCode(); + } catch (IOException e) { + IOUtils.closeQuietly(response); + throw e; + } + if (HttpURLConnection.HTTP_MOVED_PERM == status || HttpURLConnection.HTTP_MOVED_TEMP == status) { + String location; + try { + location = connection.getHeaderField("Location"); + } finally { + IOUtils.closeQuietly(response); + } + if (location == null) { + throw new IOException("Could not follow redirect, missing header/no value for header 'Location'"); + } + URL next = new URL(url, location); // Deal with relative URLs + + return loadUrl(next); + } + // handle unexpected status code + if (status != 200) { + // try to check error stream + String errorMsg = getErrorMsg(connection); + + // construct message for exception + StringBuilder sb = new StringBuilder("Unexpected HTTP status code: "+status); + + if (errorMsg != null) { + sb.append(" Details: "); + sb.append(errorMsg); + } + throw new IOException(sb.toString()); + } + + // try to detect charset + String contentType = connection.getHeaderField("Content-Type"); + String charset = null; + + if (contentType != null) { + for (String param : contentType.replace(" ", "").split(";")) { + if (param.startsWith("charset=")) { + charset = param.split("=", 2)[1]; + break; + } + } + } + + // get string response from stream + String string; + try { + if (charset != null) { + string = IOUtils.toString(response, charset); + } + else { + string = IOUtils.toString(response); + } + } catch (IOException e) { + throw e; + } + finally { + IOUtils.closeQuietly(response); + } + return new StringReader(string); + } + + private static String getErrorMsg(HttpURLConnection connection) { + String errorMsg = null; + InputStream errorStream = null; + try { + errorStream = connection.getErrorStream(); + if (errorStream != null) { + errorMsg =IOUtils.toString(errorStream); + } + errorMsg = StringUtils.trimToNull(errorMsg); + } + catch (IOException e) { + // ignore errors, while trying to retrieve the error message + } + finally { + IOUtils.closeQuietly(errorStream); + } + return errorMsg; + } + + static TraversingEcoMapper createTraversingEcoMapper(Reader mappingsReader, MinervaOWLGraphWrapper eco, OWLReasoner reasoner, boolean disposeReasoner) throws IOException, OWLException { + EcoMappings mappings = loadEcoMappings(mappingsReader, eco); + return new TraversingEcoMapperImpl(mappings, reasoner, disposeReasoner); + } + + private static EcoMappings loadEcoMappings(Reader mappingsReader, MinervaOWLGraphWrapper eco) throws IOException { + EcoMappings mappings = new EcoMappings(); + List lines = IOUtils.readLines(mappingsReader); + for (String line : lines) { + line = StringUtils.trimToNull(line); + if (line != null) { + char c = line.charAt(0); + if ('#' != c) { + String[] split = StringUtils.split(line, '\t'); + if (split.length == 3) { + String code = split[0]; + String ref = split[1]; + String ecoId = split[2]; + OWLClass cls = eco.getOWLClassByIdentifier(ecoId); + if (cls != null) { + mappings.add(code, ref, cls); + } + } + } + } + } + return mappings; + } + + private static SimpleEcoMapper createSimpleMapper(Reader mappingsReader) throws IOException { + EcoMappings mappings = loadEcoMappings(mappingsReader); + return new SimpleEcoMapperImpl(mappings); + } + + private static EcoMappings loadEcoMappings(Reader mappingsReader) throws IOException { + EcoMappings mappings = new EcoMappings(); + List lines = IOUtils.readLines(mappingsReader); + for (String line : lines) { + line = StringUtils.trimToNull(line); + if (line != null) { + char c = line.charAt(0); + if ('#' != c) { + String[] split = StringUtils.split(line, '\t'); + if (split.length == 3) { + String code = split[0]; + String ref = split[1]; + String ecoId = split[2]; + mappings.add(code, ref, ecoId); + } + } + } + } + return mappings; + } + + /** + * Helper to access the mapping for ECO codes. ECO codes should always have + * a 'Default' mapping. Optionally, they have additional mappings for + * specific annotation references. + * + * @param + */ + static class EcoMappings { + + static final String DEFAULT_REF = "Default"; + + private final Map> allMappings = new HashMap>(); + + void add(String code, String ref, T cls) { + Map codeMap = allMappings.get(code); + if (codeMap == null) { + codeMap = new HashMap(); + allMappings.put(code, codeMap); + } + if (ref == null) { + ref = DEFAULT_REF; + } + codeMap.put(ref, cls); + } + + T get(String code, String ref) { + T result = null; + if (code != null) { + Map codeMap = allMappings.get(code); + if (codeMap != null) { + if (ref == null) { + ref = DEFAULT_REF; + } + result = codeMap.get(ref); + } + } + return result; + } + + T get(String code) { + return get(code, DEFAULT_REF); + } + + Set getAll(String code) { + Set result = new HashSet(); + if (code != null) { + Map codeMap = allMappings.get(code); + if (codeMap != null) { + result.addAll(codeMap.values()); + } + } + return result; + } + + boolean hasCode(String code) { + return allMappings.containsKey(code); + } + + Map> getReverseMap() { + Map> reverseMap = new HashMap>(); + for(Entry> e : allMappings.entrySet()) { + Map codeMap = e.getValue(); + for(Entry codeEntry : codeMap.entrySet()) { + T eco = codeEntry.getValue(); + String ref = codeEntry.getKey(); + if (DEFAULT_REF.equals(ref)) { + ref = null; + } + reverseMap.put(eco, Pair.of(e.getKey(), ref)); + } + } + return reverseMap; + } + } +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperImpl.java b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperImpl.java new file mode 100644 index 00000000..bd597737 --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/EcoMapperImpl.java @@ -0,0 +1,53 @@ +package owltools.gaf.eco; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.tuple.Pair; +import org.semanticweb.owlapi.model.OWLClass; + +public class EcoMapperImpl implements EcoMapper { + + private final EcoMapperFactory.EcoMappings mappings; + + EcoMapperImpl(EcoMapperFactory.EcoMappings mappings) { + this.mappings = mappings; + } + + @Override + public OWLClass getEcoClassForCode(String code) { + return mappings.get(code); + } + + @Override + public Set getAllEcoClassesForCode(String code) { + return mappings.getAll(code); + } + + @Override + public OWLClass getEcoClassForCode(String code, String refCode) { + return mappings.get(code, refCode); + } + + @Override + public boolean isGoEvidenceCode(String code) { + return mappings.hasCode(code); + } + + @Override + public Map getCodesForEcoClasses() { + Map> fullReverseMap = mappings.getReverseMap(); + Map simpleReverseMap = new HashMap(); + for(Entry> e : fullReverseMap.entrySet()) { + String ref = e.getValue().getRight(); + if (ref == null) { + simpleReverseMap.put(e.getKey(), e.getValue().getLeft()); + } + + } + return simpleReverseMap; + } + +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapper.java b/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapper.java new file mode 100644 index 00000000..61b82bcf --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapper.java @@ -0,0 +1,14 @@ +package owltools.gaf.eco; + +import java.util.Collection; + +import org.apache.commons.lang3.tuple.Pair; + +public interface SimpleEcoMapper { + + public String getEco(String goCode, String ref); + + public String getEco(String goCode, Collection allRefs); + + public Pair getGoCode(String eco); +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapperImpl.java b/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapperImpl.java new file mode 100644 index 00000000..939c2c09 --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/SimpleEcoMapperImpl.java @@ -0,0 +1,42 @@ +package owltools.gaf.eco; + +import java.util.Collection; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Pair; + +import owltools.gaf.eco.EcoMapperFactory.EcoMappings; + +public class SimpleEcoMapperImpl implements SimpleEcoMapper { + + private final EcoMapperFactory.EcoMappings mappings; + private final Map> reverseMap; + + SimpleEcoMapperImpl(EcoMappings mappings) { + this.mappings = mappings; + reverseMap = mappings.getReverseMap(); + } + + @Override + public String getEco(String goCode, String ref) { + return mappings.get(goCode, ref); + } + + @Override + public String getEco(String goCode, Collection allRefs) { + String eco = null; + for (String ref : allRefs) { + eco = mappings.get(goCode, ref); + if (eco != null) { + break; + } + } + return eco; + } + + @Override + public Pair getGoCode(String eco) { + return reverseMap.get(eco); + } + +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapper.java b/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapper.java new file mode 100644 index 00000000..f8f632fe --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapper.java @@ -0,0 +1,70 @@ +package owltools.gaf.eco; + +import java.util.Set; + +import org.semanticweb.owlapi.model.OWLClass; + +public interface TraversingEcoMapper extends EcoMapper { + + /** + * Traversing method for the ECO ontology. + * + * @param sources + * @param reflexive + * @return set of super classes + */ + public Set getAncestors(Set sources, boolean reflexive); + + /** + * Traversing method for the ECO ontology. + * + * @param source + * @param reflexive + * @return set of super classes + */ + public Set getAncestors(OWLClass source, boolean reflexive); + + /** + * Traversing method for the ECO ontology. + * + * @param sources + * @param reflexive + * @return set of sub classes + */ + public Set getDescendents(Set sources, boolean reflexive); + + /** + * Traversing method for the ECO ontology. + * + * @param source + * @param reflexive + * @return set of sub classes + */ + public Set getDescendents(OWLClass source, boolean reflexive); + + + /** + * Get all strings which are valid identifiers for a given evidence code. + * This includes, the the codes itself and valid OBO-style identifier from ECO. + * + * @param code + * @param includeChildren + * @return set of ids + */ + public Set getAllValidEvidenceIds(String code, boolean includeChildren); + + /** + * Get all strings which are valid identifiers for the given evidence codes. + * This includes, the the codes itself and valid OBO-style identifier from ECO. + * + * @param codes + * @param includeChildren + * @return set of ids + */ + public Set getAllValidEvidenceIds(Set codes, boolean includeChildren); + + /** + * Dispose this instance + */ + public void dispose(); +} diff --git a/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapperImpl.java b/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapperImpl.java new file mode 100644 index 00000000..4b0064f3 --- /dev/null +++ b/minerva-core/src/main/java/owltools/gaf/eco/TraversingEcoMapperImpl.java @@ -0,0 +1,125 @@ +package owltools.gaf.eco; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +//import org.obolibrary.obo2owl.Owl2Obo; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.reasoner.OWLReasoner; + +import owltools.gaf.eco.EcoMapperFactory.EcoMappings; +import owltools.util.OwlHelper; + +public class TraversingEcoMapperImpl extends EcoMapperImpl implements TraversingEcoMapper { + + private final OWLReasoner reasoner; + private final boolean disposeReasoner; + + private final Map> mappingCache = new HashMap>(); + + TraversingEcoMapperImpl(EcoMappings mappings, OWLReasoner reasoner, boolean disposeReasoner) { + super(mappings); + this.reasoner = reasoner; + this.disposeReasoner = disposeReasoner; + } + + @Override + public Set getAncestors(Set sources, boolean reflexive) { + if (sources == null || sources.isEmpty()) { + return Collections.emptySet(); + } + Set result = new HashSet(); + for (OWLClass source : sources) { + Set set = reasoner.getSuperClasses(source, false).getFlattened(); + for (OWLClass cls : set) { + if (cls.isBuiltIn() == false) { + result.add(cls); + } + } + } + if (reflexive) { + result.addAll(sources); + } + if (result.isEmpty()) { + return Collections.emptySet(); + } + return result; + } + + @Override + public Set getAncestors(OWLClass source, boolean reflexive) { + return getAncestors(Collections.singleton(source), reflexive); + } + + @Override + public Set getDescendents(Set sources, boolean reflexive) { + if (sources == null || sources.isEmpty()) { + return Collections.emptySet(); + } + Set result = new HashSet(); + for (OWLClass source : sources) { + Set set = reasoner.getSubClasses(source, false).getFlattened(); + for (OWLClass cls : set) { + if (cls.isBuiltIn() == false) { + result.add(cls); + } + } + } + if (reflexive) { + result.addAll(sources); + } + if (result.isEmpty()) { + return Collections.emptySet(); + } + return result; + } + + @Override + public Set getDescendents(OWLClass source, boolean reflexive) { + return getDescendents(Collections.singleton(source), reflexive); + } + + @Override + public Set getAllValidEvidenceIds(String code, boolean includeChildren) { + return getAllValidEvidenceIds(Collections.singleton(code), includeChildren); + } + + @Override + public Set getAllValidEvidenceIds(Set codes, boolean includeChildren) { + if (codes == null || codes.isEmpty()) { + return Collections.emptySet(); + } + Set result = new HashSet(); + for(String code : codes) { + Set classes = getAllEcoClassesForCode(code); + for (OWLClass owlClass : classes) { + result.add(getId(owlClass)); + } + if (includeChildren) { + Set descendents = getDescendents(classes, false); + for (OWLClass owlClass : descendents) { + result.add(getId(owlClass)); + } + } + } + result.addAll(codes); + return result; + } + + private String getId(OWLClass cls) { + //return Owl2Obo.getIdentifier(cls.getIRI()); + return OwlHelper.getIdentifier(cls.getIRI(), null); + } + + @Override + public void dispose() { + mappingCache.clear(); + if (disposeReasoner) { + reasoner.dispose(); + } + } + +} diff --git a/minerva-core/src/main/java/owltools/io/CatalogXmlIRIMapper.java b/minerva-core/src/main/java/owltools/io/CatalogXmlIRIMapper.java new file mode 100644 index 00000000..4aa45e21 --- /dev/null +++ b/minerva-core/src/main/java/owltools/io/CatalogXmlIRIMapper.java @@ -0,0 +1,187 @@ +package owltools.io; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import org.apache.log4j.Logger; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLOntologyIRIMapper; +import org.xml.sax.Attributes; +import org.xml.sax.SAXException; +import org.xml.sax.helpers.DefaultHandler; + +/** + * {@link OWLOntologyIRIMapper} using the mappings from a catalog.xml file. + */ +public class CatalogXmlIRIMapper implements OWLOntologyIRIMapper { + + private static final Logger logger = Logger.getLogger(CatalogXmlIRIMapper.class); + + private final Map mappings; + + CatalogXmlIRIMapper(Map mappings) { + this.mappings = mappings; + } + + /** + * Create an CatalogXmlIRIMapper from the given catalog.xml file. + * Assume, that relative paths are relative to the catalog file location. + * + * @param catalogFile + * @throws IOException + */ + public CatalogXmlIRIMapper(String catalogFile) throws IOException { + this(new File(catalogFile).getAbsoluteFile()); + } + + /** + * Create an CatalogXmlIRIMapper from the given catalog.xml file. + * Assume, that relative paths are relative to the catalog file location. + * + * @param catalogFile + * @throws IOException + */ + public CatalogXmlIRIMapper(File catalogFile) throws IOException { + this(catalogFile, catalogFile.getAbsoluteFile().getParentFile()); + } + + /** + * Create an CatalogXmlIRIMapper from the given catalog.xml file. + * Use the parentFolder to resolve relative paths from the catalog file. + * + * @param catalogFile + * @param parentFolder + * @throws IOException + */ + public CatalogXmlIRIMapper(File catalogFile, File parentFolder) throws IOException { + this(parseCatalogXml(new FileInputStream(catalogFile), parentFolder)); + } + + /** + * Create an CatalogXmlIRIMapper from the given catalog URL. + * Assume, there are no relative paths in the catalog file. + * + * @param catalogURL + * @throws IOException + */ + public CatalogXmlIRIMapper(URL catalogURL) throws IOException { + if ("file".equals(catalogURL.getProtocol())) { + try { + File catalogFile = new File(catalogURL.toURI()); + mappings = parseCatalogXml(new FileInputStream(catalogFile), catalogFile.getParentFile()); + } catch (URISyntaxException e) { + throw new IOException(e); + } + } + else { + mappings = parseCatalogXml(catalogURL.openStream(), null); + } + } + + /** + * Create an CatalogXmlIRIMapper from the given catalog URL. + * Use the parentFolder to resolve relative paths from the catalog file. + * + * @param catalogURL + * @param parentFolder + * @throws IOException + */ + public CatalogXmlIRIMapper(URL catalogURL, File parentFolder) throws IOException { + this(parseCatalogXml(catalogURL.openStream(), parentFolder)); + } + + @Override + public IRI getDocumentIRI(IRI ontologyIRI) { + return mappings.get(ontologyIRI); + } + + public Map getMappings() { + return Collections.unmodifiableMap(mappings); + } + + /** + * Parse the inputStream as a catalog.xml file and extract IRI mappings. + * + * Optional: Resolve relative file paths with the given parent folder. + * + * @param inputStream input stream (never null) + * @param parentFolder folder or null + * @return mappings + * @throws IOException + * @throws IllegalArgumentException if input stream is null + */ + static Map parseCatalogXml(InputStream inputStream, final File parentFolder) throws IOException { + if (inputStream == null) { + throw new IllegalArgumentException("InputStream should never be null, missing resource?"); + } + + // use the Java built-in SAX parser + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setValidating(false); + + try { + final Map mappings = new HashMap(); + SAXParser saxParser = factory.newSAXParser(); + saxParser.parse(inputStream, new DefaultHandler(){ + + @Override + public void startElement(String uri, String localName, + String qName, Attributes attributes) + throws SAXException + { + // only look at 'uri' tags + // does not check any parent tags + if ("uri".equals(qName)) { + IRI original = null; + IRI mapped = null; + String nameString = attributes.getValue("name"); + if (nameString != null) { + original = IRI.create(nameString); + } + String mappedString = attributes.getValue("uri"); + if (mappedString != null) { + if (parentFolder != null && mappedString.indexOf(":") < 0) { + // there is a parent folder and the mapping is not an IRI or URL + File file = new File(mappedString); + if (!file.isAbsolute()) { + file = new File(parentFolder, mappedString); + } + try { + file = file.getCanonicalFile(); + mapped = IRI.create(file); + } catch (IOException e) { + logger.warn("Skipping mapping: "+nameString+" "+mappedString, e); + } + } + else { + mapped = IRI.create(mappedString); + } + } + + if (original != null && mapped != null) { + mappings.put(original, mapped); + } + } + } + }); + return mappings; + } catch (ParserConfigurationException e) { + throw new IOException(e); + } catch (SAXException e) { + throw new IOException(e); + } finally { + inputStream.close(); + } + } +} diff --git a/minerva-core/src/main/java/owltools/io/ParserWrapper.java b/minerva-core/src/main/java/owltools/io/ParserWrapper.java new file mode 100644 index 00000000..002ee1e9 --- /dev/null +++ b/minerva-core/src/main/java/owltools/io/ParserWrapper.java @@ -0,0 +1,383 @@ +package owltools.io; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.apache.commons.io.IOUtils; +import org.apache.log4j.Logger; +import org.apache.log4j.lf5.util.StreamUtils; +import org.geneontology.minerva.MinervaOWLGraphWrapper; +import org.obolibrary.oboformat.model.Frame; +import org.obolibrary.oboformat.model.OBODoc; +import org.obolibrary.oboformat.parser.OBOFormatConstants.OboFormatTag; +import org.obolibrary.oboformat.writer.OBOFormatWriter; +import org.obolibrary.oboformat.writer.OBOFormatWriter.NameProvider; +import org.obolibrary.oboformat.writer.OBOFormatWriter.OBODocNameProvider; +import org.semanticweb.owlapi.apibinding.OWLManager; +import org.semanticweb.owlapi.formats.OBODocumentFormat; +import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLDocumentFormat; +import org.semanticweb.owlapi.model.OWLObject; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyAlreadyExistsException; +import org.semanticweb.owlapi.model.OWLOntologyCreationException; +import org.semanticweb.owlapi.model.OWLOntologyDocumentAlreadyExistsException; +import org.semanticweb.owlapi.model.OWLOntologyID; +import org.semanticweb.owlapi.model.OWLOntologyIRIMapper; +import org.semanticweb.owlapi.model.OWLOntologyLoaderListener; +import org.semanticweb.owlapi.model.OWLOntologyManager; +import org.semanticweb.owlapi.model.OWLOntologyStorageException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.google.common.base.Optional; + +/** + * Convenience class wrapping org.oboformat that abstracts away underlying details of ontology format or location + * @author cjm + * + */ +public class ParserWrapper { + + private static Logger LOG = Logger.getLogger(ParserWrapper.class); + OWLOntologyManager manager; + private final List mappers = new ArrayList(); + OBODoc obodoc; + boolean isCheckOboDoc = true; + + + public ParserWrapper() { + manager = OWLManager.createOWLOntologyManager(); + OWLOntologyLoaderListener listener = new OWLOntologyLoaderListener() { + + // generated + private static final long serialVersionUID = 8475800207882525640L; + + @Override + public void startedLoadingOntology(LoadingStartedEvent event) { + IRI id = event.getOntologyID().getOntologyIRI().orNull(); + IRI source = event.getDocumentIRI(); + LOG.info("Start loading ontology: "+id+" from: "+source); + } + + @Override + public void finishedLoadingOntology(LoadingFinishedEvent event) { + IRI id = event.getOntologyID().getOntologyIRI().orNull(); + IRI source = event.getDocumentIRI(); + LOG.info("Finished loading ontology: "+id+" from: "+source); + } + }; + manager.addOntologyLoaderListener(listener); + } + + public OWLOntologyManager getManager() { + return manager; + } + public void setManager(OWLOntologyManager manager) { + this.manager = manager; + } + + public boolean isCheckOboDoc() { + return isCheckOboDoc; + } + + public void setCheckOboDoc(boolean isCheckOboDoc) { + this.isCheckOboDoc = isCheckOboDoc; + } + + public void addIRIMapper(OWLOntologyIRIMapper mapper) { + manager.getIRIMappers().add(mapper); + mappers.add(0, mapper); + } + public void removeIRIMapper(OWLOntologyIRIMapper mapper) { + manager.getIRIMappers().remove(mapper); + mappers.remove(mapper); + } + public List getIRIMappers() { + return Collections.unmodifiableList(mappers); + } + public void addIRIMappers(List mappers) { + List reverse = new ArrayList(mappers); + Collections.reverse(reverse); + for (OWLOntologyIRIMapper mapper : reverse) { + addIRIMapper(mapper); + } + } + + public MinervaOWLGraphWrapper parseToOWLGraph(String iriString) throws OWLOntologyCreationException, IOException { + return new MinervaOWLGraphWrapper(parse(iriString)); + } + + public OWLOntology parse(String iriString) throws OWLOntologyCreationException, IOException { + return parseOWL(iriString); + } + + public OWLOntology parseOBO(String source) throws IOException, OWLOntologyCreationException { + return parseOWL(source); + } + + public OWLOntology parseOWL(String iriString) throws OWLOntologyCreationException { + IRI iri; + if (LOG.isDebugEnabled()) { + LOG.debug("parsing: "+iriString); + } + if (isIRI(iriString)) { + iri = IRI.create(iriString); + } + else { + iri = IRI.create(new File(iriString)); + } + return parseOWL(iri); + } + + private boolean isIRI(String iriString) { + return iriString.startsWith("file:") || iriString.startsWith("http:") || iriString.startsWith("https:"); + } + + public OWLOntology parseOWL(IRI iri) throws OWLOntologyCreationException { + if (LOG.isDebugEnabled()) { + LOG.debug("parsing: "+iri.toString()+" using "+manager); + } + OWLOntology ont; + try { + ont = manager.loadOntology(iri); + } catch (OWLOntologyAlreadyExistsException e) { + // Trying to recover from exception + OWLOntologyID ontologyID = e.getOntologyID(); + ont = manager.getOntology(ontologyID); + if (ont == null) { + // throw original exception, if no ontology could be found + // never return null ontology + throw e; + } + LOG.info("Skip already loaded ontology: "+iri); + } catch (OWLOntologyDocumentAlreadyExistsException e) { + // Trying to recover from exception + IRI duplicate = e.getOntologyDocumentIRI(); + ont = manager.getOntology(duplicate); + if (ont == null) { + for(OWLOntology managed : manager.getOntologies()) { + Optional managedIRI = managed.getOntologyID().getOntologyIRI(); + if(managedIRI.isPresent() && duplicate.equals(managedIRI.get())) { + LOG.info("Skip already loaded ontology: "+iri); + ont = managed; + break; + } + } + } + if (ont == null) { + // throw original exception, if no ontology could be found + // never return null ontology + throw e; + } + } + return ont; + } + +// public void saveOWL(OWLOntology ont, String file) throws OWLOntologyStorageException, IOException { +// OWLDocumentFormat owlFormat = new RDFXMLDocumentFormat(); +// saveOWL(ont, owlFormat, file); +// } +// public void saveOWL(OWLOntology ont, OWLDocumentFormat owlFormat, String file) throws OWLOntologyStorageException, IOException { +// if ((owlFormat instanceof OBODocumentFormat) || +// (owlFormat instanceof OWLOboGraphsFormat) || +// (owlFormat instanceof OWLOboGraphsYamlFormat) || +// (owlFormat instanceof OWLJSONFormat) || +// (owlFormat instanceof OWLJsonLDFormat)){ +// try { +// FileOutputStream os = new FileOutputStream(new File(file)); +// saveOWL(ont, owlFormat, os); +// } catch (FileNotFoundException e) { +// throw new OWLOntologyStorageException("Could not open file: "+file, e); +// } +// } +// else { +// IRI iri; +// if (file.startsWith("file://")) { +// iri = IRI.create(file); +// } +// else { +// iri = IRI.create(new File(file)); +// } +// manager.saveOntology(ont, owlFormat, iri); +// } +// } +// public void saveOWL(OWLOntology ont, OWLDocumentFormat owlFormat, +// OutputStream outputStream) throws OWLOntologyStorageException, IOException { +// if (owlFormat instanceof OBODocumentFormat && this.isCheckOboDoc == false) { +// // special work-around for skipping the OBO validation before write +// // see also OWL-API issue: https://github.com/owlcs/owlapi/issues/290 +// // see also saveOWL(OWLOntology, OWLOntologyFormat, String) for redundant code +// Owl2Obo bridge = new Owl2Obo(); +// OBODoc doc; +// BufferedWriter bw = null; +// try { +// doc = bridge.convert(ont); +// OBOFormatWriter oboWriter = new OBOFormatWriter(); +// oboWriter.setCheckStructure(isCheckOboDoc); +// bw = new BufferedWriter(new OutputStreamWriter(outputStream)); +// oboWriter.write(doc, bw); +// } catch (IOException e) { +// throw new OWLOntologyStorageException("Could not write ontology to output stream.", e); +// } +// finally { +// IOUtils.closeQuietly(bw); +// } +// } +// else if (owlFormat instanceof OWLJSONFormat) { +// +// BufferedWriter bw = null; +// try { +// bw = new BufferedWriter(new OutputStreamWriter(outputStream)); +// OWLGsonRenderer gr = new OWLGsonRenderer(new PrintWriter(outputStream)); +// gr.render(ont); +// gr.flush(); +// } +// finally { +// IOUtils.closeQuietly(bw); +// } +// } +// else if (owlFormat instanceof OWLOboGraphsFormat || owlFormat instanceof OWLOboGraphsYamlFormat) { +// +// // TODO: +// FromOwl fromOwl = new FromOwl(); +// GraphDocument gd = fromOwl.generateGraphDocument(ont); +// String out; +// if (owlFormat instanceof OWLOboGraphsFormat) +// out = OgJsonGenerator.render(gd); +// else +// out = OgYamlGenerator.render(gd); +// BufferedWriter bw = null; +// try { +// bw = new BufferedWriter(new OutputStreamWriter(outputStream)); +// bw.write(out); +// } +// finally { +// IOUtils.closeQuietly(bw); +// } +// +// } +// else if (owlFormat instanceof OWLJsonLDFormat) { +// +// //JsonLdStorer.register(manager); // Needed once per ontologyManager +// +// //TODO: fix this after https://github.com/stain/owlapi-jsonld/issues/4 +// //manager.saveOntology(ont, new JsonLdOntologyFormat(), outputStream); +// +// } +// else { +// manager.saveOntology(ont, owlFormat, outputStream); +// } +// } +// +// public OBODoc getOBOdoc() { +// return obodoc; +// } + + /** + * Provide names for the {@link OBOFormatWriter} using an + * {@link MinervaOWLGraphWrapper}. + * + * @see OboAndOwlNameProvider use the {@link OboAndOwlNameProvider}, the + * pure OWL lookup is problematic for relations. + */ + public static class OWLGraphWrapperNameProvider implements NameProvider { + private final MinervaOWLGraphWrapper graph; + private final String defaultOboNamespace; + + /** + * @param graph + */ + public OWLGraphWrapperNameProvider(MinervaOWLGraphWrapper graph) { + super(); + this.graph = graph; + this.defaultOboNamespace = null; + + } + + /** + * @param graph + * @param defaultOboNamespace + */ + public OWLGraphWrapperNameProvider(MinervaOWLGraphWrapper graph, String defaultOboNamespace) { + super(); + this.graph = graph; + this.defaultOboNamespace = defaultOboNamespace; + + } + + /** + * @param graph + * @param oboDoc + * + * If an {@link OBODoc} is available use {@link OboAndOwlNameProvider}. + */ + @Deprecated + public OWLGraphWrapperNameProvider(MinervaOWLGraphWrapper graph, OBODoc oboDoc) { + super(); + this.graph = graph; + String defaultOboNamespace = null; + if (oboDoc != null) { + Frame headerFrame = oboDoc.getHeaderFrame(); + if (headerFrame != null) { + defaultOboNamespace = headerFrame.getTagValue(OboFormatTag.TAG_DEFAULT_NAMESPACE, String.class); + } + } + this.defaultOboNamespace = defaultOboNamespace; + + } + + @Override + public String getName(String id) { + String name = null; + OWLObject obj = graph.getOWLObjectByIdentifier(id); + if (obj != null) { + name = graph.getLabel(obj); + } + return name; + } + + @Override + public String getDefaultOboNamespace() { + return defaultOboNamespace; + } + } + + /** + * Provide names for the {@link OBOFormatWriter} using an {@link OBODoc} + * first and an {@link MinervaOWLGraphWrapper} as secondary. + */ + public static class OboAndOwlNameProvider extends OBODocNameProvider { + + private final MinervaOWLGraphWrapper graph; + + public OboAndOwlNameProvider(OBODoc oboDoc, MinervaOWLGraphWrapper wrapper) { + super(oboDoc); + this.graph = wrapper; + } + + @Override + public String getName(String id) { + String name = super.getName(id); + if (name != null) { + return name; + } + OWLObject owlObject = graph.getOWLObjectByIdentifier(id); + if (owlObject != null) { + name = graph.getLabel(owlObject); + } + return name; + } + + } + +} \ No newline at end of file diff --git a/minerva-core/src/main/java/owltools/util/OwlHelper.java b/minerva-core/src/main/java/owltools/util/OwlHelper.java new file mode 100644 index 00000000..7c90fa5f --- /dev/null +++ b/minerva-core/src/main/java/owltools/util/OwlHelper.java @@ -0,0 +1,373 @@ +package owltools.util; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +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.OWLClass; +import org.semanticweb.owlapi.model.OWLClassAssertionAxiom; +import org.semanticweb.owlapi.model.OWLClassExpression; +import org.semanticweb.owlapi.model.OWLEntity; +import org.semanticweb.owlapi.model.OWLEquivalentClassesAxiom; +import org.semanticweb.owlapi.model.OWLIndividual; +import org.semanticweb.owlapi.model.OWLNamedIndividual; +import org.semanticweb.owlapi.model.OWLObjectPropertyAssertionAxiom; +import org.semanticweb.owlapi.model.OWLObjectPropertyExpression; +import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLSubAnnotationPropertyOfAxiom; +import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; +import org.semanticweb.owlapi.model.OWLSubObjectPropertyOfAxiom; +import org.semanticweb.owlapi.model.OWLSubPropertyAxiom; + +public class OwlHelper { + + private OwlHelper() { + // no instances + } + + public static Set getAnnotations(OWLEntity e, OWLAnnotationProperty property, OWLOntology ont) { + Set annotations; + if (e != null && property != null && ont != null) { + annotations = new HashSet<>(); + for (OWLAnnotationAssertionAxiom ax : ont.getAnnotationAssertionAxioms(e.getIRI())) { + if (property.equals(ax.getProperty())) { + annotations.add(ax.getAnnotation()); + } + } + } + else { + annotations = Collections.emptySet(); + } + return annotations; + } + + public static Set getAnnotations(OWLEntity e, OWLOntology ont) { + Set annotations; + if (e != null && ont != null) { + Set axioms = ont.getAnnotationAssertionAxioms(e.getIRI()); + annotations = new HashSet<>(axioms.size()); + for(OWLAnnotationAssertionAxiom ax : axioms) { + annotations.add(ax.getAnnotation()); + } + } + else { + annotations = Collections.emptySet(); + } + return annotations; + } + + public static Set getAnnotations(OWLEntity e, Set ontolgies) { + Set annotations; + if (e != null && ontolgies != null && !ontolgies.isEmpty()) { + annotations = new HashSet<>(); + for(OWLOntology ont : ontolgies) { + annotations.addAll(getAnnotations(e, ont)); + } + } + else { + annotations = Collections.emptySet(); + } + return annotations; + } + + public static Set getEquivalentClasses(OWLClass cls, OWLOntology ont) { + Set expressions; + if (cls != null && ont != null) { + Set axioms = ont.getEquivalentClassesAxioms(cls); + expressions = new HashSet<>(axioms.size()); + for(OWLEquivalentClassesAxiom ax : axioms) { + expressions.addAll(ax.getClassExpressions()); + } + expressions.remove(cls); // set should not contain the query cls + } + else { + expressions = Collections.emptySet(); + } + return expressions; + } + + public static Set getEquivalentClasses(OWLClass cls, Set ontologies) { + Set expressions; + if (cls != null && ontologies != null && ontologies.isEmpty() == false) { + expressions = new HashSet<>(); + for(OWLOntology ont : ontologies) { + expressions.addAll(getEquivalentClasses(cls, ont)); + } + } + else { + expressions = Collections.emptySet(); + } + return expressions; + } + + public static Set getSuperClasses(OWLClass subCls, OWLOntology ont) { + Set result; + if (subCls != null && ont != null) { + result = new HashSet<>(); + Set axioms = ont.getSubClassAxiomsForSubClass(subCls); + for (OWLSubClassOfAxiom axiom : axioms) { + result.add(axiom.getSuperClass()); + } + } + else { + result = Collections.emptySet(); + } + return result; + } + + public static Set getSuperClasses(OWLClass subCls, Set ontologies) { + Set result; + if (subCls != null && ontologies != null && ontologies.isEmpty() == false) { + result = new HashSet<>(); + for(OWLOntology ont : ontologies) { + result.addAll(getSuperClasses(subCls, ont)); + } + } + else { + result = Collections.emptySet(); + } + return result; + } + + public static Set getSubClasses(OWLClass superCls, OWLOntology ont) { + Set result; + if (superCls != null && ont != null) { + result = new HashSet<>(); + Set axioms = ont.getSubClassAxiomsForSuperClass(superCls); + for (OWLSubClassOfAxiom axiom : axioms) { + result.add(axiom.getSubClass()); + } + } + else { + result = Collections.emptySet(); + } + return result; + } + + public static Set getSubClasses(OWLClass superCls, Set ontologies) { + Set result; + if (superCls != null && ontologies != null && ontologies.isEmpty() == false) { + result = new HashSet<>(); + for(OWLOntology ont : ontologies) { + result.addAll(getSubClasses(superCls, ont)); + } + } + else { + result = Collections.emptySet(); + } + return result; + } + + public static Set getTypes(OWLIndividual i, OWLOntology ont) { + Set types; + if (ont != null && i != null && i.isNamed()) { + types = getTypes(i.asOWLNamedIndividual(), ont); + } + else { + types = Collections.emptySet(); + } + return types; + } + + public static Set getTypes(OWLNamedIndividual i, OWLOntology ont) { + Set types; + if (i != null && ont != null) { + types = new HashSet<>(); + for (OWLClassAssertionAxiom axiom : ont.getClassAssertionAxioms(i)) { + types.add(axiom.getClassExpression()); + } + } + else { + types = Collections.emptySet(); + } + return types; + } + + public static Set getTypes(OWLNamedIndividual i, Set ontologies) { + Set types; + if (i != null && ontologies != null && ontologies.isEmpty() == false) { + types = new HashSet<>(); + for(OWLOntology ont : ontologies) { + types.addAll(getTypes(i, ont)); + } + } + else { + types = Collections.emptySet(); + } + return types; + } + + public static Map> getObjectPropertyValues(OWLIndividual i, OWLOntology ont) { + Set axioms = ont.getObjectPropertyAssertionAxioms(i); + Map> result = new HashMap<>(); + for(OWLObjectPropertyAssertionAxiom ax : axioms) { + Set inds = result.get(ax.getProperty()); + if (inds == null) { + inds = new HashSet<>(); + result.put(ax.getProperty(), inds); + } + inds.add(ax.getObject()); + } + return result; + } + + public static boolean isTransitive(OWLObjectPropertyExpression property, OWLOntology ontology) { + return !ontology.getTransitiveObjectPropertyAxioms(property).isEmpty(); + } + + public static boolean isTransitive(OWLObjectPropertyExpression property, Set ontologies) { + for (OWLOntology ont : ontologies) { + if (isTransitive(property, ont)) { + return true; + } + } + return false; + } + + public static Set getSubProperties(OWLAnnotationProperty superProp, OWLOntology ont) { + return getSubProperties(superProp, Collections.singleton(ont)); + } + + public static Set getSubProperties(OWLAnnotationProperty superProp, Set ontologies) { + Set result = new HashSet(); + for (OWLOntology ont : ontologies) { + for (OWLSubAnnotationPropertyOfAxiom ax : ont.getAxioms(AxiomType.SUB_ANNOTATION_PROPERTY_OF)) { + if (ax.getSuperProperty().equals(superProp)) { + result.add(ax.getSubProperty()); + } + } + } + return result; + } + + public static Set getSuperProperties(OWLAnnotationProperty subProp, OWLOntology ont) { + return getSuperProperties(subProp, Collections.singleton(ont)); + } + + public static Set getSuperProperties(OWLAnnotationProperty subProp, Set ontologies) { + Set result = new HashSet(); + for (OWLOntology ont : ontologies) { + for (OWLSubAnnotationPropertyOfAxiom ax : ont.getAxioms(AxiomType.SUB_ANNOTATION_PROPERTY_OF)) { + if (ax.getSubProperty().equals(subProp)) { + result.add(ax.getSuperProperty()); + } + } + } + return result; + } + + public static Set getSuperProperties(OWLObjectPropertyExpression prop, OWLOntology ont) { + Set result = new HashSet<>(); + Set axioms = ont.getObjectSubPropertyAxiomsForSubProperty(prop); + for (OWLSubPropertyAxiom axiom : axioms) { + result.add(axiom.getSuperProperty()); + } + return result; + } + + public static Set getSubProperties(OWLObjectPropertyExpression prop, OWLOntology ont) { + Set results = new HashSet<>(); + Set axioms = ont.getObjectSubPropertyAxiomsForSuperProperty(prop); + for (OWLSubObjectPropertyOfAxiom axiom : axioms) { + results.add(axiom.getSubProperty()); + } + return results; + } + + public static String getIdentifier(IRI iriId, OWLOntology baseOntology) { + + if(iriId == null) + return null; + + String iri = iriId.toString(); + + /* + // canonical IRIs + if (iri.startsWith("http://purl.obolibrary.org/obo/")) { + String canonicalId = iri.replace("http://purl.obolibrary.org/obo/", ""); + } + */ + + int indexSlash = iri.lastIndexOf("/"); + + + String prefixURI = null; + String id = null; + + if(indexSlash>-1){ + prefixURI = iri.substring(0, indexSlash+1); + id = iri.substring(indexSlash+1); + }else + id = iri; + + String s[]= id.split("#_"); + + // table 5.9.2 row 2 - NonCanonical-Prefixed-ID + if(s.length>1){ + return s[0] + ":" + s[1]; + } + + // row 3 - Unprefixed-ID + s= id.split("#"); + if(s.length>1){ + // prefixURI = prefixURI + s[0] + "#"; + + // if(!(s[1].contains("#") || s[1].contains("_"))){ + String prefix = ""; + + if("owl".equals(s[0]) || "rdf".equals(s[0]) || "rdfs".equals(s[0])){ + prefix = s[0] + ":"; + } + // TODO: the following implements behavior in current spec, but this leads to undesirable results + /* + else if (baseOntology != null) { + String oid = getOntologyId(baseOntology); // OBO-style ID + if (oid.equals(s[0])) + prefix = ""; + else { + return iri; + } + //prefix = s[0]; + } + */ + + return prefix + s[1]; + } + + // row 1 - Canonical-Prefixed-ID + s= id.split("_"); + + if(s.length==2 && !id.contains("#") && !s[1].contains("_")){ + String localId = java.net.URLDecoder.decode(s[1]); + return s[0] + ":" + localId; + } + if(s.length > 2 && !id.contains("#")) { + if (s[s.length-1].replaceAll("[0-9]","").length() == 0) { + StringBuffer sb = new StringBuffer(); + for (int i=0; i < s.length; i++) { + if (i > 0) { + if (i == s.length -1) { + sb.append(":"); + } + else { + sb.append("_"); + } + } + sb.append(s[i]); + } + return sb.toString(); + } + } + + + return iri; + } + +} diff --git a/minerva-core/src/main/java/owltools/version/VersionInfo.java b/minerva-core/src/main/java/owltools/version/VersionInfo.java new file mode 100644 index 00000000..6e00f473 --- /dev/null +++ b/minerva-core/src/main/java/owltools/version/VersionInfo.java @@ -0,0 +1,50 @@ +package owltools.version; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.Enumeration; +import java.util.jar.Attributes; +import java.util.jar.JarFile; +import java.util.jar.Manifest; + +public class VersionInfo { + + private VersionInfo() { + // make constructor private + } + + /** + * Try to retrieve the value for the given key from a manifest file. + * Returns the first match or null, if it does not exist. + * + * @param key + * @return string value or null + */ + public static String getManifestVersion(String key) { + Enumeration resEnum; + try { + resEnum = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME); + while (resEnum.hasMoreElements()) { + try { + URL url = resEnum.nextElement(); + InputStream is = url.openStream(); + if (is != null) { + Manifest manifest = new Manifest(is); + Attributes mainAttribs = manifest.getMainAttributes(); + String version = mainAttribs.getValue(key); + if(version != null) { + return version; + } + } + } + catch (Exception exception) { + // Silently ignore problematic manifests in classpath + } + } + } catch (IOException ioException) { + // Silently ignore any IO issues with manifests + } + return null; + } +} diff --git a/minerva-core/src/main/java/owltools/vocab/OBONamespaces.java b/minerva-core/src/main/java/owltools/vocab/OBONamespaces.java new file mode 100644 index 00000000..b816f4f8 --- /dev/null +++ b/minerva-core/src/main/java/owltools/vocab/OBONamespaces.java @@ -0,0 +1,13 @@ +package owltools.vocab; + +public enum OBONamespaces { + GO("GO"), + BFO("BFO"), + GOREL("GOREL"), + RO("RO"); + + final String ns; + OBONamespaces(String ns) { + this.ns = ns; + } +} diff --git a/minerva-core/src/main/java/owltools/vocab/OBOUpperVocabulary.java b/minerva-core/src/main/java/owltools/vocab/OBOUpperVocabulary.java new file mode 100644 index 00000000..3fd88ede --- /dev/null +++ b/minerva-core/src/main/java/owltools/vocab/OBOUpperVocabulary.java @@ -0,0 +1,74 @@ +package owltools.vocab; + +import org.semanticweb.owlapi.model.IRI; +import org.semanticweb.owlapi.model.OWLClass; +import org.semanticweb.owlapi.model.OWLDataFactory; +import org.semanticweb.owlapi.model.OWLObjectProperty; +import org.semanticweb.owlapi.model.OWLOntology; + + +public enum OBOUpperVocabulary { + + /** + * + */ + GO_molecular_function(OBONamespaces.GO, "0003674"), + GO_biological_process(OBONamespaces.GO, "0008150"), + GO_cellular_process(OBONamespaces.GO, "0009987"), + BFO_part_of(OBONamespaces.BFO, "0000050"), + BFO_has_part(OBONamespaces.BFO, "0000051"), + BFO_occurs_in(OBONamespaces.BFO, "0000066"), + RO_regulates(OBONamespaces.RO, "0002211"), + RO_negatively_regulates(OBONamespaces.RO, "0002212"), + RO_positively_regulates(OBONamespaces.RO, "0002213"), + RO_starts(OBONamespaces.RO, "0002223"), + RO_ends(OBONamespaces.RO, "0002229"), + RO_gene_product_of(OBONamespaces.RO, "0002204"), + RO_involved_in(OBONamespaces.RO, "0002331"), + GOREL_enabled_by(OBONamespaces.RO, "0002333"), + GOREL_directly_provides_input_for(OBONamespaces.RO, "0002413"); + + + + + final IRI iri; + final OBONamespaces namespace; + final String id; + + public static final String OBO = "http://purl.obolibrary.org/obo/"; + + OBOUpperVocabulary(OBONamespaces ns, String id) { + this.namespace = ns; + this.id = id; + iri = IRI.create(OBO + ns + "_" + id); + } + + + + public IRI getIRI() { + return iri; + } + + + public OWLClass getOWLClass(OWLDataFactory f) { + return f.getOWLClass(iri); + } + public OWLClass getOWLClass(OWLOntology o) { + return getOWLClass(o.getOWLOntologyManager().getOWLDataFactory()); + } + + public OWLObjectProperty getObjectProperty(OWLDataFactory f) { + return f.getOWLObjectProperty(iri); + } + public OWLObjectProperty getObjectProperty(OWLOntology o) { + return getObjectProperty(o.getOWLOntologyManager().getOWLDataFactory()); + } + + @Override + public String toString() { + return iri.toString(); + } + + + +} diff --git a/minerva-core/src/test/java/org/geneontology/minerva/BlazegraphMolecularModelManagerTest.java b/minerva-core/src/test/java/org/geneontology/minerva/BlazegraphMolecularModelManagerTest.java index cc21f7fc..bd1a39d5 100644 --- a/minerva-core/src/test/java/org/geneontology/minerva/BlazegraphMolecularModelManagerTest.java +++ b/minerva-core/src/test/java/org/geneontology/minerva/BlazegraphMolecularModelManagerTest.java @@ -18,7 +18,7 @@ import org.openrdf.query.TupleQueryResult; import org.semanticweb.owlapi.apibinding.OWLManager; import org.semanticweb.owlapi.model.*; -import owltools.OWLToolsTestBasics; +//import owltools.OWLToolsTestBasics; import java.io.File; import java.io.FileInputStream; @@ -27,7 +27,7 @@ import static org.junit.Assert.*; -public class BlazegraphMolecularModelManagerTest extends OWLToolsTestBasics { +public class BlazegraphMolecularModelManagerTest { private final CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); @Rule diff --git a/minerva-core/src/test/java/org/geneontology/minerva/UndoAwareMolecularModelManagerTest.java b/minerva-core/src/test/java/org/geneontology/minerva/UndoAwareMolecularModelManagerTest.java index d3755651..3e472e62 100644 --- a/minerva-core/src/test/java/org/geneontology/minerva/UndoAwareMolecularModelManagerTest.java +++ b/minerva-core/src/test/java/org/geneontology/minerva/UndoAwareMolecularModelManagerTest.java @@ -24,13 +24,12 @@ import org.semanticweb.owlapi.model.OWLNamedIndividual; import org.semanticweb.owlapi.model.OWLOntology; -import owltools.OWLToolsTestBasics; -import owltools.graph.OWLGraphWrapper; + import owltools.io.ParserWrapper; -public class UndoAwareMolecularModelManagerTest extends OWLToolsTestBasics { +public class UndoAwareMolecularModelManagerTest { - static OWLGraphWrapper g = null; + static MinervaOWLGraphWrapper g = null; static CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); static UndoAwareMolecularModelManager m3 = null; diff --git a/minerva-core/src/test/java/org/geneontology/minerva/json/MolecularModelJsonRendererTest.java b/minerva-core/src/test/java/org/geneontology/minerva/json/MolecularModelJsonRendererTest.java index 6d1ea938..0e8d2f9a 100644 --- a/minerva-core/src/test/java/org/geneontology/minerva/json/MolecularModelJsonRendererTest.java +++ b/minerva-core/src/test/java/org/geneontology/minerva/json/MolecularModelJsonRendererTest.java @@ -10,6 +10,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; import org.geneontology.minerva.curie.CurieHandler; import org.geneontology.minerva.curie.DefaultCurieHandler; @@ -35,12 +36,11 @@ import org.semanticweb.owlapi.model.OWLOntology; import org.semanticweb.owlapi.model.OWLOntologyManager; -import owltools.graph.OWLGraphWrapper; import owltools.io.ParserWrapper; public class MolecularModelJsonRendererTest { - private static OWLGraphWrapper g = null; + private static MinervaOWLGraphWrapper g = null; private static CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); private static OWLOntologyManager m = null; private static OWLDataFactory f = null; @@ -51,7 +51,7 @@ public static void setUpBeforeClass() throws Exception { ParserWrapper pw = new ParserWrapper(); File file = new File("src/test/resources/mgi-go.obo").getCanonicalFile(); OWLOntology ont = pw.parseOWL(IRI.create(file)); - g = new OWLGraphWrapper(ont); + g = new MinervaOWLGraphWrapper(ont); f = g.getDataFactory(); m = g.getManager(); partOf = g.getOWLObjectPropertyByIdentifier("BFO:0000050"); @@ -162,7 +162,7 @@ private void testSimpleClassExpression(OWLClassExpression ce, String expectedJso assertNotNull(jsonOwlIndividualParse); assertEquals(jsonOwlIndividualOriginal, jsonOwlIndividualParse); - Set ces = TestJsonOwlObjectParser.parse(new OWLGraphWrapper(o), jsonOwlIndividualParse.type); + Set ces = TestJsonOwlObjectParser.parse(new MinervaOWLGraphWrapper(o), jsonOwlIndividualParse.type); assertEquals(1, ces.size()); assertEquals(ce, ces.iterator().next()); } @@ -231,7 +231,7 @@ private static void addFact(OWLOntology o, OWLNamedIndividual source, OWLNamedIn } static class TestJsonOwlObjectParser { - static OWLClassExpression parse(OWLGraphWrapper g, JsonOwlObject expression) + static OWLClassExpression parse(MinervaOWLGraphWrapper g, JsonOwlObject expression) throws Exception { if (expression == null) { throw new Exception("Missing expression: null is not a valid expression."); @@ -285,7 +285,7 @@ else if (JsonOwlObjectType.UnionOf == expression.type) { } } - static OWLClassExpression parse(OWLGraphWrapper g, JsonOwlObject[] expressions, JsonOwlObjectType type) + static OWLClassExpression parse(MinervaOWLGraphWrapper g, JsonOwlObject[] expressions, JsonOwlObjectType type) throws Exception { if (expressions.length == 0) { throw new Exception("Missing expressions: empty expression list is not allowed."); @@ -309,7 +309,7 @@ else if (type == JsonOwlObjectType.IntersectionOf) { } } - static Set parse(OWLGraphWrapper g, JsonOwlObject[] expressions) + static Set parse(MinervaOWLGraphWrapper g, JsonOwlObject[] expressions) throws Exception { if (expressions.length == 0) { throw new Exception("Missing expressions: empty expression list is not allowed."); diff --git a/minerva-lookup/pom.xml b/minerva-lookup/pom.xml index 047d92b1..2bb805c6 100644 --- a/minerva-lookup/pom.xml +++ b/minerva-lookup/pom.xml @@ -30,10 +30,6 @@ minerva-core ${project.parent.version} - - org.bbop - golr-client - diff --git a/minerva-lookup/src/main/java/org/bbop/golr/java/AbstractRetrieveGolr.java b/minerva-lookup/src/main/java/org/bbop/golr/java/AbstractRetrieveGolr.java new file mode 100644 index 00000000..9a2ab243 --- /dev/null +++ b/minerva-lookup/src/main/java/org/bbop/golr/java/AbstractRetrieveGolr.java @@ -0,0 +1,250 @@ +package org.bbop.golr.java; + +import java.io.IOException; +import java.io.InputStream; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; +import java.util.Random; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.http.client.utils.URIBuilder; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; + +public abstract class AbstractRetrieveGolr { + + protected static final Gson GSON = new GsonBuilder().create(); + + private final String server; + private int retryCount; + + public AbstractRetrieveGolr(String server) { + this(server, 3); + } + + public AbstractRetrieveGolr(String server, int retryCount) { + this.server = server; + this.retryCount = retryCount; + } + + protected abstract boolean isIndentJson(); + + protected abstract List getRelevantFields(); + + URI createGolrRequest(List tagvalues, String category, int start, int pagination) throws IOException { + try { + URIBuilder builder = new URIBuilder(server); + String currentPath = StringUtils.trimToEmpty(builder.getPath()); + builder.setPath(currentPath+"/select"); + builder.addParameter("defType", "edismax"); + builder.addParameter("qt", "standard"); + builder.addParameter("wt", "json"); + if (isIndentJson()) { + builder.addParameter("indent","on"); + } + builder.addParameter("fl",StringUtils.join(getRelevantFields(), ',')); + builder.addParameter("facet","false"); + builder.addParameter("json.nl","arrarr"); + builder.addParameter("q","*:*"); + builder.addParameter("rows", Integer.toString(pagination)); + builder.addParameter("start", Integer.toString(start)); + builder.addParameter("fq", "document_category:\""+category+"\""); + for (String [] tagvalue : tagvalues) { + if (tagvalue.length == 2) { + builder.addParameter("fq", tagvalue[0]+":\""+tagvalue[1]+"\""); + } + else if (tagvalue.length > 2) { + // if there is more than one value, assume that this is an OR query + StringBuilder value = new StringBuilder(); + value.append(tagvalue[0]).append(":("); + for (int i = 1; i < tagvalue.length; i++) { + if (i > 1) { + value.append(" OR "); + } + value.append('"').append(tagvalue[i]).append('"'); + } + value.append(')'); + builder.addParameter("fq", value.toString()); + } + } + return builder.build(); + } catch (URISyntaxException e) { + throw new IOException("Could not build URI for Golr request", e); + } + } + + protected String getJsonStringFromUri(URI uri) throws IOException { + logRequest(uri); + return getJsonStringFromUri(uri, retryCount); + } + + protected String getJsonStringFromUri(URI uri, int retryCount) throws IOException { + final URL url = uri.toURL(); + final HttpURLConnection connection; + InputStream response = null; + // setup and open (actual connection) + try { + connection = (HttpURLConnection) url.openConnection(); + connection.setInstanceFollowRedirects(true); // warning does not follow redirects from http to https + response = connection.getInputStream(); // opens the connection to the server + } + catch (IOException e) { + IOUtils.closeQuietly(response); + return retryRequest(uri, e, retryCount); + } + // check status code + final int status; + try { + status = connection.getResponseCode(); + } catch (IOException e) { + IOUtils.closeQuietly(response); + return retryRequest(uri, e, retryCount); + } + // handle unexpected status code + if (status != 200) { + // try to check error stream + String errorMsg = getErrorMsg(connection); + + // construct message for exception + StringBuilder sb = new StringBuilder("Unexpected HTTP status code: "+status); + + if (errorMsg != null) { + sb.append(" Details: "); + sb.append(errorMsg); + } + IOException e = new IOException(sb.toString()); + return retryRequest(uri, e, retryCount); + } + + // try to detect charset + String contentType = connection.getHeaderField("Content-Type"); + String charset = null; + + if (contentType != null) { + for (String param : contentType.replace(" ", "").split(";")) { + if (param.startsWith("charset=")) { + charset = param.split("=", 2)[1]; + break; + } + } + } + + // get string response from stream + String json; + try { + if (charset != null) { + json = IOUtils.toString(response, charset); + } + else { + json = IOUtils.toString(response); + } + } catch (IOException e) { + return retryRequest(uri, e, retryCount); + } + finally { + IOUtils.closeQuietly(response); + } + return json; + } + + protected String retryRequest(URI uri, IOException e, int retryCount) throws IOException { + if (retryCount > 0) { + int remaining = retryCount - 1; + defaultRandomWait(); + logRetry(uri, e, remaining); + return getJsonStringFromUri(uri, remaining); + } + logRequestError(uri, e); + throw e; + } + + private static String getErrorMsg(HttpURLConnection connection) { + String errorMsg = null; + InputStream errorStream = null; + try { + errorStream = connection.getErrorStream(); + if (errorStream != null) { + errorMsg =IOUtils.toString(errorStream); + } + errorMsg = StringUtils.trimToNull(errorMsg); + } + catch (IOException e) { + // ignore errors, while trying to retrieve the error message + } + finally { + IOUtils.closeQuietly(errorStream); + } + return errorMsg; + } + + protected void defaultRandomWait() { + // wait a random interval between 400 and 1500 ms + randomWait(400, 1500); + } + + protected void randomWait(int min, int max) { + Random random = new Random(System.currentTimeMillis()); + long wait = min + random.nextInt((max - min)); + try { + Thread.sleep(wait); + } catch (InterruptedException exception) { + // ignore + } + } + + + protected void logRequest(URI uri) { + // do nothing + // hook to implement logging of requests + } + + protected void logRequestError(URI uri, IOException exception) { + // do nothing + // hook to implement logging of request errors + } + + protected void logRetry(URI uri, IOException exception, int remaining) { + // do nothing + // hook to implement logging of a retry + } + + + protected > T parseGolrResponse(String response, Class clazz) throws IOException { + try { + T envelope = GSON.fromJson(response, clazz); + if (envelope == null || envelope.response == null || envelope.responseHeader == null) { + throw new IOException("Unexpected response content in GOLR response."); + } + if ("0".equals(envelope.responseHeader.status) == false) { + throw new IOException("Unexpected response status in GOLR response header: "+envelope.responseHeader.status); + } + return envelope; + } catch (JsonSyntaxException e) { + throw new IOException("Could not parse JSON response.", e); + } + } + + static class GolrEnvelope { + GolrResponseHeader responseHeader; + GolrResponse response; + } + + static class GolrResponseHeader { + String status; + String QTime; + Object params; + } + + static class GolrResponse { + int numFound; + int start; + T[] docs; + } + +} diff --git a/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrAnnotations.java b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrAnnotations.java new file mode 100644 index 00000000..d30bc505 --- /dev/null +++ b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrAnnotations.java @@ -0,0 +1,319 @@ +package org.bbop.golr.java; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.bbop.golr.java.RetrieveGolrAnnotations.GolrAnnotationExtension.GolrAnnotationExtensionEntry.GolrAnnotationExtensionRelation; + +//import owltools.gaf.Bioentity; +//import owltools.gaf.ExtensionExpression; +//import owltools.gaf.GafDocument; +//import owltools.gaf.GeneAnnotation; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; + +public class RetrieveGolrAnnotations extends AbstractRetrieveGolr{ + + static boolean JSON_INDENT_FLAG = false; + static int PAGINATION_CHUNK_SIZE = 100; + + private static final Gson GSON = new GsonBuilder().create(); + + /* + * This flag indicates that missing c16 data, due to malformed JSON is acceptable. + */ + private final boolean ignoreC16ParseErrors; + + public RetrieveGolrAnnotations(String server) { + this(server, 3, false); + } + + public RetrieveGolrAnnotations(String server, int retryCount, boolean ignoreC16ParseErrors) { + super(server, retryCount); + this.ignoreC16ParseErrors = ignoreC16ParseErrors; + } + + @Override + protected boolean isIndentJson() { + return JSON_INDENT_FLAG; + } + + @Override + protected List getRelevantFields() { + return GolrAnnotationDocument.getRelevantFields(); + } + +// public GafDocument convert(List golrAnnotationDocuments) throws IOException { +// Map entities = new HashMap(); +// GafDocument document = new GafDocument(null, null); +// convert(golrAnnotationDocuments, entities, document); +// return document; +// } +// +// public void convert(List golrAnnotationDocuments, Map entities, GafDocument document) throws IOException, JsonSyntaxException { +// for (GolrAnnotationDocument golrDocument : golrAnnotationDocuments) { +// String bioentityId = golrDocument.bioentity; +// Bioentity entity = entities.get(bioentityId); +// if (entity == null) { +// entity = new Bioentity(); +// entity.setId(bioentityId); +// entity.setSymbol(golrDocument.bioentity_label); +// entity.setFullName(golrDocument.bioentity_name); +// entity.setNcbiTaxonId(golrDocument.taxon); +// entity.setTypeCls(golrDocument.type); +// entity.setDb(golrDocument.source); // TODO check is that the correct mapping +// entity.setSynonyms(golrDocument.synonym); +// entities.put(bioentityId, entity); +// document.addBioentity(entity); +// } +// GeneAnnotation annotation = new GeneAnnotation(); +// annotation.setAspect(golrDocument.aspect); +// annotation.setAssignedBy(golrDocument.assigned_by); +// annotation.setBioentity(bioentityId); +// annotation.setBioentityObject(entity); +// annotation.setCls(golrDocument.annotation_class); +// annotation.setEvidence(golrDocument.evidence_type, null); +// annotation.setGeneProductForm(golrDocument.bioentity_isoform); +// annotation.setLastUpdateDate(golrDocument.date); +// if (golrDocument.reference != null) { +// annotation.addReferenceIds(golrDocument.reference); +// } +// if (golrDocument.evidence_with != null) { +// annotation.setWithInfos(golrDocument.evidence_with); +// } +// if (golrDocument.qualifier != null) { +// for (String qualifier : golrDocument.qualifier) { +// if ("not".equalsIgnoreCase(qualifier)) { +// annotation.setIsNegated(true); +// } +// else if ("contributes_to".equalsIgnoreCase(qualifier)) { +// annotation.setIsContributesTo(true); +// } +// else if ("integral_to".equalsIgnoreCase(qualifier)) { +// annotation.setIsIntegralTo(true); +// } +// else if ("colocalizes_with".equalsIgnoreCase(qualifier)) { +// annotation.setIsColocatesWith(true); +// } +// else if ("cut".equalsIgnoreCase(qualifier)) { +// annotation.setIsCut(true); +// } +// } +// } +// handleAnnotationExtension(annotation, golrDocument); +// document.addGeneAnnotation(annotation); +// } +// } +// +// protected void handleAnnotationExtension(GeneAnnotation annotation, GolrAnnotationDocument document) throws JsonSyntaxException { +// if (document.annotation_extension_json != null && +// document.annotation_extension_json.isEmpty() == false){ +// List> expressions = annotation.getExtensionExpressions(); +// if (expressions == null) { +// expressions = new ArrayList>(document.annotation_extension_json.size()); +// } +// for(String json : document.annotation_extension_json) { +// try { +// GolrAnnotationExtension extension = GSON.fromJson(json, GolrAnnotationExtension.class); +// if (extension != null && extension.relationship != null) { +// // WARNING the Golr c16 model is lossy! There is no distinction between disjunction and conjunction in Golr-c16 +// // add all as disjunction +// String relation = extractRelation(extension); +// if (relation != null) { +// ExtensionExpression ee = new ExtensionExpression(relation, extension.relationship.id); +// expressions.add(Collections.singletonList(ee)); +// } +// } +// } catch (JsonSyntaxException e) { +// // when the ignore flag is set, the user has decided that incomplete c16 data is better than no data. +// if (ignoreC16ParseErrors == false) { +// throw e; +// } +// } +// } +// annotation.setExtensionExpressions(expressions); +// }; +// } + + private String extractRelation(GolrAnnotationExtension extension) { + StringBuilder sb = new StringBuilder(); + for(GolrAnnotationExtensionRelation rel : extension.relationship.relation) { + if (sb.length() > 0) { + sb.append(" o "); + } + sb.append(rel.id); + } + if (sb.length() > 0) { + return sb.toString(); + } + return null; + } + + public List getGolrAnnotationsForGenes(List ids) throws IOException { + return getGolrAnnotationsForGenes(ids, false); + } + + public List getGolrAnnotationsForGenes(List ids, boolean noIEAs) throws IOException { + List tagvalues = new ArrayList(); + String [] tagvalue = new String[ids.size() + 1]; + tagvalue[0] = "bioentity"; + for (int i = 0; i < ids.size(); i++) { + tagvalue[i+1] = ids.get(i); + } + tagvalues.add(tagvalue); + if (noIEAs) { + // add negative filter for IEAs + tagvalues.add(new String[]{"-evidence_type", "IEA"}); + } + final List documents = getGolrAnnotations(tagvalues); + return documents; + } + + public List getGolrAnnotationsForGene(String id) throws IOException { + List tagvalues = new ArrayList(); + String [] tagvalue = new String[2]; + tagvalue[0] = "bioentity"; + tagvalue[1] = id; + tagvalues.add(tagvalue); + final List documents = getGolrAnnotations(tagvalues); + return documents; + } + + public List getGolrAnnotationsForSynonym(String source, String synonym) throws IOException { + return getGolrAnnotationsForSynonym(source, Collections.singletonList(synonym)); + } + + public List getGolrAnnotationsForSynonym(String source, List synonyms) throws IOException { + return getGolrAnnotationsForSynonym(source, synonyms, false); + } + + public List getGolrAnnotationsForSynonym(String source, List synonyms, boolean noIEAs) throws IOException { + List tagvalues = new ArrayList(); + String [] param1 = new String[2]; + param1[0] = "source"; + param1[1] = source; + tagvalues.add(param1); + String [] param2 = new String[synonyms.size() + 1]; + param2[0] = "synonym"; + for (int i = 0; i < synonyms.size(); i++) { + param2[i+1] = synonyms.get(i); + } + tagvalues.add(param2); + if (noIEAs) { + // add negative filter for IEAs + tagvalues.add(new String[]{"-evidence_type", "IEA"}); + } + final List documents = getGolrAnnotations(tagvalues); + + return documents; + } + + public List getGolrAnnotations(List tagvalues) throws IOException { + JSON_INDENT_FLAG = true; + final URI uri = createGolrRequest(tagvalues, "annotation", 0, PAGINATION_CHUNK_SIZE); + final String jsonString = getJsonStringFromUri(uri); + final GolrResponse response = parseGolrResponse(jsonString); + final List documents = new ArrayList(response.numFound); + documents.addAll(Arrays.asList(response.docs)); + if (response.numFound > PAGINATION_CHUNK_SIZE) { + // fetch remaining documents + int start = PAGINATION_CHUNK_SIZE; + int end = response.numFound / PAGINATION_CHUNK_SIZE; + if (response.numFound % PAGINATION_CHUNK_SIZE != 0) { + end += 1; + } + end = end * PAGINATION_CHUNK_SIZE; + while (start <= end) { + URI uriPagination = createGolrRequest(tagvalues, "annotation", start, PAGINATION_CHUNK_SIZE); + String jsonStringPagination = getJsonStringFromUri(uriPagination); + GolrResponse responsePagination = parseGolrResponse(jsonStringPagination); + documents.addAll(Arrays.asList(responsePagination.docs)); + start += PAGINATION_CHUNK_SIZE; + } + } + return documents; + } + + private static class GolrAnnotationResponse extends GolrEnvelope { + // empty + } + + public static class GolrAnnotationDocument { + String source; + String bioentity; + String bioentity_internal_id; + String bioentity_label; + String bioentity_name; + String annotation_class; + String annotation_class_label; + String evidence_type; + String aspect; + String type; + String taxon; + String taxon_label; + String date; + String assigned_by; + String bioentity_isoform; + String panther_family; + String panther_family_label; + List annotation_extension_json; + List synonym; + List evidence_with; + List reference; + List qualifier; + + static List getRelevantFields() { + // explicit list of fields, avoid "*" retrieval of unused fields + return Arrays.asList("source", + "qualifier", + "bioentity", + "bioentity_internal_id", + "bioentity_label", + "bioentity_name", + "annotation_class", + "annotation_class_label", + "evidence_type", + "aspect", + "type", + "taxon", + "taxon_label", + "date", + "assigned_by", + "bioentity_isoform", + "panther_family", + "panther_family_label", + "annotation_extension_json", + "synonym", + "evidence_with", + "reference"); + } + } + + public static class GolrAnnotationExtension { + + GolrAnnotationExtensionEntry relationship; + + public static class GolrAnnotationExtensionEntry { + List relation; // list represents a property chain + String id; + String label; + + public static class GolrAnnotationExtensionRelation { + String id; + String label; + } + } + } + + private GolrResponse parseGolrResponse(String jsonString) throws IOException { + return parseGolrResponse(jsonString, GolrAnnotationResponse.class).response; + } +} diff --git a/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrBioentities.java b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrBioentities.java new file mode 100644 index 00000000..6a02828d --- /dev/null +++ b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrBioentities.java @@ -0,0 +1,100 @@ +package org.bbop.golr.java; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RetrieveGolrBioentities extends AbstractRetrieveGolr { + + static int PAGINATION_CHUNK_SIZE = 100; + + private final List relevantFields; + + public RetrieveGolrBioentities(String server, int retryCount) { + super(server, retryCount); + relevantFields = GolrBioentityDocument.getRelevantFields(); + } + + @Override + protected boolean isIndentJson() { + return true; + } + + @Override + protected List getRelevantFields() { + return relevantFields; + } + + public List getGolrBioentites(String id) throws IOException { + List tagvalues = new ArrayList(); + String [] tagvalue = new String[2]; + tagvalue[0] = "bioentity"; + tagvalue[1] = id; + tagvalues.add(tagvalue); + final List documents = getGolrBioentities(tagvalues); + return documents; + } + + public List getGolrBioentities(List tagvalues) throws IOException { + final URI uri = createGolrRequest(tagvalues, "bioentity", 0, PAGINATION_CHUNK_SIZE); + final String jsonString = getJsonStringFromUri(uri); + final GolrResponse response = parseGolrResponse(jsonString); + final List documents = new ArrayList(response.numFound); + documents.addAll(Arrays.asList(response.docs)); + if (response.numFound > PAGINATION_CHUNK_SIZE) { + // fetch remaining documents + int start = PAGINATION_CHUNK_SIZE; + int end = response.numFound / PAGINATION_CHUNK_SIZE; + if (response.numFound % PAGINATION_CHUNK_SIZE != 0) { + end += 1; + } + end = end * PAGINATION_CHUNK_SIZE; + while (start <= end) { + URI uriPagination = createGolrRequest(tagvalues, "bioentity", start, PAGINATION_CHUNK_SIZE); + String jsonStringPagination = getJsonStringFromUri(uriPagination); + GolrResponse responsePagination = parseGolrResponse(jsonStringPagination); + documents.addAll(Arrays.asList(responsePagination.docs)); + start += PAGINATION_CHUNK_SIZE; + } + } + return documents; + } + + private static class GolrBioentityResponse extends GolrEnvelope { + // empty + } + + public static class GolrBioentityDocument { + + public String document_category; + public String id; + public String bioentity; + public String bioentity_label; + public String bioentity_name; + public String source; + public String type; + public String taxon; + public String taxon_label; + public List synonym; + + static List getRelevantFields() { + // explicit list of fields, avoid "*" retrieval of unused fields + return Arrays.asList("document_category", + "id", + "bioentity", + "bioentity_label", + "bioentity_name", + "source", + "type", + "taxon", + "taxon_label", + "synonym"); + } + } + + private GolrResponse parseGolrResponse(String jsonString) throws IOException { + return parseGolrResponse(jsonString, GolrBioentityResponse.class).response; + } +} diff --git a/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrOntologyClass.java b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrOntologyClass.java new file mode 100644 index 00000000..6cb37616 --- /dev/null +++ b/minerva-lookup/src/main/java/org/bbop/golr/java/RetrieveGolrOntologyClass.java @@ -0,0 +1,114 @@ +package org.bbop.golr.java; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class RetrieveGolrOntologyClass extends AbstractRetrieveGolr { + + static int PAGINATION_CHUNK_SIZE = 100; + + private final List relevantFields; + + public RetrieveGolrOntologyClass(String server, int retryCount) { + super(server, retryCount); + relevantFields = GolrOntologyClassDocument.getRelevantFields(); + } + + @Override + protected boolean isIndentJson() { + return true; + } + + @Override + protected List getRelevantFields() { + return relevantFields; + } + + public List getGolrOntologyCls(String id) throws IOException { + List tagvalues = new ArrayList(); + String [] tagvalue = new String[2]; + tagvalue[0] = "annotation_class"; + tagvalue[1] = id; + tagvalues.add(tagvalue); + final List documents = getGolrOntologyCls(tagvalues); + return documents; + } + + public List getGolrOntologyCls(List tagvalues) throws IOException { + final URI uri = createGolrRequest(tagvalues, "ontology_class", 0, PAGINATION_CHUNK_SIZE); + final String jsonString = getJsonStringFromUri(uri); + final GolrResponse response = parseGolrResponse(jsonString); + final List documents = new ArrayList(response.numFound); + documents.addAll(Arrays.asList(response.docs)); + if (response.numFound > PAGINATION_CHUNK_SIZE) { + // fetch remaining documents + int start = PAGINATION_CHUNK_SIZE; + int end = response.numFound / PAGINATION_CHUNK_SIZE; + if (response.numFound % PAGINATION_CHUNK_SIZE != 0) { + end += 1; + } + end = end * PAGINATION_CHUNK_SIZE; + while (start <= end) { + URI uriPagination = createGolrRequest(tagvalues, "ontology_class", start, PAGINATION_CHUNK_SIZE); + String jsonStringPagination = getJsonStringFromUri(uriPagination); + GolrResponse responsePagination = parseGolrResponse(jsonStringPagination); + documents.addAll(Arrays.asList(responsePagination.docs)); + start += PAGINATION_CHUNK_SIZE; + } + } + return documents; + } + + private static class GolrOntologyClassResponse extends GolrEnvelope { + // empty + } + + public static class GolrOntologyClassDocument { + + public String document_category; + public String annotation_class; + public String annotation_class_label; + public String description; + public String source; + public String is_obsolete; + public List alternate_id; + public List replaced_by; + public List consider; + public List synonym; + public List subset; + public List definition_xref; + public List database_xref; + public List isa_partof_closure; + public List regulates_closure; + public String only_in_taxon; + public List only_in_taxon_closure; + + + static List getRelevantFields() { + // explicit list of fields, avoid "*" retrieval of unused fields + return Arrays.asList("document_category", + "annotation_class", + "annotation_class_label", + "description", + "source", + "is_obsolete", + "alternate_id", + "replaced_by", + "synonym", + "subset", + "definition_xref", + "database_xref", + "isa_partof_closure", + "regulates_closure", + "only_in_taxon", + "only_in_taxon_closure"); + } + } + + private GolrResponse parseGolrResponse(String jsonString) throws IOException { + return parseGolrResponse(jsonString, GolrOntologyClassResponse.class).response; + } +} diff --git a/minerva-server/pom.xml b/minerva-server/pom.xml index dbd9f68e..4748880b 100644 --- a/minerva-server/pom.xml +++ b/minerva-server/pom.xml @@ -113,10 +113,22 @@ minerva-converter ${project.parent.version} - + + + + org.apache.ant + ant + 1.9.14 + org.eclipse.jetty jetty-server diff --git a/minerva-server/src/main/java/org/geneontology/minerva/generate/GolrSeedingDataProvider.java b/minerva-server/src/main/java/org/geneontology/minerva/generate/GolrSeedingDataProvider.java deleted file mode 100644 index 3aaa69ac..00000000 --- a/minerva-server/src/main/java/org/geneontology/minerva/generate/GolrSeedingDataProvider.java +++ /dev/null @@ -1,194 +0,0 @@ -package org.geneontology.minerva.generate; - -import java.io.IOException; -import java.net.URI; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.bbop.golr.java.RetrieveGolrAnnotations; -import org.bbop.golr.java.RetrieveGolrAnnotations.GolrAnnotationDocument; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.reasoner.OWLReasoner; - -import owltools.gaf.Bioentity; -import owltools.gaf.GafDocument; -import owltools.gaf.GeneAnnotation; -import owltools.graph.OWLGraphWrapper; - -public class GolrSeedingDataProvider implements SeedingDataProvider { - - private final RetrieveGolrAnnotations golr; - private final OWLGraphWrapper graph; - private final OWLReasoner reasoner; - private final Set locationRoots; - private Set evidenceRestriction = null; - private Set taxonRestriction; - private final Set blackList; - - public GolrSeedingDataProvider(String golrServer, OWLGraphWrapper graph, OWLReasoner reasoner, Set locationRoots, Set evidenceRestriction, Set taxonRestriction, Set blackList) { - this.graph = graph; - this.reasoner = reasoner; - this.evidenceRestriction = evidenceRestriction; - this.locationRoots = locationRoots; - this.taxonRestriction = taxonRestriction; - this.blackList = blackList; - golr = new RetrieveGolrAnnotations(golrServer) { - @Override - protected void logRequest(URI uri) { - GolrSeedingDataProvider.this.logRequest(uri); - } - }; - } - - protected void logRequest(URI uri) { - // hook for logging requests - } - - @Override - public Map> getGeneProducts(String bp) throws IOException { - List tagvalues = new ArrayList(); - tagvalues.add(new String[]{"annotation_class", bp}); - addRestrictions(tagvalues); // taxon, evidence, not - List golrAnnotations = golr.getGolrAnnotations(tagvalues); - GafDocument gafDocument = golr.convert(golrAnnotations); - Map> result = new HashMap>(); - for(GeneAnnotation annotation : gafDocument.getGeneAnnotations()) { - Bioentity bioentity = annotation.getBioentityObject(); - List relatedAnnotations = result.get(bioentity); - if (relatedAnnotations == null) { - relatedAnnotations = new ArrayList(); - result.put(bioentity, relatedAnnotations); - } - relatedAnnotations.add(annotation); - } - return result; - } - - @Override - public Map> getFunctions(Set entities) throws IOException { - Map> results = new HashMap>(); - Map map = new HashMap(); - String[] bioentityFq = new String[entities.size() + 1]; - int bioentityFqCounter = 1; - bioentityFq[0] = "bioentity"; - for (Bioentity bioentity : entities) { - map.put(bioentity.getId(), bioentity); - bioentityFq[bioentityFqCounter] = bioentity.getId(); - bioentityFqCounter += 1; - } - List tagvalues = new ArrayList(); - tagvalues.add(bioentityFq); - tagvalues.add(new String[]{"aspect", "F"}); // functions - addRestrictions(tagvalues); // taxon, evidence, not - - List golrAnnotations = golr.getGolrAnnotations(tagvalues); - if (golrAnnotations != null && !golrAnnotations.isEmpty()) { - GafDocument doc = new GafDocument(null, null); - golr.convert(golrAnnotations, map, doc); - List annotations = doc.getGeneAnnotations(); - if (annotations != null && !annotations.isEmpty()) { - for (GeneAnnotation annotation : annotations) { - if(blackList.contains(annotation.getCls())) { - continue; - } - String bioentityId = annotation.getBioentity(); - Bioentity bioentity = map.get(bioentityId); - if (bioentity != null) { - List relatedAnnotations = results.get(bioentity); - if (relatedAnnotations == null) { - relatedAnnotations = new ArrayList(); - results.put(bioentity, relatedAnnotations); - } - relatedAnnotations.add(annotation); - } - } - } - } - return results; - } - - @Override - public Map> getLocations(Set entities) throws IOException { - Map> results = new HashMap>(); - Map map = new HashMap(); - String[] bioentityFq = new String[entities.size() + 1]; - int bioentityFqCounter = 1; - bioentityFq[0] = "bioentity"; - for (Bioentity bioentity : entities) { - map.put(bioentity.getId(), bioentity); - bioentityFq[bioentityFqCounter] = bioentity.getId(); - bioentityFqCounter += 1; - } - List tagvalues = new ArrayList(); - tagvalues.add(bioentityFq); - tagvalues.add(new String[]{"-aspect", "F"}); // not function - tagvalues.add(new String[]{"-aspect", "P"}); // not process - addRestrictions(tagvalues); // taxon, evidence, not - List golrAnnotations = golr.getGolrAnnotations(tagvalues); - if (golrAnnotations != null && !golrAnnotations.isEmpty()) { - GafDocument doc = new GafDocument(null, null); - golr.convert(golrAnnotations, map, doc); - List annotations = doc.getGeneAnnotations(); - if (annotations != null && !annotations.isEmpty()) { - for (GeneAnnotation annotation : annotations) { - String bioentityId = annotation.getBioentity(); - Bioentity bioentity = map.get(bioentityId); - if (bioentity != null && isLocation(annotation)) { - List relatedAnnotations = results.get(bioentity); - if (relatedAnnotations == null) { - relatedAnnotations = new ArrayList(); - results.put(bioentity, relatedAnnotations); - } - relatedAnnotations.add(annotation); - } - } - } - } - return results; - } - - /** - * Check that the gene annotation is a location. Does not rely on the aspect! - * - * @param annotation - * @return list of annotations - */ - private boolean isLocation(GeneAnnotation annotation) { - final String clsId = annotation.getCls(); - final OWLClass cls = graph.getOWLClassByIdentifier(clsId); - if (cls != null) { - Set superClasses = reasoner.getSuperClasses(cls, false).getFlattened(); - for (OWLClass locationRoot : locationRoots) { - if (superClasses.contains(locationRoot)) { - return true; - } - } - } - return false; - } - - private void addRestrictions(List tagvalues) { - if (evidenceRestriction != null) { - tagvalues.add(createTagValues("evidence_type_closure", evidenceRestriction)); - } - if (taxonRestriction != null) { - tagvalues.add(createTagValues("taxon_closure", taxonRestriction)); - } - tagvalues.add(new String[]{"-qualifier","not"}); // exclude not annotations - } - - private String[] createTagValues(String tag, Collection values) { - String[] result = new String[values.size()+1]; - result[0] = tag; - int i = 1; - for (String value : values) { - result[i] = value; - i += 1; - } - return result; - } -} diff --git a/minerva-server/src/main/java/org/geneontology/minerva/generate/ModelSeeding.java b/minerva-server/src/main/java/org/geneontology/minerva/generate/ModelSeeding.java deleted file mode 100644 index 37f3968a..00000000 --- a/minerva-server/src/main/java/org/geneontology/minerva/generate/ModelSeeding.java +++ /dev/null @@ -1,296 +0,0 @@ -package org.geneontology.minerva.generate; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.geneontology.minerva.ModelContainer; -import org.geneontology.minerva.MolecularModelManager; -import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.util.AnnotationShorthand; -import org.geneontology.reasoner.ExpressionMaterializingReasoner; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLAnnotation; -import org.semanticweb.owlapi.model.OWLAnnotationProperty; -import org.semanticweb.owlapi.model.OWLClass; -import org.semanticweb.owlapi.model.OWLClassExpression; -import org.semanticweb.owlapi.model.OWLDataFactory; -import org.semanticweb.owlapi.model.OWLNamedIndividual; -import org.semanticweb.owlapi.model.OWLObjectProperty; -import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; -import org.semanticweb.owlapi.util.OWLClassExpressionVisitorAdapter; - -import owltools.gaf.Bioentity; -import owltools.gaf.GeneAnnotation; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.vocab.OBOUpperVocabulary; - -import com.google.common.collect.Sets; - -public class ModelSeeding { - - private final ExpressionMaterializingReasoner reasoner; - private final SeedingDataProvider dataProvider; - private final CurieHandler curieHandler; - private final Set defaultAnnotations; - private final SimpleEcoMapper ecoMapper; - - public ModelSeeding(ExpressionMaterializingReasoner reasoner, SeedingDataProvider dataProvider, - Set defaultAnnotations, CurieHandler curieHandler, SimpleEcoMapper ecoMapper) { - this.reasoner = reasoner; - this.dataProvider = dataProvider; - this.defaultAnnotations = defaultAnnotations; - this.curieHandler = curieHandler; - this.ecoMapper = ecoMapper; - reasoner.setIncludeImports(true); - } - - public void seedModel(ModelContainer model, MolecularModelManager manager, String bp, final METADATA metadata) throws Exception { - final IRI modelId = model.getModelId(); - final Map> geneProducts = dataProvider.getGeneProducts(bp); - if (geneProducts.isEmpty()) { - throw new Exception("No gene products found for the given process id: "+bp); - } - - final OWLDataFactory f = model.getOWLDataFactory(); - final Relations relations = new Relations(f, curieHandler); - - // create bp - Set bpAnnotations = null; - final OWLNamedIndividual bpIndividual = manager.createIndividualNonReasoning(modelId, bp, bpAnnotations , metadata); - - // create gene products - final Map gpIndividuals = new HashMap<>(); - for(Bioentity gp : geneProducts.keySet()) { - List source = geneProducts.get(gp); - - // explicitly create OWL class for gene product - final IRI gpIRI = curieHandler.getIRI(gp.getId()); - final OWLClass gpClass = f.getOWLClass(gpIRI); - manager.addAxiom(model, f.getOWLDeclarationAxiom(gpClass), metadata); - - Set gpAnnotations = generateAnnotationAndEvidence(source, model, manager, metadata); - OWLNamedIndividual gpIndividual = manager.createIndividualNonReasoning(modelId, gp.getId(), gpAnnotations, metadata); - gpIndividuals.put(gp, gpIndividual); - } - - Map> mfIndividuals = new HashMap<>(); - // add functions - Map> functions = dataProvider.getFunctions(geneProducts.keySet()); - for(Bioentity gp : functions.keySet()) { - List functionAnnotations = functions.get(gp); - OWLNamedIndividual gpIndividual = gpIndividuals.get(gp); - List mfIndividualList = new ArrayList(functionAnnotations.size()); - mfIndividuals.put(gp, mfIndividualList); - - // TODO choose one representative and preserve others as choice! - // for now group to minimize mf individuals - Map> mfGroups = removeRedundants(groupByCls(functionAnnotations), f); - for(Entry> mfGroup : mfGroups.entrySet()) { - String mf = mfGroup.getKey(); - Set mfAnnotations = generateAnnotationAndEvidence(mfGroup.getValue(), model, manager, metadata); - OWLNamedIndividual mfIndividual = manager.createIndividualNonReasoning(modelId, mf, mfAnnotations , metadata); - mfIndividualList.add(mfIndividual); - manager.addFact(model, relations.enabled_by, mfIndividual, gpIndividual, mfAnnotations, metadata); - manager.addFact(model, relations.part_of, mfIndividual, bpIndividual, null, metadata); - - // TODO check c16 for 'occurs in' - } - } - -// // set GO:0003674 'molecular_function' for gp with unknown function -// for(Bioentity gp : Sets.difference(geneProducts.keySet(), functions.keySet())) { -// Pair gpIndividual = gpIndividuals.get(gp); -// -// Pair mfIndividual = manager.createIndividualNonReasoning(modelId, "GO:0003674", null, metadata); -// mfIndividuals.put(gp, Collections.singletonList(mfIndividual)); -// manager.addFactNonReasoning(modelId, enabled_by_id, mfIndividual.getKey(), gpIndividual.getKey(), null, metadata); -// manager.addFactNonReasoning(modelId, part_of_id, mfIndividual.getKey(), bpIndividual.getKey(), generateAnnotations(geneProducts.get(gp)), metadata); -// } - // remove individuals for gp with unknown function - Set unused = Sets.difference(geneProducts.keySet(), functions.keySet()); - for(Bioentity gp : unused) { - OWLNamedIndividual gpIndividual = gpIndividuals.remove(gp); - manager.deleteIndividual(modelId, gpIndividual, metadata); - } - - // add locations - Map> locations = dataProvider.getLocations(functions.keySet()); - for(Bioentity gp : locations.keySet()) { - List relevantMfIndividuals = mfIndividuals.get(gp); - if (relevantMfIndividuals == null) { - continue; - } - List locationAnnotations = locations.get(gp); - Map> locationGroups = removeRedundants(groupByCls(locationAnnotations), f); - for(Entry> locationGroup : locationGroups.entrySet()) { - String location = locationGroup.getKey(); - Set source = generateAnnotationAndEvidence(locationGroup.getValue(), model, manager, metadata); - for(OWLNamedIndividual relevantMfIndividual : relevantMfIndividuals) { - OWLNamedIndividual locationIndividual = manager.createIndividualNonReasoning(modelId, location, source, metadata); - manager.addFact(model, relations.occurs_in, relevantMfIndividual, locationIndividual, source, metadata); - } - } - - } - - // add relations - // TODO - } - - static class Relations { - final OWLObjectProperty part_of; - final String part_of_id; - final OWLObjectProperty enabled_by; - final String enabled_by_id; - final OWLObjectProperty occurs_in; - final String occurs_in_id; - - Relations(OWLDataFactory f, CurieHandler curieHandler) { - part_of = OBOUpperVocabulary.BFO_part_of.getObjectProperty(f); - part_of_id = curieHandler.getCuri(part_of); - occurs_in = OBOUpperVocabulary.BFO_occurs_in.getObjectProperty(f); - occurs_in_id = curieHandler.getCuri(occurs_in); - enabled_by = OBOUpperVocabulary.GOREL_enabled_by.getObjectProperty(f); - enabled_by_id = curieHandler.getCuri(enabled_by); - } - } - - private Map> groupByCls(List annotations) { - Map> groups = new HashMap>(); - for (GeneAnnotation annotation : annotations) { - String cls = annotation.getCls(); - List group = groups.get(cls); - if (group == null) { - group = new ArrayList(); - groups.put(cls, group); - } - group.add(annotation); - } - return groups; - } - - private Map> removeRedundants(Map> groups, final OWLDataFactory f) throws UnknownIdentifierException { - // calculate all ancestors for each group - Map> allAncestors = new HashMap>(); - for(String cls : groups.keySet()) { - OWLClass owlCls = f.getOWLClass(curieHandler.getIRI(cls)); - Set superClassExpressions = reasoner.getSuperClassExpressions(owlCls, false); - final Set ancestors = new HashSet(); - allAncestors.put(cls, ancestors); - for (OWLClassExpression ce : superClassExpressions) { - ce.accept(new OWLClassExpressionVisitorAdapter(){ - - @Override - public void visit(OWLClass desc) { - ancestors.add(curieHandler.getCuri(desc)); - } - - @Override - public void visit(OWLObjectSomeValuesFrom desc) { - OWLClassExpression filler = desc.getFiller(); - filler.accept(new OWLClassExpressionVisitorAdapter(){ - @Override - public void visit(OWLClass desc) { - ancestors.add(curieHandler.getCuri(desc)); - } - - }); - } - - }); - } - } - // check that cls is not an ancestor in any other group - Map> redundantFree = new HashMap>(); - for(String cls : groups.keySet()) { - boolean nonRedundant = true; - for(Entry> group : allAncestors.entrySet()) { - if (group.getValue().contains(cls)) { - nonRedundant = false; - break; - } - } - if (nonRedundant) { - redundantFree.put(cls, groups.get(cls)); - } - } - - return redundantFree; - } - - private Set generateAnnotationAndEvidence(final List source, ModelContainer model, MolecularModelManager manager, final METADATA metadata) { - final OWLDataFactory f = model.getOWLDataFactory(); - final OWLAnnotationProperty evidenceProperty = f.getOWLAnnotationProperty(AnnotationShorthand.evidence.getAnnotationProperty()); - final OWLAnnotationProperty sourceProperty = f.getOWLAnnotationProperty(AnnotationShorthand.source.getAnnotationProperty()); - final OWLAnnotationProperty withProperty = f.getOWLAnnotationProperty(AnnotationShorthand.with.getAnnotationProperty()); - final OWLAnnotationProperty contributorProperty = f.getOWLAnnotationProperty(AnnotationShorthand.contributor.getAnnotationProperty()); - Set annotations = new HashSet(); - - if (source != null) { - for (GeneAnnotation annotation : source) { - OWLClass ecoCls = findEco(annotation, model); - if (ecoCls != null) { - final OWLNamedIndividual evidenceIndividual = manager.createIndividualNonReasoning(model, defaultAnnotations, metadata); - manager.addType(model, evidenceIndividual, ecoCls, metadata); - Set evidenceAnnotations = new HashSet(); - List referenceIds = annotation.getReferenceIds(); - if (referenceIds != null) { - for (String referenceId : referenceIds) { - evidenceAnnotations.add(f.getOWLAnnotation(sourceProperty, f.getOWLLiteral(referenceId))); - } - } - Collection withInfos = annotation.getWithInfos(); - if (withInfos != null) { - for (String withInfo : withInfos) { - evidenceAnnotations.add(f.getOWLAnnotation(withProperty, f.getOWLLiteral(withInfo))); - } - } - if (annotation.getAssignedBy() != null) { - evidenceAnnotations.add(f.getOWLAnnotation(contributorProperty, f.getOWLLiteral(annotation.getAssignedBy()))); - } - evidenceAnnotations.add(f.getOWLAnnotation(f.getRDFSComment(), f.getOWLLiteral("Generated from: "+annotation.toString()))); - manager.addAnnotations(model, evidenceIndividual, evidenceAnnotations , metadata); - annotations.add(f.getOWLAnnotation(evidenceProperty, evidenceIndividual.getIRI())); - } - } - } - if (defaultAnnotations != null) { - annotations.addAll(defaultAnnotations); - } - return annotations; - } - - private OWLClass findEco(GeneAnnotation annotation, ModelContainer model) { - OWLClass result = null; - String ecoId = annotation.getEcoEvidenceCls(); - String goCode = annotation.getShortEvidence(); - if (ecoId == null && goCode != null) { - List referenceIds = annotation.getReferenceIds(); - if (referenceIds != null) { - ecoId = ecoMapper.getEco(goCode, referenceIds); - } - if (ecoId == null) { - ecoId = ecoMapper.getEco(goCode, (String) null); - } - } - if (ecoId != null) { - IRI ecoIRI; - try { - ecoIRI = curieHandler.getIRI(ecoId); - } catch (UnknownIdentifierException e) { - ecoIRI = null; - } - if (ecoIRI != null) { - result = model.getOWLDataFactory().getOWLClass(ecoIRI); - } - } - return result; - } -} diff --git a/minerva-server/src/main/java/org/geneontology/minerva/generate/SeedingDataProvider.java b/minerva-server/src/main/java/org/geneontology/minerva/generate/SeedingDataProvider.java deleted file mode 100644 index bc552687..00000000 --- a/minerva-server/src/main/java/org/geneontology/minerva/generate/SeedingDataProvider.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.geneontology.minerva.generate; - -import java.io.IOException; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import owltools.gaf.Bioentity; -import owltools.gaf.GeneAnnotation; - -public interface SeedingDataProvider { - - public Map> getGeneProducts(String bp) - throws IOException; - - public Map> getFunctions( - Set entities) throws IOException; - - public Map> getLocations( - Set entities) throws IOException; - -} \ No newline at end of file diff --git a/minerva-server/src/main/java/org/geneontology/minerva/server/StartUpTool.java b/minerva-server/src/main/java/org/geneontology/minerva/server/StartUpTool.java index a69f9023..08b56b0e 100644 --- a/minerva-server/src/main/java/org/geneontology/minerva/server/StartUpTool.java +++ b/minerva-server/src/main/java/org/geneontology/minerva/server/StartUpTool.java @@ -8,6 +8,7 @@ //import org.eclipse.jetty.server.nio.SelectChannelConnector; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.ModelReaderHelper; import org.geneontology.minerva.UndoAwareMolecularModelManager; import org.geneontology.minerva.curie.CurieHandler; @@ -31,7 +32,6 @@ import owltools.cli.Opts; import owltools.gaf.eco.EcoMapperFactory; import owltools.gaf.eco.SimpleEcoMapper; -import owltools.graph.OWLGraphWrapper; import owltools.io.CatalogXmlIRIMapper; import owltools.io.ParserWrapper; @@ -272,7 +272,7 @@ else if (opts.nextEq("--sparql-endpoint-timeout")) { * @param g * @return property or null */ - public static OWLObjectProperty getRelation(String rel, OWLGraphWrapper g) { + public static OWLObjectProperty getRelation(String rel, MinervaOWLGraphWrapper g) { if (rel == null || rel.isEmpty()) { return null; } @@ -299,7 +299,7 @@ public static OWLObjectProperty getRelation(String rel, OWLGraphWrapper g) { * @param g * @return set */ - public static Set getAssertedSubProperties(OWLObjectProperty parent, OWLGraphWrapper g) { + public static Set getAssertedSubProperties(OWLObjectProperty parent, MinervaOWLGraphWrapper g) { Set properties = new HashSet(); for(OWLOntology ont : g.getAllOntologies()) { Set axioms = ont.getObjectSubPropertyAxiomsForSuperProperty(parent); @@ -323,7 +323,7 @@ public static Server startUp(final MinervaStartUpConfig conf) LOGGER.info("Adding catalog xml: "+conf.catalog); pw.addIRIMapper(new CatalogXmlIRIMapper(conf.catalog)); } - OWLGraphWrapper graph = pw.parseToOWLGraph(conf.ontology); + MinervaOWLGraphWrapper graph = pw.parseToOWLGraph(conf.ontology); OWLOntology full_tbox = forceMergeImports(graph.getSourceOntology(), graph.getAllOntologies()); graph.setSourceOntology(full_tbox); @@ -380,7 +380,7 @@ public static OWLOntology forceMergeImports(OWLOntology sourceOntology, Set factory; - - private final Type requestType = new TypeToken(){ - - // generated - private static final long serialVersionUID = 5452629810143143422L; - - }.getType(); - - public JsonOrJsonpSeedHandler(UndoAwareMolecularModelManager m3, String defaultModelState, String golr, SimpleEcoMapper ecoMapper) { - super(m3, defaultModelState); - this.golrUrl = golr; - this.ecoMapper = ecoMapper; - factory = new ExpressionMaterializingReasonerFactory(new ElkReasonerFactory()); - } - - @Override - @JSONP(callback = JSONP_DEFAULT_CALLBACK, queryParam = JSONP_DEFAULT_OVERWRITE) - public SeedResponse fromProcessPost(String intention, String packetId, String requestString) { - // only privileged calls are allowed - SeedResponse response = new SeedResponse(null, Collections.emptySet(), intention, packetId); - return error(response, "Insufficient permissions for seed operation.", null); - } - - @Override - @JSONP(callback = JSONP_DEFAULT_CALLBACK, queryParam = JSONP_DEFAULT_OVERWRITE) - public SeedResponse fromProcessPostPrivileged(String uid, Set providerGroups, String intention, String packetId, String requestString) { - return fromProcess(uid, providerGroups, intention, checkPacketId(packetId), requestString); - } - - @Override - @JSONP(callback = JSONP_DEFAULT_CALLBACK, queryParam = JSONP_DEFAULT_OVERWRITE) - public SeedResponse fromProcessGet(String intention, String packetId, String requestString) { - // only privileged calls are allowed - SeedResponse response = new SeedResponse(null, Collections.emptySet(), intention, packetId); - return error(response, "Insufficient permissions for seed operation.", null); - } - - @Override - @JSONP(callback = JSONP_DEFAULT_CALLBACK, queryParam = JSONP_DEFAULT_OVERWRITE) - public SeedResponse fromProcessGetPrivileged(String uid, Set providerGroups, String intention, String packetId, String requestString) { - return fromProcess(uid, providerGroups, intention, checkPacketId(packetId), requestString); - } - - private static String checkPacketId(String packetId) { - if (packetId == null) { - packetId = PacketIdGenerator.generateId(); - } - return packetId; - } - - private SeedResponse fromProcess(String uid, Set providerGroups, String intention, String packetId, String requestString) { - SeedResponse response = new SeedResponse(uid, providerGroups, intention, packetId); - ModelContainer model = null; - try { - requestString = StringUtils.trimToNull(requestString); - requireNotNull(requestString, "The requests parameter may not be null."); - SeedRequest[] request = MolecularModelJsonRenderer.parseFromJson(requestString, requestType); - requireNotNull(request, "The requests array may not be null"); - if (request.length == 0 || request[0] == null || request.length > 1) { - throw new MissingParameterException("The requests array must contain exactly one non-null entry"); - } - uid = normalizeUserId(uid); - UndoMetadata token = new UndoMetadata(uid); - model = createModel(uid, providerGroups, token, VariableResolver.EMPTY, null); - return seedFromProcess(uid, providerGroups, request[0].arguments, model, response, token); - } catch (Exception e) { - deleteModel(model); - return error(response, "Could not successfully handle batch request.", e); - } catch (Throwable t) { - deleteModel(model); - logger.error("A critical error occured.", t); - return error(response, "An internal error occured at the server level.", t); - } - } - - private SeedResponse seedFromProcess(String uid, Set providerGroups, SeedRequestArgument request, ModelContainer model, SeedResponse response, UndoMetadata token) throws Exception { - // check required fields - requireNotNull(request.process, "A process id is required for seeding"); - requireNotNull(request.taxon, "A taxon id is required for seeding"); - - // prepare seeder - OWLGraphWrapper graph = new OWLGraphWrapper(model.getAboxOntology()); - Set locationRoots = new HashSet(); - if (request.locationRoots != null) { - for(String loc : request.locationRoots) { - OWLClass cls = graph.getOWLClassByIdentifier(loc); - if (cls != null) { - locationRoots.add(cls); - } - } - } - Set evidenceRestriction = request.evidenceRestriction != null ? new HashSet<>(Arrays.asList(request.evidenceRestriction)) : null; - Set blackList = request.ignoreList != null ? new HashSet<>(Arrays.asList(request.ignoreList)) : null; - Set taxonRestriction = Collections.singleton(request.taxon); - ExpressionMaterializingReasoner reasoner = null; - try { - reasoner = factory.createReasoner(model.getAboxOntology()); - reasoner.setIncludeImports(true); - GolrSeedingDataProvider provider = new GolrSeedingDataProvider(golrUrl, graph, - reasoner, locationRoots, evidenceRestriction, taxonRestriction, blackList) { - - @Override - protected void logRequest(URI uri) { - logGolrRequest(uri); - } - - }; - Set defaultAnnotations = new HashSet(); - addGeneratedAnnotations(uid, providerGroups, defaultAnnotations, model.getOWLDataFactory()); - addDateAnnotation(defaultAnnotations, model.getOWLDataFactory()); - ModelSeeding seeder = new ModelSeeding(reasoner, provider, defaultAnnotations, curieHandler, ecoMapper); - - // seed - seeder.seedModel(model, m3, request.process, token); - - // render result - // create response.data - response.messageType = SeedResponse.MESSAGE_TYPE_SUCCESS; - response.message = SeedResponse.MESSAGE_TYPE_SUCCESS; - response.signal = SeedResponse.SIGNAL_META; - response.data = new SeedResponseData(); - - // model id - response.data.id = curieHandler.getCuri(model.getModelId()); - return response; - } - finally { - if (reasoner != null) { - reasoner.dispose(); - } - } - } - - protected void logGolrRequest(URI uri) { - // empty, overwrite for custom logging - } - - /* - * commentary is now to be a string, not an unknown multi-leveled object. - */ - private SeedResponse error(SeedResponse state, String msg, Throwable e) { - state.messageType = "error"; - state.message = msg; - if (e != null) { - - // Add in the exception name if possible. - String ename = e.getClass().getName(); - if( ename != null ){ - state.message = state.message + " Exception: " + ename + "."; - } - - // And the exception message. - String emsg = e.getMessage(); - if( emsg != null ){ - state.message = state.message + " " + emsg; - } - - // Add the stack trace as commentary. - StringWriter stacktrace = new StringWriter(); - e.printStackTrace(new PrintWriter(stacktrace)); - state.commentary = stacktrace.toString(); - } - return state; - } -} diff --git a/minerva-server/src/main/java/org/geneontology/minerva/server/handler/M3ExpressionParser.java b/minerva-server/src/main/java/org/geneontology/minerva/server/handler/M3ExpressionParser.java index 96fb219b..baac7fde 100644 --- a/minerva-server/src/main/java/org/geneontology/minerva/server/handler/M3ExpressionParser.java +++ b/minerva-server/src/main/java/org/geneontology/minerva/server/handler/M3ExpressionParser.java @@ -5,6 +5,7 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.ModelContainer; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; import org.geneontology.minerva.curie.CurieHandler; @@ -19,8 +20,6 @@ import org.semanticweb.owlapi.model.OWLException; import org.semanticweb.owlapi.model.OWLObjectProperty; -import owltools.graph.OWLGraphWrapper; - public class M3ExpressionParser { private final boolean checkLiteralIds; @@ -38,11 +37,11 @@ public class M3ExpressionParser { OWLClassExpression parse(ModelContainer model, JsonOwlObject expression, ExternalLookupService externalLookupService) throws MissingParameterException, UnknownIdentifierException, OWLException { - OWLGraphWrapper g = new OWLGraphWrapper(model.getAboxOntology()); + MinervaOWLGraphWrapper g = new MinervaOWLGraphWrapper(model.getAboxOntology()); return parse(g, expression, externalLookupService); } - OWLClassExpression parse(OWLGraphWrapper g, JsonOwlObject expression, + OWLClassExpression parse(MinervaOWLGraphWrapper g, JsonOwlObject expression, ExternalLookupService externalLookupService) throws MissingParameterException, UnknownIdentifierException, OWLException { if (expression == null) { @@ -119,7 +118,7 @@ else if (JsonOwlObjectType.ComplementOf == expression.type) { } } - private OWLClassExpression parse(OWLGraphWrapper g, JsonOwlObject[] expressions, + private OWLClassExpression parse(MinervaOWLGraphWrapper g, JsonOwlObject[] expressions, ExternalLookupService externalLookupService, JsonOwlObjectType type) throws MissingParameterException, UnknownIdentifierException, OWLException { if (expressions.length == 0) { @@ -144,7 +143,7 @@ else if (type == JsonOwlObjectType.IntersectionOf) { } } - private OWLClass createClass(IRI iri, OWLGraphWrapper g) { + private OWLClass createClass(IRI iri, MinervaOWLGraphWrapper g) { return g.getDataFactory().getOWLClass(iri); } diff --git a/minerva-server/src/main/java/org/geneontology/minerva/server/handler/OperationsImpl.java b/minerva-server/src/main/java/org/geneontology/minerva/server/handler/OperationsImpl.java index efa95d0b..1cb210e9 100644 --- a/minerva-server/src/main/java/org/geneontology/minerva/server/handler/OperationsImpl.java +++ b/minerva-server/src/main/java/org/geneontology/minerva/server/handler/OperationsImpl.java @@ -13,7 +13,6 @@ import org.geneontology.minerva.UndoAwareMolecularModelManager.ChangeEvent; import org.geneontology.minerva.UndoAwareMolecularModelManager.UndoMetadata; import org.geneontology.minerva.json.*; -import org.geneontology.minerva.legacy.GafExportTool; import org.geneontology.minerva.legacy.sparql.ExportExplanation; import org.geneontology.minerva.legacy.sparql.GPADSPARQLExport; import org.geneontology.minerva.lookup.ExternalLookupService; @@ -685,17 +684,17 @@ private void exportLegacy(M3BatchResponse response, ModelContainer model, String initMetaResponse(response); response.data.exportModel = ExportExplanation.exportExplanation(m3.createInferredModel(model.getModelId()), externalLookupService, m3.getLegacyRelationShorthandIndex()); } else { - final GafExportTool exportTool = GafExportTool.getInstance(); - if (format == null) { - format = "gaf"; // set a default format, if necessary - } - Map allExported = exportTool.exportModelLegacy(model, curieHandler, externalLookupService, Collections.singleton(format)); - String exported = allExported.get(format); - if (exported == null) { +// final GafExportTool exportTool = GafExportTool.getInstance(); +// if (format == null) { +// format = "gaf"; // set a default format, if necessary +// } +// Map allExported = exportTool.exportModelLegacy(model, curieHandler, externalLookupService, Collections.singleton(format)); +// String exported = allExported.get(format); +// if (exported == null) { throw new IOException("Unknown export format: "+format); - } - initMetaResponse(response); - response.data.exportModel = exported; +// } +// initMetaResponse(response); +// response.data.exportModel = exported; } } diff --git a/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/CachingInferenceProviderCreatorImpl.java b/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/CachingInferenceProviderCreatorImpl.java index 5e747c03..9435c695 100644 --- a/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/CachingInferenceProviderCreatorImpl.java +++ b/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/CachingInferenceProviderCreatorImpl.java @@ -34,15 +34,17 @@ public static InferenceProviderCreator createElk(boolean useSLME, MinervaShexVal return new CachingInferenceProviderCreatorImpl(new ElkReasonerFactory(), 1, useSLME, name, shex); } - public static InferenceProviderCreator createHermiT(MinervaShexValidator shex) { - int maxConcurrent = Runtime.getRuntime().availableProcessors(); - return createHermiT(maxConcurrent, shex); - } +//TODO current Hermit doesn't provide a reasonerfactory ? +//Not using hermit anyway, can probably just delete. +// public static InferenceProviderCreator createHermiT(MinervaShexValidator shex) { +// int maxConcurrent = Runtime.getRuntime().availableProcessors(); +// return createHermiT(maxConcurrent, shex); +// } - public static InferenceProviderCreator createHermiT(int maxConcurrent, MinervaShexValidator shex) { - return new CachingInferenceProviderCreatorImpl(new org.semanticweb.HermiT.ReasonerFactory(), - maxConcurrent, true, "Caching Hermit-SLME", shex); - } +// public static InferenceProviderCreator createHermiT(int maxConcurrent, MinervaShexValidator shex) { +// return new CachingInferenceProviderCreatorImpl(new org.semanticweb.HermiT.ReasonerFactory(), +// maxConcurrent, true, "Caching Hermit-SLME", shex); +// } public static InferenceProviderCreator createArachne(RuleEngine arachne, MinervaShexValidator shex) { return new CachingInferenceProviderCreatorImpl(new ArachneOWLReasonerFactory(arachne), 1, false, "Caching Arachne", shex); diff --git a/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/InferenceProviderCreatorImpl.java b/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/InferenceProviderCreatorImpl.java index a75a9139..499d78f6 100644 --- a/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/InferenceProviderCreatorImpl.java +++ b/minerva-server/src/main/java/org/geneontology/minerva/server/inferences/InferenceProviderCreatorImpl.java @@ -50,14 +50,14 @@ public static InferenceProviderCreator createElk(boolean useSLME, MinervaShexVal return new InferenceProviderCreatorImpl(new ElkReasonerFactory(), 1, useSLME, name, shex); } - public static InferenceProviderCreator createHermiT(MinervaShexValidator shex) { - int maxConcurrent = Runtime.getRuntime().availableProcessors(); - return createHermiT(maxConcurrent, shex); - } +// public static InferenceProviderCreator createHermiT(MinervaShexValidator shex) { +// int maxConcurrent = Runtime.getRuntime().availableProcessors(); +// return createHermiT(maxConcurrent, shex); +// } - public static InferenceProviderCreator createHermiT(int maxConcurrent, MinervaShexValidator shex) { - return new InferenceProviderCreatorImpl(new org.semanticweb.HermiT.ReasonerFactory(), maxConcurrent, true, "Hermit-SLME", shex); - } +// public static InferenceProviderCreator createHermiT(int maxConcurrent, MinervaShexValidator shex) { +// return new InferenceProviderCreatorImpl(new org.semanticweb.HermiT.ReasonerFactory(), maxConcurrent, true, "Hermit-SLME", shex); +// } @Override public InferenceProvider create(ModelContainer model) throws OWLOntologyCreationException, InterruptedException { diff --git a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/BatchModelHandlerTest.java b/minerva-server/src/test/java/org/geneontology/minerva/server/handler/BatchModelHandlerTest.java index 4a03539e..6a1ab5ba 100644 --- a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/BatchModelHandlerTest.java +++ b/minerva-server/src/test/java/org/geneontology/minerva/server/handler/BatchModelHandlerTest.java @@ -1,6 +1,7 @@ package org.geneontology.minerva.server.handler; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.UndoAwareMolecularModelManager; import org.geneontology.minerva.curie.CurieHandler; import org.geneontology.minerva.curie.CurieMappings; @@ -26,7 +27,7 @@ import org.semanticweb.owlapi.model.OWLObjectProperty; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.parameters.Imports; -import owltools.graph.OWLGraphWrapper; + import owltools.io.ParserWrapper; import java.io.IOException; @@ -59,7 +60,7 @@ public static void setUpBeforeClass() throws Exception { } static void init(ParserWrapper pw) throws OWLOntologyCreationException, IOException, UnknownIdentifierException { - final OWLGraphWrapper graph = pw.parseToOWLGraph("src/test/resources/go-lego-minimal.owl"); + final MinervaOWLGraphWrapper graph = pw.parseToOWLGraph("src/test/resources/go-lego-minimal.owl"); final OWLObjectProperty legorelParent = StartUpTool.getRelation("http://purl.obolibrary.org/obo/LEGOREL_0000000", graph); assertNotNull(legorelParent); importantRelations = StartUpTool.getAssertedSubProperties(legorelParent, graph); diff --git a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/M3ExpressionParserTest.java b/minerva-server/src/test/java/org/geneontology/minerva/server/handler/M3ExpressionParserTest.java index 49755e8e..4e94662b 100644 --- a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/M3ExpressionParserTest.java +++ b/minerva-server/src/test/java/org/geneontology/minerva/server/handler/M3ExpressionParserTest.java @@ -5,6 +5,7 @@ import java.io.File; import java.io.IOException; +import org.geneontology.minerva.MinervaOWLGraphWrapper; import org.geneontology.minerva.MolecularModelManager.UnknownIdentifierException; import org.geneontology.minerva.curie.CurieHandler; import org.geneontology.minerva.curie.DefaultCurieHandler; @@ -22,13 +23,12 @@ import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; import org.semanticweb.owlapi.model.OWLOntologyCreationException; -import owltools.graph.OWLGraphWrapper; import owltools.io.ParserWrapper; public class M3ExpressionParserTest { private static final CurieHandler curieHandler = DefaultCurieHandler.getDefaultHandler(); - private static OWLGraphWrapper graph; + private static MinervaOWLGraphWrapper graph; // these are present in the test module private static final String CELL_MORPHOGENESIS = "GO:0000902"; @@ -43,7 +43,7 @@ public static void setUpBeforeClass() throws Exception { static void init(ParserWrapper pw) throws OWLOntologyCreationException, IOException { /* File file = new File("src/test/resources/go-lego-module.omn.gz").getCanonicalFile(); */ File file = new File("src/test/resources/go-lego-module-compact.omn.gz").getCanonicalFile(); - graph = new OWLGraphWrapper(pw.parseOWL(IRI.create(file))); + graph = new MinervaOWLGraphWrapper(pw.parseOWL(IRI.create(file))); } @Test(expected=MissingParameterException.class) diff --git a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/SeedHandlerTest.java b/minerva-server/src/test/java/org/geneontology/minerva/server/handler/SeedHandlerTest.java deleted file mode 100644 index 50dc0f67..00000000 --- a/minerva-server/src/test/java/org/geneontology/minerva/server/handler/SeedHandlerTest.java +++ /dev/null @@ -1,118 +0,0 @@ -package org.geneontology.minerva.server.handler; - -import org.geneontology.minerva.ModelContainer; -import org.geneontology.minerva.UndoAwareMolecularModelManager; -import org.geneontology.minerva.curie.CurieHandler; -import org.geneontology.minerva.curie.CurieMappings; -import org.geneontology.minerva.curie.DefaultCurieHandler; -import org.geneontology.minerva.curie.MappedCurieHandler; -import org.geneontology.minerva.json.MolecularModelJsonRenderer; -import org.geneontology.minerva.server.handler.M3BatchHandler.M3BatchResponse; -import org.geneontology.minerva.server.handler.M3SeedHandler.SeedRequest; -import org.geneontology.minerva.server.handler.M3SeedHandler.SeedRequestArgument; -import org.geneontology.minerva.server.handler.M3SeedHandler.SeedResponse; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.rules.TemporaryFolder; -import org.semanticweb.owlapi.apibinding.OWLManager; -import org.semanticweb.owlapi.model.IRI; -import org.semanticweb.owlapi.model.OWLOntology; -import owltools.gaf.eco.EcoMapperFactory; -import owltools.gaf.eco.SimpleEcoMapper; -import owltools.io.ParserWrapper; - -import java.io.File; -import java.net.URI; -import java.util.Collections; -import java.util.Set; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class SeedHandlerTest { - - @ClassRule - public static TemporaryFolder folder = new TemporaryFolder(); - - private static CurieHandler curieHandler = null; - private static JsonOrJsonpSeedHandler handler = null; - private static UndoAwareMolecularModelManager models = null; - - private static final String uid = "test-user"; - private static final Set providedBy = Collections.singleton("test-provider"); - private static final String intention = "test-intention"; - private static final String packetId = "foo-packet-id"; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - init(new ParserWrapper(), "http://golr.geneontology.org/solr"); - } - - static void init(ParserWrapper pw, String golr) throws Exception { - //TODO need more from go-lego - final OWLOntology tbox = OWLManager.createOWLOntologyManager().loadOntology(IRI.create(new File("src/test/resources/go-lego-minimal.owl"))); - // curie handler - final String modelIdcurie = "gomodel"; - final String modelIdPrefix = "http://model.geneontology.org/"; - final CurieMappings localMappings = new CurieMappings.SimpleCurieMappings(Collections.singletonMap(modelIdcurie, modelIdPrefix)); - curieHandler = new MappedCurieHandler(DefaultCurieHandler.loadDefaultMappings(), localMappings); - models = new UndoAwareMolecularModelManager(tbox, curieHandler, modelIdPrefix, folder.newFile().getAbsolutePath(), null); - SimpleEcoMapper ecoMapper = EcoMapperFactory.createSimple(); - handler = new JsonOrJsonpSeedHandler(models, "unknown", golr, ecoMapper) { - - @Override - protected void logGolrRequest(URI uri) { - System.err.println(uri); - } - - }; - } - - @AfterClass - public static void tearDownAfterClass() throws Exception { - if (handler != null) { - handler = null; - } - if (models != null) { - models.dispose(); - } - } - - //FIXME @Test - public void test1() throws Exception { - // B cell apoptotic process - // mouse - SeedResponse response = seed("GO:0001783", "NCBITaxon:10090"); - assertNotNull(response.data.id); - ModelContainer model = models.getModel(curieHandler.getIRI(response.data.id)); - assertNotNull(model); - MolecularModelJsonRenderer renderer = new MolecularModelJsonRenderer(model, null, curieHandler); - String json = toJson(renderer.renderModel()); - System.out.println("-----------"); - System.out.println(json); - System.out.println("-----------"); - } - - private SeedResponse seed(String process, String taxon) throws Exception { - SeedRequest request = new SeedRequest(); - request.arguments = new SeedRequestArgument(); - request.arguments.process = process; - request.arguments.taxon = taxon; - return seed(request); - } - - private SeedResponse seed(SeedRequest request) { - String json = MolecularModelJsonRenderer.renderToJson(new SeedRequest[]{request}, false); - SeedResponse response = handler.fromProcessGetPrivileged(uid, providedBy, intention, packetId, json); - assertEquals(uid, response.uid); - assertEquals(intention, response.intention); - assertEquals(response.message, M3BatchResponse.MESSAGE_TYPE_SUCCESS, response.messageType); - return response; - } - - private String toJson(Object data) { - String json = MolecularModelJsonRenderer.renderToJson(data, true); - return json; - } -} diff --git a/pom.xml b/pom.xml index 2ba3224d..05425295 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,6 @@ UTF-8 - 0.3.0-SNAPSHOT 4.5.13 2.7.12 9.2.3.v20140905 @@ -138,56 +137,6 @@ gson 2.8.5 - - org.bbop - OWLTools-Annotation - ${owltools.version} - - - commons-logging - commons-logging - - - org.apache.jena - jena-core - - - - - org.bbop - OWLTools-Core - ${owltools.version} - test-jar - test - - - commons-logging - commons-logging - - - - - org.bbop - golr-client - ${owltools.version} - - - commons-logging - commons-logging - - - - - org.bbop - OWLTools-Runner - ${owltools.version} - - - commons-logging - commons-logging - - - org.eclipse.jetty jetty-server @@ -373,7 +322,6 @@ 3.12.0 pom - net.sf.trove4j trove4j