001package org.biopax.paxtools.pattern.constraint;
002
003import org.biopax.paxtools.pattern.Match;
004import org.biopax.paxtools.model.BioPAXElement;
005import org.biopax.paxtools.model.level3.Conversion;
006import org.biopax.paxtools.model.level3.ConversionDirectionType;
007import org.biopax.paxtools.model.level3.Interaction;
008import org.biopax.paxtools.model.level3.PhysicalEntity;
009import org.biopax.paxtools.pattern.util.Blacklist;
010import org.biopax.paxtools.pattern.util.RelType;
011
012import java.util.Collection;
013import java.util.HashSet;
014
015/**
016 * Gets the related Conversion where the PhysicalEntity is input or output, whichever is desired.
017 *
018 * var0 is a PE
019 * var1 is a Conversion
020 *
021 * @author Ozgun Babur
022 */
023public class ParticipatesInConv extends ConstraintAdapter
024{
025        /**
026         * Input or output.
027         */
028        private RelType type;
029
030        /**
031         * Constructor with parameters.
032         * @param type input or output conversion
033         * @param blacklist for detecting blacklisted small molecules
034         */
035        public ParticipatesInConv(RelType type, Blacklist blacklist)
036        {
037                super(2, blacklist);
038                this.type = type;
039        }
040
041        /**
042         * Constructor with parameters.
043         * @param type input or output
044         * conversion
045         */
046        public ParticipatesInConv(RelType type)
047        {
048                this(type, null);
049        }
050
051        /**
052         * This is a generative constraint.
053         * @return true
054         */
055        @Override
056        public boolean canGenerate()
057        {
058                return true;
059        }
060
061        /**
062         * Identifies the conversion direction and gets the related participants.
063         * @param match current pattern match
064         * @param ind mapped indices
065         * @return input or output participants
066         */
067        @Override
068        public Collection<BioPAXElement> generate(Match match, int... ind)
069        {
070                Collection<BioPAXElement> result = new HashSet<BioPAXElement>();
071
072                PhysicalEntity pe = (PhysicalEntity) match.get(ind[0]);
073
074                for (Interaction inter : pe.getParticipantOf())
075                {
076                        if (inter instanceof Conversion)
077                        {
078                                Conversion cnv = (Conversion) inter;
079                                ConversionDirectionType dir = getDirection(cnv);
080
081                                // do not get blacklisted small molecules
082                                if (blacklist != null && blacklist.isUbique(pe, cnv, dir, type)) continue;
083
084                                if (dir == ConversionDirectionType.REVERSIBLE)
085                                {
086                                        result.add(cnv);
087                                }
088                                else if (dir == ConversionDirectionType.RIGHT_TO_LEFT &&
089                                        (type == RelType.INPUT ? cnv.getRight().contains(pe) : cnv.getLeft().contains(pe)))
090                                {
091                                        result.add(cnv);
092                                }
093                                // Note that null direction is treated as if LEFT_TO_RIGHT. This is not a best
094                                // practice, but it is a good approximation.
095                                else if ((dir == ConversionDirectionType.LEFT_TO_RIGHT || dir == null) &&
096                                        (type == RelType.INPUT ? cnv.getLeft().contains(pe) : cnv.getRight().contains(pe)))
097                                {
098                                        result.add(cnv);
099                                }
100                        }
101                }
102
103                return result;
104        }
105}