001package org.biopax.paxtools.pattern; 002 003import org.biopax.paxtools.model.level3.*; 004import org.biopax.paxtools.pattern.constraint.*; 005import org.biopax.paxtools.pattern.util.Blacklist; 006import org.biopax.paxtools.pattern.util.RelType; 007 008import java.util.HashSet; 009import java.util.Map; 010import java.util.Set; 011 012import static org.biopax.paxtools.pattern.constraint.ConBox.*; 013 014/** 015 * This class contains several pattern samples. 016 * 017 * @author Ozgun Babur 018 */ 019public class PatternBox 020{ 021 //---- Section: Binary interaction patterns ---------------------------------------------------| 022 023 /** 024 * Pattern for a EntityReference has a member PhysicalEntity that is controlling a state change 025 * reaction of another EntityReference. 026 * @return the pattern 027 */ 028 public static Pattern controlsStateChange() 029 { 030 Pattern p = new Pattern(SequenceEntityReference.class, "controller ER"); 031 p.add(linkedER(true), "controller ER", "generic controller ER"); 032 p.add(erToPE(), "generic controller ER", "controller simple PE"); 033 p.add(linkToComplex(), "controller simple PE", "controller PE"); 034 p.add(peToControl(), "controller PE", "Control"); 035 p.add(controlToConv(), "Control", "Conversion"); 036 p.add(new NOT(participantER()), "Conversion", "controller ER"); 037 p.add(new Participant(RelType.INPUT, true), "Control", "Conversion", "input PE"); 038 p.add(linkToSpecific(), "input PE", "input simple PE"); 039 p.add(new Type(SequenceEntity.class), "input simple PE"); 040 p.add(peToER(), "input simple PE", "changed generic ER"); 041 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE), "input PE", "Conversion", "output PE"); 042 p.add(equal(false), "input PE", "output PE"); 043 p.add(linkToSpecific(), "output PE", "output simple PE"); 044 p.add(peToER(), "output simple PE", "changed generic ER"); 045 p.add(linkedER(false), "changed generic ER", "changed ER"); 046 047 return p; 048 } 049 050 /** 051 * Pattern for a ProteinReference has a member PhysicalEntity that is controlling a 052 * transportation of another ProteinReference. 053 * @return the pattern 054 */ 055 public static Pattern controlsTransport() 056 { 057 Pattern p = controlsStateChange(); 058 p.add(new OR( 059 new MappedConst(hasDifferentCompartments(), 0, 1), 060 new MappedConst(hasDifferentCompartments(), 2, 3)), 061 "input simple PE", "output simple PE", "input PE", "output PE"); 062 063 return p; 064 } 065 066 /** 067 * Pattern for a ProteinReference has a member PhysicalEntity that is controlling a reaction 068 * that changes cellular location of a small molecule. 069 * 070 * @param blacklist a skip-list of ubiquitous molecules 071 * @return the pattern 072 */ 073 public static Pattern controlsTransportOfChemical(Blacklist blacklist) 074 { 075 Pattern p = new Pattern(SequenceEntityReference.class, "controller ER"); 076 p.add(linkedER(true), "controller ER", "controller generic ER"); 077 p.add(erToPE(), "controller generic ER", "controller simple PE"); 078 p.add(linkToComplex(), "controller simple PE", "controller PE"); 079 p.add(peToControl(), "controller PE", "Control"); 080 p.add(controlToConv(), "Control", "Conversion"); 081 p.add(new Participant(RelType.INPUT, blacklist, true), "Control", "Conversion", "input PE"); 082 p.add(linkToSimple(blacklist), "input PE", "input simple PE"); 083 p.add(new Type(SmallMolecule.class), "input simple PE"); 084 p.add(notGeneric(), "input simple PE"); 085 p.add(peToER(), "input simple PE", "changed generic SMR"); 086 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE, blacklist, RelType.OUTPUT), "input PE", "Conversion", "output PE"); 087 p.add(equal(false), "input PE", "output PE"); 088 p.add(linkToSimple(blacklist), "output PE", "output simple PE"); 089 p.add(new Type(SmallMolecule.class), "output simple PE"); 090 p.add(notGeneric(), "output simple PE"); 091 p.add(peToER(), "output simple PE", "changed generic SMR"); 092 p.add(linkedER(false), "changed generic SMR", "changed SMR"); 093 p.add(new OR( 094 new MappedConst(hasDifferentCompartments(), 0, 1), 095 new MappedConst(hasDifferentCompartments(), 2, 3)), 096 "input simple PE", "output simple PE", "input PE", "output PE"); 097 098 return p; 099 } 100 101 /** 102 * Pattern for a EntityReference has a member PhysicalEntity that is controlling a state change 103 * reaction of another EntityReference. In this case the controller is also an input to the 104 * reaction. The affected protein is the one that is represented with different non-generic 105 * physical entities at left and right of the reaction. 106 * @return the pattern 107 */ 108 public static Pattern controlsStateChangeBothControlAndPart() 109 { 110 Pattern p = new Pattern(SequenceEntityReference.class, "controller ER"); 111 p.add(linkedER(true), "controller ER", "controller generic ER"); 112 p.add(erToPE(), "controller generic ER", "controller simple PE"); 113 p.add(linkToComplex(), "controller simple PE", "controller PE"); 114 p.add(peToControl(), "controller PE", "Control"); 115 p.add(controlToConv(), "Control", "Conversion"); 116 117 // the controller PE is also an input 118 p.add(new ParticipatesInConv(RelType.INPUT), "controller PE", "Conversion"); 119 120 // same controller simple PE is also an output 121 p.add(linkToComplex(), "controller simple PE", "special output PE"); 122 p.add(equal(false), "special output PE", "controller PE"); 123 p.add(new ParticipatesInConv(RelType.OUTPUT), "special output PE", "Conversion"); 124 125 stateChange(p, "Control"); 126 127 // non-generic input and outputs are only associated with one side 128 p.add(equal(false), "input simple PE", "output simple PE"); 129 p.add(new NOT(simplePEToConv(RelType.OUTPUT)), "input simple PE", "Conversion"); 130 p.add(new NOT(simplePEToConv(RelType.INPUT)), "output simple PE", "Conversion"); 131 132 p.add(equal(false), "controller ER", "changed ER"); 133 p.add(type(SequenceEntityReference.class), "changed ER"); 134 135 return p; 136 } 137 138 /** 139 * Pattern for a EntityReference has a member PhysicalEntity that is controlling a state change 140 * reaction of another EntityReference. This pattern is different from the original 141 * controls-state-change. The controller in this case is not modeled as a controller, but as a 142 * participant of the conversion, and it is at both sides. 143 * @return the pattern 144 */ 145 public static Pattern controlsStateChangeButIsParticipant() 146 { 147 Pattern p = new Pattern(SequenceEntityReference.class, "controller ER"); 148 p.add(linkedER(true), "controller ER", "controller generic ER"); 149 p.add(erToPE(), "controller generic ER", "controller simple PE"); 150 p.add(linkToComplex(), "controller simple PE", "controller PE"); 151 p.add(participatesInConv(), "controller PE", "Conversion"); 152 p.add(left(), "Conversion", "controller PE"); 153 p.add(right(), "Conversion", "controller PE"); 154 // The controller ER is not associated with the Conversion in another way. 155 p.add(new NOT(new InterToPartER(1)), "Conversion", "controller PE", "controller ER"); 156 157 stateChange(p, null); 158 159 p.add(equal(false), "controller ER", "changed ER"); 160 p.add(equal(false), "controller PE", "input PE"); 161 p.add(equal(false), "controller PE", "output PE"); 162 163 return p; 164 } 165 166 /** 167 * Pattern for a Conversion has an input PhysicalEntity and another output PhysicalEntity that 168 * belongs to the same EntityReference. 169 * 170 * @param p pattern to update 171 * @param ctrlLabel label 172 * @return the pattern 173 */ 174 public static Pattern stateChange(Pattern p, String ctrlLabel) 175 { 176 if (p == null) p = new Pattern(Conversion.class, "Conversion"); 177 178 if (ctrlLabel == null) p.add(new Participant(RelType.INPUT), "Conversion", "input PE"); 179 else p.add(new Participant(RelType.INPUT, true), ctrlLabel, "Conversion", "input PE"); 180 181 p.add(linkToSpecific(), "input PE", "input simple PE"); 182 p.add(peToER(), "input simple PE", "changed generic ER"); 183 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE), "input PE", "Conversion", "output PE"); 184 p.add(equal(false), "input PE", "output PE"); 185 p.add(linkToSpecific(), "output PE", "output simple PE"); 186 p.add(peToER(), "output simple PE", "changed generic ER"); 187 p.add(linkedER(false), "changed generic ER", "changed ER"); 188 return p; 189 } 190 191 /** 192 * Pattern for an entity is producing a small molecule, and the small molecule controls state 193 * change of another molecule. 194 * 195 * @param blacklist a skip-list of ubiquitous molecules 196 * @return the pattern 197 */ 198 public static Pattern controlsStateChangeThroughControllerSmallMolecule(Blacklist blacklist) 199 { 200 Pattern p = new Pattern(SequenceEntityReference.class, "upper controller ER"); 201 p.add(linkedER(true), "upper controller ER", "upper controller generic ER"); 202 p.add(erToPE(), "upper controller generic ER", "upper controller simple PE"); 203 p.add(linkToComplex(), "upper controller simple PE", "upper controller PE"); 204 p.add(peToControl(), "upper controller PE", "upper Control"); 205 p.add(controlToConv(), "upper Control", "upper Conversion"); 206 p.add(new NOT(participantER()), "upper Conversion", "upper controller ER"); 207 p.add(new Participant(RelType.OUTPUT, blacklist), "upper Conversion", "controller PE"); 208 p.add(type(SmallMolecule.class), "controller PE"); 209 if (blacklist != null) p.add(new NonUbique(blacklist), "controller PE"); 210 211 // the linker small mol is at also an input 212 p.add(new NOT(new ConstraintChain( 213 new ConversionSide(ConversionSide.Type.OTHER_SIDE), linkToSpecific())), 214 "controller PE", "upper Conversion", "controller PE"); 215 216 p.add(peToControl(), "controller PE", "Control"); 217 p.add(controlToConv(), "Control", "Conversion"); 218 p.add(equal(false), "upper Conversion", "Conversion"); 219 220// p.add(nextInteraction(), "upper Conversion", "Conversion"); 221 222 stateChange(p, "Control"); 223 224 p.add(type(SequenceEntityReference.class), "changed ER"); 225 p.add(equal(false), "upper controller ER", "changed ER"); 226 p.add(new NOT(participantER()), "Conversion", "upper controller ER"); 227 228 return p; 229 } 230 231 /** 232 * Pattern for an entity is producing a small molecule, and the small molecule controls state 233 * change of another molecule. 234 * 235 * @param blacklist a skip-list of ubiquitous molecules 236 * @return the pattern 237 */ 238 public static Pattern controlsStateChangeThroughBindingSmallMolecule(Blacklist blacklist) 239 { 240 Pattern p = new Pattern(SequenceEntityReference.class, "upper controller ER"); 241 p.add(linkedER(true), "upper controller ER", "upper controller generic ER"); 242 p.add(erToPE(), "upper controller ER", "upper controller simple PE"); 243 p.add(linkToComplex(), "upper controller simple PE", "upper controller PE"); 244 p.add(peToControl(), "upper controller PE", "upper Control"); 245 p.add(controlToConv(), "upper Control", "upper Conversion"); 246 p.add(new NOT(participantER()), "upper Conversion", "upper controller ER"); 247 p.add(new Participant(RelType.OUTPUT, blacklist, true), "upper Control", "upper Conversion", "SM"); 248 p.add(type(SmallMolecule.class), "SM"); 249 if (blacklist != null) p.add(new NonUbique(blacklist), "SM"); 250 251 // the linker small mol is at also an input 252 p.add(new NOT(new ConstraintChain( 253 new ConversionSide(ConversionSide.Type.OTHER_SIDE), linkToSpecific())), 254 "SM", "upper Conversion", "SM"); 255 256 p.add(new ParticipatesInConv(RelType.INPUT), "SM", "Conversion"); 257 p.add(peToER(), "SM", "SM ER"); 258 p.add(equal(false), "upper Conversion", "Conversion"); 259 260// p.add(nextInteraction(), "upper Conversion", "Conversion"); 261 262 stateChange(p, null); 263 264 p.add(type(SequenceEntityReference.class), "changed ER"); 265 p.add(equal(false), "upper controller ER", "changed ER"); 266 p.add(new NOT(participantER()), "Conversion", "upper controller ER"); 267 p.add(compToER(), "output PE", "SM ER"); 268 269 return p; 270 } 271 272 /** 273 * Finds cases where proteins affect their degradation. 274 * @return the pattern 275 */ 276 public static Pattern controlsStateChangeThroughDegradation() 277 { 278 Pattern p = new Pattern(SequenceEntityReference.class, "upstream ER"); 279 p.add(linkedER(true), "upstream ER", "upstream generic ER"); 280 p.add(erToPE(), "upstream generic ER", "upstream SPE"); 281 p.add(linkToComplex(), "upstream SPE", "upstream PE"); 282 p.add(peToControl(), "upstream PE", "Control"); 283 p.add(controlToConv(), "Control", "Conversion"); 284 p.add(new NOT(participantER()), "Conversion", "upstream ER"); 285 p.add(new Empty(new Participant(RelType.OUTPUT)), "Conversion"); 286 p.add(new Participant(RelType.INPUT), "Conversion", "input PE"); 287 p.add(linkToSpecific(), "input PE", "input SPE"); 288 p.add(peToER(), "input SPE", "downstream generic ER"); 289 p.add(type(SequenceEntityReference.class), "downstream generic ER"); 290 p.add(linkedER(false), "downstream generic ER", "downstream ER"); 291 return p; 292 } 293 294 public static Pattern controlsPhosphorylation() 295 { 296 Pattern p = controlsStateChange(); 297 p.add(new NOT(ConBox.linkToSpecific()), "input PE", "output simple PE"); 298 p.add(new NOT(ConBox.linkToSpecific()), "output PE", "input simple PE"); 299 p.add(new ModificationChangeConstraint(ModificationChangeConstraint.Type.ANY, 300 "phospho"), "input simple PE", "output simple PE"); 301 return p; 302 } 303 304 /** 305 * Pattern for a Protein controlling a reaction whose participant is a small molecule. 306 * 307 * @param blacklist a skip-list of ubiquitous molecules 308 * @param consumption true/false (TODO explain) 309 * @return the pattern 310 */ 311 public static Pattern controlsMetabolicCatalysis(Blacklist blacklist, boolean consumption) 312 { 313 Pattern p = new Pattern(SequenceEntityReference.class, "controller ER"); 314 p.add(linkedER(true), "controller ER", "controller generic ER"); 315 p.add(erToPE(), "controller generic ER", "controller simple PE"); 316 p.add(linkToComplex(), "controller simple PE", "controller PE"); 317 p.add(peToControl(), "controller PE", "Control"); 318 p.add(controlToConv(), "Control", "Conversion"); 319 p.add(new NOT(participantER()), "Conversion", "controller ER"); 320 321 p.add(new Participant(consumption ? RelType.INPUT : RelType.OUTPUT, blacklist, true), 322 "Control", "Conversion", "part PE"); 323 324 p.add(linkToSimple(blacklist), "part PE", "part SM"); 325 p.add(notGeneric(), "part SM"); 326 p.add(type(SmallMolecule.class), "part SM"); 327 p.add(peToER(), "part SM", "part SMR"); 328 329 // The small molecule is associated only with left or right, but not both. 330 p.add(new XOR( 331 new MappedConst(new InterToPartER(InterToPartER.Direction.LEFT), 0, 1), 332 new MappedConst(new InterToPartER(InterToPartER.Direction.RIGHT), 0, 1)), 333 "Conversion", "part SMR"); 334 335 return p; 336 } 337 338 339 /** 340 * Pattern for detecting two EntityReferences are controlling consecutive reactions, where 341 * output of one reaction is input to the other. 342 * 343 * @param blacklist to detect ubiquitous small molecules 344 * @return the pattern 345 */ 346 public static Pattern catalysisPrecedes(Blacklist blacklist) 347 { 348 Pattern p = new Pattern(SequenceEntityReference.class, "first ER"); 349 p.add(linkedER(true), "first ER", "first generic ER"); 350 p.add(erToPE(), "first generic ER", "first simple controller PE"); 351 p.add(linkToComplex(), "first simple controller PE", "first controller PE"); 352 p.add(peToControl(), "first controller PE", "first Control"); 353 p.add(controlToConv(), "first Control", "first Conversion"); 354 p.add(new Participant(RelType.OUTPUT, blacklist, true), "first Control", "first Conversion", "linker PE"); 355 p.add(new NOT(new ConstraintChain(new ConversionSide(ConversionSide.Type.OTHER_SIDE), linkToSpecific())), "linker PE", "first Conversion", "linker PE"); 356 p.add(type(SmallMolecule.class), "linker PE"); 357 p.add(new ParticipatesInConv(RelType.INPUT, blacklist), "linker PE", "second Conversion"); 358 p.add(new NOT(new ConstraintChain(new ConversionSide(ConversionSide.Type.OTHER_SIDE), linkToSpecific())), "linker PE", "second Conversion", "linker PE"); 359 p.add(equal(false), "first Conversion", "second Conversion"); 360 361 // make sure that conversions are not replicates or reverse of each other 362 // and also outward facing sides of reactions contain at least one non ubique 363 p.add(new ConstraintAdapter(3, blacklist) 364 { 365 @Override 366 public boolean satisfies(Match match, int... ind) 367 { 368 Conversion cnv1 = (Conversion) match.get(ind[0]); 369 Conversion cnv2 = (Conversion) match.get(ind[1]); 370 SmallMolecule linker = (SmallMolecule) match.get(ind[2]); 371 372 Set<PhysicalEntity> input1 = cnv1.getLeft().contains(linker) ? cnv1.getRight() : cnv1.getLeft(); 373 Set<PhysicalEntity> input2 = cnv2.getLeft().contains(linker) ? cnv2.getLeft() : cnv2.getRight(); 374 Set<PhysicalEntity> output1 = cnv1.getLeft().contains(linker) ? cnv1.getLeft() : cnv1.getRight(); 375 Set<PhysicalEntity> output2 = cnv2.getLeft().contains(linker) ? cnv2.getRight() : cnv2.getLeft(); 376 377 if (input1.equals(input2) && output1.equals(output2)) return false; 378 if (input1.equals(output2) && output1.equals(input2)) return false; 379 380 if (blacklist != null) 381 { 382 Set<PhysicalEntity> set = new HashSet<PhysicalEntity>(input1); 383 set = blacklist.getNonUbiques(set, RelType.INPUT); 384 set.removeAll(output2); 385 if (set.isEmpty()) 386 { 387 set.addAll(output2); 388 set = blacklist.getNonUbiques(set, RelType.OUTPUT); 389 set.removeAll(input1); 390 391 if (set.isEmpty()) return false; 392 } 393 } 394 return true; 395 } 396 }, "first Conversion", "second Conversion", "linker PE"); 397 398 p.add(new RelatedControl(RelType.INPUT, blacklist), "linker PE", "second Conversion", "second Control"); 399 p.add(controllerPE(), "second Control", "second controller PE"); 400 p.add(new NOT(compToER()), "second controller PE", "first ER"); 401 p.add(linkToSpecific(), "second controller PE", "second simple controller PE"); 402 p.add(type(SequenceEntity.class), "second simple controller PE"); 403 p.add(peToER(), "second simple controller PE", "second generic ER"); 404 p.add(linkedER(false), "second generic ER", "second ER"); 405 p.add(equal(false), "first ER", "second ER"); 406 return p; 407 } 408 409 /** 410 * Finds transcription factors that trans-activate or trans-inhibit an entity. 411 * @return the pattern 412 */ 413 public static Pattern controlsExpressionWithTemplateReac() 414 { 415 Pattern p = new Pattern(SequenceEntityReference.class, "TF ER"); 416 p.add(linkedER(true), "TF ER", "TF generic ER"); 417 p.add(erToPE(), "TF generic ER", "TF SPE"); 418 p.add(linkToComplex(), "TF SPE", "TF PE"); 419 p.add(peToControl(), "TF PE", "Control"); 420 p.add(controlToTempReac(), "Control", "TempReac"); 421 p.add(product(), "TempReac", "product PE"); 422 p.add(linkToSpecific(), "product PE", "product SPE"); 423 p.add(new Type(SequenceEntity.class), "product SPE"); 424 p.add(peToER(), "product SPE", "product generic ER"); 425 p.add(linkedER(false), "product generic ER", "product ER"); 426 p.add(equal(false), "TF ER", "product ER"); 427 return p; 428 } 429 430 /** 431 * Finds the cases where transcription relation is shown using a Conversion instead of a 432 * TemplateReaction. 433 * @return the pattern 434 */ 435 public static Pattern controlsExpressionWithConversion() 436 { 437 Pattern p = new Pattern(SequenceEntityReference.class, "TF ER"); 438 p.add(linkedER(true), "TF ER", "TF generic ER"); 439 p.add(erToPE(), "TF generic ER", "TF SPE"); 440 p.add(linkToComplex(), "TF SPE", "TF PE"); 441 p.add(peToControl(), "TF PE", "Control"); 442 p.add(controlToConv(), "Control", "Conversion"); 443 p.add(new Size(right(), 1, Size.Type.EQUAL), "Conversion"); 444 p.add(new OR(new MappedConst(new Empty(left()), 0), new MappedConst(new ConstraintAdapter(1) 445 { 446 @Override 447 public boolean satisfies(Match match, int... ind) 448 { 449 Conversion cnv = (Conversion) match.get(ind[0]); 450 Set<PhysicalEntity> left = cnv.getLeft(); 451 if (left.size() > 1) return false; 452 if (left.isEmpty()) return true; 453 PhysicalEntity pe = left.iterator().next(); 454 if (pe instanceof NucleicAcid) 455 { 456 PhysicalEntity rPE = cnv.getRight().iterator().next(); 457 return rPE instanceof Protein; 458 } 459 return false; 460 } 461 }, 0)), "Conversion"); 462 p.add(right(), "Conversion", "right PE"); 463 p.add(linkToSpecific(), "right PE", "right SPE"); 464 p.add(new Type(SequenceEntity.class), "right SPE"); 465 p.add(peToER(), "right SPE", "product generic ER"); 466 p.add(linkedER(false), "product generic ER", "product ER"); 467 p.add(equal(false), "TF ER", "product ER"); 468 return p; 469 } 470 471 /** 472 * Finds cases where protein A changes state of B, and B is then degraded. 473 * 474 * NOTE: THIS PATTERN DOES NOT WORK. KEEPING ONLY FOR HISTORICAL REASONS. 475 * 476 * @return the pattern 477 */ 478 public static Pattern controlsDegradationIndirectly() 479 { 480 Pattern p = controlsStateChange(); 481 p.add(new Size(new ParticipatesInConv(RelType.INPUT), 1, Size.Type.EQUAL), "output PE"); 482 p.add(new Empty(peToControl()), "output PE"); 483 p.add(new ParticipatesInConv(RelType.INPUT), "output PE", "degrading Conv"); 484 p.add(new NOT(type(ComplexAssembly.class)), "degrading Conv"); 485 p.add(new Size(participant(), 1, Size.Type.EQUAL), "degrading Conv"); 486 p.add(new Empty(new Participant(RelType.OUTPUT)), "degrading Conv"); 487 p.add(new Empty(convToControl()), "degrading Conv"); 488 p.add(equal(false), "degrading Conv", "Conversion"); 489 return p; 490 } 491 492 /** 493 * Two proteins have states that are members of the same complex. Handles nested complexes and 494 * homologies. Also guarantees that relationship to the complex is through different direct 495 * complex members. 496 * @return pattern 497 */ 498 public static Pattern inComplexWith() 499 { 500 Pattern p = new Pattern(SequenceEntityReference.class, "Protein 1"); 501 p.add(linkedER(true), "Protein 1", "generic Protein 1"); 502 p.add(erToPE(), "generic Protein 1", "SPE1"); 503 p.add(linkToComplex(), "SPE1", "PE1"); 504 p.add(new PathConstraint("PhysicalEntity/componentOf"), "PE1", "Complex"); 505 p.add(new PathConstraint("Complex/component"), "Complex", "PE2"); 506 p.add(equal(false), "PE1", "PE2"); 507 p.add(linkToSpecific(), "PE2", "SPE2"); 508 p.add(peToER(), "SPE2", "generic Protein 2"); 509 p.add(linkedER(false), "generic Protein 2", "Protein 2"); 510 p.add(equal(false), "Protein 1", "Protein 2"); 511 p.add(new Type(ProteinReference.class), "Protein 2"); 512 return p; 513 } 514 515 /** 516 * A small molecule is in a complex with a protein. 517 * 518 * @param blacklist a skip-list of ubiquitous molecules 519 * @return pattern 520 */ 521 public static Pattern chemicalAffectsProteinThroughBinding(Blacklist blacklist) 522 { 523 Pattern p = new Pattern(SmallMoleculeReference.class, "SMR"); 524 p.add(erToPE(), "SMR", "SPE1"); 525 p.add(notGeneric(), "SPE1"); 526 if (blacklist != null) p.add(new NonUbique(blacklist), "SPE1"); 527 p.add(linkToComplex(), "SPE1", "PE1"); 528 p.add(new PathConstraint("PhysicalEntity/componentOf"), "PE1", "Complex"); 529 p.add(new PathConstraint("Complex/component"), "Complex", "PE2"); 530 p.add(equal(false), "PE1", "PE2"); 531 p.add(linkToSpecific(), "PE2", "SPE2"); 532 p.add(new Type(SequenceEntity.class), "SPE2"); 533 p.add(peToER(), "SPE2", "generic ER"); 534 p.add(linkedER(false), "generic ER", "ER"); 535 return p; 536 } 537 538 /** 539 * A small molecule controls an interaction of which the protein is a participant. 540 * @return pattern 541 */ 542 public static Pattern chemicalAffectsProteinThroughControl() 543 { 544 Pattern p = new Pattern(SmallMoleculeReference.class, "controller SMR"); 545 p.add(erToPE(), "controller SMR", "controller simple PE"); 546 p.add(notGeneric(), "controller simple PE"); 547 p.add(linkToComplex(), "controller simple PE", "controller PE"); 548 p.add(peToControl(), "controller PE", "Control"); 549 p.add(controlToInter(), "Control", "Interaction"); 550 p.add(new NOT(participantER()), "Interaction", "controller SMR"); 551 p.add(participant(), "Interaction", "affected PE"); 552 p.add(linkToSpecific(), "affected PE", "affected simple PE"); 553 p.add(new Type(SequenceEntity.class), "affected simple PE"); 554 p.add(peToER(), "affected simple PE", "affected generic ER"); 555 p.add(linkedER(false), "affected generic ER", "affected ER"); 556 return p; 557 } 558 559 /** 560 * Constructs a pattern where first and last proteins are related through an interaction. They 561 * can be participants or controllers. No limitation. 562 * @return the pattern 563 */ 564 public static Pattern neighborOf() 565 { 566 Pattern p = new Pattern(SequenceEntityReference.class, "Protein 1"); 567 p.add(linkedER(true), "Protein 1", "generic Protein 1"); 568 p.add(erToPE(), "generic Protein 1", "SPE1"); 569 p.add(linkToComplex(), "SPE1", "PE1"); 570 p.add(peToInter(), "PE1", "Inter"); 571 p.add(interToPE(), "Inter", "PE2"); 572 p.add(linkToSpecific(), "PE2", "SPE2"); 573 p.add(equal(false), "SPE1", "SPE2"); 574 p.add(type(SequenceEntity.class), "SPE2"); 575 p.add(peToER(), "SPE2", "generic Protein 2"); 576 p.add(linkedER(false), "generic Protein 2", "Protein 2"); 577 p.add(equal(false), "Protein 1", "Protein 2"); 578 return p; 579 } 580 581 /** 582 * Constructs a pattern where first and last small molecules are substrates to the same 583 * biochemical reaction. 584 * 585 * @param blacklist a skip-list of ubiquitous molecules 586 * @return the pattern 587 */ 588 public static Pattern reactsWith(Blacklist blacklist) 589 { 590 Pattern p = new Pattern(SmallMoleculeReference.class, "SMR1"); 591 p.add(erToPE(), "SMR1", "SPE1"); 592 p.add(notGeneric(), "SPE1"); 593 p.add(linkToComplex(blacklist), "SPE1", "PE1"); 594 p.add(new ParticipatesInConv(RelType.INPUT, blacklist), "PE1", "Conv"); 595 p.add(type(BiochemicalReaction.class), "Conv"); 596 p.add(new InterToPartER(InterToPartER.Direction.ONESIDERS), "Conv", "SMR1"); 597 p.add(new ConversionSide(ConversionSide.Type.SAME_SIDE, blacklist, RelType.INPUT), "PE1", "Conv", "PE2"); 598 p.add(type(SmallMolecule.class), "PE2"); 599 p.add(linkToSpecific(), "PE2", "SPE2"); 600 p.add(notGeneric(), "SPE2"); 601 p.add(new PEChainsIntersect(false), "SPE1", "PE1", "SPE2", "PE2"); 602 p.add(peToER(), "SPE2", "SMR2"); 603 p.add(equal(false), "SMR1", "SMR2"); 604 p.add(new InterToPartER(InterToPartER.Direction.ONESIDERS), "Conv", "SMR2"); 605 return p; 606 } 607 608 /** 609 * Constructs a pattern where first small molecule is an input a biochemical reaction that 610 * produces the second small molecule. 611 * biochemical reaction. 612 * 613 * @param blacklist a skip-list of ubiquitous molecules 614 * @return the pattern 615 */ 616 public static Pattern usedToProduce(Blacklist blacklist) 617 { 618 Pattern p = new Pattern(SmallMoleculeReference.class, "SMR1"); 619 p.add(erToPE(), "SMR1", "SPE1"); 620 p.add(notGeneric(), "SPE1"); 621 p.add(linkToComplex(blacklist), "SPE1", "PE1"); 622 p.add(new ParticipatesInConv(RelType.INPUT, blacklist), "PE1", "Conv"); 623 p.add(type(BiochemicalReaction.class), "Conv"); 624 p.add(new InterToPartER(InterToPartER.Direction.ONESIDERS), "Conv", "SMR1"); 625 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE, blacklist, RelType.OUTPUT), "PE1", "Conv", "PE2"); 626 p.add(type(SmallMolecule.class), "PE2"); 627 p.add(linkToSimple(blacklist), "PE2", "SPE2"); 628 p.add(notGeneric(), "SPE2"); 629 p.add(equal(false), "SPE1", "SPE2"); 630 p.add(peToER(), "SPE2", "SMR2"); 631 p.add(equal(false), "SMR1", "SMR2"); 632 p.add(new InterToPartER(InterToPartER.Direction.ONESIDERS), "Conv", "SMR2"); 633 return p; 634 } 635 636 /** 637 * Constructs a pattern where first and last molecules are participants of a 638 * MolecularInteraction. 639 * @return the pattern 640 */ 641 public static Pattern molecularInteraction() 642 { 643 Pattern p = new Pattern(SequenceEntityReference.class, "Protein 1"); 644 p.add(linkedER(true), "Protein 1", "generic Protein 1"); 645 p.add(erToPE(), "generic Protein 1", "SPE1"); 646 p.add(linkToComplex(), "SPE1", "PE1"); 647 p.add(new PathConstraint("PhysicalEntity/participantOf:MolecularInteraction"), "PE1", "MI"); 648 p.add(participant(), "MI", "PE2"); 649 p.add(equal(false), "PE1", "PE2"); 650 651 // participants are not both baits or preys 652 p.add(new NOT(new AND(new MappedConst(isPrey(), 0), new MappedConst(isPrey(), 1))), "PE1", "PE2"); 653 p.add(new NOT(new AND(new MappedConst(isBait(), 0), new MappedConst(isBait(), 1))), "PE1", "PE2"); 654 655 p.add(linkToSpecific(), "PE2", "SPE2"); 656 p.add(type(SequenceEntity.class), "SPE2"); 657 p.add(new PEChainsIntersect(false), "SPE1", "PE1", "SPE2", "PE2"); 658 p.add(peToER(), "SPE2", "generic Protein 2"); 659 p.add(linkedER(false), "generic Protein 2", "Protein 2"); 660 p.add(equal(false), "Protein 1", "Protein 2"); 661 return p; 662 } 663 664 665 //----- Section: Other patterns ---------------------------------------------------------------| 666 667 /** 668 * Finds ProteinsReference related to an interaction. If specific types of interactions are 669 * desired, they should be sent as parameter, otherwise leave the parameter empty. 670 * 671 * @param seedType specific BioPAX interaction sub-types (interface classes) 672 * @return pattern 673 */ 674 public static Pattern relatedProteinRefOfInter(Class<? extends Interaction>... seedType) 675 { 676 Pattern p = new Pattern(Interaction.class, "Interaction"); 677 678 if (seedType.length == 1) 679 { 680 p.add(new Type(seedType[0]), "Interaction"); 681 } 682 else if (seedType.length > 1) 683 { 684 MappedConst[] mc = new MappedConst[seedType.length]; 685 for (int i = 0; i < mc.length; i++) 686 { 687 mc[i] = new MappedConst(new Type(seedType[i]), 0); 688 } 689 690 p.add(new OR(mc), "Interaction"); 691 } 692 693 p.add(new OR(new MappedConst(participant(), 0, 1), 694 new MappedConst(new PathConstraint( 695 "Interaction/controlledOf*/controller:PhysicalEntity"), 0, 1)), 696 "Interaction", "PE"); 697 698 p.add(linkToSpecific(), "PE", "SPE"); 699 p.add(peToER(), "SPE", "generic PR"); 700 p.add(new Type(ProteinReference.class), "generic PR"); 701 p.add(linkedER(false), "generic PR", "PR"); 702 return p; 703 } 704 705 /** 706 * Pattern for two different EntityReference have member PhysicalEntity in the same Complex. 707 * Complex membership can be through multiple nesting and/or through homology relations. 708 * @return the pattern 709 */ 710 public static Pattern inSameComplex() 711 { 712 Pattern p = new Pattern(EntityReference.class, "first ER"); 713 p.add(erToPE(), "first ER", "first simple PE"); 714 p.add(linkToComplex(), "first simple PE", "Complex"); 715 p.add(new Type(Complex.class), "Complex"); 716 p.add(linkToSpecific(), "Complex", "second simple PE"); 717 p.add(equal(false), "first simple PE", "second simple PE"); 718 p.add(new PEChainsIntersect(false, true), "first simple PE", "Complex", "second simple PE", "Complex"); 719 p.add(peToER(), "second simple PE", "second ER"); 720 p.add(equal(false), "first ER", "second ER"); 721 return p; 722 } 723 724 /** 725 * Pattern for two different EntityReference have member PhysicalEntity in the same Complex, and 726 * the Complex has an activity. Complex membership can be through multiple nesting and/or 727 * through homology relations. 728 * @return the pattern 729 */ 730 public static Pattern inSameActiveComplex() 731 { 732 Pattern p = inSameComplex(); 733 p.add(new ActivityConstraint(true), "Complex"); 734 return p; 735 } 736 737 /** 738 * Pattern for two different EntityReference have member PhysicalEntity in the same Complex, and 739 * the Complex has transcriptional activity. Complex membership can be through multiple nesting 740 * and/or through homology relations. 741 * @return the pattern 742 */ 743 public static Pattern inSameComplexHavingTransActivity() 744 { 745 Pattern p = inSameComplex(); 746 747 p.add(peToControl(), "Complex", "Control"); 748 p.add(controlToTempReac(), "Control", "TR"); 749 p.add(new NOT(participantER()), "TR", "first ER"); 750 p.add(new NOT(participantER()), "TR", "second ER"); 751 return p; 752 } 753 754 /** 755 * Pattern for two different EntityReference have member PhysicalEntity in the same Complex, and 756 * the Complex is controlling a Conversion. Complex membership can be through multiple nesting 757 * and/or through homology relations. 758 * @return the pattern 759 */ 760 public static Pattern inSameComplexEffectingConversion() 761 { 762 Pattern p = inSameComplex(); 763 764 p.add(peToControl(), "Complex", "Control"); 765 p.add(controlToConv(), "Control", "Conversion"); 766 p.add(new NOT(participantER()), "Control", "first ER"); 767 p.add(new NOT(participantER()), "Control", "second ER"); 768 return p; 769 } 770 771 public static Pattern peInOut() 772 { 773 Pattern p = new Pattern(EntityReference.class, "changed ER"); 774 p.add(erToPE(), "changed ER", "input simple PE"); 775 p.add(linkToComplex(), "input simple PE", "input PE"); 776 p.add(new ParticipatesInConv(RelType.INPUT), "input PE", "Conversion"); 777 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE), "input PE", "Conversion", "output PE"); 778 p.add(equal(false), "input PE", "output PE"); 779 p.add(linkToSpecific(), "output PE", "output simple PE"); 780 p.add(peToER(), "output simple PE", "changed ER"); 781 return p; 782 } 783 784 /** 785 * Pattern for an EntityReference has distinct PhysicalEntities associated with both left and 786 * right of a Conversion. 787 * @return the pattern 788 */ 789 public static Pattern modifiedPESimple() 790 { 791 Pattern p = new Pattern(EntityReference.class, "modified ER"); 792 p.add(erToPE(), "modified ER", "first PE"); 793 p.add(participatesInConv(), "first PE", "Conversion"); 794 p.add(new ConversionSide(ConversionSide.Type.OTHER_SIDE), "first PE", "Conversion", "second PE"); 795 p.add(equal(false), "first PE", "second PE"); 796 p.add(peToER(), "second PE", "modified ER"); 797 return p; 798 } 799 800 /** 801 * Pattern for the activity of an EntityReference is changed through a Conversion. 802 * @param activating desired change 803 * @param activityFeat modification features associated with activity 804 * @param inactivityFeat modification features associated with inactivity 805 * @return the pattern 806 */ 807 public static Pattern actChange(boolean activating, 808 Map<EntityReference, Set<ModificationFeature>> activityFeat, 809 Map<EntityReference, Set<ModificationFeature>> inactivityFeat) 810 { 811 Pattern p = peInOut(); 812 p.add(new OR( 813 new MappedConst(differentialActivity(activating), 0, 1), 814 new MappedConst(new ActivityModificationChangeConstraint( 815 activating, activityFeat, inactivityFeat), 0, 1)), 816 "input simple PE", "output simple PE"); 817 return p; 818 } 819 820 /** 821 * Pattern for finding Conversions that an EntityReference is participating. 822 * @return the pattern 823 */ 824 public static Pattern modifierConv() 825 { 826 Pattern p = new Pattern(EntityReference.class, "ER"); 827 p.add(erToPE(), "ER", "SPE"); 828 p.add(linkToComplex(), "SPE", "PE"); 829 p.add(participatesInConv(), "PE", "Conversion"); 830 return p; 831 } 832 833 /** 834 * Pattern for detecting PhysicalEntity that controls a Conversion whose participants are not 835 * associated with the EntityReference of the initial PhysicalEntity. 836 * @return the pattern 837 */ 838 public static Pattern hasNonSelfEffect() 839 { 840 Pattern p = new Pattern(PhysicalEntity.class, "SPE"); 841 p.add(peToER(), "SPE", "ER"); 842 p.add(linkToComplex(), "SPE", "PE"); 843 p.add(peToControl(), "PE", "Control"); 844 p.add(controlToInter(), "Control", "Inter"); 845 p.add(new NOT(participantER()), "Inter", "ER"); 846 return p; 847 } 848 849 // Patterns for PSB 850 851 /** 852 * Finds two Protein that appear together in a Complex. 853 * @return the pattern 854 */ 855 public static Pattern bindsTo() 856 { 857 Pattern p = new Pattern(ProteinReference.class, "first PR"); 858 p.add(erToPE(), "first PR", "first simple PE"); 859 p.add(linkToComplex(), "first simple PE", "Complex"); 860 p.add(new Type(Complex.class), "Complex"); 861 p.add(linkToSpecific(), "Complex", "second simple PE"); 862 p.add(peToER(), "second simple PE", "second PR"); 863 p.add(equal(false), "first PR", "second PR"); 864 return p; 865 } 866 867}