|
43 | 43 |
|
44 | 44 | package org.baderlab.csplugins.enrichmentmap.actions;
|
45 | 45 |
|
46 |
| - |
47 |
| - |
48 |
| - |
49 |
| -import java.util.HashMap; |
50 | 46 | import java.util.List;
|
51 |
| -import java.util.TreeMap; |
52 |
| - |
53 |
| -import javax.swing.ListSelectionModel; |
54 |
| -import javax.swing.table.TableModel; |
55 | 47 |
|
56 | 48 | import org.baderlab.csplugins.enrichmentmap.EnrichmentMapManager;
|
57 |
| -import org.baderlab.csplugins.enrichmentmap.autoannotate.AutoAnnotationManager; |
58 |
| -import org.baderlab.csplugins.enrichmentmap.autoannotate.AutoAnnotationParameters; |
59 |
| -import org.baderlab.csplugins.enrichmentmap.autoannotate.model.AnnotationSet; |
60 |
| -import org.baderlab.csplugins.enrichmentmap.autoannotate.model.Cluster; |
61 |
| -import org.baderlab.csplugins.enrichmentmap.autoannotate.task.Observer; |
62 | 49 | import org.baderlab.csplugins.enrichmentmap.heatmap.HeatMapParameters;
|
63 | 50 | import org.baderlab.csplugins.enrichmentmap.heatmap.task.UpdateHeatMapTask;
|
64 | 51 | import org.baderlab.csplugins.enrichmentmap.model.EnrichmentMap;
|
|
75 | 62 | import org.cytoscape.model.events.RowsSetEvent;
|
76 | 63 | import org.cytoscape.model.events.RowsSetListener;
|
77 | 64 | import org.cytoscape.util.swing.FileUtil;
|
78 |
| -import org.cytoscape.view.model.CyNetworkView; |
79 | 65 | import org.cytoscape.work.SynchronousTaskManager;
|
80 | 66 | import org.cytoscape.work.TaskIterator;
|
81 | 67 |
|
82 | 68 | /**
|
83 |
| - * Created by |
84 |
| - * User: risserlin |
85 |
| - * Date: Feb 2, 2009 |
86 |
| - * Time: 1:25:36 PM |
| 69 | + * Created by User: risserlin Date: Feb 2, 2009 Time: 1:25:36 PM |
87 | 70 | * <p>
|
88 |
| - * Class listener for node and edge selections. For each enrichment map there is a separate instance of this |
89 |
| - * class specifying the enrichment map parameters, selected nodes, selected edges and heatmap panels |
| 71 | + * Class listener for node and edge selections. For each enrichment map there is |
| 72 | + * a separate instance of this class specifying the enrichment map parameters, |
| 73 | + * selected nodes, selected edges and heatmap panels |
90 | 74 | */
|
91 |
| -public class EnrichmentMapActionListener implements RowsSetListener{ |
92 |
| - |
93 |
| - private EnrichmentMap map; |
94 |
| - private HeatMapPanel edgeOverlapPanel; |
95 |
| - private HeatMapPanel nodeOverlapPanel; |
| 75 | +public class EnrichmentMapActionListener implements RowsSetListener { |
96 | 76 |
|
97 |
| - private List<CyNode> Nodes; |
98 |
| - private List<CyEdge> Edges; |
99 |
| - private CyApplicationManager applicationManager; |
100 |
| - private SynchronousTaskManager syncTaskManager; |
101 |
| - private final CytoPanel cytoPanelSouth; |
102 |
| - private FileUtil fileUtil; |
103 |
| - private StreamUtil streamUtil; |
| 77 | + private HeatMapPanel edgeOverlapPanel; |
| 78 | + private HeatMapPanel nodeOverlapPanel; |
| 79 | + private CyApplicationManager applicationManager; |
| 80 | + private SynchronousTaskManager syncTaskManager; |
| 81 | + private final CytoPanel cytoPanelSouth; |
| 82 | + private FileUtil fileUtil; |
| 83 | + private StreamUtil streamUtil; |
104 | 84 |
|
105 |
| - private boolean heatMapUpdating; |
106 |
| - |
107 | 85 |
|
108 |
| - /** |
109 |
| - * Constructor for network action listener. |
110 |
| - * |
111 |
| - * @param params - enrichment map parameters associated with this actionlistener |
112 |
| - */ |
113 |
| - public EnrichmentMapActionListener(HeatMapPanel heatMapPanel_node,HeatMapPanel heatMapPanel_edge, |
114 |
| - CyApplicationManager applicationManager,CySwingApplication application, |
115 |
| - FileUtil fileUtil, StreamUtil streamUtil,SynchronousTaskManager syncTaskManager) { |
116 |
| - |
117 |
| - this.applicationManager = applicationManager; |
118 |
| - this.fileUtil = fileUtil; |
119 |
| - this.streamUtil = streamUtil; |
120 |
| - this.syncTaskManager = syncTaskManager; |
121 |
| - this.edgeOverlapPanel = heatMapPanel_edge; |
122 |
| - this.nodeOverlapPanel = heatMapPanel_node; |
123 |
| - heatMapUpdating = false; |
124 |
| - |
125 |
| - this.cytoPanelSouth = application.getCytoPanel(CytoPanelName.SOUTH); |
| 86 | + public EnrichmentMapActionListener(HeatMapPanel heatMapPanel_node, HeatMapPanel heatMapPanel_edge, |
| 87 | + CyApplicationManager applicationManager, CySwingApplication application, FileUtil fileUtil, |
| 88 | + StreamUtil streamUtil, SynchronousTaskManager syncTaskManager) { |
126 | 89 |
|
127 |
| - |
128 |
| - } |
| 90 | + this.applicationManager = applicationManager; |
| 91 | + this.fileUtil = fileUtil; |
| 92 | + this.streamUtil = streamUtil; |
| 93 | + this.syncTaskManager = syncTaskManager; |
| 94 | + this.edgeOverlapPanel = heatMapPanel_edge; |
| 95 | + this.nodeOverlapPanel = heatMapPanel_node; |
129 | 96 |
|
130 |
| - public boolean isHeatMapUpdating() { |
131 |
| - return heatMapUpdating; |
| 97 | + this.cytoPanelSouth = application.getCytoPanel(CytoPanelName.SOUTH); |
132 | 98 | }
|
133 | 99 |
|
134 | 100 | /**
|
135 |
| - * intialize the parameters needed for this instance of the action |
136 |
| - */ |
137 |
| - private boolean initialize(CyNetwork network){ |
138 |
| - //get the static enrichment map manager. |
139 |
| - EnrichmentMapManager manager = EnrichmentMapManager.getInstance(); |
140 |
| - this.map = manager.getMap(network.getSUID()); |
141 |
| - if(map != null){ |
142 |
| - if(map.getParams().isData() && map.getParams().getHmParams() == null){ |
143 |
| - //create a heatmap parameters instance for this action listener |
144 |
| - HeatMapParameters hmParams = new HeatMapParameters(edgeOverlapPanel, nodeOverlapPanel); |
145 |
| - //If there are two distinct datasets intialize the theme and range for the heatmap coloring separately. |
146 |
| - if(map.getParams().isData2() && map.getDataset(EnrichmentMap.DATASET2).getExpressionSets() != null |
147 |
| - && !map.getDataset(EnrichmentMap.DATASET1).getExpressionSets().getFilename().equalsIgnoreCase(map.getDataset(EnrichmentMap.DATASET2).getExpressionSets().getFilename())) |
148 |
| - hmParams.initColorGradients(this.map.getDataset(EnrichmentMap.DATASET1).getExpressionSets(),this.map.getDataset(EnrichmentMap.DATASET2).getExpressionSets()); |
149 |
| - else |
150 |
| - hmParams.initColorGradients(this.map.getDataset(EnrichmentMap.DATASET1).getExpressionSets()); |
151 |
| - //associate the newly created heatmap parameters with the current enrichment map paramters |
152 |
| - this.map.getParams().setHmParams(hmParams); |
153 |
| - } |
154 |
| - |
155 |
| - this.Nodes = this.map.getParams().getSelectedNodes(); |
156 |
| - this.Edges = this.map.getParams().getSelectedEdges(); |
157 |
| - return true; |
158 |
| - } |
159 |
| - return false; |
160 |
| - } |
161 |
| - /** |
162 |
| - * Handle network action. This method handles edge or node selection or unselections. |
163 |
| - * |
164 |
| - * @param event |
165 |
| - */ |
166 |
| - public void handleEvent(RowsSetEvent e) { |
167 |
| - //TODO: improve performance of calculating the Union of genesets (Nodes) and intersection of overlaps (Edges) |
168 |
| - // Meanwhile we have a flag to skip the updating of the Heatmap, which can be toggled by a check-mark in the EM-Menu |
169 |
| - heatMapUpdating = true; |
170 |
| - |
171 |
| - boolean override_revalidate_heatmap = EnrichmentMapManager.getInstance().isOverrideHeatmapRevalidation(); |
172 |
| - |
173 |
| - //get the current network |
174 |
| - CyNetwork network = this.applicationManager.getCurrentNetwork(); |
175 |
| - CyNetworkView view = this.applicationManager.getCurrentNetworkView(); |
176 |
| - |
177 |
| - //only handle event if it is a selected node |
178 |
| - |
179 |
| - if(network != null && e != null && (e.getSource() == network.getDefaultEdgeTable() || e.getSource() == network.getDefaultNodeTable())){ |
180 |
| - if(initialize(network)){ |
181 |
| - |
182 |
| - //There is no flag to indicate that this is only an edge/node selection |
183 |
| - //After select get the nodes and the edges that were selected. |
184 |
| - if( ! override_revalidate_heatmap ) { |
185 |
| - |
186 |
| - //get the edges |
187 |
| - List<CyEdge> selectedEdges = CyTableUtil.getEdgesInState(network, CyNetwork.SELECTED, true); |
188 |
| - |
189 |
| - Edges.clear(); |
190 |
| - Edges.addAll(selectedEdges); |
191 |
| - |
192 |
| - List<CyNode> selectedNodes = CyTableUtil.getNodesInState(network, CyNetwork.SELECTED, true); |
193 |
| - |
194 |
| - Nodes.clear(); |
195 |
| - Nodes.addAll(selectedNodes); |
196 |
| - |
197 |
| - //once we have amalgamated all the nodes and edges, launch a task to update the heatmap. |
198 |
| - UpdateHeatMapTask updateHeatmap = new UpdateHeatMapTask(map, Nodes, Edges, edgeOverlapPanel, nodeOverlapPanel, cytoPanelSouth,applicationManager); |
199 |
| - Observer observer = new Observer(); |
200 |
| - syncTaskManager.execute(new TaskIterator(updateHeatmap), observer); |
201 |
| - while (!observer.isFinished()) { |
202 |
| - try { |
203 |
| - Thread.sleep(1); |
204 |
| - } catch (InterruptedException e1) { |
205 |
| - e1.printStackTrace(); |
206 |
| - } |
207 |
| - } |
208 |
| - |
209 |
| - |
210 |
| - //if the network has been autoannotated we need to make sure the clusters have been selected |
211 |
| - //also only handle the node selection events (not edges) |
212 |
| - //TODO:need a cleaner way to find out if the currentView has an annotation |
213 |
| - if(AutoAnnotationManager.getInstance().getAnnotationPanel()!=null && !AutoAnnotationManager.getInstance().isClusterTableUpdating() |
214 |
| - && e.getSource() == network.getDefaultNodeTable()){ |
215 |
| - |
216 |
| - //go through all the clusters for this network to see if any of the cluster have all of their nodes selected |
217 |
| - HashMap<CyNetworkView, AutoAnnotationParameters> annotations = AutoAnnotationManager.getInstance().getNetworkViewToAutoAnnotationParameters(); |
218 |
| - if(annotations.containsKey(view)){ |
219 |
| - AnnotationSet currentAnnotation = annotations.get(view).getSelectedAnnotationSet(); |
220 |
| - TableModel clusterTableModel = currentAnnotation.getClusterTable().getModel(); |
221 |
| - ListSelectionModel clusterListSelectionModel = currentAnnotation.getClusterTable().getSelectionModel(); |
222 |
| - |
223 |
| - //if there are clusters to add or to remove only do it once we have gone through all the clusters - to avoid race conditions. |
224 |
| - clusterListSelectionModel.setValueIsAdjusting(true); |
225 |
| - |
226 |
| - TreeMap<Integer, Cluster> clusters = currentAnnotation.getClusterMap(); |
227 |
| - //go through each cluster - figure out which ones need to be selected and |
228 |
| - //which ones need to deselected |
229 |
| - //If any nodes in a cluster are no longer selected then deselect cluster |
230 |
| - //If all nodes in a cluster are selected then select cluster (in table and annotation) |
231 |
| - for(Cluster cluster:clusters.values()){ |
232 |
| - |
233 |
| - boolean select = true; |
234 |
| - boolean unselectCluster = false; |
235 |
| - for (CyNode node : cluster.getNodes()) { |
236 |
| - //if any of the nodes that belong to this cluster are not in the selected set |
237 |
| - //And the cluster is current marked as selected |
238 |
| - //then unselect the cluster |
239 |
| - if (!selectedNodes.contains(node) && cluster.isSelected()) { |
240 |
| - unselectCluster = true; |
241 |
| - break; |
242 |
| - } |
243 |
| - //if any of the nodes that belong to this cluster are not in the selected set |
244 |
| - //then do not select this cluster. |
245 |
| - if (!selectedNodes.contains(node)) { |
246 |
| - select = false; |
247 |
| - break; |
248 |
| - } |
249 |
| - } |
250 |
| - |
251 |
| - //one last check, if the cluster is already selected and all its nodes are |
252 |
| - //already selected then this is not a new selection event |
253 |
| - if(select == true && cluster.isSelected()) |
254 |
| - select = false; |
255 |
| - |
256 |
| - //Cluster has been selected |
257 |
| - //if all nodes in a cluster are selected |
258 |
| - //update the cluster table |
259 |
| - if (select) { |
260 |
| - //set flag to tell listener that it shouldn't reselect the nodes as the user manually selected them. |
261 |
| - currentAnnotation.setManualSelection(true); |
262 |
| - for (int rowIndex = 0; rowIndex < clusterTableModel.getRowCount(); rowIndex++) { |
263 |
| - if (cluster.equals(clusterTableModel.getValueAt(rowIndex, 0))) { |
264 |
| - clusterListSelectionModel.addSelectionInterval(rowIndex, rowIndex); |
265 |
| - //AutoAnnotationManager.getInstance().flushPayloadEvents(); |
266 |
| - break; |
267 |
| - } |
268 |
| - } |
269 |
| - } |
270 |
| - |
271 |
| - //Cluster has been unselected |
272 |
| - //update the cluster table |
273 |
| - if(unselectCluster){ |
274 |
| - //set flag to tell listener that it shouldn't reselect the nodes as the user manually selected them. |
275 |
| - currentAnnotation.setManualSelection(true); |
276 |
| - for (int rowIndex = 0; rowIndex < clusterTableModel.getRowCount(); rowIndex++) { |
277 |
| - if (cluster.equals(clusterTableModel.getValueAt(rowIndex, 0))) { |
278 |
| - clusterListSelectionModel.removeSelectionInterval(rowIndex, rowIndex); |
279 |
| - //AutoAnnotationManager.getInstance().flushPayloadEvents(); |
280 |
| - break; |
281 |
| - }//end of if |
282 |
| - }//end of for |
283 |
| - |
284 |
| - }//end of if unselectedcluster |
285 |
| - |
286 |
| - }//end of For going through all clusters |
287 |
| - |
288 |
| - //if there are clusters to add or to remove only do it once we have gone through all the clusters - to avoid race conditions. |
289 |
| - clusterListSelectionModel.setValueIsAdjusting(false); |
| 101 | + * intialize the parameters needed for this instance of the action |
| 102 | + */ |
| 103 | + private EnrichmentMap getAndInitializeEnrichmentMap(CyNetwork network) { |
| 104 | + // get the static enrichment map manager. |
| 105 | + EnrichmentMapManager manager = EnrichmentMapManager.getInstance(); |
| 106 | + EnrichmentMap map = manager.getMap(network.getSUID()); |
| 107 | + if (map != null) { |
| 108 | + if (map.getParams().isData() && map.getParams().getHmParams() == null) { |
| 109 | + // create a heatmap parameters instance for this action listener |
| 110 | + HeatMapParameters hmParams = new HeatMapParameters(edgeOverlapPanel, nodeOverlapPanel); |
| 111 | + // If there are two distinct datasets intialize the theme and range for the heatmap coloring separately. |
| 112 | + if (map.getParams().isData2() && map.getDataset(EnrichmentMap.DATASET2).getExpressionSets() != null && !map.getDataset(EnrichmentMap.DATASET1).getExpressionSets().getFilename().equalsIgnoreCase(map.getDataset(EnrichmentMap.DATASET2).getExpressionSets().getFilename())) |
| 113 | + hmParams.initColorGradients(map.getDataset(EnrichmentMap.DATASET1).getExpressionSets(), map.getDataset(EnrichmentMap.DATASET2).getExpressionSets()); |
| 114 | + else |
| 115 | + hmParams.initColorGradients(map.getDataset(EnrichmentMap.DATASET1).getExpressionSets()); |
| 116 | + // associate the newly created heatmap parameters with the current enrichment map paramters |
| 117 | + map.getParams().setHmParams(hmParams); |
| 118 | + } |
| 119 | + |
| 120 | + } |
| 121 | + return map; |
| 122 | + } |
290 | 123 |
|
291 |
| - |
292 |
| - } |
293 |
| - |
294 |
| - } |
295 |
| - |
296 |
| - } |
297 |
| - } |
298 |
| - }//end of if e.getSource check |
299 |
| - heatMapUpdating = false; |
300 |
| - } |
| 124 | + /** |
| 125 | + * Handle network action. This method handles edge or node selection or unselections. |
| 126 | + */ |
| 127 | + public void handleEvent(RowsSetEvent e) { |
| 128 | + // TODO: improve performance of calculating the Union of genesets (Nodes) and intersection of overlaps (Edges) |
| 129 | + // Meanwhile we have a flag to skip the updating of the Heatmap, which can be toggled by a check-mark in the EM-Menu |
| 130 | + boolean override_revalidate_heatmap = EnrichmentMapManager.getInstance().isOverrideHeatmapRevalidation(); |
| 131 | + |
| 132 | + CyNetwork network = this.applicationManager.getCurrentNetwork(); |
| 133 | + |
| 134 | + // only handle event if it is a selected node |
| 135 | + if (network != null && e != null && (e.getSource() == network.getDefaultEdgeTable() || e.getSource() == network.getDefaultNodeTable())) { |
| 136 | + final EnrichmentMap map = getAndInitializeEnrichmentMap(network); |
| 137 | + if (map != null) { |
| 138 | + |
| 139 | + // There is no flag to indicate that this is only an edge/node selection |
| 140 | + // After select get the nodes and the edges that were selected. |
| 141 | + if (!override_revalidate_heatmap) { |
| 142 | + |
| 143 | + List<CyNode> selectedNodes = CyTableUtil.getNodesInState(network, CyNetwork.SELECTED, true); |
| 144 | + List<CyEdge> selectedEdges = CyTableUtil.getEdgesInState(network, CyNetwork.SELECTED, true); |
| 145 | + |
| 146 | + final List<CyNode> Nodes = map.getParams().getSelectedNodes(); |
| 147 | + final List<CyEdge> Edges = map.getParams().getSelectedEdges(); |
| 148 | + |
| 149 | + Nodes.clear(); |
| 150 | + Nodes.addAll(selectedNodes); |
| 151 | + |
| 152 | + Edges.clear(); |
| 153 | + Edges.addAll(selectedEdges); |
| 154 | + |
| 155 | + // Once we have amalgamated all the nodes and edges, launch a task to update the heatmap. |
| 156 | + // Start the task in a separate thread to avoid Cytoscape deadlock bug (redmine issue #3370) |
| 157 | + new Thread() { |
| 158 | + public void run() { |
| 159 | + UpdateHeatMapTask updateHeatmap = new UpdateHeatMapTask(map, Nodes, Edges, edgeOverlapPanel, nodeOverlapPanel, cytoPanelSouth, applicationManager); |
| 160 | + syncTaskManager.execute(new TaskIterator(updateHeatmap)); |
| 161 | + } |
| 162 | + }.start(); |
| 163 | + } |
| 164 | + } |
| 165 | + } // end of if e.getSource check |
| 166 | + } |
301 | 167 |
|
302 | 168 | }
|
0 commit comments