001package org.biopax.paxtools.pattern.constraint; 002 003import org.biopax.paxtools.controller.PathAccessor; 004import org.biopax.paxtools.model.BioPAXElement; 005import org.biopax.paxtools.model.level3.PhysicalEntity; 006import org.biopax.paxtools.pattern.Constraint; 007import org.biopax.paxtools.pattern.MappedConst; 008import org.biopax.paxtools.pattern.Match; 009import org.biopax.paxtools.pattern.util.Blacklist; 010import org.biopax.paxtools.pattern.util.RelType; 011 012import java.util.Arrays; 013import java.util.HashSet; 014 015/** 016 * Some predefined constraints. 017 * 018 * @author Ozgun Babur 019 */ 020public class ConBox 021{ 022 /** 023 * From EntityReference to the member PhysicalEntity 024 * @return generative constraint to get to the member PhysicalEntity of the EntityReference 025 */ 026 public static Constraint erToPE() 027 { 028 return new PathConstraint("EntityReference/entityReferenceOf"); 029 } 030 031 /** 032 * From SimplePhysicalEntity to its EntityReference. 033 * @return generative constraint to get the EntityReference of the SimplePhysicalEntity 034 */ 035 public static Constraint peToER() 036 { 037 return new PathConstraint("SimplePhysicalEntity/entityReference"); 038 } 039 040 /** 041 * From PhysicalEntity to the downstream Control 042 * @return generative constraint to get the Control that the PhysicalEntity is a controller 043 */ 044 public static Constraint peToControl() 045 { 046 return new PathConstraint("PhysicalEntity/controllerOf"); 047 } 048 049 /** 050 * From PhysicalEntity to the downstream Conversion. 051 * @return generative constraint to get the Conversion that the PhysicalEntity is a controller 052 */ 053 public static Constraint peToControlledConv() 054 { 055 return new PathConstraint("PhysicalEntity/controllerOf/controlled*:Conversion"); 056 } 057 058 /** 059 * From PhysicalEntity to the downstream Interaction. 060 * @return generative constraint to get the Interaction that the PhysicalEntity is a controller 061 */ 062 public static Constraint peToControlledInter() 063 { 064 return new PathConstraint("PhysicalEntity/controllerOf/controlled*:Interaction"); 065 } 066 067 /** 068 * From PhysicalEntity to the related Interaction. 069 * @return generative constraint to get the Interaction that the PhysicalEntity is a controller 070 */ 071 public static Constraint peToInter() 072 { 073 return new OR( 074 new MappedConst(peToControlledInter(), 0, 1), 075 new MappedConst(participatesInInter(), 0, 1)); 076 } 077 078 /** 079 * From simple PhysicalEntity to related Conversion. The relation can be through complexes and 080 * generics. 081 * 082 * @param type relationship type 083 * @return generative constraint 084 */ 085 public static Constraint simplePEToConv(RelType type) 086 { 087 return new ConstraintChain(linkToComplex(), new ParticipatesInConv(type)); 088 } 089 090 /** 091 * From Interaction to the related PhysicalEntity. 092 * @return the constraint 093 */ 094 public static Constraint interToPE() 095 { 096 return new OR( 097 new MappedConst(interToController(), 0, 1), 098 new MappedConst(participant(), 0, 1)); 099 } 100 101 /** 102 * From Control to the controlled Process 103 * @return generative constraint to get the controlled Process of the Control 104 */ 105 public static Constraint controlled() 106 { 107 return new PathConstraint("Control/controlled"); 108 } 109 110 /** 111 * From Control to the controller PhysicalEntity 112 * @return generative constraint to get the controller PhysicalEntity of the Control 113 */ 114 public static Constraint controllerPE() 115 { 116 return new PathConstraint("Control/controller:PhysicalEntity"); 117 } 118 119 /** 120 * From Control to the controlled Conversion, traversing downstream Controls recursively. 121 * @return generative constraint to get the downstream (controlled) Conversion of the Control 122 */ 123 public static Constraint controlToConv() 124 { 125 return new PathConstraint("Control/controlled*:Conversion"); 126 } 127 128 /** 129 * From Control to the controlled TemplateReaction, traversing downstream Controls recursively. 130 * @return generative constraint to get the downstream (controlled) TemplateReaction of the 131 * Control 132 */ 133 public static Constraint controlToTempReac() 134 { 135 return new PathConstraint("Control/controlled*:TemplateReaction"); 136 } 137 138 /** 139 * From Control to the controlled Interaction, traversing downstream Controls recursively. 140 * @return generative constraint to get the downstream (controlled) Interaction of the Control 141 */ 142 public static Constraint controlToInter() 143 { 144 return new PathConstraint("Control/controlled*:Interaction"); 145 } 146 147 /** 148 * From Conversion to the upstream Control (and its upstream Control recursively). 149 * @return generative constraint to get the upstream Controls of the Conversion 150 */ 151 public static Constraint convToControl() 152 { 153 return new PathConstraint("Conversion/controlledOf*"); 154 } 155 156 /** 157 * From Conversion to the controller of the upstream Control (and its upstream Control 158 * recursively). 159 * @return the constraint 160 */ 161 public static Constraint convToController() 162 { 163 return new PathConstraint("Conversion/controlledOf*/controller"); 164 } 165 166 /** 167 * From Interaction to the upstream Control (and its upstream Control recursively). 168 * @return generative constraint to get the upstream Controls of the Interaction 169 */ 170 public static Constraint interToControl() 171 { 172 return new PathConstraint("Interaction/controlledOf*"); 173 } 174 175 /** 176 * From PhysicalEntity to the controlled Conversion, skipping the middle Control. 177 * @return generative constraint to get the Conversion that the PhysicalEntity controls 178 */ 179 public static Constraint controlsConv() 180 { 181 return new PathConstraint("PhysicalEntity/controllerOf/controlled*:Conversion"); 182 } 183 184 /** 185 * From PhysicalEntity to the controlled Interaction, skipping the middle Control. 186 * @return generative constraint to get the Interaction that the PhysicalEntity controls 187 */ 188 public static Constraint controlsInteraction() 189 { 190 return new PathConstraint("PhysicalEntity/controllerOf/controlled*:Interaction"); 191 } 192 193 /** 194 * Starts from an Interaction and gets next Interactions in temporal order, if ever defined in 195 * a Pathway. 196 * @return generative constraint 197 */ 198 public static Constraint nextInteraction() 199 { 200 return new PathConstraint("Interaction/stepProcessOf/nextStep/stepProcess:Interaction"); 201 } 202 203 /** 204 * From PhysicalEntity to its generic equivalents, i.e. either parent PhysicalEntity recursively 205 * or member PhysicalEntity recursively. Note that another member of the parent is not a generic 206 * equivalent. 207 * @return generative constraint to get the generic equivalents of the PhysicalEntity 208 */ 209 public static Constraint genericEquiv() 210 { 211 return new SelfOrThis(new MultiPathConstraint("PhysicalEntity/memberPhysicalEntity*", 212 "PhysicalEntity/memberPhysicalEntityOf*")); 213 } 214 215 /** 216 * From Complex to its members recursively (also getting member of the inner complexes). 217 * @return generative constraint to get the members of the Complex 218 */ 219 public static Constraint complexMembers() 220 { 221 return new PathConstraint("Complex/component*"); 222 } 223 224 /** 225 * From complex to its simple members (members which are of type SimplePhysicalEntity) 226 * recursively. 227 * @return generative constraint to get the simple members of the Complex recursively 228 */ 229 public static Constraint simpleMembers() 230 { 231 return new PathConstraint("Complex/component*:SimplePhysicalEntity"); 232 } 233 234 /** 235 * From Complex to its members, or the complex itself. 236 * @return generative constraint to get the members of a complex and to itself 237 */ 238 public static Constraint withComplexMembers() 239 { 240 return new SelfOrThis(complexMembers()); 241 } 242 243 /** 244 * From complex to its simple members recursively, or the Complex itself 245 * @return generative constraint to get the simple members of the Complex recursively, or the 246 * Complex itself 247 */ 248 public static Constraint withSimpleMembers() 249 { 250 return new SelfOrThis(simpleMembers()); 251 } 252 253 /** 254 * From PhysicalEntity to its parent Complex recursively. 255 * @return generative constraint to get the parent Complex of the PhysicalEntity recursively 256 */ 257 public static Constraint complexes() 258 { 259 return new PathConstraint("PhysicalEntity/componentOf*"); 260 } 261 262 /** 263 * From PhysicalEntity to parent Complex recursively, or to itself. 264 * @return generative constraint to get the parent Complex of PhysicalEntity recursively, ot to 265 * itself 266 */ 267 public static Constraint withComplexes() 268 { 269 return new SelfOrThis(complexes()); 270 } 271 272 /** 273 * From Conversion to its left participants. 274 * @return generative constraint to get the left participants of the Conversion 275 */ 276 public static Constraint left() 277 { 278 return new PathConstraint("Conversion/left"); 279 } 280 281 /** 282 * From Conversion to its right participants. 283 * @return generative constraint to get the right participants of the Conversion 284 */ 285 public static Constraint right() 286 { 287 return new PathConstraint("Conversion/right"); 288 } 289 290 /** 291 * From PhysicalEntity to the Conversion that it participates. 292 * @return generative constraint to get the Conversions that the PhysicalEntity is a participant 293 * of 294 */ 295 public static Constraint participatesInConv() 296 { 297 return new PathConstraint("PhysicalEntity/participantOf:Conversion"); 298 } 299 300 /** 301 * From PhysicalEntity to the Interaction that it participates. 302 * @return generative constraint to get the Interactions that the PhysicalEntity is a 303 * participant of 304 */ 305 public static Constraint participatesInInter() 306 { 307 return new PathConstraint("PhysicalEntity/participantOf"); 308 } 309 310 /** 311 * From Interaction to the controlling Controls recursively, and their controller PEs. 312 * @return the constraint 313 */ 314 public static Constraint interToController() 315 { 316 return new PathConstraint("Interaction/controlledOf*:Control/controller:PhysicalEntity"); 317 } 318 319 /** 320 * From Complex or SimplePhysicalEntity to the related EntityReference. If Complex, then 321 * EntityReference of simple members (recursively) are related. 322 * @return generative constraint to get the related EntityReference of the Complex or 323 * SimplePhysicalEntity 324 */ 325 public static Constraint compToER() 326 { 327 return new PathConstraint("Complex/component*:SimplePhysicalEntity/entityReference"); 328 } 329 330 /** 331 * Filters Named to contain a specific name. 332 * @param name name to require 333 * @return constraint to check if the name exists in among names 334 */ 335 public static Constraint nameEquals(String name) 336 { 337 return new Field("Named/name", Field.Operation.INTERSECT, name); 338 } 339 340 /** 341 * Filters Named to contain a name from the input set. 342 * @param name name to require 343 * @return constraint 344 */ 345 public static Constraint nameEquals(String... name) 346 { 347 return new Field("Named/name", Field.Operation.INTERSECT, 348 new HashSet<String>(Arrays.asList(name))); 349 } 350 351// /** 352// * Filters out ubiquitous elements. 353// * @param ubiques set of ubique IDs 354// * @return constraint to filter out ubique based on IDs 355// */ 356// public static Constraint notUbique(Set<String> ubiques) 357// { 358// return new NOT(new IDConstraint(ubiques)); 359// } 360 361 /** 362 * Gets a constraint to ensure that ensures only one of the two PhysicalEntities has an 363 * activity. Size of this constraint is 2. 364 * 365 * @param activating true/false (TODO explain) 366 * @return constraint to make sure only one of the PhysicalEntity has an activity 367 */ 368 public static Constraint differentialActivity(boolean activating) 369 { 370 if (activating) return new AND(new MappedConst(new ActivityConstraint(true), 1), new MappedConst(new ActivityConstraint(false), 0)); 371 else return new AND(new MappedConst(new ActivityConstraint(true), 0), new MappedConst(new ActivityConstraint(false), 1)); 372 } 373 374 /** 375 * From Interaction to its PhysicalEntity participants. 376 * @return generative constraint to get the participants of the Interaction 377 */ 378 public static Constraint participant() 379 { 380 return new PathConstraint("Interaction/participant:PhysicalEntity"); 381 } 382 383 /** 384 * From Interaction to the related EntityReference of its participants. 385 * @return generative constraint to get the related PhysicalEntity of the participants of an 386 * Interaction 387 */ 388 public static Constraint participantER() 389 { 390 return new ConstraintChain(participant(), linkToSpecific(), peToER(), linkedER(false)); 391 } 392 393 /** 394 * From TemplateReaction to its products. 395 * @return generative constraint to get the products of the TemplateReaction 396 */ 397 public static Constraint product() 398 { 399 return new PathConstraint("TemplateReaction/product"); 400 } 401 402 /** 403 * Makes sure the Interaction has no Control 404 * @return constraint to filter out Interactions with a Control 405 */ 406 public static Constraint notControlled() 407 { 408 return new Empty(new PathConstraint("Interaction/controlledOf")); 409 } 410 411 /** 412 * Makes sure the EntityReference or the PhysicalEntity belongs to human. Please note that this 413 * check depends on the display name of the related BioSource object to be "Homo sapiens". If 414 * that is not the case, the constraint won't work. 415 * @return constraint to make sure the EntityReference or the PhysicalEntity belongs to human 416 */ 417 public static Constraint isHuman() 418 { 419 return new OR( 420 new MappedConst(new Field("SequenceEntityReference/organism/displayName", 421 Field.Operation.INTERSECT, "Homo sapiens"), 0), 422 new MappedConst(new Field("PhysicalEntity/entityReference/organism/displayName", 423 Field.Operation.INTERSECT, "Homo sapiens"), 0)); 424 } 425 426 /** 427 * Makes sure that the object has an Xref with the given ID. This id is not an RDF ID, it is 428 * the value of the Xref, like gene symbol. 429 * @param xrefID xref id 430 * @return constraint 431 */ 432 public static Constraint hasXref(String xrefID) 433 { 434 return new Field("XReferrable/xref/id", Field.Operation.INTERSECT, xrefID); 435 } 436 437 /** 438 * Makes sure that the second element (PhysicalEntity) is not a participant of the first element 439 * (Interaction). 440 * @return constraint to make sure that the PhysicalEntity in second index is not a participant 441 * of the Interaction in first index 442 */ 443 public static Constraint notAParticipant() 444 { 445 return new NOT(new Field("Interaction/participant", Field.Operation.INTERSECT, 446 Field.USE_SECOND_ARG)); 447 } 448 449 /** 450 * Makes sure that the given physical entity is not related to the entity reference. 451 * @return the constraint 452 * todo: method not tested 453 */ 454 public static Constraint peNotRelatedToER() 455 { 456 return new NOT(new ConstraintChain(linkToSpecific(), peToER())); 457 } 458 459 /** 460 * Makes sure the second element (Control) is not a controller to the first element 461 * (Interaction). 462 * @return constraint to filter out cases where the Control at the second index is controlling 463 * the Interaction at the first index. 464 */ 465 public static Constraint notControlsThis() 466 { 467 // Asserts the control (first variable), does not control the conversion (second variable) 468 return new NOT(ConBox.controlToInter()); 469 } 470 471 /** 472 * Makes sure a PhysicalEntity of any linked member PhysicalEntities toward members are not 473 * labeled as inactive. 474 * @return constraint to filter out PhysicalEntity labeled as inactive. 475 */ 476 public static Constraint notLabeledInactive() 477 { 478 // Asserts the PE (and lower equivalent) are not labeled inactive 479 return new NOT(ConBox.modificationConstraint("residue modification, inactive")); 480 } 481 482 /** 483 * Makes sure that the PhysicalEntity or any linked PE contains the modification term. Size = 1. 484 * @param modifTerm term to check 485 * @return constraint to filter out PhysicalEntity not associated to a modification term 486 */ 487 public static Constraint modificationConstraint(String modifTerm) 488 { 489 return new FieldOfMultiple(new MappedConst(new LinkedPE(LinkedPE.Type.TO_SPECIFIC), 0), 490 "PhysicalEntity/feature:ModificationFeature/modificationType/term", 491 Field.Operation.INTERSECT, modifTerm); 492 } 493 494 /** 495 * Makes a linker constraint from PhysicalEntity to its linked PhysicalEntity towards member 496 * direction. 497 * @return the constraint 498 */ 499 public static Constraint linkToSpecific() 500 { 501 return new LinkedPE(LinkedPE.Type.TO_SPECIFIC); 502 } 503 504 /** 505 * Makes a linker constraint from PhysicalEntity to its linked PhysicalEntity towards complex 506 * direction. 507 * @return the constraint 508 */ 509 public static Constraint linkToComplex() 510 { 511 return new LinkedPE(LinkedPE.Type.TO_GENERAL); 512 } 513 514 public static Constraint linkedER(boolean up) 515 { 516 return new SelfOrThis(new PathConstraint("EntityReference/memberEntityReference" + (up ? "Of" : "") + "*")); 517 } 518 519 /** 520 * Makes a linker constraint from PhysicalEntity to its linked PhysicalEntity towards member 521 * direction. 522 * @param blacklist used to detect ubiquitous small molecules 523 * @return the constraint 524 */ 525 public static Constraint linkToSimple(Blacklist blacklist) 526 { 527 return new LinkedPE(LinkedPE.Type.TO_SPECIFIC, blacklist); 528 } 529 530 /** 531 * Makes a linker constraint from PhysicalEntity to its linked PhysicalEntity towards complex 532 * direction. 533 * @param blacklist used to detect ubiquitous small molecules 534 * @return the constraint 535 */ 536 public static Constraint linkToComplex(Blacklist blacklist) 537 { 538 return new LinkedPE(LinkedPE.Type.TO_GENERAL, blacklist); 539 } 540 541 /** 542 * Makes a linker constraint from PhysicalEntity to its linked PhysicalEntity towards complex 543 * direction. 544 * 545 * @param equal true/false (TODO explain) 546 * @return the constraint 547 */ 548 public static Constraint equal(boolean equal) 549 { 550 return new Equality(equal); 551 } 552 553 /** 554 * Creates an element type constraint. 555 * 556 * @param clazz a BioPAX type, i.e., corresponding interface class 557 * @return the constraint 558 */ 559 public static Constraint type(Class<? extends BioPAXElement> clazz) 560 { 561 return new Type(clazz); 562 } 563 564 /** 565 * Makes sure that the PhysicalEntity do not have member physical entities.. 566 * @return the constraint 567 */ 568 public static Constraint notGeneric() 569 { 570 return new Empty(new PathConstraint("PhysicalEntity/memberPhysicalEntity")); 571 } 572 573 /** 574 * Makes sure the participant degree (number of Conversions that this is a participant) of the 575 * PhysicalEntity is less than or equal to the parameter. 576 * 577 * @param limit max degree limit 578 * @return the constraint 579 */ 580 public static Constraint maxDegree(int limit) 581 { 582 return new Size(new PathConstraint("PhysicalEntity/participantOf:Conversion"), limit, 583 Size.Type.LESS_OR_EQUAL); 584 } 585 586 public static Constraint source(String dbname) 587 { 588 return new Field("Entity/dataSource/displayName", Field.Operation.INTERSECT, dbname); 589 } 590 591 /** 592 * Makes sure that the two interactions are members of the same pathway. 593 * @return non-generative constraint 594 */ 595 public static Constraint inSamePathway() 596 { 597 String s1 = "Interaction/stepProcessOf/pathwayOrderOf"; 598 String s2 = "Interaction/pathwayComponentOf"; 599 return new OR(new MappedConst(new Field(s1, s1, Field.Operation.INTERSECT), 0, 1), 600 new MappedConst(new Field(s2, s2, Field.Operation.INTERSECT), 0, 1)); 601 } 602 603 /** 604 * Makes sure that the PhysicalEntity is controlling more reactions than it participates 605 * (excluding complex assembly). 606 * @return non-generative constraint 607 */ 608 public static Constraint moreControllerThanParticipant() 609 { 610 return new ConstraintAdapter(1) 611 { 612 PathAccessor partConv = new PathAccessor("PhysicalEntity/participantOf:Conversion"); 613 PathAccessor partCompAss = new PathAccessor("PhysicalEntity/participantOf:ComplexAssembly"); 614 PathAccessor effects = new PathAccessor("PhysicalEntity/controllerOf/controlled*:Conversion"); 615 616 @Override 617 public boolean satisfies(Match match, int... ind) 618 { 619 PhysicalEntity pe = (PhysicalEntity) match.get(ind[0]); 620 621 int partCnvCnt = partConv.getValueFromBean(pe).size(); 622 int partCACnt = partCompAss.getValueFromBean(pe).size(); 623 int effCnt = effects.getValueFromBean(pe).size(); 624 625 return (partCnvCnt - partCACnt) <= effCnt; 626 } 627 }; 628 } 629 630 /** 631 * Checks if two physical entities have non-empty and different compartments. 632 * @return the constraint 633 */ 634 public static Constraint hasDifferentCompartments() 635 { 636 String acStr = "PhysicalEntity/cellularLocation/term"; 637 return new Field(acStr, acStr, Field.Operation.NOT_EMPTY_AND_NOT_INTERSECT); 638 } 639 640 /** 641 * Checks if the molecule is a prey of a Y2H experiment. 642 * @return the constraint 643 */ 644 public static Constraint isPrey() 645 { 646 return new Field("PhysicalEntity/evidence/experimentalForm/experimentalFormDescription/term", 647 Field.Operation.INTERSECT, "prey"); 648 } 649 650 /** 651 * Checks if the molecule is a bait of a Y2H experiment. 652 * @return the constraint 653 */ 654 public static Constraint isBait() 655 { 656 return new Field("PhysicalEntity/evidence/experimentalForm/experimentalFormDescription/term", 657 Field.Operation.INTERSECT, "bait"); 658 } 659}