From 07eeeefd0bb2c08f90bba8098ed53d8cd9d964d8 Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Fri, 19 Jan 2018 18:34:18 -0800 Subject: [PATCH 1/5] remint --- .../java/owltools/mooncat/AxiomCopier.java | 136 ++++++++++++++++-- .../main/java/owltools/cli/CommandRunner.java | 62 +++++++- 2 files changed, 186 insertions(+), 12 deletions(-) diff --git a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java index e35a3af17..10c9f8a78 100644 --- a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java +++ b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java @@ -1,8 +1,10 @@ package owltools.mooncat; +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; @@ -22,12 +24,15 @@ import org.semanticweb.owlapi.model.OWLLiteral; import org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom; import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyChange; import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; +import org.semanticweb.owlapi.model.parameters.ChangeApplied; import org.semanticweb.owlapi.model.parameters.Imports; import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; +import org.semanticweb.owlapi.util.OWLEntityRenamer; import uk.ac.manchester.cs.owlapi.modularity.ModuleType; import uk.ac.manchester.cs.owlapi.modularity.SyntacticLocalityModuleExtractor; @@ -63,8 +68,13 @@ public class AxiomCopier { * We have 2 strategies; see below */ public boolean isUseConservative = true; + + public boolean isIncludeUnmapped = false; + public OWLReasonerFactory reasonerFactory = new ElkReasonerFactory(); + public boolean isCopyLabelToExactSynonym = true; + /** @@ -198,6 +208,13 @@ else if (ax instanceof OWLAnnotationAssertionAxiom) { } } + if (isIncludeUnmapped) { + // seed with reflexive mappings + for (OWLClass c : sourceOnt.getClassesInSignature(Imports.EXCLUDED)) { + eqMap.put(c, c); + } + } + // build equivalence map S->T, pointing source classes to target classes // this map is reflexive for (OWLAxiom ax : mapOnt.getAxioms(Imports.INCLUDED)) { @@ -306,17 +323,29 @@ else if (ax instanceof OWLAnnotationAssertionAxiom){ // OBO convention: xref annotations are treated differently for // axiom annotations (as are defs) boolean isXrefAnn = aax.getProperty().getIRI().toString().contains("Synonym"); - - OWLAnnotationAssertionAxiom newAxiom = df.getOWLAnnotationAssertionAxiom(aax.getProperty(), - eqMap.get(srcClass).getIRI(), - aax.getValue(), - anns(df, srcClass, isXrefAnn)); - AnnTuple tup = getAnnTuple(newAxiom); + OWLAnnotationProperty ap1 = aax.getProperty(); + Set aps = new HashSet<>(); + aps.add(ap1); + if (ap1.isLabel()) { + if (isCopyLabelToExactSynonym) { + OWLAnnotationProperty sp = + df.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#hasExactSynonym")); + + aps.add(sp); + } + } + for (OWLAnnotationProperty ap: aps) { + OWLAnnotationAssertionAxiom newAxiom = df.getOWLAnnotationAssertionAxiom(ap, + eqMap.get(srcClass).getIRI(), + aax.getValue(), + anns(df, srcClass, isXrefAnn)); + AnnTuple tup = getAnnTuple(newAxiom); - boolean isDupe = annTuples.contains(tup) || - axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations()); - if (isCopyDuplicates || !isDupe) { + boolean isDupe = annTuples.contains(tup) || + axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations()); + if (isCopyDuplicates || !isDupe) { axiomsToAdd.add(newAxiom); + } } } } @@ -440,6 +469,93 @@ public Set findIncoherentAxioms(OWLReasonerFactory rf, return badAxioms; } - + + public class IdAssigner { + public OWLOntology ontology; + public String prefix; + Integer lastId = 0; + Set taken = null; + } + + public IRI getNextId(IdAssigner ida) { + //int id = ida.lastId; + Set taken = ida.taken; + + if (taken == null) { + taken = new HashSet<>(); + for (OWLClass cls : ida.ontology.getClassesInSignature()) { + String frag = cls.getIRI().getFragment(); + String[] parts = frag.split("_"); + if (parts.length == 2) { + String id = parts[0] + ":" + parts[1]; + taken.add(id); + String prefix = parts[0]; + if (ida.prefix == null) + ida.prefix = prefix; + if (ida.prefix.equals(prefix)) { + } + else { + // + } + } + else { + // warn + } + } + } + String id = null; + while (id == null) { + ida.lastId ++; + String nextid = ida.prefix + String.format(":%07d", ida.lastId); + if (!taken.contains(nextid)) { + id = nextid; + } + } + + return IRI.create(id); + + } + + public void remintOntologyIds(OWLOntology ontology, String prefix, boolean isCreateLabels) { + IdAssigner ida = new IdAssigner(); + ida.ontology = ontology; + ida.prefix = prefix; + remintOntologyIds(ontology, ida, isCreateLabels); + } + + /** + * Mint new IDs for all classes in an ontology + * + * @param ontology + * @param ida + */ + public void remintOntologyIds(OWLOntology ontology, IdAssigner ida, boolean isCreateLabels) { + if (ida == null) { + ida = new IdAssigner(); + ida.ontology = ontology; + } + OWLOntologyManager m = ontology.getOWLOntologyManager(); + OWLDataFactory df = m.getOWLDataFactory(); + Map iriMap = new HashMap<>(); + OWLEntityRenamer renamer = new OWLEntityRenamer(m, + ontology.getImportsClosure()); + List changes = new ArrayList (); + for (OWLClass c : ontology.getClassesInSignature()) { + IRI id = getNextId(ida); + iriMap.put(c.getIRI(), id); + List ch = + renamer.changeIRI(c.getIRI(), id); + changes.addAll(ch); + if (isCreateLabels) { + String label = c.getIRI().getFragment(); + label = label.replaceAll("_", " "); + OWLAnnotationValue value = df.getOWLLiteral(label); + OWLAnnotationAssertionAxiom ax = + df.getOWLAnnotationAssertionAxiom(df.getRDFSLabel(), id, value); + m.addAxiom(ontology, ax); + } + } + m.applyChanges(changes); + } } diff --git a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java index 41f44dfd2..9795dd2b3 100644 --- a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java +++ b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java @@ -168,6 +168,7 @@ import owltools.io.TableRenderer; import owltools.io.TableToAxiomConverter; import owltools.mooncat.AxiomCopier; +import owltools.mooncat.AxiomCopier.IdAssigner; import owltools.mooncat.BridgeExtractor; import owltools.mooncat.Diff; import owltools.mooncat.DiffUtil; @@ -1146,7 +1147,7 @@ else if (opts.nextEq("--remove-deprecation-axioms")) { isPreserveDeprecations = true; } else if (opts.nextEq("-r|--preserve-relations")) { - opts.info("", "unless specified, all axioms about properties are removed"); + opts.info("", "unless this is specified, all axioms about properties are removed"); isPreserveRelations = true; } else if (opts.nextEq("-p|--preserve-property")) { @@ -2798,6 +2799,44 @@ else if (opts.nextEq("--reason-subontologies")) { g.getManager().applyChange(x); } } + else if (opts.nextEq("--export-inferences")) { + opts.info("[-r reasonername]", "infer new relationships and generate new ontology"); + + while (opts.hasOpts()) { + if (opts.nextEq("-r")) { + opts.info("REASONERNAME", "selects the reasoner to use"); + reasonerName = opts.nextOpt(); + } + else { + break; + } + } + if (reasoner == null) { + reasoner = createReasoner(g.getSourceOntology(),reasonerName,g.getManager()); + } + Set unsats = reasoner.getUnsatisfiableClasses().getEntitiesMinusBottom(); + if (unsats.size() > 0) { + LOG.error("UNSATS: "+ unsats); + } + OWLOntology ont = g.getManager().createOntology(); + OWLDataFactory df = g.getDataFactory(); + for (OWLClass c : g.getAllOWLClasses()) { + Set directSupers = reasoner.getSuperClasses(c, true).getFlattened(); + Set indirectSupers = reasoner.getSuperClasses(c, false).getFlattened(); + for (OWLClass superClass : indirectSupers) { + boolean isDirect = directSupers.contains(superClass); + OWLAnnotationProperty p = + df.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#source")); + OWLAnnotation ann = df.getOWLAnnotation(p, + df.getOWLLiteral("OWLReasoner")); + Set anns = Collections.singleton(ann); + OWLSubClassOfAxiom ax = + df.getOWLSubClassOfAxiom(c, superClass, anns); + g.getManager().addAxiom(ont, ax); + } + } + g.setSourceOntology(ont); + } else if (opts.nextEq("--run-reasoner")) { opts.info("[-r reasonername] [--assert-implied] [--indirect] [-u] [-m UNSATMODFILE]", "infer new relationships"); boolean isAssertImplied = false; @@ -3035,12 +3074,26 @@ else if (opts.nextEq("--trace-module-axioms")) { } } } + else if (opts.nextEq("--remint-ids")) { + opts.info("", "generate new class IRIs for an ontology"); + AxiomCopier cp = new AxiomCopier(); + String prefix = null; + while (opts.hasOpts()) { + if (opts.nextEq("p|--prefix")) { + opts.info("PREFIX", "prefix for new ids"); + prefix = opts.nextOpt(); + } + else { + break; + } + } + cp.remintOntologyIds(g.getSourceOntology(), prefix, true); + } else if (opts.nextEq("--copy-axioms")) { opts.info("[-m MAPONT] [-s SRCONT] [-n] [-l] [--no-strict]", "copies axioms from SRC to current (target) ontology"); AxiomCopier copier = new AxiomCopier(); OWLOntology mapOnt = null; - OWLOntology targetOnt = g.getSourceOntology(); OWLOntology sourceOnt = null; boolean isCopyDuplicates = false; boolean isTestForCoherency = false; @@ -3063,6 +3116,10 @@ else if (opts.nextEq("-l|--logic")) { opts.info("", "if true, do logical test for coherency on each logical axiom"); isTestForCoherency = true; } + else if (opts.nextEq("-a|--all")) { + opts.info("", "if true, bring all classes from source across, even if unmapped"); + copier.isIncludeUnmapped = true; + } else if (opts.nextEq("--no-strict")) { opts.info( "", "if set, perform less rigorous filtering. "+ @@ -3079,6 +3136,7 @@ else if (opts.nextEq("-d|--copy-duplicates")) { break; } } + OWLOntology targetOnt = g.getSourceOntology(); copier.isCopyDuplicates = isCopyDuplicates; copier.isTestForCoherency = isTestForCoherency; Set axioms = copier.copyAxioms(sourceOnt, targetOnt, mapOnt); From 34ac462411b6f280646dea12174407972915d8de Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Fri, 26 Jan 2018 17:54:00 -0800 Subject: [PATCH 2/5] added remint command --- .../owltools/mooncat/ProvenanceReasonerWrapperTest.java | 6 +++++- OWLTools-Parent/pom.xml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/OWLTools-Core/src/test/java/owltools/mooncat/ProvenanceReasonerWrapperTest.java b/OWLTools-Core/src/test/java/owltools/mooncat/ProvenanceReasonerWrapperTest.java index ad250e475..b97c2fc1e 100644 --- a/OWLTools-Core/src/test/java/owltools/mooncat/ProvenanceReasonerWrapperTest.java +++ b/OWLTools-Core/src/test/java/owltools/mooncat/ProvenanceReasonerWrapperTest.java @@ -7,6 +7,8 @@ import org.junit.Test; import org.semanticweb.elk.owlapi.ElkReasonerFactory; import org.semanticweb.owlapi.model.OWLOntology; +import org.semanticweb.owlapi.model.OWLOntologyIRIMapper; +import org.semanticweb.owlapi.util.PriorityCollection; import owltools.OWLToolsTestBasics; import owltools.io.CatalogXmlIRIMapper; @@ -23,7 +25,9 @@ public class ProvenanceReasonerWrapperTest extends OWLToolsTestBasics { @Test public void testReason() throws Exception { ParserWrapper pw = new ParserWrapper(); - pw.getManager().getIRIMappers().add(new CatalogXmlIRIMapper(getResource("mooncat/eq-lattice/catalog-v001.xml"))); + CatalogXmlIRIMapper cm = new CatalogXmlIRIMapper(getResource("mooncat/eq-lattice/catalog-v001.xml")); + PriorityCollection im = pw.getManager().getIRIMappers(); + im.add(cm); OWLOntology o = pw.parseOWL(getResourceIRIString("mooncat/eq-lattice/eq-with-imports.owl")); diff --git a/OWLTools-Parent/pom.xml b/OWLTools-Parent/pom.xml index 8c98d11d0..cb439aefd 100644 --- a/OWLTools-Parent/pom.xml +++ b/OWLTools-Parent/pom.xml @@ -18,7 +18,7 @@ UTF-8 - 4.5.0 + 4.2.8 1.7.10 From b4cc2e8a531b3a2e96c990fc594d0a18ddce8d9b Mon Sep 17 00:00:00 2001 From: Chris Mungall Date: Thu, 15 Feb 2018 11:31:40 -0800 Subject: [PATCH 3/5] logging --- .../src/main/java/owltools/gaf/inference/FoldBasedPredictor.java | 1 + 1 file changed, 1 insertion(+) diff --git a/OWLTools-Annotation/src/main/java/owltools/gaf/inference/FoldBasedPredictor.java b/OWLTools-Annotation/src/main/java/owltools/gaf/inference/FoldBasedPredictor.java index 7f36907a6..cd7fa3e92 100644 --- a/OWLTools-Annotation/src/main/java/owltools/gaf/inference/FoldBasedPredictor.java +++ b/OWLTools-Annotation/src/main/java/owltools/gaf/inference/FoldBasedPredictor.java @@ -171,6 +171,7 @@ public List predictForBioEntities(Map Date: Mon, 19 Feb 2018 13:31:05 -0800 Subject: [PATCH 4/5] added option --exclude-seen-literals for copy-axioms --- .../java/owltools/mooncat/AxiomCopier.java | 24 ++++++++++++++++--- .../main/java/owltools/cli/CommandRunner.java | 4 ++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java index 10c9f8a78..c294eba52 100644 --- a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java +++ b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java @@ -57,7 +57,13 @@ public class AxiomCopier { * We may want to do this if we want to annotate an axiom with all sources */ public boolean isCopyDuplicates = false; - + + /** + * If true, exclude annotation axiom if we already have seen the literal + * (regardless of axiom) + */ + public boolean isFreshLiteralsOnly = false; + /** * If true, check all incoming axioms to ensure they do not cause * incoherency @@ -73,7 +79,7 @@ public class AxiomCopier { public OWLReasonerFactory reasonerFactory = new ElkReasonerFactory(); - public boolean isCopyLabelToExactSynonym = true; + public boolean isCopyLabelToExactSynonym = false; @@ -180,6 +186,11 @@ public Set copyAxioms(OWLOntology sourceOnt, OWLOntology targetOnt, OW // reflexive mappings of classes S->T Map eqMap = new HashMap<>(); + // all literals encountered + Set literals = new HashSet(); + + + OWLDataFactory df = targetOnt.getOWLOntologyManager().getOWLDataFactory(); Set targetAxioms = targetOnt.getAxioms(Imports.EXCLUDED); @@ -205,6 +216,7 @@ else if (ax instanceof OWLAnnotationAssertionAxiom) { OWLAnnotationAssertionAxiom aax = (OWLAnnotationAssertionAxiom)ax; AnnTuple tup = getAnnTuple(aax); annTuples.add(tup); + literals.add(tup.val); } } @@ -322,7 +334,9 @@ else if (ax instanceof OWLAnnotationAssertionAxiom){ // OBO convention: xref annotations are treated differently for // axiom annotations (as are defs) - boolean isXrefAnn = aax.getProperty().getIRI().toString().contains("Synonym"); + boolean isXrefAnn = + aax.getProperty().getIRI().toString().contains("Synonym") || + aax.getProperty().getIRI().toString().equals("http://purl.obolibrary.org/obo/IAO_0000115"); OWLAnnotationProperty ap1 = aax.getProperty(); Set aps = new HashSet<>(); aps.add(ap1); @@ -343,10 +357,13 @@ else if (ax instanceof OWLAnnotationAssertionAxiom){ boolean isDupe = annTuples.contains(tup) || axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations()); + if (isFreshLiteralsOnly && literals.contains(tup.val)) + isDupe = true; if (isCopyDuplicates || !isDupe) { axiomsToAdd.add(newAxiom); } } + axiomsToAdd.add(df.getOWLDeclarationAxiom(eqMap.get(srcClass))); } } else { @@ -388,6 +405,7 @@ private AnnTuple getAnnTuple(OWLAnnotationAssertionAxiom aax) { v = av.toString(); } v = v.toLowerCase(); + v = v.replaceAll("^ +", "").replaceAll(" +$", ""); return new AnnTuple((IRI)aax.getSubject(), v); } diff --git a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java index 9795dd2b3..fb7e47ce2 100644 --- a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java +++ b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java @@ -3120,6 +3120,10 @@ else if (opts.nextEq("-a|--all")) { opts.info("", "if true, bring all classes from source across, even if unmapped"); copier.isIncludeUnmapped = true; } + else if (opts.nextEq("-x|--exclude-seen-literals")) { + opts.info("", "if true, include only axioms with novel literals"); + copier.isFreshLiteralsOnly = true; + } else if (opts.nextEq("--no-strict")) { opts.info( "", "if set, perform less rigorous filtering. "+ From 3bfe2792f0feab3c0110a7c970db939e8b1be8d4 Mon Sep 17 00:00:00 2001 From: cmungall Date: Wed, 18 Apr 2018 19:23:26 -0700 Subject: [PATCH 5/5] minting --- .../java/owltools/mooncat/AxiomCopier.java | 67 ++++++++++++++++++- .../main/java/owltools/cli/CommandRunner.java | 15 ++++- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java index c294eba52..9a3e50ea0 100644 --- a/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java +++ b/OWLTools-Core/src/main/java/owltools/mooncat/AxiomCopier.java @@ -8,6 +8,7 @@ import java.util.Map; import java.util.Set; +import org.apache.log4j.Logger; import org.semanticweb.elk.owlapi.ElkReasonerFactory; import org.semanticweb.owlapi.model.IRI; import org.semanticweb.owlapi.model.OWLAnnotation; @@ -28,7 +29,6 @@ import org.semanticweb.owlapi.model.OWLOntologyCreationException; import org.semanticweb.owlapi.model.OWLOntologyManager; import org.semanticweb.owlapi.model.OWLSubClassOfAxiom; -import org.semanticweb.owlapi.model.parameters.ChangeApplied; import org.semanticweb.owlapi.model.parameters.Imports; import org.semanticweb.owlapi.reasoner.OWLReasoner; import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; @@ -52,12 +52,16 @@ */ public class AxiomCopier { + private static Logger LOG = Logger.getLogger(AxiomCopier.class); + /** * If true, copy axiom over even if it exists in target. * We may want to do this if we want to annotate an axiom with all sources */ public boolean isCopyDuplicates = false; + public boolean isCopyDuplicatesOnly = false; + /** * If true, exclude annotation axiom if we already have seen the literal * (regardless of axiom) @@ -80,8 +84,9 @@ public class AxiomCopier { public OWLReasonerFactory reasonerFactory = new ElkReasonerFactory(); public boolean isCopyLabelToExactSynonym = false; - - + + public boolean isIncludeInferred = false; + /** * Simple IRI-value pairs representing an Annotation minus property @@ -173,6 +178,7 @@ public String toString() { * @throws OWLOntologyCreationException */ public Set copyAxioms(OWLOntology sourceOnt, OWLOntology targetOnt, OWLOntology mapOnt) throws OWLOntologyCreationException { + LOG.info("Copying axioms..."); // axioms in targetOnt (minus annotations) Set axiomsExisting = new HashSet<>(); @@ -219,6 +225,7 @@ else if (ax instanceof OWLAnnotationAssertionAxiom) { literals.add(tup.val); } } + LOG.info("AnnTuples = "+annTuples.size()); if (isIncludeUnmapped) { // seed with reflexive mappings @@ -242,12 +249,42 @@ else if (ax instanceof OWLAnnotationAssertionAxiom) { } } } + LOG.info("eqMap = "+eqMap.size()); Set axiomsToAdd = new HashSet<>(); Set srcAxioms = sourceOnt.getAxioms(Imports.EXCLUDED); + Set inferredSrcAxioms = new HashSet<>(); + if (isIncludeInferred) { + + LOG.info("computing inferred source axioms; orig = "+srcAxioms.size()); + OWLReasoner reasoner = reasonerFactory.createReasoner(sourceOnt); + for (OWLClass c : sourceOnt.getClassesInSignature()) { + + Set ancs = new HashSet<>(reasoner.getSuperClasses(c, false).getFlattened()); + ancs.removeAll(reasoner.getSuperClasses(c, true).getFlattened()); + LOG.info("C= "+c +" ancs = "+ancs.size()); + for (OWLClass a : ancs) { + String id = c.getIRI().toString(); + id = id.replaceAll(".*/", ""); + id = id.replaceAll("_", ":"); + + OWLAnnotationProperty p = + df.getOWLAnnotationProperty(IRI.create("http://www.geneontology.org/formats/oboInOwl#source")); + OWLAnnotation ann = df.getOWLAnnotation(p, df.getOWLLiteral(id+"/inferred")); + OWLSubClassOfAxiom ax = df.getOWLSubClassOfAxiom(c, a, Collections.singleton(ann)); + srcAxioms.add(ax); + inferredSrcAxioms.add(ax); + } + + } + LOG.info("computed inferred source axioms; total = "+srcAxioms.size()); + } + if (isTestForCoherency) { + LOG.info("testing for coherency"); + Set badAxioms = findIncoherentAxioms(reasonerFactory, sourceOnt, targetOnt, mapOnt); System.out.println("ORIG:"+srcAxioms.size()); System.out.println("INCOHERENCY-CAUSING AXIOMS:"+badAxioms.size()); @@ -282,9 +319,24 @@ else if (ax instanceof OWLAnnotationAssertionAxiom) { eqMap.get(supc), anns(df, srcClass, false)); + // preserve original annotations for inferred + // (we previously stamp these) + if (inferredSrcAxioms.contains(ax)) { + newAxiom = df.getOWLSubClassOfAxiom(eqMap.get(srcClass), + eqMap.get(supc), + ax.getAnnotations()); + } + + boolean isAdd = false; // add copy to list if (isCopyDuplicates || !axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations())) { + isAdd = true; + } + if (isCopyDuplicatesOnly) { + isAdd = axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations()); + } + if (isAdd) { axiomsToAdd.add(newAxiom); } } @@ -305,11 +357,19 @@ else if (!sca.getSubClass().isAnonymous() && sca.getSuperClass().isAnonymous()) df.getOWLObjectSomeValuesFrom(x.getProperty(), eqMap.get(supc)), anns(df, srcClass, false)); + boolean isAdd = false; // add copy to list if (isCopyDuplicates || !axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations())) { + isAdd = true; + } + if (isCopyDuplicatesOnly) { + isAdd = axiomsExisting.contains(newAxiom.getAxiomWithoutAnnotations()); + } + if (isAdd) { axiomsToAdd.add(newAxiom); } + } } } @@ -371,6 +431,7 @@ else if (ax instanceof OWLAnnotationAssertionAxiom){ } } + LOG.info("Axioms to add = "+axiomsToAdd.size()); return axiomsToAdd; } diff --git a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java index fb7e47ce2..86529c57c 100644 --- a/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java +++ b/OWLTools-Runner/src/main/java/owltools/cli/CommandRunner.java @@ -3090,7 +3090,7 @@ else if (opts.nextEq("--remint-ids")) { cp.remintOntologyIds(g.getSourceOntology(), prefix, true); } else if (opts.nextEq("--copy-axioms")) { - opts.info("[-m MAPONT] [-s SRCONT] [-n] [-l] [--no-strict]", + opts.info("[-m MAPONT] [-s SRCONT] [-n] [-l] [-I] [-D] [-x] [--no-strict]", "copies axioms from SRC to current (target) ontology"); AxiomCopier copier = new AxiomCopier(); OWLOntology mapOnt = null; @@ -3101,11 +3101,11 @@ else if (opts.nextEq("--copy-axioms")) { boolean isNew = false; while (opts.hasOpts()) { if (opts.nextEq("-m|--map-ontology")) { - opts.info("ONTPATH", "REQUIRED"); + opts.info("ONTPATH", "REQUIRED - the ontology containing equiv axioms"); mapOnt = pw.parse( opts.nextOpt() ); } else if (opts.nextEq("-s|--source-ontology")) { - opts.info("ONTPATH", "REQUIRED"); + opts.info("ONTPATH", "REQUIRED - copy axioms from here"); sourceOnt = pw.parse( opts.nextOpt() ); } else if (opts.nextEq("-n|--new")) { @@ -3136,6 +3136,15 @@ else if (opts.nextEq("-d|--copy-duplicates")) { opts.info("", "if true, copy axioms that already exist"); isCopyDuplicates = true; } + else if (opts.nextEq("-I|--infer")) { + opts.info("", "if true, include inferred axioms from source"); + copier.isIncludeInferred = true; + } + else if (opts.nextEq("-D|--copy-duplicates-only")) { + opts.info("", "if true, only copy axioms if they are also in target "+ + "-- this can be used to add axiom annotations"); + copier.isCopyDuplicatesOnly = true; + } else { break; }