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 --> dependent relation</li> 032 * <li>Downwards only --> dependent relation</li> 033 * <li>Downwards then upwards --> 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