001package org.biopax.paxtools.query.wrapperL3; 002 003import org.biopax.paxtools.model.level3.*; 004import org.biopax.paxtools.model.level3.Process; 005import org.biopax.paxtools.query.model.AbstractNode; 006import org.biopax.paxtools.query.model.Edge; 007import org.biopax.paxtools.query.model.Node; 008 009import java.util.Collection; 010import java.util.HashSet; 011import java.util.Set; 012 013/** 014 * Wrapper for PhysicalEntity. 015 * 016 * @author Ozgun Babur 017 */ 018public class PhysicalEntityWrapper extends AbstractNode 019{ 020 /** 021 * Wrapped PhysicalEntity. 022 */ 023 protected PhysicalEntity pe; 024 025 /** 026 * Flag to remember if parent equivalents initialized. 027 */ 028 protected boolean upperEquivalentInited; 029 030 /** 031 * Flag to remember if child equivalents initialized. 032 */ 033 protected boolean lowerEquivalentInited; 034 035 /** 036 * Flag to say this is a ubiquitous molecule. 037 */ 038 protected boolean ubique; 039 040 /** 041 * Constructor with the wrapped PhysicalEntity and the owner graph. 042 * @param pe PhysicalEntity to wrap 043 * @param graph Owner graph 044 */ 045 public PhysicalEntityWrapper(PhysicalEntity pe, GraphL3 graph) 046 { 047 super(graph); 048 this.pe = pe; 049 this.upperEquivalentInited = false; 050 this.lowerEquivalentInited = false; 051 this.ubique = false; 052 } 053 054 /** 055 * @return Whether this is ubique 056 */ 057 public boolean isUbique() 058 { 059 return ubique; 060 } 061 062 /** 063 * Set the ubique flag. 064 * @param ubique Whether this is a ubiquitous molecule 065 */ 066 public void setUbique(boolean ubique) 067 { 068 this.ubique = ubique; 069 } 070 071 /** 072 * Binds to upstream interactions. 073 */ 074 public void initUpstream() 075 { 076 for (Conversion conv : getUpstreamConversions(pe.getParticipantOf())) 077 { 078 ConversionWrapper conW = (ConversionWrapper) graph.getGraphObject(conv); 079 if (conW == null) continue; 080 081 if (conv.getConversionDirection() == ConversionDirectionType.REVERSIBLE && 082 conv.getLeft().contains(pe)) 083 { 084 conW = conW.getReverse(); 085 } 086 Edge edge = new EdgeL3(conW, this, graph); 087 conW.getDownstreamNoInit().add(edge); 088 this.getUpstreamNoInit().add(edge); 089 } 090 091 for (Interaction inter : pe.getParticipantOf()) 092 { 093 if (inter instanceof TemplateReaction) 094 { 095 TemplateReaction tr = (TemplateReaction) inter; 096 TemplateReactionWrapper trw = (TemplateReactionWrapper) graph.getGraphObject(tr); 097 if (trw == null) continue; 098 099 Edge edge = new EdgeL3(trw, this, graph); 100 101 assert trw.getDownstreamNoInit() != null; 102 103 trw.getDownstreamNoInit().add(edge); 104 this.getUpstreamNoInit().add(edge); 105 } 106 } 107 } 108 109 /** 110 * Binds to downstream interactions. 111 */ 112 public void initDownstream() 113 { 114 for (Interaction inter : getDownstreamInteractions(pe.getParticipantOf())) 115 { 116 AbstractNode node = (AbstractNode) graph.getGraphObject(inter); 117 118 if (node == null) continue; 119 120 if (inter instanceof Conversion) 121 { 122 Conversion conv = (Conversion) inter; 123 ConversionWrapper conW = (ConversionWrapper) node; 124 if (conv.getConversionDirection() == ConversionDirectionType.REVERSIBLE && 125 conv.getRight().contains(pe)) 126 { 127 node = conW.getReverse(); 128 } 129 } 130 131 Edge edge = new EdgeL3(this, node, graph); 132 this.getDownstreamNoInit().add(edge); 133 node.getUpstreamNoInit().add(edge); 134 } 135 } 136 137 //--- Upstream conversions --------------------------------------------------------------------| 138 139 /** 140 * Gets the conversions at the upstream of this PhysicalEntity. 141 * @param inters Interactions to search for 142 * @return Upstream conversions 143 */ 144 protected Set<Conversion> getUpstreamConversions(Collection<Interaction> inters) 145 { 146 Set<Conversion> set = new HashSet<Conversion>(); 147 148 for (Interaction inter : inters) 149 { 150 if (inter instanceof Conversion) 151 { 152 Conversion conv = (Conversion) inter; 153 ConversionDirectionType dir = conv.getConversionDirection(); 154 155 if (dir == ConversionDirectionType.REVERSIBLE || 156 (dir == ConversionDirectionType.RIGHT_TO_LEFT && conv.getLeft().contains(pe)) || 157 ((dir == ConversionDirectionType.LEFT_TO_RIGHT || dir == null) && 158 conv.getRight().contains(pe))) 159 { 160 set.add(conv); 161 } 162 } 163 } 164 return set; 165 } 166 167 //--- Downstream interactions ------------------------------------------------------------------| 168 169 /** 170 * Gets the downstream interactions among the given set. 171 * @param inters Interactions to search 172 * @return Downstream interactions 173 */ 174 protected Set<Interaction> getDownstreamInteractions(Collection<Interaction> inters) 175 { 176 Set<Interaction> set = new HashSet<Interaction>(); 177 178 for (Interaction inter : inters) 179 { 180 if (inter instanceof Conversion) 181 { 182 Conversion conv = (Conversion) inter; 183 ConversionDirectionType dir = conv.getConversionDirection(); 184 185 if (dir == ConversionDirectionType.REVERSIBLE || 186 (dir == ConversionDirectionType.RIGHT_TO_LEFT && conv.getRight().contains(pe)) || 187 ((dir == ConversionDirectionType.LEFT_TO_RIGHT || dir == null) && 188 conv.getLeft().contains(pe))) 189 { 190 set.add(conv); 191 } 192 } 193 else if (inter instanceof Control) 194 { 195 set.add(inter); 196 } 197 } 198 return set; 199 } 200 201 //--- Related conversions ---------------------------------------------------------------------| 202 203 /** 204 * Get all related Conversions of the given Interaction set. 205 * @param inters Interactions to query 206 * @return Related Conversions 207 */ 208 private Set<Conversion> getRelatedConversions(Collection<Interaction> inters) 209 { 210 Set<Conversion> set = new HashSet<Conversion>(); 211 212 for (Interaction inter : inters) 213 { 214 if (inter instanceof Conversion) 215 { 216 set.add((Conversion) inter); 217 } 218 else if (inter instanceof Control) 219 { 220 getRelatedConversions((Control) inter, set); 221 } 222 } 223 return set; 224 } 225 226 /** 227 * Recursively searches the related Conversions of a Control. 228 * @param ctrl Control to query 229 * @param set Set to collect the related Conversions 230 * @return The same set 231 */ 232 private Set<Conversion> getRelatedConversions(Control ctrl, Set<Conversion> set) 233 { 234 for (Process process : ctrl.getControlled()) 235 { 236 if (process instanceof Conversion) 237 { 238 set.add((Conversion) process); 239 } 240 else if (process instanceof Control) 241 { 242 getRelatedConversions((Control) process, set); 243 } 244 } 245 return set; 246 } 247 248 //----- Equivalence ---------------------------------------------------------------------------| 249 250 /** 251 * @return Parent equivalent objects 252 */ 253 @Override 254 public Collection<Node> getUpperEquivalent() 255 { 256 if (!upperEquivalentInited) 257 { 258 initUpperEquivalent(); 259 } 260 return super.getUpperEquivalent(); 261 } 262 263 /** 264 * @return Child equivalent objects 265 */ 266 @Override 267 public Collection<Node> getLowerEquivalent() 268 { 269 if (!lowerEquivalentInited) 270 { 271 initLowerEquivalent(); 272 } 273 return super.getLowerEquivalent(); 274 } 275 276 /** 277 * Finds homology parent. 278 */ 279 protected void initUpperEquivalent() 280 { 281 this.upperEquivalent = new HashSet<Node>(); 282 283 for (PhysicalEntity eq : pe.getMemberPhysicalEntityOf()) 284 { 285 Node node = (Node) graph.getGraphObject(eq); 286 if (node != null) this.upperEquivalent.add(node); 287 } 288 289 upperEquivalentInited = true; 290 } 291 292 /** 293 * Finds member nodes if this is a homology node 294 */ 295 protected void initLowerEquivalent() 296 { 297 this.lowerEquivalent = new HashSet<Node>(); 298 299 for (PhysicalEntity eq : pe.getMemberPhysicalEntity()) 300 { 301 Node node = (Node) graph.getGraphObject(eq); 302 if (node != null) this.lowerEquivalent.add(node); 303 } 304 305 lowerEquivalentInited = true; 306 } 307 308 //------ Other --------------------------------------------------------------------------------| 309 310 /** 311 * PhysicalEntity is a breadth node. 312 * @return True 313 */ 314 public boolean isBreadthNode() 315 { 316 return true; 317 } 318 319 /** 320 * PhysicalEntity have positive sign. 321 * @return POSITIVE (1) 322 */ 323 public int getSign() 324 { 325 return POSITIVE; 326 } 327 328 /** 329 * RDF ID of the PhysicalEntity is used as key. 330 * @return Key 331 */ 332 public String getKey() 333 { 334 return pe.getRDFId(); 335 } 336 337 /** 338 * @return Wrapped PhysicalEntity 339 */ 340 public PhysicalEntity getPhysicalEntity() 341 { 342 return pe; 343 } 344 345 /** 346 * @return display name with ID added 347 */ 348 @Override 349 public String toString() 350 { 351 return pe.getDisplayName() + " -- "+ pe.getRDFId(); 352 } 353}