def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) dock_position = Dock("Position") dock_area.addDock(dock_position) # Position 2d plot position_graphics = pg.GraphicsLayoutWidget() position_graphics.show() view = position_graphics.addViewBox() self.position_img = pg.ImageItem(border='w') view.addItem(self.position_img) dock_position.addWidget(position_graphics) # Status widget dock_status = Dock("Status", size=(800, 1)) dock_area.addDock(dock_status, 'top') cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.spin_box = Qt.QSpinBox(value=1) self.spin_box.setMaximum(10) self.spin_box.setSuffix(" Threshold") layout.addWidget(self.spin_box, 0, 6, 0, 1) dock_status.addWidget(cw) self.spin_box.valueChanged.connect(lambda value: self.send_command(str(value)))
def onAddPlot(self): name, ok = QtGui.QInputDialog.getText(self, 'Plot Name', 'Please enter a plot name: ') if ok and name!= 'Autoload': name = str(name) dock = Dock(name) widget = DateTimePlotWidget(self) view = widget._graphicsView self.area.addDock(dock, "bottom") dock.addWidget(widget) self.plotDict[name] = {"dock":dock, "widget":widget, "view":view}
def onAddPlot(self): name, ok = QtWidgets.QInputDialog.getText(self, 'Plot Name', 'Please enter a plot name: ') if ok: name = str(name) dock = Dock(name) widget = CoordinatePlotWidget(self) view = widget._graphicsView self.area.addDock(dock, "bottom") dock.addWidget(widget) self.plotDict[name] = {"dock":dock, "widget":widget, "view":view} self.plotConfigurationChanged.emit( self.plotDict )
def __init__(self, deviceClass, config, parent=None): Base.__init__(self, parent) Form.__init__(self) Form.setupUi(self, self) self.config = config self.configname = "AWGOptimizer" self.setWindowTitle("AWG Optimizer") guiState = self.config.get(self.configname+".guiState") state = self.config.get(self.configname+'.state') pos = self.config.get(self.configname+'.pos') size = self.config.get(self.configname+'.size') isMaximized = self.config.get(self.configname+'.isMaximized') restoreGuiState(self, self.config.get(self.configname+".guiState")) if state: self.restoreState(state) if pos: self.move(pos) if size: self.resize(size) if isMaximized: self.showMaximized() self.show() self.awgUi = AWGUi(deviceClass, config, dict()) self.awgUi.setupUi(self.awgUi) self.splitter.insertWidget(1, self.awgUi) #oscilloscope plot window name = "Oscilloscope Trace" self.scopeDock = Dock(name) self.scopePlot = CoordinatePlotWidget(self, name=name) self.scopeView = self.scopePlot._graphicsView self.scopeDock.addWidget(self.scopePlot) self.area = DockArea() self.area.addDock(self.scopeDock) self.plotDict ={name: {"dock":self.scopeDock, "widget":self.scopePlot, "view":self.scopeView}} self.verticalLayout.insertWidget(0, self.area) #trace ui self.penicons = pens.penicons().penicons() self.traceui = Traceui.Traceui(self.penicons, self.config, self.configname, self.plotDict, hasMeasurementLog=False, highlightUnsaved=False) self.traceui.setupUi(self.traceui) traceDock = Dock("Traces") traceDock.addWidget(self.traceui) self.area.addDock(traceDock, 'left') self.device = self.awgUi.device self.measureWaveformButton.clicked.connect(self.onMeasureWaveform) self.optimizeButton.clicked.connect(self.onOptimize) dockAreaState = self.config.get(self.configname+'.dockAreaState') try: if dockAreaState: self.area.restoreState(dockAreaState) except Exception as e: print(e)
def setup_plots(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) dock_position = Dock("Position Correlation") dock_area.addDock(dock_position) # Position 2d plot position_graphics = pg.GraphicsLayoutWidget() position_graphics.show() view = position_graphics.addViewBox() self.position_img = pg.ImageItem(border='w') view.addItem(self.position_img) dock_position.addWidget(position_graphics)
def add_plot_dock(self, depth, widget): dock = Dock(depth, size=(1,1), closable=False, autoOrientation=False) split_dock_widget = SplitDockWidget(widget) ### Connect signals ### self.s.x_range_updated.connect(widget.set_x_range) self.s.y_range_updated.connect(widget.set_y_range) widget.s.title_updated.connect(dock.setTitle) if settings.annotation_on: self.toggle_annotation.toggled.connect(split_dock_widget.toggle_second_widget) dock.addWidget(split_dock_widget) self.selected_depths[depth] = dock
def setupPlots(self): self.area = DockArea() self.setCentralWidget(self.area) self.plotDict = dict() # initialize all the plot windows we want plotNames = self.config.get( 'PlotNames', ['Scan'] ) if len(plotNames)<1: plotNames.append('Scan') for name in plotNames: dock = Dock(name) widget = CoordinatePlotWidget(self) view = widget._graphicsView self.area.addDock(dock, "bottom") dock.addWidget(widget) self.plotDict[name] = {"dock":dock, "widget":widget, "view":view}
def setupPlots(self): self.area = DockArea() self.setCentralWidget(self.area) self.plotDict = SequenceDict() # initialize all the plot windows we want plotNames = self.config.get(self.configName+'.PlotNames', ['Plot']) if len(plotNames) < 1: plotNames.append('Plot') if 'Autoload' not in plotNames: plotNames.append('Autoload') for name in plotNames: dock = Dock(name) widget = DateTimePlotWidget(self, name=name) view = widget._graphicsView self.area.addDock(dock, "bottom") dock.addWidget(widget) self.plotDict[name] = {"dock":dock, "widget":widget, "view":view}
def initDialog(self,results=None,KData=None,bDrawText=False): # 1) creates layouts dialog = QtGui.QDialog() mainLayout = QtGui.QHBoxLayout() rightLayout = QtGui.QVBoxLayout() mainLayout.addLayout(rightLayout) dialog.setLayout(mainLayout) dialog.setWindowTitle(('Strategy Results')) # 2) creates widgets from Widgets.pgCandleWidgetCross import pgCandleWidgetCross from Widgets.pgCrossAddition import pgCrossAddition from pyqtgraph.dockarea import DockArea,Dock area = DockArea() ## Create docks, place them into the window one at a time. ## Note that size arguments are only a suggestion; docks will still have to ## fill the entire dock area and obey the limits of their internal widgets. d1 = Dock("price", size=(200,100)) d2 = Dock("position", size=(200,100)) area.addDock(d1, 'bottom') area.addDock(d2, 'bottom') rightLayout.addWidget(area) pgCandleView = pgCandleWidgetCross(dataForCandle=KData) PyqtGraphindicators = pgCrossAddition() toShow = pgCandleView self.pricePlot(toShow) d1.addWidget(toShow) PyqtGraphPosition = pgCrossAddition() self.positionPlot(PyqtGraphPosition) d2.addWidget(PyqtGraphPosition) PyqtGraphPosition.showGrid(x=True, y=True) PyqtGraphPosition.setXLink(toShow) return dialog
def load_protocol(self, path): lua = lupa.LuaRuntime(attribute_handlers=(getter, setter)) self.lua = lua lua.globals()["flow"] = flow lua.globals()["channels"] = self.context.get_channels() lua.globals()["context"] = self.context source = open(path).read() try: lua.execute(source) self.guiBlocks = lua.eval('setup()') #lua.eval('gui()') except Exception as e: print ('Lua Exception occured: ', e, type(e)) raise for block in self.guiBlocks: dock = Dock(block.name) dock.addWidget(block.widget()) self.dockarea.addDock(dock) if 'doc_config' in lua.globals(): self.restore_layout()
def initDialogSummary(self,result,KData=None): # 1) creates layouts dialog = QtGui.QDialog() mainLayout = QtGui.QHBoxLayout() rightLayout = QtGui.QVBoxLayout() mainLayout.addLayout(rightLayout) dialog.setLayout(mainLayout) dialog.setWindowTitle(('Strategy Results')) import os,sys xpower = os.path.abspath(os.path.join(os.path.dirname(__file__),os.pardir,os.pardir,os.pardir,'midProjects','histdataUI')) sys.path.append(xpower) from Widgets.pgCandleWidgetCross import pgCandleWidgetCross from Widgets.pgCrossAddition import pgCrossAddition from pyqtgraph.dockarea import DockArea,Dock area = DockArea() rightLayout.addWidget(area) # 2) creates widgets # 2.1)candle pgCandleView = pgCandleWidgetCross(dataForCandle=KData) dCandle = Dock("candles",closable=True, size=(200,300)) ## give this dock the minimum possible size area.addDock(dCandle, 'bottom') dCandle.addWidget(pgCandleView) # 2) creates widgets # 2.3)position_cost if(True): PyqtGraphPositionCost = pgCrossAddition() self.availableCashPlot(PyqtGraphPositionCost) dAvailableCash = Dock("available_cash",closable=True, size=(200,100)) area.addDock(dAvailableCash, 'bottom') dAvailableCash.addWidget(PyqtGraphPositionCost) PyqtGraphPositionCost.setXLink(pgCandleView) # 2.3)position_cost if(True): PyqtGraphPositionCost = pgCrossAddition() self.portfolioPlot(PyqtGraphPositionCost) dPortfolioValue = Dock("portfolio_value",closable=True, size=(200,100)) area.addDock(dPortfolioValue, 'bottom') dPortfolioValue.addWidget(PyqtGraphPositionCost) PyqtGraphPositionCost.setXLink(pgCandleView) return dialog
def add_widgets(self): # Main window with dock area self.dock_area = DockArea() self.setCentralWidget(self.dock_area) # Docks dock_waveform = Dock("Waveform", size=(600, 400)) dock_histogram = Dock("Histogram", size=(600, 400)) dock_status = Dock("Status", size=(1200, 40)) self.dock_area.addDock(dock_waveform, 'left') self.dock_area.addDock(dock_histogram, 'right', dock_waveform) self.dock_area.addDock(dock_status, 'top') # Status widget cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() layout.setColumnStretch(2, 1) cw.setLayout(layout) self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.total_events_label = QtGui.QLabel("Total Events\n0") self.spin_box = Qt.QSpinBox(value=20, maximum=1000) self.reset_button = Qt.QPushButton('Reset', self) self.reset_button.clicked.connect(self.reset_plots) layout.addWidget(self.event_rate_label, 0, 1, 1, 1) layout.addWidget(self.total_events_label, 1, 1, 1, 1) layout.addWidget(self.spin_box, 0, 3, 1, 1) layout.addWidget(self.reset_button, 1, 3, 1, 1) dock_status.addWidget(cw) # Different plot docks waveform_widget = pg.PlotWidget(background="w") self.waveform_plot = waveform_widget.plot(range(0, 200), np.zeros(shape=(200))) self.thr_line = pg.InfiniteLine(pos=1000, angle=0, pen={'color':0.0, 'style':QtCore.Qt.DashLine}) waveform_widget.addItem(self.thr_line) dock_waveform.addWidget(waveform_widget) histogram_widget = pg.PlotWidget(background="w") self.histogram_plot = histogram_widget.plot(range(0, 2**14 + 1), np.zeros(shape=(2**14)), stepMode=True) histogram_widget.showGrid(y=True) self.thr_line_hist = pg.InfiniteLine(pos=1000, angle=90, pen={'color':0.0, 'style':QtCore.Qt.DashLine}) histogram_widget.addItem(self.thr_line_hist) dock_histogram.addWidget(histogram_widget)
class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() self.layerC = 1 self.layerObjList = [[] for i in range(self.layerC + 1)] self.typeObjList = {} self.busNames = [] self.busObjList = defaultdict(list) self.totalObj, self.totalObjC, self.totalObjInfo = [], [], [] self.typeAction = [] self.layerAction = [] self.busAction = [] # tmp self.tmpObjName = '' self.tmpBusName = '' def resizeLayer(self, layerC): self.layerObjList.extend([[] for i in range(layerC - self.layerC)]) self.pointList.extend([[[], []] for i in range(layerC - self.layerC)]) self.lineList.extend([[[], []] for i in range(layerC - self.layerC)]) self.rectList.extend([[] for i in range(layerC - self.layerC)]) self.layerC = layerC def start(self): self.win = QtGui.QMainWindow() self.win.resize(1000, 500) self.win.setWindowTitle(title) self.area = DockArea() self.visualizeDock = Dock("Visualization", size=(800, 500)) self.visualizePlt = pg.PlotWidget(background=(255, 255, 255)) self.visualizePlt.setTitle(title=opt.input, color=(0, 0, 0)) self.visualizePlt.showGrid(x=True, y=True) self.visualizePlt.getAxis("left").setPen((0, 0, 0)) self.visualizePlt.getAxis("top").setPen((0, 0, 0)) self.visualizePlt.getAxis("bottom").setPen((0, 0, 0)) self.visualizePlt.getAxis("right").setPen((0, 0, 0)) self.buttonDock = Dock("Buttons", size=(100, 500)) self.bottonScroll = QtGui.QScrollArea() self.buttonGroup = QtGui.QGroupBox() self.bottonVBox = QtGui.QVBoxLayout() def end(self): self.buttonGroup.setLayout(self.bottonVBox) self.bottonScroll.setWidget(self.buttonGroup) self.buttonDock.addWidget(self.bottonScroll) self.visualizeDock.addWidget(self.visualizePlt) self.area.addDock(self.buttonDock) self.area.addDock(self.visualizeDock, 'left', self.buttonDock) self.win.setCentralWidget(self.area) self.win.show() def beginObj(self, name): self.typeObjList[name] = [] self.tmpObjName = name def beginBus(self, name): self.tmpBusName = name self.pointList = [[[], []] for i in range(self.layerC + 1)] self.lineList = [[[], []] for i in range(self.layerC + 1)] self.rectList = [[] for i in range(self.layerC + 1)] def addPoint(self, x, y, z): self.pointList[z][0].append(x) self.pointList[z][1].append(y) def addLine(self, x0, y0, z0, x1, y1, z1): self.lineList[z0][0].extend([x0, x1]) self.lineList[z0][1].extend([y0, y1]) def addRect(self, x0, y0, x1, y1, z): self.rectList[z].append((x0, y0, x1 - x0, y1 - y0)) def endBus(self, lineWidth, symbol): self.addObjs(lineWidth, symbol) def addObjs(self, lineWidth, symbol): pen = pg.mkPen((0, 0, 0), width=lineWidth) brushes = [pg.mkBrush(color) for color in layerColor] for z, (xs, ys) in enumerate(self.pointList): if len(xs) > 0: scatter = pg.ScatterPlotItem(size=15, pen=None, symbol=symbol, symbolBrush=brushes[z - 1]) scatter.addPoints(xs, ys) self.addObj(scatter, z) for z, lines in enumerate(self.lineList): if len(lines[0]) > 0: connect = np.ones(len(lines[0]), dtype=np.ubyte) connect[1::2] = 0 line = pg.arrayToQPath(np.array(lines[0]), np.array(lines[1]), connect) line = QtGui.QGraphicsPathItem(line) line.setPen(pen) self.addObj(line, z) self.totalObjInfo.append( (self.line2rect(lines), z, self.tmpBusName)) for z, rects in enumerate(self.rectList): if len(rects) > 0: obj = QtGui.QGraphicsItemGroup() for i, rect in enumerate(rects): rect = QtGui.QGraphicsRectItem(*rect) rect.setPen(pen) rect.setBrush(brushes[z - 1]) obj.addToGroup(rect) obj.mouseDoubleClickEvent = self.printInfo self.addObj(obj, z) self.totalObjInfo.append((rects, z, self.tmpBusName)) def addObj(self, obj, z): obj.setZValue(z) self.visualizePlt.addItem(obj) self.layerObjList[z].append((obj, len(self.totalObj))) self.typeObjList[self.tmpObjName].append((obj, len(self.totalObj))) self.busObjList[self.tmpBusName].append((obj, len(self.totalObj))) self.totalObj.append((obj, 3)) self.totalObjC.append(3) def line2rect(self, ls): rtn = [] for i in range(0, len(ls[0]), 2): rtn.append((ls[0][i], ls[1][i], ls[0][i + 1] - ls[0][i], ls[1][i + 1] - ls[1][i])) return rtn def printInfo(self, event): x = event.lastPos().x() y = event.lastPos().y() clicked_infos = [] for i in range(len(self.totalObjInfo)): if self.totalObjC[i] != self.totalObj[i][1]: continue infos, z, busName = self.totalObjInfo[i] for info in infos: if info[0] <= x <= info[0] + info[2] and info[ 1] <= y <= info[1] + info[3]: name = "{}".format(busName) xyz = "({:d}, {:d}, {:d}), ({:d}, {:d}, {:d})".format( info[0], info[1], z, info[0] + info[2], info[1] + info[3], z) wh = "width = {}, height = {}".format(info[2], info[3]) clicked_infos.append("\n".join(["-" * 30, xyz, wh, name])) msg = QtGui.QMessageBox( QtGui.QMessageBox.Information, "Informations", "clicked on {}, {}\n".format(int(x), int(y)) + "\n".join(clicked_infos)) msg.exec_() def sortByNum(self, y): return re.sub('\d+', lambda m: m.group().zfill(9), y) def resetAction(self, action, st): action.blockSignals(True) action.setChecked(st) action.blockSignals(False) def updateSt(self, st, objs): for obj, i in objs: if st: self.totalObjC[i] += 1 if self.totalObjC[i] == self.totalObj[i][1]: obj.show() else: self.totalObjC[i] -= 1 if self.totalObjC[i] != self.totalObj[i][1]: obj.hide() def typeFunc(self, st, label): self.updateSt(st, self.typeObjList[label]) def totalLayerFunc(self, st): for i in range(len(self.layerAction)): if self.layerAction[i].isChecked() != st: self.updateSt(st, self.layerObjList[i + 1]) self.resetAction(self.layerAction[i], st) def layerFunc(self, st, idx): self.updateSt(st, self.layerObjList[idx]) def totalBusFunc(self, st): for i in range(len(self.busNames)): if self.busAction[i].isChecked() != st: self.updateSt(st, self.busObjList[self.busNames[i]]) self.resetAction(self.busAction[i], st) def busFunc(self, st, idx): self.updateSt(st, self.busObjList[self.busNames[idx]]) def typeMenu(self): typyM = QtGui.QMenu() for typeName, condition in visClass.items(): if condition[0]: self.typeAction.append(typyM.addAction(typeName)) self.typeAction[-1].setCheckable(True) self.typeAction[-1].setChecked(True) self.typeAction[-1].toggled.connect( partial(self.typeFunc, label=typeName)) self.bottonVBox.addWidget(typyM) def layerMenu(self): totalLayerM = QtGui.QMenu() self.totalBusAction = totalLayerM.addAction("Total Layer") self.totalBusAction.setCheckable(True) self.totalBusAction.setChecked(True) self.totalBusAction.toggled.connect(self.totalLayerFunc) self.bottonVBox.addWidget(totalLayerM) layerM = QtGui.QMenu() for i in range(1, self.layerC + 1): if (i % 2 == 1): self.layerAction.append( layerM.addAction('MetalLayer' + str((i + 1) // 2))) else: self.layerAction.append( layerM.addAction('ViaLayer' + str(i // 2))) self.layerAction[-1].setCheckable(True) self.layerAction[-1].setChecked(True) self.layerAction[-1].toggled.connect(partial(self.layerFunc, idx=i)) layerButton = QtGui.QPushButton("Layers") layerButton.setMenu(layerM) self.bottonVBox.addWidget(layerButton) def busMenu(self): self.busNames = list(sorted(self.busObjList.keys(), key=self.sortByNum)) totalBusM = QtGui.QMenu() self.totalBusAction = totalBusM.addAction("Total Bus") self.totalBusAction.setCheckable(True) self.totalBusAction.setChecked(True) self.totalBusAction.toggled.connect(self.totalBusFunc) self.bottonVBox.addWidget(totalBusM) for i, busName in enumerate(self.busNames): busM = QtGui.QMenu() self.busAction.append(busM.addAction(busName)) self.busAction[-1].setCheckable(True) self.busAction[-1].setChecked(True) self.busAction[-1].toggled.connect(partial(self.busFunc, idx=i)) font = busM.font() font.setPointSize(9) busM.setFont(font) self.bottonVBox.addWidget(busM)
class MeasuringApp(CamObject, QtGui.QMainWindow): def __init__(self, *args, **kwargs): CamObject.__init__(self) QtGui.QMainWindow.__init__(self) self.resize(700, 150) self.setWindowTitle('Workpiece Dimensional Control') self.area = DockArea() self.setCentralWidget(self.area) # Window Docks self.camMenuDock = Dock('Camera Menu', size=(1, 1)) self.procMenuDock = Dock('Analysis Menu', size=(1, 1)) self.paramDock = Dock('Parameter Tree', size=(250, 150)) self.area.addDock(self.camMenuDock, 'right') self.area.addDock(self.procMenuDock, 'right') self.area.addDock(self.paramDock, 'left') # Parameter Tree self._parameter_tree = ParameterTree() self._parameter_tree.setWindowTitle('Parameter Tree') self.paramDock.addWidget(self._parameter_tree) # Camera Menu self._cam_menu = pg.LayoutWidget(parent=self.camMenuDock) self._cam_buttons = self.cam_buttons() [btn.resize(btn.minimumSizeHint()) for btn in self._cam_buttons] [self._cam_menu.addWidget(btn, row=i, col=0) for btn, i in zip( self._cam_buttons, range(len(self._cam_buttons)))] self.camMenuDock.addWidget(self._cam_menu) # Analysis menu self._proc_menu = pg.LayoutWidget(parent=self.procMenuDock) self._proc_buttons = self.process_buttons() [btn.resize(btn.minimumSizeHint()) for btn in self._proc_buttons] [self._proc_menu.addWidget(btn, row=i, col=1) for btn, i in zip( self._proc_buttons, range(len(self._proc_buttons)))] self.procMenuDock.addWidget(self._proc_menu) # Original frames window self._orig_frame = FrameWindow("Original") # Flowchart input preparation window self._prep_flow = FlowchartPrepWindow('Flowchart Input preparation') # Calibrate system window self._calib_window = FlowchartCalibrateWindow() # Calibration Parameters self._calib_params = None # Measurement preparation window self._measure_prep_window = FlowchartMeasureWindow() # Realtime measurement window self._realtime_measure_window = MeasureRealtimeWindow() # Show Main Window self.show() # Result Queue init self.preproc_queue = queue.Queue() # FPS display count self.fps_display_count = 0 def cam_buttons(self): """ Menu buttons as list """ # Camera create button cam_create = QtGui.QPushButton('Find Camera', parent=self._cam_menu) cam_create.clicked.connect(self.create) # Camera open button cam_open = QtGui.QPushButton('Open Camera', parent=self._cam_menu) cam_open.clicked.connect(self.open) # Camera print info cam_print_info = QtGui.QPushButton('Print Info', parent=self._cam_menu) cam_print_info.clicked.connect(self.print_info) # Camera start grabbing cam_start_grab = QtGui.QPushButton( 'Start Grabbing', parent=self._cam_menu) cam_start_grab.clicked.connect(self.start_grabbing) # Camera stop grabbing cam_stop_grab = QtGui.QPushButton( 'Stop Grabbing', parent=self._cam_menu) cam_stop_grab.clicked.connect(self.stop_grabbing) # Camera close cam_close = QtGui.QPushButton('Close Camera', parent=self._cam_menu) cam_close.clicked.connect(self.close) return [ cam_create, cam_open, cam_print_info, cam_start_grab, cam_stop_grab, cam_close ] def process_buttons(self): """ Process buttons as list """ # Grab single frame button proc_grab_frame = QtGui.QPushButton( 'Grab Frame', parent=self._proc_menu) proc_grab_frame.clicked.connect(self.grab_single_frame) proc_discard_frame = QtGui.QPushButton( 'Discard Frame', parent=self._proc_menu) proc_discard_frame.clicked.connect(self.discard_frame) proc_calib_sys = QtGui.QPushButton( 'Calibrate System', parent=self._proc_menu) proc_calib_sys.clicked.connect(self.calibrate_system) proc_set_calib_const = QtGui.QPushButton( 'Set Calibration Constants', parent=self._proc_menu) proc_set_calib_const.clicked.connect(self.set_calib_const) proc_measure_prep = QtGui.QPushButton( 'Measurement Preparation', parent=self._proc_menu) proc_measure_prep.clicked.connect(self.measurement_preparation) proc_realtime_start = QtGui.QPushButton( 'Start Measurement', parent=self._proc_menu) proc_realtime_start.clicked.connect(self.start_realtime_measurement) proc_realtime_stop = QtGui.QPushButton( 'Stop Measurement', parent=self._proc_menu) proc_realtime_stop.clicked.connect(self.stop_realtime_measurement) return [ proc_grab_frame, proc_discard_frame, proc_calib_sys, proc_set_calib_const, proc_measure_prep, proc_realtime_start, proc_realtime_stop ] def open(self): """ Reimplementation of open function to update GUI numbers and sliders """ super().open() self._parameter_tree.clear() self._parameter_tree.addParameters( CameraParams(name='Camera Parameters', cam_obj=self), showTop=True) def close(self): """ Reimplementation of close function to update GUI numbers and sliders """ super().close() self._parameter_tree.clear() def set_default_params(self): """ Reimplementation of set_default_params function to update GUI """ super().set_default_params() self._cam_gain.value = self.cam.Gain() self._cam_exposure.value = self.cam.ExposureTime() self._cam_width.value = self.cam.Width.GetValue() self._cam_height.value = self.cam.Height.GetValue() self._cam_offsetx.value = self.cam.OffsetX.GetValue() self._cam_offsety.value = self.cam.OffsetY.GetValue() def start_grabbing(self, strategy=pylon.GrabStrategy_LatestImageOnly): """ Reimplementation of start_grabbing to show new window """ if not self.cam.IsGrabbing(): self._orig_frame.show() self.frame_queue = queue.Queue() fg_hndl = FrameGrabEventHandler(self.frame_queue) # Frame grab event registering self.cam.RegisterImageEventHandler( fg_hndl, pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_Delete ) super().start_grabbing(strategy) self.frame_burst(graphicsObject=self._orig_frame) def stop_grabbing(self): """ Reimplementation of stop_grabbing to close new window """ if self.cam.IsGrabbing(): super().stop_grabbing() self._orig_frame.close() def frame_burst(self, graphicsObject, updateFrame=True, updateFPS=True, updateMeasurementResult=False, numProc=1, fps_display=5): """ Grab frames from camera using software trigger, scheduling and event handler. frame_burst reimplementation for FPS, frame and measurement result update. :param graphicsObject: object which methods are called and graphics updated :param updateFrame: bool :param updateFPS: bool :param updateMeasurementResult: bool :param numProc: 1 :param fps_display: int """ if self.fps_count == 0: if updateFPS: # Update graphicsObject FPS label graphicsObject.update_fps(self.fps) self.fps_start = pg.ptime.time() if self.cam.IsGrabbing(): for _ in range(numProc): if self.cam.WaitForFrameTriggerReady( 300, pylon.TimeoutHandling_ThrowException): self.cam.ExecuteSoftwareTrigger() frames = [self.frame_queue.get() for _ in range(numProc)] self.fps_display_count += 1 # print('FPS_display_count: {}'.format(self.fps_display_count)) if updateFrame and not (self.fps_display_count % fps_display): self.fps_display_count = 0 # Update graphicsObject ImageItem [graphicsObject.update_frame(frame) for frame in frames] self.fps_count += numProc if updateMeasurementResult: while not self.preproc_queue.empty(): graphicsObject.update_measurement_result( self._measure_prep_window.fc_process( dip.Image(self.preproc_queue.get()) )) # Average FPS on number of frames if self.fps_count >= 10: fps_time = pg.ptime.time() - self.fps_start self.fps = self.fps_count / fps_time print("Camera FPS: {:.2f}".format( self.cam.ResultingFrameRate.GetValue())) print("FPS: {:.2f}".format(self.fps)) self.fps_count = 0 QtCore.QTimer.singleShot( 1, lambda : self.frame_burst(graphicsObject, updateFrame, updateFPS, numProc, )) def grab_single_frame(self): self._prep_flow.set_frame(self._orig_frame.grab_single_frame()) self._prep_flow.show() def discard_frame(self): self._prep_flow.close() def calibrate_system(self): """ Show Calibration flowchart and set input frame """ self._calib_window.setInput(self._prep_flow.get_dip_slice()) self._calib_window.show() def set_calib_const(self): """ Set and show calibration parameters in parameterTree """ standard_dict = self._calib_window.output() self._calib_params = CalibrationParams( name='Calibration Parameters', standard_dict=standard_dict) self._parameter_tree.clear() self._parameter_tree.addParameters(self._calib_params, showTop=True) def measurement_preparation(self): """ Show Measurement preparation flowchart and set input frame """ self._measure_prep_window.setInput( self._prep_flow.get_dip_slice(), self._calib_params.obj_mm_px.value() ) self._measure_prep_window.show() def start_realtime_measurement( self, strategy=pylon.GrabStrategy_LatestImageOnly): """ Show window for realtime measurement and start grabbing frames from cam """ if not self.cam.IsGrabbing(): self._realtime_measure_window.show() procParallel = ProcessParallel( self._measure_prep_window, numberProc=3 ) # Queue for storing frames self.frame_queue = queue.Queue() # Queue for storing measurement result list self.preproc_queue = queue.Queue() self.fm_hndl = FrameMeasureEventHandler( self.frame_queue, self.preproc_queue, procParallel ) # Frame grab event registering self.cam.RegisterImageEventHandler( self.fm_hndl, pylon.RegistrationMode_ReplaceAll, pylon.Cleanup_Delete ) super().start_grabbing(strategy) self.frame_burst( graphicsObject=self._realtime_measure_window, updateFPS=False, updateMeasurementResult=True, fps_display=10, # numProc=procParallel.getNumProc() ) def stop_realtime_measurement(self): """ Close window for realtime measurement and stop grabbing frames from cam """ if self.cam.IsGrabbing(): super().stop_grabbing() self._realtime_measure_window.close() self.cam.DeregisterImageEventHandler(self.fm_hndl)
class OnlineMonitorApplication(pg.Qt.QtGui.QMainWindow): app_name = 'Online Monitor' def __init__(self, config_file, loglevel='INFO'): super(OnlineMonitorApplication, self).__init__() utils.setup_logging(loglevel) logging.debug("Initialize online monitor with configuration in %s", config_file) self.configuration = utils.parse_config_file(config_file, expect_receiver=True) self.setup_style() self.setup_widgets() self.receivers = self.start_receivers() def closeEvent(self, event): super(OnlineMonitorApplication, self).closeEvent(event) self.stop_receivers() settings.set_window_geometry(self.geometry().getRect()) def setup_style(self): self.setWindowTitle(self.app_name) stored_windows_geometry = settings.get_window_geometry() if stored_windows_geometry: self.setGeometry(pg.Qt.QtCore.QRect(*stored_windows_geometry)) # Fore/Background color pg.setConfigOption('background', 'w') pg.setConfigOption('foreground', 'k') # Enable antialiasing for prettier plots pg.setConfigOptions(antialias=True) def start_receivers(self): receivers = [] try: self.configuration['receiver'] except KeyError: return receivers if self.configuration['receiver']: logging.info('Starting %d receivers', len(self.configuration['receiver'])) for (receiver_name, receiver_settings) in self.configuration['receiver'].items(): receiver_settings['name'] = receiver_name receiver = utils.load_receiver(receiver_settings['kind'], base_class_type=Receiver, *(), **receiver_settings) receiver.setup_widgets(self.tab_widget, name=receiver_name) receiver.start() receivers.append(receiver) return receivers def on_tab_changed(self, value): for index, actual_receiver in enumerate(self.receivers, start=1): # First index is status tab widget actual_receiver.active(True if index == value else False) def stop_receivers(self): if self.receivers: logging.info('Stopping %d receivers', len(self.receivers)) for receiver in self.receivers: receiver.shutdown() def setup_widgets(self): # Main window with Tab widget self.tab_widget = Qt.QTabWidget() self.setCentralWidget(self.tab_widget) self.setup_status_widget(self.tab_widget) self.tab_widget.currentChanged.connect(self.on_tab_changed) def setup_status_widget(self, parent): # Visualizes the nodes + their connections + CPU usage # Status dock area showing setup dock_area = DockArea() parent.addTab(dock_area, 'Status') self.status_dock = Dock("Status") dock_area.addDock(self.status_dock) # GraphicsLayout to align graphics status_graphics_widget = pg.GraphicsLayoutWidget() status_graphics_widget.show() self.status_dock.addWidget(status_graphics_widget) try: self.configuration['receiver'] except KeyError: return # Create nodes with links from configuration file for converter/receiver for receiver_index, (receiver_name, receiver_settings) in enumerate(self.configuration['receiver'].items()): # Add receiver info view = status_graphics_widget.addViewBox(row=receiver_index, col=5, lockAspect=True, enableMouse=False) text = pg.TextItem('Receiver\n%s' % receiver_name, border='b', fill=(0, 0, 255, 100), anchor=(0.5, 0.5), color=(0, 0, 0, 200)) text.setPos(0.5, 0.5) view.addItem(text) # Add corresponding producer info try: if self.configuration['converter']: try: actual_converter = self.configuration['converter'][receiver_name] view = status_graphics_widget.addViewBox(row=receiver_index, col=1, lockAspect=True, enableMouse=False) text = pg.TextItem('Producer\n%s' % receiver_name, border='b', fill=(0, 0, 255, 100), anchor=(0.5, 0.5), color=(0, 0, 0, 200)) text.setPos(0.5, 0.5) view.addItem(text) view = status_graphics_widget.addViewBox(row=receiver_index, col=3, lockAspect=True, enableMouse=False) text = pg.TextItem('Converter\n%s' % receiver_settings, border='b', fill=(0, 0, 255, 100), anchor=(0.5, 0.5), color=(0, 0, 0, 200)) text.setPos(0.5, 0.5) view.addItem(text) except KeyError: # no converter for receiver pass except KeyError: # No converter defined in configruation pass
class AppDockArea(DockArea): def __init__(self, parent=None): DockArea.__init__(self, parent=parent) self._status_dict = defaultdict(lambda: True) self.app = App() self.crystal_controller = CrystalsController( self.app.crystals_database, self, self) self.crystal_viewer = MainCrystalViewer(self.crystal_controller, self) self.__init_image_viewer() self.__init_polar_viewer() # self.__init_control_widget__() self.__init_radial_widget() self.__init_file_widget() self.__init_angular_widget() self.__init_crystal_image_widget() self._DOCK_DICT = { 'image_view': self.image_viewer_dock, 'polar': self.polar_viewer_dock, 'radial_profile': self.radial_profile_dock, 'file_widget': self.file_dock, 'angular_profile': self.angular_profile_dock, 'crystal_image': self.crystal_image_viewer_dock } self._apply_default_view() self._fit_widget = None self.app.image_holder.sigFitOpen.connect(self._open_fit_widget) def open_load_from_h5_window(self): self.app.save_state() load_window = LoadFromH5Widget(self) load_window.sigLoadClicked.connect( self.app.data_manager.load_project_from_h5) load_window.show() def open_save_window(self): self.app.save_state() save_window = SaveWindow(self) save_window.sigSaveClicked.connect(self.app.data_manager.save) save_window.show() def _open_fit_widget(self, fit_object): fit_widget = FitWidget(fit_object, parent=self.parent()) fit_widget.sigFitApplyActiveImage.connect( self.app.image_holder.apply_fit) def _apply_default_view(self): self.show_hide_docks('polar') self.show_hide_docks('radial_profile') self.show_hide_docks('angular_profile') self.show_hide_docks('crystal_image') # self.show_hide_docks('control') def __init_image_viewer(self): self.image_view = Basic2DImageWidget(self) dock = Dock('ImageViewer') dock.addWidget(self.image_view) self.addDock(dock, size=(1000, 1000)) self.image_viewer_dock = dock def __init_polar_viewer(self): self.polar_view = PolarImageViewer(self) dock = Dock('PolarImageViewer') dock.addWidget(self.polar_view) self.addDock(dock, position='right') self.polar_viewer_dock = dock def __init_radial_widget(self): self.radial_profile = RadialProfileWidget(self) dock = Dock('Radial Profile') dock.addWidget(self.radial_profile) self.addDock(dock, position='bottom') self.radial_profile_dock = dock def __init_angular_widget(self): self.angular_profile = AngularProfileWidget(self) dock = Dock('Angular Profile') dock.addWidget(self.angular_profile) self.addDock(dock, position='bottom') self.angular_profile_dock = dock def __init_crystal_image_widget(self): self.crystal_image_viewer = CrystalImageWidget(self) self.crystal_controller.connect_image_widget(self.crystal_image_viewer) dock = Dock('Crystal Image Viewer') dock.addWidget(self.crystal_image_viewer) self.addDock(dock, position='right') self.crystal_image_viewer_dock = dock # def __init_control_widget__(self): # self.control_widget = ControlWidget( # self.get_lower_connector('ControlWidget'), self) # control_dock = Dock('Segments') # control_dock.addWidget(self.control_widget) # self.addDock(control_dock, position='right') # self.control_dock = control_dock def __init_file_widget(self): self.file_widget = MainFileWidget(self.app.fm, self) self.file_dock = Dock('Project') self.file_dock.addWidget(self.file_widget) self.addDock(self.file_dock, position='left') def show_hide_docks(self, dock_name: str): assert dock_name in self._DOCK_DICT.keys() dock = self._DOCK_DICT[dock_name] status = self._status_dict[dock_name] if status: dock.hide() else: dock.show() self._status_dict[dock_name] = not status def show_hide_crystal_database(self): if self.crystal_viewer.isHidden(): self.crystal_viewer.show() self.crystal_image_viewer_dock.show() else: self.crystal_viewer.close() self.crystal_image_viewer_dock.hide()
def __init_polar_viewer(self): self.polar_view = PolarImageViewer(self) dock = Dock('PolarImageViewer') dock.addWidget(self.polar_view) self.addDock(dock, position='right') self.polar_viewer_dock = dock
def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) # Occupancy Docks self.occupancy_images = [] for plane in range(3): # Loop over 3 * 2 plot widgets # Dock left dock_occcupancy = Dock("Occupancy plane %d" % 2 * plane, size=(100, 200)) dock_area.addDock(dock_occcupancy) occupancy_graphics = pg.GraphicsLayoutWidget() # Plot docks occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_images.append(pg.ImageItem(border='w')) view.addItem(self.occupancy_images[2 * plane]) view.setRange(QtCore.QRectF(0, 0, 80, 336)) dock_occcupancy.addWidget(occupancy_graphics) # Dock right dock_occcupancy_2 = Dock("Occupancy plane %d" % (2 * plane + 1), size=(100, 200)) dock_area.addDock(dock_occcupancy_2, 'right', dock_occcupancy) occupancy_graphics = pg.GraphicsLayoutWidget() # Plot docks occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_images.append(pg.ImageItem(border='w')) view.addItem(self.occupancy_images[2 * plane + 1]) view.setRange(QtCore.QRectF(0, 0, 80, 336)) dock_occcupancy_2.addWidget(occupancy_graphics) # dock_event_status = Dock("Event status", size=(400, 400)) # dock_trigger_status = Dock("Trigger status", size=(400, 400)) # dock_area.addDock(dock_trigger_status, 'above', dock_service_records) # dock_area.addDock(dock_event_status, 'above', dock_trigger_status) dock_status = Dock("Status", size=(800, 40)) dock_area.addDock(dock_status, 'top') # Status dock on top cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Scan Parameters\n") self.spin_box = Qt.QSpinBox(value=0) self.spin_box.setMaximum(1000000) self.spin_box.setSuffix(" Readouts") self.reset_button = QtGui.QPushButton('Reset') self.noisy_checkbox = QtGui.QCheckBox('Mask noisy pixels') layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.event_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) layout.addWidget(self.noisy_checkbox, 0, 7, 0, 1) layout.addWidget(self.reset_button, 0, 8, 0, 1) dock_status.addWidget(cw) # Connect widgets self.reset_button.clicked.connect(lambda: self.send_command('RESET')) self.spin_box.valueChanged.connect(lambda value: self.send_command(str(value))) self.noisy_checkbox.stateChanged.connect(lambda value: self.send_command('MASK %d' % value)) # event_status_widget = pg.PlotWidget() # self.event_status_plot = event_status_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) # event_status_widget.showGrid(y=True) # dock_event_status.addWidget(event_status_widget) # trigger_status_widget = pg.PlotWidget() # self.trigger_status_plot = trigger_status_widget.plot(np.linspace(-0.5, 7.5, 9), np.zeros((8)), stepMode=True) # trigger_status_widget.showGrid(y=True) # dock_trigger_status.addWidget(trigger_status_widget) self.plot_delay = 0
def set_GUI(self): """ """ #%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #main_layout = QtWidgets.QGridLayout() #self.area.setLayout(main_layout) #vsplitter = QtWidgets.QSplitter(Qt.Vertical) # Hsplitter=QtWidgets.QSplitter(Qt.Horizontal) params = [ { 'title': 'set data:', 'name': 'set_data_4D', 'type': 'action', 'visible': False }, { 'title': 'set data:', 'name': 'set_data_3D', 'type': 'action', 'visible': False }, { 'title': 'set data:', 'name': 'set_data_2D', 'type': 'action', 'visible': False }, { 'title': 'set data:', 'name': 'set_data_1D', 'type': 'action', 'visible': False }, { 'title': 'Signal shape', 'name': 'data_shape_settings', 'type': 'group', 'children': [ { 'title': 'Initial Data shape:', 'name': 'data_shape_init', 'type': 'str', 'value': "", 'readonly': True }, { 'title': 'Axes shape:', 'name': 'nav_axes_shapes', 'type': 'group', 'children': [], 'readonly': True }, { 'title': 'Data shape:', 'name': 'data_shape', 'type': 'str', 'value': "", 'readonly': True }, { 'title': 'Navigator axes:', 'name': 'navigator_axes', 'type': 'itemselect' }, { 'title': 'Set Nav axes:', 'name': 'set_nav_axes', 'type': 'action', 'visible': True }, ] }, ] self.settings = Parameter.create(name='Param', type='group', children=params) ##self.signal_axes_selection() # connecting from tree self.settings.sigTreeStateChanged.connect( self.parameter_tree_changed) # any changes on the settings self.settings.child( ('set_data_1D' )).sigActivated.connect(lambda: self.set_data_test('1D')) self.settings.child( ('set_data_2D' )).sigActivated.connect(lambda: self.set_data_test('2D')) self.settings.child( ('set_data_3D' )).sigActivated.connect(lambda: self.set_data_test('3D')) self.settings.child( ('set_data_4D' )).sigActivated.connect(lambda: self.set_data_test('4D')) self.settings.child('data_shape_settings', 'set_nav_axes').sigActivated.connect( self.update_data) ##%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ##% 1D signalviewer viewer1D_widget = QtWidgets.QWidget() self.ui.viewer1D = Viewer1D(viewer1D_widget) self.ROI1D = LinearRegionItem() self.ui.viewer1D.viewer.plotwidget.plotItem.addItem(self.ROI1D) self.ui.combomath = QtWidgets.QComboBox() self.ui.combomath.addItems(['Sum', 'Mean', 'Half-life']) self.ui.viewer1D.ui.button_widget.layout().insertWidget( 4, self.ui.combomath) self.ui.combomath.currentIndexChanged.connect(self.update_Navigator) self.ROI1D.sigRegionChangeFinished.connect(self.update_Navigator) # % 2D viewer Dock viewer2D_widget = QtWidgets.QWidget() self.ui.viewer2D = Viewer2D(viewer2D_widget) self.ui.viewer2D.ui.Ini_plot_pb.setVisible(False) self.ui.viewer2D.ui.FlipUD_pb.setVisible(False) self.ui.viewer2D.ui.FlipLR_pb.setVisible(False) self.ui.viewer2D.ui.rotate_pb.setVisible(False) self.ui.viewer2D.ui.auto_levels_pb.click() self.ui.viewer2D.ui.ROIselect_pb.click() self.ROI2D = self.ui.viewer2D.ui.ROIselect self.ui.viewer2D.ROI_select_signal.connect(self.update_Navigator) dock_signal = Dock('Signal') dock_signal.addWidget(viewer1D_widget) dock_signal.addWidget(viewer2D_widget) ##%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ##% Navigator viewer Dock navigator1D_widget = QtWidgets.QWidget() self.ui.navigator1D = Viewer1D(navigator1D_widget) self.ui.navigator1D.ui.crosshair.crosshair_dragged.connect( self.update_viewer_data) self.ui.navigator1D.ui.crosshair_pb.click() self.ui.navigator1D.data_to_export_signal.connect(self.export_data) navigator2D_widget = QtWidgets.QWidget() self.ui.navigator2D = Viewer2D(navigator2D_widget) self.ui.navigator2D.ui.auto_levels_pb.click() self.ui.navigator2D.crosshair_dragged.connect( self.update_viewer_data ) # export scaled position in conjonction with 2D scaled axes self.ui.navigator2D.ui.crosshair_pb.click() self.ui.navigator2D.data_to_export_signal.connect(self.export_data) self.ui.navigation_widget = QtWidgets.QWidget() # vlayout_navigation = QtWidgets.QVBoxLayout() # self.navigator_label = QtWidgets.QLabel('Navigation View') # self.navigator_label.setMaximumHeight(15) #layout_navigation.addWidget(self.navigator_label) self.ui.nav_axes_widget = QtWidgets.QWidget() self.ui.nav_axes_widget.setLayout(QtWidgets.QVBoxLayout()) #vlayout_navigation.addWidget(navigator2D_widget) #vlayout_navigation.addWidget(self.ui.nav_axes_widget) self.ui.nav_axes_widget.setVisible(False) #vlayout_navigation.addWidget(navigator1D_widget) #self.ui.navigation_widget.setLayout(vlayout_navigation) #vsplitter.insertWidget(0, self.ui.navigation_widget) dock_navigation = Dock('Navigation') dock_navigation.addWidget(navigator1D_widget) dock_navigation.addWidget(navigator2D_widget) self.area.addDock(dock_navigation) self.area.addDock(dock_signal, 'right', dock_navigation) # self.ui.signal_widget = QtWidgets.QWidget() # VLayout1 = QtWidgets.QVBoxLayout() # self.viewer_label = QtWidgets.QLabel('Data View') # self.viewer_label.setMaximumHeight(15) # VLayout1.addWidget(self.viewer_label) # VLayout1.addWidget(viewer1D_widget) # VLayout1.addWidget(viewer2D_widget) # self.ui.signal_widget.setLayout(VLayout1) #vsplitter.insertWidget(1, self.ui.signal_widget) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/cartesian.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.ui.set_signals_pb_1D = QtWidgets.QPushButton('') self.ui.set_signals_pb_1D.setToolTip('Change navigation/signal axes') self.ui.set_signals_pb_1D_bis = QtWidgets.QPushButton('') self.ui.set_signals_pb_1D_bis.setToolTip( 'Change navigation/signal axes') self.ui.set_signals_pb_1D.setIcon(icon) self.ui.set_signals_pb_1D_bis.setIcon(icon) self.ui.set_signals_pb_2D = QtWidgets.QPushButton('') self.ui.set_signals_pb_2D.setToolTip('Change navigation/signal axes') self.ui.set_signals_pb_2D.setIcon(icon) self.ui.set_signals_pb_2D_bis = QtWidgets.QPushButton('') self.ui.set_signals_pb_2D_bis.setToolTip( 'Change navigation/signal axes') self.ui.set_signals_pb_2D_bis.setIcon(icon) self.ui.navigator1D.ui.button_widget.layout().insertWidget( 0, self.ui.set_signals_pb_1D) self.ui.navigator2D.ui.buttons_layout.insertWidget( 0, self.ui.set_signals_pb_2D) self.ui.viewer1D.ui.button_widget.layout().insertWidget( 0, self.ui.set_signals_pb_1D_bis) self.ui.viewer2D.ui.buttons_layout.insertWidget( 0, self.ui.set_signals_pb_2D_bis) #main_layout.addWidget(vsplitter) self.ui.set_signals_pb_1D.clicked.connect(self.signal_axes_selection) self.ui.set_signals_pb_2D.clicked.connect(self.signal_axes_selection) self.ui.set_signals_pb_1D_bis.clicked.connect( self.signal_axes_selection) self.ui.set_signals_pb_2D_bis.clicked.connect( self.signal_axes_selection) #to start: display as default a 2D navigator and a 1D viewer self.ui.navigator1D.parent.setVisible(False) self.ui.viewer2D.parent.setVisible(True)
def set_GUI(self): ########################################### ########################################### #init the docks containing the main widgets ############################################# #this one for the custom application settings dock_settings = Dock('Settings', size=(350, 350)) self.dockarea.addDock(dock_settings, 'left') # create main parameter tree self.settings_tree = ParameterTree() dock_settings.addWidget(self.settings_tree, 10) self.settings_tree.setMinimumWidth(300) #create a Parameter object containing the settings self.settings = Parameter.create(name='Settings', type='group', children=self.params) #load the tree with this parameter object self.settings_tree.setParameters(self.settings, showTop=False) #any change to the tree on the user interface will call the parameter_tree_changed method where all actions will be applied self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed) ################################################################ #create a logger dock where to store info senf from the programm self.dock_logger = Dock("Logger") self.logger_list = QtWidgets.QListWidget() self.logger_list.setMinimumWidth(300) self.dock_logger.addWidget(self.logger_list) self.dockarea.addDock(self.dock_logger, 'bottom', dock_settings) # dock_logger.setVisible(False) #connect together this custom signal with the add_log method self.log_signal[str].connect(self.add_log) ####################################################################################################################### #create a dock containing a viewer object, could be 0D, 1D or 2D depending what kind of data one want to plot here a 0D dock_Viewer0D = Dock('Viewer dock', size=(350, 350)) self.dockarea.addDock(dock_Viewer0D, 'right', self.dock_logger) target_widget = QtWidgets.QWidget() self.target_viewer = Viewer0D(target_widget) dock_Viewer0D.addWidget(target_widget) ################################################################################### #create 2 docks to display the DAQ_Viewer (one for its settings, one for its viewer) dock_detector_settings = Dock("Detector Settings", size=(350, 350)) self.dockarea.addDock(dock_detector_settings, 'right', dock_settings) dock_detector = Dock("Detector Viewer", size=(350, 350)) self.dockarea.addDock(dock_detector, 'right', dock_detector_settings) #init one daq_viewer object named detector self.detector = DAQ_Viewer(self.dockarea, dock_settings=dock_detector_settings, dock_viewer=dock_detector, title="A detector", DAQ_type='DAQ0D') #set its type to 'Mock' control_type = 'Mock' self.detector.ui.Detector_type_combo.setCurrentText(control_type) #init the detector and wait 1000ms for the completion self.detector.ui.IniDet_pb.click() self.detector.settings.child('main_settings', 'wait_time').setValue(100) QtWidgets.QApplication.processEvents() QThread.msleep(1000) self.detector.grab_done_signal.connect(self.data_done) ############################# #create a dock for a DAQ_Move dock_move = Dock("Move module", size=(350, 350)) self.dockarea.addDock(dock_move, 'right', self.dock_logger) move_widget = QtWidgets.QWidget() self.move = DAQ_Move(move_widget) dock_move.addWidget(move_widget) self.move.ui.IniStage_pb.click() QtWidgets.QApplication.processEvents() QThread.msleep(1000) ############################################ # creating a menubar self.menubar = self.mainwindow.menuBar() self.create_menu(self.menubar) #creating a toolbar self.toolbar = QtWidgets.QToolBar() self.create_toolbar() self.mainwindow.addToolBar(self.toolbar)
class AppDockArea(DockArea, AppNode): def __init__(self): DockArea.__init__(self) AppNode.__init__(self, CentralSignalConnector(Image())) self._status_dict = defaultdict(lambda: True) self.__init_image_view__() self.__init_control_widget__() self.__init_interpolate_widget__() self.__init_radial_widget__() self.__init_file_widget__() self.__init_angular_widget__() self._DOCK_DICT = { 'interpolation': self.interpolation_dock, 'radial_profile': self.radial_profile_dock, 'control': self.control_dock, 'image_view': self.image_view_dock, 'file_widget': self.file_dock, 'angular_profile': self.angular_profile_dock } self.__apply_default_view__() def __apply_default_view__(self): self.show_hide_docks('interpolation') self.show_hide_docks('radial_profile') self.show_hide_docks('angular_profile') self.show_hide_docks('control') def __init_image_view__(self): self.image_view = Basic2DImageWidget( self.get_lower_connector('Basic2DImageWidget')) dock = Dock('Image') dock.addWidget(self.image_view) self.addDock(dock, size=(1000, 1000)) self.image_view_dock = dock def __init_interpolate_widget__(self): self.interpolate_view = InterpolateImageWidget( self.get_lower_connector('InterpolateImageWidget'), self) dock = Dock('Interpolate') dock.addWidget(self.interpolate_view) self.addDock(dock, position='right') self.interpolate_view.update_image() self.interpolation_dock = dock def __init_radial_widget__(self): self.radial_profile = RadialProfileWidget( self.get_lower_connector('RadialProfileWidget'), self) dock = Dock('Radial Profile') dock.addWidget(self.radial_profile) self.addDock(dock, position='bottom') self.radial_profile.update_image() self.radial_profile_dock = dock def __init_angular_widget__(self): self.angular_profile = AngularProfileWidget( self.get_lower_connector('AngularProfileWidget'), self) dock = Dock('Angular Profile') dock.addWidget(self.angular_profile) self.addDock(dock, position='bottom') self.angular_profile.update_profile() self.angular_profile_dock = dock def __init_control_widget__(self): self.control_widget = ControlWidget( self.get_lower_connector('ControlWidget'), self) control_dock = Dock('Segments') control_dock.addWidget(self.control_widget) self.addDock(control_dock, position='right') self.control_dock = control_dock def __init_file_widget__(self): self.file_widget = FileWidget(self.get_lower_connector('FileWidget'), self) self.file_dock = Dock('Files') self.file_dock.addWidget(self.file_widget) self.addDock(self.file_dock, position='left') def show_hide_docks(self, dock_name: str): assert dock_name in self._DOCK_DICT.keys() dock = self._DOCK_DICT[dock_name] status = self._status_dict[dock_name] if status: dock.hide() else: dock.show() self._status_dict[dock_name] = not status
def setUpGUI(self): # widget where the liveview image will be displayed imageWidget = pg.GraphicsLayoutWidget() self.vb = imageWidget.addViewBox(row=0, col=0) self.lplotWidget = linePlotWidget() # Viewbox and image item where the liveview will be displayed self.vb.setMouseMode(pg.ViewBox.RectMode) self.img = pg.ImageItem() self.img.translate(-0.5, -0.5) self.vb.addItem(self.img) self.vb.setAspectLocked(True) imageWidget.setAspectLocked(True) # set up histogram for the liveview image self.hist = pg.HistogramLUTItem(image=self.img) lut = viewbox_tools.generatePgColormap(cmaps.parula) self.hist.gradient.setColorMap(lut) self.hist.vb.setLimits(yMin=0, yMax=10000) for tick in self.hist.gradient.ticks: tick.hide() imageWidget.addItem(self.hist, row=0, col=1) # widget with scanning parameters self.paramWidget = QtGui.QFrame() self.paramWidget.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised) scanParamTitle = QtGui.QLabel( '<h2><strong>Scan settings</strong></h2>') scanParamTitle.setTextFormat(QtCore.Qt.RichText) # LiveView Button self.liveviewButton = QtGui.QPushButton('confocal liveview') self.liveviewButton.setFont( QtGui.QFont('Helvetica', weight=QtGui.QFont.Bold)) self.liveviewButton.setCheckable(True) self.liveviewButton.setStyleSheet( "font-size: 12px; background-color:rgb(180, 180, 180)") # ROI buttons self.ROIButton = QtGui.QPushButton('ROI') self.ROIButton.setCheckable(True) self.ROIButton.clicked.connect(self.ROImethod) self.selectROIButton = QtGui.QPushButton('select ROI') self.selectROIButton.clicked.connect(self.selectROI) # Acquire frame button self.acquireFrameButton = QtGui.QPushButton('Acquire new frame') self.acquireFrameButton.setCheckable(True) # Save current frame button self.currentFrameButton = QtGui.QPushButton('Save current frame') self.currentFrameButton.setCheckable(True) # preview scan button self.previewScanButton = QtGui.QPushButton('Scan preview') self.previewScanButton.setCheckable(True) self.previewScanButton.clicked.connect(self.previewScan) # line profile button self.lineProfButton = QtGui.QPushButton('Line profile') self.lineProfButton.setCheckable(True) self.lineProfButton.clicked.connect(self.lineProfile) # no-display checkbox self.nodisplayCheckBox = QtGui.QCheckBox('No-display scan') # Scanning parameters self.initialPosLabel = QtGui.QLabel('Initial Pos' ' [x0, y0, z0] (µm)') self.initialPosEdit = QtGui.QLineEdit('3 3 10') self.scanRangeLabel = QtGui.QLabel('Scan range (µm)') self.scanRangeEdit = QtGui.QLineEdit('8') self.pxTimeLabel = QtGui.QLabel('Pixel time (µs)') self.pxTimeEdit = QtGui.QLineEdit('500') self.maxCountsLabel = QtGui.QLabel('') self.NofPixelsLabel = QtGui.QLabel('Number of pixels') self.NofPixelsEdit = QtGui.QLineEdit('80') self.pxSizeValue = QtGui.QLabel('') self.frameTimeValue = QtGui.QLabel('') self.advancedButton = QtGui.QPushButton('Advanced options') self.advancedButton.setCheckable(True) self.advancedButton.clicked.connect(self.toggleAdvanced) self.auxAccelerationLabel = QtGui.QLabel('Aux acc' ' (% of a_max)') self.auxAccelerationEdit = QtGui.QLineEdit('1 1 1 1') self.waitingTimeLabel = QtGui.QLabel('Scan waiting time (µs)') self.waitingTimeEdit = QtGui.QLineEdit('0') self.toggleAdvanced() # filename self.filenameLabel = QtGui.QLabel('File name') self.filenameEdit = QtGui.QLineEdit('filename') # folder today = str(date.today()).replace('-', '') root = r'C:\\Data\\' folder = root + today try: os.mkdir(folder) except OSError: print("Creation of the directory %s failed" % folder) else: print("Successfully created the directory %s " % folder) self.folderLabel = QtGui.QLabel('Folder') self.folderEdit = QtGui.QLineEdit(folder) self.browseFolderButton = QtGui.QPushButton('Browse') self.browseFolderButton.setCheckable(True) self.browseFolderButton.clicked.connect(self.loadFolder) # scan selection self.scanModeLabel = QtGui.QLabel('Scan type') self.scanMode = QtGui.QComboBox() self.scanModes = ['xy', 'xz', 'yz'] self.scanMode.addItems(self.scanModes) self.detectorType = QtGui.QComboBox() self.dettypes = ['APD', 'photodiode'] self.detectorType.addItems(self.dettypes) # widget with EBP parameters and buttons self.EBPWidget = QtGui.QFrame() self.EBPWidget.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised) EBPparamTitle = QtGui.QLabel( '<h2><strong>Excitation Beam Pattern</strong></h2>') EBPparamTitle.setTextFormat(QtCore.Qt.RichText) self.EBProiButton = QtGui.QPushButton('EBP ROI') self.EBProiButton.setCheckable(True) self.EBProiButton.clicked.connect(self.ROImethod) self.showEBPButton = QtGui.QPushButton('show/hide EBP') self.showEBPButton.setCheckable(True) self.showEBPButton.clicked.connect(self.toggleEBP) self.setEBPButton = QtGui.QPushButton('set EBP') self.setEBPButton.clicked.connect(self.setEBP) # EBP selection self.EBPtypeLabel = QtGui.QLabel('EBP type') self.EBPtype = QtGui.QComboBox() self.EBPoptions = ['triangle', 'square'] self.EBPtype.addItems(self.EBPoptions) self.Llabel = QtGui.QLabel('L (nm)') self.LEdit = QtGui.QLineEdit('100') # piezo navigation widget self.positioner = QtGui.QFrame() self.positioner.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised) self.xUpButton = QtGui.QPushButton("(+x) ►") # → self.xUpButton.pressed.connect(self.xMoveUp) self.xDownButton = QtGui.QPushButton("◄ (-x)") # ← self.xDownButton.pressed.connect(self.xMoveDown) self.yUpButton = QtGui.QPushButton("(+y) ▲") # ↑ self.yUpButton.pressed.connect(self.yMoveUp) self.yDownButton = QtGui.QPushButton("(-y) ▼") # ↓ self.yDownButton.pressed.connect(self.yMoveDown) self.zUpButton = QtGui.QPushButton("(+z) ▲") # ↑ self.zUpButton.pressed.connect(self.zMoveUp) self.zDownButton = QtGui.QPushButton("(-z) ▼") # ↓ self.zDownButton.pressed.connect(self.zMoveDown) self.xStepLabel = QtGui.QLabel('x step (µm)') self.xStepEdit = QtGui.QLineEdit('0.050') self.yStepLabel = QtGui.QLabel('y step (µm)') self.yStepEdit = QtGui.QLineEdit('0.050') self.zStepLabel = QtGui.QLabel('z step (µm)') self.zStepEdit = QtGui.QLineEdit('0.050') # move to button self.moveToButton = QtGui.QPushButton('Move to') self.moveToLabel = QtGui.QLabel('Move to [x0, y0, z0] (µm)') self.moveToEdit = QtGui.QLineEdit('0 0 10') # scan GUI layout grid = QtGui.QGridLayout() self.setLayout(grid) dockArea = DockArea() grid.addWidget(dockArea, 0, 0) EBPDock = Dock('EBP') EBPDock.addWidget(self.EBPWidget) dockArea.addDock(EBPDock) positionerDock = Dock('Positioner') positionerDock.addWidget(self.positioner) dockArea.addDock(positionerDock, 'above', EBPDock) paramDock = Dock('Scan parameters') paramDock.addWidget(self.paramWidget) dockArea.addDock(paramDock, 'above', positionerDock) imageDock = Dock('Confocal view') imageDock.addWidget(imageWidget) dockArea.addDock(imageDock, 'right', paramDock) # paramwidget layout subgrid = QtGui.QGridLayout() self.paramWidget.setLayout(subgrid) subgrid.addWidget(self.scanModeLabel, 2, 1) subgrid.addWidget(self.scanMode, 3, 1) subgrid.addWidget(self.detectorType, 4, 1) subgrid.addWidget(self.liveviewButton, 6, 1, 2, 1) subgrid.addWidget(self.ROIButton, 8, 1) subgrid.addWidget(self.selectROIButton, 9, 1) subgrid.addWidget(self.acquireFrameButton, 10, 1) subgrid.addWidget(self.currentFrameButton, 11, 1) subgrid.addWidget(self.lineProfButton, 13, 1) subgrid.addWidget(scanParamTitle, 0, 0, 2, 3) subgrid.addWidget(self.initialPosLabel, 2, 0) subgrid.addWidget(self.initialPosEdit, 3, 0) subgrid.addWidget(self.scanRangeLabel, 4, 0) subgrid.addWidget(self.scanRangeEdit, 5, 0) subgrid.addWidget(self.pxTimeLabel, 6, 0) subgrid.addWidget(self.pxTimeEdit, 7, 0) subgrid.addWidget(self.NofPixelsLabel, 8, 0) subgrid.addWidget(self.NofPixelsEdit, 9, 0) subgrid.addWidget(self.pxSizeValue, 10, 0) subgrid.addWidget(self.frameTimeValue, 11, 0) subgrid.addWidget(self.maxCountsLabel, 12, 0) subgrid.addWidget(self.nodisplayCheckBox, 13, 0) subgrid.addWidget(self.advancedButton, 14, 0) subgrid.addWidget(self.auxAccelerationLabel, 15, 0) subgrid.addWidget(self.auxAccelerationEdit, 16, 0) subgrid.addWidget(self.waitingTimeLabel, 17, 0) subgrid.addWidget(self.waitingTimeEdit, 18, 0) subgrid.addWidget(self.previewScanButton, 19, 0) subgrid.addWidget(self.filenameLabel, 2, 2) subgrid.addWidget(self.filenameEdit, 3, 2) subgrid.addWidget(self.folderLabel, 4, 2) subgrid.addWidget(self.folderEdit, 5, 2) subgrid.addWidget(self.browseFolderButton, 6, 2) self.paramWidget.setFixedHeight(500) self.paramWidget.setFixedWidth(450) subgrid.setColumnMinimumWidth(1, 130) imageWidget.setFixedHeight(500) imageWidget.setFixedWidth(500) # EBP widget layout subgridEBP = QtGui.QGridLayout() self.EBPWidget.setLayout(subgridEBP) subgridEBP.addWidget(EBPparamTitle, 0, 0, 2, 4) subgridEBP.addWidget(self.EBProiButton, 2, 0, 1, 1) subgridEBP.addWidget(self.setEBPButton, 3, 0, 1, 1) subgridEBP.addWidget(self.showEBPButton, 4, 0, 2, 1) subgridEBP.addWidget(self.EBPtypeLabel, 2, 1) subgridEBP.addWidget(self.EBPtype, 3, 1) subgridEBP.addWidget(self.Llabel, 4, 1) subgridEBP.addWidget(self.LEdit, 5, 1) self.EBPWidget.setFixedHeight(150) self.EBPWidget.setFixedWidth(250) # piezo navigation layout layout = QtGui.QGridLayout() self.positioner.setLayout(layout) positionerTitle = QtGui.QLabel('<h2><strong>Position</strong></h2>') positionerTitle.setTextFormat(QtCore.Qt.RichText) layout.addWidget(positionerTitle, 0, 0, 2, 3) layout.addWidget(self.xUpButton, 2, 4, 2, 1) layout.addWidget(self.xDownButton, 2, 2, 2, 1) layout.addWidget(self.xStepLabel, 0, 6) layout.addWidget(self.xStepEdit, 1, 6) layout.addWidget(self.yUpButton, 1, 3, 2, 1) layout.addWidget(self.yDownButton, 3, 3, 2, 1) layout.addWidget(self.yStepLabel, 2, 6) layout.addWidget(self.yStepEdit, 3, 6) layout.addWidget(self.zUpButton, 1, 5, 2, 1) layout.addWidget(self.zDownButton, 3, 5, 2, 1) layout.addWidget(self.zStepLabel, 4, 6) layout.addWidget(self.zStepEdit, 5, 6) layout.addWidget(self.moveToLabel, 6, 1, 1, 3) layout.addWidget(self.moveToEdit, 7, 1, 1, 1) layout.addWidget(self.moveToButton, 8, 1, 1, 2) self.positioner.setFixedHeight(250) self.positioner.setFixedWidth(400)
def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) # Docks dock_values = Dock("Temperature and Humidity", size=(400, 400)) dock_status = Dock("Status", size=(800, 40)) dock_area.addDock(dock_values, "above") dock_area.addDock(dock_status, "top") # Status dock on top cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.avg_sensor_temp_label = QtGui.QLabel("Mean sensor temperature over last %d s\n" % self.avg_window) self.dewpoint_label = QtGui.QLabel("Dew point:\n-- C") self.last_timestamp_label = QtGui.QLabel("Last timestamp:\n%s" % "No data yet") self.avg_setting = Qt.QSpinBox() self.avg_setting.setMinimum(1) self.avg_setting.setMaximum(3600) self.avg_setting.setValue(self.avg_window) self.avg_setting.setPrefix("Average over ") self.avg_setting.setSuffix(" s") self.reset_button = QtGui.QPushButton("Reset") layout.addWidget(self.avg_sensor_temp_label, 0, 0, 1, 1) layout.addWidget(self.avg_setting, 0, 1, 1, 1) layout.addWidget(self.dewpoint_label, 0, 2, 1, 1) layout.addWidget(self.last_timestamp_label, 0, 3, 1, 1) layout.addWidget(self.reset_button, 0, 4, 1, 1) dock_status.addWidget(cw) # Connect widgets self.reset_button.clicked.connect(lambda: self.send_command("RESET")) self.avg_setting.valueChanged.connect(lambda value: self._update_avg_window(value)) # particle rate dock cooling_graphics = pg.GraphicsLayoutWidget() cooling_graphics.show() # Temperature plots date_axis_temp = TimeAxisItem(orientation="bottom") date_axis_humid = TimeAxisItem(orientation="bottom") plot_temp = pg.PlotItem(axisItems={"bottom": date_axis_temp}, labels={"left": "Temperature / C"}) plot_humidity = pg.PlotItem(axisItems={"bottom": date_axis_humid}, labels={"left": "rel. Humidity / %"}) plot_humidity.setXLink(plot_temp) self.temp_sensor_curve = pg.PlotCurveItem(pen=pg.mkPen(color=(181, 0, 15), width=2)) self.temp_box_curve = pg.PlotCurveItem(pen=pg.mkPen(color=(0, 181, 97), width=2)) self.humid_sensor_curve = pg.PlotCurveItem(pen=pg.mkPen((181, 0, 15), width=2)) # add legend legend_temp = pg.LegendItem(offset=(50, 1)) legend_temp.setParentItem(plot_temp) legend_temp.addItem(self.temp_sensor_curve, "Sensor temperature close to DUT") legend_temp.addItem(self.temp_box_curve, "Box temperature with dry ice") legend_humid_sensor = pg.LegendItem(offset=(50, 1)) legend_humid_sensor.setParentItem(plot_humidity) legend_humid_sensor.addItem(self.humid_sensor_curve, "Sensor humidity close to DUT") # add items to plots and customize plots viewboxes plot_temp.addItem(self.temp_sensor_curve) plot_temp.addItem(self.temp_box_curve) vb = plot_temp.vb.setBackgroundColor("#E6E5F4") plot_temp.getAxis("left").setZValue(0) plot_temp.getAxis("left").setGrid(155) plot_temp.getAxis("bottom").setStyle(showValues=False) plot_humidity.addItem(self.humid_sensor_curve) plot_humidity.vb.setBackgroundColor("#E6E5F4") plot_humidity.showGrid(x=True, y=True) plot_humidity.getAxis("left").setZValue(0) plot_humidity.getAxis("bottom").setGrid(155) cooling_graphics.addItem(plot_temp, row=0, col=1, rowspan=1, colspan=3) cooling_graphics.addItem(plot_humidity, row=1, col=1, rowspan=1, colspan=3) dock_values.addWidget(cooling_graphics) # add dict of all used plotcurveitems for individual handling of each plot self.plots = { "temp_sensor": self.temp_sensor_curve, "temp_box": self.temp_box_curve, "humidity_sensor": self.humid_sensor_curve, } self.plot_delay = 0
def initDialog(self,results=None,KData=None,bDrawText=False): ''' orders,记录当日00:00前一日开盘时间发送的交易命令 trasactions,记录当日00:00前一日已执行的orders positions,记录当日00:00时,各个symbols的positions 所以,这三个量都是数组,且大小不定,所以,不宜图形方式展示,适宜table方式展示 其他单值参数都可以考虑图形化方式 特别是pnl,cash,portfolio等 perf的生成时点是00:00,其内容为00:00前一天的活动 perf转化记录入result时,需要设置Index, 此Index的值为生成记录时点后的一天的收盘时间。 例如: 有三个交易日:2015-12-01,12-02,12-03 开收盘时间:Asia/Shanghai:09:30--15:00 (utc:01:30--07:00) 使用instant_fill==True方式执行订单 每日开盘时Buy(1) 有如下Events列表会生成并被处理 1)2015-12-01 00:00 utc 生成perf perf内容:由于是第一交易日的开始时间(非开市时间),无内容可记 记录入result: 记录Index:result.index = 2015-12-01 07:00 2)2015-12-01 01:30 utc 生成order,生成transaction,生成position 3)2015-12-02 00:00 utc 生成perf perf内容:2015-12-01 00:00 utc 至 2015-12-02 00:00 utc期间发生的交易事项及内容 记录入result: 记录Index:result.index = 2015-12-02 07:00 之后的4)5)6)同上 不合逻辑的地方需特别注意: 1)perf的生成时间和记录时间不一致,00:00生成(当日开始(非开市)),07:00记录(当日收市) 2)perf记录的是00:00之前一日的交易,记录时点却是当日收盘(当日收盘时间的记录,给人直观的理解应是记录当日开盘到收盘期间发生的业务) ''' # 1) creates layouts dialog = QtGui.QDialog() mainLayout = QtGui.QHBoxLayout() rightLayout = QtGui.QVBoxLayout() mainLayout.addLayout(rightLayout) dialog.setLayout(mainLayout) dialog.setWindowTitle(('Strategy Results')) # 2) creates widgets # 2.1)candle import os,sys xpower = os.path.abspath(os.path.join(os.path.dirname(__file__),os.pardir,os.pardir,os.pardir,'midProjects','histdataUI')) sys.path.append(xpower) from Widgets.pgCandleWidgetCross import pgCandleWidgetCross from Widgets.pgCrossAddition import pgCrossAddition pgCandleView = pgCandleWidgetCross(dataForCandle=KData) self.pricePlot(pgCandleView) # 2.2)Pnl PyqtGraphPnl = pgCrossAddition() self.pnlPlot(PyqtGraphPnl,bDrawText=bDrawText) # 2.3)Position #PyqtGraphPosition = pgCrossAddition() #self.positionPlot(PyqtGraphPosition) # 2.4)portfolio PyqtGraphPortfolio = pgCrossAddition() self.portfolioPlot(PyqtGraphPortfolio) # 2.5)price PyqtGraphindicators = pgCrossAddition() self.pricePlot(PyqtGraphindicators) self.indicatorsPlot(PyqtGraphindicators) # 2.6)order #PyqtGraphOrder = pgCrossAddition() #self.orderPlot(PyqtGraphOrder) #self.pricePlot(PyqtGraphOrder) from pyqtgraph.dockarea import DockArea,Dock area = DockArea() ## Create docks, place them into the window one at a time. ## Note that size arguments are only a suggestion; docks will still have to ## fill the entire dock area and obey the limits of their internal widgets. d1 = Dock("candles", size=(200,300)) ## give this dock the minimum possible size d2 = Dock("pnl", closable=True, size=(200,100)) #d3 = Dock("position", size=(200,100)) d4 = Dock("portfolio", size=(200,100)) d5 = Dock("price", size=(200,100)) #d6 = Dock("order time,amount",size=(200,100)) area.addDock(d1, 'bottom') area.addDock(d2, 'bottom') #area.addDock(d3, 'bottom') area.addDock(d4, 'bottom') area.addDock(d5, 'bottom', d1) #area.addDock(d6, 'bottom', d1) rightLayout.addWidget(area) d1.addWidget(pgCandleView) d2.addWidget(PyqtGraphPnl) #d3.addWidget(PyqtGraphPosition) d4.addWidget(PyqtGraphPortfolio) d5.addWidget(PyqtGraphindicators) #d6.addWidget(PyqtGraphOrder) PyqtGraphPnl.setXLink(pgCandleView) #PyqtGraphPosition.setXLink(pgCandleView) PyqtGraphPortfolio.setXLink(pgCandleView) PyqtGraphindicators.setXLink(pgCandleView) #PyqtGraphOrder.setXLink(pgCandleView) return dialog
def setupUi(self, parent): logger = logging.getLogger(__name__) AWGForm.setupUi(self, parent) self.setWindowTitle(self.device.displayName) self._varAsOutputChannelDict = dict() self.area = DockArea() self.splitter.insertWidget(0, self.area) self.awgChannelUiList = [] for channel in range(self.device.deviceProperties['numChannels']): awgChannelUi = AWGChannelUi(channel, self.settings, self.globalDict, self.waveformCache, parent=self) awgChannelUi.setupUi(awgChannelUi) awgChannelUi.dependenciesChanged.connect(self.onDependenciesChanged) self.awgChannelUiList.append(awgChannelUi) dock = Dock("AWG Channel {0}".format(channel)) dock.addWidget(awgChannelUi) self.area.addDock(dock, 'right') self.device.waveforms[channel] = awgChannelUi.waveform self.refreshVarDict() # Settings control self.saveButton.clicked.connect( self.onSave ) self.removeButton.clicked.connect( self.onRemove ) self.reloadButton.clicked.connect( self.onReload ) self.settingsModel = QtCore.QStringListModel() self.settingsComboBox.setModel(self.settingsModel) self.settingsModel.setStringList( sorted(self.settingsDict.keys()) ) self.settingsComboBox.setCurrentIndex( self.settingsComboBox.findText(self.settingsName) ) self.settingsComboBox.currentIndexChanged[str].connect( self.onLoad ) self.settingsComboBox.lineEdit().editingFinished.connect( self.onComboBoxEditingFinished ) self.autoSaveCheckBox.setChecked(self.autoSave) self.saveButton.setEnabled( not self.autoSave ) self.saveButton.setVisible( not self.autoSave ) self.reloadButton.setEnabled( not self.autoSave ) self.reloadButton.setVisible( not self.autoSave ) self.autoSaveCheckBox.stateChanged.connect(self.onAutoSave) #programming options table self.programmingOptionsTable.setupUi(globalDict=self.globalDict, parameterDict=self.device.parameters()) self.programmingOptionsTable.valueChanged.connect( self.device.update ) # Table self.tableModel = AWGTableModel(self.settings, self.globalDict) self.tableView.setModel(self.tableModel) self.tableModel.valueChanged.connect(self.onValue) self.delegate = MagnitudeSpinBoxDelegate(self.globalDict) self.tableView.setItemDelegateForColumn(self.tableModel.column.value, self.delegate) #File self.filenameModel = QtCore.QStringListModel() self.filenameComboBox.setModel(self.filenameModel) self.filenameModel.setStringList( [basename for basename, filename in list(self.recentFiles.items()) if os.path.exists(filename)] ) self.filenameComboBox.setCurrentIndex(self.filenameComboBox.findText(os.path.basename(self.settings.filename))) self.filenameComboBox.currentIndexChanged[str].connect(self.onFilename) self.removeFileButton.clicked.connect(self.onRemoveFile) self.newFileButton.clicked.connect(self.onNewFile) self.openFileButton.clicked.connect(self.onOpenFile) self.saveFileButton.clicked.connect(self.onSaveFile) self.reloadFileButton.clicked.connect(self.onReloadFile) #cache self.cacheDepthSpinBox.setValue(self.settings.cacheDepth) self.cacheDepthSpinBox.valueChanged.connect(self.onCacheDepth) self.clearCacheButton.clicked.connect(self.onClearCache) #status bar self.label = QtGui.QLabel('Sample Rate: {0}'.format(self.settings.deviceProperties['sampleRate'])) self.statusbar.addWidget(self.label) #Restore GUI state state = self.config.get(self.configname+'.state') pos = self.config.get(self.configname+'.pos') size = self.config.get(self.configname+'.size') isMaximized = self.config.get(self.configname+'.isMaximized') dockAreaState = self.config.get(self.configname+'.dockAreaState') guiState = self.config.get(self.configname+".guiState") restoreGuiState(self, guiState) try: if pos: self.move(pos) if size: self.resize(size) if isMaximized: self.showMaximized() if state: self.restoreState(state) for awgChannelUi in self.awgChannelUiList: channelGuiState = self.config[self.configname+"channel{0}.guiState".format(awgChannelUi.channel)] restoreGuiState(awgChannelUi, channelGuiState) except Exception as e: logger.warning("Error on restoring state in AWGUi {0}. Exception occurred: {1}".format(self.device.displayName, e)) try: if dockAreaState: self.area.restoreState(dockAreaState) except Exception as e: logger.warning("Cannot restore dock state in AWGUi {0}. Exception occurred: {1}".format(self.device.displayName, e)) self.area.deleteLater() self.area = DockArea() self.splitter.insertWidget(0, self.area) for channelUi in self.awgChannelUiList: dock = Dock("AWG Channel {0}".format(channel)) dock.addWidget(channelUi) self.area.addDock(dock, 'right') self.saveIfNecessary()
pass def getCurrentImage(self): return self._currImg def closeEvent(self, ev): if self._catchTimer: self._catchTimer.stop() ev.accept() if __name__ == '__main__': app = QtWidgets.QApplication([]) win = QtWidgets.QMainWindow() from pyqtgraph.dockarea import DockArea, Dock from fcre.pool import DevPool from fcre.camera import Camera devpool = DevPool() devpool.register('camera', 'cm') devpool.do('camera', 'cm', 'connect', 0) d = DockArea() win.setCentralWidget(d) dock = Dock('cm') UI = CameraUI('camera', devpool, 'cm') dock.addWidget(UI) d.addDock(dock) win.show() app.exec_()
def add_widgets(self): # Main window with dock area self.dock_area = DockArea() self.setCentralWidget(self.dock_area) # Docks dock_occcupancy = Dock("Occupancy", size=(400, 400)) dock_run_config = Dock("Run configuration", size=(400, 400)) dock_global_config = Dock("Global configuration", size=(400, 400)) dock_tot = Dock("Time over threshold values (TOT)", size=(400, 400)) dock_tdc = Dock("Time digital converter values (TDC)", size=(400, 400)) dock_event_status = Dock("Event status", size=(400, 400)) dock_trigger_status = Dock("Trigger status", size=(400, 400)) dock_service_records = Dock("Service records", size=(400, 400)) dock_hit_timing = Dock("Hit timing (rel. BCID)", size=(400, 400)) dock_status = Dock("Status", size=(800, 40)) self.dock_area.addDock(dock_global_config, 'left') self.dock_area.addDock(dock_run_config, 'above', dock_global_config) self.dock_area.addDock(dock_occcupancy, 'above', dock_run_config) self.dock_area.addDock(dock_tdc, 'right', dock_occcupancy) self.dock_area.addDock(dock_tot, 'above', dock_tdc) self.dock_area.addDock(dock_service_records, 'bottom', dock_occcupancy) self.dock_area.addDock(dock_trigger_status, 'above', dock_service_records) self.dock_area.addDock(dock_event_status, 'above', dock_trigger_status) self.dock_area.addDock(dock_hit_timing, 'bottom', dock_tot) self.dock_area.addDock(dock_status, 'top') # Status widget cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Scan Parameters\n") self.spin_box = Qt.QSpinBox(value=1) self.spin_box.setMaximum(1000000) self.spin_box.setSuffix(" Readouts") self.reset_button = QtGui.QPushButton('Reset') layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.event_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) layout.addWidget(self.reset_button, 0, 7, 0, 1) dock_status.addWidget(cw) # Run config dock self.run_conf_list_widget = Qt.QListWidget() dock_run_config.addWidget(self.run_conf_list_widget) # Global config dock self.global_conf_list_widget = Qt.QListWidget() dock_global_config.addWidget(self.global_conf_list_widget) # Different plot docks occupancy_graphics = pg.GraphicsLayoutWidget() occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_img = pg.ImageItem(border='w') view.addItem(self.occupancy_img) view.setRange(QtCore.QRectF(0, 0, 80, 336)) dock_occcupancy.addWidget(occupancy_graphics) tot_plot_widget = pg.PlotWidget(background="w") self.tot_plot = tot_plot_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) tot_plot_widget.showGrid(y=True) dock_tot.addWidget(tot_plot_widget) tdc_plot_widget = pg.PlotWidget(background="w") self.tdc_plot = tdc_plot_widget.plot(np.linspace(-0.5, 4095.5, 4097), np.zeros((4096)), stepMode=True) tdc_plot_widget.showGrid(y=True) tdc_plot_widget.setXRange(0, 800, update=True) dock_tdc.addWidget(tdc_plot_widget) event_status_widget = pg.PlotWidget() self.event_status_plot = event_status_widget.plot(np.linspace( -0.5, 15.5, 17), np.zeros((16)), stepMode=True) event_status_widget.showGrid(y=True) dock_event_status.addWidget(event_status_widget) trigger_status_widget = pg.PlotWidget() self.trigger_status_plot = trigger_status_widget.plot(np.linspace( -0.5, 7.5, 9), np.zeros((8)), stepMode=True) trigger_status_widget.showGrid(y=True) dock_trigger_status.addWidget(trigger_status_widget) service_record_widget = pg.PlotWidget() self.service_record_plot = service_record_widget.plot(np.linspace( -0.5, 31.5, 33), np.zeros((32)), stepMode=True) service_record_widget.showGrid(y=True) dock_service_records.addWidget(service_record_widget) hit_timing_widget = pg.PlotWidget() self.hit_timing_plot = hit_timing_widget.plot(np.linspace( -0.5, 15.5, 17), np.zeros((16)), stepMode=True) hit_timing_widget.showGrid(y=True) dock_hit_timing.addWidget(hit_timing_widget)
class CustomApp(QtWidgets.QWidget, QObject): #custom signal that will be fired sometimes. Could be connected to an external object method or an internal method log_signal = pyqtSignal(str) #list of dicts enabling the settings tree on the user interface params = [ { 'title': 'Main settings:', 'name': 'main_settings', 'type': 'group', 'children': [ { 'title': 'File name:', 'name': 'target_filename', 'type': 'str', 'value': "", 'readonly': True }, { 'title': 'Date:', 'name': 'date', 'type': 'date', 'value': QDate.currentDate() }, { 'title': 'Do something:', 'name': 'do_something', 'type': 'bool', 'value': False }, { 'title': 'Something done:', 'name': 'something_done', 'type': 'led', 'value': False, 'readonly': True }, { 'title': 'Infos:', 'name': 'info', 'type': 'text', 'value': "" }, ] }, { 'title': 'Other settings:', 'name': 'other_settings', 'type': 'group', 'children': [ { 'title': 'List of stuffs:', 'name': 'list_stuff', 'type': 'list', 'value': 'first', 'values': ['first', 'second', 'third'], 'tip': 'choose a stuff from the list' }, { 'title': 'List of integers:', 'name': 'list_int', 'type': 'list', 'value': 0, 'values': [0, 256, 512], 'tip': 'choose a stuff from this int list' }, { 'title': 'one integer:', 'name': 'an_integer', 'type': 'int', 'value': 500, }, { 'title': 'one float:', 'name': 'a_float', 'type': 'float', 'value': 2.7, }, ] }, ] def __init__(self, parent): QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates)) super(CustomApp, self).__init__() if not isinstance(parent, DockArea): raise Exception('no valid parent container, expected a DockArea') self.dockarea = parent self.mainwindow = parent.parent() #init the object parameters self.one_parameter = None self.another_parameter = None self.detector = None self.save_file_pathname = None self.raw_data = [] #init the user interface self.set_GUI() def set_GUI(self): ########################################### ########################################### #init the docks containing the main widgets ############################################# #this one for the custom application settings dock_settings = Dock('Settings', size=(350, 350)) self.dockarea.addDock(dock_settings, 'left') # create main parameter tree self.settings_tree = ParameterTree() dock_settings.addWidget(self.settings_tree, 10) self.settings_tree.setMinimumWidth(300) #create a Parameter object containing the settings self.settings = Parameter.create(name='Settings', type='group', children=self.params) #load the tree with this parameter object self.settings_tree.setParameters(self.settings, showTop=False) #any change to the tree on the user interface will call the parameter_tree_changed method where all actions will be applied self.settings.sigTreeStateChanged.connect(self.parameter_tree_changed) ################################################################ #create a logger dock where to store info senf from the programm self.dock_logger = Dock("Logger") self.logger_list = QtWidgets.QListWidget() self.logger_list.setMinimumWidth(300) self.dock_logger.addWidget(self.logger_list) self.dockarea.addDock(self.dock_logger, 'bottom', dock_settings) # dock_logger.setVisible(False) #connect together this custom signal with the add_log method self.log_signal[str].connect(self.add_log) ####################################################################################################################### #create a dock containing a viewer object, could be 0D, 1D or 2D depending what kind of data one want to plot here a 0D dock_Viewer0D = Dock('Viewer dock', size=(350, 350)) self.dockarea.addDock(dock_Viewer0D, 'right', self.dock_logger) target_widget = QtWidgets.QWidget() self.target_viewer = Viewer0D(target_widget) dock_Viewer0D.addWidget(target_widget) ################################################################################### #create 2 docks to display the DAQ_Viewer (one for its settings, one for its viewer) dock_detector_settings = Dock("Detector Settings", size=(350, 350)) self.dockarea.addDock(dock_detector_settings, 'right', dock_settings) dock_detector = Dock("Detector Viewer", size=(350, 350)) self.dockarea.addDock(dock_detector, 'right', dock_detector_settings) #init one daq_viewer object named detector self.detector = DAQ_Viewer(self.dockarea, dock_settings=dock_detector_settings, dock_viewer=dock_detector, title="A detector", DAQ_type='DAQ0D') #set its type to 'Mock' control_type = 'Mock' self.detector.ui.Detector_type_combo.setCurrentText(control_type) #init the detector and wait 1000ms for the completion self.detector.ui.IniDet_pb.click() self.detector.settings.child('main_settings', 'wait_time').setValue(100) QtWidgets.QApplication.processEvents() QThread.msleep(1000) self.detector.grab_done_signal.connect(self.data_done) ############################# #create a dock for a DAQ_Move dock_move = Dock("Move module", size=(350, 350)) self.dockarea.addDock(dock_move, 'right', self.dock_logger) move_widget = QtWidgets.QWidget() self.move = DAQ_Move(move_widget) dock_move.addWidget(move_widget) self.move.ui.IniStage_pb.click() QtWidgets.QApplication.processEvents() QThread.msleep(1000) ############################################ # creating a menubar self.menubar = self.mainwindow.menuBar() self.create_menu(self.menubar) #creating a toolbar self.toolbar = QtWidgets.QToolBar() self.create_toolbar() self.mainwindow.addToolBar(self.toolbar) @pyqtSlot(OrderedDict) def data_done(self, data): print(data) @pyqtSlot(QRectF) def update_weighted_settings(self, rect): self.settings.child('weighting_settings', 'x0').setValue(int(rect.x())) self.settings.child('weighting_settings', 'y0').setValue(int(rect.y())) self.settings.child('weighting_settings', 'width').setValue(max([1, int(rect.width())])) self.settings.child('weighting_settings', 'height').setValue(max([1, int(rect.height())])) def parameter_tree_changed(self, param, changes): for param, change, data in changes: path = self.settings.childPath(param) if path is not None: childName = '.'.join(path) else: childName = param.name() if change == 'childAdded': pass elif change == 'value': if param.name() == 'do_something': if param.value(): self.log_signal.emit('Do something') self.detector.grab_done_signal.connect(self.show_data) self.settings.child('main_settings', 'something_done').setValue(True) else: self.log_signal.emit('Stop Doing something') self.detector.grab_done_signal.disconnect() self.settings.child('main_settings', 'something_done').setValue(False) elif change == 'parent': pass @pyqtSlot(OrderedDict) def show_data(self, data): """ do stuff with data from the detector if its grab_done_signal has been connected Parameters ---------- data: (OrderedDict) #OrderedDict(name=self.title,x_axis=None,y_axis=None,z_axis=None,data0D=None,data1D=None,data2D=None) """ data0D = [[data['data0D'][key]] for key in data['data0D']] self.raw_data.append(data0D) self.target_viewer.show_data(data0D) def create_menu(self, menubar): """ """ menubar.clear() #%% create file menu file_menu = menubar.addMenu('File') load_action = file_menu.addAction('Load file') load_action.triggered.connect(self.load_file) save_action = file_menu.addAction('Save file') save_action.triggered.connect(self.save_data) file_menu.addSeparator() quit_action = file_menu.addAction('Quit') quit_action.triggered.connect(self.quit_function) settings_menu = menubar.addMenu('Settings') docked_menu = settings_menu.addMenu('Docked windows') action_load = docked_menu.addAction('Load Layout') action_save = docked_menu.addAction('Save Layout') def load_file(self): #init the data browser module widg = QtWidgets.QWidget() self.data_browser = H5Browser(widg) widg.show() def quit_function(self): #close all stuff that need to be self.detector.quit_fun() QtWidgets.QApplication.processEvents() self.mainwindow.close() def create_toolbar(self): iconquit = QtGui.QIcon() iconquit.addPixmap( QtGui.QPixmap(":/Labview_icons/Icon_Library/close2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.quit_action = QtWidgets.QAction(iconquit, "Quit program", None) self.toolbar.addAction(self.quit_action) self.quit_action.triggered.connect(self.quit_function) icon_detector = QtGui.QIcon() icon_detector.addPixmap( QtGui.QPixmap(":/Labview_icons/Icon_Library/camera.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.detector_action = QtWidgets.QAction(icon_detector, "Grab from camera", None) self.detector_action.setCheckable(True) self.toolbar.addAction(self.detector_action) self.detector_action.triggered.connect(lambda: self.run_detector()) iconload = QtGui.QIcon() iconload.addPixmap( QtGui.QPixmap(":/Labview_icons/Icon_Library/Open.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.loadaction = QtWidgets.QAction( iconload, "Load target file (.h5, .png, .jpg) or data from camera", None) self.toolbar.addAction(self.loadaction) self.loadaction.triggered.connect(self.load_file) iconsave = QtGui.QIcon() iconsave.addPixmap( QtGui.QPixmap(":/Labview_icons/Icon_Library/SaveAs.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.saveaction = QtWidgets.QAction(iconsave, "Save current data", None) self.toolbar.addAction(self.saveaction) self.saveaction.triggered.connect(self.save_data) def run_detector(self): self.detector.ui.grab_pb.click() def save_data(self): try: fname = utils.select_file(start_path=self.save_file_pathname, save=True, ext='h5') if not (not (fname)): with tables.open_file( str(fname), mode='w', title='an example h5 file name') as h5file: data_to_save = np.squeeze(np.array(self.raw_data)) #save metadata h5file.root._v_attrs[ 'settings'] = custom_tree.parameter_to_xml_string( self.settings) for ind in range(data_to_save.shape[1]): arr = h5file.create_array('/', 'data_{:d}'.format(ind), data_to_save[:, ind]) arr._v_attrs['shape'] = data_to_save.shape[0] arr._v_attrs['type'] = 'data1D' arr = h5file.create_array('/', 'data_2D', data_to_save) arr._v_attrs['shape'] = data_to_save.shape arr._v_attrs['type'] = 'data2D' logger = "logging" text_atom = tables.atom.ObjectAtom() logger_array = h5file.create_vlarray('/', logger, atom=text_atom) logger_array._v_attrs['type'] = 'list' for ind_log in range(self.logger_list.count()): txt = self.logger_list.item(ind_log).text() logger_array.append(txt) st = 'file {:s} has been saved'.format(fname) self.add_log(st) self.settings.child('min_settings', 'info').setValue(st) except Exception as e: self.add_log(str(e)) @pyqtSlot(str) def add_log(self, txt): """ Add a log to the logger list from the given text log and the current time ================ ========= ====================== **Parameters** **Type** **Description** *txt* string the log to be added ================ ========= ====================== """ now = datetime.datetime.now() new_item = QtWidgets.QListWidgetItem(str(now) + ": " + txt) self.logger_list.addItem(new_item) ##to do ##self.save_parameters.logger_array.append(str(now)+": "+txt) @pyqtSlot(str) def emit_log(self, txt): """ Emit a log-signal from the given log index =============== ======== ======================= **Parameters** **Type** **Description** *txt* string the log to be emitted =============== ======== ======================= """ self.log_signal.emit(txt)
def __init__(self, scanZ, recWidget=None, *args, **kwargs): super().__init__(*args, **kwargs) self.setMinimumSize(2, 350) self.mainRec = recWidget self.webcam = instruments.Webcam() self.z = scanZ self.z.zHostPosition = 'left' self.z.zobject.HostBackLashEnable = False self.setPoint = 0 self.V = Q_(1, 'V') self.um = Q_(1, 'um') self.nm = Q_(1, 'nm') self.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised) self.scansPerS = 10 self.ProcessData = ProcessData(self.webcam) # Focus lock widgets self.kpEdit = QtGui.QLineEdit('4') self.kpEdit.setFixedWidth(60) self.kpEdit.textChanged.connect(self.unlockFocus) self.kpLabel = QtGui.QLabel('kp') self.kiEdit = QtGui.QLineEdit('0.01') self.kiEdit.setFixedWidth(60) self.kiEdit.textChanged.connect(self.unlockFocus) self.kiLabel = QtGui.QLabel('ki') self.lockButton = QtGui.QPushButton('Lock') self.lockButton.setCheckable(True) self.lockButton.clicked.connect(self.toggleFocus) self.lockButton.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding) moveLabel = QtGui.QLabel('Move [nm]') moveLabel.setAlignment(QtCore.Qt.AlignCenter) self.moveEdit = QtGui.QLineEdit('0') self.moveEdit.setFixedWidth(60) self.moveEdit.returnPressed.connect(self.zMoveEdit) self.focusDataBox = QtGui.QCheckBox('Save focus data') self.focusPropertiesDisplay = QtGui.QLabel(' st_dev = 0 max_dev = 0') self.graph = FocusLockGraph(self, self.mainRec) self.focusTime = 1000 / self.scansPerS self.focusTimer = QtCore.QTimer() self.focusTimer.timeout.connect(self.update) self.focusTimer.start(self.focusTime) self.locked = False self.n = 1 self.max_dev = 0 self.focusCalib = FocusCalibration(self) self.focusCalibThread = QtCore.QThread(self) self.focusCalib.moveToThread(self.focusCalibThread) self.focusCalibButton = QtGui.QPushButton('Calibrate') self.focusCalibButton.clicked.connect(self.focusCalib.start) self.focusCalibThread.start() try: prevCal = np.around(np.loadtxt('calibration')[0]/10) text = '1 px --> {} nm'.format(prevCal) self.calibrationDisplay = QtGui.QLineEdit(text) except: self.calibrationDisplay = QtGui.QLineEdit('0 px --> 0 nm') self.calibrationDisplay.setReadOnly(False) self.webcamgraph = WebcamGraph(self) dockArea = DockArea() graphDock = Dock("Focus laser graph", size=(400, 200)) graphDock.addWidget(self.graph) dockArea.addDock(graphDock) webcamDock = Dock("Focus laser view", size=(200, 200)) webcamDock.addWidget(self.webcamgraph) dockArea.addDock(webcamDock, 'right', graphDock) # GUI layout grid = QtGui.QGridLayout() self.setLayout(grid) grid.addWidget(dockArea, 0, 0, 1, 6) grid.addWidget(self.focusCalibButton, 1, 0) grid.addWidget(self.calibrationDisplay, 2, 0) grid.addWidget(self.focusDataBox, 1, 1) grid.addWidget(moveLabel, 1, 2) grid.addWidget(self.moveEdit, 2, 2) grid.addWidget(self.kpLabel, 1, 3) grid.addWidget(self.kpEdit, 1, 4) grid.addWidget(self.kiLabel, 2, 3) grid.addWidget(self.kiEdit, 2, 4) grid.addWidget(self.lockButton, 1, 5, 2, 1) grid.setColumnMinimumWidth(5, 170)
def initDialog(self, results=None, KData=None, bDrawText=False): ''' orders,记录当日00:00前一日开盘时间发送的交易命令 trasactions,记录当日00:00前一日已执行的orders positions,记录当日00:00时,各个symbols的positions 所以,这三个量都是数组,且大小不定,所以,不宜图形方式展示,适宜table方式展示 其他单值参数都可以考虑图形化方式 特别是pnl,cash,portfolio等 perf的生成时点是00:00,其内容为00:00前一天的活动 perf转化记录入result时,需要设置Index, 此Index的值为生成记录时点后的一天的收盘时间。 例如: 有三个交易日:2015-12-01,12-02,12-03 开收盘时间:Asia/Shanghai:09:30--15:00 (utc:01:30--07:00) 使用instant_fill==True方式执行订单 每日开盘时Buy(1) 有如下Events列表会生成并被处理 1)2015-12-01 00:00 utc 生成perf perf内容:由于是第一交易日的开始时间(非开市时间),无内容可记 记录入result: 记录Index:result.index = 2015-12-01 07:00 2)2015-12-01 01:30 utc 生成order,生成transaction,生成position 3)2015-12-02 00:00 utc 生成perf perf内容:2015-12-01 00:00 utc 至 2015-12-02 00:00 utc期间发生的交易事项及内容 记录入result: 记录Index:result.index = 2015-12-02 07:00 之后的4)5)6)同上 不合逻辑的地方需特别注意: 1)perf的生成时间和记录时间不一致,00:00生成(当日开始(非开市)),07:00记录(当日收市) 2)perf记录的是00:00之前一日的交易,记录时点却是当日收盘(当日收盘时间的记录,给人直观的理解应是记录当日开盘到收盘期间发生的业务) ''' self.results = results # 1) creates layouts dialog = QtGui.QDialog() mainLayout = QtGui.QHBoxLayout() rightLayout = QtGui.QVBoxLayout() mainLayout.addLayout(rightLayout) dialog.setLayout(mainLayout) dialog.setWindowTitle(('Strategy Results')) import os, sys xpower = os.path.abspath( os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, os.pardir, 'midProjects', 'histdataUI')) sys.path.append(xpower) from Widgets.pgCandleWidgetCross import pgCandleWidgetCross from Widgets.pgCrossAddition import pgCrossAddition from pyqtgraph.dockarea import DockArea, Dock area = DockArea() rightLayout.addWidget(area) # 2) creates widgets # 2.1)candle pgCandleView = pgCandleWidgetCross(dataForCandle=KData) self.pricePlot(pgCandleView) self.pricePlot(pgCandleView) self.indicatorsPlot(pgCandleView) self.signalPlot(pgCandleView) dCandle = Dock("candles", closable=True, size=(200, 300)) ## give this dock the minimum possible size area.addDock(dCandle, 'bottom') dCandle.addWidget(pgCandleView) # 2.2)position_pnl 当前position_pnl曲线 if (True): PyqtGraphPnl = pgCrossAddition() self.positionPnlPlot(PyqtGraphPnl, bDrawText=bDrawText) self.signalPlot(PyqtGraphPnl) dPnl = Dock("position_pnl", closable=True, size=(200, 100)) area.addDock(dPnl, 'bottom') dPnl.addWidget(PyqtGraphPnl) PyqtGraphPnl.setXLink(pgCandleView) # 2.3)position_cost if (True): PyqtGraphPositionCost = pgCrossAddition() self.positionCostPlot(PyqtGraphPositionCost) dPositionCost = Dock("position_cost", closable=True, size=(200, 100)) area.addDock(dPositionCost, 'bottom') dPositionCost.addWidget(PyqtGraphPositionCost) PyqtGraphPositionCost.setXLink(pgCandleView) # 2.3)position_volume if (False): PyqtGraphPosition = pgCrossAddition() self.positionVolumePlot(PyqtGraphPosition) dPosition = Dock("position_volume", closable=True, size=(200, 100)) area.addDock(dPosition, 'bottom') dPosition.addWidget(PyqtGraphPosition) PyqtGraphPosition.setXLink(pgCandleView) # 2.4)portfolio 总资产变动曲线 cash + equity if (True): PyqtGraphPortfolio = pgCrossAddition() self.portfolioPlot(PyqtGraphPortfolio) dPortfolio = Dock("portfolio", closable=True, size=(200, 100)) area.addDock(dPortfolio, 'bottom') dPortfolio.addWidget(PyqtGraphPortfolio) PyqtGraphPortfolio.setXLink(pgCandleView) # 2.5)indicator if (False): PyqtGraphindicators = pgCrossAddition() self.pricePlot(PyqtGraphindicators) self.indicatorsPlot(PyqtGraphindicators) dIndicator = Dock("indicator", closable=True, size=(200, 100)) dIndicator.addWidget(PyqtGraphindicators) area.addDock(dIndicator, 'bottom', dCandle) PyqtGraphindicators.setXLink(pgCandleView) # 2.6)order #PyqtGraphOrder = pgCrossAddition() #self.orderPlot(PyqtGraphOrder) #self.pricePlot(PyqtGraphOrder) ## Create docks, place them into the window one at a time. ## Note that size arguments are only a suggestion; docks will still have to ## fill the entire dock area and obey the limits of their internal widgets. #d6 = Dock("order time,amount",size=(200,100)) #area.addDock(d6, 'bottom', d1) #d6.addWidget(PyqtGraphOrder) #PyqtGraphOrder.setXLink(pgCandleView) return dialog
def __init__(self): """ Flowchart inside new window for system calibration """ # Graphics window self.win = QtGui.QMainWindow() self.win.setWindowTitle('System Calibration Flowchart') # Dock Area dockArea = DockArea() # Central widget self.win.setCentralWidget(dockArea) # Window Docks fcWidgetDock = Dock('Flowchart Widget', size=(1, 1), hideTitle=True) displayDock = Dock('Measurement and Calibration', size=(1, 1)) plotDocks = [Dock('Plot {}'.format(i), size=(1, 1)) for i in range(4)] dockArea.addDock(fcWidgetDock, 'left') dockArea.addDock(displayDock, 'right', fcWidgetDock) dockArea.addDock(plotDocks[0], 'top', displayDock) dockArea.addDock(plotDocks[1], 'right', plotDocks[0]) dockArea.addDock(plotDocks[2], 'top', displayDock) dockArea.addDock(plotDocks[3], 'right', plotDocks[2]) # Window size self.win.resize(800, 600) # Flowchart self.fc = Flowchart(terminals={ 'dipImgIn': { 'io': 'in' }, 'CalibConstOut': { 'io': 'out' }, }) # row, column, rowspan, colspan fcWidgetDock.addWidget(self.fc.widget()) # Plot widgets self.plt_widg = [FlowchartPlotWidget() for _ in range(len(plotDocks))] [ plotDocks[i].addWidget(self.plt_widg[i]) for i in range(len(plotDocks)) ] # Graphics layout for displays displayLayout = pg.GraphicsLayoutWidget(border='w') displayDock.addWidget(displayLayout) # Display widgets self.disp_widg = [] self.disp_widg.append( displayLayout.addLabel('', colspan=2, justify='left')) displayLayout.nextRow() self.disp_widg.append( displayLayout.addLabel('', colspan=2, justify='left')) # Flowchart library copy - custom nodes available to user self.fc_library = fclib.LIBRARY.copy() [ self.fc_library.addNodeType(nd, [('dipImage', 'Display')]) for nd in (FlowchartPlotNode, MeasurementDisplayNode, CalibDisplayNode, ORingMeasurementDisplayNode) ] # Filter nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Filters')]) for nd in (GaussianConvolutionNode, GradientNode, GradientMagnitudeNode, GradientDirectionNode, EdgeObjectsRemoveNode, KuwaharaNode, BilateralFilterNode) ] # Binary Filter nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Binary')]) for nd in (BinaryClosingNode, BinaryOpeningNode, BinaryErosionNode, BinaryDilationNode, BinaryAreaClosingNode, BinaryAreaOpeningNode, BinaryPropagationNode, FillHolesNode) ] # Segmentation nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Segmentation')]) for nd in (ThresholdNode, RangeThresholdNode, MinimaNode, MaximaNode, WatershedNode, SeededWatershedNode, CannyNode, SegmentORingNode) ] # Morphological nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Morphological')]) for nd in (DilationNode, ErosionNode, OpeningNode, ClosingNode) ] # Image nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Image')]) for nd in (ConvertNode, FillNode, LabelNode, SetPixelSizeNode) ] # Arithmetics nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Arithmetics')]) for nd in (InvertNode, ApplyMaskNode, CreateMaskNode, OperatorPlusNode) ] # Measurement nodes [ self.fc_library.addNodeType(nd, [('dipImage', 'Measurement')]) for nd in (MeasureNode, WorkingDistanceCorrectionNode, CombineMeasurementNode) ] self.fc.setLibrary(self.fc_library) # Plot nodes and Widget connection plt_nodes_x = (-20 + x * 120 for x in range(len(self.plt_widg))) plt_nodes = [ self.fc.createNode('FlowchartPlot', pos=(x, -60)) for x in plt_nodes_x ] [ nd.set_fcPlotWidget(widg) for nd, widg in zip(plt_nodes, self.plt_widg) ] # Connecting plot and display widgets with nodes self.fc.sigFileLoaded.connect(self.setFlowchartPlotWidgets) self.fc.sigFileLoaded.connect(self.setDisplayWidgets) self.fc.sigChartChanged.connect(self.setFlowchartPlotWidgets) self.fc.sigChartChanged.connect(self.setDisplayWidgets)
def __init_radial_widget(self): self.radial_profile = RadialProfileWidget(self) dock = Dock('Radial Profile') dock.addWidget(self.radial_profile) self.addDock(dock, position='bottom') self.radial_profile_dock = dock
def plot_pyqtgraph(self, event): try: iter(event) signals = event except: iterator = QTreeWidgetItemIterator(self.channels_tree) group = -1 index = 0 signals = [] while iterator.value(): item = iterator.value() if item.parent() is None: iterator += 1 group += 1 index = 0 continue if item.checkState(0) == Qt.Checked: group, index = item.entry ch = self.mdf.groups[group].channels[index] if not ch.component_addr: signals.append((None, group, index)) index += 1 iterator += 1 signals = self.mdf.select(signals) signals = [ sig for sig in signals if not sig.samples.dtype.names and len(sig.samples.shape) <= 1 ] signals = natsorted(signals, key=lambda x: x.name) if signals: if not self.subplots: wid = self.splitter.widget(1) wid.setParent(None) self.dock_area = DockArea(self.splitter) self.splitter.addWidget(self.dock_area) count = len(self.dock_area.docks) self.dock_area.hide() dock_name = self._dock_names.get_unique_name('Plot') dock = Dock(dock_name, size=(1, 1), closable=True) self.dock_area.addDock(dock) dock.label.sigClicked.connect( partial(self.mark_active_plot, dock_name)) dock.sigClosed.connect(self.close_plot) plot = Plot(signals, self.with_dots) plot.plot.update_lines(force=True) plot.clicked.connect(partial(self.mark_active_plot, dock_name)) plot.close_request.connect(partial(self.close_plot, dock)) dock.addWidget(plot) self.dock_area.show() if count and self.subplots_link: plot.plot.viewbox.setXLink( self.get_current_plot().plot.viewbox) self.splitter.setSizes([100, 100]) self.mark_active_plot(dock_name) QApplication.processEvents()
def __init_image_viewer(self): self.image_view = Basic2DImageWidget(self) dock = Dock('ImageViewer') dock.addWidget(self.image_view) self.addDock(dock, size=(1000, 1000)) self.image_viewer_dock = dock
def set_viewer(self): dock_viewer = Dock('Viewer2D') self.area.addDock(dock_viewer, 'right') widget = QtWidgets.QWidget() self.viewer = Viewer2D(widget) dock_viewer.addWidget(widget)
class OutputItem(GroupItemChild): def __init__(self, group): super(OutputItem, self).__init__("Output_1", [ ("simulation", group.setup.sims_item, group.setup.sims_item.items_list()[0].name()), ("mode", group.setup.modes_item, group.setup.modes_item.items_list()[0].name()), ("report type", ["Wigner", "Expect-XYZ"], "Wigner"), ("wigner range", float, 5), ("wigner resolution", int, 100), ], group) self.context_menu.add_action("Re-Compute", self.compute) self.data = None self.dock = None self.plot = None def compute(self): win.set_status("Computing Output %s" % self.name()) output_steps = [] if self.report_type == "Wigner": dx = self.wigner_range nx = self.wigner_resolution axis = linspace(-dx, dx, nx) step_function = lambda state: wigner(state, axis, axis) else: dim = self.mode.dimension a = destroy(dim) ad = a.dag() ops = [a + ad, 1j*(a - ad), a*ad] step_function = lambda state: [expect(op, state) for op in ops] n_states = len(self.simulation.states) for i, s in enumerate(self.simulation.states): output_steps.append(step_function(s.ptrace(self.mode.tensor_index()))) win.set_progress(100*float(i)/n_states) win.set_progress(0) win.set_status("") if output_steps: self.data = np.array(output_steps) if self.report_type == "Wigner": self.plot_wigner() elif self.report_type == "Expect-XYZ": self.plot_xyz() def plot_type(self): return { "Wigner": MyImageView, "Expect-XYZ": TimePlot, }[self.report_type] def check_dock(self): if self.plot is not None: self.plot.setParent(None) self.plot = self.plot_type()() if self.dock is None: self.dock = Dock(self.name(), widget=self.plot) win.outputs_dock_area.addDock(self.dock) else: self.dock.addWidget(self.plot) def plot_wigner(self): if not isinstance(self.plot, ImageView): self.check_dock() self.plot.setImage(self.data, xvals=array(self.simulation.times)) # TODO: Bloch/XYZ plot output implementation def plot_xyz(self): if not isinstance(self.plot, PlotWidget): self.check_dock() self.plot.clear() self.plot.add_line() self.plot.addLegend() for trace, name, pen in zip(self.data.transpose(), 'XYZ', pen_generator()): self.plot.plot(self.simulation.times, trace, pen=pen, name=name)
def add_widgets(self): # Main window with dock area self.dock_area = DockArea() self.setCentralWidget(self.dock_area) # Docks dock_occcupancy = Dock("Occupancy", size=(400, 400)) dock_run_config = Dock("Configuration", size=(400, 400)) dock_tot = Dock("Time over threshold values (TOT)", size=(400, 400)) dock_tdc = Dock("Time digital converter values (TDC)", size=(400, 400)) dock_event_status = Dock("Event status", size=(400, 400)) dock_trigger_status = Dock("Trigger status", size=(400, 400)) dock_service_records = Dock("Service records", size=(400, 400)) dock_hit_timing = Dock("Hit timing (rel. BCID)", size=(400, 400)) dock_status = Dock("Status", size=(800, 40)) self.dock_area.addDock(dock_run_config, 'left') self.dock_area.addDock(dock_occcupancy, 'above', dock_run_config) self.dock_area.addDock(dock_tdc, 'right', dock_occcupancy) self.dock_area.addDock(dock_tot, 'above', dock_tdc) self.dock_area.addDock(dock_service_records, 'bottom', dock_occcupancy) self.dock_area.addDock(dock_trigger_status, 'above', dock_service_records) self.dock_area.addDock(dock_event_status, 'above', dock_trigger_status) self.dock_area.addDock(dock_hit_timing, 'bottom', dock_tot) self.dock_area.addDock(dock_status, 'top') # Status widget cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Scan Parameters\n") self.spin_box = Qt.QSpinBox(value=1) layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.event_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) dock_status.addWidget(cw) # Config dock self.run_conf_list_widget = Qt.QListWidget() dock_run_config.addWidget(self.run_conf_list_widget) # Different plot docks occupancy_graphics = pg.GraphicsLayoutWidget() occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_img = pg.ImageItem(border='w') view.addItem(self.occupancy_img) view.setRange(QtCore.QRectF(0, 0, 80, 336)) dock_occcupancy.addWidget(occupancy_graphics) tot_plot_widget = pg.PlotWidget(background="w") self.tot_plot = tot_plot_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) tot_plot_widget.showGrid(y=True) dock_tot.addWidget(tot_plot_widget) tdc_plot_widget = pg.PlotWidget(background="w") self.tdc_plot = tdc_plot_widget.plot(np.linspace(-0.5, 4095.5, 4097), np.zeros((4096)), stepMode=True) tdc_plot_widget.showGrid(y=True) tdc_plot_widget.setXRange(0, 800, update=True) dock_tdc.addWidget(tdc_plot_widget) event_status_widget = pg.PlotWidget() self.event_status_plot = event_status_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) event_status_widget.showGrid(y=True) dock_event_status.addWidget(event_status_widget) trigger_status_widget = pg.PlotWidget() self.trigger_status_plot = trigger_status_widget.plot(np.linspace(-0.5, 7.5, 9), np.zeros((8)), stepMode=True) trigger_status_widget.showGrid(y=True) dock_trigger_status.addWidget(trigger_status_widget) service_record_widget = pg.PlotWidget() self.service_record_plot = service_record_widget.plot(np.linspace(-0.5, 31.5, 33), np.zeros((32)), stepMode=True) service_record_widget.showGrid(y=True) dock_service_records.addWidget(service_record_widget) hit_timing_widget = pg.PlotWidget() self.hit_timing_plot = hit_timing_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) hit_timing_widget.showGrid(y=True) dock_hit_timing.addWidget(hit_timing_widget)
print e # p=pg.plot() # for e in sorted(dir(p)): # print e w=pg.PlotWidget() w.setWindowTitle('pyqtgraph example: PlotSpeedTest') w.setRange(QtCore.QRectF(0, -20, 5000, 30)) w.setLabel('bottom', 'Index', units='B') curve = w.plot() # curve= pg.PlotWidget().plotItem d1.addWidget(w) d2.addWidget(w) #curve.setFillBrush((0, 0, 100, 100)) #curve.setFillLevel(0) #lr = pg.LinearRegionItem([100, 4900]) #p.addItem(lr) data = np.random.normal(size=(50,5000)) ptr = 0 lastTime = time() fps = None
def __init_angular_widget(self): self.angular_profile = AngularProfileWidget(self) dock = Dock('Angular Profile') dock.addWidget(self.angular_profile) self.addDock(dock, position='bottom') self.angular_profile_dock = dock
class MainWindow(QMainWindow): """ Main control window for showing the live captured images and initiating special tasks """ def __init__(self, experiment): """ Inits the camera window :param experiment: Experiment that is controlled by the GUI """ super().__init__() self.setWindowTitle('PyNTA: Python Nanoparticle Tracking Analysis') self.setMouseTracking(True) self.experiment = experiment self.area = DockArea() self.setCentralWidget(self.area) self.resize(1064, 840) self.area.setMouseTracking(True) # Main widget self.camWidget = MonitorMainWidget() self.camWidget.setup_cross_cut(self.experiment.max_height) self.camWidget.setup_cross_hair( [self.experiment.max_width, self.experiment.max_height]) self.camWidget.setup_roi_lines( [self.experiment.max_width, self.experiment.max_height]) self.camWidget.setup_mouse_tracking() self.messageWidget = messageWidget() self.cheatSheet = popOutWindow() self.dmainImage = Dock("Camera", size=(80, 35)) # sizes are in percentage self.dmainImage.addWidget(self.camWidget) self.area.addDock(self.dmainImage, 'right') self.dmessage = Dock("Messages", size=(40, 30)) self.dmessage.addWidget(self.messageWidget) self.area.addDock(self.dmessage, 'right') # # Widget for displaying information to the user # # Small window to display the results of the special task # self.trajectoryWidget = trajectoryWidget() # # Window for the camera viewer # # self.camViewer = cameraViewer(self._session, self.camera, parent=self) # # Configuration widget with a parameter tree # # self.config = ConfigWidget(self._session) # # Line cut widget # self.crossCut = crossCutWindow(parent=self) # self.popOut = popOutWindow(parent=self) #_future: for making long message pop-ups # # Select settings Window # # self.selectSettings = HDFLoader() # self.refreshTimer = QtCore.QTimer() self.refreshTimer.timeout.connect(self.updateGUI) # self.refreshTimer.timeout.connect(self.crossCut.update) # self.refreshTimer.start(self.experiment.config['GUI']['refresh_time']) # # self.acquiring = False # self.logmessage = [] # # ''' Initialize the camera and the camera related things ''' # self.max_sizex = self.camera.GetCCDWidth() # self.max_sizey = self.camera.GetCCDHeight() # self.current_width = self.max_sizex # self.current_height = self.max_sizey # # # if self._session.Camera['roi_x1'] == 0: # # self._session.Camera = {'roi_x1': 1} # # if self._session.Camera['roi_x2'] == 0 or self._session.Camera['roi_x2'] > self.max_sizex: # # self._session.Camera = {'roi_x2': self.max_sizex} # # if self._session.Camera['roi_y1'] == 0: # # self._session.Camera = {'roi_y1': 1} # # if self._session.Camera['roi_y2'] == 0 or self._session.Camera['roi_y2'] > self.max_sizey: # # self._session.Camera = {'roi_y2': self.max_sizey} # # # self.config.populateTree(self.experiment.config) # self.lastBuffer = time.time() # self.lastRefresh = time.time() # # # Program variables # self.tempimage = [] # self.bgimage = [] # self.trackinfo = np.zeros((1,5)) # real particle trajectory filled by "LocateParticle" analysis # # self.noiselvl = self._session.Tracking['noise_level'] # self.fps = 0 # self.buffertime = 0 # self.buffertimes = [] # self.refreshtimes = [] # self.totalframes = 0 # self.droppedframes = 0 # self.buffer_memory = 0 # self.waterfall_data = [] # self.watindex = 0 # Waterfall index # self.corner_roi = [] # Real coordinates of the corner of the ROI region. (Min_x and Min_y). # self.docks = [] # # self.corner_roi.append(self._session.Camera['roi_x1']) # # self.corner_roi.append(self._session.Camera['roi_y1']) # # # Program status controllers # self.continuous_saving = False # self.show_waterfall = False # self.subtract_background = False # self.save_running = False # self.accumulate_buffer = False # self.specialtask_running = False # self.dock_state = None # self.setupActions() self.setupToolbar() self.setupMenubar() # self.setupDocks() # self.setupSignals() ### This block should erased in due time and one must rely exclusively on Session variables. # self.filedir = self._session.Saving['directory'] # self.snap_filename = self._session.Saving['filename_photo'] # self.movie_filename = self._session.Saving['filename_video'] ### self.messageWidget.appendLog( 'i', 'Program started by %s' % self.experiment.config['User']['name']) def start_tracking(self): self.experiment.start_tracking() def showHelp(self): """To show the cheatsheet for shortcuts in a pop-up meassage box OBSOLETE, will be deleted after transferring info into a better message viewer! """ self.experiment.plot_histogram() # msgBox = QtGui.QMessageBox() # msgBox.setIcon(QtGui.QMessageBox.Information) # msgBox.setText("Keyboard shortcuts and Hotkeys") # msgBox.setInformativeText("Press details for a full list") # msgBox.setWindowTitle("nanoparticle_tracking CheatSheet") # msgBox.setDetailedText(""" # F1, Show cheatsheet\n # F5, Snap image\n # F6, Continuous run\n # Alt+mouse: Select line \n # Ctrl+mouse: Crosshair \n # Ctrl+B: Toggle buffering\n # Ctrl+G: Toggle background subtraction\n # Ctrl+F: Empty buffer\n # Ctrl+C: Start tracking\n # Ctrl+V: Stop tracking\n # Ctrl+M: Autosave on\n # Ctrl+N: Autosave off\n # Ctrl+S: Save image\n # Ctrl+W: Start waterfall\n # Ctrl+Q: Exit application\n # Ctrl+Shift+W: Save waterfall data\n # Ctrl+Shift+T: Save trajectory\n # """) def setupActions(self): """Setups the actions that the program will have. It is placed into a function to make it easier to reuse in other windows. :rtype: None """ self.exitAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/power-icon.png'), '&Exit', self) self.exitAction.setShortcut('Ctrl+Q') self.exitAction.setStatusTip('Exit application') self.exitAction.triggered.connect(self.exitSafe) self.saveAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/floppy-icon.png'), '&Save image', self) self.saveAction.setShortcut('Ctrl+S') self.saveAction.setStatusTip('Save Image') self.saveAction.triggered.connect(self.saveImage) self.showHelpAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/info-icon.png'), 'Show cheatsheet', self) self.showHelpAction.setShortcut(QtCore.Qt.Key_F1) self.showHelpAction.setStatusTip('Show Cheatsheet') self.showHelpAction.triggered.connect(self.showHelp) self.saveWaterfallAction = QtGui.QAction("Save Waterfall", self) self.saveWaterfallAction.setShortcut('Ctrl+Shift+W') self.saveWaterfallAction.setStatusTip( 'Save waterfall data to new file') self.saveWaterfallAction.triggered.connect(self.saveWaterfall) self.saveTrajectoryAction = QtGui.QAction("Save Trajectory", self) self.saveTrajectoryAction.setShortcut('Ctrl+Shift+T') self.saveTrajectoryAction.setStatusTip( 'Save trajectory data to new file') self.saveTrajectoryAction.triggered.connect(self.saveTrajectory) self.snapAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/snap.png'), 'S&nap photo', self) self.snapAction.setShortcut(QtCore.Qt.Key_F5) self.snapAction.setStatusTip('Snap Image') self.snapAction.triggered.connect(self.snap) self.movieAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/video-icon.png'), 'Start &movie', self) self.movieAction.setShortcut(QtCore.Qt.Key_F6) self.movieAction.setStatusTip('Start Movie') self.movieAction.triggered.connect(self.startMovie) self.movieSaveStartAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/Download-Database-icon.png' ), 'Continuous saves', self) self.movieSaveStartAction.setShortcut('Ctrl+M') self.movieSaveStartAction.setStatusTip('Continuous save to disk') self.movieSaveStartAction.triggered.connect(self.movieSave) self.movieSaveStopAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/Delete-Database-icon.png' ), 'Stop continuous saves', self) self.movieSaveStopAction.setShortcut('Ctrl+N') self.movieSaveStopAction.setStatusTip('Stop continuous save to disk') self.movieSaveStopAction.triggered.connect(self.movieSaveStop) self.startWaterfallAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/Blue-Waterfall-icon.png' ), 'Start &Waterfall', self) self.startWaterfallAction.setShortcut('Ctrl+W') self.startWaterfallAction.setStatusTip('Start Waterfall') self.startWaterfallAction.triggered.connect(self.startWaterfall) self.toggleBGAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/noBg.png'), 'Toggle B&G-reduction', self) self.toggleBGAction.setShortcut('Ctrl+G') self.toggleBGAction.setStatusTip('Toggle Background Reduction') self.toggleBGAction.triggered.connect(self.start_tracking) self.setROIAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/Zoom-In-icon.png'), 'Set &ROI', self) self.setROIAction.setShortcut('Ctrl+T') self.setROIAction.setStatusTip('Set ROI') self.setROIAction.triggered.connect(self.getROI) self.clearROIAction = QtGui.QAction( QtGui.QIcon( 'nanoparticle_tracking/View/GUI/Icons/Zoom-Out-icon.png'), 'Set R&OI', self) self.clearROIAction.setShortcut('Ctrl+T') self.clearROIAction.setStatusTip('Clear ROI') self.clearROIAction.triggered.connect(self.clearROI) self.accumulateBufferAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/disk-save.png'), 'Accumulate buffer', self) self.accumulateBufferAction.setShortcut('Ctrl+B') self.accumulateBufferAction.setStatusTip( 'Start or stop buffer accumulation') self.accumulateBufferAction.triggered.connect(self.bufferStatus) self.clearBufferAction = QtGui.QAction('Clear Buffer', self) self.clearBufferAction.setShortcut('Ctrl+F') self.clearBufferAction.setStatusTip('Clears the buffer') self.clearBufferAction.triggered.connect(self.emptyQueue) self.viewerAction = QtGui.QAction('Start Viewer', self) # self.viewerAction.triggered.connect(self.camViewer.show) self.configAction = QtGui.QAction('Config Window', self) # self.configAction.triggered.connect(self.config.show) self.dockAction = QtGui.QAction('Restore Docks', self) self.dockAction.triggered.connect(self.setupDocks) self.crossCutAction = QtGui.QAction( QtGui.QIcon('nanoparticle_tracking/View/GUI/Icons/Ruler-icon.png'), 'Show cross cut', self) # self.crossCutAction.triggered.connect(self.crossCut.show) self.settingsAction = QtGui.QAction('Load config', self) # self.settingsAction.triggered.connect(self.selectSettings.show) def setupToolbar(self): """Setups the toolbar with the desired icons. It's placed into a function to make it easier to reuse in other windows. """ self.toolbar = self.addToolBar('Exit') self.toolbar.addAction(self.exitAction) self.toolbar2 = self.addToolBar('Image') self.toolbar2.addAction(self.saveAction) self.toolbar2.addAction(self.snapAction) self.toolbar2.addAction(self.crossCutAction) self.toolbar3 = self.addToolBar('Movie') self.toolbar3.addAction(self.movieAction) self.toolbar3.addAction(self.movieSaveStartAction) self.toolbar3.addAction(self.movieSaveStopAction) self.toolbar4 = self.addToolBar('Extra') self.toolbar4.addAction(self.startWaterfallAction) self.toolbar4.addAction(self.setROIAction) self.toolbar4.addAction(self.clearROIAction) self.toolbar4.addAction(self.clearROIAction) self.toolbar4.addAction(self.toggleBGAction) self.toolbar5 = self.addToolBar('Help') self.toolbar5.addAction(self.showHelpAction) def setupMenubar(self): """Setups the menubar. """ menubar = self.menuBar() self.fileMenu = menubar.addMenu('&File') self.fileMenu.addAction(self.settingsAction) self.fileMenu.addAction(self.saveAction) self.fileMenu.addAction(self.exitAction) self.snapMenu = menubar.addMenu('&Snap') self.snapMenu.addAction(self.snapAction) self.snapMenu.addAction(self.saveAction) self.movieMenu = menubar.addMenu('&Movie') self.movieMenu.addAction(self.movieAction) self.movieMenu.addAction(self.movieSaveStartAction) self.movieMenu.addAction(self.movieSaveStopAction) self.movieMenu.addAction(self.startWaterfallAction) self.configMenu = menubar.addMenu('&Configure') self.configMenu.addAction(self.toggleBGAction) self.configMenu.addAction(self.setROIAction) self.configMenu.addAction(self.clearROIAction) self.configMenu.addAction(self.accumulateBufferAction) self.configMenu.addAction(self.clearBufferAction) self.configMenu.addAction(self.viewerAction) self.configMenu.addAction(self.configAction) self.configMenu.addAction(self.dockAction) self.saveMenu = menubar.addMenu('S&ave') self.snapMenu.addAction(self.saveAction) self.saveMenu.addAction(self.saveWaterfallAction) self.saveMenu.addAction(self.saveTrajectoryAction) self.helpMenu = menubar.addMenu('&Help') self.helpMenu.addAction(self.showHelpAction) def setupDocks(self): """Setups the docks in order to recover the initial configuration if one gets closed.""" for d in self.docks: try: d.close() except: pass self.docks = [] self.dmainImage = Dock("Camera", size=(80, 35)) #sizes are in percentage self.dwaterfall = Dock("Waterfall", size=(80, 35)) self.dparams = Dock("Parameters", size=(20, 100)) self.dtraj = Dock("Trajectory", size=(40, 30)) # self.dstatus = Dock("Status", size=(100, 3)) self.area.addDock(self.dmainImage, 'right') self.area.addDock(self.dparams, 'left', self.dmainImage) self.area.addDock(self.dtraj, 'bottom', self.dmainImage) self.area.addDock(self.dmessage, 'right', self.dtraj) self.docks.append(self.dmainImage) self.docks.append(self.dtraj) self.docks.append(self.dmessage) self.docks.append(self.dparams) self.docks.append(self.dwaterfall) # self.area.addDock(self.dstatus, 'bottom', self.dparams) self.dmainImage.addWidget(self.camWidget) self.dparams.addWidget(self.config) self.dtraj.addWidget(self.trajectoryWidget) self.dock_state = self.area.saveState() def setupSignals(self): """Setups all the signals that are going to be handled during the excution of the program.""" self.connect(self._session, QtCore.SIGNAL('updated'), self.config.populateTree) self.connect(self.config, QtCore.SIGNAL('updateSession'), self.updateSession) self.connect(self.camWidget, QtCore.SIGNAL('specialTask'), self.startSpecialTask) self.connect(self.camWidget, QtCore.SIGNAL('stopSpecialTask'), self.stopSpecialTask) self.connect(self.camViewer, QtCore.SIGNAL('stopMainAcquisition'), self.stopMovie) self.connect(self, QtCore.SIGNAL('stopChildMovie'), self.camViewer.stop_camera) self.connect(self, QtCore.SIGNAL('closeAll'), self.camViewer.closeViewer) self.connect(self.selectSettings, QtCore.SIGNAL("settings"), self.update_settings) self.connect(self, QtCore.SIGNAL('closeAll'), self.selectSettings.close) def snap(self): """Function for acquiring a single frame from the camera. It is triggered by the user. It gets the data the GUI will be updated at a fixed framerate. """ if self.experiment.acquiring: #If it is itself acquiring a message is displayed to the user warning him msgBox = QtGui.QMessageBox() msgBox.setIcon(QtGui.QMessageBox.Critical) msgBox.setText("You cant snap a photo while in free run") msgBox.setInformativeText("The program is already acquiring data") msgBox.setWindowTitle("Already acquiring") msgBox.setDetailedText( """When in free run, you can\'t trigger another acquisition. \n You should stop the free run acquisition and then snap a photo.""" ) msgBox.setStandardButtons(QtGui.QMessageBox.Ok) retval = msgBox.exec_() self.messageWidget.appendLog('e', 'Tried to snap while in free run') else: self.experiment.snap() # self.messageWidget.appendLog('i', 'Snapped photo') def toggleBGReduction(self): """Toggles between background cancellation modes. Takes a background snap if necessary """ if self.subtract_background: self.subtract_background = False self.messageWidget.appendLog('i', 'Background reduction deactivated') else: if len(self.tempimage) == 0: self.snap() self.messageWidget.appendLog('i', 'Snapped an image as background') else: self.subtract_background = True self.bgimage = self.tempimage.astype(float) self.messageWidget.appendLog('i', 'Background reduction active') def saveImage(self): """Saves the image that is being displayed to the user. """ if len(self.tempimage) >= 1: # Data will be appended to existing file fn = self._session.Saving['filename_photo'] filename = '%s.hdf5' % (fn) fileDir = self._session.Saving['directory'] if not os.path.exists(fileDir): os.makedirs(fileDir) f = h5py.File(os.path.join(fileDir, filename), "a") now = str(datetime.now()) g = f.create_group(now) dset = g.create_dataset('image', data=self.tempimage) meta = g.create_dataset('metadata', data=self._session.serialize()) f.flush() f.close() self.messageWidget.appendLog('i', 'Saved photo') def startMovie(self): self.experiment.start_free_run() def stopMovie(self): if self.acquiring: self.workerThread.keep_acquiring = False while self.workerThread.isRunning(): pass self.acquiring = False self.camera.stopAcq() self.messageWidget.appendLog('i', 'Continuous run stopped') if self.continuous_saving: self.movieSaveStop() def movieData(self): """Function just to trigger and read the camera in the separate thread. """ self.workerThread.start() def movieSave(self): """Saves the data accumulated in the queue continuously. """ if not self.continuous_saving: # Child process to save the data. It runs continuously until and exit flag # is passed through the Queue. (self.q.put('exit')) self.accumulate_buffer = True if len(self.tempimage) > 1: im_size = self.tempimage.nbytes max_element = int(self._session.Saving['max_memory'] / im_size) #self.q = Queue(0) fn = self._session.Saving['filename_video'] filename = '%s.hdf5' % (fn) fileDir = self._session.Saving['directory'] if not os.path.exists(fileDir): os.makedirs(fileDir) to_save = os.path.join(fileDir, filename) metaData = self._session.serialize( ) # This prints a YAML-ready version of the session. self.p = Process(target=workerSaver, args=( to_save, metaData, self.q, )) # self.p.start() self.continuous_saving = True self.messageWidget.appendLog('i', 'Continuous autosaving started') else: self.messageWidget.appendLog( 'w', 'Continuous savings already triggered') def movieSaveStop(self): """Stops the saving to disk. It will however flush the queue. """ if self.continuous_saving: self.q.put('Stop') self.accumulate_buffer = False #self.p.join() self.messageWidget.appendLog('i', 'Continuous autosaving stopped') self.continuous_saving = False def emptyQueue(self): """Clears the queue. """ # Worker thread for clearing the queue. self.clearWorker = Process(target=clearQueue, args=(self.q, )) self.clearWorker.start() def startWaterfall(self): """Starts the waterfall. The waterfall can be accelerated if camera supports hardware binning in the appropriate direction. If not, has to be done via software but the acquisition time cannot be improved. TODO: Fast waterfall should have separate window, since the acquisition of the full CCD will be stopped. """ if not self.show_waterfall: self.watWidget = waterfallWidget() self.area.addDock(self.dwaterfall, 'bottom', self.dmainImage) self.dwaterfall.addWidget(self.watWidget) self.show_waterfall = True Sx, Sy = self.camera.get_size() self.waterfall_data = np.zeros( (self._session.GUI['length_waterfall'], Sx)) self.watWidget.img.setImage(np.transpose(self.waterfall_data), autoLevels=False, autoRange=False, autoHistogramRange=False) self.messageWidget.appendLog('i', 'Waterfall opened') else: self.closeWaterfall() def stopWaterfall(self): """Stops the acquisition of the waterfall. """ pass def closeWaterfall(self): """Closes the waterfall widget. """ if self.show_waterfall: self.watWidget.close() self.dwaterfall.close() self.show_waterfall = False del self.waterfall_data self.messageWidget.appendLog('i', 'Waterfall closed') def setROI(self, X, Y): """ Gets the ROI from the lines on the image. It also updates the GUI to accommodate the changes. :param X: :param Y: :return: """ if not self.acquiring: self.corner_roi[0] = X[0] self.corner_roi[1] = Y[0] if self._session.Debug['to_screen']: print('Corner: %s, %s' % (self.corner_roi[0], self.corner_roi[1])) self._session.Camera = {'roi_x1': int(X[0])} self._session.Camera = {'roi_x2': int(X[1])} self._session.Camera = {'roi_y1': int(Y[0])} self._session.Camera = {'roi_y2': int(Y[1])} self.messageWidget.appendLog('i', 'Updated roi_x1: %s' % int(X[0])) self.messageWidget.appendLog('i', 'Updated roi_x2: %s' % int(X[1])) self.messageWidget.appendLog('i', 'Updated roi_y1: %s' % int(Y[0])) self.messageWidget.appendLog('i', 'Updated roi_y2: %s' % int(Y[1])) Nx, Ny = self.camera.set_ROI(X, Y) Sx, Sy = self.camera.get_size() self.current_width = Sx self.current_height = Sy self.tempimage = np.zeros((Nx, Ny)) self.camWidget.hline1.setValue(1) self.camWidget.hline2.setValue(Ny) self.camWidget.vline1.setValue(1) self.camWidget.vline2.setValue(Nx) self.trackinfo = np.zeros((1, 5)) #self.camWidget.img2.clear() if self.show_waterfall: self.waterfall_data = np.zeros( (self._session.GUI['length_waterfall'], self.current_width)) self.watWidget.img.setImage(np.transpose(self.waterfall_data)) self.config.populateTree(self._session) self.messageWidget.appendLog('i', 'Updated the ROI') else: self.messageWidget.appendLog('e', 'Cannot change ROI while acquiring.') def getROI(self): """Gets the ROI coordinates from the GUI and updates the values.""" y1 = np.int(self.camWidget.hline1.value()) y2 = np.int(self.camWidget.hline2.value()) x1 = np.int(self.camWidget.vline1.value()) x2 = np.int(self.camWidget.vline2.value()) X = np.sort((x1, x2)) Y = np.sort((y1, y2)) # Updates to the real values X += self.corner_roi[0] - 1 Y += self.corner_roi[1] - 1 self.setROI(X, Y) def clearROI(self): """Resets the roi to the full image. """ if not self.acquiring: self.camWidget.hline1.setValue(1) self.camWidget.vline1.setValue(1) self.camWidget.vline2.setValue(self.max_sizex) self.camWidget.hline2.setValue(self.max_sizey) self.corner_roi = [1, 1] self.getROI() else: self.messageWidget.appendLog('e', 'Cannot change ROI while acquiring.') def bufferStatus(self): """Starts or stops the buffer accumulation. """ if self.accumulate_buffer: self.accumulate_buffer = False self.messageWidget.appendLog('i', 'Buffer accumulation stopped') else: self.accumulate_buffer = True self.messageWidget.appendLog('i', 'Buffer accumulation started') def getData(self, data, origin): """Gets the data that is being gathered by the working thread. .. _getData: .. data: single image or a list of images (saved in buffer) .. origin: indicates which command has trigerred execution of this method (e.g. 'snap' of 'movie') both input variables are handed it through QThread signal that is "emit"ted """ s = 0 if origin == 'snap': # Single snap. self.acquiring = False self.workerThread.origin = None self.workerThread.keep_acquiring = False # This already happens in the worker thread itself. self.camera.stopAcq() if isinstance(data, list): for d in data: if self.accumulate_buffer: s = float(self.q.qsize()) * int(d.nbytes) / 1024 / 1024 if s < self._session.Saving['max_memory']: self.q.put(d) else: self.droppedframes += 1 if self.show_waterfall: if self.watindex == self._session.GUI['length_waterfall']: if self._session.Saving['autosave_trajectory']: self.saveWaterfall() self.waterfall_data = np.zeros( (self._session.GUI['length_waterfall'], self.current_width)) self.watindex = 0 centerline = np.int(self.current_height / 2) vbinhalf = np.int(self._session.GUI['vbin_waterfall']) if vbinhalf >= self.current_height / 2 - 1: wf = np.array([np.sum(d, 1)]) else: wf = np.array([ np.sum( d[:, centerline - vbinhalf:centerline + vbinhalf], 1) ]) self.waterfall_data[self.watindex, :] = wf self.watindex += 1 self.totalframes += 1 self.tempimage = d else: self.tempimage = data if self.accumulate_buffer: s = float(self.q.qsize()) * int(data.nbytes) / 1024 / 1024 if s < self._session.Saving['max_memory']: self.q.put(data) else: self.droppedframes += 1 if self.show_waterfall: if self.watindex == self._session.GUI['length_waterfall']: # checks if the buffer variable for waterfall image is full, saves it if requested, and sets it to zero. if self._session.Saving['autosave_trajectory']: self.saveWaterfall() self.waterfall_data = np.zeros( (self._session.GUI['length_waterfall'], self.current_width)) self.watindex = 0 centerline = np.int(self.current_height / 2) vbinhalf = np.int(self._session.GUI['vbin_waterfall'] / 2) if vbinhalf >= self.current_height - 1: wf = np.array([np.sum(data, 1)]) else: wf = np.array([ np.sum( data[:, centerline - vbinhalf:centerline + vbinhalf], 1) ]) self.waterfall_data[self.watindex, :] = wf self.watindex += 1 self.totalframes += 1 new_time = time.time() self.buffertime = new_time - self.lastBuffer self.lastBuffer = new_time self.buffer_memory = s if self._session.Debug['queue_memory']: print('Queue Memory: %3.2f MB' % self.buffer_memory) def updateGUI(self): """Updates the image displayed to the user. """ if self.experiment.temp_image is not None: img = self.experiment.temp_image self.camWidget.img.setImage(img.astype(int), autoLevels=False, autoRange=False, autoHistogramRange=False) if self.experiment.link_particles_running: self.camWidget.draw_target_pointer( self.experiment.localize_particles_image(img)) def saveWaterfall(self): """Saves the waterfall data, if any. """ if len(self.waterfall_data) > 1: fn = self._session.Saving['filename_waterfall'] filename = '%s.hdf5' % (fn) fileDir = self._session.Saving['directory'] if not os.path.exists(fileDir): os.makedirs(fileDir) f = h5py.File(os.path.join(fileDir, filename), "a") now = str(datetime.now()) g = f.create_group(now) dset = g.create_dataset('waterfall', data=self.waterfall_data) meta = g.create_dataset('metadata', data=self._session.serialize().encode( "ascii", "ignore")) f.flush() f.close() self.messageWidget.appendLog('i', 'Saved Waterfall') def saveTrajectory(self): """Saves the trajectory data, if any. """ if len(self.trackinfo) > 1: fn = self._session.Saving['filename_trajectory'] filename = '%s.hdf5' % (fn) fileDir = self._session.Saving['directory'] if not os.path.exists(fileDir): os.makedirs(fileDir) f = h5py.File(os.path.join(fileDir, filename), "a") now = str(datetime.now()) g = f.create_group(now) dset = g.create_dataset('trajectory', data=[self.trackinfo]) meta = g.create_dataset('metadata', data=self._session.serialize().encode( "ascii", "ignore")) f.flush() f.close() self.messageWidget.appendLog('i', 'Saved Trajectory') def update_settings(self, settings): new_session = _session(settings) self.updateSession(new_session) self.config.populateTree(self._session) def updateSession(self, session): """Updates the session variables passed by the config window. """ update_cam = False update_roi = False update_exposure = False update_binning = True for k in session.params['Camera']: new_prop = session.params['Camera'][k] old_prop = self._session.params['Camera'][k] if new_prop != old_prop: update_cam = True if k in ['roi_x1', 'roi_x2', 'roi_y1', 'roi_y2']: update_roi = True if self._session.Debug['to_screen']: print('Update ROI') elif k == 'exposure_time': update_exposure = True elif k in ['binning_x', 'binning_y']: update_binning = True if session.GUI['length_waterfall'] != self._session.GUI[ 'length_waterfall']: if self.show_waterfall: self.closeWaterfall() self.restart_waterfall = True self.messageWidget.appendLog('i', 'Parameters updated') self.messageWidget.appendLog( 'i', 'Measurement: %s' % session.User['measurement']) self._session = session.copy() if update_cam: if self.acquiring: self.stopMovie() if update_roi: X = np.sort( [session.Camera['roi_x1'], session.Camera['roi_x2']]) Y = np.sort( [session.Camera['roi_y1'], session.Camera['roi_y2']]) self.setROI(X, Y) if update_exposure: new_exp = self.camera.set_exposure( session.Camera['exposure_time']) self._session.Camera = {'exposure_time': new_exp} self.messageWidget.appendLog('i', 'Updated exposure: %s' % new_exp) if self._session.Debug['to_screen']: print("New Exposure: %s" % new_exp) print(self._session) if update_binning: self.camera.set_binning(session.Camera['binning_x'], session.Camera['binning_y']) self.refreshTimer.stop() self.refreshTimer.start(session.GUI['refresh_time']) def startSpecialTask(self): """Starts a special task. This is triggered by the user with a special combination of actions, for example clicking with the mouse on a plot, draggin a crosshair, etc.""" if not self.specialtask_running: if self.acquiring: self.stopMovie() self.acquiring = False locy = self.camWidget.crosshair[0].getPos()[1] locx = self.camWidget.crosshair[1].getPos()[0] self.trackinfo = np.zeros((1, 5)) self.trajectoryWidget.plot.clear() imgsize = self.tempimage.shape iniloc = [locx, locy] self.specialTaskWorker = specialTaskTracking( self._session, self.camera, self.noiselvl, imgsize, iniloc) self.connect(self.specialTaskWorker, QtCore.SIGNAL('image'), self.getData) self.connect(self.specialTaskWorker, QtCore.SIGNAL('coordinates'), self.getParticleLocation) self.specialTaskWorker.start() self.specialtask_running = True self.messageWidget.appendLog('i', 'Live tracking started') else: print('Special task already running') def stopSpecialTask(self): """Stops the special task""" if self.specialtask_running: self.specialTaskWorker.keep_running = False self.specialtask_running = False if self._session.Saving['autosave_trajectory'] == True: self.saveTrajectory() self.messageWidget.appendLog('i', 'Live tracking stopped') def done(self): #self.saveRunning = False self.acquiring = False def exitSafe(self): self.close() def closeEvent(self, evnt): """ Triggered at closing. Checks that the save is complete and closes the dataFile """ self.experiment.finalize() # self.messageWidget.appendLog('i', 'Closing the program') # if self.acquiring: # self.stopMovie() # if self.specialtask_running: # self.stopSpecialTask() # while self.specialTaskWorker.isRunning(): # pass # self.emit(QtCore.SIGNAL('closeAll')) # self.camera.stopCamera() # self.movieSaveStop() # try: # # Checks if the process P exists and tries to close it. # if self.p.is_alive(): # qs = self.q.qsize() # with ProgressDialog("Finish saving data...", 0, qs) as dlg: # while self.q.qsize() > 1: # dlg.setValue(qs - self.q.qsize()) # time.sleep(0.5) # self.p.join() # except AttributeError: # pass # if self.q.qsize() > 0: # self.messageWidget.appendLog('i', 'The queue was not empty') # print('Freeing up memory...') # self.emptyQueue() # # # Save LOG. # fn = self._session.Saving['filename_log'] # timestamp = datetime.now().strftime('%H%M%S') # filename = '%s%s.log' % (fn, timestamp) # fileDir = self._session.Saving['directory'] # if not os.path.exists(fileDir): # os.makedirs(fileDir) # # f = open(os.path.join(fileDir,filename), "a") # for line in self.messageWidget.logText: # f.write(line+'\n') # f.flush() # f.close() # print('Saved LOG') super(MainWindow, self).closeEvent(evnt)
def initDialogSymbol(self,results=None,KData=None,bDrawText=False,InKLine = False): # 1) creates layouts dialog = QtGui.QDialog() mainLayout = QtGui.QHBoxLayout() rightLayout = QtGui.QVBoxLayout() mainLayout.addLayout(rightLayout) dialog.setLayout(mainLayout) dialog.setWindowTitle(('Strategy Results')) import os,sys xpower = os.path.abspath(os.path.join(os.path.dirname(__file__),os.pardir,os.pardir,os.pardir,'midProjects','histdataUI')) sys.path.append(xpower) from Widgets.pgCandleWidgetCross import pgCandleWidgetCross from Widgets.pgCrossAddition import pgCrossAddition from pyqtgraph.dockarea import DockArea,Dock area = DockArea() rightLayout.addWidget(area) # 2) creates widgets # 2.1)candle pgCandleView = pgCandleWidgetCross(dataForCandle=KData) self.pricePlot(pgCandleView) if(InKLine): self.indicatorsPlot(pgCandleView) #self.signalPlot(pgCandleView,yBuy = KData.take([1],axis=1),ySell = KData.take([1],axis=1)) self.signalPlot(pgCandleView) dCandle = Dock("candles",closable=True, size=(200,300)) ## give this dock the minimum possible size area.addDock(dCandle, 'bottom') dCandle.addWidget(pgCandleView) # 2.2)long_pnl 当前position_pnl曲线 if(True): PyqtGraphPnl = pgCrossAddition() self.longPnlPlot(PyqtGraphPnl,bDrawText=bDrawText) long_pnl = np.array(self.results.long_pnl) self.signalPlot(PyqtGraphPnl,yBuy = long_pnl,ySell = long_pnl) dPnl = Dock("long_pnl", closable=True, size=(200,100)) area.addDock(dPnl, 'bottom') dPnl.addWidget(PyqtGraphPnl) PyqtGraphPnl.setXLink(pgCandleView) # 2.3)long_cost if(True): PyqtGraphPositionCost = pgCrossAddition() self.longCostPlot(PyqtGraphPositionCost) dPositionCost = Dock("long_cost",closable=True, size=(200,100)) area.addDock(dPositionCost, 'bottom') dPositionCost.addWidget(PyqtGraphPositionCost) PyqtGraphPositionCost.setXLink(pgCandleView) # 2.2)long_pnl 当前position_pnl曲线 if(True): PyqtGraphPnl = pgCrossAddition() self.shortPnlPlot(PyqtGraphPnl,bDrawText=bDrawText) short_pnl = np.array(self.results.short_pnl) self.signalPlot(PyqtGraphPnl,yBuy = short_pnl,ySell = short_pnl) dPnl = Dock("short_pnl", closable=True, size=(200,100)) area.addDock(dPnl, 'bottom') dPnl.addWidget(PyqtGraphPnl) PyqtGraphPnl.setXLink(pgCandleView) # 2.3)long_cost if(True): PyqtGraphPositionCost = pgCrossAddition() self.shortCostPlot(PyqtGraphPositionCost) dPositionCost = Dock("short_cost",closable=True, size=(200,100)) area.addDock(dPositionCost, 'bottom') dPositionCost.addWidget(PyqtGraphPositionCost) PyqtGraphPositionCost.setXLink(pgCandleView) # 2.3)position_volume if(False): PyqtGraphPosition = pgCrossAddition() self.positionVolumePlot(PyqtGraphPosition) dPosition = Dock("position_volume",closable=True, size=(200,100)) area.addDock(dPosition, 'bottom') dPosition.addWidget(PyqtGraphPosition) PyqtGraphPosition.setXLink(pgCandleView) # 2.4)portfolio 总资产变动曲线 cash + equity if(True): PyqtGraphPortfolio = pgCrossAddition() self.positionValuePlot(PyqtGraphPortfolio) dPortfolio = Dock("portfolio", closable=True,size=(200,100)) area.addDock(dPortfolio, 'bottom') dPortfolio.addWidget(PyqtGraphPortfolio) PyqtGraphPortfolio.setXLink(pgCandleView) # 2.5)indicator if(True): PyqtGraphindicators = pgCrossAddition() self.pricePlot(PyqtGraphindicators) self.indicatorsPlot(PyqtGraphindicators) self.signalPlot(PyqtGraphindicators) dIndicator = Dock("indicator",closable=True, size=(200,100)) dIndicator.addWidget(PyqtGraphindicators) area.addDock(dIndicator, 'bottom', dCandle) PyqtGraphindicators.setXLink(pgCandleView) # 2.2)position_pnl 当前position_pnl曲线 if(False): PyqtGraphPortfolioInstruments = pgCrossAddition() self.instrumentPnlPlot(PyqtGraphPortfolioInstruments,bDrawText=bDrawText) position_pnl = np.array(self.results.position_pnl) self.signalPlot(PyqtGraphPortfolioInstruments,yBuy = position_pnl,ySell = position_pnl) dPnl = Dock("instrumentsPNL", closable=True, size=(200,100)) area.addDock(dPnl, 'bottom',dPositionCost) dPnl.addWidget(PyqtGraphPortfolioInstruments) PyqtGraphPortfolioInstruments.setXLink(pgCandleView) return dialog
class ChronoTimer(QObject): def __init__(self, parent, duration=None): """ :param parent: :param Nteams: :param duration: (dict) containing optional keys : days, minutes, seconds, hours, weeks, milliseconds, microseconds """ super().__init__() self.area = parent if duration is None: self.type = 'chrono' self.duration = timedelta() else: self.type = 'timer' self.duration = timedelta(**duration) # seconds self.displayed_time = 0 # in seconds self.started = False self.timer = QTimer() self.timer.setInterval(100) self.timer.timeout.connect(self.display_time) self.setup_ui() def setup_ui(self): self.dock_chrono_timer = Dock(self.type.capitalize()) self.area.addDock(self.dock_chrono_timer) self.dock_chrono_timer.float() widget_chrono_timer = QtWidgets.QWidget() self.dock_chrono_timer.addWidget(widget_chrono_timer) self.layout_lcd = QtWidgets.QVBoxLayout() widget_chrono_timer.setLayout(self.layout_lcd) self.dock_chrono_timer.setAutoFillBackground(True) palette = self.dock_chrono_timer.palette() palette.setColor(palette.Background, QtGui.QColor(0, 0, 0)) self.dock_chrono_timer.setPalette(palette) self.time_lcd = QtWidgets.QLCDNumber(8) self.set_lcd_color(self.time_lcd, 'red') self.layout_lcd.addWidget(self.time_lcd) hours, minutes, seconds = self.get_times(self.duration) self.time_lcd.display('{:02d}:{:02d}:{:02d}'.format( hours, minutes, seconds)) self.dock_controls = Dock('Chrono/Timer Controls') self.area.addDock(self.dock_controls) self.dock_controls.setOrientation('vertical', True) self.dock_controls.setMaximumHeight(150) self.widget_controls = QtWidgets.QWidget() self.controls_layout = QtWidgets.QVBoxLayout() self.widget_controls.setLayout(self.controls_layout) hor_layout = QtWidgets.QHBoxLayout() hor_widget = QtWidgets.QWidget() hor_widget.setLayout(hor_layout) self.controls_layout.addWidget(hor_widget) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/run2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.start_pb = PushButtonShortcut(icon, 'Start', shortcut='Home', shortcut_widget=self.area) self.start_pb.clicked.connect(self.start) self.start_pb.setToolTip('home ("début") key shorcut') hor_layout.addWidget(self.start_pb) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/pause.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.pause_pb = PushButtonShortcut(icon, 'Pause', shortcut='Ctrl+p', shortcut_widget=self.area) self.pause_pb.setCheckable(True) self.pause_pb.setToolTip("Ctrl+p key shortcut") self.pause_pb.clicked.connect(self.pause) hor_layout.addWidget(self.pause_pb) icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(":/icons/Icon_Library/Refresh2.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.reset_pb = PushButtonShortcut(icon, 'Reset', shortcut='F5', shortcut_widget=self.area) self.reset_pb.setToolTip('F5 key shortcut') self.reset_pb.clicked.connect(self.reset) hor_layout.addWidget(self.reset_pb) self.dock_controls.addWidget(self.widget_controls) def get_times(self, duration): seconds = int(duration.total_seconds() % 60) total_minutes = duration.total_seconds() // 60 minutes = int(total_minutes % 60) hours = int(total_minutes // 60) return hours, minutes, seconds def get_elapsed_time(self): return time.perf_counter() - self.ini_time def display_time(self): elapsed_time = self.get_elapsed_time() if self.type == 'timer': display_timedelta = self.duration - timedelta(seconds=elapsed_time) else: display_timedelta = self.duration + timedelta(seconds=elapsed_time) self.displayed_time = display_timedelta.total_seconds() if display_timedelta.total_seconds() <= 0: self.reset() return else: hours, minutes, seconds = self.get_times(display_timedelta) self.time_lcd.display('{:02d}:{:02d}:{:02d}'.format( hours, minutes, seconds)) QtWidgets.QApplication.processEvents() def start(self): self.ini_time = time.perf_counter() self.timer.start() self.started = True self.start_pb.setEnabled(False) def pause(self): if self.pause_pb.isChecked(): self.started = False self.timer.stop() self.paused_time = time.perf_counter() else: elapsed_pause_time = time.perf_counter() - self.paused_time self.ini_time += elapsed_pause_time self.timer.start() self.started = True def reset(self): if self.pause_pb.isChecked(): self.pause_pb.setChecked(False) QtWidgets.QApplication.processEvents() self.timer.stop() self.start_pb.setEnabled(True) self.started = False hours, minutes, seconds = self.get_times(self.duration) self.time_lcd.display('{:02d}:{:02d}:{:02d}'.format( hours, minutes, seconds)) def set_lcd_color(self, lcd, color): palette = lcd.palette() # lcd.setPalette(QtGui.QPalette(Qt.red)) if hasattr(Qt, color): palette.setBrush(palette.WindowText, getattr(Qt, color)) palette.setColor(palette.Background, QtGui.QColor(0, 0, 0)) lcd.setPalette(palette)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowTitle('PyFLUX') self.cwidget = QtGui.QWidget() self.setCentralWidget(self.cwidget) # Actions in menubar menubar = self.menuBar() fileMenu = menubar.addMenu('Measurement') self.psfMeasAction = QtGui.QAction('PSF measurement', self) self.psfMeasAction.setStatusTip('Routine to measure one MINFLUX PSF') fileMenu.addAction(self.psfMeasAction) self.psfMeasAction.triggered.connect(self.psfMeasurement) self.minfluxMeasAction = QtGui.QAction('MINFLUX measurement', self) self.minfluxMeasAction.setStatusTip( 'Routine to perform a tcspc-MINFLUX measurement') fileMenu.addAction(self.minfluxMeasAction) # GUI layout grid = QtGui.QGridLayout() self.cwidget.setLayout(grid) # Dock Area dockArea = DockArea() grid.addWidget(dockArea, 0, 0) # Scan scanDock = Dock('Confocal scan', size=(1, 1)) DEVICENUMBER = 0x1 self.adw = drivers.ADwin.ADwin(DEVICENUMBER, 1) scan.setupDevice(self.adw) self.scanWidget = scan.scanWidget(self.adw) scanDock.addWidget(self.scanWidget) dockArea.addDock(scanDock, 'left') # tcspc measurement tcspcDock = Dock("Time-correlated single-photon counting") ph = drivers.picoharp.PicoHarp300() self.tcspcWidget = tcspc.tcspcWidget(ph) tcspcDock.addWidget(self.tcspcWidget) dockArea.addDock(tcspcDock, 'bottom', scanDock) # focus lock focusDock = Dock("Focus Lock") uc480Camera = uc480.UC480_Camera() self.focusWidget = focus.focusWidget(uc480Camera, self.adw) focusDock.addWidget(self.focusWidget) dockArea.addDock(focusDock, 'right') # xy drift xyDock = Dock("xy drift control") andorCamera = ccd.CCD() self.xyWidget = xy.xyWidget(andorCamera) xyDock.addWidget(self.xyWidget) xyDock.addWidget(self.xyWidget) dockArea.addDock(xyDock, 'top', focusDock) # threads self.scanThread = QtCore.QThread(self) self.scanThread.start() self.scanWidget.scworker.moveToThread(self.scanThread) self.focusThread = QtCore.QThread(self) self.focusThread.start() self.focusWidget.fworker.moveToThread(self.focusThread) self.xyThread = QtCore.QThread(self) self.xyThread.start() self.xyWidget.xyworker.moveToThread(self.xyThread) # self.tcspcThread = QtCore.QThread(self) # self.tcspcThread.start() # self.tcspcWidget.tcspcworker.moveToThread(self.tcspcThread) # sizes to fit my screen properly self.scanWidget.setMinimumSize(1000, 550) self.xyWidget.setMinimumSize(800, 300) self.move(1, 1)
class SegmentInfoDockArea(DockArea): segid2treenode = WeakValueDictionary() def __init__(self): DockArea.__init__(self) self.project_tree_dock = Dock(u"Project Tree", hideTitle=True) self.addDock(self.project_tree_dock, 'top') #'above', self.flowcharts_dock) self.project_tree = SegmentTreeWidget() self.project_tree_dock.addWidget(self.project_tree) self.properties_table = TableWidget(sortable=False, editable=False) self.properties_table.setFormat("%.3f", 1) self.properties_table.setColumnCount(1) self.properties_table.contextMenu.clear() self.properties_table.horizontalHeader().hide() self.properties_dock = Dock("Selected Object Properties", widget=self.properties_table, hideTitle=True) self.addDock(self.properties_dock, 'bottom') MarkWriteMainWindow.instance().sigProjectChanged.connect( self.handleProjectChange) MarkWriteMainWindow.instance().sigSegmentCreated.connect( self.handleSegmentCreated) MarkWriteMainWindow.instance().sigSegmentRemoved.connect( self.handleSegmentRemoved) MarkWriteMainWindow.instance().sigActiveObjectChanged.connect( self.handleActiveObjectChanged) self.project_tree.currentItemChanged.connect( self.currentTreeItemChangedEvent) self.project_tree.itemDoubleClicked.connect( self.treeItemDoubleClickedEvent) self.project_tree.customContextMenuRequested.connect( self.rightClickTreeEvent) # self.project_tree.itemSelectionChanged.connect(self.handleItemSelectionChanged) self.project_tree.setExpandsOnDoubleClick(False) self.doNotSetActiveObject = False def updatePropertiesTableData(self, objwithprops, cleartable=False): if cleartable: self.properties_table.clear() self.properties_table.horizontalHeader().setResizeMode( QtGui.QHeaderView.Stretch) self.properties_table.setData(objwithprops.propertiesTableData()) else: i = 0 for v in objwithprops.propertiesTableData().values(): self.properties_table.setRow(i, v) i += 1 # # Signal Handlers # def handleProjectChange(self, project): self.project_tree.clear() self.segid2treenode.clear() # Create Project Tree Node projecttreeitem = QtGui.QTreeWidgetItem([project.name]) projecttreeitem._pydat = proxy(project.segmenttree) self.segid2treenode[project.segmenttree.id] = projecttreeitem self.project_tree.addTopLevelItem(projecttreeitem) for seg in project.segmenttree.children: self.handleSegmentCreated(seg) def handleSegmentCreated(self, segment): #print '>>TREE.handleSegmentCreated:',segment self.doNotSetActiveObject = True segindex = segment.parent.getChildIndex(segment) parent_tree_node = self.segid2treenode[segment.parent.id] #parent_tree_node = self.project_tree.topLevelItem(0) segtreeitem = QtGui.QTreeWidgetItem([segment.name]) self.segid2treenode[segment.id] = segtreeitem segtreeitem._pydat = proxy(segment) parent_tree_node.insertChild(segindex, segtreeitem) #for i in self.project_tree.selectedItems(): # i.setSelected(False) #segtreeitem.setSelected(True) self.project_tree.setCurrentItem(segtreeitem) #print '<< TREE.handleSegmentCreated' self.doNotSetActiveObject = False for seg in segment.children: self.handleSegmentCreated(seg) def handleSegmentRemoved(self, segment, segment_index): self.doNotSetActiveObject = True parent_tree_node = self.segid2treenode[segment.parent.id] segmenttreeitem = parent_tree_node.child(segment_index) parent_tree_node.removeChild(segmenttreeitem) self.doNotSetActiveObject = False if MarkWriteMainWindow.instance(): MarkWriteMainWindow.instance().setActiveObject(segment.parent) def handleActiveObjectChanged(self, activeobj, prevactiveobj): #if activeobj != prevactiveobj: # print "Active Obj Changed:",activeobj, prevactiveobj if activeobj: self.updatePropertiesTableData(activeobj, activeobj != prevactiveobj) if activeobj != prevactiveobj: if not isinstance(activeobj, PenDataSegmentCategory): #print "Deselecting Tree Node.." # set root node as current, otherwise if user tries to press on # prev selected segment, tree change event will not fire. if self.segid2treenode.has_key(0): self.project_tree.setCurrentItem(self.segid2treenode[0]) self.project_tree.clearSelection() #self.project_tree.setCurrentItem(None) else: #print "Settting tree node",activeobj,self.segid2treenode[activeobj.id] self.project_tree.setCurrentItem( self.segid2treenode[activeobj.id]) def rightClickTreeEvent(self, *args, **kwargs): # Show Segment name editing dialog segment = MarkWriteMainWindow.instance().activeobject #print "rightClickTreeEvent:",segment if segment: if isinstance(segment, PenDataSegmentCategory): if segment.locked is False: tag, ok = showSegmentNameDialog( MarkWriteMainWindow.instance().predefinedtags, default=segment.name) if len(tag) > 0 and ok: segment.name = tag self.project_tree.selectedItems()[0].setText( 0, segment.name) def currentTreeItemChangedEvent(self, *args, **kwargs): current_tree_item, old_tree_widget = args #print ">> currentTreeItemChangedEvent:",current_tree_item, old_tree_widget # print " selected items:",self.project_tree.selectedItems() try: if current_tree_item is None: #passing in not obj sets activeObject to project.selectedtimeregion MarkWriteMainWindow.instance().setActiveObject() elif self.doNotSetActiveObject is False: self.project_tree.setCurrentItem(current_tree_item) selectedsegment = current_tree_item._pydat if selectedsegment.isRoot(): ao = MarkWriteMainWindow.instance().setActiveObject() else: ao = MarkWriteMainWindow.instance().setActiveObject( selectedsegment) #print "Set active object:",ao except Exception, e: #import traceback #traceback.print_exc() self.properties_table.clear()
class SegmentInfoDockArea(DockArea): segid2treenode = WeakValueDictionary() def __init__(self): DockArea.__init__(self) self.project_tree_dock = Dock(u"Project Tree", hideTitle=True) self.addDock(self.project_tree_dock, 'top') #'above', self.flowcharts_dock) self.project_tree = SegmentTreeWidget() self.project_tree_dock.addWidget(self.project_tree) self.properties_table = TableWidget(sortable=False, editable=False) self.properties_table.setFormat("%.3f",1) self.properties_table.setColumnCount(1) self.properties_table.contextMenu.clear() self.properties_table.horizontalHeader().hide() self.properties_dock = Dock("Selected Object Properties", widget=self.properties_table, hideTitle=True) self.addDock(self.properties_dock, 'bottom') MarkWriteMainWindow.instance().sigProjectChanged.connect( self.handleProjectChange) MarkWriteMainWindow.instance().sigSegmentCreated.connect( self.handleSegmentCreated) MarkWriteMainWindow.instance().sigSegmentRemoved.connect( self.handleSegmentRemoved) MarkWriteMainWindow.instance().sigActiveObjectChanged.connect( self.handleActiveObjectChanged) self.project_tree.currentItemChanged.connect( self.currentTreeItemChangedEvent) self.project_tree.itemDoubleClicked.connect( self.treeItemDoubleClickedEvent) self.project_tree.customContextMenuRequested.connect( self.rightClickTreeEvent) # self.project_tree.itemSelectionChanged.connect(self.handleItemSelectionChanged) self.project_tree.setExpandsOnDoubleClick(False) self.doNotSetActiveObject=False def updatePropertiesTableData(self, objwithprops, cleartable=False): if cleartable: self.properties_table.clear() self.properties_table.horizontalHeader().setResizeMode( QtGui.QHeaderView.Stretch) self.properties_table.setData(objwithprops.propertiesTableData()) else: i=0 for v in objwithprops.propertiesTableData().values(): self.properties_table.setRow(i,v) i+=1 # # Signal Handlers # def handleProjectChange(self, project): self.project_tree.clear() self.segid2treenode.clear() # Create Project Tree Node projecttreeitem = QtGui.QTreeWidgetItem([project.name]) projecttreeitem._pydat = proxy(project.segmenttree) self.segid2treenode[project.segmenttree.id] = projecttreeitem self.project_tree.addTopLevelItem(projecttreeitem) for seg in project.segmenttree.children: self.handleSegmentCreated(seg) def handleSegmentCreated(self, segment): #print '>>TREE.handleSegmentCreated:',segment self.doNotSetActiveObject = True segindex = segment.parent.getChildIndex(segment) parent_tree_node = self.segid2treenode[segment.parent.id] #parent_tree_node = self.project_tree.topLevelItem(0) segtreeitem = QtGui.QTreeWidgetItem([segment.name]) self.segid2treenode[segment.id] = segtreeitem segtreeitem._pydat = proxy(segment) parent_tree_node.insertChild(segindex, segtreeitem) #for i in self.project_tree.selectedItems(): # i.setSelected(False) #segtreeitem.setSelected(True) self.project_tree.setCurrentItem(segtreeitem) #print '<< TREE.handleSegmentCreated' self.doNotSetActiveObject = False for seg in segment.children: self.handleSegmentCreated(seg) def handleSegmentRemoved(self, segment, segment_index): self.doNotSetActiveObject = True parent_tree_node = self.segid2treenode[segment.parent.id] segmenttreeitem = parent_tree_node.child(segment_index) parent_tree_node.removeChild(segmenttreeitem) self.doNotSetActiveObject = False if MarkWriteMainWindow.instance(): MarkWriteMainWindow.instance().setActiveObject(segment.parent) def handleActiveObjectChanged(self,activeobj, prevactiveobj): #if activeobj != prevactiveobj: # print "Active Obj Changed:",activeobj, prevactiveobj if activeobj: self.updatePropertiesTableData(activeobj, activeobj!=prevactiveobj) if activeobj != prevactiveobj: if not isinstance(activeobj,PenDataSegmentCategory): #print "Deselecting Tree Node.." # set root node as current, otherwise if user tries to press on # prev selected segment, tree change event will not fire. if self.segid2treenode.has_key(0): self.project_tree.setCurrentItem(self.segid2treenode[0]) self.project_tree.clearSelection() #self.project_tree.setCurrentItem(None) else: #print "Settting tree node",activeobj,self.segid2treenode[activeobj.id] self.project_tree.setCurrentItem(self.segid2treenode[activeobj.id]) def rightClickTreeEvent(self, *args, **kwargs): # Show Segment name editing dialog segment = MarkWriteMainWindow.instance().activeobject #print "rightClickTreeEvent:",segment if segment: if isinstance(segment, PenDataSegmentCategory): if segment.locked is False: tag, ok = showSegmentNameDialog( MarkWriteMainWindow.instance().predefinedtags, default=segment.name) if len(tag) > 0 and ok: segment.name = tag self.project_tree.selectedItems()[0].setText(0, segment.name) def currentTreeItemChangedEvent(self, *args, **kwargs): current_tree_item, old_tree_widget = args #print ">> currentTreeItemChangedEvent:",current_tree_item, old_tree_widget # print " selected items:",self.project_tree.selectedItems() try: if current_tree_item is None: #passing in not obj sets activeObject to project.selectedtimeregion MarkWriteMainWindow.instance().setActiveObject() elif self.doNotSetActiveObject is False: self.project_tree.setCurrentItem(current_tree_item) selectedsegment = current_tree_item._pydat if selectedsegment.isRoot(): ao=MarkWriteMainWindow.instance().setActiveObject() else: ao=MarkWriteMainWindow.instance().setActiveObject(selectedsegment) #print "Set active object:",ao except Exception, e: #import traceback #traceback.print_exc() self.properties_table.clear()
def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) # Occupancy Docks self.occupancy_images = [] self.event_status_plots = [] # Plots with axis stored in here self.plots = [] self.event_status_widgets = [] poss = np.array([0.0, 0.01, 0.5, 1.0]) color = np.array([[1.0, 1.0, 1.0, 1.0], [0.267004, 0.004874, 0.329415, 1.0], [0.127568, 0.566949, 0.550556, 1.0], [0.993248, 0.906157, 0.143936, 1.0]]) # Zero is white mapp = pg.ColorMap(poss, color) lutt = mapp.getLookupTable(0.0, 1.0, 100) self.occ_hist_sum = np.zeros(shape=(6, )) for plane in range(3): # Loop over 3 * 2 plot widgets # Dock left dock_occcupancy = Dock("Occupancy plane %d" % (2 * plane + 1), size=(100, 150)) dock_event_status = Dock("Event status plane %d" % (2 * plane + 1), size=(100, 50)) if plane > 0: dock_area.addDock(dock_occcupancy, 'bottom') else: dock_area.addDock(dock_occcupancy, 'left') dock_area.addDock(dock_event_status, 'right', dock_occcupancy) occupancy_graphics = pg.GraphicsLayoutWidget() # Plot docks occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_images.append(pg.ImageItem(border='w')) view.addItem(self.occupancy_images[2 * plane]) self.occupancy_images[2 * plane].setLookupTable(lutt, update=True) self.plots.append( pg.PlotWidget(viewBox=view, labels={ 'bottom': 'Column', 'left': 'Row' }, title='Occupancy Map, Sum: %i' % self.occ_hist_sum[2 * plane])) self.plots[2 * plane].addItem(self.occupancy_images[2 * plane]) dock_occcupancy.addWidget(self.plots[2 * plane]) # event_status_widget = pg.PlotWidget() # self.event_status_plots.append(event_status_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True)) # event_status_widget.showGrid(y=True) # dock_event_status.addWidget(event_status_widget) self.event_status_widgets.append(pg.PlotWidget()) self.event_status_plots.append( self.event_status_widgets[2 * plane].plot(np.linspace( -0.5, 15.5, 17), np.zeros((16)), stepMode=True)) self.event_status_widgets[2 * plane].showGrid(y=True) dock_event_status.addWidget(self.event_status_widgets[2 * plane]) # Dock right dock_occcupancy_2 = Dock("Occupancy plane %d" % (2 * plane + 2), size=(100, 150)) dock_event_status_2 = Dock("Event status plane %d" % (2 * plane + 2), size=(100, 50)) dock_area.addDock(dock_occcupancy_2, 'right', dock_event_status) dock_area.addDock(dock_event_status_2, 'right', dock_occcupancy_2) occupancy_graphics = pg.GraphicsLayoutWidget() # Plot docks occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_images.append(pg.ImageItem(border='w')) view.addItem(self.occupancy_images[2 * plane + 1]) self.occupancy_images[2 * plane + 1].setLookupTable(lutt, update=True) self.plots.append( pg.PlotWidget(viewBox=view, labels={ 'bottom': 'Column', 'left': 'Row' }, title='Occupancy Map, Sum: %i' % self.occ_hist_sum[2 * plane + 1])) self.plots[2 * plane + 1].addItem(self.occupancy_images[2 * plane + 1]) dock_occcupancy_2.addWidget(self.plots[2 * plane + 1]) self.event_status_widgets.append(pg.PlotWidget()) self.event_status_plots.append( self.event_status_widgets[2 * plane + 1].plot(np.linspace( -0.5, 15.5, 17), np.zeros((16)), stepMode=True)) self.event_status_widgets[2 * plane + 1].showGrid(y=True) # self.event_status_widgets[2 * plane + 1].setLogMode(y=True) dock_event_status_2.addWidget(self.event_status_widgets[2 * plane + 1]) dock_status = Dock("Status", size=(800, 40)) dock_area.addDock(dock_status, 'top') # Status dock on top cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Scan Parameters\n") self.spin_box = Qt.QSpinBox(value=0) self.spin_box.setMaximum(1000000) self.spin_box.setSuffix(" Readouts") self.reset_button = QtGui.QPushButton('Reset') self.noisy_checkbox = QtGui.QCheckBox('Mask noisy pixels') self.convert_checkbox = QtGui.QCheckBox('Axes in ' + u'\u03BC' + 'm') layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.event_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) layout.addWidget(self.noisy_checkbox, 0, 7, 0, 1) layout.addWidget(self.convert_checkbox, 0, 8, 0, 1) layout.addWidget(self.reset_button, 0, 9, 0, 1) dock_status.addWidget(cw) # Connect widgets self.reset_button.clicked.connect(lambda: self.send_command('RESET')) self.spin_box.valueChanged.connect( lambda value: self.send_command(str(value))) self.noisy_checkbox.stateChanged.connect( lambda value: self.send_command('MASK %d' % value)) # Change axis scaling def scale_axes(scale_state): for plot in self.plots: if scale_state == 0: plot.getAxis('bottom').setScale(1.0) plot.getAxis('left').setScale(1.0) plot.getAxis('bottom').setLabel('Columns') plot.getAxis('left').setLabel('Rows') elif scale_state == 2: plot.getAxis('bottom').setScale(18.4) plot.getAxis('left').setScale(18.4) plot.getAxis('bottom').setLabel('Columns / ' + u'\u03BC' + 'm') plot.getAxis('left').setLabel('Rows / ' + u'\u03BC' + 'm') self.convert_checkbox.stateChanged.connect( lambda value: scale_axes(value)) self.plot_delay = 0
def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) # Docks dock_occcupancy = Dock("Occupancy", size=(400, 400)) dock_run_config = Dock("Run configuration", size=(400, 400)) dock_global_config = Dock("Global configuration", size=(400, 400)) dock_tot = Dock("Time over threshold values (TOT)", size=(400, 400)) dock_tdc = Dock("Time digital converter values (TDC)", size=(400, 400)) dock_event_status = Dock("Event status", size=(400, 400)) dock_trigger_status = Dock("Trigger status", size=(400, 400)) dock_service_records = Dock("Service records", size=(400, 400)) dock_hit_timing = Dock("Hit timing (rel. BCID)", size=(400, 400)) dock_status = Dock("Status", size=(800, 40)) dock_area.addDock(dock_global_config, 'left') dock_area.addDock(dock_run_config, 'above', dock_global_config) dock_area.addDock(dock_occcupancy, 'above', dock_run_config) dock_area.addDock(dock_tdc, 'right', dock_occcupancy) dock_area.addDock(dock_tot, 'above', dock_tdc) dock_area.addDock(dock_service_records, 'bottom', dock_occcupancy) dock_area.addDock(dock_trigger_status, 'above', dock_service_records) dock_area.addDock(dock_event_status, 'above', dock_trigger_status) dock_area.addDock(dock_hit_timing, 'bottom', dock_tot) dock_area.addDock(dock_status, 'top') # Status dock on top cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.event_rate_label = QtGui.QLabel("Event Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Scan Parameters\n") self.spin_box = Qt.QSpinBox(value=0) self.spin_box.setMaximum(1000000) self.spin_box.setSuffix(" Readouts") self.reset_button = QtGui.QPushButton('Reset') layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.event_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) layout.addWidget(self.reset_button, 0, 7, 0, 1) dock_status.addWidget(cw) # Connect widgets self.reset_button.clicked.connect(lambda: self.send_command('RESET')) self.spin_box.valueChanged.connect(lambda value: self.send_command(str(value))) # Run config dock self.run_conf_list_widget = Qt.QListWidget() dock_run_config.addWidget(self.run_conf_list_widget) # Global config dock self.global_conf_list_widget = Qt.QListWidget() dock_global_config.addWidget(self.global_conf_list_widget) # Different plot docks occupancy_graphics = pg.GraphicsLayoutWidget() occupancy_graphics.show() view = occupancy_graphics.addViewBox() self.occupancy_img = pg.ImageItem(border='w') view.addItem(self.occupancy_img) view.setRange(QtCore.QRectF(0, 0, 80, 336)) dock_occcupancy.addWidget(occupancy_graphics) tot_plot_widget = pg.PlotWidget(background="w") self.tot_plot = tot_plot_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) tot_plot_widget.showGrid(y=True) dock_tot.addWidget(tot_plot_widget) tdc_plot_widget = pg.PlotWidget(background="w") self.tdc_plot = tdc_plot_widget.plot(np.linspace(-0.5, 4095.5, 4097), np.zeros((4096)), stepMode=True) tdc_plot_widget.showGrid(y=True) tdc_plot_widget.setXRange(0, 800, update=True) dock_tdc.addWidget(tdc_plot_widget) event_status_widget = pg.PlotWidget() self.event_status_plot = event_status_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) event_status_widget.showGrid(y=True) dock_event_status.addWidget(event_status_widget) trigger_status_widget = pg.PlotWidget() self.trigger_status_plot = trigger_status_widget.plot(np.linspace(-0.5, 7.5, 9), np.zeros((8)), stepMode=True) trigger_status_widget.showGrid(y=True) dock_trigger_status.addWidget(trigger_status_widget) service_record_widget = pg.PlotWidget() self.service_record_plot = service_record_widget.plot(np.linspace(-0.5, 31.5, 33), np.zeros((32)), stepMode=True) service_record_widget.showGrid(y=True) dock_service_records.addWidget(service_record_widget) hit_timing_widget = pg.PlotWidget() self.hit_timing_plot = hit_timing_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) hit_timing_widget.showGrid(y=True) dock_hit_timing.addWidget(hit_timing_widget) self.plot_delay = 0
def setup_widgets(self, parent, name): dock_area = DockArea() parent.addTab(dock_area, name) # Docks dock_occcupancy = Dock("Occupancy", size=(400, 400)) dock_tot = Dock("Time over threshold values (TOT)", size=(400, 400)) dock_tdc = Dock("TDC", size=(400, 400)) dock_status = Dock("Status", size=(800, 40)) dock_area.addDock(dock_occcupancy, 'top') dock_area.addDock(dock_tot, 'bottom', dock_occcupancy) dock_area.addDock(dock_tdc, 'right', dock_tot) dock_area.addDock(dock_status, 'top') # Status dock on top cw = QtGui.QWidget() cw.setStyleSheet("QWidget {background-color:white}") layout = QtGui.QGridLayout() cw.setLayout(layout) self.rate_label = QtGui.QLabel("Readout Rate\n0 Hz") self.hit_rate_label = QtGui.QLabel("Hit Rate\n0 Hz") self.trigger_rate_label = QtGui.QLabel("Trigger Rate\n0 Hz") self.timestamp_label = QtGui.QLabel("Data Timestamp\n") self.plot_delay_label = QtGui.QLabel("Plot Delay\n") self.scan_parameter_label = QtGui.QLabel("Parameter ID\n") self.spin_box = Qt.QSpinBox(value=0) self.spin_box.setMaximum(1000000) self.spin_box.setSuffix(" Readouts") self.reset_button = QtGui.QPushButton('Reset') self.noisy_checkbox = QtGui.QCheckBox('Mask noisy pixels') layout.addWidget(self.timestamp_label, 0, 0, 0, 1) layout.addWidget(self.plot_delay_label, 0, 1, 0, 1) layout.addWidget(self.rate_label, 0, 2, 0, 1) layout.addWidget(self.hit_rate_label, 0, 3, 0, 1) layout.addWidget(self.trigger_rate_label, 0, 4, 0, 1) layout.addWidget(self.scan_parameter_label, 0, 5, 0, 1) layout.addWidget(self.spin_box, 0, 6, 0, 1) layout.addWidget(self.noisy_checkbox, 0, 7, 0, 1) layout.addWidget(self.reset_button, 0, 8, 0, 1) dock_status.addWidget(cw) # Connect widgets self.reset_button.clicked.connect(lambda: self.send_command('RESET')) self.spin_box.valueChanged.connect(lambda value: self.send_command(str(value))) self.noisy_checkbox.stateChanged.connect(lambda value: self.send_command('MASK %d' % value)) # Different plot docks occupancy_graphics = pg.GraphicsLayoutWidget() occupancy_graphics.show() view = occupancy_graphics.addViewBox() view.invertY(True) self.occupancy_img = pg.ImageItem(border='w') # Set colormap from matplotlib lut = generateColorMapLut("viridis") self.occupancy_img.setLookupTable(lut, update=True) # view.addItem(self.occupancy_img) plot = pg.PlotWidget(viewBox=view, labels={'bottom': 'Column', 'left': 'Row'}) plot.addItem(self.occupancy_img) dock_occcupancy.addWidget(plot) tot_plot_widget = pg.PlotWidget(background="w") self.tot_plot = tot_plot_widget.plot(np.linspace(-0.5, 15.5, 17), np.zeros((16)), stepMode=True) tot_plot_widget.showGrid(y=True) dock_tot.addWidget(tot_plot_widget) tdc_widget = pg.PlotWidget() self.tdc_plot = tdc_widget.plot(np.linspace(-0.5, 500 - 0.5, 500 + 1), np.zeros((500)), stepMode=True) tdc_widget.showGrid(y=True) dock_tdc.addWidget(tdc_widget) self.plot_delay = 0
prog = DAQ_Viewer(area, title="Testing2D", DAQ_type='DAQ2D') prog2 = DAQ_Viewer(area, title="Testing1D", DAQ_type='DAQ1D') prog3 = DAQ_Viewer(area, title="Testing0D", DAQ_type='DAQ0D') act1_widget = QtWidgets.QWidget() act2_widget = QtWidgets.QWidget() act1 = DAQ_Move(act1_widget, title='X_axis') act2 = DAQ_Move(act2_widget, title='Y_axis') QThread.msleep(1000) prog.ui.IniDet_pb.click() prog2.ui.IniDet_pb.click() prog3.ui.IniDet_pb.click() dock1 = Dock('actuator 1') dock1.addWidget(act1_widget) area.addDock(dock1) dock2 = Dock('actuator 2') dock2.addWidget(act2_widget) area.addDock(dock2) act1.ui.IniStage_pb.click() act2.ui.IniStage_pb.click() QtWidgets.QApplication.processEvents() win.show() manager = ModulesManager(actuators=[act1, act2], detectors=[prog, prog2, prog3], selected_detectors=[prog2])
# "raw" voltages raw_plotwidget = pg.GraphicsLayoutWidget() raw_curves = list() raw_plot = raw_plotwidget.addPlot() raw_plot.setClipToView(True) raw_plot.setRange(yRange=[0, 3.3]) data = np.random.normal(size=20) for j in range(4): raw_curves.append( raw_plot.plot( data, pen=pg.mkPen(color=pg.intColor(j, hues=5, alpha=255, width=3)))) d0.addWidget(raw_plotwidget) # "forces" force_plotwidget = pg.GraphicsLayoutWidget() force_curves = list() force_plot = force_plotwidget.addPlot() force_plot.setClipToView(True) force_plot.setRange(yRange=[-1.5, 1.5]) for j in range(3): force_curves.append( force_plot.plot( data, pen=pg.mkPen(color=pg.intColor(j, hues=5, alpha=255, width=3)))) d1.addWidget(force_plotwidget)