SpeciesSubsetterUtil { public Collection<List<OWLObject>> explainTaxonConstraint(Collection<String> clsIds, Collection<String> taxonIds) throws IllegalArgumentException { if (LOG.isInfoEnabled()) { LOG.info("Start explaining taxon constraints of classes " + clsIds + " in taxa " + taxonIds); } OWLGraphManipulator manip = new OWLGraphManipulator(graph, false); manip.removeUnrelatedRelations(Arrays.asList(IN_TAXON_ID)); Set<OWLClass> taxa = new HashSet<OWLClass>(); Set<OWLClass> taxonAncestors = new HashSet<OWLClass>(); Map<OWLClass, Set<OWLClass>> taxaWithDescendants = new HashMap<OWLClass, Set<OWLClass>>(); for (String taxonId: taxonIds) { OWLClass taxon = graph.getOWLClassByIdentifier(taxonId); if (taxon == null) { throw new IllegalArgumentException("The provided taxon ID " + taxonId + " does not exist in the provided ontology."); } taxa.add(taxon); taxonAncestors.addAll(graph.getOWLClassAncestors(taxon)); taxaWithDescendants.put(taxon, graph.getOWLClassDescendants(taxon)); } OWLAnnotationProperty neverInTaxon = fac.getOWLAnnotationProperty( graph.getIRIByIdentifier(NEVER_IN_TAXON_ID)); Map<OWLClass, Set<OWLClass>> neverInTaxa = this.neverInTaxa(); Collection<List<OWLObject>> allExplanations = new ArrayList<List<OWLObject>>(); for (String clsId: clsIds) { OWLClass cls = graph.getOWLClassByIdentifier(clsId); if (cls == null) { throw new IllegalArgumentException("The provided class ID " + clsId + " does not exist in the provided ontology."); } Deque<List<OWLObject>> walks = new ArrayDeque<List<OWLObject>>(); walks.add(new ArrayList<OWLObject>(Arrays.asList(cls))); List<OWLObject> aWalk; Set<OWLClass> alreadyWalked = new HashSet<OWLClass>(); while ((aWalk = walks.pollFirst()) != null) { OWLObject currentStep = aWalk.get(aWalk.size() - 1); OWLClass clsToWalk = null; if (currentStep instanceof OWLClass) { clsToWalk = (OWLClass) currentStep; } else { Set<OWLGraphEdge> edges = graph.getOutgoingEdges(currentStep); if (edges.size() != 1 || !(edges.iterator().next().getTarget() instanceof OWLClass)) { throw new AssertionError("Unexpected class expression walked: " + currentStep); } clsToWalk = (OWLClass) edges.iterator().next().getTarget(); } if (!alreadyWalked.add(clsToWalk)) { continue; } for (OWLGraphEdge edge: graph.getOutgoingEdges(clsToWalk)) { if (this.isInTaxonEdge(edge) && edge.getTarget() instanceof OWLClass) { OWLClass targetedTaxon = (OWLClass) edge.getTarget(); boolean constraintUsed = false; if (taxa.contains(targetedTaxon) || taxonAncestors.contains(targetedTaxon)) { constraintUsed = true; } else { for (Set<OWLClass> descendants: taxaWithDescendants.values()) { if (!descendants.contains(targetedTaxon)) { constraintUsed = true; break; } } } if (constraintUsed) { List<OWLObject> explanation = new ArrayList<OWLObject>(aWalk); explanation.add(graph.edgeToTargetExpression(edge)); allExplanations.add(explanation); } } } Set<OWLClass> clsNeverInTaxa = neverInTaxa.get(clsToWalk); if (clsNeverInTaxa != null) { for (OWLClass targetedTaxon: clsNeverInTaxa) { if (taxa.contains(targetedTaxon) || taxonAncestors.contains(targetedTaxon)) { List<OWLObject> explanation = new ArrayList<OWLObject>(aWalk); explanation.add(fac.getOWLAnnotation(neverInTaxon, targetedTaxon.getIRI())); allExplanations.add(explanation); } } } for (OWLGraphEdge edge: graph.getOutgoingEdges(clsToWalk)) { if (!this.isInTaxonEdge(edge)) { List<OWLObject> walkContinue = new ArrayList<OWLObject>(aWalk); walkContinue.add(graph.edgeToTargetExpression(edge)); walks.offerLast(walkContinue); } } } } if (LOG.isInfoEnabled()) { LOG.info("Done explaining taxon constraints, explanations: " + allExplanations); } return allExplanations; } SpeciesSubsetterUtil(OWLGraphWrapper g);  SpeciesSubsetterUtil(OWLGraphWrapper g, boolean performMacroExpansion); void removeOtherSpecies(); void removeSpecies(); Collection<List<OWLObject>> explainTaxonConstraint(Collection<String> clsIds, 
	        Collection<String> taxonIds); public OWLReasoner reasoner; public OWLObjectProperty viewProperty; public OWLClass taxClass; public OWLClass rootClass; }
@SuppressWarnings("unchecked") @Test public void testExplainTaxonConstraint() throws Exception { ParserWrapper p = new ParserWrapper(); OWLOntology owlOntology = p.parse(getResourceIRIString("graph/explainConstraints.owl")); OWLGraphWrapper graph = new OWLGraphWrapper(owlOntology); OWLDataFactory factory = owlOntology.getOWLOntologyManager().getOWLDataFactory(); String clsId1 = "UBERON:0000001"; String clsId2 = "UBERON:0000002"; String clsId3 = "UBERON:0000003"; String clsId4 = "UBERON:0000004"; String clsId5 = "UBERON:0000005"; String clsId6 = "UBERON:0000006"; String clsId7 = "UBERON:0000007"; OWLClass cls1 = graph.getOWLClassByIdentifier(clsId1); OWLClass cls2 = graph.getOWLClassByIdentifier(clsId2); OWLClass cls3 = graph.getOWLClassByIdentifier(clsId3); OWLClass cls4 = graph.getOWLClassByIdentifier(clsId4); OWLClass cls5 = graph.getOWLClassByIdentifier(clsId5); OWLClass cls6 = graph.getOWLClassByIdentifier(clsId6); OWLClass cls7 = graph.getOWLClassByIdentifier(clsId7); String taxonId1 = "NCBITaxon:1"; String taxonId2 = "NCBITaxon:2"; String taxonId3 = "NCBITaxon:3"; OWLClass taxon1 = graph.getOWLClassByIdentifier(taxonId1); OWLClass taxon2 = graph.getOWLClassByIdentifier(taxonId2); OWLClass taxon3 = graph.getOWLClassByIdentifier(taxonId3); OWLObjectProperty partOf = graph.getOWLObjectPropertyByIdentifier("BFO:0000050"); OWLObjectProperty onlyInTaxon = graph.getOWLObjectPropertyByIdentifier("RO:0002160"); OWLAnnotationProperty neverInTaxon = factory.getOWLAnnotationProperty( graph.getIRIByIdentifier("RO:0002161")); SpeciesSubsetterUtil smu = new SpeciesSubsetterUtil(graph); List<OWLObject> expectedExplain1 = Arrays.asList((OWLObject) cls1, factory.getOWLObjectSomeValuesFrom(onlyInTaxon, taxon1)); assertEquals(expectedExplain1, smu.explainTaxonConstraint(Arrays.asList(clsId1), Arrays.asList(taxonId1)). iterator().next()); assertEquals(expectedExplain1, smu.explainTaxonConstraint(Arrays.asList(clsId1), Arrays.asList(taxonId2)). iterator().next()); assertEquals(expectedExplain1, smu.explainTaxonConstraint(Arrays.asList(clsId1), Arrays.asList(taxonId3)). iterator().next()); List<OWLObject> expectedExplain2 = Arrays.asList((OWLObject) cls2, factory.getOWLObjectSomeValuesFrom(onlyInTaxon, taxon2)); assertEquals(expectedExplain2, smu.explainTaxonConstraint(Arrays.asList(clsId2), Arrays.asList(taxonId2)). iterator().next()); assertEquals(expectedExplain2, smu.explainTaxonConstraint(Arrays.asList(clsId2), Arrays.asList(taxonId3)). iterator().next()); List<OWLObject> expectedExplain3 = Arrays.asList((OWLObject) cls2, cls1, factory.getOWLObjectSomeValuesFrom(onlyInTaxon, taxon1)); assertEquals(expectedExplain3, smu.explainTaxonConstraint(Arrays.asList(clsId2), Arrays.asList(taxonId1)). iterator().next()); List<OWLObject> expectedExplain4 = Arrays.asList(cls3, factory.getOWLAnnotation(neverInTaxon, taxon3.getIRI())); assertEquals(expectedExplain4, smu.explainTaxonConstraint(Arrays.asList(clsId3), Arrays.asList(taxonId3)). iterator().next()); assertTrue(smu.explainTaxonConstraint(Arrays.asList(clsId3), Arrays.asList(taxonId1)). isEmpty()); assertTrue(smu.explainTaxonConstraint(Arrays.asList(clsId3), Arrays.asList(taxonId2)). isEmpty()); List<OWLObject> expectedExplain5 = Arrays.asList(cls4, factory.getOWLAnnotation(neverInTaxon, taxon2.getIRI())); assertEquals(expectedExplain5, smu.explainTaxonConstraint(Arrays.asList(clsId4), Arrays.asList(taxonId2)). iterator().next()); List<OWLObject> expectedExplain6 = Arrays.asList(cls4, factory.getOWLObjectSomeValuesFrom(partOf, cls3), factory.getOWLAnnotation(neverInTaxon, taxon3.getIRI())); assertEquals(expectedExplain6, smu.explainTaxonConstraint(Arrays.asList(clsId4), Arrays.asList(taxonId3)). iterator().next()); assertTrue(smu.explainTaxonConstraint(Arrays.asList(clsId4), Arrays.asList(taxonId1)). isEmpty()); List<OWLObject> expectedExplain7 = Arrays.asList(cls7, factory.getOWLObjectSomeValuesFrom(partOf, cls6), factory.getOWLObjectSomeValuesFrom(partOf, cls5), factory.getOWLAnnotation(neverInTaxon, taxon1.getIRI())); assertEquals(expectedExplain7, smu.explainTaxonConstraint(Arrays.asList(clsId7), Arrays.asList(taxonId2)). iterator().next()); assertEquals(expectedExplain7, smu.explainTaxonConstraint(Arrays.asList(clsId7), Arrays.asList(taxonId3)). iterator().next()); assertEquals(expectedExplain7, smu.explainTaxonConstraint(Arrays.asList(clsId7), Arrays.asList(taxonId1)). iterator().next()); Collection<List<OWLObject>> allExplanations = smu.explainTaxonConstraint( Arrays.asList(clsId1, clsId2, clsId3, clsId4, clsId7), Arrays.asList(taxonId1, taxonId2, taxonId3)); assertTrue("Incorrect explanations returned, expected " + Arrays.asList(expectedExplain1, expectedExplain2, expectedExplain4, expectedExplain5, expectedExplain7) + ", but was: " + allExplanations, allExplanations.size() == 7 && allExplanations.contains(expectedExplain1) && allExplanations.contains(expectedExplain2) && allExplanations.contains(expectedExplain3) && allExplanations.contains(expectedExplain4) && allExplanations.contains(expectedExplain5) && allExplanations.contains(expectedExplain6) && allExplanations.contains(expectedExplain7)); }