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