001package org.biopax.paxtools.io.sif.level2;
002
003import org.biopax.paxtools.io.sif.BinaryInteractionType;
004import org.biopax.paxtools.io.sif.InteractionSet;
005import org.biopax.paxtools.io.sif.SimpleInteraction;
006import org.biopax.paxtools.model.Model;
007import org.biopax.paxtools.model.level2.control;
008import org.biopax.paxtools.model.level2.physicalEntity;
009import org.biopax.paxtools.model.level2.physicalEntityParticipant;
010import org.biopax.paxtools.model.level2.process;
011
012import java.util.Arrays;
013import java.util.List;
014
015import static org.biopax.paxtools.io.sif.BinaryInteractionType.CO_CONTROL;
016
017/**
018 * Implements Co-Control rule, which means A and B have a control over the same interaction.
019 *
020 * This class performs a recursive search both downwards and and upwards of a
021 * control that A is a controller. Upwards search always proceed to upwards, i.e.
022 * never switch back to downwards at any point. If this is directly upwards of the
023 * first control that we start the search, then all reachable B have dependent
024 * activity to A. Downward search, however, is different. It can switch to an
025 * upwards search when possible, to infer independent controls.
026 *
027 * There appears three possible search patterns, starting from the first control
028 * (of A), each provides only dependent or independent relations:
029 *
030 * <ul>
031 * <li>Upwards only --&gt; dependent relation</li>
032 * <li>Downwards only --&gt; dependent relation</li>
033 * <li>Downwards then upwards --&gt; independent relation</li>
034 * </ul>
035 * @author Emek Demir
036 * @author Ozgun Babur
037 */
038public class ControlsTogetherRule extends InteractionRuleL2Adaptor
039{
040        /**
041         * Supported interaction types.
042         */
043        private static List<BinaryInteractionType> binaryInteractionTypes = Arrays.asList(CO_CONTROL);
044
045        /**
046         * Infers interactions using A as source.
047         * @param interactionSet to be populated
048         * @param A source
049         * @param model BioPAX model
050         */
051        public void inferInteractionsFromPE(InteractionSet interactionSet, physicalEntity A, Model model)
052        {
053
054                // Iterate over controls of A
055                for (control ctrl : A.getAllInteractions(control.class))
056                {
057                        // Iterate other controllers
058                        iterateControllers(ctrl, A, interactionSet);
059                        // Iterate upward controls
060                        proceedUpwards(ctrl, A, interactionSet);
061                        // Iterate downward controls
062                        proceedDownwards(ctrl, A, interactionSet);
063                }
064        }
065
066        /**
067         * Iterates downwards processes, initiates a downwards search of controls and
068         * upwards search of controls and conversions.
069         * @param ctrl to look downward
070         * @param A first entity in A-B binary interaction
071         * @param interactionSet set to collect inferred interactions
072         */
073        private void proceedDownwards(control ctrl, physicalEntity A, InteractionSet interactionSet)
074        {
075                // Iterate each controlled process
076                for (process prcss : ctrl.getCONTROLLED())
077                {
078                        // Search downwards of controls
079                        if (prcss instanceof control)
080                        {
081                                searchDownwards((control) prcss, A, interactionSet);
082                        }
083
084                        // Search other upwards control trees of all processes (controls and conversions)
085                        for (control cnt : prcss.isCONTROLLEDOf())
086                        {
087                                if (cnt != ctrl) // Do not go where we came from
088                                {
089                                        searchUpwards(cnt, A, interactionSet);
090                                }
091                        }
092                }
093        }
094
095        /**
096         * Tries to infer relations with the controllers of the control and proceeds
097         * downwards.
098         * @param ctrl to search downwards
099         * @param A A of A-B
100         * @param interactionSet set to collect inferred interactions
101         */
102        private void searchDownwards(control ctrl, physicalEntity A, InteractionSet interactionSet)
103        {
104                // Search for rules
105                iterateControllers(ctrl, A, interactionSet);
106                proceedDownwards(ctrl, A, interactionSet);
107        }
108
109        /**
110         * Tries to infer relations with the controllers of the control and proceeds to
111         * upwards.
112         * @param ctrl to search upwards
113         * @param A A in A-B
114         * @param interactionSet set to collect inferred rules
115         */
116        private void searchUpwards(control ctrl, physicalEntity A, InteractionSet interactionSet)
117        {
118                iterateControllers(ctrl, A, interactionSet);
119                proceedUpwards(ctrl, A, interactionSet);
120        }
121
122        /**
123         * Iterates the controller of ctrl and infers possible binary interactions.
124         * @param ctrl to iterate controllers
125         * @param A A in A-B ctrl
126         * @param interactionSet set to collect inferred interactions
127         */
128        private void iterateControllers(control ctrl, physicalEntity A, InteractionSet interactionSet)
129        {
130                for (physicalEntityParticipant pep : ctrl.getCONTROLLER())
131                {
132                        physicalEntity B = pep.getPHYSICAL_ENTITY();
133                        if (B != A)
134                        {
135                                interactionSet.add(new SimpleInteraction(A, B, CO_CONTROL));
136                        }
137                }
138        }
139
140        /**
141         * Iterates upward controls and initiates an upward search for each one.
142         * @param ctrl to proceed upwards
143         * @param A A in A-B
144         * @param interactionSet set to collect inferred interactions
145         */
146        private void proceedUpwards(control ctrl, physicalEntity A, InteractionSet interactionSet)
147        {
148                for (control cnt : ctrl.isCONTROLLEDOf())
149                {
150                        searchUpwards(cnt, A, interactionSet);
151                }
152        }
153
154        /**
155         * Gets supported interaction types.
156         * @return supported interaction types
157         */
158        public List<BinaryInteractionType> getRuleTypes()
159        {
160                return binaryInteractionTypes;
161        }
162}
163
164