001package org.biopax.paxtools.pattern.constraint; 002 003import org.biopax.paxtools.model.BioPAXElement; 004import org.biopax.paxtools.model.level3.*; 005import org.biopax.paxtools.pattern.Match; 006import org.biopax.paxtools.pattern.util.Blacklist; 007import org.biopax.paxtools.pattern.util.RelType; 008 009import java.util.*; 010 011/** 012 * This constraint is useful when we want traverse Control-Conversion-PE (input or output). Control 013 * and Conversion are prerequisites, PE is generated. 014 * 015 * Var0 - Control 016 * Var1 - Conversion 017 * Var2 - input or output PhysicalEntity 018 * 019 * @deprecated 020 * @see Participant 021 * 022 * @author Ozgun Babur 023 */ 024public class ParticipatingPE extends ConstraintAdapter 025{ 026 /** 027 * Desired direction after the Conversion. 028 */ 029 RelType type; 030 031 /** 032 * Constructor with parameters. 033 * @param type direction from the Conversion - input or output type 034 * @param blacklist a skip-list of ubiquitous molecules 035 */ 036 public ParticipatingPE(RelType type, Blacklist blacklist) 037 { 038 super(3, blacklist); 039 this.type = type; 040 } 041 042 /** 043 * Constructor with parameters. 044 * @param type direction from the Conversion 045 */ 046 public ParticipatingPE(RelType type) 047 { 048 this(type, null); 049 } 050 051 /** 052 * This is a generative constraint. 053 * @return true if the constraint can generate candidates 054 */ 055 @Override 056 public boolean canGenerate() 057 { 058 return true; 059 } 060 061 /** 062 * First evaluates the direction that the Control is affecting the Conversion, then gets the 063 * related participants. 064 * @param match current pattern match 065 * @param ind mapped indices 066 * @return related participants 067 */ 068 @Override 069 public Collection<BioPAXElement> generate(Match match, int... ind) 070 { 071 Control cont = (Control) match.get(ind[0]); 072 Conversion conv = (Conversion) match.get(ind[1]); 073 074 // This is the direction for our use only. 075 ConversionDirectionType dir = getDirection(conv, cont); 076 077 Set<Set<PhysicalEntity>> sides = new HashSet<Set<PhysicalEntity>>(); 078 079 if (dir == ConversionDirectionType.LEFT_TO_RIGHT) 080 { 081 sides.add(type == RelType.INPUT ? conv.getLeft() : conv.getRight()); 082 } 083 else if (dir == ConversionDirectionType.RIGHT_TO_LEFT) 084 { 085 sides.add(type == RelType.OUTPUT ? conv.getLeft() : conv.getRight()); 086 } 087 else // dir is reversible and we will go both sides 088 { 089 sides.add(conv.getLeft()); 090 sides.add(conv.getRight()); 091 } 092 093 Set<BioPAXElement> result = new HashSet<BioPAXElement>(); 094 095 if (blacklist == null) 096 { 097 for (Set<PhysicalEntity> side : sides) 098 { 099 result.addAll(side); 100 } 101 } 102 else 103 { 104 for (Set<PhysicalEntity> side : sides) 105 { 106 // if the control is in fact reversible then don't mind the context 107 result.addAll(blacklist.getNonUbiques(side, 108 dir == ConversionDirectionType.REVERSIBLE ? null : type)); 109 } 110 } 111 112 return result; 113 } 114}