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.ModelUtils; 006import org.biopax.paxtools.model.BioPAXElement; 007import org.biopax.paxtools.model.BioPAXLevel; 008import org.biopax.paxtools.model.Model; 009import org.biopax.paxtools.model.level3.*; 010import org.biopax.paxtools.model.level3.Process; 011 012import java.io.IOException; 013import java.io.OutputStream; 014import java.io.OutputStreamWriter; 015import java.io.Writer; 016import java.util.HashMap; 017import java.util.HashSet; 018import java.util.Map; 019import java.util.Set; 020 021/** 022 * This class analyzes the network to predict the effect of modifications on PEs on their activity. 023 * 024 * NOTE: This method is experimental and makes several assumptions based on the existing data sources. 025 * It might not work universally or return unexpected results for untested data sets. Use with caution. 026 * 027 * @author Emek Demir 028 * @deprecated 029 */ 030public class ActivityNetworkAnalyzer 031{ 032 private static final Log log = LogFactory.getLog(ActivityNetworkAnalyzer.class); 033 034 Map<BioPAXElement, Set<PEStateChange>> stateChangeMap; 035 036 Map<Conversion, Set<EntityReference>> extendedControls; 037 038 private static final Control EXTENDED; 039 040 static 041 { 042 EXTENDED = BioPAXLevel.L3.getDefaultFactory().create( 043 Control.class,"http://biopax" + ".org/generated/ExtendedControl"); 044 EXTENDED.setControlType(ControlType.ACTIVATION); 045 EXTENDED.addName("Inferred from complex binding"); 046 } 047 048 /** 049 * Given a model this method will analyze the states and populate the stateChangeMap and extendedControls maps. 050 * @param model to be analyzed. 051 */ 052 public void analyzeStates(Model model) 053 { 054 GroupMap groupMap = Grouper.inferGroups(model); 055 ModelUtils.replaceEquivalentFeatures(model); 056 057 stateChangeMap = new HashMap<BioPAXElement, Set<PEStateChange>>(); 058 extendedControls = new HashMap<Conversion, Set<EntityReference>>(); 059 060 for (EntityReference pr : model.getObjects(EntityReference.class)) 061 { 062 if (!pr.getRDFId().startsWith("http://biopax.org/generated/fixer/normalizeGenerics/")) 063 { 064 065 Set<PEStateChange> stateChanges = stateChangeMap.get(pr); 066 if (stateChanges == null) 067 { 068 stateChanges = new HashSet<PEStateChange>(); 069 stateChangeMap.put(pr, stateChanges); 070 } 071 for (SimplePhysicalEntity spe : pr.getEntityReferenceOf()) 072 { 073 scanInteractions(groupMap, stateChanges, pr, spe); 074 075 } 076 } 077 } 078 } 079 080 private void scanInteractions(GroupMap groupMap, Set<PEStateChange> stateChanges, EntityReference pr, 081 PhysicalEntity spe) 082 { 083 for (Interaction interaction : spe.getParticipantOf()) 084 { 085 if (interaction instanceof Conversion) 086 { 087 Simplify.entityHasAChange(pr, (Conversion) interaction, groupMap, stateChanges, extendedControls); 088 } 089 } 090 091 for (PhysicalEntity generic : spe.getMemberPhysicalEntityOf()) 092 { 093 094 scanInteractions(groupMap, stateChanges, pr, generic); 095 } 096 097 for (Complex complex : spe.getComponentOf()) 098 { 099 100 scanInteractions(groupMap, stateChanges, pr, complex); 101 } 102 } 103 104 /** 105 * @param spe a physical entity but complex 106 * @return all preceding states of a SimplePhysicalEntity. Preceding states are other spes of the 107 * same EntityReference that are converted into this spe in one conversion. 108 */ 109 public Set<SimplePhysicalEntity> getPrecedingStates(SimplePhysicalEntity spe) 110 { 111 Set<SimplePhysicalEntity> result = new HashSet<SimplePhysicalEntity>(); 112 EntityReference er = spe.getEntityReference(); 113 Set<PEStateChange> peStateChanges = stateChangeMap.get(er); 114 for (PEStateChange peStateChange : peStateChanges) 115 { 116 SimplePhysicalEntity next = peStateChange.changedInto(spe); 117 if (next != null) 118 { 119 result.add(peStateChange.left); 120 } 121 } 122 return result; 123 } 124 125 public Set<PEStateChange> getAllStates(EntityReference er) 126 { 127 return stateChangeMap.get(er); 128 } 129 /** 130 * @param spe a physical entity but complex 131 * @return all succeeding states of a SimplePhysicalEntity. Preceding states are other spes of the 132 * same EntityReference that this spe is converted into in one conversion. 133 */ 134 public Set<SimplePhysicalEntity> getSucceedingStates(SimplePhysicalEntity spe) 135 { 136 Set<SimplePhysicalEntity> result = new HashSet<SimplePhysicalEntity>(); 137 EntityReference er = spe.getEntityReference(); 138 Set<PEStateChange> peStateChanges = stateChangeMap.get(er); 139 for (PEStateChange peStateChange : peStateChanges) 140 { 141 SimplePhysicalEntity next = peStateChange.changedFrom(spe); 142 if (next != null) 143 { 144 result.add(peStateChange.left); 145 } 146 } 147 return result; 148 } 149 150 /** 151 * This method writes out the results of the stateNetworkAnalysis for each detected state change. 152 * 153 * @param out output stream 154 * @throws IOException when an I/O error happens 155 */ 156 public void writeStateNetworkAnalysis(OutputStream out) throws IOException 157 { 158 Writer writer = new OutputStreamWriter(out); 159 log.debug("stateChangeMap.size = " + stateChangeMap.values().size()); 160 int ineligible = 0; 161 int eligible = 0; 162 for (BioPAXElement bpe : stateChangeMap.keySet()) 163 { 164 if (bpe instanceof ProteinReference) 165 { 166 EntityReference er = (EntityReference) bpe; 167 Set<PEStateChange> sc = stateChangeMap.get(bpe); 168 for (PEStateChange sChange : sc) 169 { 170 if (isEligibleProteinModification(sChange)) 171 { 172 Set<Pathway> pathwayComponentOf = sChange.getConv().getPathwayComponentOf(); 173 for (Pathway pathway : pathwayComponentOf) 174 { 175 String s = pathway.getName().toString(); 176 if (s.isEmpty()) 177 { 178 log.debug("Empty name pathway = " + pathway); 179 } 180 writer.write(s + ";"); 181 } 182 writer.write("\t"); 183 writer.write(sChange.getConv().getName().toString()); 184 writer.write("\t"); 185 writer.write(er.getName().toString()); 186 writer.write("\t"); 187 writer.write(er.getXref().toString()); 188 writer.write("\t"); 189 writer.write(printControls(getDeltaControl(sChange))); 190 writer.write("\t"); 191 writer.write(sChange.getDeltaFeatures().toString()); 192 writer.write("\t"); 193 writer.write(sChange.getControllersAsString()); 194 writer.write("\n"); 195 196 eligible++; 197 } else 198 { 199 ineligible++; 200 } 201 202 } 203 } else 204 { 205 log.debug("bpe = " + bpe); 206 } 207 208 } 209 log.debug("ineligible = " + ineligible); 210 log.debug("eligible = " + eligible); 211 writer.flush(); 212 213 214 } 215 216 private Map<Control, Boolean> getDeltaControl(PEStateChange sChange) 217 { 218 Map<Control, Boolean> dc = sChange.getDeltaControls(); 219 if (!dc.isEmpty() || sChange.getRight() == null) 220 { 221 return dc; 222 } 223 else 224 { 225 //Look ahead: 226 PhysicalEntity rightRoot = sChange.getRightRoot(); 227 for (PEStateChange next : stateChangeMap.get(sChange.getRight().getEntityReference())) 228 { 229 if (nextFollows(rightRoot, next)) 230 { 231 dc = next.getDeltaControls(); 232 } 233 } 234 if (dc.isEmpty()) 235 { 236 dc = new HashMap<Control, Boolean>(); 237 HashSet<SimplePhysicalEntity> partners = new HashSet<SimplePhysicalEntity>(); 238 Simplify.getSimpleMembers(rightRoot, partners); 239 for (SimplePhysicalEntity partner : partners) 240 { 241 for (PEStateChange next : stateChangeMap.get(partner.getEntityReference())) 242 { 243 if (nextFollows(rightRoot, next)) 244 { 245 Set<EntityReference> xC = extendedControls.get(next.getConv()); 246 if (xC != null && xC.contains(sChange.getRight().getEntityReference())) 247 { 248 log.debug("extended"); 249 dc.put(EXTENDED, false); 250 } 251 } 252 } 253 254 } 255 } 256 } 257 return dc; 258 } 259 260 private boolean nextFollows(PhysicalEntity rightRoot, PEStateChange next) 261 { 262 return next != null && next.getLeftRoot() != null && next.getLeftRoot().equals(rightRoot); 263 } 264 265 private String printControls(Map<Control, Boolean> dc) 266 { 267 StringBuilder ctString = new StringBuilder(); 268 for (Control control : dc.keySet()) 269 { 270 Boolean direction = dc.get(control); 271 ctString.append(direction ? "Lost activity:" : "Gained activity").append(":").append( 272 control.getControlType()); 273 for (Process process : control.getControlled()) 274 { 275 ctString.append(process.getName()).append(" ,"); 276 } 277 ctString.append("; "); 278 } 279 return ctString.toString(); 280 } 281 282 private boolean isEligibleProteinModification(PEStateChange sChange) 283 { 284 for (EntityFeature ef : sChange.getDeltaFeatures().keySet()) 285 { 286 if (ef instanceof ModificationFeature && !sChange.getDeltaFeatures().get(ef).equals(ChangeType.UNCHANGED)) 287 { 288 return true; 289 } 290 } 291 return false; 292 } 293 294 295}