Attachment 'SimpleMetaNodeAttributesHandler.java'
Download 1 package metaNodeViewer.data;
2 //import cytoscape.data.GraphObjAttributes;
3 import cytoscape.data.*;
4 import giny.model.*;
5 import cern.colt.map.AbstractIntIntMap;
6 import cern.colt.function.IntIntProcedure;
7 import java.util.*;
8 import cytoscape.*;
9
10 /**
11 * Implementation of MetaNodesAttributesHandler that transfers the union of all
12 * attributes on the child nodes to the parent meta-nodes.
13 *
14 * <p>
15 * This is a specific implementation of MetaNodesAttributesHandler that:
16 * </p>
17 * <p>
18 * 1) Handles canonical and common naming of the new meta_node and its
19 * associated meta_edges. 2) Transfers the union of all attributes on the child
20 * nodes to the parent meta node. 3) Transfers edge attributes from each child
21 * edge to its corresponding meta edge 4) Collapses meta edges with the same
22 * name, taking the union of their attributes
23 * </p>
24 * <p>
25 * Step 4 above is invoked whenever multiple meta_edges connect from the same
26 * source or target. For instance, consider the graph: A pd B A pd C If the user
27 * collapses B and C into a meta_node, this will create corresponding
28 * meta_edges: A (pd) MetaNode1 A (pd) MetaNode1 which will have their
29 * attributes transferred and then get themselves collapsed to a single edge. Of
30 * course, this was a specific design decision on my part and I could have
31 * handled things differently. But in this case where you are collapsing many
32 * (N) nodes with the same neighbor, it seems undesirable to end up with N edges
33 * connecting this neighbor to the meta_node.
34 * </p>
35 * @author Trey Ideker trey@bioeng.ucsd.edu
36 * @author Iliana Avila iavila@systemsbiology.org
37 * @version 1.0
38 */
39
40 // TODO: method setNodeAttributes(CyNetwork cy_network,int metanode_root_index, int[] children_nodes_root_indices) has commented
41 // code that is crashing due to GraphObjAttributes. Since we think we are going to refactor/rewrite GraphObjAttrbutes, leave it
42 // as it is and fix later. iliana.
43 // TODO: internal class CopyEdgeAttr needs to be looked at. See comments. iliana.
44 // TODO: Implement removeFromAttributes() -iliana
45 // TODO: Imeplemnt removeMetaEdgesFromAttributes() -iliana
46
47 public class SimpleMetaNodeAttributesHandler implements
48 MetaNodeAttributesHandler {
49
50 /**
51 * Tracks the edge names that have been examined so far
52 */
53 protected HashSet usedEdgeNames;
54
55 /**
56 * Transfers all children names to meta node name
57 */
58 public String assignName(CyNetwork cy_net, int metanode_root_index) {
59
60 RootGraph rootGraph = cy_net.getRootGraph();
61
62 Node node = rootGraph.getNode(metanode_root_index);
63 if (node == null) {
64 return null;
65 }
66 String unique_name = getCanonicalMetaName(metanode_root_index);
67 String common_name = getCommonMetaName(metanode_root_index, cy_net);
68 Cytoscape.getNodeNetworkData().addNameMapping(unique_name, node);
69 cy_net.setNodeAttributeValue(node, Semantics.COMMON_NAME, common_name);
70 return unique_name;
71 } // end assignName
72
73 /**
74 * Simply calls separate methods for nodes then edges
75 */
76 public boolean setAttributes(CyNetwork cy_network, int metanode_root_index,
77 int[] children_nodes_root_indices,
78 AbstractIntIntMap meta_edge_to_child_edge) {
79 setNodeAttributes(cy_network, metanode_root_index,
80 children_nodes_root_indices);
81 setEdgeAttributes(cy_network, metanode_root_index,
82 meta_edge_to_child_edge);
83 return true;
84 } // end setAttributes
85
86 /**
87 * takes union of all children attributes, treating canonical and common
88 * name as special cases
89 */
90 public boolean setNodeAttributes(CyNetwork cy_network,
91 int metanode_root_index, int[] children_nodes_root_indices) {
92 RootGraph rootGraph = cy_network.getRootGraph();
93 Node metaNode = rootGraph.getNode(metanode_root_index);
94 if (metaNode == null)
95 return false;
96 String metaName = (String) cy_network.getNodeAttributeValue(metaNode,
97 Semantics.CANONICAL_NAME);
98 if (metaName == null) {
99 metaName = assignName(cy_network, metanode_root_index);
100 }
101 HashSet metaAttrs = new HashSet(); // the set of attributes for meta
102 // node
103
104 // get children Nodes instead of indices
105 Node[] childrenNodes = new Node[children_nodes_root_indices.length];
106 for (int i = 0; i < children_nodes_root_indices.length; i++) {
107 int childIndex = children_nodes_root_indices[i];
108 childrenNodes[i] = rootGraph.getNode(childIndex);
109 }//for i
110
111 // iterate over attributes of children nodes
112 String[] childrenAtts = Cytoscape.getNodeAttributesList(childrenNodes);
113 for (int i = 0; i < childrenAtts.length; i++) {
114 String attrName = childrenAtts[i];
115 if (attrName.equals(Semantics.CANONICAL_NAME)
116 || attrName.equals(Semantics.COMMON_NAME)) {
117 continue; // reserved
118 }
119
120 // iterate over children, constructing set of values for this attr
121 HashSet uniqueValues = new HashSet();
122 for (int j = 0; j < childrenNodes.length; j++) {
123 Object value = cy_network.getNodeAttributeValue(
124 childrenNodes[j], attrName);
125 if (value instanceof java.lang.reflect.Array) {
126 Object[] valueArray = (Object[]) value;
127 for (int k = 0; k < valueArray.length; k++) {
128 uniqueValues.add(valueArray[k]);
129 }
130 } else {
131 uniqueValues.add(value);
132 }
133 }// for j
134
135 // add to node attributes for meta node
136 if (attrName == null) {
137 System.out.println("attrName null");
138 }
139
140 if (metaName == null) {
141 System.out.println("metaName null");
142 }
143
144 //Object[] array = uniqueValues.toArray();
145 //for ( int i = 0; i < array.length; ++i ) {
146 //System.out.println( "uv :"+i+ " "+array[i] );
147 //}
148 //nodeAttr.set(attrName, metaName, uniqueValues.toArray());
149
150 // THIS IS THROWING AN EXCEPTION - GraphObjAttributes expects a String but it gets an Object
151 // need to solve this in GraphObjAttributes, or add a method in CyNetwork to 'append' values
152 // to an attribute:
153
154 //cy_network.setNodeAttributeValue(metaNode, attrName, uniqueValues.toArray());
155 //System.err.println("DBG " +attrName+ " " +metaName+ " "
156 // +uniqueValues);
157 }
158 return true;
159 } // end setNodeAttributes
160
161 /**
162 * Copies all edge attributes from child to meta edges
163 */
164 public boolean setEdgeAttributes(CyNetwork cy_network,
165 int metanode_root_index, AbstractIntIntMap meta_edge_to_child_edge) {
166
167 // get graph and attributes
168 RootGraph rootGraph = cy_network.getRootGraph();
169
170 // copy over edge attributes, including edge names
171 // -- also merges edges with same name
172 usedEdgeNames = new HashSet();
173 meta_edge_to_child_edge.forEachPair(new CopyEdgeAttr());
174
175 return true;
176 } // end setEdgeAttributes
177
178 public boolean removeFromAttributes(CyNetwork cy_network,
179 int metanode_root_index, int[] meta_edge_root_indices) {
180
181 return true;
182 } // end removeFromAttributes
183
184 public boolean removeMetaEdgesFromAttributes(CyNetwork cy_network,
185 int metanode_root_index, int[] meta_edge_root_indices) {
186
187 return true;
188 } // end removeMetaEdgesFromAttributes
189
190 /**
191 * Method to encapsulate the canonical naming of meta nodes and edges
192 */
193 protected String getCanonicalMetaName(int metanode_root_index) {
194 return "MetaNode_" + Integer.toString((metanode_root_index * -1));
195 }
196
197 /**
198 * @return a String with the concatenated canonical names of the children of
199 * the given meta-node
200 */
201 protected String getCommonMetaName(int metanode_root_index,
202 CyNetwork cy_network) {
203
204 RootGraph rootGraph = cy_network.getRootGraph();
205 String commonName = new String();
206 List children = rootGraph.nodeMetaChildrenList(metanode_root_index);
207 if (children == null)
208 return null;
209 int count = 0;
210 for (Iterator it = children.iterator(); it.hasNext();) {
211 count++;
212 Node child = (Node) it.next();
213 commonName += cy_network.getNodeAttributeValue(child,
214 Semantics.CANONICAL_NAME);
215 //if (it.hasNext() && (count % 3) == 0) commonName += '\n';
216 if (it.hasNext())
217 commonName += ",";
218 }
219 return commonName;
220 }
221
222 /**
223 * Procedure class to copy over edge attributes
224 */
225 protected class CopyEdgeAttr implements IntIntProcedure {
226
227 public boolean apply(int metaEdgeIndex, int childEdgeIndex) {
228 RootGraph rootGraph = Cytoscape.getRootGraph();
229 // get edge info
230 Edge metaEdge = rootGraph.getEdge(metaEdgeIndex);
231 Edge childEdge = rootGraph.getEdge(childEdgeIndex);
232 if (metaEdge == null || childEdge == null) {
233 throw new NullPointerException("metaEdge or childEdge is null");
234 }
235 String childEdgeName = (String) Cytoscape.getEdgeAttributeValue(
236 childEdge, Semantics.CANONICAL_NAME);
237 String metaEdgeName = "unknown";
238
239 // infer the metaNode and use it to name the metaEdge
240 String interaction = (String) Cytoscape.getEdgeAttributeValue(
241 childEdge, "interaction");
242 Node sourceNode = metaEdge.getSource();
243 Node targetNode = metaEdge.getTarget();
244 if (rootGraph.nodeMetaChildrenList(sourceNode) != null
245 && rootGraph.nodeMetaChildrenList(sourceNode).size() > 0) {
246 metaEdgeName = Cytoscape.getNodeAttributeValue(sourceNode,
247 Semantics.CANONICAL_NAME)
248 + " ("
249 + interaction
250 + ") "
251 + Cytoscape.getNodeAttributeValue(metaEdge.getTarget(),
252 Semantics.CANONICAL_NAME);
253 } else if (rootGraph.nodeMetaChildrenList(targetNode) != null
254 && rootGraph.nodeMetaChildrenList(targetNode).size() > 0) {
255 metaEdgeName = Cytoscape.getNodeAttributeValue(metaEdge
256 .getSource(), Semantics.CANONICAL_NAME)
257 + " ("
258 + interaction
259 + ") "
260 + Cytoscape.getNodeAttributeValue(targetNode,
261 Semantics.CANONICAL_NAME);
262 }
263 // Transfer attributes b/w edges--
264 // if edge name redundant, merge attrs with existing name and remove
265
266 if (usedEdgeNames.contains(metaEdgeName)) {
267
268 String[] allAttrNames = Cytoscape.getEdgeAttributesList();
269 for (int i = 0; i < allAttrNames.length; i++) {
270 String attrName = allAttrNames[i];
271 if (attrName.equals("metaedgesize")) // added by mrsva 2005-06-24
272 continue; // reserved // added by mrsva 2005-06-24
273 if (attrName.equals("interaction"))
274 continue; // reserved
275 if (attrName.equals(Semantics.CANONICAL_NAME))
276 continue; // reserved
277 Object childValue = Cytoscape.getEdgeAttributeValue(
278 childEdge, attrName);
279 Object metaValue = Cytoscape.getEdgeAttributeValue(
280 metaEdge, attrName);
281
282 // take union of previous and new attr values
283 HashSet uniqueValues = new HashSet();
284 if (childValue instanceof java.lang.reflect.Array) {
285 Object[] valueArray = (Object[]) childValue;
286 for (int j = 0; j < valueArray.length; j++) {
287 uniqueValues.add(valueArray[j]);
288 }
289 } else {
290 uniqueValues.add(childValue);
291 }
292 if (metaValue instanceof java.lang.reflect.Array) {
293 Object[] valueArray = (Object[]) metaValue;
294 for (int j = 0; j < valueArray.length; j++) {
295 uniqueValues.add(valueArray[j]);
296 }
297 } else {
298 uniqueValues.add(metaValue);
299 }
300 Cytoscape.setEdgeAttributeValue(metaEdge, attrName,
301 uniqueValues.toArray());
302 // NOT SURE WHY TREY DID THIS:
303 // try {
304 // edgeAttr.deleteAttribute(attrName, metaEdgeName);
305 // for (Iterator it=uniqueValues.iterator(); it.hasNext(); )
306 // {
307 // Object thisValue = it.next();
308 // String thisValue = (String) it.next();
309 // //System.err.println("Adding value: " + thisValue);
310 // edgeAttr.append(attrName, metaEdgeName, thisValue);
311 // }
312 // System.err.println("ADDED: ");
313 // System.err.println(" Attr Name " + attrName);
314 // System.err.println(" MetaEdgeName " + metaEdgeName);
315 // System.err.println(" ChildEdgeName " + childEdgeName);
316 // System.err.println(" Values " + uniqueValues);
317 // } catch (IllegalArgumentException exc) {
318 // System.err.println("Caught IllegalArgumentException:");
319 // System.err.println(" Attr Name " + attrName);
320 // System.err.println(" MetaEdgeName " + metaEdgeName);
321 // System.err.println(" ChildEdgeName " + childEdgeName);
322 // System.err.println(" Values " + uniqueValues);
323 // }
324
325 // Why do we need to do this ?
326 // remove the redundant metaEdge
327 rootGraph.removeEdge(metaEdgeIndex);
328 }
329 } else { // if meta edge not seen before, register name and lump
330 // transfer attrs
331 //System.out.println("adding name mapping : " + metaEdgeName
332 // + "-->" + metaEdge);
333 Cytoscape.getEdgeNetworkData().addNameMapping(metaEdgeName,
334 metaEdge);
335 // NOT SURE WHY I NEED THIS AS WELL:
336 //Cytoscape.setEdgeAttributeValue(metaEdge,
337 // Semantics.CANONICAL_NAME,
338 // metaEdgeName);
339
340 // THIS METHOD IS NO LONGER THERE:
341 //Edge [] edges = {childEdge};
342 //String [] attributes =
343 // Cytoscape.getEdgeAttributesList(edges);
344 String[] attributes = Cytoscape.getEdgeAttributesList();
345 for (int i = 0; i < attributes.length; i++) {
346 if (attributes[i].equals(Semantics.CANONICAL_NAME)
347 || attributes[i].equals(Semantics.COMMON_NAME)
348 || attributes[i].equals("metaedgesize")) { // added by mrsva 2005-06-24
349 continue;
350 }
351 Object value = Cytoscape.getEdgeAttributeValue(childEdge,
352 attributes[i]);
353 Cytoscape.setEdgeAttributeValue(metaEdge, attributes[i],
354 value);
355 }
356 usedEdgeNames.add(metaEdgeName);
357 //System.err.println("\nFIRST OBSERVATION-- transferring all
358 // attributes");
359 }
360
361 //System.err.println("FINISHED MetaEdge " + metaEdgeName
362 // + " to ChildEdge " + childEdgeName + "\n");
363 return true;
364 }
365 } // end CopyEdgeAttr
366
367 /**
368 * If multiple edges map to the same name, merge edges and edge attrs NOTE --
369 * CURRENTLY NOT BEING USED, FUNCTIONALITY WAS SUBSUMED BY CopyEdgeAttr
370 * class.
371 */
372 protected boolean mergeEdgesOfSameName(int[] metaEdgeArray) {
373 RootGraph rootGraph = Cytoscape.getRootGraph();
374 HashSet allEdgeNames = new HashSet();
375 for (int i = 0; i < metaEdgeArray.length; i++) {
376 int metaEdgeIndex = metaEdgeArray[i];
377 Edge metaEdge = rootGraph.getEdge(metaEdgeIndex);
378 String metaEdgeName = (String) Cytoscape.getEdgeAttributeValue(
379 metaEdge, Semantics.CANONICAL_NAME);
380 // if edge seen before, merge attrs
381 if (allEdgeNames.contains(metaEdgeName)) {
382 rootGraph.removeEdge(metaEdgeIndex);
383 } else
384 allEdgeNames.add(metaEdgeName);
385 }
386 return true;
387 } // end mergeEdgesOfSameName
388
389 } // end class
390
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.