001package org.biopax.paxtools.io.sif.level2;
002
003import org.apache.commons.logging.Log;
004import org.apache.commons.logging.LogFactory;
005import org.biopax.paxtools.io.sif.BinaryInteractionType;
006import org.biopax.paxtools.io.sif.InteractionSet;
007import org.biopax.paxtools.io.sif.MaximumInteractionThresholdExceedException;
008import org.biopax.paxtools.io.sif.SimpleInteraction;
009import org.biopax.paxtools.model.Model;
010import org.biopax.paxtools.model.level2.*;
011
012import java.util.Arrays;
013import java.util.List;
014import java.util.Map;
015import java.util.Set;
016
017import static org.biopax.paxtools.io.sif.BinaryInteractionType.INTERACTS_WITH;
018import static org.biopax.paxtools.io.sif.BinaryInteractionType.REACTS_WITH;
019
020/**
021 * Finds pairs of molecules that are participants of the same interaction.
022 * User: demir Date: Dec 28, 2007 Time: 5:52:06 PM
023 */
024public class ParticipatesRule extends InteractionRuleL2Adaptor
025{
026        /**
027         * Supported interaction types.
028         */
029        private static List<BinaryInteractionType> binaryInteractionTypes =
030                        Arrays.asList(BinaryInteractionType.INTERACTS_WITH, REACTS_WITH);
031
032        /**
033         * A limit for number of participants.
034         */
035        private long threshold;
036
037        /**
038         * Log for logging.
039         */
040        private static Log log = LogFactory.getLog(ComponentRule.class);
041
042        /**
043         * Option to not to throw an exception when the participant threshold is exceeded, but to just
044         * skip it
045         */
046        boolean suppressExceptions = false;
047
048        /**
049         * Option to not to mine INTERACTS_WITH type.
050         */
051        private boolean skipInteractions;
052
053        /**
054         * Option to not to mine REACTS_WITH type.
055         */
056        private boolean skipConversions;
057
058        /**
059         * Constructor with default values.
060         */
061        public ParticipatesRule()
062        {
063                this(Integer.MAX_VALUE);
064        }
065
066        /**
067         * Constructor with participant number threshold.
068         * @param threshold participant number threshold
069         */
070        public ParticipatesRule(int threshold)
071        {
072                this(threshold, false);
073
074        }
075
076        /**
077         * Constructor with participant number threshold and option to suppress exceptions.
078         * @param threshold participant number threshold
079         * @param suppressExceptions option to just skip interactions with too many participants
080         */
081        public ParticipatesRule(int threshold, boolean suppressExceptions)
082        {
083                this.threshold = threshold;
084                this.suppressExceptions = suppressExceptions;
085
086        }
087
088        /**
089         * Initializes options.
090         * @param options options map
091         */
092        @Override public void initOptionsNotNull(Map options)
093        {
094                skipConversions = options.containsKey(REACTS_WITH) &&
095                        options.get(REACTS_WITH).equals(false);
096                skipInteractions = options.containsKey(INTERACTS_WITH) &&
097                        options.get(INTERACTS_WITH).equals(false);
098        }
099
100        /**
101         * Infer using given physicalEntity as source.
102         * @param interactionSet to be populated
103         * @param pe source
104         * @param model BioPAX model
105         */
106        public void inferInteractionsFromPE(InteractionSet interactionSet, physicalEntity pe,
107                Model model)
108        {
109                // There is nothing to find if we are skipping both rules
110                if (skipConversions && skipInteractions)
111                {
112                        return;
113                }
114
115                Set<interaction> interactions = pe.getAllInteractions();
116                for (interaction interaction : interactions)
117                {
118                        BinaryInteractionType type;
119                        if ((interaction instanceof control))
120                        {
121                                continue;
122                        } else if (interaction instanceof conversion)
123                        {
124                                if (skipConversions)
125                                {
126                                        continue;
127                                }
128
129                                type = REACTS_WITH;
130                        } else
131                        {
132                                if (skipInteractions)
133                                {
134                                        continue;
135                                }
136
137                                type = INTERACTS_WITH;
138                        }
139
140                        Set<InteractionParticipant> ips = interaction.getPARTICIPANTS();
141                        if (ips.size() > threshold)
142                        {
143                                log.warn("The size of participants is too large! Skipping");
144                                if (suppressExceptions) return;
145                                else throw new MaximumInteractionThresholdExceedException(pe.toString());
146                        } else
147                        {
148                                for (InteractionParticipant ip : ips)
149                                {
150                                        processParticipant(interactionSet, pe, ip, type, interaction);
151                                }
152                        }
153                }
154        }
155
156        /**
157         * Creates the binary interaction using the other participant.
158         * @param interactionSet to populate
159         * @param pe source
160         * @param ip related to target
161         * @param type type of the binary interaction
162         * @param interaction the interaction that relates two participants
163         */
164        private void processParticipant(InteractionSet interactionSet, physicalEntity pe, InteractionParticipant ip,
165                        BinaryInteractionType type, interaction interaction)
166        {
167                physicalEntity pe2 = null;
168                if (ip instanceof physicalEntity)
169                {
170                        pe2 = (physicalEntity) ip;
171                } else if (ip instanceof physicalEntityParticipant)
172                {
173                        pe2 = ((physicalEntityParticipant) ip).getPHYSICAL_ENTITY();
174                }
175                if (pe2 != null)
176                {
177                        createInteraction(pe, pe2, interactionSet, type, interaction);
178                }
179        }
180
181        /**
182         * Creates the interaction between given source and target.
183         * @param pe source
184         * @param pe2 target
185         * @param set to populate
186         * @param type binary interaction type
187         * @param interaction mediator
188         */
189        private void createInteraction(physicalEntity pe, physicalEntity pe2, InteractionSet set,
190                        BinaryInteractionType type, interaction interaction)
191        {
192                if (!pe2.equals(pe))
193                {
194                        SimpleInteraction si = new SimpleInteraction(pe, pe2, type);
195                        si.addMediator(interaction);
196                        set.add(si);
197
198                }
199        }
200
201        public List<BinaryInteractionType> getRuleTypes()
202        {
203                return binaryInteractionTypes;
204        }
205}