ModelUtils { public static void replaceEquivalentFeatures(Model model) { EquivalenceGrouper<EntityFeature> equivalents = new EquivalenceGrouper<EntityFeature>(); HashMap<EntityFeature, EntityFeature> mapped = new HashMap<EntityFeature, EntityFeature>(); HashSet<EntityFeature> scheduled = new HashSet<EntityFeature>(); for (EntityFeature ef : model.getObjects(EntityFeature.class)) { if (ef.getEntityFeatureOf() == null) inferEntityReference(ef); equivalents.add(ef); } for (List<EntityFeature> bucket : equivalents.getBuckets()) { for (int i = 1; i < bucket.size(); i++) { EntityFeature ef = bucket.get(i); if (LOG.isWarnEnabled()) { LOG.warn("removing: "+ ef.getUri()+ " since it is equivalent to: "+ bucket.get(0)); } scheduled.add(ef); } } for (EntityFeature entityFeature : scheduled) { model.remove(entityFeature); } for (PhysicalEntity physicalEntity : model.getObjects(PhysicalEntity.class)) { Set<EntityFeature> features = new HashSet<EntityFeature>(physicalEntity.getFeature()); for (EntityFeature feature : features) { EntityFeature that = mapped.get(feature); if (that != null && !that.equals(feature)) { LOG.debug(" replacing " + feature + "{" + feature.getUri() + "} with " + that + "{" + that.getUri() + "}"); physicalEntity.removeFeature(feature); physicalEntity.addFeature(that); } } } } 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 testFixEquivalentFeatures() { MockFactory mock = new MockFactory(BioPAXLevel.L3); Model model = mock.createModel(); SequenceSite[] ss= mock.create(model, SequenceSite.class,1); ss[0].setSequencePosition(0); ss[0].setPositionStatus(PositionStatusType.EQUAL); ModificationFeature[] mf = mock.create(model, ModificationFeature.class, 2); mf[0].setFeatureLocation(ss[0]); mf[1].setFeatureLocation(ss[0]); mf[0].setFeatureLocation(ss[0]); mf[1].setFeatureLocation(ss[0]); ProteinReference[] pr = mock.create(model, ProteinReference.class, 1); pr[0].addEntityFeature(mf[0]); pr[0].addEntityFeature(mf[1]); ModelUtils.replaceEquivalentFeatures(model); assertTrue(model.getObjects(ModificationFeature.class).size()==1); }