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}