ModelUtils { public static void mergeEquivalentPhysicalEntities(Model model) { HashMap<BioPAXElement,BioPAXElement> subs = new HashMap<BioPAXElement, BioPAXElement>(); EquivalenceGrouper<PhysicalEntity> groups = new EquivalenceGrouper(model.getObjects(PhysicalEntity.class)); for (List<PhysicalEntity> group : groups.getBuckets()) { if (group.size() > 1) { PhysicalEntity primus = null; for (PhysicalEntity pe : group) { if (primus == null) { primus = pe; } else { copySimplePointers(model, pe, primus); if(!subs.containsKey(pe)) subs.put(pe,primus); else throw new AssertionError("mergeEquivalentPhysicalEntities: equivalence groups do intersect; " + pe.getUri() + " was in the other group as well"); } } } } replace(model, subs); for (BioPAXElement pe : subs.keySet()) { model.remove(pe); } } ModelUtils(); static void replace(Model model, final Map<? extends BioPAXElement, ? extends BioPAXElement> subs); static Set<T> getRootElements(final Model model, final Class<T> filterClass); static Set<BioPAXElement> removeObjectsIfDangling(Model model, Class<T> clazz); static Model writeRead(Model model); static Model getDirectChildren(BioPAXElement bpe); static Model getAllChildren(BioPAXElement bpe, 
		@SuppressWarnings("rawtypes") Filter<PropertyEditor>... filters); static Set<BioPAXElement> getDirectChildrenAsSet(BioPAXElement bpe); static Map<Class<? extends BioPAXElement>, Integer> generateClassMetrics(Model model); static T getObject(Model model, String uri, Class<T> clazz); static String md5hex(String id); static void fixDanglingObjectProperties(BioPAXElement bpe, Model model); static void fixDanglingInverseProperties(BioPAXElement bpe, Model model); static Set<EntityFeature> getFeatureIntersection(PhysicalEntity first, FeatureType firstClass,
			PhysicalEntity second, FeatureType secondClass); static Set<EntityFeature> getFeatureSetByType(PhysicalEntity pe, FeatureType type); static boolean checkERFeatureSet(EntityReference er, boolean fix); static Set<EntityFeature> findFeaturesAddedToSecond(PhysicalEntity first, PhysicalEntity second,
			boolean fix); static void fixControlled(Model model, Control control); static void normalizeGeneric(Model model, PhysicalEntity generic); static void normalizeGenerics(Model model); static void addMissingEntityReference(Model model, SimplePhysicalEntity pe); static void replaceEquivalentFeatures(Model model); static Set<String> getKeywords(BioPAXElement biopaxElement, int depth,
										  Filter<DataPropertyEditor>... dataPropertyFilters); static Set<BioSource> getOrganisms(BioPAXElement biopaxElement); static Set<Provenance> getDatasources(BioPAXElement biopaxElement); static Set<Pathway> getParentPathways(BioPAXElement biopaxElement); static void mergeEquivalentInteractions(Model model); static void mergeEquivalentPhysicalEntities(Model model); static String encodeBase62(String str); static String shortenUri(String xmlbase, String uri); static void updateUri(Model model, BioPAXElement el, String newUri); static void breakPathwayComponentCycle(final Model model); static boolean isGeneric(BioPAXElement e);  }
@Test public void testMergeEquivalentPhysicalEntities() { MockFactory mock = new MockFactory(BioPAXLevel.L3); Model model = mock.createModel(); ProteinReference[] pr = mock.create(model, ProteinReference.class, 2); Protein[] proteins = mock.create(model, Protein.class, 4); mock.bindInPairs("entityReference", proteins[0], pr[0], proteins[1], pr[0], proteins[2], pr[1], proteins[3], pr[1]); BiochemicalReaction[] rxn = mock.create(model, BiochemicalReaction.class, 2); mock.bindInPairs("left", rxn[0], proteins[2], rxn[1], proteins[2]); mock.bindInPairs("right", rxn[0], proteins[3], rxn[1], proteins[3]); Catalysis[] ctl = mock.create(model, Catalysis.class,2); mock.bindArrays("controlled", ctl, rxn); mock.bindInPairs("controller", ctl[0], proteins[0], ctl[1], proteins[1]); ModelUtils.mergeEquivalentPhysicalEntities(model); assertTrue(model.contains(proteins[0])^model.contains(proteins[1])); assertTrue(model.contains(proteins[2])^model.contains(proteins[3])); assertTrue(ctl[1].getController().contains(proteins[0])^ctl[1].getController().contains(proteins[1])); assertTrue(ctl[1].getController().contains(proteins[0])^ctl[1].getController().contains(proteins[1])); assertEquals(1, rxn[0].getRight().size()); assertEquals(1, rxn[1].getRight().size()); assertEquals(1, rxn[0].getLeft().size()); assertEquals(1, rxn[1].getLeft().size()); if(model.contains(proteins[2])) { assertTrue(rxn[0].getRight().contains(proteins[2])); assertTrue(rxn[1].getRight().contains(proteins[2])); assertTrue(rxn[0].getLeft().contains(proteins[2])); assertTrue(rxn[1].getLeft().contains(proteins[2])); } else if(model.contains(proteins[3])) { assertTrue(rxn[0].getRight().contains(proteins[3])); assertTrue(rxn[1].getRight().contains(proteins[3])); assertTrue(rxn[0].getLeft().contains(proteins[3])); assertTrue(rxn[1].getLeft().contains(proteins[3])); } ModelUtils.mergeEquivalentInteractions(model); assertTrue(model.contains(rxn[0])^model.contains(rxn[1])); }