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