class MatplotlibWidgetWFPot(QtGui.QGraphicsView): def __init__(self, parent = None): QtGui.QWidget.__init__(self, parent) self.canvas = MplCanvas() self.vbl = QtGui.QVBoxLayout() self.vbl.addWidget(self.canvas) self.setLayout(self.vbl) self.canvas.ax.set_title('Calculated PCB electrode potentials', fontsize=10) self.canvas.fig.patch.set_alpha(0) self.mpl_toolbar = NavigationToolbar(self.canvas, self) params = { 'legend.fontsize': 8, 'xtick.labelsize': 8, 'ytick.labelsize': 8, 'legend.handletextpad': .5, } plt.rcParams.update(params) self.mpl_toolbar.pan() def plot(self, wfPotentials, plotitems): if hasattr(wfPotentials, 'plotTime'): argX = wfPotentials.plotTime argY = wfPotentials.potentialsOut # get axis limits to not reset zoom/pan axlim = self.canvas.ax.axis() self.canvas.ax.clear() if not any(plotitems): self.canvas.draw() return if plotitems[0]: self.canvas.ax.plot(argX, argY[1,:], 'r.') self.canvas.ax.plot(argX, argY[1,:], 'r', label="2", linewidth=1.2) if plotitems[1]: self.canvas.ax.plot(argX, argY[3,:], 'b.') self.canvas.ax.plot(argX, argY[3,:], 'b', label="4", linewidth=1.2) if plotitems[2]: self.canvas.ax.plot(argX, argY[5,:], 'g.') self.canvas.ax.plot(argX, argY[5,:], 'g', label="6", linewidth=1.2) if not axlim == (0.0, 1.0, 0.0, 1.0): self.canvas.ax.axis(axlim) else: pass self.canvas.ax.grid(True) self.canvas.ax.set_title("Calculated PCB electrode potentials", fontsize=10) self.canvas.ax.set_xlabel("Time ($\mu$s)", fontsize=10) self.canvas.ax.set_ylabel("Amplitude (bits)", fontsize=10) self.canvas.ax.legend(bbox_to_anchor=(0.02, 0.99), loc=2, borderpad=None, borderaxespad=0., fontsize=8, frameon=False) # mares in potential generation self.canvas.ax.plot([wfPotentials.incplTime,wfPotentials.incplTime],[(wfPotentials.maxAmp*2+50),-50], 'k--', linewidth=1.5) self.canvas.ax.plot([wfPotentials.plotTime[-1]-wfPotentials.outcplTime, wfPotentials.plotTime[-1]-wfPotentials.outcplTime], \ [-1,wfPotentials.maxAmp*2+1], 'k--', linewidth=1.5) #self.WaveformDisplay.canvas.ax.plot([wfPotentials.incplTime+wfPotentials.decelTime,\ #wfPotentials.incplTime+wfPotentials.decelTime],[wfPotentials.maxAmp*-2-1, wfPotentials.maxAmp*2+1], 'k--', linewidth=1) self.canvas.fig.patch.set_alpha(0) self.canvas.fig.tight_layout() self.canvas.draw() else: print 'No potentials generated'
class Window(QtGui.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() # Just some button self.button = QtGui.QPushButton('Plot') self.button.clicked.connect(self.plot) self.button1 = QtGui.QPushButton('Zoom') self.button1.clicked.connect(self.zoom) self.button2 = QtGui.QPushButton('Pan') self.button2.clicked.connect(self.pan) self.button3 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) layout.addWidget(self.button1) layout.addWidget(self.button2) layout.addWidget(self.button3) self.setLayout(layout) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def plot(self): ''' plot some random stuff ''' data = [random.random() for i in range(25)] ax = self.figure.add_subplot(111) ax.hold(False) ax.plot(data, '*-') self.canvas.draw()
def pan(self, *args): """ :param args: :return: """ NavigationToolbar2.pan(self, args) if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_PAN: # out of pan mode self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE else: # into pan mode self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_PAN return
def pan(self, *args): """ :param args: :return: """ NavigationToolbar2.pan(self, args) if self._navigationMode == MyNavigationToolbar.NAVIGATION_MODE_PAN: # out of pan mode self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_NONE else: # into pan mode self._navigationMode = MyNavigationToolbar.NAVIGATION_MODE_PAN return
class PlotManager(QtGui.QWidget): def __init__(self, parent=None): super(PlotManager, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() self.zoombut = QtGui.QPushButton("Збільшити") self.zoombut.clicked.connect(self.zoom) self.panbut = QtGui.QPushButton("Перемістити") self.panbut.clicked.connect(self.pan) self.homebut = QtGui.QPushButton("Повністю") self.homebut.clicked.connect(self.home) self.savebut = QtGui.QPushButton("Зберегти") self.savebut.clicked.connect(self.save) layout = QtGui.QVBoxLayout() buttonbox = QtGui.QHBoxLayout() buttonbox.addWidget(self.zoombut) buttonbox.addWidget(self.panbut) buttonbox.addWidget(self.homebut) buttonbox.addWidget(self.savebut) layout.addLayout(buttonbox) layout.addWidget(self.toolbar) layout.addWidget(self.canvas) self.setLayout(layout) self.ax = self.figure.add_subplot(111) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def save(self): timestr = time.strftime("%Y%m%d_%H%M%S", time.gmtime()) self.figure.savefig(f'{timestr}.png')
def pan(self): NavigationToolbar.pan(self) self.mode = "" #<--- whatever you want to replace "pan/zoom" goes here self.set_message(self.mode)
class PyWeramiWindow(QtGui.QMainWindow, Ui_MainWindow): def __init__(self, filename=None, parent=None): super(PyWeramiWindow,self).__init__(parent) self.settings = QtCore.QSettings("LX", "pywerami") self.setupUi(self) self._fig = plt.figure(facecolor="white") self._ax = self._fig.add_subplot(111) self._canvas = FigureCanvas(self._fig) self._canvas.setParent(self.widget) self._canvas.setFocusPolicy(QtCore.Qt.StrongFocus) self.matplot.addWidget(self._canvas) self.mpl_toolbar = NavigationToolbar(self._canvas,self.widget) self.mpl_toolbar.hide() self.matplot.addWidget(self.mpl_toolbar) #set combos self.cmaps = [m for m in plt.cm.datad if not m.endswith("_r")] self.mapstyle.addItems(self.cmaps) # set validators self.levelmin.setValidator(QtGui.QDoubleValidator(self.levelmin)) self.levelmax.setValidator(QtGui.QDoubleValidator(self.levelmax)) self.levelnum.setValidator(QtGui.QIntValidator(self.levelmin)) self.levelstep.setValidator(QtGui.QDoubleValidator(self.levelstep)) self.clipmin.setValidator(QtGui.QDoubleValidator(self.clipmin)) self.clipmax.setValidator(QtGui.QDoubleValidator(self.clipmax)) # Set icons in toolbar self.actionOpen.setIcon(QtGui.QIcon.fromTheme('document-open')) self.actionSave.setIcon(QtGui.QIcon.fromTheme('document-save')) self.actionSaveas.setIcon(QtGui.QIcon.fromTheme('document-save-as')) self.actionImport.setIcon(QtGui.QIcon.fromTheme('x-office-spreadsheet')) self.actionHome.setIcon(self.mpl_toolbar._icon('home.png')) self.actionPan.setIcon(self.mpl_toolbar._icon('move.png')) self.actionZoom.setIcon(self.mpl_toolbar._icon('zoom_to_rect.png')) self.actionGrid.setIcon(QtGui.QIcon.fromTheme('format-justify-fill')) self.actionAxes.setIcon(self.mpl_toolbar._icon('qt4_editor_options.png')) self.actionSavefig.setIcon(self.mpl_toolbar._icon('filesave.png')) #self.action3D.setIcon(QtGui.QIcon.fromTheme('')) self.actionProperties.setIcon(QtGui.QIcon.fromTheme('preferences-other')) self.actionQuit.setIcon(QtGui.QIcon.fromTheme('application-exit')) self.actionAbout.setIcon(QtGui.QIcon.fromTheme('help-about')) self.actionImport.triggered.connect(self.import_data) self.actionHome.triggered.connect(self.mpl_toolbar.home) self.actionPan.triggered.connect(self.plotpan) self.actionZoom.triggered.connect(self.plotzoom) self.actionGrid.triggered.connect(self.plotgrid) self.actionAxes.triggered.connect(self.mpl_toolbar.edit_parameters) self.actionSavefig.triggered.connect(self.mpl_toolbar.save_figure) self.actionProperties.triggered.connect(self.edit_options) self.actionQuit.triggered.connect(self.close) if filename: self.import_data(filename) # ready self.statusbar.showMessage("Ready", 5000) def closeEvent(self,event): reply=QtGui.QMessageBox.question(self,'Message',"Are you sure to quit?",QtGui.QMessageBox.Yes,QtGui.QMessageBox.No) if reply==QtGui.QMessageBox.Yes: event.accept() else: event.ignore() def import_data(self, filename=None): if not filename: filename = QtGui.QFileDialog.getOpenFileName(self, "Import tab file", ".", "TAB (*.tab);;All files (*.*)") if filename: self.data = WeramiData.from_tab(filename) # populate listview and setup properties self.props = {} self._model = QtGui.QStandardItemModel(self.listView) for var in self.data.dep: item = QtGui.QStandardItem(var) item.setCheckable(True) self._model.appendRow(item) self.default_var_props(var) self.listView.setModel(self._model) self.listView.show() # connect listview signals self.varSel = self.listView.selectionModel() self.varSel.selectionChanged.connect(self.on_var_changed) self._model.itemChanged.connect(self.plot) # buttons signals self.buttonBox.button(QtGui.QDialogButtonBox.Apply).clicked.connect(self.apply_props) self.buttonBox.button(QtGui.QDialogButtonBox.RestoreDefaults).clicked.connect(self.restore_props) self.contcolor.clicked.connect(self.contours_color) self.action3D.triggered.connect(self.switch3d) # signals to calculate step size self.levelmin.editingFinished.connect(self.step_from_levels) self.levelmax.editingFinished.connect(self.step_from_levels) self.levelnum.editingFinished.connect(self.step_from_levels) self.setlevels.toggled.connect(self.step_from_levels) # all done focus self.action3D.setChecked(False) # no 3d on import self.varSel.setCurrentIndex(self._model.index(0, 0), QtGui.QItemSelectionModel.ClearAndSelect | QtGui.QItemSelectionModel.Rows) self.listView.setFocus() self.plot() self.statusbar.showMessage("Data from {} imported".format(self.data.label), 5000) def contours_color(self): col = QtGui.QColorDialog.getColor() if col.isValid(): self.contcolor.setStyleSheet("background-color: {}".format(col.name())) def step_from_levels(self): if self.setlevels.isChecked(): step = (float(self.levelmax.text()) - float(self.levelmin.text())) / (int(self.levelnum.text()) - 1) self.levelstep.setText(repr(step)) self.props[self.var]['step'] = step def default_var_props(self, var): data = self.data.get_var(var) prop = {} #levels prop['min'] = data.min() prop['max'] = data.max() prop['num'] = 10 prop['step'] = (prop['max'] - prop['min']) / (prop['num'] - 1) prop['levels'] = 'num' prop['type'] = 'linear' #style prop['fill'] = False prop['opacity'] = 100 prop['cmap'] = 'jet' prop['contours'] = 'color' prop['color'] = '#000000' prop['label'] = False #processing prop['resample'] = 1 prop['median'] = 1 prop['gauss'] = 0 prop['clipmin'] = data.min() prop['clipmax'] = data.max() self.props[var] = prop def set_var_props(self, var): #levels self.levelmin.setText(repr(self.props[var]['min'])) self.levelmax.setText(repr(self.props[var]['max'])) self.levelnum.setText(repr(self.props[var]['num'])) self.levelstep.setText(repr(self.props[var]['step'])) if self.props[var]['levels'] == 'num': self.setlevels.setChecked(True) else: self.setstep.setChecked(True) if self.props[var]['type'] == 'linear': self.linlevel.setChecked(True) else: self.cdflevel.setChecked(True) #style if self.props[var]['fill']: self.fillstyle.setChecked(True) else: self.fillstyle.setChecked(False) self.opacity.setValue(self.props[var]['opacity']) self.mapstyle.setCurrentIndex(self.cmaps.index(self.props[var]['cmap'])) self.contcolor.setStyleSheet("background-color: {}".format(self.props[var]['color'])) if self.props[var]['contours'] == 'map': self.contcheckmap.setChecked(True) elif self.props[var]['contours'] == 'color': self.contcheckcolor.setChecked(True) else: self.contchecknone.setChecked(True) if self.props[var]['label']: self.contlabel.setChecked(True) else: self.contlabel.setChecked(False) #processing self.resample.setValue(self.props[var]['resample']) self.filtersize.setValue(self.props[var]['median']) self.filtersigma.setValue(self.props[var]['gauss']) self.clipmin.setText(repr(self.props[var]['clipmin'])) self.clipmax.setText(repr(self.props[var]['clipmax'])) def on_var_changed(self, selected): self.var = self.data.dep[selected.indexes()[0].row()] self.set_var_props(self.var) if self.action3D.isChecked(): self.plot() def apply_props(self): #levels self.props[self.var]['min'] = float(self.levelmin.text()) self.props[self.var]['max'] = float(self.levelmax.text()) self.props[self.var]['num'] = int(self.levelnum.text()) self.props[self.var]['step'] = float(self.levelstep.text()) if self.setlevels.isChecked(): self.props[self.var]['levels'] = 'num' else: self.props[self.var]['levels'] = 'step' if self.linlevel.isChecked(): self.props[self.var]['type'] = 'linear' else: self.props[self.var]['type'] = 'cdf' #style if self.fillstyle.isChecked(): self.props[self.var]['fill'] = True else: self.props[self.var]['fill'] = False self.props[self.var]['opacity'] = self.opacity.value() self.props[self.var]['cmap'] = str(self.mapstyle.currentText()) self.props[self.var]['color'] = str(self.contcolor.palette().color(1).name()) if self.contcheckmap.isChecked(): self.props[self.var]['contours'] = 'map' elif self.contcheckcolor.isChecked(): self.props[self.var]['contours'] = 'color' else: self.props[self.var]['contours'] = '' if self.contlabel.isChecked(): self.props[self.var]['label'] = True else: self.props[self.var]['label'] = False #processing self.props[self.var]['resample'] = self.resample.value() self.props[self.var]['median'] = self.filtersize.value() self.props[self.var]['gauss'] = self.filtersigma.value() self.props[self.var]['clipmin'] = float(self.clipmin.text()) self.props[self.var]['clipmax'] = float(self.clipmax.text()) self.plot() def restore_props(self): self.default_var_props(self.var) self.set_var_props(self.var) self.plot() def edit_options(self): dlg = OptionsForm(self) dlg.exec_() def plotpan(self): self.actionZoom.setChecked(False) self.mpl_toolbar.pan() def plotzoom(self): self.actionPan.setChecked(False) self.mpl_toolbar.zoom() def plotgrid(self): plt.grid() self._canvas.draw() def switch3d(self): if not self.action3D.isChecked(): self._fig.clear() self._ax = self._fig.add_subplot(111) else: self._fig.clear() self._ax = self._fig.add_subplot(111, projection='3d') self.plot() def plot(self): self._ax.cla() if not self.action3D.isChecked(): extent = self.data.get_extent() i = 0 while self._model.item(i): if self._model.item(i).checkState(): CS = None var = str(self._model.item(i).text()) # get data, smooth and clip data = self.data.get_var(var,nan=np.float(self.settings.value("nan", "NaN", type=str))) if self.props[var]['resample'] > 1: data = np.ma.array(ndimage.zoom(data.filled(0), self.props[var]['resample']), mask=ndimage.zoom(data.mask, self.props[var]['resample'], order=0)) if self.props[var]['median'] > 1: data = np.ma.array(ndimage.median_filter(data, size=self.props[var]['median']*self.props[var]['resample']), mask=data.mask) if self.props[var]['gauss'] > 0: data = np.ma.array(ndimage.gaussian_filter(data, sigma=self.props[var]['gauss']*self.props[var]['resample']), mask=data.mask) data = np.ma.masked_outside(data, self.props[var]['clipmin'], self.props[var]['clipmax']) if self.props[var]['fill']: self._ax.imshow(data, interpolation='none', origin='lower', extent=extent, aspect='auto', cmap=plt.get_cmap(self.props[var]['cmap']), alpha=self.props[var]['opacity']/100.0) if self.props[var]['type'] == 'linear': if self.props[var]['levels'] == 'num': clevels = np.linspace(self.props[var]['min'], self.props[var]['max'], self.props[var]['num']) else: # trick to include max in levels clevels = np.arange(self.props[var]['min'], self.props[var]['max'] + 10**np.ceil(np.log10(np.abs(self.props[var]['max']))), self.props[var]['step']) else: # cdf based on histogram binned acording to the Freedman-Diaconis rule v = np.sort(data.compressed()) IQR = v[int(round((v.size-1) * float(0.75)))] - v[int(round((v.size-1) * float(0.25)))] bin_size = 2 * IQR * v.size**(-1.0/3) nbins = int(round(max(self.props[var]['num'], (v[-1]-v[0]) / (bin_size+0.001)))) hist, bin_edges = np.histogram(v, bins=nbins) cdf = np.cumsum(hist) cdfx = np.cumsum(np.diff(bin_edges)) + bin_edges[:2].sum()/2 clevels = np.interp(np.linspace(cdf[0],cdf[-1],self.props[var]['num'] + 2)[1:-1], cdf, cdfx) if self.props[var]['contours'] == 'map': CS = self._ax.contour(self.data.get_xrange(self.props[var]['resample']), self.data.get_yrange(self.props[var]['resample']), data, clevels, cmap=plt.get_cmap(self.props[var]['cmap'])) elif self.props[var]['contours'] == 'color': CS = self._ax.contour(self.data.get_xrange(self.props[var]['resample']), self.data.get_yrange(self.props[var]['resample']), data, clevels, colors=self.props[var]['color']) if self.props[var]['label'] and CS: self._ax.clabel(CS, fontsize=8, inline=1) i += 1 self._ax.axis(extent) plt.title(self.data.label) else: # get data, smooth and clip data = self.data.get_var(self.var) if self.props[self.var]['resample'] > 1: data = np.ma.array(ndimage.zoom(data.filled(0), self.props[self.var]['resample']), mask=ndimage.zoom(data.mask, self.props[self.var]['resample'], order=0)) if self.props[self.var]['median'] > 1: data = np.ma.array(ndimage.median_filter(data, size=self.props[self.var]['median']*self.props[self.var]['resample']), mask=data.mask) if self.props[self.var]['gauss'] > 0: data = np.ma.array(ndimage.gaussian_filter(data, sigma=self.props[self.var]['gauss']*self.props[self.var]['resample']), mask=data.mask) data = np.ma.masked_outside(data, self.props[self.var]['clipmin'], self.props[self.var]['clipmax']) x,y = np.meshgrid(self.data.get_xrange(self.props[self.var]['resample']), self.data.get_yrange(self.props[self.var]['resample'])) self._ax.plot_surface(x, y, data.filled(np.NaN), vmin=data.min(), vmax=data.max(), cmap=plt.get_cmap(self.props[self.var]['cmap']), linewidth=0.5, alpha=self.props[self.var]['opacity']/100.0) self._ax.view_init(azim=235, elev=30) plt.xlabel(self.data.ind[self.data.xvar]['name']) plt.ylabel(self.data.ind[self.data.yvar]['name']) plt.tight_layout() self._canvas.draw()
class Window(QtGui.QWidget): # G2 = nil def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) # self.toolbar.hide() # Just some button self.button = QtGui.QPushButton('Plot') self.button.clicked.connect(self.plot) self.button1 = QtGui.QPushButton('Zoom') self.button1.clicked.connect(self.zoom) self.button2 = QtGui.QPushButton('Pan') self.button2.clicked.connect(self.pan) self.button3 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) self.button4 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) # tabs = QtGui.QTabWidget() # tab1 = QtGui.QWidget() # tab2 = QtGui.QWidget() # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) layout.addWidget(self.button1) layout.addWidget(self.button2) layout.addWidget(self.button3) self.setLayout(layout) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def addData(self, G=None): self.G2 def plot(self): ''' plot some random stuff ''' G = nx.balanced_tree(3, 5) pos = graphviz_layout(G, prog='twopi', args='') # self.plt2.figure(figsize=(8, 8)) nx.draw(G, pos, node_size=100, alpha=0.5, node_color="blue", with_labels=False) # data = [random.random() for i in range(25)] # ax = self.figure.add_subplot(111) # ax.hold(False) # ax.plot(data, '*-') self.canvas.draw() def addData(self, G=None): G2 = G print("G2 is ->", G2)
class Window(Qt.QWidget): def __init__(self): super(Window, self).__init__() self.startButton = Qt.QPushButton() self.startButton.setFixedSize(100, 100) self.startButton.setIcon(Qt.QIcon('Green_Start.png')) self.startButton.setIconSize(Qt.QSize(75, 75)) self.stopButton = Qt.QPushButton() self.stopButton.setFixedSize(100, 100) self.stopButton.setIcon(Qt.QIcon('Red_Stop.png')) self.stopButton.setIconSize(Qt.QSize(75, 75)) self.vidThread = Qt.QThread() self.ardThread = Qt.QThread() self.vidThread.start() self.ardThread.start() self.vidTracking = VideoTracking() self.vidTracking.moveToThread(self.vidThread) self.arduino = Arduino() self.arduino.moveToThread(self.ardThread) self.stopButton.clicked.connect(lambda: self.arduino.stop()) self.stopButton.clicked.connect(lambda: self.vidTracking.stop()) self.startButton.clicked.connect(self.arduino.Run) self.startButton.clicked.connect(self.start_pressed) self.table = Qt.QTableWidget() self.table_rowCount = 0 self.table.setRowCount(self.table_rowCount) self.table.setColumnCount(6) self.table.setHorizontalHeaderLabels([ 'Trial #', 'Date', 'Start Time', 'End Time', 'Duration (sec)', 'Comments' ]) #self.table.horizontalHeader().setResizeMode(Qt.QHeaderView.Stretch) self.table.horizontalHeader().setStretchLastSection(True) self.table.cellChanged.connect(self.cell_was_clicked) boldFont = Qt.QFont() boldFont.setBold(True) label1 = Qt.QLabel("Python Console Output") label1.setFont(boldFont) self.txtEdt1 = Qt.QTextEdit() self.txtEdt1.setReadOnly(True) # Install the custom output stream sys.stdout = EmittingStream(textWritten=self.normalOutputWritten) self.actButton1 = Qt.QPushButton(self.tr("&actButton1")) self.actButton1.setCheckable(True) self.actButton1.toggled.connect( lambda: self.arduino.actButton1(self.actButton1.isChecked())) self.actButton2 = Qt.QPushButton(self.tr("&actButton2")) self.actButton2.setCheckable(True) self.actButton2.toggled.connect( lambda: self.arduino.actButton2(self.actButton2.isChecked())) self.actButton3 = Qt.QPushButton(self.tr("&actButton3")) self.actButton3.setCheckable(True) self.actButton3.toggled.connect( lambda: self.arduino.actButton3(self.actButton3.isChecked())) self.actButton4 = Qt.QPushButton(self.tr("&actButton4")) self.actButton4.setCheckable(True) self.actButton4.toggled.connect( lambda: self.arduino.actButton4(self.actButton4.isChecked())) self.actButton5 = Qt.QPushButton(self.tr("&actButton5")) self.actButton5.setCheckable(True) self.actButton5.toggled.connect( lambda: self.arduino.actButton5(self.actButton5.isChecked())) self.actButton6 = Qt.QPushButton(self.tr("&actButton6")) self.actButton6.setCheckable(True) self.actButton6.toggled.connect( lambda: self.arduino.actButton6(self.actButton6.isChecked())) self.actButton7 = Qt.QPushButton(self.tr("&actButton7")) self.actButton7.setCheckable(True) self.actButton7.toggled.connect( lambda: self.arduino.actButton7(self.actButton7.isChecked())) self.actButton8 = Qt.QPushButton(self.tr("&actButton8")) self.actButton8.setCheckable(True) self.actButton8.toggled.connect( lambda: self.arduino.actButton8(self.actButton8.isChecked())) self.frame4 = Qt.QFrame() self.frame4.setFrameStyle(1) self.frame4.setFixedSize(350, 370) self.arena_setup_new_edit = Qt.QPushButton("New/Edit") self.arena_setup_new_edit.clicked.connect(self.new_edit_arena_setup) self.arena_setup_load = Qt.QPushButton("Load") self.arena_setup_load.clicked.connect(self.load_arena_setup) self.arena_setup_save = Qt.QPushButton("Save") self.arena_setup_save.clicked.connect(self.save_arena_setup) layout6 = Qt.QHBoxLayout() layout6.addWidget(self.arena_setup_new_edit) layout6.addWidget(self.arena_setup_load) layout6.addWidget(self.arena_setup_save) self.main_frame = Qt.QWidget() self.main_frame.setFixedSize(325, 325) self.fig = Figure((5.0, 4.0), dpi=100) self.canvas = FigureCanvas(self.fig) self.canvas.setParent(self.main_frame) self.fig.canvas.mpl_connect("motion_notify_event", self.mouse_movement) self.fig_toolbar = NavigationToolbar(self.canvas, self.main_frame) self.fig_toolbar.hide() self.homeBtn = Qt.QPushButton() self.homeBtn.setFixedSize(25, 25) self.homeBtn.setIcon(Qt.QIcon('home.png')) self.homeBtn.setIconSize(Qt.QSize(20, 20)) self.homeBtn.clicked.connect(self.home) self.panBtn = Qt.QPushButton() self.panBtn.setCheckable(True) self.panBtn.setFixedSize(25, 25) self.panBtn.setIcon(Qt.QIcon('move.png')) self.panBtn.setIconSize(Qt.QSize(20, 20)) self.panBtn.clicked.connect(self.pan) self.zoomBtn = Qt.QPushButton() self.zoomBtn.setCheckable(True) self.zoomBtn.setFixedSize(25, 25) self.zoomBtn.setIcon(Qt.QIcon('zoom_to_rect.png')) self.zoomBtn.setIconSize(Qt.QSize(20, 20)) self.zoomBtn.clicked.connect(self.zoom_to_rect) self.lblsBtn = Qt.QPushButton() self.lblsBtn.setCheckable(True) self.lblsBtn.setFixedSize(25, 25) self.lblsBtn.setIcon(Qt.QIcon('label_icon.png')) self.lblsBtn.setIconSize(Qt.QSize(20, 20)) self.lblsBtn.clicked.connect(self.show_hide_labels) self.drawBtn = Qt.QPushButton() self.drawBtn.setFixedSize(25, 25) self.drawBtn.setIcon(Qt.QIcon('refresh_icon.jpeg')) self.drawBtn.setIconSize(Qt.QSize(20, 20)) self.drawBtn.clicked.connect(self.redraw_arena_setup) self.coords_label = Qt.QLabel() self.coords_label.setAlignment(QtCore.Qt.AlignCenter) self.fig_statusbar = Qt.QStatusBar() self.fig_statusbar.setSizeGripEnabled(False) self.fig_statusbar.addWidget(self.homeBtn) self.fig_statusbar.addWidget(self.panBtn) self.fig_statusbar.addWidget(self.zoomBtn) self.fig_statusbar.addWidget(self.lblsBtn) self.fig_statusbar.addWidget(self.drawBtn) self.fig_statusbar.addWidget(self.coords_label, 1) frame_layout4 = Qt.QVBoxLayout() frame_layout4.addLayout(layout6) frame_layout4.addWidget(self.main_frame) frame_layout4.addWidget(self.fig_statusbar) self.frame4.setLayout(frame_layout4) self.radBtn1 = Qt.QRadioButton( self.tr("Connect to Raspberry Pi Camera")) self.radBtn1.setFont(boldFont) self.radBtn1.setChecked(False) self.radBtn1.toggled.connect(self.connect_to_camera) self.radBtn4 = Qt.QRadioButton(self.tr("Video Record Trial")) self.radBtn4.setChecked(False) self.radBtn4.setDisabled(True) self.radBtn4.toggled.connect(self.video_record_trial) self.lneEdt1 = Qt.QLineEdit() self.lneEdt1.setDisabled(True) self.lneEdt1.setText("example_video_name.mp4") self.lneEdt1.textChanged.connect(self.video_record_trial) self.new_edit1 = Qt.QPushButton("New/Edit") self.new_edit1.clicked.connect(self.new_edit_video_tracking_method) self.new_edit1.setDisabled(True) self.load1 = Qt.QPushButton("Load") self.load1.clicked.connect(self.load_video_tracking_method) self.load1.setDisabled(True) self.save1 = Qt.QPushButton("Save") self.save1.clicked.connect(self.save_video_tracking_method) self.save1.setDisabled(True) butLayout1 = Qt.QHBoxLayout() butLayout1.addWidget(self.new_edit1) butLayout1.addWidget(self.load1) butLayout1.addWidget(self.save1) self.frame1 = Qt.QFrame() self.frame1.setFrameStyle(1) self.frame1.setFixedSize(350, 140) frame_layout1 = Qt.QVBoxLayout() frame_layout1.addWidget(self.radBtn1) frame_layout1.addLayout(butLayout1) frame_layout1.addWidget(self.radBtn4) frame_layout1.addWidget(self.lneEdt1) self.frame1.setLayout(frame_layout1) self.radBtn2 = Qt.QRadioButton(self.tr("Load Video Recording")) self.radBtn2.setFont(boldFont) self.radBtn2.setChecked(False) self.radBtn2.toggled.connect(self.load_video_recording) self.btnLneEdt1 = ButtonLineEdit() self.btnLneEdt1.setReadOnly(True) self.btnLneEdt1.setDisabled(True) self.btnLneEdt1.buttonClicked.connect(self.find_video_recording) self.vid_len_label = Qt.QLabel( "Loaded video length / Trial Runtime (seconds):") self.vid_len_label.setDisabled(True) self.vid_len_spnBox = Qt.QSpinBox() self.vid_len_spnBox.setMaximum(86400) self.vid_len_spnBox.setDisabled(True) vidLenLayout = Qt.QFormLayout() vidLenLayout.addRow(self.vid_len_label, self.vid_len_spnBox) vidLenLayout.setLabelAlignment(QtCore.Qt.AlignRight) self.new_edit2 = Qt.QPushButton("New/Edit") self.new_edit2.clicked.connect(self.new_edit_video_tracking_method) self.new_edit2.setDisabled(True) self.load2 = Qt.QPushButton("Load") self.load2.clicked.connect(self.load_video_tracking_method) self.load2.setDisabled(True) self.save2 = Qt.QPushButton("Save") self.save2.clicked.connect(self.save_video_tracking_method) self.save2.setDisabled(True) butLayout2 = Qt.QHBoxLayout() butLayout2.addWidget(self.new_edit2) butLayout2.addWidget(self.load2) butLayout2.addWidget(self.save2) self.frame2 = Qt.QFrame() self.frame2.setFrameStyle(1) self.frame2.setFixedSize(350, 145) frame_layout2 = Qt.QVBoxLayout() frame_layout2.addWidget(self.radBtn2) frame_layout2.addWidget(self.btnLneEdt1) frame_layout2.addLayout(vidLenLayout) frame_layout2.addLayout(butLayout2) self.frame2.setLayout(frame_layout2) self.radBtn3 = Qt.QRadioButton(self.tr("Connect to Arduino")) self.radBtn3.setFont(boldFont) self.radBtn3.setChecked(False) self.radBtn3.toggled.connect(self.connect_to_arduino) self.new_edit3 = Qt.QPushButton("New/Edit") self.new_edit3.clicked.connect(self.new_edit_ard_method) self.new_edit3.setDisabled(True) self.load3 = Qt.QPushButton("Load") self.load3.clicked.connect(self.load_ard_method) self.load3.setDisabled(True) self.save3 = Qt.QPushButton("Save") self.save3.clicked.connect(self.save_ard_method) self.save3.setDisabled(True) butLayout3 = Qt.QHBoxLayout() butLayout3.addWidget(self.new_edit3) butLayout3.addWidget(self.load3) butLayout3.addWidget(self.save3) self.frame3 = Qt.QFrame() self.frame3.setFrameStyle(1) self.frame3.setFixedSize(350, 80) frame_layout3 = Qt.QVBoxLayout() frame_layout3.addWidget(self.radBtn3) frame_layout3.addLayout(butLayout3) self.frame3.setLayout(frame_layout3) self.group = Qt.QButtonGroup() self.group.addButton(self.radBtn1) self.group.addButton(self.radBtn2) self.group.setExclusive(False) self.lcd = QtGui.QLCDNumber() self.lcd.setFixedSize(140, 40) self.frame6 = Qt.QFrame() self.frame6.setFrameStyle(1) frame_layout6 = Qt.QHBoxLayout() frame_layout6.addWidget(self.lcd) self.frame6.setLayout(frame_layout6) self.timer = QtCore.QTimer(self) self.timer.timeout.connect(self.timer_time) global s, m, h s = 0 m = 0 h = 0 layout = Qt.QGridLayout() layout.addWidget(self.actButton1, 0, 0) layout.addWidget(self.actButton2, 1, 0) layout.addWidget(self.actButton3, 0, 1) layout.addWidget(self.actButton4, 1, 1) layout.addWidget(self.actButton5, 0, 2) layout.addWidget(self.actButton6, 1, 2) layout.addWidget(self.actButton7, 0, 3) layout.addWidget(self.actButton8, 1, 3) layout5 = Qt.QHBoxLayout() layout5.addWidget(self.startButton) layout5.addWidget(self.stopButton) self.frame5 = Qt.QFrame() self.frame5.setFrameStyle(1) frame_layout5 = Qt.QHBoxLayout() frame_layout5.addLayout(layout5) frame_layout5.addLayout(layout) self.frame5.setLayout(frame_layout5) layout1 = Qt.QHBoxLayout() layout1.addWidget(self.frame5) layout1.addWidget(self.frame6) layout2 = Qt.QVBoxLayout() layout2.addLayout(layout1) layout2.addWidget(self.table) layout2.addWidget(label1) layout2.addWidget(self.txtEdt1) layout5 = Qt.QVBoxLayout() layout5.addWidget(self.canvas) layout5.addWidget(self.fig_statusbar) self.main_frame.setLayout(layout5) layout3 = Qt.QVBoxLayout() layout3.addWidget(self.frame4) layout3.addWidget(self.frame1) layout3.addWidget(self.frame2) layout3.addWidget(self.frame3) layout3.addStretch(True) layout4 = Qt.QHBoxLayout() layout4.addLayout(layout3) layout4.addLayout(layout2) self.setLayout(layout4) global global_results, vidTrack_setup_parameters, ard_setup_parameters, arena_setup_parameters, camera, video_name, recording, record_name global_results = {} vidTrack_setup_parameters = None ard_setup_parameters = None arena_setup_parameters = None camera = None video_name = None recording = False record_name = None def __del__(self): # Restore sys.stdout sys.stdout = sys.__stdout__ def normalOutputWritten(self, text): self.txtEdt1.append(text) def cell_was_clicked(self): global global_results try: current_row = self.table.currentRow() current_column = self.table.currentColumn() current_item_text = self.table.currentItem().text() if current_column == 5: global_results[str(current_row + 1)]["trial_info"].update( {"Comments": current_item_text}) except: pass def new_edit_arena_setup(self): global arena_setup_parameters if arena_setup_parameters == None: try: from setup_arena_picture import arena_setup_parameters except: pass self.new_edit_arena = setup_arena_picture.Window( cam=camera, vid_name=video_name, arena_sp=arena_setup_parameters) self.new_edit_arena.show() arena_setup_parameters = None def load_arena_setup(self): try: global arena_setup_parameters name = Qt.QFileDialog.getOpenFileName(self, 'Load Arena Setup') with open(name, 'r') as f: arena_setup_parameters = eval(f.read()) print("loaded arena setup: %s" % (arena_setup_parameters)) except: pass def save_arena_setup(self): global arena_setup_parameters try: try: from setup_arena_picture import arena_setup_parameters except: pass name = Qt.QFileDialog.getSaveFileName(self, 'Save Arena Setup') with open(name, 'w') as text_file: text_file.write(str(arena_setup_parameters)) print("arena setup saved %s" % (arena_setup_parameters)) except: pass def home(self): self.fig_toolbar.home() def pan(self): self.fig_toolbar.pan() def zoom_to_rect(self): self.fig_toolbar.zoom() def show_hide_labels(self): global arena_setup_parameters if self.lblsBtn.isChecked(): # add labels to the grid squares self.grid_labels = [] for j in range(self.num_height_divs): y = self.height_div / 2 + j * self.height_div for i in range(self.num_width_divs): x = self.width_div / 2. + float(i) * self.width_div if arena_setup_parameters['arena_pic_name'] != "no picture": grid_label = self.axes.text(x, y, ("(%d,%d)" % (i, j)), fontsize=6, color='w', ha='center', va='center') else: grid_label = self.axes.text(x, y, ("(%d,%d)" % (i, j)), fontsize=6, color='b', ha='center', va='center') self.grid_labels.append(grid_label) self.canvas.draw() elif not self.lblsBtn.isChecked(): for label in self.grid_labels: label.remove() self.canvas.draw() def redraw_arena_setup(self): global arena_setup_parameters if arena_setup_parameters == None: from setup_arena_picture import arena_setup_parameters self.lblsBtn.setChecked(False) self.arena_pic_name = arena_setup_parameters['arena_pic_name'] try: self.arena_pic = mpimg.imread(self.arena_pic_name) except: pass self.arena_width = arena_setup_parameters['arena_width'] self.arena_height = arena_setup_parameters['arena_height'] self.width_div = arena_setup_parameters['width_div'] self.height_div = arena_setup_parameters['height_div'] self.num_width_divs = int(round(self.arena_width / self.width_div, 0)) self.num_height_divs = int( round(self.arena_height / self.height_div, 0)) self.fig.clear() self.axes = self.fig.add_subplot(111) try: self.axes.imshow(self.arena_pic, origin="lower", extent=(0, self.arena_width, 0, self.arena_height)) except: npArray = np.array([[[0, 0, 0, 0]]], dtype="uint8") self.axes.imshow(npArray, origin="lower", extent=(0, self.arena_width, 0, self.arena_height)) self.axes.set_xticks( np.arange(0, (self.arena_width + self.width_div), self.width_div)) self.axes.set_yticks( np.arange(0, (self.arena_height + self.height_div), self.height_div)) self.axes.tick_params(axis="both", which="major", labelsize="6") self.axes.grid(which="major", axis="both", linestyle='-', color='r') self.axes.xaxis.tick_top() self.axes.invert_yaxis() self.axes.set_xlabel("Arena Width (cm)", fontsize=8) self.axes.set_ylabel("Arena Height (cm)", fontsize=8) self.axes.tick_params(axis="both", which="major", labelsize=6) self.canvas.draw() def mouse_movement(self, event): try: self.coords_label.setText("x=%.3f, y=%.3f" % (event.xdata, event.ydata)) except: if not self.coords_label.text == "": self.coords_label.setText("") else: pass def connect_to_camera(self): global camera, vidTrack_setup_parameters if self.radBtn1.isChecked(): camera = True self.new_edit1.setDisabled(False) self.load1.setDisabled(False) self.save1.setDisabled(False) self.radBtn4.setDisabled(False) self.radBtn2.setChecked(False) #self.load_video_recording() elif not self.radBtn1.isChecked(): camera = None vidTrack_setup_parameters = None self.new_edit1.setDisabled(True) self.load1.setDisabled(True) self.save1.setDisabled(True) self.radBtn4.setDisabled(True) self.lneEdt1.setDisabled(True) def new_edit_video_tracking_method(self): global camera, video_name, vidTrack_setup_parameters if vidTrack_setup_parameters == None: try: from Camera_Wizard_v2 import vidTrack_setup_parameters except: pass self.cwiz = Camera_Wizard_v2.CameraWizard( cam=camera, vid_name=video_name, vidTrack_sp=vidTrack_setup_parameters) self.cwiz.show() vidTrack_setup_parameters = None def load_video_tracking_method(self): try: global vidTrack_setup_parameters name = Qt.QFileDialog.getOpenFileName(self, 'Load Video Tracking Setup') with open(name, 'r') as f: vidTrack_setup_parameters = eval(f.read()) print("loaded video tracking setup: %s" % (vidTrack_setup_parameters)) except: pass def save_video_tracking_method(self): global vidTrack_setup_parameters try: if vidTrack_setup_parameters == None: try: from Camera_Wizard_v2 import vidTrack_setup_parameters except: pass name = Qt.QFileDialog.getSaveFileName(self, 'Save Video Tracking Setup') with open(name, 'w') as text_file: text_file.write(str(vidTrack_setup_parameters)) print("video tracking setup saved %s" % (vidTrack_setup_parameters)) except: pass def video_record_trial(self): global recording, record_name if self.radBtn4.isChecked(): self.lneEdt1.setDisabled(False) recording = True record_name = self.lneEdt1.text() elif not self.radBtn4.isChecked(): self.lneEdt1.setDisabled(True) recording = False record_name = None def load_video_recording(self): global video_name, vidTrack_setup_parameters if self.radBtn2.isChecked(): self.btnLneEdt1.setDisabled(False) self.radBtn4.setChecked(False) self.radBtn4.setDisabled(False) self.radBtn1.setChecked(False) #self.connect_to_camera() elif not self.radBtn2.isChecked(): video_name = None vidTrack_setup_parameters = None self.btnLneEdt1.clear() self.btnLneEdt1.setDisabled(True) self.vid_len_label.setDisabled(True) self.vid_len_spnBox.clear() self.vid_len_spnBox.setDisabled(True) self.new_edit2.setDisabled(True) self.load2.setDisabled(True) self.save2.setDisabled(True) def find_video_recording(self): try: global video_name video_name = Qt.QFileDialog.getOpenFileName( self, 'Find Video Recording') self.btnLneEdt1.setText(video_name) self.vid_len_label.setDisabled(False) self.vid_len_spnBox.setDisabled(False) self.new_edit2.setDisabled(False) self.load2.setDisabled(False) self.save2.setDisabled(False) print("video name: %s" % (video_name)) except: pass def connect_to_arduino(self): global a, ard_setup_parameters if self.radBtn3.isChecked(): try: from nanpy import (SerialManager, ArduinoApi) connection = SerialManager() a = ArduinoApi(connection=connection) self.new_edit3.setDisabled(False) self.load3.setDisabled(False) self.save3.setDisabled(False) except: print("Failed to connect to Arduino") self.radBtn3.setChecked(False) # change back to False elif not self.radBtn3.isChecked(): try: del a except: pass ard_setup_parameters = None self.new_edit3.setDisabled(True) self.load3.setDisabled(True) self.save3.setDisabled(True) def new_edit_ard_method(self): global ard_setup_parameters if ard_setup_parameters == None: try: from Arduino_Wizard_v2 import ard_setup_parameters except: pass self.awiz = Arduino_Wizard_v2.ArduinoWizard( arduino_sp=ard_setup_parameters) self.awiz.show() ard_setup_parameters = None def load_ard_method(self): global ard_setup_parameters try: name = Qt.QFileDialog.getOpenFileName(self, 'Load DAAC setup') with open(name, 'r') as f: ard_setup_parameters = eval(f.read()) print("loaded DAAC setup: %s" % (ard_setup_parameters)) except: pass def save_ard_method(self): global ard_setup_parameters try: if ard_setup_parameters == None: try: from Arduino_Wizard_v2 import ard_setup_parameters except: pass name = Qt.QFileDialog.getSaveFileName(self, 'Save DAAC setup') with open(name, 'w') as text_file: text_file.write(str(ard_setup_parameters)) print("DAAC setup saved %s" % (ard_setup_parameters)) except: pass def timer_start(self): global s, m, h self.timer.start(1000) def timer_time(self): global s, m, h if s < 59: s += 1 else: if m < 59: s = 0 m += 1 elif m == 59 and h < 24: h += 1 m = 0 s = 0 else: self.timer.stop() time = "{0}:{1}:{2}".format(h, m, s) self.lcd.setDigitCount(len(time)) self.lcd.display(time) self.activateWindow() def timer_reset(self): global s, m, h self.timer.stop() s = 0 m = 0 h = 0 time = "{0}:{1}:{2}".format(h, m, s) self.lcd.setDigitCount(len(time)) self.lcd.display(time) def start_pressed(self): global global_results, ard_results, _isRunning2, vidTrack_setup_parameters, ard_setup_parameters date = strftime("%Y-%m-%d") start_time = strftime("%H:%M:%S") self.timer_reset() self.timer_start() if (self.radBtn1.isChecked() or self.radBtn2.isChecked()): trck = self.vidTracking.Run() while _isRunning2: Qt.qApp.processEvents() self.timer.stop() end_time = strftime("%H:%M:%S") self.actButton1.setChecked(False) self.actButton2.setChecked(False) self.actButton3.setChecked(False) self.actButton4.setChecked(False) self.actButton5.setChecked(False) self.actButton6.setChecked(False) self.actButton7.setChecked(False) self.actButton8.setChecked(False) vidTrack_results = {} trial_info = {} try: if (vidTrack_setup_parameters['video_tracking_algorithm'] == "Frame Differencing") or ( vidTrack_setup_parameters['video_tracking_algorithm'] == "MOG"): if self.radBtn1.isChecked() or ( self.radBtn2.isChecked() and (int(self.vid_len_spnBox.value() == 0))): vidTrack_results['run_time'] = trck[2] trial_info['Trial_Duration'] = trck[2][-1] vidTrack_results['vid_pts_time'] = trck[0] elif self.radBtn2.isChecked() and (int( self.vid_len_spnBox.value()) != 0): video_time_calibration_factor = trck[2][-1] / int( self.vid_len_spnBox.value()) vidTrack_results['run_time'] = [] for time in trck[2]: mod_time = round(time / video_time_calibration_factor, 2) vidTrack_results['run_time'].append(mod_time) trial_info['Trial_Duration'] = vidTrack_results[ 'run_time'][-1] vidTrack_results['vid_pts_time'] = [] for time in trck[0]: mod_time = round(time / video_time_calibration_factor, 2) vidTrack_results["vid_pts_time"].append(mod_time) vidTrack_results['position'] = trck[1] elif vidTrack_setup_parameters[ 'video_tracking_algorithm'] == "None": if self.radBtn1.isChecked() or ( self.radBtn2.isChecked() and (int(self.vid_len_spnBox.value()) == 0)): vidTrack_results['run_time'] = trck trial_info['Trial_Duration'] = trck[-1] elif self.radBtn2.isChecked() and (int( self.vid_len_spnBox.value()) != 0): video_time_calibration_factor = ( trck[-1] / int(self.vid_len_spnBox.value())) vidTrack_results['vid_pts_time'] = [] for time in trck[0]: mod_time = round(time / video_time_calibration_factor, 2) vidTrack_results['vid_pts_time'].append(mod_time) trial_info['Trial_Duration'] = vidTrack_results[ 'run_time'][-1] except: pass try: try: duration = str(trial_info['Trial_Duration']) except: duration = str(ard_results['ard_loop_time'][-1]) except: duration = str(0) trial_info["Date"] = date trial_info["Start_Time"] = start_time trial_info["End_Time"] = end_time trial_info["Trial_Duration"] = duration self.table_rowCount += 1 self.table.setRowCount(self.table_rowCount) global_results[str(self.table_rowCount)] = {} global_results[str(self.table_rowCount)]["trial_info"] = trial_info try: global_results[str( self.table_rowCount)]["results"] = vidTrack_results global_results[str( self.table_rowCount)]["results"].update(ard_results) try: ard_results = {} global_results[str( self.table_rowCount)]["results"].update(ard_results) except: pass except: pass self.table.setItem(self.table_rowCount - 1, 0, Qt.QTableWidgetItem(str(self.table_rowCount))) self.table.setItem(self.table_rowCount - 1, 1, Qt.QTableWidgetItem(date)) self.table.setItem(self.table_rowCount - 1, 2, Qt.QTableWidgetItem(start_time)) self.table.setItem(self.table_rowCount - 1, 3, Qt.QTableWidgetItem(end_time)) self.table.setItem(self.table_rowCount - 1, 4, Qt.QTableWidgetItem(duration))
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(1150, 655) MainWindow.setMinimumSize(QtCore.QSize(1500, 250)) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.gridLayout = QtGui.QGridLayout(self.centralwidget) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.pushButton_2 = QtGui.QPushButton(self.centralwidget) self.pushButton_2.setMinimumSize(QtCore.QSize(0, 30)) self.pushButton_2.setMaximumSize(QtCore.QSize(70, 16777215)) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.pushButton_2.setFont(font) self.pushButton_2.setLayoutDirection(QtCore.Qt.RightToLeft) self.pushButton_2.setObjectName(_fromUtf8("pushButton_2")) self.pushButton_2.clicked.connect(self.zoom) ########### zoom 함수 연결 self.gridLayout.addWidget(self.pushButton_2, 2, 1, 1, 1) self.pushButton = QtGui.QPushButton(self.centralwidget) self.pushButton.setMinimumSize(QtCore.QSize(0, 30)) self.pushButton.setMaximumSize(QtCore.QSize(70, 16777215)) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.pushButton.setFont(font) self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) self.pushButton.setObjectName(_fromUtf8("pushButton")) self.pushButton.clicked.connect(self.pan) ###########pan 함수 연결 self.gridLayout.addWidget(self.pushButton, 2, 2, 1, 1) self.pushButton_3 = QtGui.QPushButton(self.centralwidget) self.pushButton_3.setMinimumSize(QtCore.QSize(0, 30)) self.pushButton_3.setMaximumSize(QtCore.QSize(70, 16777215)) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.pushButton_3.setFont(font) self.pushButton_3.setLayoutDirection(QtCore.Qt.RightToLeft) self.pushButton_3.setObjectName(_fromUtf8("pushButton_3")) self.pushButton_3.clicked.connect(self.home) ##########home 함수 연결 self.gridLayout.addWidget(self.pushButton_3, 2, 3, 1, 1) self.frame_4 = QtGui.QFrame(self.centralwidget) self.frame_4.setMinimumSize(QtCore.QSize(150, 0)) self.frame_4.setMaximumSize(QtCore.QSize(16777215, 40)) self.frame_4.setFrameShape(QtGui.QFrame.StyledPanel) self.frame_4.setFrameShadow(QtGui.QFrame.Plain) self.frame_4.setLineWidth(1) self.frame_4.setObjectName(_fromUtf8("frame_4")) self.horizontalLayout = QtGui.QHBoxLayout(self.frame_4) self.horizontalLayout.setContentsMargins(-1, 0, -1, -1) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.label = QtGui.QLabel(self.frame_4) self.label.setMinimumSize(QtCore.QSize(0, 35)) self.label.setMaximumSize(QtCore.QSize(40, 30)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label.setFont(font) self.label.setAlignment(QtCore.Qt.AlignCenter) self.label.setObjectName(_fromUtf8("label")) self.horizontalLayout.addWidget(self.label) self.dateEdit = QtGui.QDateEdit(self.frame_4) self.dateEdit.setMinimumSize(QtCore.QSize(0, 30)) self.dateEdit.setMaximumSize(QtCore.QSize(121, 20)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.dateEdit.setFont(font) self.dateEdit.setAlignment(QtCore.Qt.AlignCenter) self.dateEdit.setObjectName(_fromUtf8("dateEdit")) self.dateEdit.setDateTime( QtCore.QDateTime.currentDateTime()) ########## 현재 날짜로 업데이트 self.dateEdit.setCalendarPopup(True) ########## 캘린더 팝업 self.dateEdit.dateChanged.connect( self.ShowDate) ########## 선택한 날짜로 데이터 업데이트 self.horizontalLayout.addWidget(self.dateEdit) self.label_2 = QtGui.QLabel(self.frame_4) self.label_2.setMinimumSize(QtCore.QSize(0, 35)) self.label_2.setMaximumSize(QtCore.QSize(81, 30)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.label_2.setFont(font) self.label_2.setAlignment(QtCore.Qt.AlignCenter) self.label_2.setObjectName(_fromUtf8("label_2")) self.horizontalLayout.addWidget(self.label_2) self.textEdit = QtGui.QTextEdit(self.frame_4) self.textEdit.setMinimumSize(QtCore.QSize(600, 30)) self.textEdit.setMaximumSize(QtCore.QSize(16777215, 20)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.textEdit.setFont(font) self.textEdit.setFrameShape(QtGui.QFrame.StyledPanel) self.textEdit.setObjectName(_fromUtf8("textEdit")) self.horizontalLayout.addWidget(self.textEdit) self.comboBox = QtGui.QComboBox(self.frame_4) self.comboBox.setMinimumSize(QtCore.QSize(0, 30)) self.comboBox.setMaximumSize(QtCore.QSize(16777215, 20)) font = QtGui.QFont() font.setPointSize(12) font.setBold(True) font.setWeight(75) self.comboBox.setFont(font) self.comboBox.setObjectName(_fromUtf8("comboBox")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.addItem(_fromUtf8("")) self.comboBox.activated.connect(self.convert_utc) self.horizontalLayout.addWidget(self.comboBox) self.gridLayout.addWidget(self.frame_4, 0, 0, 1, 4) self.verticalLayout = QtGui.QVBoxLayout() self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.fig = plt.figure() ########## figure 만들기 self.canvas = FigureCanvas(self.fig) ########## canvas 만들기 self.verticalLayout.addWidget(self.canvas) ########## figure 삽입 self.toolbar = NavigationToolbar(self.canvas, MainWindow) ##########툴바 생성 self.toolbar.hide() ##########툴바 숨김 self.gridLayout.addLayout(self.verticalLayout, 1, 0, 1, 4) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 1150, 21)) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuOpen = QtGui.QMenu(self.menubar) self.menuOpen.setObjectName(_fromUtf8("menuOpen")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.actionFile = QtGui.QAction(MainWindow) self.actionFile.setObjectName(_fromUtf8("actionFile")) self.actionFile.triggered.connect( self.OpenFile) ########## OpenFile 연결 self.actionDirectory = QtGui.QAction(MainWindow) self.actionDirectory.setObjectName(_fromUtf8("actionDirectory")) self.actionDirectory.triggered.connect( self.OpenDirectory) ########## OpenDirectory 연결 self.menuOpen.addAction(self.actionFile) self.menuOpen.addAction(self.actionDirectory) self.menubar.addAction(self.menuOpen.menuAction()) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) self.pushButton_2.setText(_translate("MainWindow", "ZOOM", None)) self.pushButton.setText(_translate("MainWindow", "PAN", None)) self.pushButton_3.setText(_translate("MainWindow", "HOME", None)) self.label.setText(_translate("MainWindow", "Date", None)) self.label_2.setText(_translate("MainWindow", "Duration", None)) self.comboBox.setCurrentIndex(14) self.comboBox.setItemText(0, _translate("MainWindow", "UTC -12:00", None)) self.comboBox.setItemText(1, _translate("MainWindow", "UTC -11:00", None)) self.comboBox.setItemText(2, _translate("MainWindow", "UTC -10:00", None)) self.comboBox.setItemText(3, _translate("MainWindow", "UTC -09:30", None)) self.comboBox.setItemText(4, _translate("MainWindow", "UTC -09:00", None)) self.comboBox.setItemText(5, _translate("MainWindow", "UTC -08:00", None)) self.comboBox.setItemText(6, _translate("MainWindow", "UTC -07:00", None)) self.comboBox.setItemText(7, _translate("MainWindow", "UTC -06:00", None)) self.comboBox.setItemText(8, _translate("MainWindow", "UTC -05:00", None)) self.comboBox.setItemText(9, _translate("MainWindow", "UTC -04:00", None)) self.comboBox.setItemText(10, _translate("MainWindow", "UTC -03:30", None)) self.comboBox.setItemText(11, _translate("MainWindow", "UTC -03:00", None)) self.comboBox.setItemText(12, _translate("MainWindow", "UTC -02:00", None)) self.comboBox.setItemText(13, _translate("MainWindow", "UTC -01:00", None)) self.comboBox.setItemText(14, _translate("MainWindow", "UTC +00:00", None)) self.comboBox.setItemText(15, _translate("MainWindow", "UTC +01:00", None)) self.comboBox.setItemText(16, _translate("MainWindow", "UTC +02:00", None)) self.comboBox.setItemText(17, _translate("MainWindow", "UTC +03:00", None)) self.comboBox.setItemText(18, _translate("MainWindow", "UTC +03:30", None)) self.comboBox.setItemText(19, _translate("MainWindow", "UTC +04:00", None)) self.comboBox.setItemText(20, _translate("MainWindow", "UTC +04:30", None)) self.comboBox.setItemText(21, _translate("MainWindow", "UTC +05:00", None)) self.comboBox.setItemText(22, _translate("MainWindow", "UTC +05:30", None)) self.comboBox.setItemText(23, _translate("MainWindow", "UTC +05:45", None)) self.comboBox.setItemText(24, _translate("MainWindow", "UTC +06:00", None)) self.comboBox.setItemText(25, _translate("MainWindow", "UTC +06:30", None)) self.comboBox.setItemText(26, _translate("MainWindow", "UTC +07:00", None)) self.comboBox.setItemText(27, _translate("MainWindow", "UTC +08:00", None)) self.comboBox.setItemText(28, _translate("MainWindow", "UTC +08:30", None)) self.comboBox.setItemText(29, _translate("MainWindow", "UTC +08:45", None)) self.comboBox.setItemText(30, _translate("MainWindow", "UTC +09:00", None)) self.comboBox.setItemText(31, _translate("MainWindow", "UTC +09:30", None)) self.comboBox.setItemText(32, _translate("MainWindow", "UTC +10:00", None)) self.comboBox.setItemText(33, _translate("MainWindow", "UTC +10:30", None)) self.comboBox.setItemText(34, _translate("MainWindow", "UTC +11:00", None)) self.comboBox.setItemText(35, _translate("MainWindow", "UTC +12:00", None)) self.comboBox.setItemText(36, _translate("MainWindow", "UTC +12:45", None)) self.comboBox.setItemText(37, _translate("MainWindow", "UTC +13:00", None)) self.comboBox.setItemText(38, _translate("MainWindow", "UTC +14:00", None)) self.menuOpen.setTitle(_translate("MainWindow", "Open", None)) self.actionFile.setText(_translate("MainWindow", "File", None)) self.actionDirectory.setText( _translate("MainWindow", "Directory", None)) def convert_utc(self): global utc_timezone temp = self.comboBox.currentText().split(" ")[1] if temp[0] == '-': utc_timezone = float(temp[0:3]) - float(temp[4:6]) / 60 else: utc_timezone = float(temp[0:3]) + float(temp[4:6]) / 60 if time_list is not None: int_time_list = [] del int_time_list[:] for i in time_list: convert_time = self.convert_utc_timezone(i, utc_timezone) if convert_time.find('-') >= 0: temp = convert_time.split('-')[0] + convert_time.split( '-')[1] + convert_time.split('-')[2] int_time_list.append(temp) min_time = min(int_time_list)[0:4] + '/' + min( int_time_list)[4:6] + '/' + min(int_time_list)[6:8] max_time = max(int_time_list)[0:4] + '/' + max( int_time_list)[4:6] + '/' + max(int_time_list)[6:8] self.textEdit.setText(min_time + ' ~ ' + max_time) ###duration 설정 else: pass self.View() def convert_utc_timezone(self, get_time, gap): get_time = get_time.replace("-", " ") get_time = get_time.replace(":", " ") temp = datetime( int(get_time.split(' ')[0]), int(get_time.split(' ')[1]), int(get_time.split(' ')[2]), int(get_time.split(' ')[3]), int(get_time.split(' ')[4]), int(get_time.split(' ')[5]), 0) convert_time = temp + timedelta(hours=gap) return str(convert_time) def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def home(self): self.toolbar.home() def ShowDate(self): date = self.dateEdit.date() string_date = str(date.toPyDate()) Date["year"] = string_date.split('-')[0] Date["month"] = string_date.split('-')[1] Date["day"] = string_date.split('-')[2] self.View() def OpenFile(self): find = ['Onhub', 'Database', 'Amazon Echo'] file_list = [] del file_list[:] #리스트 초기화 del device_list[:] device_list.append('') # y축 한 줄 띄려고 추가 reload(sys) sys.setdefaultencoding('utf-8') FilePath = QtGui.QFileDialog.getOpenFileName() if FilePath: if FilePath[-4:] == '.csv': # 확장자로 csv 파일만 필터링 f = open(FilePath, 'r') first = f.readline().split(',')[0].split('-')[0] if first.split('(')[0] in find: # 분석 대상 파일 필터링 file_list.append(FilePath) device_list.append(first) f.close() self.Analyze_Data(file_list) else: pass self.init_view() def OpenDirectory(self): reload(sys) sys.setdefaultencoding('utf-8') DirPath = str(QtGui.QFileDialog.getExistingDirectory()) if DirPath: self.Directory_Search(DirPath) else: pass self.init_view() def Directory_Search(self, DirPath): find = ['Onhub', 'Database', 'Amazon Echo'] file_list = [] del file_list[:] #리스트 초기화 del device_list[:] device_list.append('') # y축 한 줄 띄려고 추가 for (path, dir, files) in os.walk( unicode(DirPath)): #unicode(DirPath): 한글 경로 가능하게 for filename in files: if filename[-4:] == '.csv': #확장자로 csv 파일만 필터링 f = open(os.path.join(path, filename), 'r') first = f.readline() if first[0:5] == 'Onhub': #분석 대상 파일 필터링 file_list.append(os.path.join(path, filename)) device_list.append(first.split(',')[0].split('-')[0]) elif first[0:8] == 'Database': file_list.append(os.path.join(path, filename)) device_list.append( first.split('_')[0] + '(' + first.split('(')[1].split('-')[0]) elif first[0:11] == 'Amazon Echo': file_list.append(os.path.join(path, filename)) device_list.append(first.split(',')[0].split('-')[0]) f.close() self.Analyze_Data(file_list) def Analyze_Data(self, file_list): empty_list = [] out_data["onhub_disconnect"] = empty_list out_data["onhub_connect"] = empty_list out_data["amazon_echo"] = empty_list out_data["Database"] = empty_list in_data = {} #기기별 모든 데이터가 포함되어 있는 딕셔너리 del time_list[:] index = 1 for i in range(1, len(device_list)): data = self.Read_Data(file_list[i - 1], time_list, index) #모든 데이터 if in_data is None: in_data[device_list[i]] = data else: if device_list[i] in in_data: in_data[device_list[i]] = data else: in_data[device_list[i]] = data index += 1 int_time_list = [] del int_time_list[:] for i in time_list: if i.find('-') >= 0: temp = i.split('-')[0] + i.split('-')[1] + i.split('-')[2] int_time_list.append(temp) min_time = min(int_time_list)[0:4] + '/' + min( int_time_list)[4:6] + '/' + min(int_time_list)[6:8] max_time = max(int_time_list)[0:4] + '/' + max( int_time_list)[4:6] + '/' + max(int_time_list)[6:8] self.textEdit.setText(min_time + ' ~ ' + max_time) ###duration 설정 connect = [] disconnect = [] database = [] echo = [] for key in in_data: if key[0:5] == 'Onhub': temp1 = in_data[key] #temp1은 각 기기별 데이터 리스트들 for temp2 in temp1: #temp2는 temp1의 리스트 하나 if temp2[2] == 'Connected': connect.append(temp2[0] + ' ' + temp2[1] + ' ' + temp2[3] + ' ' + temp2[4]) elif temp2[2] == 'Disconnected': disconnect.append(temp2[0] + ' ' + temp2[1] + ' ' + temp2[3] + ' ' + temp2[4]) else: continue out_data["onhub_connect"] = connect out_data["onhub_disconnect"] = disconnect elif key[0:11] == 'Amazon Echo': temp1 = in_data[key] # temp1은 각 기기별 데이터 리스트들 for temp2 in temp1: # temp2는 temp1의 리스트 하나 echo.append(temp2) out_data["amazon_echo"] = echo elif key[0:8] == 'Database': temp1 = in_data[key] # temp1은 각 기기별 데이터 리스트들 for temp2 in temp1: # temp2는 temp1의 리스트 하나 database.append(temp2) out_data["Database"] = database ###View 함수로 이동 def Read_Data(self, Filepath, time_list, index): global utc_timezone f = open(Filepath, 'r') data_a = csv.reader(f) count = 0 list = [] device_name = 0 for data in data_a: if not data: pass else: if count == 0: if data[0][0:5] == 'Onhub': device_name = data[0].split('-')[0] elif data[0][0:11] == 'Amazon Echo': device_name = data[0].split('-')[0] elif data[0][0:8] == 'Database': device_name = data[0].split( '_')[0] + '(' + data[0].split('(')[1].split('-')[0] temp = QtCore.QString(data[1].split("UTC")[1]) if temp[0] == '-': utc_timezone_temp = float( temp[0:3]) - float(temp[4:6]) / 60 else: utc_timezone_temp = float( temp[0:3]) + float(temp[4:6]) / 60 utc_timezone_dic[device_name] = utc_timezone_temp count = 1 elif data[0].find('Time') >= 0: count = 2 elif count == 2: if data[0] == '="None"': pass else: data.append( device_name) # 기기정보 추가(날짜, 맥주소, 연결/연결해제, 기기정보) data.append(str(index)) list.append(data) if utc_timezone_dic[device_name] == utc_timezone: time_list.append(data[0].split('"')[1].split('"') [0]) # time_list는 시간정보 else: time_temp = data[0].split('"')[1].split('"')[0] time_temp = self.convert_utc_timezone( time_temp, utc_timezone - utc_timezone_dic[device_name]) time_list.append(time_temp) # time_list는 시간정보 f.close() return list def init_view(self): plt.clf() plt.ylim(0, len(device_list)) # y축 최소,최대값 설정 plt.yticks(np.arange(0, len(device_list)), device_list) # y축 눈금 plt.xlim(0, 24) # x축 최소,최대값 설정 plt.xticks(np.arange(0, 25)) # x축 눈금 plt.xlabel('time(hours)') plt.ylabel('devices') plt.title('Result') def View(self): self.init_view() global utc_timezone sc_onhub_connect = [] del sc_onhub_connect[:] sc_onhub_connect_index = [] del sc_onhub_connect_index[:] sc_onhub_disconnect = [] del sc_onhub_disconnect[:] sc_onhub_disconnect_index = [] del sc_onhub_disconnect_index[:] onhub_disconnect_annot.clear onhub_connect_annot.clear sc_Database = [] del sc_Database[:] sc_Database_index = [] del sc_Database_index[:] Database_annot.clear sc_amazon_echo = [] del sc_amazon_echo[:] sc_amazon_echo_index = [] del sc_amazon_echo_index[:] echo_annot.clear if (out_data["onhub_connect"] is '' ) & (out_data["onhub_disconnect"] is '') & ( out_data["Database"] is '') & (out_data["amazon_echo"] is ''): self.canvas.draw() self.clear_view() else: self.annot = plt.annotate("", xy=(0, 0), xytext=(20, 20), textcoords="offset points", bbox=dict(boxstyle="round", fc="w"), arrowprops=dict(arrowstyle="->")) if out_data["onhub_connect"]: sc_onhub_connect_temp = out_data["onhub_connect"] if utc_timezone_dic[sc_onhub_connect_temp[0].split(' ') [3]] == utc_timezone: for i in range(len(sc_onhub_connect_temp)): time = sc_onhub_connect_temp[i].split(' ')[0].split( '"')[1] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = sc_onhub_connect_temp[i].split( ' ')[1].split('"')[0] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2]) / 60) / 60 ) # X축 시간 계산 ##########split 데이터 수정 sc_onhub_connect.append(round(add_data, 4)) index = sc_onhub_connect_temp[i].split(' ')[4] onhub_connect_annot[round( add_data, 4 )] = index + '|' + 'MAC address : ' + sc_onhub_connect_temp[ i].split(' ')[2].split('"')[1].split( '"' )[0] + '\n' + 'time : ' + sc_onhub_connect_temp[ i].split(' ')[0].split( '"')[1] + ' ' + sc_onhub_connect_temp[ i].split(' ')[1].split('"')[ 0] + '\n' + 'Action: Connected' sc_onhub_connect_index.append(int(index)) else: continue else: gap = utc_timezone - utc_timezone_dic[ sc_onhub_connect_temp[0].split(' ')[3]] for i in range(len(sc_onhub_connect_temp)): time_temp = sc_onhub_connect_temp[i].split( '"')[1].split('"')[0] convert_time = self.convert_utc_timezone( time_temp, gap) time = convert_time.split(' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = convert_time.split(' ')[1] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2]) / 60) / 60 ) # X축 시간 계산 ##########split 데이터 수정 sc_onhub_connect.append(round(add_data, 4)) index = sc_onhub_connect_temp[i].split(' ')[4] onhub_connect_annot[round( add_data, 4 )] = index + '|' + 'MAC address : ' + sc_onhub_connect_temp[ i].split(' ')[2].split('"')[1].split( '"' )[0] + '\n' + 'time : ' + convert_time + '\n' + 'Action: Connected' sc_onhub_connect_index.append(int(index)) self.onhub_connect = plt.scatter(sc_onhub_connect, sc_onhub_connect_index, color='R', edgecolors='R', s=50, label='Connected') else: self.onhub_connect = plt.scatter(sc_onhub_connect, sc_onhub_connect_index, color='R', edgecolors='R', s=50) if out_data["onhub_disconnect"]: sc_onhub_disconnect_temp = out_data["onhub_disconnect"] if utc_timezone_dic[sc_onhub_disconnect_temp[0].split(' ') [3]] == utc_timezone: for i in range(len(sc_onhub_disconnect_temp)): time = sc_onhub_disconnect_temp[i].split(' ')[0].split( '"')[1] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = sc_onhub_disconnect_temp[i].split( ' ')[1].split('"')[0] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_onhub_disconnect.append(round(add_data, 4)) index = sc_onhub_disconnect_temp[i].split(' ')[4] sc_onhub_disconnect_index.append(int(index)) onhub_disconnect_annot[round( add_data, 4 )] = index + '|' + 'MAC address : ' + sc_onhub_disconnect_temp[ i].split(' ')[2].split('"')[1].split( '"' )[0] + '\n' + 'time : ' + sc_onhub_disconnect_temp[ i].split(' ')[0].split( '"' )[1] + ' ' + sc_onhub_disconnect_temp[ i].split(' ')[1].split('"')[ 0] + '\n' + 'Action: Disconnected' else: continue else: gap = utc_timezone - utc_timezone_dic[ sc_onhub_disconnect_temp[0].split(' ')[3]] for i in range(len(sc_onhub_disconnect_temp)): time_temp = sc_onhub_disconnect_temp[i].split( '"')[1].split('"')[0] convert_time = self.convert_utc_timezone( time_temp, gap) time = convert_time.split(' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = convert_time.split(' ')[1] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_onhub_disconnect.append(round(add_data, 4)) index = sc_onhub_disconnect_temp[i].split(' ')[4] sc_onhub_disconnect_index.append(int(index)) onhub_disconnect_annot[round( add_data, 4 )] = index + '|' + 'MAC address : ' + sc_onhub_disconnect_temp[ i].split(' ')[2].split('"')[1].split( '"' )[0] + '\n' + 'time : ' + convert_time + '\n' + 'Action: Disconnected' self.onhub_disconnect = plt.scatter(sc_onhub_disconnect, sc_onhub_disconnect_index, marker='X', color='k', label='Disconnected') else: self.onhub_disconnect = plt.scatter(sc_onhub_disconnect, sc_onhub_disconnect_index, marker='X', color='k') if out_data["amazon_echo"]: sc_amazon_echo_temp = out_data["amazon_echo"] if utc_timezone_dic[sc_amazon_echo_temp[0][3]] == utc_timezone: for i in range(len(sc_amazon_echo_temp)): time = sc_amazon_echo_temp[i][0].split('"')[1].split( ' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = sc_amazon_echo_temp[i][0].split( ' ')[1].split('"')[0] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_amazon_echo.append(round(add_data, 4)) index = sc_amazon_echo_temp[i][4] sc_amazon_echo_index.append(int(index)) echo_annot[round( add_data, 4 )] = 'File name : ' + sc_amazon_echo_temp[i][ 1] + '\n' + 'time : ' + sc_amazon_echo_temp[i][ 0].split('"')[1].split( '"' )[0] + '\n' + 'command : ' + sc_amazon_echo_temp[ i][2] else: continue else: gap = utc_timezone - utc_timezone_dic[ sc_amazon_echo_temp[0][3]] for i in range(len(sc_amazon_echo_temp)): time_temp = sc_amazon_echo_temp[i][0].split( '"')[1].split('"')[0] convert_time = self.convert_utc_timezone( time_temp, gap) time = convert_time.split(' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = convert_time.split(' ')[1] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_amazon_echo.append(round(add_data, 4)) index = sc_amazon_echo_temp[i][4] sc_amazon_echo_index.append(int(index)) echo_annot[round( add_data, 4 )] = 'File name : ' + sc_amazon_echo_temp[i][ 1] + '\n' + 'time : ' + convert_time + '\n' + 'command : ' + sc_amazon_echo_temp[ i][2] self.amazon_echo = plt.scatter(sc_amazon_echo, sc_amazon_echo_index, marker='*', color='b', label='Command Event') else: self.amazon_echo = plt.scatter(sc_amazon_echo, sc_amazon_echo_index, marker='*', color='b') if out_data["Database"]: sc_Database_temp = out_data["Database"] if utc_timezone_dic[sc_Database_temp[0][2]] == utc_timezone: for i in range(len(sc_Database_temp)): time = sc_Database_temp[i][0].split('"')[1].split( ' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = sc_Database_temp[i][0].split(' ')[1].split( '"')[0] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_Database.append(round(add_data, 4)) index = sc_Database_temp[i][3] sc_Database_index.append(int(index)) Database_annot[round( add_data, 4)] = 'File name : ' + sc_Database_temp[i][ 1] + '\n' + 'time : ' + sc_Database_temp[ i][0].split('"')[1].split('"')[ 0] + '\n' + 'Action: File Modified' else: continue else: gap = utc_timezone - utc_timezone_dic[sc_Database_temp[0] [2]] for i in range(len(sc_Database_temp)): time_temp = sc_Database_temp[i][0].split('"')[1].split( '"')[0] convert_time = self.convert_utc_timezone( time_temp, gap) time = convert_time.split(' ')[0] if (Date["year"] == time.split('-')[0]) & ( Date["month"] == time.split('-')[1]) & ( Date["day"] == time.split('-')[2]): time2 = convert_time.split(' ')[1] add_data = float(time2.split(":")[0]) + ( float(time2.split(":")[1]) / 60) + ( (float(time2.split(":")[2].split(".")[0]) / 60) / 60) # X축 시간 계산 sc_Database.append(round(add_data, 4)) index = sc_Database_temp[i][3] sc_Database_index.append(int(index)) Database_annot[round( add_data, 4 )] = 'File name : ' + sc_Database_temp[i][ 1] + '\n' + 'time : ' + convert_time + '\n' + 'Action: File Modified' self.Database = plt.scatter(sc_Database, sc_Database_index, marker='<', color='g', label='File Modified') else: self.Database = plt.scatter(sc_Database, sc_Database_index, marker='<', color='g') plt.legend(loc='best') self.annot.set_visible(False) self.canvas.draw() self.canvas.mpl_connect("motion_notify_event", self.event) def event(self, event): if event.inaxes is not None: if self.onhub_connect.contains(event)[0] is True: onhub_connect_x, onhub_connect_index = self.onhub_connect.contains( event) self.update_connect_onhub(onhub_connect_index) self.annot.set_visible(True) event.canvas.draw() elif self.onhub_disconnect.contains(event)[0] is True: onhub_disconnect_x, onhub_disconnect_index = self.onhub_disconnect.contains( event) self.update_disconnect_onhub(onhub_disconnect_index) self.annot.set_visible(True) event.canvas.draw() elif self.amazon_echo.contains(event)[0] is True: amazon_echo_x, amazon_echo_index = self.amazon_echo.contains( event) self.update_amazon_echo(amazon_echo_index) self.annot.set_visible(True) event.canvas.draw() elif self.Database.contains(event)[0] is True: Database_x, Database_index = self.Database.contains(event) self.updat_database(Database_index) self.annot.set_visible(True) event.canvas.draw() else: self.annot.set_visible(False) self.canvas.draw_idle() def updat_database(self, ind): pos = self.Database.get_offsets()[ind["ind"][0]] self.annot.xy = pos text = Database_annot[pos[0]] self.annot.set_text(text) def update_amazon_echo(self, ind): pos = self.amazon_echo.get_offsets()[ind["ind"][0]] self.annot.xy = pos text = echo_annot[pos[0]] self.annot.set_text(text) def update_connect_onhub(self, ind): pos = self.onhub_connect.get_offsets()[ind["ind"][0]] self.annot.xy = pos text = onhub_connect_annot[pos[0]] if int(text.split('|')[0]) == pos[1]: self.annot.set_text(text.split('|')[1]) else: pass def update_disconnect_onhub(self, ind): pos = self.onhub_disconnect.get_offsets()[ind["ind"][0]] self.annot.xy = pos text = onhub_disconnect_annot[pos[0]] if int(text.split('|')[0]) == pos[1]: self.annot.set_text(text.split('|')[1]) else: pass
class PlotCanvasWithToolbar(PlotFigure, QWidget): def __init__(self, parent=None): PlotFigure.__init__(self) QWidget.__init__(self, parent) self.canvas = FigureCanvas(self.fig) self.canvas.mpl_connect('draw_event', self.on_draw) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.pan() # Pan by default vbox = QVBoxLayout(self) vbox.addWidget(self.canvas) vbox.addWidget(self.toolbar) self.setLayout(vbox) def setupLockButtons(self, layout): self.x_locked = QtWidgets.QPushButton(u"Lock X", self) self.x_locked.setCheckable(True) layout.addWidget(self.x_locked) self.x_locked.toggled.connect(self.x_locked_changed) self.x_limits = None self.y1_locked = QtWidgets.QPushButton(u"Lock Y1", self) self.y1_locked.setCheckable(True) layout.addWidget(self.y1_locked) self.y1_locked.toggled.connect(self.y1_locked_changed) self.y1_limits = None self.y2_locked = QtWidgets.QPushButton(u"Lock Y2", self) self.y2_locked.setCheckable(True) layout.addWidget(self.y2_locked) self.y2_locked.toggled.connect(self.y2_locked_changed) self.y2_limits = None def axesDialog(self): SimpleAxesDialog(self).exec_() def on_draw(self, event): pass def draw(self): self.canvas.toolbar.update( ) # drop history of Home, Forward and Back buttons in the navigation toolbar PlotFigure.draw(self, self.x_limits, self.y1_limits, self.y2_limits) self.canvas.draw() def _y_lock_changed(self, name, cbox, get_lim): if cbox.isChecked(): cbox.setText(u"Lock {}".format(name)) return get_lim() else: cbox.setText(u"Lock {}".format(name)) return None def x_locked_changed(self, status): self.x_limits = self._y_lock_changed("X", self.x_locked, self.axes.get_xlim) def y1_locked_changed(self, status): self.y1_limits = self._y_lock_changed("Y1", self.y1_locked, self.axes.get_ylim) def y2_locked_changed(self, status): self.y2_limits = self._y_lock_changed("Y2", self.y2_locked, self.axes2.get_ylim)
def pan(self): if self._active != 'PAN': self.toogle_off_all_active() NavigationToolbar.pan(self)
class Window(QtGui.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.setAcceptDrops(True) self.figure = plt.figure() # --- Just for fun lets start with nice picture img = mpimg.imread('./bq_t4_sys/thor.png') ax = plt.Axes(self.figure,[0.,0.,1.,1.]) ax.set_axis_off() self.figure.add_axes(ax) plt.imshow(img,cmap=cm.get_cmap('gray')) # --------------------------------------------- self.canvas = FigureCanvas(self.figure) # --------------------------------------------- self.toolbar = NavigationToolbar(self.canvas, self) # --------------------------------------------- self.slider = QtGui.QSlider(orientation=Qt.Qt.Horizontal) self.slider.setTickInterval(1) self.slider.valueChanged.connect(self.plot) # ---------------------------------------------- self.view_combo = QtGui.QComboBox(self) self.view_combo.activated[str].connect(self.changeView) self.view_combo.addItem('X-Y') self.view_combo.addItem('X-Z') self.view_combo.addItem('Y-Z') self.view = 'X-Y' self.slide_dimension = 2 # will slide by default though z self.combo = QtGui.QComboBox(self) self.combo.activated[str].connect(self.comboActivated) # -- check box self.hbox = QtGui.QHBoxLayout() # self.hbox.addStretch(1) self.back_button = QtGui.QPushButton('<',self) self.back_button.clicked.connect(self.goBack) self.next_button = QtGui.QPushButton('>',self) self.next_button.clicked.connect(self.goNext) self.check_abs = QtGui.QCheckBox('Absolute') # self.check_abs.toggle() self.check_abs.stateChanged.connect(self.plot) self.check_bw = QtGui.QCheckBox('B&W') # self.check_bw.toggle() self.check_bw.stateChanged.connect(self.plot) self.check_log = QtGui.QCheckBox('Log') # self.check_log.toggle() self.check_log.stateChanged.connect(self.plot) self.check_si = QtGui.QCheckBox('CGS Units') self.check_si.toggle() self.check_si.stateChanged.connect(self.plot) self.check_aux = QtGui.QCheckBox('No AUX') self.check_aux.toggle() self.check_aux.stateChanged.connect(self.reset_bifrost_obj) self.hbox.addWidget(self.check_si) self.hbox.addWidget(self.check_abs) self.hbox.addWidget(self.check_log) self.hbox.addWidget(self.check_bw) self.hbox.addWidget(self.check_aux) self.hbox.addWidget(self.back_button) self.hbox.addWidget(self.next_button) self.hbox.addWidget(self.combo) self.hbox.addWidget(self.view_combo) # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addLayout(self.hbox) layout.addWidget(self.canvas) layout.addWidget(self.slider) self.setLayout(layout) # actual data stuff self.fpath = first_file_name # self.data = np.einsum('ijk->kji', self.data) self.tag = 'r' if (first_file_name != "no_file"): self.param = get_bifrost_param(self.fpath,0) self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0, self.check_aux.isChecked()) self.data = self.b.getvar(self.tag) self.slide_dimension = 2 self.slider.setMinimum(0) self.slider.setMaximum(self.data.shape[self.slide_dimension]-1) if (first_slice != -1): self.slider.setValue(first_slice) if (first_depth != -1000.0): self.slider.setValue(np.argmax( self.b.z >= first_depth )) if self.slider.value() >= self.data.shape[self.slide_dimension]: self.slider.setValue(self.data.shape[self.slide_dimension]-1) elif self.slider.value() < 0: self.slider.setValue(0) self.setCombo() self.plot() else: print "\t[!] Drag & Drop a snap file to plot its content" def keyPressEvent(self, event): key = event.key if key == Qt.Qt.Key_Right: self.slider.setValue(self.slider.value() + 1) elif key == Qt.Qt.Key_Left: self.slider.setValue(self.slider.value() - 1) def goBack(self): self.param = get_bifrost_param(self.fpath,-1) self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,-1, self.check_aux.isChecked()) self.get_data() self.plot() where_str, base_name, snap_n = process_file_name(self.fpath) snap_n = str(int(snap_n) - 1) self.fpath = where_str + base_name + '_' + snap_n + '.snap' pass def goNext(self): self.param = get_bifrost_param(self.fpath,1) self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,1,self.check_aux.isChecked()) self.get_data() self.plot() where_str, base_name, snap_n = process_file_name(self.fpath) snap_n = str(int(snap_n) + 1) self.fpath = where_str + base_name + '_' + snap_n + '.snap' pass def setCombo(self): self.combo.clear() for tag in self.b.snapvars: self.combo.addItem(tag) if not self.check_aux.isChecked(): for tag in self.b.auxvars: self.combo.addItem(tag) def changeView(self, text): self.view = text self.get_data() self.plot() print 'View changed to: ', self.view def comboActivated(self, text): self.tag = text self.data = self.b.getvar(self.tag) self.plot() def reset_bifrost_obj(self): self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0,self.check_aux.isChecked()) print self.b.snapvars self.get_data() def get_data(self): self.data = self.b.getvar(self.tag) if self.view == 'X-Y': self.slide_dimension = 2 elif self.view == 'X-Z': self.slide_dimension = 1 elif self.view == 'Y-Z': self.slide_dimension = 0 self.slider.setMinimum(0) self.slider.setMaximum(self.data.shape[self.slide_dimension]-1) if self.slider.value() >= self.data.shape[self.slide_dimension]: self.slider.setValue(self.data.shape[self.slide_dimension]-1) elif self.slider.value() < 0: self.slider.setValue(0) self.setCombo() def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def plot(self): plt.clf() ax = self.figure.add_subplot(111) slice_str = '[?]' # extension = [] if self.view == 'X-Y': image = self.data[:,:,self.slider.value()] slice_str = 'z = %f ' % self.b.z[self.slider.value()] ax.set_ylabel('y-direction') ax.set_xlabel('x-direction') # extension = [0, self.param['mx'], 0, self.param['my']] elif self.view == 'X-Z': image = self.data[:,self.slider.value(),:] slice_str = 'y = %f ' % self.b.y[self.slider.value()] ax.set_ylabel('z-direction') ax.set_xlabel('x-direction') # extension = [0, self.param['mx'], 0, self.param['mz']] elif self.view == 'Y-Z': image = self.data[self.slider.value(),:,:] slice_str = 'x = %f ' % self.b.x[self.slider.value()] ax.set_ylabel('z-direction') ax.set_xlabel('y-direction') # extension = [0, self.param['my'], 0, self.param['mz']] # image = np.fliplr(image) # image = np.rot90(image,k=3) label = "Value" color = cm.get_cmap('jet') ax.set_title("[%s] %s (Snap: %s) for %s \n[time: %s]" % (self.tag, self.base_name, self.snap_n, slice_str, str(datetime.timedelta(seconds=self.param['t']*self.param['u_t'])))) # ax.xaxis.set_major_locator(ticker.MultipleLocator(int(64))) # ax.yaxis.set_major_locator(ticker.MultipleLocator(int(64))) if self.check_si.isChecked(): if self.tag == 'r': image = image * self.param['u_r'] unit_label = "[g/cm3]" label = "Value %s" % unit_label elif (self.tag == 'bx' or self.tag == 'by' or self.tag == 'bz'): image = image * self.param['u_b'] unit_label = "[G]" label = "Value %s" % unit_label elif (self.tag == 'px' or self.tag == 'py' or self.tag == 'pz'): image = image * self.param['u_p'] unit_label = "[Ba]" label = "Value %s" % unit_label elif self.tag == 'e': image = image * self.param['u_e'] unit_label = "[erg]" label = "Value %s" % unit_label if self.check_abs.isChecked(): image = np.absolute(image) label = "ABS( %s )" % label if self.check_log.isChecked(): image = np.log10(image) label = "Log10( %s )" % label if self.check_bw.isChecked(): # color = cm.get_cmap('gist_yarg') color = cm.get_cmap('Greys_r') # Mats favorite color palette if self.view == 'X-Y': ax.set_ylabel('y-direction [Mm]') ax.set_xlabel('x-direction [Mm]') im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.x.min(),self.b.x.max(),self.b.y.min(),self.b.y.max()), cmap=color) im.set_data(self.b.x, self.b.y, np.fliplr(zip(*image[::-1]))) ax.images.append(im) ax.set_xlim(self.b.x.min(),self.b.x.max()) ax.set_ylim(self.b.y.min(),self.b.y.max()) ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4))) ax.yaxis.set_major_locator(ticker.MultipleLocator(int(4))) elif self.view == 'X-Z': ax.set_ylabel('z-direction [Mm]') ax.set_xlabel('x-direction [Mm]') im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.x.min(),self.b.x.max(),self.b.z.min(),self.b.z.max()), cmap=color) im.set_data(self.b.x, self.b.z[::-1], np.flipud(np.fliplr(zip(*image[::-1])))) ax.images.append(im) ax.set_xlim(self.b.x.min(),self.b.x.max()) ax.set_ylim(self.b.z.max(),self.b.z.min()) ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4))) ax.yaxis.set_major_locator(ticker.MultipleLocator(int(2))) elif self.view == 'Y-Z': ax.set_ylabel('z-direction [Mm]') ax.set_xlabel('y-direction [Mm]') im = NonUniformImage(ax, interpolation='bilinear', extent=(self.b.y.min(),self.b.y.max(),self.b.z.min(),self.b.z.max()), cmap=color) im.set_data(self.b.y, self.b.z[::-1], np.flipud(np.fliplr(zip(*image[::-1])))) ax.images.append(im) ax.set_xlim(self.b.y.min(),self.b.y.max()) ax.set_ylim(self.b.z.max(),self.b.z.min()) ax.xaxis.set_major_locator(ticker.MultipleLocator(int(4))) ax.yaxis.set_major_locator(ticker.MultipleLocator(int(2))) # im = ax.imshow(image, interpolation='none', origin='lower', cmap=color, extent=extension) # ax.text(0.025, 0.025, (r'$\langle B_{z} \rangle = %2.2e$'+'\n'+r'$\langle |B_{z}| \rangle = %2.2e$') % (np.average(img),np.average(np.absolute(img))), ha='left', va='bottom', transform=ax.transAxes) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(im, cax=cax,label=label) self.canvas.draw() def dragEnterEvent(self, event): if event.mimeData().hasUrls(): event.accept() else: event.ignore() def dropEvent(self, event): for url in event.mimeData().urls(): path = url.toLocalFile().toLocal8Bit().data() if os.path.isfile(path): self.fpath = path self.param = get_bifrost_param(self.fpath,0) self.b, self.base_name, self.snap_n = get_bifrost_obj(self.fpath,0, self.check_aux.isChecked()) self.get_data() self.plot()
def pan(self): NavigationToolbar.pan(self) self.mode = "" #<--- whatever you want to replace "pan/zoom" goes here self.set_message(self.mode)
class MainWindow(QtGui.QMainWindow, mw.Ui_MainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.datalst = [] self.modellst = [] self.lstdatamodel = QtGui.QStandardItemModel(self.listView) self.listView.setModel(self.lstdatamodel) self.current_lst_index = -1 self.addButton.clicked.connect(self.add) self.removeButton.clicked.connect(self.remove) self.actionCalcLSSParameter.triggered.connect(self.calculatelss) self.actionAutomaticElutionWindowStretching.triggered.connect(self.calcautelwindowstretch) self.actionSelectivityMap.triggered.connect(self.pltselectivitymap) self.actionResolutionMap.triggered.connect(self.pltresolutionmap) self.actionAbout.triggered.connect(self.about) self.actionQuit.triggered.connect(self.quit) self.listView.clicked.connect(self.viewmatrix) self.toolBox.currentChanged.connect(self.viewmatrix) self.zoomButton.clicked.connect(self.zoom) self.panButton.clicked.connect(self.pan) self.rescaleButton.clicked.connect(self.home) self.modelBox.currentIndexChanged.connect(self.gradientanalyser) self.doubleSpinBox_1.valueChanged.connect(self.gradientanalyser) self.doubleSpinBox_2.valueChanged.connect(self.gradientanalyser) self.doubleSpinBox_3.valueChanged.connect(self.gradientanalyser) self.doubleSpinBox_4.valueChanged.connect(self.gradientanalyser) self.doubleSpinBox_5.valueChanged.connect(self.gradientanalyser) self.ColumnLenghtSpinBox.valueChanged.connect(self.gradientanalyser) self.CulumnDiameterSpinBox.valueChanged.connect(self.gradientanalyser) self.ColumnPorositySpinBox.valueChanged.connect(self.gradientanalyser) # Add plot self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() # set the layout layout_chormatogram = QtGui.QVBoxLayout() layout_chormatogram.addWidget(self.canvas) self.plotterBox.setLayout(layout_chormatogram) # Add selectivity map plot #self.figure_smap = plt.figure() #self.canvas_smap = FigureCanvas(self.figure_smap) #self.toolbar_smap = NavigationToolbar(self.canvas_smap, self) #self.toolbar_smap.hide() #layout_smap = QtGui.QVBoxLayout() #layout_smap.addWidget(self.canvas_smap) #self.plotterBox_2.setLayout(layout_smap) self.tablemodel = TableModel(self) self.tableView.setModel(self.tablemodel) self.tableView.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.tableView.customContextMenuRequested.connect(self.openTableMenu) # constant parameters self.crit_resolution = 1.8 self.crit_alpha = 1.1 def openTableMenu(self, position): """ context menu event """ menu = QtGui.QMenu(self) exportAction = menu.addAction("Export table as CSV") action = menu.exec_(self.tableView.viewport().mapToGlobal(position)) if action == exportAction: fname = QtGui.QFileDialog.getSaveFileName(self, "Save File", "CSV (*.csv)"); #fname = QtGui.getSaveFileName.getOpenFileName(self, tr('Save File'), ) self.tablemodel.SaveTable(fname) else: return return def keyPressEvent(self, e): if (e.modifiers() & QtCore.Qt.ControlModifier): if e.key() == QtCore.Qt.Key_C: #copy if len(self.tableView.selectionModel().selectedIndexes()) > 0: previous = self.tableView.selectionModel().selectedIndexes()[0] columns = [] rows = [] for index in self.tableView.selectionModel().selectedIndexes(): if previous.column() != index.column(): columns.append(rows) rows = [] rows.append(str(index.data().toPyObject())) previous = index columns.append(rows) # add rows and columns to clipboard clipboard = "" nrows = len(columns[0]) ncols = len(columns) for r in xrange(nrows): for c in xrange(ncols): clipboard += columns[c][r] if c != (ncols-1): clipboard += '\t' clipboard += '\n' # copy to the system clipboard sys_clip = QtGui.QApplication.clipboard() sys_clip.setText(clipboard) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def plotchromatogram(self): ''' plot some random stuff ''' data = [random.random() for i in range(25)] ax = self.figure.add_subplot(111) ax.hold(False) ax.plot(data, '*-') self.canvas.draw() def add(self): idialog = ImportDialog() if idialog.exec_() == 1: [name, molname, trdata, grad, tg, td, t0, flow, c_length, c_diameter, c_particle] = idialog.getdata() self.datalst.append(Data(name, molname, trdata, grad, tg, td, t0, flow, c_length, c_diameter, c_particle)) self.lstdatamodel.appendRow(QtGui.QStandardItem(name)) def remove(self): if self.current_lst_index >= 0 and self.current_lst_index < len(self.datalst): del self.datalst[self.current_lst_index] self.lstdatamodel.removeRow(self.current_lst_index) def viewmatrix(self, indx): if self.toolBox.currentIndex() == 0: if indx: self.current_lst_index = indx.row() del self.tablemodel.arraydata[:] del self.tablemodel.header[:] self.tablemodel.clean() self.tableView.model().layoutChanged.emit() molname = self.datalst[self.current_lst_index].molname trdata = self.datalst[self.current_lst_index].trdata grad = self.datalst[self.current_lst_index].grad tg = self.datalst[self.current_lst_index].tg header = ["Molecule"] for j in range(len(tg)): header.append(str("%.1f%% %.1f%% %.1f min" % (round(grad[j][0]*100,1), round(grad[j][1]*100,1), tg[j]))) self.tablemodel.setHeader(header) for i in range(len(trdata)): row = [molname[i]] for j in range(len(trdata[i])): row.append(round(trdata[i][j], 2)) self.tablemodel.addRow(row) self.tableView.model().layoutChanged.emit() else: del self.tablemodel.arraydata[:] del self.tablemodel.header[:] self.tablemodel.clean() self.tableView.model().layoutChanged.emit() self.gradientanalyser() def about(self): adialog = AboutDialog() adialog.exec_() def quit(self): QtGui.QApplication.quit() def calculatelss(self): items = [] lstmodel = self.listView.model() for index in range(lstmodel.rowCount()): item = lstmodel.item(index) items.append(item.text()) runlss = ComputeLSS(items) if runlss.exec_() == 1: [indx, modelname] = runlss.getdata() t0 = self.datalst[indx].t0 v_d = self.datalst[indx].vd flow = self.datalst[indx].flow lssmol = SSGenerator(None, None, None, t0, v_d, flow) self.modellst.append(Model()) self.modellst[-1].modname = modelname self.modellst[-1].molname = self.datalst[indx].molname self.modellst[-1].flow = self.datalst[indx].flow self.modellst[-1].c_length = self.datalst[indx].c_length self.modellst[-1].c_diameter = self.datalst[indx].c_diameter self.modellst[-1].c_particle = self.datalst[indx].c_particle self.modelBox.addItem(modelname) tg = self.datalst[indx].tg init_B = [] final_B = [] for i in range(len(tg)): init_B.append(self.datalst[indx].grad[i][0]) final_B.append(self.datalst[indx].grad[i][1]) self.modellst[-1].v_d = v_d self.modellst[-1].v_m = t0 * flow for row in self.datalst[indx].trdata: lss_logkw, lss_s = lssmol.getlssparameters(row, tg, init_B, final_B) self.modellst[-1].lss.append([lss_logkw, lss_s]) if len(self.modellst) == 1: self.gradientanalyser() def calcautelwindowstretch(self): aws = AutomaticElutionWindowStretching(self.modellst) aws.exec_() def pltselectivitymap(self): smap = PlotMaps(self.modellst, "sel") smap.exec_() def pltresolutionmap(self): rsmap = PlotMaps(self.modellst, "res") rsmap.exec_() def gradientanalyser(self): indx = self.modelBox.currentIndex() del self.tablemodel.arraydata[:] del self.tablemodel.header[:] self.tablemodel.clean() header = ["Molecule", "log kW", "S", "tR"] self.tablemodel.setHeader(header) self.tableView.model().layoutChanged.emit() if indx >= 0 and indx < len(self.modellst): #predict the retention time for each compound molname = [name for name in self.modellst[indx].molname] lss = self.modellst[indx].lss flow_sofware = float(self.doubleSpinBox_1.value()) init_B_soft = float(self.doubleSpinBox_2.value())/100. final_B_soft = float(self.doubleSpinBox_3.value())/100. tg_soft = float(self.doubleSpinBox_4.value()) c_length = self.ColumnLenghtSpinBox.value() c_diameter = self.CulumnDiameterSpinBox.value() c_particle = self.ColumnPorositySpinBox.value() t0_soft = 0. td_soft = 0. v_m = None v_d = float(self.doubleSpinBox_5.value()) #if c_length > 0 and c_diameter > 0 and c_porosity > 0: # v_m = ((square(self.c_diameter)*self.c_length*pi*self.c_porosity)/4.)/1000. #else: v_m = self.modellst[indx].v_m t0_soft = float(v_m/flow_sofware) td_soft = float(v_d/flow_sofware) A = 1.0 #N = (c_length*10000.)/(3.4*c_particle) trtab = [] lssmol = SSGenerator(None, None, None, t0_soft, float(self.modellst[indx].v_d), flow_sofware) i = 0 trlst = [] for row in lss: lss_logkw = float(row[0]) lss_s = float(row[1]) W = get_lss_peak_width(c_length, c_particle, lss_logkw, lss_s, init_B_soft, final_B_soft, tg_soft, flow_sofware, self.modellst[indx].v_m, self.modellst[indx].v_d, None) tr = lssmol.rtpred(lss_logkw, lss_s, tg_soft, init_B_soft, final_B_soft, t0_soft, td_soft) if tr < t0_soft: trtab.append([t0_soft, A, W]) else: trtab.append([tr, A, W]) trlst.append([round(trtab[-1][0], 2), W, molname[i]]) row = [molname[i], round(lss_logkw, 3), round(lss_s, 3), round(trtab[-1][0],2)] self.tablemodel.addRow(row) self.tableView.model().layoutChanged.emit() i += 1 # Calculate the critical resolution trlst = sorted(trlst, key=lambda x:x[0]) # get min and max time tr_min = tr_max = 0. if len(trlst) > 0: tr_min = trlst[0][0] tr_max = trlst[-1][0] # calculate resolution and critical couple # get the peak width at base multiplying by 1.7 self.plainTextEdit.clear() text = "Critical couples:\n" self.plainTextEdit.appendPlainText(text) crit_trtab = [] crit_molname = [] ncc = 0 for i in range(1, len(trlst)): width1 = trlst[i][1] * 1.7 width2 = trlst[i-1][1] * 1.7 tr1 = trlst[i-1][0] tr2 = trlst[i][0] tmp_rs = (2*(tr2-tr1)) / (width1+width2) if tmp_rs < self.crit_resolution: molname_a = trlst[i-1][2] molname_b = trlst[i][2] text = " - %s %.2f min\n" % (molname_a, round(trlst[i-1][0], 2)) text += " - %s %.2f min\n" % (molname_b, round(trlst[i][0], 2)) text += "Rs: %.2f\n" % round(tmp_rs, 2) text += "#"*20 text += "\n" self.plainTextEdit.appendPlainText(text) ncc += 1 if molname_a not in crit_molname: # add to critical tr tab a_indx = molname.index(molname_a) crit_trtab.append(trtab.pop(a_indx)) crit_molname.append(molname.pop(a_indx)) if molname_b not in crit_molname: b_indx = molname.index(molname_b) crit_trtab.append(trtab.pop(b_indx)) crit_molname.append(molname.pop(b_indx)) else: continue self.plainTextEdit.appendPlainText("Total critical couples: %d" % (ncc)) #Create a cromatogram peaks = BuildChromatogram(trtab, tg_soft, 0.01) peaks = zip(*peaks) crit_peaks = BuildChromatogram(crit_trtab, tg_soft, 0.01) crit_peaks = zip(*crit_peaks) y = [] x = [] for i in range(len(peaks)): x.append(peaks[i][0]) y.append(0.) len(peaks[0]) for j in range(1, len(peaks[0])): y[-1] += peaks[i][j] crit_y = [] crit_x = [] for i in range(len(crit_peaks)): crit_x.append(crit_peaks[i][0]) crit_y.append(0.) len(peaks[0]) for j in range(1, len(crit_peaks[0])): crit_y[-1] += crit_peaks[i][j] ax = self.figure.add_subplot(111) ax.hold(False) ax.plot(x, y, "b", crit_x, crit_y, "r") #ax.plot(x, y, '-', color='blue') #ax.plot(crit_x, crit_y, '-', color='red') plt.xlabel('Time') plt.ylabel('Signal') plt.xlim([tr_min-((tr_min*10.)/100.), tr_max+((tr_max*10.)/100.)]) self.canvas.draw()
class calibrlogger(PyQt4.QtGui.QMainWindow, Calibr_Ui_Dialog): # An instance of the class Calibr_Ui_Dialog is created same time as instance of calibrlogger is created def __init__(self, parent, settingsdict1={}, obsid=''): PyQt4.QtGui.QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))#show the user this may take a long time... self.obsid = obsid self.log_pos = None self.y_pos = None self.meas_ts = None self.head_ts = None self.level_masl_ts = None self.loggerpos_masl_or_offset_state = 1 self.settingsdict = settingsdict1 PyQt4.QtGui.QDialog.__init__(self, parent) self.setAttribute(PyQt4.QtCore.Qt.WA_DeleteOnClose) self.setupUi(self) # Required by Qt4 to initialize the UI self.setWindowTitle("Calculate water level from logger") # Set the title for the dialog self.INFO.setText("Select the observation point with logger data to be adjusted.") self.log_calc_manual.setText("<a href=\"https://github.com/jkall/qgis-midvatten-plugin/wiki/4.-Edit-data\">Midvatten manual</a>") # Create a plot window with one single subplot self.calibrplotfigure = plt.figure() self.axes = self.calibrplotfigure.add_subplot( 111 ) self.canvas = FigureCanvas( self.calibrplotfigure ) self.mpltoolbar = NavigationToolbar( self.canvas, self.widgetPlot ) lstActions = self.mpltoolbar.actions() self.mpltoolbar.removeAction( lstActions[ 7 ] ) self.layoutplot.addWidget( self.canvas ) self.layoutplot.addWidget( self.mpltoolbar ) self.calibrplotfigure.tight_layout() self.show() self.cid =[] self.connect(self.pushButtonSet, PyQt4.QtCore.SIGNAL("clicked()"), self.set_logger_pos) self.connect(self.pushButtonAdd, PyQt4.QtCore.SIGNAL("clicked()"), self.add_to_level_masl) self.connect(self.pushButtonFrom, PyQt4.QtCore.SIGNAL("clicked()"), self.set_from_date_from_x) self.connect(self.pushButtonTo, PyQt4.QtCore.SIGNAL("clicked()"), self.set_to_date_from_x) self.connect(self.pushButtonupdateplot, PyQt4.QtCore.SIGNAL("clicked()"), self.update_plot) #self.connect(self.loggerpos_masl_or_offset, PyQt4.QtCore.SIGNAL("clicked()"), self.loggerpos_masl_or_offset_change) #self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.calibrate_from_plot_selection) self.connect(self.pushButtonLpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_old_level) self.connect(self.pushButtonMpos, PyQt4.QtCore.SIGNAL("clicked()"), self.catch_new_level) self.pushButtonMpos.setEnabled(False) self.connect(self.pushButtonCalcBestFit, PyQt4.QtCore.SIGNAL("clicked()"), self.logger_pos_best_fit) self.connect(self.pushButtonCalcBestFit2, PyQt4.QtCore.SIGNAL("clicked()"), self.level_masl_best_fit) self.connect(self.pushButton_delete_logger, PyQt4.QtCore.SIGNAL("clicked()"), lambda: self.delete_selected_range(u'w_levels_logger')) self.get_search_radius() # Populate combobox with obsid from table w_levels_logger self.load_obsid_from_db() PyQt4.QtGui.QApplication.restoreOverrideCursor()#now this long process is done and the cursor is back as normal def load_obsid_from_db(self): print ('am here')#debug self.combobox_obsid.clear() myconnection = utils.dbconnection() if myconnection.connect2db() == True: print('connected')#debug # skapa en cursor curs = myconnection.conn.cursor() rs=curs.execute("""select distinct obsid from w_levels_logger order by obsid""") self.combobox_obsid.addItem('') for row in curs: print(row[0])#debug self.combobox_obsid.addItem(row[0]) rs.close() myconnection.closedb() def load_obsid_and_init(self): """ Checks the current obsid and reloads all ts. :return: obsid Info: Before, some time series was only reloaded when the obsid was changed, but this caused a problem if the data was changed in the background in for example spatialite gui. Now all time series are reloaded always. It's rather fast anyway. """ obsid = unicode(self.combobox_obsid.currentText()) if not obsid: utils.pop_up_info("ERROR: no obsid is chosen") return None meas_sql = r"""SELECT date_time, level_masl FROM w_levels WHERE obsid = '""" + obsid + """' ORDER BY date_time""" self.meas_ts = self.sql_into_recarray(meas_sql) head_sql = r"""SELECT date_time as 'date [datetime]', head_cm / 100 FROM w_levels_logger WHERE obsid = '""" + obsid + """' ORDER BY date_time""" self.head_ts = self.sql_into_recarray(head_sql) self.obsid = obsid level_masl_ts_sql = r"""SELECT date_time as 'date [datetime]', level_masl FROM w_levels_logger WHERE obsid = '""" + self.obsid + """' ORDER BY date_time""" self.level_masl_ts = self.sql_into_recarray(level_masl_ts_sql) return obsid def getlastcalibration(self): obsid = self.load_obsid_and_init() if not obsid=='': sql = """SELECT MAX(date_time), loggerpos FROM (SELECT date_time, (level_masl - (head_cm/100)) as loggerpos FROM w_levels_logger WHERE level_masl > -990 AND obsid = '""" sql += obsid sql += """')""" self.lastcalibr = utils.sql_load_fr_db(sql)[1] if self.lastcalibr[0][1] and self.lastcalibr[0][0]: text = """Last pos. for logger in """ text += obsid text += """ was """ + str(self.lastcalibr[0][1]) + """ masl at """ + str(self.lastcalibr[0][0]) else: text = """There is no earlier known position for the logger in """ + unicode(self.combobox_obsid.currentText())#self.obsid[0] self.INFO.setText(text) def set_logger_pos(self): self.loggerpos_masl_or_offset_state = 1 obsid = self.load_obsid_and_init() if not self.LoggerPos.text() == '': self.calibrate() self.update_plot() def add_to_level_masl(self): self.loggerpos_masl_or_offset_state = 0 obsid = self.load_obsid_and_init() if not self.Add2Levelmasl.text() == '': self.calibrate() self.update_plot() def calibrate(self): self.calib_help.setText("Calibrating") PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor) obsid = self.load_obsid_and_init() if not obsid=='': sanity1sql = """select count(obsid) from w_levels_logger where obsid = '""" + obsid[0] + """'""" sanity2sql = """select count(obsid) from w_levels_logger where head_cm not null and head_cm !='' and obsid = '""" + obsid[0] + """'""" if utils.sql_load_fr_db(sanity1sql)[1] == utils.sql_load_fr_db(sanity2sql)[1]: # This must only be done if head_cm exists for all data fr_d_t = self.FromDateTime.dateTime().toPyDateTime() to_d_t = self.ToDateTime.dateTime().toPyDateTime() if self.loggerpos_masl_or_offset_state == 1: self.update_level_masl_from_head(obsid, fr_d_t, to_d_t, self.LoggerPos.text()) else: self.update_level_masl_from_level_masl(obsid, fr_d_t, to_d_t, self.Add2Levelmasl.text()) self.getlastcalibration() else: utils.pop_up_info("Calibration aborted!!\nThere must not be empty cells or\nnull values in the 'head_cm' column!") else: self.INFO.setText("Select the observation point with logger data to be calibrated.") self.calib_help.setText("") PyQt4.QtGui.QApplication.restoreOverrideCursor() def update_level_masl_from_level_masl(self, obsid, fr_d_t, to_d_t, newzref): """ Updates the level masl using newzref :param obsid: (str) The obsid :param fr_d_t: (datetime) start of calibration :param to_d_t: (datetime) end of calibration :param newzref: (int/float/str [m]) The correction that should be made against the head [m] :return: None """ sql =r"""UPDATE w_levels_logger SET level_masl = """ sql += str(newzref) sql += """ + level_masl WHERE obsid = '""" sql += obsid # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first. sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """ sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds()) sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """ sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds()) sql += """ """ dummy = utils.sql_alter_db(sql) def update_level_masl_from_head(self, obsid, fr_d_t, to_d_t, newzref): """ Updates the level masl using newzref :param obsid: (str) The obsid :param fr_d_t: (datetime) start of calibration :param to_d_t: (datetime) end of calibration :param newzref: (int/float/str [m]) The correction that should be made against the head [m] :return: None """ sql =r"""UPDATE w_levels_logger SET level_masl = """ sql += str(newzref) sql += """ + head_cm / 100 WHERE obsid = '""" sql += obsid # Sqlite seems to have problems with date comparison date_time >= a_date, so they have to be converted into total seconds first (but now we changed to > but kept .total_seconds()) sql += """' AND CAST(strftime('%s', date_time) AS NUMERIC) > """ sql += str((fr_d_t - datetime.datetime(1970,1,1)).total_seconds()) sql += """ AND CAST(strftime('%s', date_time) AS NUMERIC) < """ sql += str((to_d_t - datetime.datetime(1970,1,1)).total_seconds()) sql += """ """ dummy = utils.sql_alter_db(sql) def sql_into_recarray(self, sql): """ Converts and runs an sql-string and turns the answer into an np.recarray and returns it""" my_format = [('date_time', datetime.datetime), ('values', float)] #Define (with help from function datetime) a good format for numpy array recs = utils.sql_load_fr_db(sql)[1] table = np.array(recs, dtype=my_format) #NDARRAY table2=table.view(np.recarray) # RECARRAY Makes the two columns inte callable objects, i.e. write table2.values return table2 def update_plot(self): """ Plots self.level_masl_ts, self.meas_ts and maybe self.head_ts """ self.reset_plot_selects_and_calib_help() self.calib_help.setText("Updating plot") PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor) obsid = self.load_obsid_and_init() if obsid == None: PyQt4.QtGui.QApplication.restoreOverrideCursor() self.calib_help.setText("") return self.axes.clear() p=[None]*2 # List for plot objects # Load manual reading (full time series) for the obsid self.plot_recarray(self.axes, self.meas_ts, obsid, 'o-', 10) # Load Loggerlevels (full time series) for the obsid if self.loggerLineNodes.isChecked(): logger_line_style = '.-' else: logger_line_style = '-' self.plot_recarray(self.axes, self.level_masl_ts, obsid + unicode(' logger', 'utf-8'), logger_line_style, 10) #Plot the original head_cm if self.plot_logger_head.isChecked(): self.plot_recarray(self.axes, self.head_ts, obsid + unicode(' original logger head', 'utf-8'), logger_line_style, 10) """ Finish plot """ self.axes.grid(True) self.axes.yaxis.set_major_formatter(tick.ScalarFormatter(useOffset=False, useMathText=False)) self.calibrplotfigure.autofmt_xdate() self.axes.set_ylabel(unicode('Level (masl)', 'utf-8')) #This is the method that accepts even national characters ('åäö') in matplotlib axes labels self.axes.set_title(unicode('Plot for ', 'utf-8') + str(obsid)) #This is the method that accepts even national characters ('åäö') in matplotlib axes labels for label in self.axes.xaxis.get_ticklabels(): label.set_fontsize(10) for label in self.axes.yaxis.get_ticklabels(): label.set_fontsize(10) #plt.show() self.calibrplotfigure.tight_layout() self.canvas.draw() plt.close(self.calibrplotfigure)#this closes reference to self.calibrplotfigure PyQt4.QtGui.QApplication.restoreOverrideCursor() self.calib_help.setText("") self.getlastcalibration() def plot_recarray(self, axes, a_recarray, lable, line_style, picker=10): """ Plots a recarray to the supplied axes object """ # Get help from function datestr2num to get date and time into float myTimestring = [a_recarray.date_time[idx] for idx in xrange(len(a_recarray))] numtime=datestr2num(myTimestring) #conv list of strings to numpy.ndarray of floats axes.plot_date(numtime, a_recarray.values, line_style, label=lable, picker=picker) def set_from_date_from_x(self): """ Used to set the self.FromDateTime by clicking on a line node in the plot self.canvas """ self.reset_plot_selects_and_calib_help() self.calib_help.setText("Select a node to use as \"from\"") self.deactivate_pan_zoom() self.canvas.setFocusPolicy(Qt.ClickFocus) self.canvas.setFocus() self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.FromDateTime))) def set_to_date_from_x(self): """ Used to set the self.ToDateTime by clicking on a line node in the plot self.canvas """ self.reset_plot_selects_and_calib_help() self.calib_help.setText("Select a node to use as \"to\"") self.deactivate_pan_zoom() self.canvas.setFocusPolicy(Qt.ClickFocus) self.canvas.setFocus() self.cid.append(self.canvas.mpl_connect('pick_event', lambda event: self.set_date_from_x_onclick(event, self.ToDateTime))) def set_date_from_x_onclick(self, event, date_holder): """ Sets the date_holder to a date from a line node closest to the pick event date_holder: a QDateTimeEdit object. """ found_date = utils.find_nearest_date_from_event(event) date_holder.setDateTime(found_date) self.reset_plot_selects_and_calib_help() def reset_plot_selects_and_calib_help(self): """ Reset self.cid and self.calib_help """ self.reset_cid() self.log_pos = None self.y_pos = None self.calib_help.setText("") def reset_cid(self): """ Resets self.cid to an empty list and disconnects unused events """ for x in self.cid: self.canvas.mpl_disconnect(x) self.cid = [] def catch_old_level(self): """Part of adjustment method 3. adjust level_masl by clicking in plot. this part selects a line node and a y-position on the plot""" #Run init to make sure self.meas_ts and self.head_ts is updated for the current obsid. self.load_obsid_and_init() self.deactivate_pan_zoom() self.canvas.setFocusPolicy(Qt.ClickFocus) self.canvas.setFocus() self.calib_help.setText("Select a logger node.") self.cid.append(self.canvas.mpl_connect('pick_event', self.set_log_pos_from_node_date_click)) def catch_new_level(self): """ Part of adjustment method 3. adjust level_masl by clicking in plot. this part selects a y-position from the plot (normally user would select a manual measurement).""" if self.log_pos is not None: self.calib_help.setText("Select a y position to move to.") self.cid.append(self.canvas.mpl_connect('button_press_event', self.set_y_pos_from_y_click)) self.calib_help.setText("") else: self.calib_help.setText("Something wrong, click \"Current\" and try again.") def calculate_offset(self): """ Part of adjustment method 3. adjust level_masl by clicking in plot. this method extracts the head from head_ts with the same date as the line node. 4. Calculating y-position - head (or level_masl) and setting self.LoggerPos. 5. Run calibration. """ if self.log_pos is not None and self.y_pos is not None: PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor) logger_ts = self.level_masl_ts y_pos = self.y_pos log_pos = self.log_pos self.y_pos = None self.log_pos = None log_pos_date = datestring_to_date(log_pos).replace(tzinfo=None) logger_value = None #Get the value for the selected node for raw_date, logger_value in logger_ts: date = datestring_to_date(raw_date).replace(tzinfo=None) if date == log_pos_date: break if logger_value is None: utils.pop_up_info("No connection between level_masl dates and logger date could be made!\nTry again or choose a new logger line node!") else: self.Add2Levelmasl.setText(str(float(y_pos) - float(logger_value))) PyQt4.QtGui.QApplication.restoreOverrideCursor() self.pushButtonMpos.setEnabled(False) def set_log_pos_from_node_date_click(self, event): """ Sets self.log_pos variable to the date (x-axis) from the node nearest the pick event """ found_date = utils.find_nearest_date_from_event(event) #self.calib_help.setText("Logger node " + str(found_date) + " selected, click button \"Calibrate by selection in plot\" again.") self.calib_help.setText("Logger node " + str(found_date) + " selected, click \"new\" and select new level.") self.log_pos = found_date self.reset_cid() self.pushButtonMpos.setEnabled(True) def set_y_pos_from_y_click(self, event): """ Sets the self.y_pos variable to the y value of the click event """ self.y_pos = event.ydata #self.calib_help.setText("Y position set, click button \"Calibrate by selection in plot\" again for calibration.") self.calculate_offset() self.calib_help.setText("Offset is calculated, now click \"add\".") self.reset_cid() def logger_pos_best_fit(self): self.loggerpos_masl_or_offset_state = 1 self.calc_best_fit() def level_masl_best_fit(self): self.loggerpos_masl_or_offset_state = 0 self.calc_best_fit() def calc_best_fit(self): """ Calculates the self.LoggerPos from self.meas_ts and self.head_ts First matches measurements from self.meas_ts to logger values from self.head_ts. This is done by making a mean of all logger values inside self.meas_ts date - search_radius and self.meas_ts date + search_radius. (this could probably be change to get only the closest logger value inside the search_radius instead) (search_radius is gotten from self.get_search_radius()) Then calculates the mean of all matches and set to self.LoggerPos. """ obsid = self.load_obsid_and_init() self.reset_plot_selects_and_calib_help() search_radius = self.get_search_radius() if self.loggerpos_masl_or_offset_state == 1:# UPDATE TO RELEVANT TEXT logger_ts = self.head_ts text_field = self.LoggerPos calib_func = self.set_logger_pos really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between head_cm and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""") else:# UPDATE TO RELEVANT TEXT logger_ts = self.level_masl_ts text_field = self.Add2Levelmasl calib_func = self.add_to_level_masl really_calibrate_question = utils.askuser("YesNo", """This will calibrate all values inside the chosen period\nusing the mean difference between level_masl and w_levels measurements.\n\nSearch radius for matching logger and measurement nodes set to '""" + ' '.join(search_radius) + """'\n\nContinue?""") if really_calibrate_question.result == 0: # if the user wants to abort return PyQt4.QtGui.QApplication.setOverrideCursor(PyQt4.QtCore.Qt.WaitCursor) coupled_vals = self.match_ts_values(self.meas_ts, logger_ts, search_radius) if not coupled_vals: utils.pop_up_info("There was no matched measurements or logger values inside the chosen period.\n Try to increase the search radius!") else: text_field.setText(str(utils.calc_mean_diff(coupled_vals))) calib_func() PyQt4.QtGui.QApplication.restoreOverrideCursor() def match_ts_values(self, meas_ts, logger_ts, search_radius_tuple): """ Matches two timeseries values for shared timesteps For every measurement point, a mean of logger values inside measurementpoint + x minutes to measurementpoint - x minutes is coupled together. At the first used measurement, only logger values greater than the set start date is used. At the last measurement, only logger values lesser than the set end date is used. This is done so that values from another logger reposition is not mixed with the chosen logger positioning. (Hard to explain). """ coupled_vals = [] #Get the search radius, default to 10 minutes search_radius = int(search_radius_tuple[0]) search_radius_period = search_radius_tuple[1] logger_gen = utils.ts_gen(logger_ts) try: l = next(logger_gen) except StopIteration: return None log_vals = [] all_done = False #The .replace(tzinfo=None) is used to remove info about timezone. Needed for the comparisons. This should not be a problem though as the date scale in the plot is based on the dates from the database. outer_begin = self.FromDateTime.dateTime().toPyDateTime().replace(tzinfo=None) outer_end = self.ToDateTime.dateTime().toPyDateTime().replace(tzinfo=None) logger_step = datestring_to_date(l[0]).replace(tzinfo=None) for m in meas_ts: if logger_step is None: break meas_step = datestring_to_date(m[0]).replace(tzinfo=None) step_begin = dateshift(meas_step, -search_radius, search_radius_period) step_end = dateshift(meas_step, search_radius, search_radius_period) if step_end < outer_begin: continue if step_begin > outer_end: break #Skip logger steps that are earlier than the chosen begin date or are not inside the measurement period. while logger_step < step_begin or logger_step < outer_begin: try: l = next(logger_gen) except StopIteration: all_done = True break logger_step = datestring_to_date(l[0]).replace(tzinfo=None) log_vals = [] while logger_step is not None and step_begin <= logger_step <= step_end and outer_begin <= logger_step <= outer_end: if not math.isnan(float(l[1])) or l[1] in ('nan', 'NULL'): log_vals.append(float(l[1])) try: l = next(logger_gen) except StopIteration: all_done = True break logger_step = datestring_to_date(l[0]).replace(tzinfo=None) if log_vals: mean = np.mean(log_vals) if not math.isnan(mean): coupled_vals.append((m[1], mean)) if all_done: break return coupled_vals def get_search_radius(self): """ Get the period search radius, default to 10 minutes """ if not self.bestFitSearchRadius.text(): search_radius = '10 minutes' self.bestFitSearchRadius.setText(search_radius) else: search_radius = self.bestFitSearchRadius.text() search_radius_splitted = search_radius.split() if len(search_radius_splitted) != 2: utils.pop_up_info("Must write time resolution also, ex. 10 minutes") return tuple(search_radius_splitted) def deactivate_pan_zoom(self): """ Deactivates the NavigationToolbar pan or zoom feature if they are currently active """ if self.mpltoolbar._active == "PAN": self.mpltoolbar.pan() elif self.mpltoolbar._active == "ZOOM": self.mpltoolbar.zoom() def delete_selected_range(self, table_name): """ Deletes the current selected range from the database from w_levels_logger :return: De """ current_loaded_obsid = self.obsid selected_obsid = self.load_obsid_and_init() if current_loaded_obsid != selected_obsid: utils.pop_up_info("Error!\n The obsid selection has been changed but the plot has not been updated. No deletion done.\nUpdating plot.") self.update_plot() return elif selected_obsid is None: utils.pop_up_info("Error!\n No obsid was selected. No deletion done.\nUpdating plot.") self.update_plot() return fr_d_t = str((self.FromDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds()) to_d_t = str((self.ToDateTime.dateTime().toPyDateTime() - datetime.datetime(1970,1,1)).total_seconds()) sql_list = [] sql_list.append(r"""delete from "%s" """%table_name) sql_list.append(r"""where obsid = '%s' """%selected_obsid) sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """) sql_list.append(r""" > '%s' """%fr_d_t) sql_list.append(r"""AND CAST(strftime('%s', date_time) AS NUMERIC) """) sql_list.append(r""" < '%s' """%to_d_t) sql = ''.join(sql_list) really_delete = utils.askuser("YesNo", "Do you want to delete the period " + str(self.FromDateTime.dateTime().toPyDateTime()) + " to " + str(self.ToDateTime.dateTime().toPyDateTime()) + " for obsid " + selected_obsid + " from table " + table_name + "?").result if really_delete: utils.sql_alter_db(sql) self.update_plot()
class MatplotlibWidgetWL(QGraphicsView): def __init__(self, parent = None): QWidget.__init__(self, parent) self.canvas = MplCanvas() self.vbl = QVBoxLayout() self.vbl.addWidget(self.canvas) self.setLayout(self.vbl) self.canvas.ax.set_title('Series of Averages', fontsize=12) self.canvas.fig.patch.set_alpha(0) self.canvas.fig.tight_layout() self.mpl_toolbar = NavigationToolbar(self.canvas, self) self.canvas.mpl_connect('button_press_event', self.onclick) self.mpl_toolbar.pan() params = { 'xtick.labelsize': 12, 'ytick.labelsize': 12, 'figure.autolayout': True, } plt.rcParams.update(params) self.data = [] self.distmeshsurf = 1. if sys.platform == 'darwin': self.filePath = '/Users/TPSGroup/Documents/Experimental Data/Data Mike/Raw Data/2015' else: self.filePath = 'C:\\Users\\tpsgroup\\Desktop\\Documents\\Data Mike\\Raw Data\\2015' self.trace = [False, False, False, False] pickedValReady = pyqtSignal(object) def onclick(self, event): if event.button == 3: self.pickedValReady.emit(event.xdata) def addTrace(self): # average traces saved as (paramter, surface, surface err, field, field err) datapath = QFileDialog.getOpenFileNames(self, 'Select Avgerage Trace File', self.filePath, '(*.txt)') if not datapath: return for i in range(len(datapath)): self.data.append(loadtxt(str(datapath[i]), skiprows=2)) self.filePath = os.path.dirname(str(datapath[0])) def kRange(self, n, ml): '''Stark states in parabolic quantum number k(n_1-n_2), {k}=-(n-|m_l|-1)...(n-|m_l|-1), (n-|m_l|) elements, elements the same for m_l=0, +/-2 where maxkmax states have pure m_l=0 character, these two states are 'missing' at the edge of the manifold for m_l=+/-2''' kRange = [i for i in range(-(n-abs(ml)-1),(n-abs(ml)),2)] return kRange def StarkEnergy(self, n, ml, k, F): # Hartree in wavenumbers, Rydberg constant in cm^-1 # Rydberg constant for Hydrogen != R_inf rh = 109677.583 hartree = 2*rh Eau = (-(1./(2*n**2)) + 1.5*n*k*F - (n**4)/16.0*(17*n**2 - 3*k**2 - 9*ml**2 + 19)*F**2 + \ 3/32*n**7*k*(23*n**2 - k**2 + 11*ml**2 + 39)*F**3 - \ (n**10)/1024.0*(5487*n**4 + 35182*n**2 - 1134*ml**2*k**2 + \ 1806*n**2*k**2 - 3402*n**2*ml**2 - 3093*k**4 - 549*ml**4 + \ 5754*k**2 - 8622*ml**2 + 16211)*F**4)*hartree return Eau def plotSpectrum(self, n, ml02j32flag, ml1j32flag, ml02j12flag, ml1j12flag, trace, d, volt, offset, smooth, smoothwin, smoothpol, normalise): if len(self.data) < 1: return # get curent xy limits xlim1, xlim2 = self.canvas.ax.get_xlim() ylim1, ylim2 = self.canvas.ax.get_ylim() self.canvas.ax.clear() self.distmeshsurf = d # build Stark manifold from expansion for energies in E-field # from http://physics.nist.gov/asd Lalphaj32 = -82259.2850014 #121.5668237310 Lalphaj12 = -82258.919113 #121.5673644609 rh = 109677.583 c = 299792458 # in eV h = 4.135667662E-15 # Electric field in V/cm to atomic units E_h/ea_0. #http://physics.nist.gov/cgi-bin/cuu/Value?auefld Fau = (100*volt/(5.142206E11))/d # energies converted to nm # account for fine splitting due to spin-orbit coupling # if not, from expansion: en = (2*10**7)/(self.StarkEnergy(n, 2, k, Fau) - self.StarkEnergy(2, 0, 1, Fau)) + offset kml02 = self.kRange(n, 0) kml1 = self.kRange(n, 1) if ml02j32flag: ml02j32 = [0]*len(kml02) for i in range(len(kml02)): ml02j32[i] = (2*10**7)/(self.StarkEnergy(n, 2, kml02[i], Fau) - (-rh-Lalphaj32)) + offset if ml1j32flag: ml1j32 = [0]*len(kml1) for i in range(len(kml1)): ml1j32[i] = (2*10**7)/(self.StarkEnergy(n, 1, kml1[i], Fau) - (-rh-Lalphaj32)) + offset if ml02j12flag: ml02j12 = [0]*len(kml02) for i in range(len(kml02)): ml02j12[i] = (2*10**7)/(self.StarkEnergy(n, 2, kml02[i], Fau) - (-rh-Lalphaj12)) + offset if ml1j12flag: ml1j12 = [0]*len(kml1) for i in range(len(kml1)): ml1j12[i] = (2*10**7)/(self.StarkEnergy(n, 1, kml1[i], Fau) - (-rh-Lalphaj12)) + offset colors = ['0.0','0.2','0.4','0.6'] ls = ['-','-','-','-'] c = ['k', 'g', 'm', 'y'] for i in range(len(self.data)): data = self.data[i] self.trace[i] = trace if self.trace[i]: argy = data[:,3] maxn = max(data[:,3]) else: argy = data[:,1] maxn = max(data[:,1]) if smooth: argx = savitzky_golay(data[:,0], smoothwin, smoothpol) argy = savitzky_golay(argy, smoothwin, smoothpol) else: argx = data[:,0] if normalise: argy = argy/maxn self.canvas.ax.plot(argx, argy, linestyle=ls[i], color=c[i], linewidth=1.4) if ml02j32flag: xx = [ml02j32, ml02j32] yy = [[-0.08]*len(ml02j32), [1.02]*len(ml02j32)] self.canvas.ax.plot(xx,yy, 'b', linewidth=1.2) for i in range(len(ml02j32)): self.canvas.ax.text(ml02j32[i], 1.06, str(kml02[i]), horizontalalignment='center', \ verticalalignment='center',color='b',fontsize=8) if ml1j32flag: xx = [ml1j32, ml1j32] yy = [[-0.08]*len(ml1j32), [1.02]*len(ml1j32)] self.canvas.ax.plot(xx,yy, 'b--', linewidth=1.2) for i in range(len(ml1j32)): self.canvas.ax.text(ml1j32[i], 1.06, str(kml1[i]), horizontalalignment='center', \ verticalalignment='center',color='b',fontsize=8) if ml02j12flag: xx = [ml02j12, ml02j12] yy = [[-0.08]*len(ml02j12), [1.02]*len(ml02j12)] self.canvas.ax.plot(xx,yy, 'r', linewidth=1.2) for i in range(len(ml02j12)): self.canvas.ax.text(ml02j12[i], 1.06, str(kml02[i]), horizontalalignment='center', \ verticalalignment='center',color='r',fontsize=8) if ml1j12flag: xx = [ml1j12, ml1j12] yy = [[-0.08]*len(ml1j12), [1.02]*len(ml1j12)] self.canvas.ax.plot(xx,yy, 'r--', linewidth=1.2) for i in range(len(ml1j12)): self.canvas.ax.text(ml1j12[i], 1.06, str(kml1[i]), horizontalalignment='center', \ verticalalignment='center',color='r',fontsize=8) self.canvas.ax.set_xlabel("Fundamental Wavelength (nm)") self.canvas.ax.set_title('Stark Manifold for n= ' + str(n), fontsize=12) if (xlim1 == 0.0 and xlim2 == 1.0): xlim1 = min(argx) xlim2 = max(argx) ylim1 = 0 ylim2 = 1.1 self.canvas.ax.set_ylim(ymin=ylim1, ymax=ylim2) self.canvas.ax.set_xlim(xmin=xlim1, xmax=xlim2) self.canvas.draw() def clearDisplay(self): self.canvas.ax.clear() self.canvas.ax.set_title("", fontsize=12) self.data = [] self.trace = [False, False, False, False] self.canvas.draw()
class Window(QtGui.QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.toolbar.hide() # Just some button self.button = QtGui.QPushButton('Plot') self.button.clicked.connect(self.plot) self.button1 = QtGui.QPushButton('Zoom') self.button1.clicked.connect(self.zoom) self.button2 = QtGui.QPushButton('Pan') self.button2.clicked.connect(self.pan) self.button3 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) layout.addWidget(self.button1) layout.addWidget(self.button2) layout.addWidget(self.button3) self.setLayout(layout) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def plot(self): ''' DO NOT CHANGE. Original sample ''' #data = [random.random() for i in range(25)] #ax = self.figure.add_subplot(111) # create an axis #ax.hold(False) # discards the old graph #ax.plot(data, '*-') # plot data #self.canvas.draw() # refresh canvas ra = [45, 40, 90, -75, 80.2, 102.63] # angle --> change to buffer_angle[4000] ra = [x / 180.0 * 3.141593 for x in ra] # convert angle to radian dec = [1.01, 6.05, 5.6, 4.02, 9.1, 7.85] # distance --> change to buffer_distance[4000] ax = self.figure.add_axes([0.1, 0.1, 0.8, 0.8], polar=True) ax.set_ylim(0, 10.0) ax.set_yticks(numpy.arange(0, 6, 2)) ax.scatter(ra, dec, c='r') # plot the first microphone self.canvas.draw()
class MatplotlibWidgetRydSeries(QGraphicsView): def __init__(self, parent = None): QWidget.__init__(self, parent) self.canvas = MplCanvas() self.vbl = QVBoxLayout() self.vbl.addWidget(self.canvas) self.setLayout(self.vbl) self.canvas.ax.set_title('Rydberg Series', fontsize=12) self.canvas.setFocusPolicy(Qt.StrongFocus) self.canvas.setFocus() self.canvas.fig.patch.set_alpha(0) self.mpl_toolbar = NavigationToolbar(self.canvas, self) params = { 'legend.fontsize': 12, 'xtick.labelsize': 12, 'ytick.labelsize': 12, 'legend.handletextpad': .5, 'figure.autolayout': True, } plt.rcParams.update(params) self.canvas.mpl_connect('button_press_event', self.onclick) self.mpl_toolbar.pan() self.clearflag = False self.defaultloaded = False self.filePath = 'C:\\Users\\tpsgroup\\Desktop\\Documents\\Data Mike' pickedValReady = pyqtSignal(object) def defaultSet(self, bool): self.defaultloaded = bool def plotWLScan(self,laseroffset): '''display complete WL scan and Rydberg series on top''' dataField = loadtxt('FullWavelengthScanField.txt') dataSurface = loadtxt('FullWavelengthScanSurface.txt') argYField = dataField[:,1]/max(dataField[:,1]) argYSurface = dataSurface[:,1]/max(dataSurface[:,1]) self.canvas.ax.clear() self.canvas.ax.plot(dataField[:,0], argYField, 'k', label="Field Signal", linewidth=1.5) self.canvas.ax.plot(dataSurface[:,0], argYSurface, 'g', label="Surface Signal", linewidth=1.5) self.canvas.ax.set_xlabel("Fundamental Wavelength (nm)", fontsize=12) self.canvas.ax.set_title('Rydberg Series', fontsize=12) self.canvas.ax.legend(loc="upper right", bbox_to_anchor = [.98,0.86], fontsize=12) self.canvas.ax.set_ylim([-0.02,1.12]) self.plotRydSeries(laseroffset) self.canvas.fig.tight_layout() self.canvas.draw() self.defaultloaded = True def addTrace(self): datapath = QFileDialog.getOpenFileName(self, 'Select WL Scan File', self.filePath, '(*.txt)') if not datapath: return self.filePath = os.path.dirname(str(datapath)) if len(datapath) < 1: return data = loadtxt(str(datapath)) argY = data[:,1]/max(data[:,1]) if self.defaultloaded: self.canvas.ax.plot(data[:,0], argY, 'r', label="Field Signal", linewidth=1.5) else: self.canvas.ax.plot(data[:,0], argY, 'k', label="Field Signal", linewidth=1.5) self.canvas.draw() def clearDisplay(self): self.canvas.ax.cla() self.canvas.draw() self.clearflag = True self.defaultloaded = False def onclick(self, event): if event.button == 3: self.pickedValReady.emit(event.xdata) def plotRydSeries(self, laseroffset): # Rydberg constant for Hydrogen rh = 109677.583 nRange = np.arange(15, 71) j32offset = 0.091 # 1/64*alpha^2*Ryd rydEn = (2.*10**7)/(rh*(0.25 - (1./nRange**2)) - j32offset) + laseroffset if not(self.clearflag): if hasattr(self, 'rydlines') and len(self.canvas.ax.lines) > 0: for i in range(np.size(self.rydlines)): self.canvas.ax.lines.remove(self.rydlines[i]) if hasattr(self, 'rydlabels') and len(self.canvas.ax.texts) > 0: for i in range(np.size(self.rydlines)): self.rydlabels[i].remove() xx = (rydEn, rydEn) yy = (np.ones(np.size(rydEn))*-0.02,np.ones(np.size(rydEn))*1.02) self.rydlines = self.canvas.ax.plot(xx,yy,linewidth=1,color='b') labels = nRange.astype(str) self.rydlabels = {} for i in range(np.size(labels)): self.rydlabels[i] = self.canvas.ax.text(rydEn[i], 1.06, labels[i], horizontalalignment='center',verticalalignment='center',color='b',fontsize=12) self.canvas.draw() self.clearflag = False
class Application(object): """ Main application class without GUI. """ def __init__(self, args): """ Initialize the main application. Args: args: the arguments given by the ArgumentParser """ super(Application, self).__init__() self.is_init = False self.args = args #default settings of the program self.defaults = DefaultProgSettings() if not self.args.reset: self.defaults.load_settings() self.frame_status = FrameStatus() #self.frame_status.set_status("pan") self.filter_status = FilterStatus() #self.filter_status.set_status("pan") self._cmaps = sorted(m for m in plt.cm.datad if not m.endswith("_r")) self.image = ImageLab("") #open initial file if os.path.isfile(self.defaults.img_fname): self.open_sis(self.defaults.img_fname) else: self.open_sis() #create panels for the images self.frames_panel = FramesCanvas( self.image, width=5, height=4, dpi=100, show_areas=self.defaults.show_regions, show_contour=self.defaults.show_contour, show_grid=self.defaults.show_grid) self.filter_panel = FFTCanvas(self.image, width=5, height=4, dpi=100, show_mask=self.defaults.show_mask) self.vlim_frame_panel = \ VlimPanel(init_values=self.defaults.vlim_img_corr) self.vlim_fft_panel = \ VlimPanel(scale=100, slide_range=(-200, 200), init_values=self.defaults.vlim_fft_corr) self.results_window = None self.progress_bar = None self.filter_panel.set_image(self.image) self.frames_panel.set_image(self.image) if os.path.isfile(self.defaults.mask_fname): self.open_mask(self.defaults.mask_fname) self.fft_frame_menu = QtGui.QMenu() self.status_bar = QtGui.QStatusBar() self.toolbar_frame = NavigationToolbar(self.frames_panel, None) self.toolbar_filter = NavigationToolbar(self.filter_panel, None) self.nav_panel_filter = FilterZoomPanel(self._set_pan_filter, self._set_filter) self.nav_panel_frames = FramesZoomPanel(self._set_pan_frames, self._set_pick_coords) self._set_pan_frames() self._set_pan_filter() def open_sis(self, fname=""): """ Open a sis image file. Args: fname (string): optional filename, if empty it will be asked """ def_fname = self.image.filename if fname == "": #if no filename is give ask it fname = QtGui.QFileDialog.getOpenFileName( self, 'Open SIS file', def_fname.decode("utf-8"), filter="SIS image (*.sis)", options=FILE_DIALOG_OPT) #must convert QString to python string fname = str(fname) if fname != "": #if a filname was given ask details if OpenSisPopup.setParams(self.defaults, self.image, parent=self): self._load_sis(fname) #otherwise if any image is currently loaded ask again elif self.image.filename == "": self.open_sis() #otherwise if any image is currently loaded ask again elif self.image.filename == "": #confirm exit to avoid infinite dialogs if one doesn't want to open a file msg = "If you don't provide a valid file to open the program will be closed. Are you sure?" reply = QtGui.QMessageBox.question( self, 'Close program', msg, QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.Yes) if reply == QtGui.QMessageBox.Yes: exit() else: self.open_sis() else: #if a filename was give try to open it self._load_sis(fname) self.defaults.img_fname = fname def _load_sis(self, fname): """ Loads into the program a given sis image file. Args: fname (string): filename of the sis file """ if fname != "": self.image = ImageLab( filename=fname, frame_w=self.defaults.frame_width, frame_h=self.defaults.frame_height, frame_w_old=self.defaults.frame_width_old, frame_h_old=self.defaults.frame_height_old, frame_cols=self.defaults.frame_colums, frame_rows=self.defaults.frame_rows, frame_num=self.defaults.frame_number, sis_img_n=self.defaults.sis_img_number, vlim_img_corr=self.defaults.vlim_img_corr, vlim_fft_corr=self.defaults.vlim_fft_corr, skip_frames=self.defaults.skip_frames, cmap_img=self.defaults.frame_cmap, cmap_fft=self.defaults.fft_cmap, fft_frame_num=self.defaults.fft_frame_n, compensate_bkg=self.defaults.img_compensate_bkg, compensate_max=self.defaults.img_compensate_max, bkg_slice=self.defaults.slices_bkg, main_slice=self.defaults.slices_main, max_slice=self.defaults.slices_max, show_residuals=self.defaults.show_residuals, gauss_filter=self.defaults.gauss_filter) self.image.init(time_delta=self.defaults.time_delta) #update some defaults values because they may be corrected during #the ImageLab initialization self.defaults.slices_bkg = self.image.background_slices self.defaults.slices_max = self.image.maximum_slices self.defaults.slices_main = self.image.main_slices self.defaults.fft_frame_n = self.image.fft_frame_num self.defaults.frame_width_old = self.defaults.frame_width self.defaults.frame_height_old = self.defaults.frame_height self.defaults.frame_height = self.image.frame_h self.defaults.frame_width = self.image.frame_w #load the filter mask file if it exists if os.path.isfile(self.defaults.mask_fname): self.open_mask(self.defaults.mask_fname) #only if the GUI has been already initialized uptdate frames #and menu if self.is_init: self.status_bar.showMessage("File: \"%s\"" % fname) self.filter_panel.set_image(self.image) self.frames_panel.set_image(self.image) self.update_plots() self._update_fft_frame_menu() def open_mask(self, fname=""): """ Loads a mask file for the fft filter. Args: fname (string): optional filename, if empty it will be asked """ if fname == "": def_fname = os.path.splitext(self.image.filename)[0] + ".mask" fname = QtGui.QFileDialog.getOpenFileName( self, 'Open mask file', def_fname.decode("utf-8"), filter="Mask CSV (*.mask)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": with open(fname, "rb") as fid: reader = csv.DictReader(fid) self.image.filter_points_list = \ [FilterPoint(**row) for row in reader] self.defaults.mask_fname = fname #only if the GUI has been already initialized update frames if self.is_init: self.update_plots() def save_sis(self): """ Saves the frames to sis files. """ def_fname = self.image.filename fname = QtGui.QFileDialog.getSaveFileName(self, 'Save sis files', def_fname.decode("utf-8"), filter="SIS (*.sis)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": self.defaults.sis_save_fname = fname if SaveSisPopup.setParams(self.defaults, self.image, parent=self): self.image.sis_writeimg(self.defaults.sis_save_fname, self.defaults.sis_save_format, self.defaults.sis_save_suffix) def save_mask(self): """ Saves the mask of the current fft filter to a file. """ def_fname = os.path.splitext(self.image.filename)[0] + ".mask" fname = QtGui.QFileDialog.getSaveFileName(self, 'Save mask file', def_fname.decode("utf-8"), filter="Mask CSV (*.mask)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": with open(fname, "wb") as fid: writer = csv.DictWriter(fid, ("mx", "my", "sx", "sy", "A", "e")) writer.writeheader() writer.writerows( [p.get_point() for p in self.image.filter_points_list]) self.defaults.mask_fname = fname def save_movie(self): """ Save the movie of the frames to a file. """ def_fname = os.path.splitext(self.image.filename)[0] + ".mp4" fname = QtGui.QFileDialog.getSaveFileName( self, 'Save movie', def_fname.decode("utf-8"), filter="MPEG (*.mp4);;GIF (*.gif)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": #check the class of the selected file extension test_mpeg = fname.lower().endswith((".mp4", ".avi", ".mkv")) test_img = fname.lower().endswith(".gif") if test_mpeg: #if the extension if of the mpeg class check in the defaults if #a valid encoder was already selected, otherwise set a default #one (this is to help systems where one of libav or ffmpeg is #not present) if self.defaults.movie_writer not in ["libav", "ffmpeg"]: self.defaults.movie_writer = "libav" elif test_img: #same for the image class self.defaults.movie_writer = "imagemagick" else: print "Error, utput movie format not supported." print "Supported formats: MP4, AVI, MKV, GIF" #if the format was valid get the parameters and write the movie if test_mpeg or test_img: if SaveMoviePopup.setParams(self.defaults, self.image, parent=self): self._write_movie(fname) def _write_movie(self, fname): """ Writes the frames movie to a file. Args: fname (string): filename of the movie """ if fname != "": self.image.create_movie(filename=fname, fps=self.defaults.movie_fps, integral_x=self.defaults.movie_integrate_x, integral_y=self.defaults.movie_integrate_y, fading=self.defaults.movie_fading, use_frames=self.defaults.movie_frames, subframes=self.defaults.movie_subframes, dpi=self.defaults.movie_dpi, writer_name=self.defaults.movie_writer) self.status_bar.showMessage("Video saved to " + fname) def save_bitmap(self): """ Saves the current frames bitmap to a file. """ def_fname = os.path.splitext(self.image.filename)[0] + ".png" fname = QtGui.QFileDialog.getSaveFileName( self, 'Save bitmap', def_fname.decode("utf-8"), filter="PNG (*.png);;JPEG (*.jpg)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": if SaveBitmapPopup.setParams(self.defaults, self.image, parent=self): self.image.save_frames_bitmap( filename=fname, reorder=self.defaults.bitmap_reorder, hor_crop=self.defaults.bitmap_hor_crop, ver_crop=self.defaults.bitmap_ver_crop) def save_fft_bitmap(self): """ Saves the current fft bitmap to a file. """ def_fname = os.path.splitext(self.image.filename)[0] + "-fft.png" fname = QtGui.QFileDialog.getSaveFileName( self, 'Save bitmap', def_fname.decode("utf-8"), filter="PNG (*.png);;JPEG (*.jpg)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": self.image.save_fft_bitmap(filename=fname, show_mask=self.filter_panel.show_mask) def update_plots(self): """ Updates all plots (fft and frames). """ self.filter_panel.update_figure() self.frames_panel.update_figure(update_img=False) #TODO check when the update img is necessary for both def do_fit(self, fit_type="gauss"): """ Handles the call for a fit. Args: fit_type (string): identifies the type of the fit "gauss" = Gaussian fit "tf" = Thomas-Fermi fit "bimodal" = Gaussian + Thomas-Fermin fit """ #set progress bar updates self.progress_bar.setVisible(True) self.image.fit_done.connect(self._on_fitupdate) #initialize and call the fitting class if fit_type == "gauss": fit_class = fitting.Gauss2d elif fit_type == "tf": fit_class = fitting.ThomasFermi2d elif fit_type == "bimodal": fit_class = fitting.Bimodal2d else: print "Warning: wrong fit type, using gaussian" fit_class = fitting.Gauss2d self.image.do_fit(fit_class) #at the end update the contours in the image and results if self.image.show_residuals: #if the fit residuals are selected the image must be updated #after a new fit self.frames_panel.update_figure(update_img=True) self.frames_panel.update_contour() self.show_results() #hide progress bar self.progress_bar.setVisible(False) def _on_fitupdate(self, fract): """ Updates the progress bar with the fraction passed as argument. Args: fract (float): number between 0 and 1 to be set in the progress bar """ self.progress_bar.setValue(100.0 * float(fract)) def show_results(self, new_window=True): """ Shows the results of the fit in a window. Args: new_window (bool): open a new window if not already open """ #enters if a window is present or it can be opened if (new_window) or\ (not new_window and self.results_window is not None): #if the window is not opened open a new one if self.results_window == None: self.results_window = FitResultsPopup(parent=self) self.results_window.\ button_save.clicked.connect(self.save_results) self.results_window.show() #build the string conatining the results table results = "\t".join(self.image.results.keys()) + "\r\n" for n_id in sorted(self.image.results.frames_list()): dat = self.image.results.get_data(n_id) #if None is present write nothing row = "\t".join([format(dat[k], ".4g") \ if dat[k] is not None \ else "" \ for k in self.image.results.keys()]) results += row + "\r\n" #update the text self.results_window.text.setText(results) def _delete_window(): """ Deletes the results window for the application internal proprieties. """ self.results_window = None #must use the custom window destroy for consistency self.results_window.destroyed.connect(_delete_window) def show_time_table(self): """ Shows the configuration popup for setting the time intervals between frames. """ if TimeTablePopup.setParams(self.defaults, self.image, parent=self): #update results window if needed self.show_results(new_window=False) def save_results(self): """ Save the results of fit and coordinates pick to a file. """ #check if there is something to save if len(self.image.results.frames_list()) > 0: def_fname = os.path.splitext(self.image.filename)[0] + ".csv" fname = QtGui.QFileDialog.getSaveFileName( self, 'Save fit results', def_fname.decode("utf-8"), filter="CSV (*.csv)", options=FILE_DIALOG_OPT) fname = str(fname) if fname != "": with open(fname, "wb") as fid: rows = [self.image.results.get_data(n_id) \ for n_id in self.image.results.frames_list()] writer = csv.DictWriter(fid, self.image.results.keys()) writer.writeheader() writer.writerows(rows) else: print "Warning: nothing to save" def _show_contour(self): """ Called when there the user changes the fit contours visibility. """ self.defaults.show_contour = not self.defaults.show_contour self.frames_panel.set_contour_visible(self.defaults.show_contour) def _show_residuals(self): """ Called when there the user changes the fit residuals visibility. """ self.defaults.show_residuals = not self.defaults.show_residuals self.image.show_residuals = self.defaults.show_residuals self.frames_panel.update_figure(update_img=True) def _show_areas(self): """ Called when there the user changes the image areas visibility. """ self.defaults.show_regions = not self.defaults.show_regions self.frames_panel.set_areas_visible(self.defaults.show_regions) def _show_grid(self): """ Called when there the user changes the image grid visibility. """ self.defaults.show_grid = not self.defaults.show_grid self.frames_panel.set_grid_visible(self.defaults.show_grid) def _show_mask(self): """ Called when there the user changes the fft mask visibility. """ self.filter_panel.show_mask = not self.filter_panel.show_mask self.defaults.show_mask = self.filter_panel.show_mask self.filter_panel.update_figure(update_img=False) def _compensate_max(self): """ Called when there the user changes the image maximum normalization. """ self.image.compensate_max = not self.image.compensate_max self.defaults.img_compensate_max = self.image.compensate_max #vlim must be updated self.image.vlim_img = (None, None) self.update_plots() def _compensate_bkg(self): """ Called when there the user changes the image background compensation. """ self.image.compensate_bkg = not self.image.compensate_bkg self.defaults.img_compensate_bkg = self.image.compensate_bkg #vlim must be updated self.image.vlim_img = (None, None) self.update_plots() def _set_cmap_fft(self, cmap): """ Called when there the user changes fft color map. Args: cmap (string): color map name """ self.image.cmap_fft = cmap self.filter_panel.update_figure(update_img=False) self.defaults.fft_cmap = cmap def _set_cmap_frame(self, cmap): """ Called when there the user changes frames color map. Args: cmap (string): color map name """ self.image.cmap_img = cmap self.frames_panel.update_figure(update_img=False) self.defaults.frame_cmap = cmap def _guess_areas(self): """ Called when there the user ask for guessing the image areas. """ self.image.guess_areas() self.frames_panel.update_areas() self.frames_panel.update_figure() self.defaults.slices_bkg = self.image.background_slices self.defaults.slices_max = self.image.maximum_slices self.defaults.slices_main = self.image.main_slices def _get_coord_frame(self, coords): """ From the coordinates get the number of the frame, column and row. Args: coords (tuple): tuple of float coordinates """ col = int(coords[0] / self.image.frame_w) row = int(coords[1] / self.image.frame_h) frame_num = row * self.image.frame_cols + col #return a negative number if the coordinates are negative if coords[0] < 0 or coords[1] < 0: frame_num = col = row = -1 return (frame_num, col, row) def _set_min_area(self): """Changes the frame panel mode to the background area setting.""" if self.frame_status.pan: self.toolbar_frame.pan() self.frame_status.set_status("min") self.nav_panel_frames.status.setText("set minimum") def _set_max_area(self): """Changes the frame panel mode to the maximum area setting.""" if self.frame_status.pan: self.toolbar_frame.pan() self.frame_status.set_status("max") self.nav_panel_frames.status.setText("set maximum") def _set_main_area(self): """Changes the frame panel mode to the main area setting.""" if self.frame_status.pan: self.toolbar_frame.pan() self.frame_status.set_status("main") self.nav_panel_frames.status.setText("set main") def _set_pick_coords(self, multi=False): """ Changes the frame panel mode to the pick coordinates setting. If called while pick is active it goes in multiple selection mode. Args: multi (bool): keep the pick coordinates mode on for multiple selections """ if self.frame_status.pan: self.toolbar_frame.pan() if self.frame_status.pick or multi: self.frame_status.set_status("pick_multi") self.nav_panel_frames.status.setText("multi pick") else: self.frame_status.set_status("pick") self.nav_panel_frames.status.setText("pick coordinates") def _set_pan_frames(self): """Changes the frame panel mode to pan/zoom.""" if not self.frame_status.pan: self.toolbar_frame.pan() self.frame_status.set_status("pan") self.nav_panel_frames.status.setText("Pan/Zoom") def _set_pan_filter(self): """Changes the filter panel mode to pan/zoom.""" if not self.filter_status.pan: self.toolbar_filter.pan() self.filter_status.set_status("pan") self.nav_panel_filter.status.setText("Pan/Zoom") def _set_filter(self): """Changes the filter panel mode to filtering mode.""" if self.filter_status.pan: self.toolbar_filter.pan() self.filter_status.set_status("filter") self.nav_panel_filter.status.setText("Filter") def _set_gauss_sigma(self, text_control): """ Changes the gaussian filter sigma width. Args: text_control (QLineEdit): the control where to take the sigma value """ gauss_filter = list(self.image.gauss_filter) gauss_filter[1] = float(text_control.text()) self.image.gauss_filter = tuple(gauss_filter) self.defaults.gauss_filter = tuple(gauss_filter) self.frames_panel.update_figure() def _set_gauss_toggle(self, text_control, toggle): """ Enables the gaussian filter. Args: text_control (QLineEdit): the control where to take the sigma value toggle (bool): filter on/off """ gauss_filter = list(self.image.gauss_filter) gauss_filter[0] = bool(toggle) self.image.gauss_filter = tuple(gauss_filter) self.defaults.gauss_filter = tuple(gauss_filter) self.frames_panel.update_figure() text_control.setEnabled(toggle) def _on_frames_click(self, event): """ Called by the mouse click event on the frames panel. """ #store first coordinates if not in pan mode if not self.frame_status.pan: self.frames_panel.coords0 = (event.xdata, event.ydata) self.frames_panel.selections["current"].set_visible(True) else: self.frames_panel.coords0 = (None, None) self.frames_panel.coords1 = self.frames_panel.coords0 def _on_frames_move(self, event): """ Called when the mouse moves on the frames panel. """ #first and current coordinates must be valid if None not in self.frames_panel.coords0 + (event.xdata, event.ydata)\ and not self.frame_status.pan: #get the frame number of the first and current coordinates frame0, _, _ = self._get_coord_frame(self.frames_panel.coords0) frame1, _, _ = self._get_coord_frame((event.xdata, event.ydata)) #if current coordinates are on the same frame update second coords if frame0 == frame1 and frame0 >= 0 and frame1 >= 0: self.frames_panel.coords1 = (event.xdata, event.ydata) self.frames_panel.update_current_sel() def _on_frames_release(self, event): """ Called by the mouse release event on the frames panel. """ #first check if all the coordinates are valid if None not in self.frames_panel.coords0 + self.frames_panel.coords1: frame_num, _, _ = self._get_coord_frame(self.frames_panel.coords1) #get coords relative to a single frame x01 = [ int(self.frames_panel.coords0[0] % self.image.frame_w), int(self.frames_panel.coords1[0] % self.image.frame_w) ] y01 = [ int(self.frames_panel.coords0[1] % self.image.frame_h), int(self.frames_panel.coords1[1] % self.image.frame_h) ] x01.sort() y01.sort() #check if the selection is null, and in that case add a minimum #1 pixel size if x01[0] == x01[1]: x01[1] += 1 print "Warning: null horizontal selection correted to one-sized" if y01[0] == y01[1]: y01[1] += 1 print "Warning: null vertical selection correted to one-sized" #invalidate stored coords self.frames_panel.coords0 = self.frames_panel.coords1 = (None, None) #delete (by setting it to null size) rectangle of current selection if not self.frame_status.pan: self.frames_panel.selections["current"].set_visible(False) #update respective slices if self.frame_status.min: self.image.background_slices = (slice(*y01), slice(*x01)) self.defaults.slices_bkg = self.image.background_slices if self.frame_status.max: self.image.maximum_slices = (slice(*y01), slice(*x01)) self.defaults.slices_max = self.image.maximum_slices if self.frame_status.main: self.image.main_slices = (slice(*y01), slice(*x01)) self.defaults.slices_main = self.image.main_slices #renormalize if self.frame_status.max or self.frame_status.min: #vlim must be updated self.image.vlim_img = (None, None) self.image.vlim_img_orig = (None, None) self.frames_panel.update_figure() #pick coordinates if self.frame_status.pick or self.frame_status.pick_multi: m_x = (x01[0] + x01[1]) / 2.0 m_y = (y01[0] + y01[1]) / 2.0 wid = abs(x01[0] - x01[1]) hei = abs(y01[0] - y01[1]) pick_keys = ["pick_x", "pick_y", "pick_w", "pick_h"] pick_values = [m_x, m_y, wid, hei] self.image.results.set_pick(frame_num, pick_keys, dict(zip(pick_keys, pick_values))) message = 'Coordinates: (%.1f, %.1f)' % (m_x, m_y) message += ' - Width: %d, Height: %d' % (wid, hei) self.status_bar.showMessage(message) #update results window if needed self.show_results(new_window=False) #finally restore pan mode if not self.frame_status.pan: self.frames_panel.update_areas() if not self.frame_status.pick_multi: self._set_pan_frames() def _on_filter_click(self, event): """ Called by the mouse click event on the filter panel. """ if self.filter_status.filter: self.filter_panel.coords0 = (event.xdata, event.ydata) self.filter_panel.selections["current"].set_visible(True) else: self.filter_panel.coords0 = (None, None) self.filter_panel.coords1 = self.filter_panel.coords0 def _on_filter_move(self, event): """ Called when the mouse moves on the filter panel. """ #first and current coordinates must be valid if None not in self.filter_panel.coords0 + (event.xdata, event.ydata)\ and not self.filter_status.pan: self.filter_panel.coords1 = (event.xdata, event.ydata) self.filter_panel.update_current_sel() def _on_filter_release(self, event): """ Called by the mouse release event on the filter panel. """ if None not in self.filter_panel.coords0 + self.filter_panel.coords1: x01 = [self.filter_panel.coords0[0], self.filter_panel.coords1[0]] y01 = [self.filter_panel.coords0[1], self.filter_panel.coords1[1]] x01.sort() y01.sort() if x01[0] == x01[1]: print "Warning: null horizontal selection" if y01[0] == y01[1]: print "Warning: null vertical selection" if self.filter_status.filter: #reset the selection circle self.filter_panel.selections["current"].set_visible(False) self.image.filter_points_list.append(FilterPoint()) self.image.filter_points_list[-1].\ set_from_coords(x01[0], y01[0], x01[1], y01[1]) self.update_plots() #invalidate stored coords self.filter_panel.coords0 = self.filter_panel.coords1 = (None, None) def _test_frames_vlim(self, vlim): """ Returns the validity of frames colorscale with the given correction. If valid the colorscale is update in the image class. Args: vlim (tuple): floats of the corrections to the colorscale """ test_min, test_max = self.image.get_vlim_img(corr=vlim) test_min_orig, test_max_orig = self.image.get_vlim_img_orig(corr=vlim) test_cond = test_max > test_min and test_max_orig > test_min_orig if test_cond: self.image.vlim_img_corr = vlim self.defaults.vlim_img_corr = vlim self.frames_panel.update_figure(update_img=False) return test_cond def _test_fft_vlim(self, vlim): """ Returns the validity of fft colorscale with the given correction. If valid the colorscale is update in the image class. Args: vlim (tuple): floats of the corrections to the colorscale """ test_min, test_max = self.image.get_vlim_fft(corr=vlim) test_cond = test_max > test_min if test_cond: self.image.vlim_fft_corr = vlim self.defaults.vlim_fft_corr = vlim self.filter_panel.update_figure(update_img=False) return test_cond def _update_fft_frame_menu(self): """ Initializes the menu that selects the frame to show in the fft filter panel. """ self.fft_frame_menu.clear() fft_frames = QtGui.QActionGroup(self) selections = [-2, -1] + list(self.image.valid_frames_id) #if the default frame is no more present set the average as preselected if self.defaults.fft_frame_n in selections: active = self.defaults.fft_frame_n else: active = -1 for frame_n in selections: #"no frame" and "average frame" are codified in the ImageLab class, #other frames are codified by their id if frame_n == -2: name = "None" elif frame_n == -1: name = "Average" else: name = str(frame_n) act = QtGui.QAction(name, self) act.triggered.connect(partial(self._select_fft_frame, frame_n)) act.setCheckable(True) if frame_n == active: act.setChecked(True) fft_frames.addAction(act) self.fft_frame_menu.addActions(fft_frames.actions()) def _select_fft_frame(self, num): """ Selects the frame number for the fft panel visualization. Args: num (int): the number of the frame selected """ num = int(num) if num != self.image.fft_frame_num: self.image.fft_frame_num = num self.defaults.fft_frame_n = num #invalidate current fft frame and renormalize self.image.fft_frame = None self.image.vlim_fft = (None, None) self.filter_panel.update_figure() def _filter_reset(self): """ Resets the fft filter deleting all the mask. """ self.image.filter_points_list = [] self.update_plots() def _filter_cancel_last(self): """ Deletes just the last mask point inserted in the fft filter. """ self.image.filter_points_list = self.image.filter_points_list[0:-1] self.update_plots()
class Window(QtGui.QWidget): # G2 = nil def __init__(self, parent=None): super(Window, self).__init__(parent) self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) # self.toolbar.hide() # Just some button self.button = QtGui.QPushButton('Plot') self.button.clicked.connect(self.plot) self.button1 = QtGui.QPushButton('Zoom') self.button1.clicked.connect(self.zoom) self.button2 = QtGui.QPushButton('Pan') self.button2.clicked.connect(self.pan) self.button3 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) self.button4 = QtGui.QPushButton('Home') self.button3.clicked.connect(self.home) # tabs = QtGui.QTabWidget() # tab1 = QtGui.QWidget() # tab2 = QtGui.QWidget() # set the layout layout = QtGui.QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) layout.addWidget(self.button1) layout.addWidget(self.button2) layout.addWidget(self.button3) self.setLayout(layout) def home(self): self.toolbar.home() def zoom(self): self.toolbar.zoom() def pan(self): self.toolbar.pan() def addData(self, G=None): self.G2 def plot(self): ''' plot some random stuff ''' squarify.plot(sizes=[13, 22, 35, 5], label=["group A", "group B", "group C", "group D"], alpha=.7) # plt.axis('off') # plt.show() # data = [random.random() for i in range(25)] # ax = self.figure.add_subplot(111) # ax.hold(False) # ax.plot(data, '*-') self.canvas.draw() def addData(self, G=None): G2 = G print("G2 is ->", G2)