source: orange/orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 9624:2bb996b0beed

Revision 9624:2bb996b0beed, 72.8 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 2 years ago (diff)

Moved old NetExplorer class to seperate file.

Line 
1"""
2<name>Net Explorer</name>
3<description>Orange widget for network exploration.</description>
4<icon>icons/Network.png</icon>
5<contact>Miha Stajdohar (miha.stajdohar(@at@)gmail.com)</contact> 
6<priority>6420</priorbity>
7"""
8import math
9import operator
10import statc
11import time
12
13import Orange
14import OWGUI
15import OWColorPalette
16#import OWToolbars
17import orngMDS
18
19from OWWidget import *
20from operator import itemgetter
21
22try:
23    from OWNxCanvasQt import *
24
25    class OWNxExplorer(OWWidget):
26
27        settingsList = ["autoSendSelection", "spinExplicit", "spinPercentage",
28        "maxLinkSize", "minVertexSize", "maxVertexSize", "networkCanvas.animate_plot",
29        "networkCanvas.animate_points", "networkCanvas.antialias_plot",
30        "networkCanvas.antialias_points", "networkCanvas.antialias_lines",
31        "networkCanvas.auto_adjust_performance", "invertSize", "optMethod",
32        "lastVertexSizeColumn", "lastColorColumn", "networkCanvas.show_indices", "networkCanvas.show_weights",
33        "lastNameComponentAttribute", "lastLabelColumns", "lastTooltipColumns",
34        "showWeights", "showEdgeLabels", "colorSettings",
35        "selectedSchemaIndex", "edgeColorSettings", "selectedEdgeSchemaIndex",
36        "showMissingValues", "fontSize", "mdsTorgerson", "mdsAvgLinkage",
37        "mdsSteps", "mdsRefresh", "mdsStressDelta", "organism", "showTextMiningInfo",
38        "toolbarSelection", "minComponentEdgeWidth", "maxComponentEdgeWidth",
39        "mdsFromCurrentPos", "labelsOnMarkedOnly", "tabIndex",
40        "networkCanvas.trim_label_words", "opt_from_curr", "networkCanvas.explore_distances",
41        "networkCanvas.show_component_distances", "fontWeight", "networkCanvas.state",
42        "networkCanvas.selection_behavior"]
43
44        def __init__(self, parent=None, signalManager=None, name='Net Explorer',
45                     NetworkCanvas=OWNxCanvas):
46            OWWidget.__init__(self, parent, signalManager, name, noReport=True)
47            #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="markerAttributes"), ContextField("attributes", selected="tooltipAttributes"), "color"])}
48            self.inputs = [("Network", Orange.network.Graph, self.set_graph, Default),
49                           ("Items", Orange.data.Table, self.set_items),
50                           ("Item Subset", Orange.data.Table, self.mark_items),
51                           ("Distances", Orange.core.SymMatrix, self.set_items_distance_matrix),
52                           ("Net View", Orange.network.NxView, self.set_network_view)]
53
54            self.outputs = [("Selected Network", Orange.network.Graph),
55                            ("Distance Matrix", Orange.core.SymMatrix),
56                            ("Marked Items", Orange.data.Table),
57                            ("Selected Items", Orange.data.Table),
58                            ("Other Items", Orange.data.Table)]
59                            #("Attribute Selection List", AttributeList)]
60
61            self.networkCanvas = NetworkCanvas(self, self.mainArea, "Net Explorer")
62
63            self.markerAttributes = []
64            self.tooltipAttributes = []
65            self.edgeLabelAttributes = []
66            self.attributes = []
67            self.edgeAttributes = []
68            self.autoSendSelection = False
69            self.graphShowGrid = 1  # show gridlines in the graph
70            self.markNConnections = 2
71            self.markNumber = 0
72            self.markProportion = 0
73            self.markSearchString = ""
74            self.markDistance = 2
75            self.frSteps = 1
76            self.hubs = 0
77            self.color = 0
78            self.edgeColor = 0
79            self.vertexSize = 0
80            self.nShown = self.nHidden = self.nMarked = self.nSelected = self.verticesPerEdge = self.edgesPerVertex = 0
81            self.optimizeWhat = 1
82            self.maxLinkSize = 3
83            self.maxVertexSize = 7
84            self.minVertexSize = 12
85            self.labelsOnMarkedOnly = 0
86            self.invertSize = 0
87            self.optMethod = 0
88            self.lastVertexSizeColumn = ''
89            self.lastColorColumn = ''
90            self.lastNameComponentAttribute = ''
91            self.lastLabelColumns = set()
92            self.lastTooltipColumns = set()
93            self.showWeights = 0
94            self.showEdgeLabels = 0
95            self.colorSettings = None
96            self.selectedSchemaIndex = 0
97            self.edgeColorSettings = [('net_edges', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(204, 204, 204), (179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174), (241, 226, 204)])]]), ('Default', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(0, 0, 255), (255, 0, 0), (0, 255, 0), (255, 128, 0), (255, 255, 0), (255, 0, 255), (0, 255, 255), (128, 0, 255), (0, 128, 255), (255, 223, 128), (127, 111, 64), (92, 46, 0), (0, 84, 0), (192, 192, 0), (0, 127, 127), (128, 0, 0), (127, 0, 127)])]])]
98            self.selectedEdgeSchemaIndex = 0
99            self.items_matrix = None
100            self.showDistances = 0
101            self.showMissingValues = 0
102            self.fontSize = 12
103            self.fontWeight = 1
104            self.mdsTorgerson = 0
105            self.mdsAvgLinkage = 1
106            self.mdsSteps = 10000
107            self.mdsRefresh = 50
108            self.mdsStressDelta = 0.0000001
109            self.organism = 'goa_human'
110            self.showTextMiningInfo = 0
111            self.toolbarSelection = 0
112            self.minComponentEdgeWidth = 10
113            self.maxComponentEdgeWidth = 70
114            self.mdsFromCurrentPos = 0
115            self.tabIndex = 0
116            self.number_of_nodes_label = -1
117            self.number_of_edges_label = -1
118            self.opt_from_curr = False
119
120            self.checkSendMarkedNodes = True
121            self.checkSendSelectedNodes = True
122            self.explore_distances = False
123
124            self.loadSettings()
125
126            self._network_view = None
127            self.graph = None
128            self.graph_base = None
129            self.markInputItems = None
130
131            # if optimization method is set to FragViz, set it to FR
132            if self.optMethod == 9:
133                self.optMethod = 3
134
135            self.networkCanvas.showMissingValues = self.showMissingValues
136            self.mainArea.layout().addWidget(self.networkCanvas)
137
138            self.networkCanvas.maxLinkSize = self.maxLinkSize
139
140            self.tabs = OWGUI.tabWidget(self.controlArea)
141
142            self.verticesTab = OWGUI.createTabPage(self.tabs, "Nodes")
143            self.edgesTab = OWGUI.createTabPage(self.tabs, "Edges")
144            self.markTab = OWGUI.createTabPage(self.tabs, "Mark")
145            self.infoTab = OWGUI.createTabPage(self.tabs, "Info")
146            self.performanceTab = OWGUI.createTabPage(self.tabs, "Performance")
147
148            self.tabs.setCurrentIndex(self.tabIndex)
149            self.connect(self.tabs, SIGNAL("currentChanged(int)"), lambda index: setattr(self, 'tabIndex', index))
150
151            self.optimizeBox = OWGUI.radioButtonsInBox(self.verticesTab, self, "optimizeWhat", [], "Optimize", addSpace=False)
152
153            self.optCombo = OWGUI.comboBox(self.optimizeBox, self, "optMethod", label='Method:     ', orientation='horizontal', callback=self.graph_layout_method)
154            self.optCombo.addItem("No optimization")
155            self.optCombo.addItem("Random")
156            self.optCombo.addItem("Fruchterman Reingold")
157            self.optCombo.addItem("Fruchterman Reingold Weighted")
158            self.optCombo.addItem("Fruchterman Reingold Radial")
159            self.optCombo.addItem("Circular Crossing Reduction")
160            self.optCombo.addItem("Circular Original")
161            self.optCombo.addItem("Circular Random")
162            self.optCombo.addItem("FragViz")
163            self.optCombo.addItem("MDS")
164            self.optCombo.addItem("Pivot MDS")
165            self.optCombo.setCurrentIndex(self.optMethod)
166            self.stepsSpin = OWGUI.spin(self.optimizeBox, self, "frSteps", 1, 100000, 1, label="Iterations: ")
167            self.cb_opt_from_curr = OWGUI.checkBox(self.optimizeBox, self, "opt_from_curr", label="Optimize from current positions")
168            self.cb_opt_from_curr.setEnabled(False)
169            self.stepsSpin.setEnabled(False)
170
171            self.optButton = OWGUI.button(self.optimizeBox, self, "Optimize layout", callback=self.graph_layout, toggleButton=1)
172
173            colorBox = OWGUI.widgetBox(self.verticesTab, "Node color attribute", orientation="horizontal", addSpace=False)
174            self.colorCombo = OWGUI.comboBox(colorBox, self, "color", callback=self.set_node_colors)
175            self.colorCombo.addItem("(same color)")
176            OWGUI.button(colorBox, self, "palette", self._set_colors, tooltip="Set node color palette", width=60, debuggingEnabled=0)
177
178            ib = OWGUI.widgetBox(self.verticesTab, "Node size attribute", orientation="vertical", addSpace=False)
179            hb = OWGUI.widgetBox(ib, orientation="horizontal", addSpace=False)
180            OWGUI.checkBox(hb, self, "invertSize", "Invert size", callback=self.set_node_sizes)
181            OWGUI.spin(hb, self, "minVertexSize", 5, 200, 1, label="Min:", callback=self.set_node_sizes)
182            OWGUI.spin(hb, self, "maxVertexSize", 5, 200, 1, label="Max:", callback=self.set_node_sizes)
183            self.vertexSizeCombo = OWGUI.comboBox(ib, self, "vertexSize", callback=self.set_node_sizes)
184            self.vertexSizeCombo.addItem("(none)")
185
186            self.attBox = OWGUI.widgetBox(self.verticesTab, "Node labels | tooltips", orientation="vertical", addSpace=False)
187            hb = OWGUI.widgetBox(self.attBox, orientation="horizontal", addSpace=False)
188            self.attListBox = OWGUI.listBox(hb, self, "markerAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_att_lstbox)
189            self.tooltipListBox = OWGUI.listBox(hb, self, "tooltipAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_tooltip_lstbox)
190            OWGUI.spin(self.attBox, self, "networkCanvas.trim_label_words", 0, 5, 1, label='Trim label words to', callback=self._clicked_att_lstbox)
191
192            ib = OWGUI.widgetBox(self.edgesTab, "General", orientation="vertical")
193            OWGUI.checkBox(ib, self, 'networkCanvas.show_weights', 'Show weights', callback=self.networkCanvas.set_edge_labels)
194            #OWGUI.checkBox(ib, self, 'showEdgeLabels', 'Show labels on edges', callback=(lambda: self._set_canvas_attr('showEdgeLabels', self.showEdgeLabels)))
195            OWGUI.spin(ib, self, "maxLinkSize", 1, 50, 1, label="Max edge width:", callback=self.set_edge_sizes)
196            self.cb_show_distances = OWGUI.checkBox(ib, self, 'explore_distances', 'Explore node distances', callback=self.set_explore_distances, disabled=1)
197            self.cb_show_component_distances = OWGUI.checkBox(ib, self, 'networkCanvas.show_component_distances', 'Show component distances', callback=self.networkCanvas.set_show_component_distances, disabled=1)
198
199            colorBox = OWGUI.widgetBox(self.edgesTab, "Edge color attribute", orientation="horizontal", addSpace=False)
200            self.edgeColorCombo = OWGUI.comboBox(colorBox, self, "edgeColor", callback=self.set_edge_colors)
201            self.edgeColorCombo.addItem("(same color)")
202            OWGUI.button(colorBox, self, "palette", self._set_edge_color_palette, tooltip="Set edge color palette", width=60, debuggingEnabled=0)
203
204            self.edgeLabelBox = OWGUI.widgetBox(self.edgesTab, "Edge labels", addSpace=False)
205            self.edgeLabelListBox = OWGUI.listBox(self.edgeLabelBox, self, "edgeLabelAttributes", "edgeAttributes", selectionMode=QListWidget.MultiSelection, callback=self._clicked_edge_label_listbox)
206            #self.edgeLabelBox.setEnabled(False)
207
208            ib = OWGUI.widgetBox(self.verticesTab, "General", orientation="vertical")
209            OWGUI.checkBox(ib, self, 'networkCanvas.show_indices', 'Show indices', callback=self.networkCanvas.set_node_labels)
210            OWGUI.checkBox(ib, self, 'labelsOnMarkedOnly', 'Show labels on marked nodes only', callback=(lambda: self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)))
211            OWGUI.spin(ib, self, "fontSize", 4, 30, 1, label="Font size:", callback=self.set_font)
212            self.comboFontWeight = OWGUI.comboBox(ib, self, "fontWeight", label='Font weight:', orientation='horizontal', callback=self.set_font)
213            self.comboFontWeight.addItem("Normal")
214            self.comboFontWeight.addItem("Bold")
215            self.comboFontWeight.setCurrentIndex(self.fontWeight)
216
217            ib = OWGUI.widgetBox(self.markTab, "Info", orientation="vertical")
218            OWGUI.label(ib, self, "Nodes (shown/hidden): %(number_of_nodes_label)i (%(nShown)i/%(nHidden)i)")
219            OWGUI.label(ib, self, "Selected: %(nSelected)i, marked: %(nMarked)i")
220
221            ribg = OWGUI.radioButtonsInBox(self.markTab, self, "hubs", [], "Mark", callback=self.set_mark_mode)
222            OWGUI.appendRadioButton(ribg, self, "hubs", "None", callback=self.set_mark_mode)
223            OWGUI.appendRadioButton(ribg, self, "hubs", "Search", callback=self.set_mark_mode)
224            self.ctrlMarkSearchString = OWGUI.lineEdit(OWGUI.indentedBox(ribg), self, "markSearchString", callback=self._set_search_string_timer, callbackOnType=True)
225            self.searchStringTimer = QTimer(self)
226            self.connect(self.searchStringTimer, SIGNAL("timeout()"), self.set_mark_mode)
227
228            OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbors of focused", callback=self.set_mark_mode)
229            OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbours of selected", callback=self.set_mark_mode)
230            ib = OWGUI.indentedBox(ribg, orientation=0)
231            self.ctrlMarkDistance = OWGUI.spin(ib, self, "markDistance", 0, 100, 1, label="Distance ", callback=(lambda h=2: self.set_mark_mode(h)))
232            #self.ctrlMarkFreeze = OWGUI.button(ib, self, "&Freeze", value="graph.freezeNeighbours", toggleButton = True)
233            OWGUI.widgetLabel(ribg, "Mark nodes with ...")
234            OWGUI.appendRadioButton(ribg, self, "hubs", "at least N connections", callback=self.set_mark_mode)
235            OWGUI.appendRadioButton(ribg, self, "hubs", "at most N connections", callback=self.set_mark_mode)
236            self.ctrlMarkNConnections = OWGUI.spin(OWGUI.indentedBox(ribg), self, "markNConnections", 0, 1000000, 1, label="N ", callback=(lambda h=4: self.set_mark_mode(h)))
237            OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than any neighbour", callback=self.set_mark_mode)
238            OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than avg neighbour", callback=self.set_mark_mode)
239            OWGUI.appendRadioButton(ribg, self, "hubs", "most connections", callback=self.set_mark_mode)
240            ib = OWGUI.indentedBox(ribg)
241            self.ctrlMarkNumber = OWGUI.spin(ib, self, "markNumber", 0, 1000000, 1, label="Number of nodes:", callback=(lambda h=8: self.set_mark_mode(h)))
242            OWGUI.widgetLabel(ib, "(More nodes are marked in case of ties)")
243            self.markInputRadioButton = OWGUI.appendRadioButton(ribg, self, "hubs", "Mark nodes given in the input signal", callback=self.set_mark_mode)
244            ib = OWGUI.indentedBox(ribg)
245            self.markInput = 0
246            self.markInputCombo = OWGUI.comboBox(ib, self, "markInput", callback=(lambda h=9: self.set_mark_mode(h)))
247            self.markInputRadioButton.setEnabled(False)
248
249            #ib = OWGUI.widgetBox(self.markTab, "General", orientation="vertical")
250            #self.checkSendMarkedNodes = True
251            #OWGUI.checkBox(ib, self, 'checkSendMarkedNodes', 'Send marked nodes', callback = self.send_marked_nodes, disabled=0)
252
253            self.toolbar = OWGUI.widgetBox(self.controlArea, orientation='horizontal')
254            prevstate = self.networkCanvas.state
255            prevselbeh = self.networkCanvas.selection_behavior
256            G = self.networkCanvas.gui
257            self.zoomSelectToolbar = G.zoom_select_toolbar(self.toolbar, nomargin=True, buttons=
258                G.default_zoom_select_buttons +
259                [
260                    G.Spacing,
261                    ("buttonM2S", "Marked to selection", None, None, "marked_to_selected", 'Dlg_Mark2Sel'),
262                    ("buttonS2M", "Selection to marked", None, None, "selected_to_marked", 'Dlg_Sel2Mark'),
263                    ("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection'),
264                    ("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection'),
265                    #("buttonUN", "Hide unselected", None, None, "hideUnSelectedVertices", 'Dlg_SelectedNodes'),
266                    #("buttonSW", "Show all nodes", None, None, "showAllVertices", 'Dlg_clear'),
267                ])
268            self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_data)
269            self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_marked_nodes)
270            self.zoomSelectToolbar.buttons[("buttonHSEL", "Hide selection", None, None, "hide_selection", 'Dlg_HideSelection')].clicked.connect(self.hide_selection)
271            self.zoomSelectToolbar.buttons[("buttonSSEL", "Show all nodes", None, None, "show_selection", 'Dlg_ShowSelection')].clicked.connect(self.show_selection)
272            #self.zoomSelectToolbar.buttons[G.SendSelection].hide()
273            self.zoomSelectToolbar.select_selection_behaviour(prevselbeh)
274            self.zoomSelectToolbar.select_state(prevstate)
275
276            ib = OWGUI.widgetBox(self.infoTab, "General")
277            OWGUI.label(ib, self, "Number of nodes: %(number_of_nodes_label)i")
278            OWGUI.label(ib, self, "Number of edges: %(number_of_edges_label)i")
279            OWGUI.label(ib, self, "Nodes per edge: %(verticesPerEdge).2f")
280            OWGUI.label(ib, self, "Edges per node: %(edgesPerVertex).2f")
281
282            ib = OWGUI.widgetBox(self.infoTab, orientation="horizontal")
283
284            OWGUI.button(ib, self, "Save net", callback=self.save_network, debuggingEnabled=False)
285            OWGUI.button(ib, self, "Save img", callback=self.networkCanvas.saveToFile, debuggingEnabled=False)
286            self.reportButton = OWGUI.button(ib, self, "&Report", self.reportAndFinish, debuggingEnabled=0)
287            self.reportButton.setAutoDefault(0)
288
289            #OWGUI.button(self.edgesTab, self, "Clustering", callback=self.clustering)
290            ib = OWGUI.widgetBox(self.infoTab, "Edit")
291            self.editAttribute = 0
292            self.editCombo = OWGUI.comboBox(ib, self, "editAttribute", label="Edit attribute:", orientation="horizontal")
293            self.editCombo.addItem("Select attribute")
294            self.editValue = ''
295            hb = OWGUI.widgetBox(ib, orientation="horizontal")
296            OWGUI.lineEdit(hb, self, "editValue", "Value:", orientation='horizontal')
297            OWGUI.button(hb, self, "Set", callback=self.edit)
298
299            ib = OWGUI.widgetBox(self.infoTab, "Prototype")
300            ib.setVisible(True)
301
302            OWGUI.lineEdit(ib, self, "organism", "Organism:", orientation='horizontal')
303
304            self.nameComponentAttribute = 0
305            self.nameComponentCombo = OWGUI.comboBox(ib, self, "nameComponentAttribute", callback=self.nameComponents, label="Name components:", orientation="horizontal")
306            self.nameComponentCombo.addItem("Select attribute")
307
308            self.showComponentAttribute = 0
309            self.showComponentCombo = OWGUI.comboBox(ib, self, "showComponentAttribute", callback=self.showComponents, label="Labels on components:", orientation="horizontal")
310            self.showComponentCombo.addItem("Select attribute")
311            OWGUI.checkBox(ib, self, 'showTextMiningInfo', "Show text mining info")
312
313            #OWGUI.spin(ib, self, "rotateSteps", 1, 10000, 1, label="Rotate max steps: ")
314            OWGUI.spin(ib, self, "minComponentEdgeWidth", 0, 100, 1, label="Min component edge width: ", callback=(lambda changedMin=1: self.set_component_edge_width(changedMin)))
315            OWGUI.spin(ib, self, "maxComponentEdgeWidth", 0, 200, 1, label="Max component edge width: ", callback=(lambda changedMin=0: self.set_component_edge_width(changedMin)))
316
317            self.attSelectionAttribute = 0
318            self.comboAttSelection = OWGUI.comboBox(ib, self, "attSelectionAttribute", label='Send attribute selection list:', orientation='horizontal', callback=self.sendAttSelectionList)
319            self.comboAttSelection.addItem("Select attribute")
320            self.autoSendAttributes = 0
321            OWGUI.checkBox(ib, self, 'autoSendAttributes', "auto send attributes", callback=self.setAutoSendAttributes)
322
323            self.icons = self.createAttributeIconDict()
324            self.set_mark_mode()
325
326            self.networkCanvas.gui.effects_box(self.performanceTab)
327
328            self.verticesTab.layout().addStretch(1)
329            self.edgesTab.layout().addStretch(1)
330            self.markTab.layout().addStretch(1)
331            self.infoTab.layout().addStretch(1)
332            self.performanceTab.layout().addStretch(1)
333
334            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
335            self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
336            self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
337
338            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
339            self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
340            self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
341
342            self.graph_layout_method()
343            self.set_font()
344            self.set_graph(None)
345
346            self.setMinimumWidth(900)
347
348            self.connect(self.networkCanvas, SIGNAL("marked_points_changed()"), self.send_marked_nodes)
349            self.connect(self.networkCanvas, SIGNAL("selection_changed()"), self.send_data)
350
351        def hide_selection(self):
352            nodes = set(self.graph.nodes()).difference(self.networkCanvas.selected_nodes())
353            self.change_graph(Orange.network.nx.Graph.subgraph(self.graph, nodes))
354
355        def show_selection(self):
356            self.change_graph(self.graph_base)
357
358        def edit(self):
359            if self.graph is None:
360                return
361
362            vars = [x.name for x in self.graph_base.items_vars()]
363            if not self.editCombo.currentText() in vars:
364                return
365            att = str(self.editCombo.currentText())
366            vertices = self.networkCanvas.selected_nodes()
367
368            if len(vertices) == 0:
369                return
370
371            items = self.graph_base.items()
372            if items.domain[att].var_type == Orange.data.Type.Continuous:
373                for v in vertices:
374                    items[v][att] = float(self.editValue)
375            else:
376                for v in vertices:
377                    items[v][att] = str(self.editValue)
378
379        def set_items_distance_matrix(self, matrix):
380            self.error()
381            self.warning()
382            self.information()
383
384            self.cb_show_distances.setEnabled(0)
385            self.cb_show_component_distances.setEnabled(0)
386
387            if matrix is None or self.graph_base is None:
388                self.items_matrix = None
389                self.networkCanvas.items_matrix = None
390                self.information('No graph found!')
391                return
392
393            if matrix.dim != self.graph_base.number_of_nodes():
394                self.error('The number of vertices does not match matrix size.')
395                self.items_matrix = None
396                self.networkCanvas.items_matrix = None
397                return
398
399            self.items_matrix = matrix
400            self.networkCanvas.items_matrix = matrix
401            self.cb_show_distances.setEnabled(1)
402            self.cb_show_component_distances.setEnabled(1)
403
404            if str(self.optMethod) in ['8', '9', '10']:
405                if self.items_matrix is not None and self.graph is not None and \
406                self.items_matrix.dim == self.graph.number_of_nodes():
407                    self.optButton.setEnabled(True)
408                    self.optButton.setChecked(True)
409                    self.graph_layout()
410
411        def _set_canvas_attr(self, attr, value):
412            setattr(self.networkCanvas, attr, value)
413            self.networkCanvas.updateCanvas()
414
415        def _set_curve_attr(self, attr, value):
416            setattr(self.networkCanvas.networkCurve, attr, value)
417            self.networkCanvas.updateCanvas()
418
419        def _set_search_string_timer(self):
420            self.hubs = 1
421            self.searchStringTimer.stop()
422            self.searchStringTimer.start(1000)
423
424        def set_mark_mode(self, i=None):
425            self.searchStringTimer.stop()
426            if not i is None:
427                self.hubs = i
428
429            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
430            QObject.disconnect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
431
432            if self.graph is None:
433                return
434
435            hubs = self.hubs
436
437            if hubs in [0, 1, 2, 3]:
438                if hubs == 0:
439                    self.networkCanvas.networkCurve.clear_node_marks()
440                elif hubs == 1:
441                    #print "mark on given label"
442                    txt = self.markSearchString
443
444                    toMark = set(i for i, values in enumerate(self.graph_base.items()) if txt.lower() in " ".join([str(values[ndx]).decode("ascii", "ignore").lower() for ndx in range(len(self.graph_base.items().domain)) + self.graph_base.items().domain.getmetas().keys()]))
445                    toMark = toMark.intersection(self.graph.nodes())
446                    self.networkCanvas.networkCurve.clear_node_marks()
447                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for i in toMark))
448                elif hubs == 2:
449                    #print "mark on focus"
450                    self.networkCanvas.mark_neighbors = self.markDistance
451                    QObject.connect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
452                elif hubs == 3:
453                    #print "mark selected"
454                    self.networkCanvas.mark_neighbors = self.markDistance
455                    QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
456                    self.networkCanvas.mark_on_selection_changed()
457
458            elif hubs in [4, 5, 6, 7, 8, 9]:
459
460                powers = sorted(self.graph.degree_iter(), key=itemgetter(1), reverse=True)
461
462                if hubs == 4:
463                    #print "mark at least N connections"
464                    N = self.markNConnections
465                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
466                        d >= N else (i, False) for i, d in powers))
467                elif hubs == 5:
468                    #print "mark at most N connections"
469                    N = self.markNConnections
470                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
471                        d <= N else (i, False) for i, d in powers))
472                elif hubs == 6:
473                    #print "mark more than any"
474                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
475                        d > max([0] + self.graph.degree(self.graph.neighbors(i)).values()) \
476                        else (i, False) for i, d in powers))
477                elif hubs == 7:
478                    #print "mark more than avg"
479                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
480                        d > statc.mean([0] + self.graph.degree(self.graph.neighbors(i)).values()) \
481                        else (i, False) for i, d in powers))
482                    self.networkCanvas.replot()
483                elif hubs == 8:
484                    #print "mark most"
485                    self.networkCanvas.networkCurve.clear_node_marks()
486
487                    if self.markNumber < 1:
488                        return
489
490                    cut = self.markNumber
491                    cutPower = powers[cut - 1][1]
492                    while cut < len(powers) and powers[cut][1] == cutPower:
493                        cut += 1
494
495                    self.networkCanvas.networkCurve.clear_node_marks()
496                    self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for \
497                        i, d in powers[:cut]))
498
499                elif hubs == 9:
500                    var = str(self.markInputCombo.currentText())
501                    if self.markInputItems is not None and len(self.markInputItems) > 0:
502                        if var == 'ID':
503                            values = [x.id for x in self.markInputItems]
504                            tomark = dict((x, True) for x in self.graph.nodes() if self.graph_base.items()[x].id in values)
505                        else:
506                            values = [str(x[var]).strip().upper() for x in self.markInputItems]
507                            tomark = dict((x, True) for x in self.graph.nodes() if str(self.graph_base.items()[x][var]).strip().upper() in values)
508                        self.networkCanvas.networkCurve.clear_node_marks()
509                        self.networkCanvas.networkCurve.set_node_marks(tomark)
510
511                    else:
512                        self.networkCanvas.networkCurve.clear_node_marks()
513
514            self.nMarked = len(self.networkCanvas.marked_nodes())
515
516        def save_network(self):
517    #        if self.networkCanvas is None or self.graph is None:
518    #            return
519    #       
520    #        filename = QFileDialog.getSaveFileName(self, 'Save Network File', '', 'NetworkX graph as Python pickle (*.gpickle)\nPajek network (*.net)\nGML network (*.gml)')
521    #        if filename:
522    #            fn = ""
523    #            head, tail = os.path.splitext(str(filename))
524    #            if not tail:
525    #                fn = head + ".net"
526    #            else:
527    #                fn = str(filename)
528    #           
529    #            for i in range(self.graph.number_of_nodes()):
530    #                node = self.graph.node[i]
531    #                node['x'] = self.layout.coors[0][i]
532    #                node['y'] = self.layout.coors[1][i]
533    #
534    #            Orange.network.readwrite.write(self.graph, fn)
535            pass
536
537        def send_data(self):
538            if len(self.signalManager.getLinks(self, None, \
539                "Selected Items", None)) > 0 or \
540                    len(self.signalManager.getLinks(self, None, \
541                        "Unselected Items", None)) > 0 or \
542                            len(self.signalManager.getLinks(self, None, \
543                                "Selected Network", None)) > 0:
544
545                # signal connected
546                selected_nodes = self.networkCanvas.selected_nodes()
547                graph = self.graph_base.subgraph(selected_nodes)
548
549                if graph is not None:
550                    self.send("Selected Items", graph.items())
551
552                    if len(self.signalManager.getLinks(self, None, \
553                                                "Unselected Items", None)) > 0:
554                        nodes = self.networkCanvas.not_selected_nodes()
555                        if len(nodes) > 0 and self.graph_base.items() is not None:
556                            self.send("Other Items", self.graph_base.items().getitems(nodes))
557                        else:
558                            self.send("Other Items", None)
559
560                    self.send("Selected Network", graph)
561                else:
562                    self.send("Selected Items", None)
563                    self.send("Other Items", None)
564                    self.send("Selected Network", None)
565
566            if len(self.signalManager.getLinks(self, None, \
567                                "Selected Items Distance Matrix", None)) > 0:
568                # signal connected
569                matrix = None if self.items_matrix is None else self.items_matrix.getitems(selected_nodes)
570                self.send("Distance Matrix", matrix)
571
572        def send_marked_nodes(self):
573            if self.checkSendMarkedNodes and \
574                len(self.signalManager.getLinks(self, None, \
575                                                "Marked Items", None)) > 0:
576                # signal connected
577                markedNodes = self.networkCanvas.marked_nodes()
578
579                if len(markedNodes) > 0 and self.graph is not None and\
580                                         self.graph_base.items() is not None:
581
582                    items = self.graph_base.items().getitems(markedNodes)
583                    self.send("Marked Items", items)
584                else:
585                    self.send("Marked Items", None)
586
587        def _set_combos(self):
588            vars = self.graph_base.items_vars()
589            edgeVars = self.graph_base.links_vars()
590            lastLabelColumns = self.lastLabelColumns
591            lastTooltipColumns = self.lastTooltipColumns
592
593            self._clear_combos()
594
595            self.attributes = [(var.name, var.varType) for var in vars]
596            self.edgeAttributes = [(var.name, var.varType) for var in edgeVars]
597
598            for var in vars:
599                if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
600                    self.colorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
601
602                if var.varType in [Orange.data.Type.String] and hasattr(self.graph, 'items') and self.graph_base.items() is not None and len(self.graph_base.items()) > 0:
603
604                    value = self.graph_base.items()[0][var].value
605
606                    # can value be a list?
607                    try:
608                        if type(eval(value)) == type([]):
609                            self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
610                            continue
611                    except:
612                        pass
613
614                    if len(value.split(',')) > 1:
615                        self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), "num of " + unicode(var.name))
616
617                elif var.varType in [Orange.data.Type.Continuous]:
618                    self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
619
620                self.nameComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
621                self.showComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
622                self.editCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
623                self.comboAttSelection.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
624
625            for var in edgeVars:
626                if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
627                    self.edgeColorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
628
629            for i in range(self.vertexSizeCombo.count()):
630                if self.lastVertexSizeColumn == self.vertexSizeCombo.itemText(i):
631                    self.vertexSize = i
632                    break
633
634            for i in range(self.colorCombo.count()):
635                if self.lastColorColumn == self.colorCombo.itemText(i):
636                    self.color = i
637                    break
638
639            for i in range(self.attListBox.count()):
640                if str(self.attListBox.item(i).text()) in lastLabelColumns:
641                    self.attListBox.item(i).setSelected(1)
642
643            for i in range(self.tooltipListBox.count()):
644                if str(self.tooltipListBox.item(i).text()) in lastTooltipColumns:
645                    self.tooltipListBox.item(i).setSelected(1)
646
647            self.lastLabelColumns = lastLabelColumns
648            self.lastTooltipColumns = lastTooltipColumns
649
650        def _clear_combos(self):
651            self.attributes = []
652            self.edgeAttributes = []
653
654            self.colorCombo.clear()
655            self.vertexSizeCombo.clear()
656            self.nameComponentCombo.clear()
657            self.showComponentCombo.clear()
658            self.edgeColorCombo.clear()
659            self.editCombo.clear()
660            self.comboAttSelection.clear()
661
662            self.colorCombo.addItem("(same color)")
663            self.edgeColorCombo.addItem("(same color)")
664            self.vertexSizeCombo.addItem("(same size)")
665            self.nameComponentCombo.addItem("Select attribute")
666            self.showComponentCombo.addItem("Select attribute")
667            self.editCombo.addItem("Select attribute")
668            self.comboAttSelection.addItem("Select attribute")
669
670        def compute_network_info(self):
671            self.nShown = self.graph.number_of_nodes()
672
673            if self.graph.number_of_edges() > 0:
674                self.verticesPerEdge = float(self.graph.number_of_nodes()) / float(self.graph.number_of_edges())
675            else:
676                self.verticesPerEdge = 0
677
678            if self.graph.number_of_nodes() > 0:
679                self.edgesPerVertex = float(self.graph.number_of_edges()) / float(self.graph.number_of_nodes())
680            else:
681                self.edgesPerVertex = 0
682
683        def change_graph(self, newgraph):
684            self.information()
685
686            # if graph has more nodes and edges than pixels in 1600x1200 display,
687            # it is too big to visualize!
688            if newgraph.number_of_nodes() + newgraph.number_of_edges() > 50000:
689                self.information('New graph is too big to visualize. Keeping the old graph.')
690                return
691
692            self.graph = newgraph
693
694            self.number_of_nodes_label = self.graph.number_of_nodes()
695            self.number_of_edges_label = self.graph.number_of_edges()
696
697            if not self.networkCanvas.change_graph(self.graph):
698                return
699
700            self.compute_network_info()
701
702            if self.graph.number_of_nodes() > 0:
703                t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
704                self.frSteps = int(2.0 / t)
705                if self.frSteps < 1: self.frSteps = 1
706                if self.frSteps > 100: self.frSteps = 100
707    #       
708    #        if self.frSteps < 10:
709    #            self.networkCanvas.use_antialiasing = 0
710    #            self.networkCanvas.use_animations = 0
711    #            self.minVertexSize = 5
712    #            self.maxVertexSize = 5
713    #            self.maxLinkSize = 1
714    #            self.optMethod = 0
715    #            self.graph_layout_method()
716
717            animation_enabled = self.networkCanvas.animate_points;
718            self.networkCanvas.animate_points = False;
719
720            self.set_node_sizes()
721            self.set_node_colors()
722            self.set_edge_sizes()
723            self.set_edge_colors()
724
725            self._clicked_att_lstbox()
726            self._clicked_tooltip_lstbox()
727            self._clicked_edge_label_listbox()
728
729            self.networkCanvas.replot()
730
731            self.networkCanvas.animate_points = animation_enabled
732            qApp.processEvents()
733            self.networkCanvas.networkCurve.layout_fr(100, weighted=False, smooth_cooling=True)
734            self.networkCanvas.update_canvas()
735
736        def set_graph_none(self):
737            self.graph = None
738            #self.graph_base = None
739            self._clear_combos()
740            self.number_of_nodes_label = -1
741            self.number_of_edges_label = -1
742            self._items = None
743            self._links = None
744            self.set_items_distance_matrix(None)
745            self.networkCanvas.set_graph(None)
746
747        def set_graph(self, graph, curve=None):
748            self.information()
749            self.warning()
750            self.error()
751
752            if graph is None:
753                self.set_graph_none()
754                return
755
756            if graph.number_of_nodes() < 2:
757                self.set_graph_none()
758                self.information('I\'m not really in a mood to visualize just one node. Try again tomorrow.')
759                return
760
761            if graph == self.graph_base and self.graph is not None and self._network_view is None:
762                self.set_items(graph.items())
763                return
764
765            self.graph_base = graph
766
767            if self._network_view is not None:
768                graph = self._network_view.init_network(graph)
769
770            self.graph = graph
771
772            # if graph has more nodes and edges than pixels in 1600x1200 display,
773            # it is too big to visualize!
774            if self.graph.number_of_nodes() + self.graph.number_of_edges() > 50000:
775                self.set_graph_none()
776                self.error('Graph is too big to visualize. Try using one of the network views.')
777                return
778
779            if self.items_matrix is not None and self.items_matrix.dim != self.graph_base.number_of_nodes():
780                self.set_items_distance_matrix(None)
781
782            self.number_of_nodes_label = self.graph.number_of_nodes()
783            self.number_of_edges_label = self.graph.number_of_edges()
784
785            self.networkCanvas.set_graph(self.graph, curve, items=self.graph_base.items(), links=self.graph_base.links())
786
787            if self._items is not None and 'x' in self._items.domain and 'y' in self._items.domain:
788                positions = dict((node, (self._items[node]['x'].value, self._items[node]['y'].value)) \
789                             for node in self.graph if self._items[node]['x'].value != '?' \
790                             and self._items[node]['y'].value != '?')
791
792                self.networkCanvas.networkCurve.set_node_coordinates(positions)
793
794
795            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
796            self.networkCanvas.maxEdgeSize = self.maxLinkSize
797            self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
798            self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
799            self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)
800
801            self.compute_network_info()
802            self._set_combos()
803
804            lastNameComponentAttributeFound = False
805            for i in range(self.nameComponentCombo.count()):
806                if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
807                    lastNameComponentAttributeFound = True
808                    self.nameComponentAttribute = i
809                    self.nameComponents()
810                    self.showComponentAttribute = self.showComponentCombo.count() - 1
811                    self.showComponents()
812                    break
813
814            if not lastNameComponentAttributeFound:
815                self.lastNameComponentAttribute = ''
816
817            self.showComponentAttribute = None
818
819            t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
820            self.frSteps = int(2.0 / t)
821            if self.frSteps < 1: self.frSteps = 1
822            if self.frSteps > 100: self.frSteps = 100
823
824            # if graph is large, set random layout, min vertex size, min edge size
825            if self.frSteps < 10:
826                self.networkCanvas.update_antialiasing(False)
827                self.networkCanvas.update_animations(False)
828                self.minVertexSize = 5
829                self.maxVertexSize = 5
830                self.maxLinkSize = 1
831                self.optMethod = 0
832                self.graph_layout_method()
833
834            self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
835            self.networkCanvas.showWeights = self.showWeights
836
837            self.set_node_sizes()
838            self.set_node_colors()
839            self.set_edge_sizes()
840            self.set_edge_colors()
841
842            self._clicked_att_lstbox()
843            self._clicked_tooltip_lstbox()
844            self._clicked_edge_label_listbox()
845
846            self.optButton.setChecked(1)
847            self.graph_layout()
848
849        def set_network_view(self, nxView):
850            self.error()
851            self.warning()
852            self.information()
853
854            if self.graph is None:
855                self.information('Do not forget to add a graph!')
856
857            if self._network_view is not None:
858                QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
859
860            self._network_view = nxView
861
862            if self._network_view is not None:
863                self._network_view.set_nx_explorer(self)
864
865            self.set_graph(self.graph_base)
866
867            if self._network_view is not None:
868                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
869
870        def set_items(self, items=None):
871            self.error()
872            self.warning()
873            self.information()
874
875            if items is None:
876                return
877
878            if self.graph is None:
879                self.warning('No graph found!')
880                return
881
882            if len(items) != self.graph_base.number_of_nodes():
883                self.error('ExampleTable items must have one example for each vertex.')
884                return
885
886            self.graph_base.set_items(items)
887
888            self.set_node_sizes()
889            self.networkCanvas.items = items
890            self.networkCanvas.showWeights = self.showWeights
891            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
892            self._set_combos()
893            #self.networkCanvas.updateData()
894
895        def mark_items(self, items):
896            self.markInputCombo.clear()
897            self.markInputRadioButton.setEnabled(False)
898            self.markInputItems = items
899
900            self.error()
901            self.warning()
902            self.information()
903
904            if items is None:
905                return
906
907            if self.graph is None or self.graph_base.items() is None or items is None:
908                self.warning('No graph found or no items attached to the graph.')
909                return
910
911            if len(items) > 0:
912                lstOrgDomain = [x.name for x in self.graph_base.items().domain] + [self.graph_base.items().domain[x].name for x in self.graph_base.items().domain.getmetas()]
913                lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
914                commonVars = set(lstNewDomain) & set(lstOrgDomain)
915
916                self.markInputCombo.addItem(self.icons[Orange.data.Type.Discrete], unicode("ID"))
917
918                if len(commonVars) > 0:
919                    for var in commonVars:
920                        orgVar = self.graph_base.items().domain[var]
921                        mrkVar = items.domain[var]
922
923                        if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.data.Type.String:
924                            self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
925
926                self.markInputRadioButton.setEnabled(True)
927                self.set_mark_mode(9)
928
929        def set_explore_distances(self):
930            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
931
932            if self.explore_distances:
933                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
934
935        def explore_focused(self):
936            sel = self.networkCanvas.selected_nodes()
937            if len(sel) == 1:
938                ndx_1 = sel[0]
939                self.networkCanvas.label_distances = [['%.2f' % \
940                                self.items_matrix[ndx_1][ndx_2]] \
941                                for ndx_2 in self.networkCanvas.graph.nodes()]
942            else:
943                self.networkCanvas.label_distances = None
944
945            self.networkCanvas.set_node_labels(self.lastLabelColumns)
946            self.networkCanvas.replot()
947
948        #######################################################################
949        ### Layout Optimization                                             ###
950        #######################################################################
951
952        def graph_layout(self):
953            if self.graph is None or self.graph.number_of_nodes <= 0:   #grafa se ni
954                self.optButton.setChecked(False)
955                return
956
957            if not self.optButton.isChecked() and not self.optMethod in [2, 3, 9, 10]:
958                self.optButton.setChecked(False)
959                return
960
961            qApp.processEvents()
962
963            if self.optMethod == 1:
964                self.networkCanvas.networkCurve.random()
965            elif self.optMethod == 2:
966                self.graph_layout_fr(False)
967            elif self.optMethod == 3:
968                self.graph_layout_fr(True)
969            elif self.optMethod == 4:
970                self.graph_layout_fr_radial()
971            elif self.optMethod == 5:
972                self.networkCanvas.networkCurve.circular(\
973                                            NetworkCurve.circular_crossing)
974            elif self.optMethod == 6:
975                self.networkCanvas.networkCurve.circular(\
976                                            NetworkCurve.circular_original)
977            elif self.optMethod == 7:
978                self.networkCanvas.networkCurve.circular(\
979                                            NetworkCurve.circular_random)
980            elif self.optMethod == 8:
981                self.graph_layout_fragviz()
982            elif self.optMethod == 9:
983                self.graph_layout_mds()
984            elif self.optMethod == 10:
985                self.graph_layout_pivot_mds()
986
987            self.optButton.setChecked(False)
988            self.networkCanvas.update_canvas()
989
990        def graph_layout_method(self, method=None):
991            self.information()
992            self.stepsSpin.label.setText('Iterations: ')
993            self.optButton.setEnabled(True)
994            self.cb_opt_from_curr.setEnabled(False)
995
996            if method is not None:
997                self.optMethod = method
998
999            if str(self.optMethod) == '0':
1000                self.optButton.setEnabled(False)
1001            else:
1002                self.optButton.setEnabled(True)
1003
1004            if str(self.optMethod) in ['2', '3', '4']:
1005                self.stepsSpin.setEnabled(True)
1006
1007            elif str(self.optMethod) in ['8', '9', '10']:
1008                if str(self.optMethod) == '8':
1009                    self.stepsSpin.label.setText('Pivots: ')
1010
1011                if str(self.optMethod) in ['9', '10']:
1012                    self.cb_opt_from_curr.setEnabled(True)
1013
1014                self.stepsSpin.setEnabled(True)
1015
1016                if self.items_matrix is None:
1017                    self.information('Set distance matrix to input signal')
1018                    self.optButton.setEnabled(False)
1019                    return
1020                if self.graph is None:
1021                    self.information('No network found')
1022                    self.optButton.setEnabled(False)
1023                    return
1024                if self.items_matrix.dim != self.graph.number_of_nodes():
1025                    self.error('Distance matrix dimensionality must equal number of vertices')
1026                    self.optButton.setEnabled(False)
1027                    return
1028            else:
1029                self.stepsSpin.setEnabled(False)
1030                self.optButton.setChecked(True)
1031                self.graph_layout()
1032
1033        def mds_progress(self, avgStress, stepCount):
1034            #self.drawForce()
1035
1036            #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1037            #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1038            self.progressBarSet(int(stepCount * 100 / self.frSteps))
1039            qApp.processEvents()
1040
1041        def graph_layout_fragviz(self):
1042            if self.items_matrix is None:
1043                self.information('Set distance matrix to input signal')
1044                self.optButton.setChecked(False)
1045                return
1046
1047            if self.layout is None:
1048                self.information('No network found')
1049                self.optButton.setChecked(False)
1050                return
1051
1052            if self.items_matrix.dim != self.graph.number_of_nodes():
1053                self.error('Distance matrix dimensionality must equal number of vertices')
1054                self.optButton.setChecked(False)
1055                return
1056
1057            if not self.optButton.isChecked():
1058                self.networkCanvas.networkCurve.stopMDS = True
1059                self.optButton.setChecked(False)
1060                self.optButton.setText("Optimize layout")
1061                return
1062
1063            self.optButton.setText("Stop")
1064            self.progressBarInit()
1065            qApp.processEvents()
1066
1067            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1068                matrix = self.items_matrix
1069            else:
1070                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1071
1072            self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mds_progress, self.opt_from_curr)
1073
1074            self.optButton.setChecked(False)
1075            self.optButton.setText("Optimize layout")
1076            self.progressBarFinished()
1077
1078        def graph_layout_mds(self):
1079            if self.items_matrix is None:
1080                self.information('Set distance matrix to input signal')
1081                self.optButton.setChecked(False)
1082                return
1083
1084            if self.layout is None:
1085                self.information('No network found')
1086                self.optButton.setChecked(False)
1087                return
1088
1089            if self.items_matrix.dim != self.graph.number_of_nodes():
1090                self.error('Distance matrix dimensionality must equal number of vertices')
1091                self.optButton.setChecked(False)
1092                return
1093
1094            if not self.optButton.isChecked():
1095                self.networkCanvas.networkCurve.stopMDS = True
1096                self.optButton.setChecked(False)
1097                self.optButton.setText("Optimize layout")
1098                return
1099
1100            self.optButton.setText("Stop")
1101            self.progressBarInit()
1102            qApp.processEvents()
1103
1104            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1105                matrix = self.items_matrix
1106            else:
1107                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1108
1109            self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mds_progress, self.opt_from_curr)
1110
1111            self.optButton.setChecked(False)
1112            self.optButton.setText("Optimize layout")
1113            self.progressBarFinished()
1114
1115        def graph_layout_fr(self, weighted):
1116            if self.graph is None:
1117                return
1118
1119            if not self.optButton.isChecked():
1120                self.networkCanvas.networkCurve.stop_optimization()
1121                self.optButton.setChecked(False)
1122                self.optButton.setText("Optimize layout")
1123                return
1124
1125            self.optButton.setText("Stop")
1126            qApp.processEvents()
1127            self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1128            self.networkCanvas.update_canvas()
1129            self.optButton.setChecked(False)
1130            self.optButton.setText("Optimize layout")
1131
1132        def graph_layout_fr_radial(self):
1133            if self.graph is None:   #grafa se ni
1134                return
1135
1136    #        #print "F-R Radial"
1137    #        k = 1.13850193174e-008
1138    #        nodes = self.graph.number_of_nodes()
1139    #        t = k * nodes * nodes
1140    #        refreshRate = int(5.0 / t)
1141    #        if refreshRate <    1: refreshRate = 1
1142    #        if refreshRate > 1500: refreshRate = 1500
1143    #        #print "refreshRate: " + str(refreshRate)
1144    #       
1145    #        tolerance = 5
1146    #        initTemp = 100
1147    #        centerNdx = 0
1148    #       
1149    #        selection = self.networkCanvas.getSelection()
1150    #        if len(selection) > 0:
1151    #            centerNdx = selection[0]
1152    #           
1153    #        #print "center ndx: " + str(centerNdx)
1154    #        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1155    #        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1156    #        #self.networkCanvas.circles = [100, 200, 300]
1157    #        self.networkCanvas.updateCanvas()
1158    #        self.networkCanvas.circles = []
1159
1160        def graph_layout_pivot_mds(self):
1161            self.information()
1162
1163            if self.items_matrix is None:
1164                self.information('Set distance matrix to input signal')
1165                return
1166
1167            if self.graph_base is None:
1168                self.information('No network found')
1169                return
1170
1171            if self.items_matrix.dim != self.graph_base.number_of_nodes():
1172                self.error('The number of vertices does not match matrix size.')
1173                return
1174
1175            self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1176            qApp.processEvents()
1177
1178            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1179                matrix = self.items_matrix
1180            else:
1181                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1182
1183            mds = orngMDS.PivotMDS(matrix, self.frSteps)
1184            x, y = mds.optimize()
1185            xy = zip(list(x), list(y))
1186            coors = dict(zip(sorted(self.graph.nodes()), xy))
1187            self.networkCanvas.networkCurve.set_node_coordinates(coors)
1188            self.networkCanvas.update_canvas()
1189
1190        #######################################################################
1191        ### Network Visualization                                           ###
1192        #######################################################################
1193
1194        def _set_colors(self):
1195            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
1196            if dlg.exec_():
1197                self.colorSettings = dlg.getColorSchemas()
1198                self.selectedSchemaIndex = dlg.selectedSchemaIndex
1199                self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1200                self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1201
1202                self.set_node_colors()
1203
1204        def _set_edge_color_palette(self):
1205            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1206            if dlg.exec_():
1207                self.edgeColorSettings = dlg.getColorSchemas()
1208                self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1209                self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1210                self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1211
1212                self.set_edge_colors()
1213
1214        def _create_color_dialog(self, colorSettings, selectedSchemaIndex):
1215            c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1216            c.createDiscretePalette("discPalette", "Discrete Palette")
1217            c.createContinuousPalette("contPalette", "Continuous Palette")
1218            c.setColorSchemas(colorSettings, selectedSchemaIndex)
1219            return c
1220
1221        def _clicked_att_lstbox(self):
1222            if self.graph is None:
1223                return
1224
1225            self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1226            self.networkCanvas.set_node_labels(self.lastLabelColumns)
1227            self.networkCanvas.replot()
1228
1229        def _clicked_tooltip_lstbox(self):
1230            if self.graph is None:
1231                return
1232
1233            self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1234            self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1235            self.networkCanvas.replot()
1236
1237        def _clicked_edge_label_listbox(self):
1238            if self.graph is None:
1239                return
1240
1241            self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1242            self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1243            self.networkCanvas.replot()
1244
1245        def set_node_colors(self):
1246            if self.graph is None:
1247                return
1248
1249            self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1250            self.lastColorColumn = self.colorCombo.currentText()
1251
1252        def set_edge_colors(self):
1253            if self.graph is None:
1254                return
1255
1256            self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1257            self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1258
1259        def set_edge_sizes(self):
1260            if self.graph is None:
1261                return
1262
1263            self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1264            self.networkCanvas.replot()
1265
1266        def set_node_sizes(self):
1267            if self.graph is None or self.networkCanvas is None:
1268                return
1269
1270            if self.minVertexSize > self.maxVertexSize:
1271                self.maxVertexSize = self.minVertexSize
1272
1273            items = self.graph_base.items()
1274
1275            if items is None:
1276                self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1277                return
1278
1279            self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1280            column = str(self.vertexSizeCombo.currentText())
1281
1282            values = {}
1283            if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1284                if column in items.domain:
1285                    values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1286                else:
1287                    values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1288
1289            if len(values) == 0:
1290                values = dict((node, 1.) for node in self.graph)
1291
1292            if self.invertSize:
1293                maxval = max(values.itervalues())
1294                values.update((key, maxval - val) for key, val in values.iteritems())
1295                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1296            else:
1297                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1298
1299            self.networkCanvas.replot()
1300
1301        def set_font(self):
1302            if self.networkCanvas is None:
1303                return
1304
1305            weights = {0: 50, 1: 80}
1306
1307            font = self.networkCanvas.font()
1308            font.setPointSize(self.fontSize)
1309            font.setWeight(weights[self.fontWeight])
1310            self.networkCanvas.setFont(font)
1311            self.networkCanvas.fontSize = font
1312            self.networkCanvas.set_node_labels()
1313
1314        def sendReport(self):
1315            self.reportSettings("Graph data",
1316                                [("Number of vertices", self.graph.number_of_nodes()),
1317                                 ("Number of edges", self.graph.number_of_edges()),
1318                                 ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1319                                 ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1320                                 ])
1321            if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1322                self.reportSettings("Visual settings",
1323                                    [self.color and ("Vertex color", self.colorCombo.currentText()),
1324                                     self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1325                                     self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1326                                     self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1327                                    ])
1328            self.reportSettings("Optimization",
1329                                [("Method", self.optCombo.currentText()),
1330                                 ("Iterations", self.frSteps)])
1331            self.reportSection("Graph")
1332            self.reportImage(self.networkCanvas.saveToFileDirect)
1333
1334        #######################################################################
1335        ### PROTOTYPE                                                       ###
1336        #######################################################################
1337
1338        def set_component_edge_width(self, changedMin=True):
1339            if self.networkCanvas is None:
1340                return
1341
1342            canvas = self.networkCanvas
1343            if changedMin:
1344                if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
1345                    self.maxComponentEdgeWidth = self.minComponentEdgeWidth
1346            else:
1347                if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
1348                    self.minComponentEdgeWidth = self.maxComponentEdgeWidth
1349
1350            canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
1351            canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
1352            self.networkCanvas.updateCanvas()
1353
1354        def showComponents(self):
1355            if self.graph is None or self.graph_base.items() is None:
1356                return
1357
1358            vars = [x.name for x in self.graph_base.items_vars()]
1359
1360            if not self.showComponentCombo.currentText() in vars:
1361                self.networkCanvas.showComponentAttribute = None
1362                self.lastNameComponentAttribute = ''
1363            else:
1364                self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()
1365
1366            self.networkCanvas.drawComponentKeywords()
1367
1368        def nameComponents(self):
1369            """Names connected components of genes according to GO terms."""
1370            self.progressBarFinished()
1371            self.lastNameComponentAttribute = None
1372
1373            if self.graph is None or self.graph_base.items() is None:
1374                return
1375
1376            vars = [x.name for x in self.graph_base.items_vars()]
1377            if not self.nameComponentCombo.currentText() in vars:
1378                return
1379
1380            self.progressBarInit()
1381            components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
1382            if 'component name' in self.graph_base.items().domain:
1383                keyword_table = self.graph_base.items()
1384            else:
1385                keyword_table = Orange.data.Table(Orange.data.Domain(Orange.data.variable.String('component name')), [[''] for i in range(len(self.graph_base.items()))])
1386
1387            import obiGO
1388            ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet)
1389            annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
1390
1391            allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
1392            foundGenesets = False
1393            if len(annotations.geneNames & allGenes) < 1:
1394                allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
1395                if len(annotations.geneNames & allGenes) < 1:
1396                    self.warning('no genes found')
1397                    return
1398                else:
1399                    foundGenesets = True
1400
1401            def rank(a, j, reverse=False):
1402                if len(a) <= 0: return
1403
1404                if reverse:
1405                    a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
1406                    top_value = a[0][j]
1407                    top_rank = len(a)
1408                    max_rank = float(len(a))
1409                    int_ndx = 0
1410                    for k in range(len(a)):
1411                        if top_value < a[k][j]:
1412                            top_value = a[k][j]
1413                            if k - int_ndx > 1:
1414                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1415                                for l in range(int_ndx, k):
1416                                    a[l][j] = avg_rank
1417
1418                            int_ndx = k
1419
1420                        a[k][j] = top_rank / max_rank
1421                        top_rank -= 1
1422
1423                    k += 1
1424                    if k - int_ndx > 1:
1425                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1426                        for l in range(int_ndx, k):
1427                            a[l][j] = avg_rank
1428
1429                else:
1430                    a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
1431                    top_value = a[0][j]
1432                    top_rank = len(a)
1433                    max_rank = float(len(a))
1434                    int_ndx = 0
1435                    for k in range(len(a)):
1436                        if top_value > a[k][j]:
1437                            top_value = a[k][j]
1438                            if k - int_ndx > 1:
1439                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1440                                for l in range(int_ndx, k):
1441                                    a[l][j] = avg_rank
1442
1443                            int_ndx = k
1444
1445                        a[k][j] = top_rank / max_rank
1446                        top_rank -= 1
1447
1448                    k += 1
1449                    if k - int_ndx > 1:
1450                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1451                        for l in range(int_ndx, k):
1452                            a[l][j] = avg_rank
1453
1454            for i in range(len(components)):
1455                component = components[i]
1456                if len(component) <= 1:
1457                    continue
1458
1459                if foundGenesets:
1460                    genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
1461                else:
1462                    genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
1463
1464                res1 = annotations.GetEnrichedTerms(genes, aspect="P")
1465                res2 = annotations.GetEnrichedTerms(genes, aspect="F")
1466                res = res1.items() + res2.items()
1467                #namingScore = [[(1-p_value) * (float(len(g)) / len(genes)) / (float(ref) / len(annotations.geneNames)), ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
1468                #namingScore = [[(1-p_value) * len(g) / ref, ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
1469
1470                namingScore = [[len(g), ref, p_value, ontology[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res if p_value < 0.1]
1471                if len(namingScore) == 0:
1472                    continue
1473
1474                annotated_genes = max([a[0] for a in namingScore])
1475
1476                rank(namingScore, 1, reverse=True)
1477                rank(namingScore, 2, reverse=True)
1478                rank(namingScore, 0)
1479
1480                namingScore = [[10 * rank_genes + 0.5 * rank_ref + rank_p_value, name, g, ref, p_value] for rank_genes, rank_ref, rank_p_value, name, g, ref, p_value in namingScore]
1481                namingScore.sort(reverse=True)
1482
1483                if len(namingScore) < 1:
1484                    print "warning. no annotations found for group of genes: " + ", ".join(genes)
1485                    continue
1486                elif len(namingScore[0]) < 2:
1487                    print "warning. error computing score for group of genes: " + ", ".join(genes)
1488                    continue
1489
1490                for v in component:
1491                    name = str(namingScore[0][1])
1492                    attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
1493                    info = ''
1494                    if self.showTextMiningInfo:
1495                        info = "\n" + attrs + "\n" + str(namingScore[0][0])
1496                    keyword_table[v]['component name'] = name + info
1497
1498                self.progressBarSet(i * 100.0 / len(components))
1499
1500            self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
1501            self.set_items(Orange.data.Table([self.graph_base.items(), keyword_table]))
1502            self.progressBarFinished()
1503
1504
1505        def setAutoSendAttributes(self):
1506            print 'TODO setAutoSendAttributes'
1507            #if self.autoSendAttributes:
1508            #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
1509            #else:
1510            #    self.networkCanvas.callbackSelectVertex = None
1511
1512        def sendAttSelectionList(self):
1513            if not self.graph is None:
1514                vars = [x.name for x in self.graph_base.links_vars()]
1515                if not self.comboAttSelection.currentText() in vars:
1516                    return
1517                att = str(self.comboAttSelection.currentText())
1518                vertices = self.networkCanvas.selected_nodes()
1519
1520                if len(vertices) != 1:
1521                    return
1522
1523                attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
1524            else:
1525                attributes = None
1526            self.send("Features", attributes)
1527
1528
1529except ImportError as err:
1530    try:
1531        from OWNxCanvas import *
1532    except:
1533        # if Qwt is also not installed throw could not import orangeqt error
1534        raise err
1535
1536    from OWNxExplorerQwt import OWNxExplorerQwt as OWNxExplorer
1537
1538if __name__ == "__main__":
1539    a = QApplication(sys.argv)
1540    ow = OWNxExplorer()
1541    ow.show()
1542
1543    def setNetwork(signal, data, id=None):
1544        if signal == 'Network':
1545            ow.set_graph(data)
1546        #if signal == 'Items':
1547        #    ow.set_items(data)
1548
1549    import OWNxFile
1550    owFile = OWNxFile.OWNxFile()
1551    owFile.send = setNetwork
1552    owFile.show()
1553    owFile.selectNetFile(0)
1554
1555    a.exec_()
1556    ow.saveSettings()
1557    owFile.saveSettings()
Note: See TracBrowser for help on using the repository browser.