001package org.biopax.paxtools.io.sif.level3; 002 003import org.apache.commons.logging.Log; 004import org.apache.commons.logging.LogFactory; 005import org.biopax.paxtools.controller.PathAccessor; 006import org.biopax.paxtools.model.BioPAXElement; 007import org.biopax.paxtools.model.level3.*; 008import org.biopax.paxtools.util.EquivalenceGrouper; 009 010import java.util.HashSet; 011import java.util.List; 012import java.util.Map; 013import java.util.Set; 014 015/** 016 * @author Emek Demir // todo annotate 017 */ 018public class Simplify 019{ 020 private static Log log = LogFactory.getLog(Simplify.class); 021 022 private static PathAccessor complexPath = new PathAccessor("Complex/component*"); 023 024 private static PathAccessor memberPath = new PathAccessor("PhysicalEntity/memberPhysicalEntity*"); 025 026 public static boolean entityHasAChange(BioPAXElement element, Conversion conv, GroupMap map, 027 Set<PEStateChange> changeSet, Map<Conversion, Set<EntityReference>> extendedControls) 028 { 029 SimplePhysicalEntity left = null; 030 SimplePhysicalEntity right = null; 031 PhysicalEntity leftRoot = null; 032 PhysicalEntity rightRoot = null; 033 034 if (element == null) 035 { 036 if (log.isWarnEnabled()) log.warn("Skipping "); 037 return false; 038 } 039 040 for (PhysicalEntity pe : conv.getLeft()) 041 { 042 left = getAssociatedState(element, pe, map); 043 if (left != null) 044 { 045 leftRoot = pe; 046 break; 047 } 048 } 049 for (PhysicalEntity pe : conv.getRight()) 050 { 051 right = getAssociatedState(element, pe, map); 052 if (right != null) 053 { 054 rightRoot = pe; 055 break; 056 } 057 } 058 059 if (left == null || right == null || !leftRoot.equals(rightRoot)) 060 { 061 if (changeSet != null) 062 { 063 changeSet.add(new PEStateChange(left, right, leftRoot, rightRoot, element, conv)); 064 //Match ER-level generics. - do not exist in Reactome -so TODO for now. 065 if (extendedControls != null) captureExtendedControls(conv, extendedControls, leftRoot, rightRoot); 066 } 067 068 return true; 069 } 070 return false; 071 } 072 073 074 private static void captureExtendedControls(Conversion conv, Map<Conversion, 075 Set<EntityReference>> extendedControls, 076 PhysicalEntity leftRoot, PhysicalEntity rightRoot) 077 { 078 if (leftRoot instanceof Complex || rightRoot instanceof Complex) 079 { 080 if (conv.getControlledOf().isEmpty()) //?? Todo check this 081 { 082 Set<SimplePhysicalEntity> leftSpe = new HashSet<SimplePhysicalEntity>(); 083 getSimpleMembers(leftRoot, leftSpe); 084 EquivalenceGrouper<SimplePhysicalEntity> leftComps = 085 new EquivalenceGrouper<SimplePhysicalEntity>(leftSpe); 086 087 Set<SimplePhysicalEntity> rightSpe = new HashSet<SimplePhysicalEntity>(); 088 getSimpleMembers(rightRoot, rightSpe); 089 090 EquivalenceGrouper rightComps = new EquivalenceGrouper<SimplePhysicalEntity>(rightSpe); 091 leftComps.getBuckets().retainAll(rightComps.getBuckets()); 092 093 for (List<SimplePhysicalEntity> bucket : leftComps.getBuckets()) 094 { 095 SimplePhysicalEntity pe = bucket.get(0); 096 Set<EntityReference> erSet = extendedControls.get(conv); 097 if (erSet == null) 098 { 099 erSet = new HashSet<EntityReference>(); 100 extendedControls.put(conv, erSet); 101 } 102 erSet.add(pe.getEntityReference()); 103 } 104 } 105 } 106 107 } 108 109 110 public static void getSimpleMembers(PhysicalEntity root, Set<SimplePhysicalEntity> value) 111 { 112 if (root != null) 113 { 114 if (root instanceof Complex) 115 { 116 Complex complex = (Complex) root; 117 for (PhysicalEntity component : complex.getComponent()) 118 { 119 getSimpleMembers(component, value); 120 } 121 } 122 123 if (root.getMemberPhysicalEntity().isEmpty()) 124 { 125 if (root instanceof SimplePhysicalEntity) value.add((SimplePhysicalEntity) root); 126 } else 127 { 128 for (PhysicalEntity generic : root.getMemberPhysicalEntity()) 129 { 130 getSimpleMembers(generic, value); 131 } 132 } 133 134 } 135 } 136 137 138 private static SimplePhysicalEntity getAssociatedState(BioPAXElement element, PhysicalEntity pe, GroupMap map) 139 { 140 if (pe instanceof Complex) 141 { 142 for (PhysicalEntity component : ((Complex) pe).getComponent()) 143 { 144 SimplePhysicalEntity viaComplex = getAssociatedState(element, component, map); 145 if (viaComplex != null) 146 { 147 return viaComplex; 148 } 149 } 150 } else if (checkEntity(map, pe, element)) return (SimplePhysicalEntity) pe; 151 for (PhysicalEntity member : pe.getMemberPhysicalEntity()) 152 { 153 SimplePhysicalEntity viaGeneric = getAssociatedState(element, member, map); 154 if (viaGeneric != null) return viaGeneric; 155 } 156 return null; 157 } 158 159 private static boolean checkEntity(GroupMap map, PhysicalEntity pe, BioPAXElement element) 160 { 161 return pe instanceof SimplePhysicalEntity && 162 (element.equals(((SimplePhysicalEntity) pe).getEntityReference())) || 163 element.equals(map.getEntityReferenceOrGroup(pe)); 164 } 165 166 public static boolean entityHasAChange(BioPAXElement target, Conversion conv, GroupMap groupMap, 167 Set<PEStateChange> peStateChanges) 168 { 169 return entityHasAChange(target, conv, groupMap, peStateChanges, null); 170 } 171}