#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Mon Aug 5 15:42:19 2019 @author: pavel """ from GraphCanvas import GraphCanvas from HistogramWidget import HistogramWidget #from NodeInformationWidget import NodeInfoWidget from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.Qt import QRect import network_dep as nwt from TubeWidget import TubeWidget from vispy.scene.visuals import Text import numpy as np DEBUG = False class NodeInfoWidget(QtWidgets.QWidget): def __init__(self, *args, **kwargs): QtWidgets.QWidget.__init__(self) self.layout = QtWidgets.QGridLayout() self.resize(900, 300) self.bar = None print("stuff 22") if 'hist' in kwargs: print("stuff") self.bar = HistogramWidget() self.bar.canvas.create_native() self.fibers_mini = TubeWidget() self.fibers_mini.canvas.create_native() self.graph_mini1 = GraphWidget() self.graph_mini1.canvas.create_native() self.graph_mini2 = GraphWidget() self.graph_mini2.canvas.create_native() self.graph_mini3 = GraphWidget() self.graph_mini3.canvas.create_native() self.graph_mini4 = GraphWidget() self.graph_mini4.canvas.create_native() self.graph_mini1.connect(self.fibers_mini) self.fibers_mini.connect(self.graph_mini1) self.fibers_mini.connect(self.graph_mini2) self.fibers_mini.connect(self.graph_mini3) self.fibers_mini.connect(self.graph_mini4) self.layout.addWidget(self.graph_mini1.canvas.native, 0, 0, 1, 1) self.layout.addWidget(self.graph_mini2.canvas.native, 0, 1, 1, 1) self.layout.addWidget(self.graph_mini3.canvas.native, 1, 0, 1, 1) self.layout.addWidget(self.graph_mini4.canvas.native, 1, 1, 1, 1) #layout.addItem(vspacer, 0, 2, 2, 1) if self.bar == None: self.layout.addWidget(self.fibers_mini.canvas.native, 0, 2, 2, 2) else: self.layout.addWidget(self.fibers_mini.canvas.native, 0, 2, 1, 1) self.layout.addWidget(self.bar.canvas.native, 1, 2, 1, 1) #layout.setColumnStretch(0, 2) #layout.setRowStretch(0, 2) #layout.setColumnStretch(2, 1) #layout.setRowStretch(0, 1) self.setLayout(self.layout) #print(layout.getContentsMargins()) #top.show() # def paintEvent(self, e): # dc = QPainter(self) def bye(self): self.exit(0) """ Initializes the entire QTlayout and sets the mouse press events. These are connected to the slots such that each is processes by this class and the class it wraps. """ #class GraphWidget(QtGui.QWidget): class GraphWidget(QtWidgets.QWidget): select = QtCore.pyqtSignal(list) def __init__(self): super(GraphWidget, self).__init__() box = QtWidgets.QVBoxLayout(self) self.resize(500,500) self.setLayout(box) self.canvas = GraphCanvas() self.setUpdatesEnabled(True) #self.canvas.create_native() box.addWidget(self.canvas.native) self.color = True self.use_3D = False self.camera = [0,0,0] self.other = None self.canvas.events.mouse_press.connect(self.on_mouse_press) self.canvas.events.mouse_release.connect(self.on_mouse_release) self.canvas.events.mouse_move.connect(self.on_mouse_move) self.canvas.events.mouse_double_click.connect(self.on_mouse_double_click) self.w = None #self.canvas.events. #self.show() #self.repaint() """ Handles the right click mouse event at the QWidget level. Depending on where the mouse button in clicked and the current zoom level, the function gets the unique id of the node, cluster or background under the cursor and opens a context menu based on the ID. The context menu level actions are also coded in this section of the code. """ def on_mouse_press(self, event): self.canvas.set_current(event) if event.button == 2: if self.canvas.view[0][0] >= 0.0010: self.canvas.refresh() c_id = self.canvas.get_clicked_id(event) self.canvas.refresh() else: self.canvas.refresh() c_id = self.canvas.get_clicked_id(event, clusters=True) self.canvas.refresh() #right click if(c_id == None): menu = QtWidgets.QMenu(self) NS = menu.addAction('Node Size') if (self.canvas.path != []): FNP = menu.addAction("Filter Network Path") #tmp = menu.addAction('temp') tmp = menu.addMenu('Node Color') vertex_props = self.canvas.G.vertex_properties.keys() vertex_actions = [] for i in range(len(vertex_props)): if(vertex_props[i] != "map" or vertex_props[i] != "RGBA"): vertex_actions.append(tmp.addAction(vertex_props[i])) #tmp.addAction("Cluster") #NC = menu.addAction('Node Color') EXP = menu.addAction('Export VTK') #EXP_adv = menu.addAction('Export VTK Advanced') NL = menu.addAction('New Layout') NSL = menu.addAction('New Spring-Onion Layout (sum)') NSLMI = menu.addAction('New Spring-Onion Layout(max)') EXPAND = menu.addAction('Expand') CL = menu.addAction('Cluster_Layout') action = menu.exec_(event.native.globalPos()) if DEBUG: print(action) for i in range(len(vertex_actions)): if action == vertex_actions[i]: if vertex_props[i] == "clusters": self.canvas.color_vertices(self.canvas.G, vertex_props[i], dtype=True) else: self.canvas.color_vertices(self.canvas.G, vertex_props[i]) if DEBUG: print(vertex_props[i]) if action == NS: if self.use_3D == False: self.use_3D = True else: self.use_3D = False self.canvas.size_vertices(self.canvas.G, 'degree' ) self.canvas.color_vertices(self.canvas.G, 'degree') if (self.canvas.path != []): if action == FNP: net = nwt.Network() G1 = net.filterBorder(self.canvas.G) BB = nwt.AABB(G1) self.canvas.set_graph(G1, BB.A, BB.B, subgraph=True) self.test.canvas.set_data(G1, BB.A, BB.B, 16) self.canvas.refresh() self.test.canvas.refresh() #self.canvas.set_data() #if action == NC: # self.canvas.color_vertices(self.canvas.G, not self.color) # self.color = not self.color if action == EXP: nwt.Network.write_vtk(self.canvas.G, "./nwt_small.vtk") # if action == EXP_adv: # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_binned.vtk") # nwt.Network.write_vtk(self.canvas.G, "./nwt_median_non_binned.vtk", binning=False) # nwt.Network.write_vtk(self.canvas.G, "./nwt_points_wise_binned.vtk", camera=self.camera, binning = True) # nwt.Network.write_vtk(self.canvas.G, "./nwt_points_wise_non_binned.vtk", camera=self.camera, binning = False) if action == tmp: if DEBUG: print("Stuff") #self.cb = QtWidgets.QComboBox() #vertex_props = self.canvas.G.vertex_properties.keys() #for i in range(len(vertex_props)): # self.cb.addItem(vertex_props[i]) #self.cb.currentIndexChanged.connect(self.selection_change) #self.cb.show() if action == NL: old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T nG = nwt.Network.gen_new_fd_layout(self.canvas.G) new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T self.canvas.animate(old_pos, new_pos) #self.canvas.gen_vertex_vbo(self.canvas.G) #self.canvas.set_data(self.canvas.G, self.canvas.bbl, self.canvas.bbu) #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) if action == NSL: old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T nG = nwt.Network.gen_spring_onion_layout(self.canvas.G, 'degree', 1.0, 1000, 0.01, 1.0) new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T self.canvas.animate(old_pos, new_pos) #self.canvas.set_data(nG, self.canvas.bbl, self.canvas.bbu) #self.canvas.gen_vertex_vbo(self.canvas.G) #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) if action == NSLMI: old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T nG = nwt.Network.gen_spring_onion_layout(self.canvas.G, 'degree', 1.0, 1000, 0.01, 1.0, False) new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T self.canvas.animate(old_pos, new_pos) #self.canvas.set_data(nG, self.canvas.bbl, self.canvas.bbu) #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) #self.canvas.gen_vertex_vbo(self.canvas.G) if action == EXPAND: #self.canvas.gen_vertex_vbo(self.canvas.G) old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) new_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T #self.canvas.expand_clusters(self.canvas.G, self.canvas.n_c) self.canvas.animate(old_pos, new_pos) if action == CL: old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T self.canvas.voronoi_layout() new_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T if self.other != None: other_old_pos = self.other.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T self.other.canvas.voronoi_layout(G_c = self.canvas.G_cluster) other_new_pos = self.other.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T self.other.canvas.animate(other_old_pos, other_new_pos) self.canvas.animate(old_pos, new_pos) #self.canvas.size_vertices(self.canvas.G, 'degree_volume') else: if self.canvas.view[0][0] >= 0.0010: menu = QtWidgets.QMenu(self) MnOC = menu.addAction('Minimize Other Clusters') RA = menu.addAction('Reset Alpha') NI = menu.addAction('Display Node Info') CI = menu.addAction('Display Cluster Info') action = menu.exec_(event.native.globalPos()) if action == MnOC: self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event) cluster_id = self.canvas.G.vp["clusters"][self.canvas.G.vertex(c_id)] self.select.emit(self.canvas.get_cluster(cluster_id)) if action == RA: t = [] self.select.emit(self.canvas.get_cluster(t)) if action == NI: self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event) self.canvas.refresh() print("Display Node Info") self.w = NodeInfoWidget() #generate the subgraph around the node vfilt = np.zeros([self.canvas.G.num_vertices(), 1], dtype="bool") center = self.canvas.G.vp["pos"][self.canvas.G.vertex(c_id)] for v in self.canvas.G.vertex(c_id).all_neighbors(): vfilt[int(v)] = 1 vfilt[int(c_id)] = 1 vfilt_prop = self.canvas.G.new_vertex_property("bool", vals = vfilt) self.canvas.G.set_vertex_filter(vfilt_prop) #get the filtered properties g = nwt.gt.Graph(self.canvas.G, prune=True, directed=False) BB = nwt.AABB(g) #print(BB.A) #print(BB.B) self.canvas.G.clear_filters() self.w.setGeometry(QRect(100, 100, 900, 800)) self.w.graph_mini1.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini1.canvas.center_camera_on(center) self.w.graph_mini1.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini1.canvas.color_vertices(g, "clusters") self.w.graph_mini2.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini2.canvas.center_camera_on(center) self.w.graph_mini2.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini2.canvas.color_vertices(g, "degree") self.w.graph_mini3.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini3.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini3.canvas.center_camera_on(center) self.w.graph_mini3.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini3.canvas.color_vertices(g, "bc") self.w.graph_mini4.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini4.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini4.canvas.center_camera_on(center) self.w.graph_mini4.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini4.canvas.color_vertices(g, "degree_volume") self.w.fibers_mini.canvas.set_data(g, BB.A, BB.B, 16) self.w.show() if action == CI: self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event) #self.canvas.refresh() self.w = NodeInfoWidget(hist=True) #self.w = NodeInfoWidget() cluster_id = self.canvas.G.vp["clusters"][self.canvas.G.vertex(c_id)] num_v_in_cluster = len(np.argwhere(self.canvas.labels == cluster_id)) vfilt = np.zeros([self.canvas.G.num_vertices(), 1], dtype="bool") vfilt[np.argwhere(self.canvas.labels == cluster_id)] = 1 vfilt_prop = self.canvas.G.new_vertex_property("bool", vals = vfilt) self.canvas.G.set_vertex_filter(vfilt_prop) #get the filtered properties g = nwt.gt.Graph(self.canvas.G, prune=True, directed=False) positions = g.vertex_properties["pos"].get_2d_array(range(3)).T center = np.sum(positions, 0)/num_v_in_cluster self.canvas.G.clear_filters() BB = nwt.AABB(g) self.canvas.G.clear_filters() self.w.setGeometry(QRect(100, 100, 900, 800)) self.w.graph_mini1.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini1.canvas.center_camera_on(center) self.w.graph_mini1.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini2.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini2.canvas.center_camera_on(center) self.w.graph_mini2.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini2.canvas.color_vertices(g, "degree") self.w.graph_mini3.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini3.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini3.canvas.center_camera_on(center) self.w.graph_mini3.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini3.canvas.color_vertices(g, "bc") self.w.graph_mini4.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini4.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini4.canvas.center_camera_on(center) self.w.graph_mini4.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini4.canvas.color_vertices(g, "degree_volume") self.w.fibers_mini.canvas.set_data(g, BB.A, BB.B, 16) self.w.bar.set_Graph(g) self.w.show() print("Display Cluster Info") else: menu = QtWidgets.QMenu(self) MnOC = menu.addAction('Minimize Other Clusters') CI = menu.addAction('Display Cluster Info') RA = menu.addAction('Reset Alpha') action = menu.exec_(event.native.globalPos()) if action == MnOC: self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event, clusters=True) self.canvas.refresh() cluster_id = self.canvas.G.vp["clusters"][c_id] self.select.emit(self.canvas.get_path(cluster_id)) if action == RA: t = [] self.select.emit(self.canvas.get_cluster(t)) if action == CI: self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event, clusters=True) self.canvas.refresh() self.w = NodeInfoWidget(hist=True) #self.w = NodeInfoWidget() cluster_id = self.canvas.G.vp["clusters"][c_id] num_v_in_cluster = len(np.argwhere(self.canvas.labels == c_id)) vfilt = np.zeros([self.canvas.G.num_vertices(), 1], dtype="bool") vfilt[np.argwhere(self.canvas.labels == c_id)] = 1 vfilt_prop = self.canvas.G.new_vertex_property("bool", vals = vfilt) self.canvas.G.set_vertex_filter(vfilt_prop) #get the filtered properties g = nwt.gt.Graph(self.canvas.G, prune=True, directed=False) positions = g.vertex_properties["pos"].get_2d_array(range(3)).T center = np.sum(positions, 0)/num_v_in_cluster self.canvas.G.clear_filters() BB = nwt.AABB(g) self.canvas.G.clear_filters() self.w.setGeometry(QRect(100, 100, 900, 800)) self.w.graph_mini1.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini1.canvas.center_camera_on(center) self.w.graph_mini1.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini2.canvas.set_graph(g, BB.A, BB.B) self.w.graph_mini2.canvas.center_camera_on(center) self.w.graph_mini2.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini2.canvas.color_vertices(g, "degree") self.w.graph_mini3.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini3.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini3.canvas.center_camera_on(center) self.w.graph_mini3.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini3.canvas.color_vertices(g, "bc") self.w.graph_mini4.canvas.set_graph(g, BB.A, BB.B) #self.w.graph_mini4.canvas.set_view_matrix(self.canvas.view) self.w.graph_mini4.canvas.center_camera_on(center) self.w.graph_mini4.canvas.zoom_camera_on(self.canvas.scale) self.w.graph_mini4.canvas.color_vertices(g, "degree_volume") self.w.fibers_mini.canvas.set_data(g, BB.A, BB.B, 16) self.w.bar.set_Graph(g) self.w.show() print("Display Cluster Info") # def selection_change(self, i): # self.canvas.size_vertices(self.canvas.G, self.cb.currentText()) def set_other(self, other): self.other = other """ Handles the mouse double click event. Pass-through function. """ def on_mouse_double_click(self, event): self.canvas.set_current(event) self.canvas.update_path(event) self.select.emit(self.canvas.get_path()) # old_pos = self.canvas.G.vertex_properties["pos"].get_2d_array(range(3)).T # nG = nwt.Network.gen_new_fd_layout(self.canvas.G) # def animate(self, new_G): # # new_pos = nG.vertex_properties["pos"].get_2d_array(range(3)).T # self.canvas.animate(old_pos, new_pos) """ Handles the mouse release event. Pass-through function. """ def on_mouse_release(self, event): n = 1 """ Handles the mouse move event. Pass-through function. """ def on_mouse_move(self, event): self.canvas.set_current(event) self.canvas.refresh() c_id = self.canvas.get_clicked_id(event) self.canvas.refresh() print(c_id) """ Internal function that interacts with the tube visualization. """ def set_g_view(self, test): self.test = test """ Function to handle the pyqt Slot that receives the interacted-with signal from the Tube visualization. The signal sends the camera position in 3D coordinates every time the camera is moved. """ @QtCore.pyqtSlot(float, float, float) def sigUpdate(self, x, y, z): self.camera = [x,y,z] if(self.use_3D == True): self.camera = [x,y,z] self.canvas.vertexSizeFromDistance(self.canvas.G, [x,y,z]) self.canvas.vertexAlphaFromDistance(self.canvas.G, [x,y,z]) if DEBUG: print("got signal", x, y, z) """ Initialization method that connects the slot to the function that handles the information being sent. """ def connect(self, signal_object): signal_object.sigUpdate.connect(self.sigUpdate)