class MyGroupParameter(parameterTypes.GroupParameter): def __init__(self, **opts): super().__init__(**opts) self.widget = None # Lets set in three cases: # 1) Value is not an instance of Parameter, # 2) Value is a child parameter and key is free # 3) The key is '_parent'. # AFAIK it is the only Parameter-type # attribute set by pyqtgraph.parametertree def __setattr__(self, key, value): if isinstance(value, Parameter) and key != "_parent": if key in self.__dict__: if ~isinstance(self.__dict__[key], Parameter): msg = ( "Can" "t set {} to {} because it is already set" " to something other than a Parameter".format( key, value ) ) raise ValueError(msg) else: msg = ( "Attribute {} is already set to {}." " Before overwriting, use removeChild.".format( key, value ) ) raise ValueError(msg) else: if value not in self.childs: msg = ( "Only children Parameter instances can be" " set as attributes. Call addChild* first." ) raise ValueError(msg) super().__setattr__(key, value) def removeChild(self, child): # If an attribute was set to refer to the child, remove it as well for key, value in self.__dict__.items(): if value is child: delattr(self, key) break super().removeChild(child) def create_widget(self): self.widget = ParameterTree(showHeader=False) self.widget.setParameters(self, showTop=True) size_policy_preferred = QtGui.QSizePolicy.Preferred self.widget.setSizePolicy(size_policy_preferred, size_policy_preferred) return self.widget
def _create_node_controls_widget(self, node): controls_cls = node_to_controls_map[node.__class__.__name__] controls = controls_cls(node) params = parameterTypes.GroupParameter(name=repr(node)) params.addChild(controls) widget = ParameterTree(showHeader=False) widget.setParameters(params) widget.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) widget.setSizeAdjustPolicy(1) return widget
class ScanAreaWidget(QtWidgets.QWidget): """ Widget where plots will be represented. TODO: add signals and slots. """ def __init__(self): super(ScanAreaWidget, self).__init__() self.scan_settings = {} self.parameters = None self.setupUI() def setupUI(self): self.setObjectName('Scan Widget Area') self.setMinimumSize(640, 480) self.master_layout = QtWidgets.QGridLayout(self) self.scan_area = pg.PlotWidget() self.parameter_tree = ParameterTree() sizePolicy = QtWidgets.QSizePolicy( QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.MinimumExpanding) self.parameter_tree.setSizePolicy(sizePolicy) self.master_layout.addWidget(self.scan_area, 0, 0) # self.setSizePolicy(sizePolicy) self.master_layout.addWidget(self.parameter_tree, 0, 1) self.start_scan_button = QtWidgets.QPushButton('Start Scan') self.start_scan_button.setEnabled(False) self.master_layout.addWidget(self.start_scan_button) self.setLayout(self.master_layout) @QtCore.pyqtSlot(dict) def acceptScanSettings(self, settings): self.scan_settings = settings self.start_scan_button.setEnabled(True) print(settings)
class Ui_WindowModel(QWidget): """ """ def __init__(self,): super().__init__() self.setupUi() def setupUi(self, ): """ """ self.gridLayout_2 = QtWidgets.QGridLayout(self) self.gridLayout_2.setObjectName("gridLayout_2") self.gridGeneral = QtWidgets.QGridLayout() self.gridGeneral.setObjectName("gridGeneral") self.toolBox = QtWidgets.QToolBox(self) self.toolBox.setFrameShadow(QtWidgets.QFrame.Plain) self.toolBox.setObjectName("toolBox") self.model = QtWidgets.QWidget() self.model.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.model.setObjectName("model") self.gridLayout_4 = QtWidgets.QGridLayout(self.model) self.gridLayout_4.setContentsMargins(0, 0, 0, 0) self.gridLayout_4.setObjectName("gridLayout_4") self.gridModel = QtWidgets.QGridLayout() self.gridModel.setContentsMargins(5, 5, 5, 5) self.gridModel.setSpacing(5) self.gridModel.setObjectName("gridModel") self.line = QtWidgets.QFrame(self.model) self.line.setFrameShape(QtWidgets.QFrame.VLine) self.line.setFrameShadow(QtWidgets.QFrame.Sunken) self.line.setObjectName("line") self.gridModel.addWidget(self.line, 0, 1, 1, 1) self.openGLWidget = QtWidgets.QOpenGLWidget(self.model) self.openGLWidget.setObjectName("openGLWidget") self.gridModel.addWidget(self.openGLWidget, 0, 2, 1, 1) self.ModelDescriptionTree = ParameterTree(self.model) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.ModelDescriptionTree.sizePolicy().hasHeightForWidth()) self.ModelDescriptionTree.setSizePolicy(sizePolicy) self.ModelDescriptionTree.setObjectName("ModelDescriptionTree") self.gridModel.addWidget(self.ModelDescriptionTree, 0, 0, 1, 1) self.gridLayout_4.addLayout(self.gridModel, 0, 1, 1, 1) self.toolBox.addItem(self.model, "") self.param = QtWidgets.QWidget() self.param.setGeometry(QtCore.QRect(0, 0, 558, 451)) self.param.setObjectName("param") self.gridLayout_6 = QtWidgets.QGridLayout(self.param) self.gridLayout_6.setContentsMargins(0, 0, 0, 0) self.gridLayout_6.setObjectName("gridLayout_6") self.gridParam = QtWidgets.QGridLayout() self.gridParam.setContentsMargins(5, 5, 5, 5) self.gridParam.setSpacing(5) self.gridParam.setObjectName("gridParam") self.ParametersTree = ParameterTree(self.param) self.ParametersTree.setObjectName("ParametersTree") self.gridParam.addWidget(self.ParametersTree, 0, 0, 1, 1) self.gridLayout_6.addLayout(self.gridParam, 0, 0, 1, 1) self.toolBox.addItem(self.param, "") self.result = QtWidgets.QWidget() self.result.setObjectName("result") self.gridLayout_8 = QtWidgets.QGridLayout(self.result) self.gridLayout_8.setContentsMargins(0, 0, 0, 0) self.gridLayout_8.setObjectName("gridLayout_8") self.gridRes = QtWidgets.QGridLayout() self.gridRes.setContentsMargins(5, 5, 5, 5) self.gridRes.setSpacing(5) self.gridRes.setObjectName("gridRes") self.ResTree = ParameterTree(self.result) self.ResTree.setObjectName("ResTree") self.gridRes.addWidget(self.ResTree, 0, 0, 1, 1) self.gridLayout_8.addLayout(self.gridRes, 0, 0, 1, 1) self.toolBox.addItem(self.result, "") self.gridGeneral.addWidget(self.toolBox, 0, 0, 1, 1) self.gridLayout_2.addLayout(self.gridGeneral, 0, 0, 1, 1) self.retranslateUi(self) self.toolBox.setCurrentIndex(2) def retranslateUi(self, WindowModel): _translate = QtCore.QCoreApplication.translate self.toolBox.setItemText(self.toolBox.indexOf(self.model), _translate("WindowModel", "General information about the subjective model")) self.toolBox.setItemText(self.toolBox.indexOf(self.param), _translate("WindowModel", "Detailed description of the parameters")) self.toolBox.setItemText(self.toolBox.indexOf(self.result), _translate("WindowModel", "Detailed description of the resultes "))
class GuiManager(QtGui.QMainWindow): def __init__(self): super(GuiManager, self).__init__() self.createLayout() def closeEvent(self, event): print 'User asked to close the app' self.stopAcquisition() Parameters.isAppKilled = True #time.sleep(0.1) #Wait for the worker death event.accept() # let the window close def startAcquisition(self): if Parameters.isConnected == False: return Parameters.isSaving = Parameters.paramObject.child("Saving parameters", "saveResults").value() if Parameters.isSaving == True: theDate = datetime.datetime.today() .strftime('%Y%m%d') theTime = datetime.datetime.today() .strftime('%H%M%S') theName=Parameters.paramObject.child("Saving parameters", "Experiment name").value() #Check counter increment folderParent = 'C:/InterferometryResults/' + theDate counter = 1 folderFound = False theFolder = folderParent + '/' + theName + '_' + str(counter).zfill(3) if not os.path.exists(folderParent): #Make sure parent exist os.makedirs(folderParent) while folderFound == False and counter < 1000: #Loop until folder is found if not os.path.exists(theFolder): #Make sure parent exist os.makedirs(theFolder) folderFound = True else: counter = counter + 1 theFolder = folderParent + '/' + theName + '_' + str(counter).zfill(3) if counter < 1000: Parameters.savingFolder = theFolder if not os.path.exists(theFolder): os.makedirs(theFolder) else: Parameters.isSaving = False; #Should not happen. self.btStart.setEnabled(False) self.btStop.setEnabled(True) self.btOpen.setEnabled(False) #Get the parameter values Parameters.nSamples=Parameters.paramObject.child("Acquisition Parameters", "Number of samples to acquire").value() acqMode=Parameters.paramObject.child("Trigger Options", "Acquisition mode").value() triggerAmplitude=Parameters.paramObject.child("Trigger Options", "Trigger amplitude").value() motorSpeed=Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").value()+28 #28 is calibration nBlocks=int(math.ceil(float(Parameters.nSamples)/512)) #Must be a multiple of 512 Parameters.nSamples = nBlocks*512 Parameters.paramObject.child("Acquisition Parameters", "Number of samples to acquire").setValue(Parameters.nSamples) #Set frequency in free mode. These settings could be optimized depending on the computer. freq=2500000 #10im/s if Parameters.nSamples > 100352: freq=5000000 #5im/s if Parameters.nSamples > 300032: freq=12500000 #2im/s if Parameters.nSamples > 1000000: freq=25000000 #1im/s if Parameters.nSamples > 2000000: freq=50000000 #0.5im/s #Start the acquisition on the FPGA data = [] data = array('i') data.append(1) data.append(freq) data.append(2) data.append(acqMode) data.append(3) data.append(nBlocks) data.append(4) data.append(motorSpeed) data.append(5) data.append(triggerAmplitude) data.append(6) data.append(0) theBytes = struct.pack('i' * len(data), *data) buf = bytearray(theBytes) Parameters.dev.WriteToPipeIn(128, buf) Parameters.dev.SetWireInValue(0, 1+2+8, 1+2+8);Parameters.dev.UpdateWireIns() #Enable DDR2 reading and writing and activate memory. time.sleep(0.1); #Wait to make sure everything is ready. TODO: Reduce this. Parameters.dev.SetWireInValue(0, 4, 4);Parameters.dev.UpdateWireIns() #Start acquisition clock. #self.plotTr.enableAutoRange('xy', True) ## stop auto-scaling after the first data set is plotted Parameters.theQueue = Queue.Queue() #Create the queue #self.DisplayUpdater(0) self.workThread.start(); #Start the display worker def stopAcquisition(self): print 'Stopping...' if hasattr(self,'tDisplay'): self.tDisplay.cancel() self.workThread.exitWorker(); while self.workThread.isRunning == True: time.sleep(0.01) #Wait for the worker death, before resetting the board Parameters.dev.SetWireInValue(0, 0, 1+2+4+8);Parameters.dev.UpdateWireIns() #Reset board. #Save format: Results / YYMMDD / ExperimentName_Counter. Could also use the time. if Parameters.isSaving == True: #global state state = Parameters.paramObject.saveState() file = open(Parameters.savingFolder + '\Parameters.txt', 'w') pickle.dump(state, file) file.close() print 'Stopped.' self.btStart.setEnabled(True) self.btStop.setEnabled(False) self.btOpen.setEnabled(True) ''' def DisplayUpdater(self,dummy): if Parameters.isAppKilled == True: return; if Parameters.theQueue.empty(): print 'no data...' while not Parameters.theQueue.empty(): #Empty the display queue data = Parameters.theQueue.get() #print 'data available!' if 'data' in locals(): #print 'display data' + str(data[2]) self.setDataCurveTr(data) tDisplay = Timer(2, self.DisplayUpdater, [0],{}) tDisplay.start() ''' def motorSpeedChanged(self,value): newSpeed=Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").value() newSpeed=newSpeed+28 #Calibration #Debug #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(enabled=False) #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(visible=False) #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(value=200) data = [] data = array('i') data.append(4) data.append(newSpeed) data.append(0) #Minimum size is 8 'int' data.append(0) data.append(0) data.append(0) data.append(0) data.append(0) theBytes = struct.pack('i' * len(data), *data) Parameters.bufferToDev = bytearray(theBytes) Parameters.bufferToDevReady = True def triggerChanged(self,value): acqMode=Parameters.paramObject.child("Trigger Options", "Acquisition mode").value() triggerAmplitude=Parameters.paramObject.child("Trigger Options", "Trigger amplitude").value() data = [] data = array('i') data.append(2) data.append(acqMode) data.append(5) data.append(triggerAmplitude) data.append(0) data.append(0) data.append(0) data.append(0) theBytes = struct.pack('i' * len(data), *data) print str(theBytes) Parameters.bufferToDev = bytearray(theBytes) Parameters.bufferToDevReady = True def triggerHalfSwitch(self): Parameters.triggerToDev = True def saveParam(self): #global state state = Parameters.paramObject.saveState() file = open('dump.txt', 'w') pickle.dump(state, file) file.close() def restoreParam(self): #lobal state file = open('dump.txt', 'r') state = pickle.load(file) #add = Parameters.paramObject['Save/Restore functionality', 'Restore State', 'Add missing items'] #rem = Parameters.paramObject['Save/Restore functionality', 'Restore State', 'Remove extra items'] Parameters.paramObject.restoreState(state, addChildren=False, removeChildren=False) #Set the status text (system connected or not) def setStatus(self, isConnected, isError = False): def dotChange(item, nDots): #Timer function to display a varying number of dots after "retrying" if Parameters.isConnected == True: return; if Parameters.isAppKilled == True: return; textNotConnected = "System not connected, retrying" item.setText(textNotConnected+".") #Number of dots varies from 1 to 5 if nDots == 1: textDots = "." nDots = 2 elif nDots == 2: textDots = ".." nDots = 3 elif nDots == 3: textDots = "..." nDots = 4 elif nDots == 4: textDots = "...." nDots = 5 else: textDots = "....." nDots = 1 item.setForeground(QtGui.QColor("red")) item.setText(textNotConnected+textDots) self.timerDotChange = Timer(0.25, dotChange, [self.itemStatus, nDots]) self.timerDotChange.start() if (isError == True): #System not connected print "Error" if hasattr(self,'timerDotChange'): self.timerDotChange.cancel() time.sleep(0.5) self.itemStatus.setForeground(QtGui.QColor("red")) self.itemStatus.setText("Error with system. Please restart the application and the system.") elif (isConnected == False): #System not connected nDots = 1 if hasattr(self,'timerDotChange'): self.timerDotChange.cancel() self.timerDotChange = Timer(0.25, dotChange, [self.itemStatus, nDots]) self.timerDotChange.start() else: print "Connected" if hasattr(self,'timerDotChange'): self.timerDotChange.cancel() time.sleep(0.1) self.itemStatus.setForeground(QtGui.QColor("green")) self.itemStatus.setText("System connected.") print "Connected2" #Set the status text (system connected or not) def setCameraStatus(self, isConnected): def dotChange(item, nDots): #Timer function to display a varying number of dots after "retrying" if Parameters.isCameraConnected == True: return; if Parameters.isAppKilled == True: return; textNotConnected = "Camera not connected, retrying" item.setText(textNotConnected+".") #Number of dots varies from 1 to 5 if nDots == 1: textDots = "." nDots = 2 elif nDots == 2: textDots = ".." nDots = 3 elif nDots == 3: textDots = "..." nDots = 4 elif nDots == 4: textDots = "...." nDots = 5 else: textDots = "....." nDots = 1 item.setForeground(QtGui.QColor("red")) item.setText(textNotConnected+textDots) self.timerDotChangeCamera = Timer(0.25, dotChange, [self.itemCameraStatus, nDots]) self.timerDotChangeCamera.start() if (isConnected == False): #System not connected print 'cam oups' nDots = 1 if hasattr(self,'timerDotChangeCamera'): self.timerDotChangeCamera.cancel() self.timerDotChangeCamera = Timer(0.25, dotChange, [self.itemCameraStatus, nDots]) self.timerDotChangeCamera.start() else: print "Camera connected" if hasattr(self,'timerDotChangeCamera'): self.timerDotChangeCamera.cancel() time.sleep(0.1) self.itemCameraStatus.setForeground(QtGui.QColor("green")) self.itemCameraStatus.setText("Camera connected.") print "Camera connected2" #Set the status text (system connected or not) def setInfo(self, text): self.tbInfo.append(text) #Set the status text (system connected or not) def setWire(self, mem1, mem2, mem3, mem4, maxValPos): self.itemMemory.setText("Acquisition board memory usage:\nDDR2: " + str(mem1) + " bytes.\nFIFO in: " + str(mem2) + " bytes.\nFIFO out: " + str(mem3) + " bytes.\nFIFO out (minimum): " + str(mem4) + " bytes.") self.itemMaxValPos.setText("Maximum RF value position: " + str(maxValPos)) def createLayout(self): print 'Creating layout...' self.setWindowTitle('Interferometry Acquisition GUI') #self.widget = QtGui.QWidget() #self.setCentralWidget(self.widget) self.layout = pg.LayoutWidget() #self.widget.setLayout(self.layout) self.setCentralWidget(self.layout) #Create GUI sizePolicyBt = QtGui.QSizePolicy(1, 1) sizePolicyBt.setHorizontalStretch(0) sizePolicyBt.setVerticalStretch(0) self.btOpen = QtGui.QPushButton("Open\nprevious results") sizePolicyBt.setHeightForWidth(self.btOpen.sizePolicy().hasHeightForWidth()) self.btOpen.setSizePolicy(sizePolicyBt); self.btOpen.setStyleSheet("background-color: yellow; font-size: 16px; font: bold") self.btStart = QtGui.QPushButton("Start\nacquisition") sizePolicyBt.setHeightForWidth(self.btStart.sizePolicy().hasHeightForWidth()) self.btStart.setSizePolicy(sizePolicyBt); self.btStart.setStyleSheet("background-color: green; font-size: 16px; font: bold") self.btStart.clicked.connect(self.startAcquisition) self.btStop = QtGui.QPushButton("Stop\nacquisition") sizePolicyBt.setHeightForWidth(self.btStop.sizePolicy().hasHeightForWidth()) self.btStop.setSizePolicy(sizePolicyBt); self.btStop.setStyleSheet("background-color: red; font-size: 16px; font: bold") self.btStop.clicked.connect(self.stopAcquisition) self.btStop.setEnabled(False) self.paramTree = ParameterTree() self.paramTree.setParameters(Parameters.paramObject, showTop=False) self.paramTree.setWindowTitle('pyqtgraph example: Parameter Tree') self.paramTree.setMinimumWidth(350) self.paramTree.setMaximumWidth(350) sizePolicyPt = QtGui.QSizePolicy(1,1) sizePolicyPt.setHorizontalStretch(QtGui.QSizePolicy.Fixed) sizePolicyPt.setVerticalStretch(1) self.paramTree.setSizePolicy(sizePolicyPt); ## Create random 2D data data = np.random.normal(size=(512, 512)) + pg.gaussianFilter(np.random.normal(size=(512, 512)), (5, 5)) * 20 + 100 data = data[:,:,np.newaxis] data = data.repeat(3,2) self.plotTl = pg.GraphicsView() self.plotTlImage = pg.ImageItem(data[:,:,:]) #parent=self.plotTl self.plotTlViewBox = pg.ViewBox() self.plotTl.setCentralWidget(self.plotTlViewBox) self.plotTlViewBox.addItem(self.plotTlImage) self.plotTr = pg.PlotWidget(title="Interferometry", labels={'left': 'Signal amplitude (A.U.)', 'bottom': 'Distance (mm)'}) #self.plotTlViewBox2.addItem(self.plotTr) self.plotTrCurve = self.plotTr.plot(pen=(255,0,0),name='C1') #Red self.plotTrCurve2 = self.plotTr.plot(pen=(0,255,0),name='C2') #Green #self.plotTlViewBox2.enableAutoRange('xy', True) ## stop auto-scaling after the first data set is plotted #self.plotTr.addLegend('Test') self.plotTr.setYRange(-1000, 1000) self.plotBl = pg.PlotWidget(title="Distance", labels={'left': 'Distance (mm)', 'bottom': 'Number of acquisitions'}) self.plotBlCurve = self.plotBl.plot(pen=(255,0,0),name='C1') self.plotBl.enableAutoRange('xy', True) ## stop auto-scaling after the first data set is plotted self.plotBl.setMaximumWidth(3500) self.tbInfo = QtGui.QTextEdit() self.tbInfo.setEnabled(False) palette = self.tbInfo.palette() palette.setColor(QtGui.QPalette.Base, QtGui.QColor("white")) #White background self.tbInfo.setPalette(palette) self.tbInfo.setTextColor(QtGui.QColor("black")) self.tbInfo.insertPlainText("Useful information will appear here.") #Create list view of multiple items self.tbStatus = QtGui.QListView() self.tbStatus.setEnabled(False) palette = self.tbStatus.palette() palette.setColor(QtGui.QPalette.Base, QtGui.QColor("white")) #White background self.tbStatus.setPalette(palette) itemModelStatus = QtGui.QStandardItemModel(self.tbStatus) self.tbStatus.setModel(itemModelStatus) #Add system status self.itemStatus = QtGui.QStandardItem() self.setStatus(False) itemModelStatus.appendRow(self.itemStatus) #Add camera status self.itemCameraStatus = QtGui.QStandardItem() self.setCameraStatus(False) itemModelStatus.appendRow(self.itemCameraStatus) #Add memory usage self.itemMemory = QtGui.QStandardItem("Acquisition board memory usage: N/A") self.itemMemory.setForeground(QtGui.QColor("black")) itemModelStatus.appendRow(self.itemMemory) #Add max value position self.itemMaxValPos = QtGui.QStandardItem("Maximum RF value position: N/A") self.itemMaxValPos.setForeground(QtGui.QColor("black")) itemModelStatus.appendRow(self.itemMaxValPos) #layout.addWidget(QtGui.QLabel("These are two views of the same data. They should always display the same values."), 0, 0, 1, 2) self.layout.addWidget(self.btOpen, 9, 6, 1, 1) self.layout.addWidget(self.btStart, 9, 7, 1, 1) self.layout.addWidget(self.btStop, 9, 8, 1, 1) self.layout.addWidget(self.paramTree, 0, 0, 10, 3) self.layout.addWidget(self.plotTl, 0, 3, 5, 3) self.layout.addWidget(self.plotTr, 0, 6, 5, 3) self.layout.addWidget(self.plotBl, 5, 3, 5, 3) self.layout.addWidget(self.tbInfo, 5, 6, 2, 3) self.layout.addWidget(self.tbStatus, 7, 6, 2, 3) self.layout.layout.setColumnStretch(3,1) self.layout.layout.setColumnStretch(4,1) self.layout.layout.setColumnStretch(5,1) self.layout.layout.setColumnStretch(6,1) self.layout.layout.setColumnStretch(7,1) self.layout.layout.setColumnStretch(8,1) self.show() self.resize(1500,800) self.move(100,100) Parameters.paramObject.param('Save/Restore functionality', 'Save State').sigActivated.connect(self.saveParam) Parameters.paramObject.param('Save/Restore functionality', 'Restore State').sigActivated.connect(self.restoreParam) Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").sigValueChanged.connect(self.motorSpeedChanged) Parameters.paramObject.child("Trigger Options", "Acquisition mode").sigValueChanged.connect(self.triggerChanged) Parameters.paramObject.child("Trigger Options", "Trigger amplitude").sigValueChanged.connect(self.triggerChanged) Parameters.paramObject.child("Trigger Options", "Trigger switch 1/2").sigActivated.connect(self.triggerHalfSwitch) # adding by emitting signal in different thread self.workThread = AcquisitionWorker() self.workThread.updateDataCamera.connect(self.setDataCurveTl) self.workThread.updateDataInterf.connect(self.setDataCurveTr) self.workThread.updateDataDistance.connect(self.setDataCurveBl) self.workThread.updateDataDistance2.connect(self.setDataCurveBl2) self.workThread.updateWire.connect(self.setWire) self.workThread.setStatus.connect(self.setStatus) self.workThread.setInfo.connect(self.setInfo) self.testCount = 0; #Fill the plots with dummy data self.data = np.random.normal(size=(10,1000)) self.plotTrXAxis = np.arange(1000) * (0.01) self.plotBlXAxis = np.arange(1000) * (1) self.plotTrCurve.setData(x=self.plotTrXAxis,y=self.data[2%10],name='C1') self.plotTrCurve2.setData(x=self.plotTrXAxis,y=self.data[3%10],name='C2') self.plotBlCurve.setData(x=self.plotBlXAxis,y=self.data[4%10],name='C1') self.valueTest = 1 def setDataCurveTl(self, data): self.dataImage1 = data self.plotTlImage.setImage(data) self.testCount = self.testCount + 1; def setDataCurveTr(self, dataIn): self.plotTrCurve.setData(dataIn[0:len(dataIn):2],name='C1') self.plotTrCurve2.setData(dataIn[1:len(dataIn):2],name='C2') def setDataCurveBl(self, dataIn): self.plotBlCurve.setData(dataIn,name='C1') def setDataCurveBl2(self, xIn, dataIn): self.plotBlCurve.setData(x=xIn,y=dataIn,name='C1')
class StepScanCentralWidget(QtWidgets.QWidget): """ Main widget for the step scan measuring software """ def __init__(self): super().__init__() self.title = 'centralWidget' self.scan = stepscan.StepScan() # this will contain all data! self.parameters = Parameter.create(name='params', type='group', children=self.scan.parameters) # self.scan_thread = QtCore.QThread() self.n_of_averages = 5 self.scansLeft = self.n_of_averages self.scanning = False self.lockinParameters = ['X', 'Y'] self.plotParameters = self.lockinParameters self.plotData = {'avg': pd.DataFrame()} self.plotPen = {'Xa': (255, 0, 0), 'Ya': (0, 255, 0), 'X': (75, 0, 0), 'Y': (0, 75, 0), } """ Generate GUI layout """ self.setup_font_styles() self.make_layout() self.show() self.monitor_timer = QtCore.QTimer() self.monitor_timer.timeout.connect(self.on_monitor_timer) self.stageMoveTimer = QtCore.QTimer() self.stageMoveTimer.timeout.connect(self.on_stage_move_timer) # self.monitor_timer.start(400) self.instruments = {} if not testMode: self.instruments['lockin'] = USBGPIBlib.USBGPIB() self.instruments['lockin'].connect() self.instruments['stage'] = NewPortStagelib.NewPortStage() self.instruments['stage'].Initilize() # self.currentStagePosition = self.instruments['stage'].get_current_position() self.currentStagePosition = 0 def make_layout(self): """ Generate the GUI layout """ # ------- DEFINE LEFT PANEL ------- layoutLeftPanel = QtWidgets.QVBoxLayout() layoutLeftPanel.setSpacing(10) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.parameterTree = ParameterTree() self.parameterTree.setParameters(self.parameters) self.parameterTree.setSizePolicy(sizePolicy) layoutLeftPanel.addWidget(QtGui.QLabel('StepScan Parameters:')) layoutLeftPanel.addWidget(self.parameterTree) self.printTreeButton = QtWidgets.QPushButton('print tree') self.printTreeButton.clicked.connect(self.print_parameters) layoutLeftPanel.addWidget(self.printTreeButton) # ------- DEFINE CENTRAL PANEL ------- layoutCentralPanel = QtWidgets.QGridLayout() layoutCentralPanel.setSpacing(10) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.mainPlot = pg.PlotWidget() layoutCentralPanel.addWidget(self.mainPlot, 0, 0, 1, 2) self.mainPlot.setSizePolicy(sizePolicy) self.scanStatusBox = QtWidgets.QGroupBox('StepScan Status:') layoutCentralPanel.addWidget(self.scanStatusBox, 2, 0) scanStatusLayout = QtWidgets.QGridLayout() scanStatusSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self.scanStatusBox.setSizePolicy(scanStatusSizePolicy) self.scanStatusBox.setLayout(scanStatusLayout) self.startstop_button = QtWidgets.QPushButton('Start StepScan') self.startstop_button.clicked.connect(self.startstop_scan) scanStatusLayout.addWidget(self.startstop_button, 0, 2, 1, 2) self.save_button = QtWidgets.QPushButton('save') scanStatusLayout.addWidget(self.save_button, 1, 3, 1, 1) self.save_button.clicked.connect(self.save_to_HDF5) self.n_of_averages_box = QtWidgets.QSpinBox() # self.n_of_averages_box.valueChanged.connect(self.set_n_of_averages) self.n_of_averages_box.setValue(self.n_of_averages) scanStatusLayout.addWidget(self.n_of_averages_box, 1, 2, 2, 2) self.stageControl = QtWidgets.QGroupBox('stageControl:') layoutCentralPanel.addWidget(self.stageControl, 2, 1) stageControlLayout = QtWidgets.QGridLayout() scanStatusSizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) self.stageControl.setSizePolicy(scanStatusSizePolicy) self.stageControl.setLayout(stageControlLayout) self.moveStageToButton = QtWidgets.QPushButton('Move stage') self.moveStageToSpinBox = QtWidgets.QDoubleSpinBox() self.moveStageToSpinBox.setSuffix(' mm') self.moveStageToSpinBox.setRange(-150, 150) self.moveStageToSpinBox.setValue(0) self.moveStageToSpinBox.setSingleStep(0.01) self.moveStageToButton.clicked.connect(self.move_stage_to_spinbox_value) self.moveStageLeft = QtWidgets.QPushButton("<") self.moveStageLeft.pressed.connect(lambda: self.moving_stage('-')) self.moveStageLeft.released.connect(lambda: self.moving_stage(None)) self.moveStageRight = QtWidgets.QPushButton(">") self.moveStageRight.pressed.connect(lambda: self.moving_stage('+')) self.moveStageRight.released.connect(lambda: self.moving_stage(None)) self.moveStageStep = QtWidgets.QDoubleSpinBox() self.moveStageStep.setSuffix(' mm') self.moveStageStep.setRange(-150, 150) self.moveStageStep.setValue(0.01) self.moveStageStep.setSingleStep(0.001) stageControlLayout.addWidget(QtWidgets.QLabel("Position:"), 0, 0) stageControlLayout.addWidget(self.moveStageToSpinBox, 0, 1) stageControlLayout.addWidget(self.moveStageToButton, 0, 2) stageControlLayout.addWidget(self.moveStageLeft, 1, 0) stageControlLayout.addWidget(self.moveStageStep, 1, 1) stageControlLayout.addWidget(self.moveStageRight, 1, 2) # ------- DEFINE RIGHT PANEL ------- layoutRightPanel = QtWidgets.QVBoxLayout() layoutRightPanel.setSpacing(10) self.monitorGroup = QtWidgets.QGroupBox('Instrument Monitor') layoutRightPanel.addWidget(self.monitorGroup) monitorGroupLayout = QtWidgets.QGridLayout() self.monitorGroup.setLayout(monitorGroupLayout) self.lockin_X_monitor = QtWidgets.QLabel('1,00') self.lockin_X_monitor.setFont(self.monitor_number_font) lockin_X_monitor_box = QtWidgets.QLabel('Lockin X:') monitorGroupLayout.addWidget(lockin_X_monitor_box, 0, 0) monitorGroupLayout.addWidget(self.lockin_X_monitor, 1, 0, 1, 3) self.lockin_Y_monitor = QtWidgets.QLabel('1,00') self.lockin_Y_monitor.setFont(self.monitor_number_font) monitorGroupLayout.addWidget(QtWidgets.QLabel('Lockin Y:'), 2, 0) monitorGroupLayout.addWidget(self.lockin_Y_monitor, 3, 0, 1, 3) self.temperature_monitor = QtWidgets.QLabel('1,00') self.temperature_monitor.setFont(self.monitor_number_font) monitorGroupLayout.addWidget(QtWidgets.QLabel('Temperature:'), 4, 0) monitorGroupLayout.addWidget(self.temperature_monitor, 5, 0, 1, 3) self.setTimeAxisGroup = QtWidgets.QGroupBox('Set Time Axis') sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) self.setTimeAxisGroup.setSizePolicy(sizePolicy) layoutRightPanel.addWidget(self.setTimeAxisGroup) setTimeAxisGroupLayout = QtWidgets.QGridLayout() self.setTimeAxisGroup.setLayout(setTimeAxisGroupLayout) setTimeAxisGroupLayout.addWidget(QtWidgets.QLabel('from:'), 0, 0) setTimeAxisGroupLayout.addWidget(QtWidgets.QLabel('Step size:'), 0, 1) v_position = 0 self.timeRanges = 3 init_steps = [0.05, 0.05, 0.1, 0.2, 0.5, 2, 5, 10] init_ranges = [-1, 0, 1, 3, 10, 50, 100, 200, 500] for i in range(self.timeRanges): v_position = i + 1 name_from = 'timeRange' + str(i) + '_from' value = QtWidgets.QDoubleSpinBox() setattr(self, name_from, QtWidgets.QDoubleSpinBox()) getattr(self, name_from).setRange(-1000, 1000) getattr(self, name_from).setSuffix(' ps') getattr(self, name_from).setSingleStep(0.01) getattr(self, name_from).setValue(init_ranges[i]) setTimeAxisGroupLayout.addWidget(getattr(self, name_from), v_position, 0) name_step = 'timeRange' + str(i) + '_step' setattr(self, name_step, QtWidgets.QDoubleSpinBox()) getattr(self, name_step).setRange(0, 100) getattr(self, name_step).setSuffix(' ps') getattr(self, name_step).setSingleStep(0.01) getattr(self, name_step).setValue(init_steps[i]) setTimeAxisGroupLayout.addWidget(getattr(self, name_step), v_position, 1) self.setTimeAxisApply = QtWidgets.QPushButton('Apply') self.setTimeAxisApply.clicked.connect(self.set_time_axis) setTimeAxisGroupLayout.addWidget(self.setTimeAxisApply, v_position + 1, 0, 1, 2) mainLayout = QtWidgets.QHBoxLayout() # create a grid for subWidgets mainLayout.setSpacing(10) mainLayout.addLayout(layoutLeftPanel) mainLayout.addLayout(layoutCentralPanel) mainLayout.addLayout(layoutRightPanel) self.setLayout(mainLayout) def setup_font_styles(self): """ Give settings for fonts to use in widget""" self.title_font = QtGui.QFont() self.title_font.setBold(True) self.title_font.setPixelSize(15) self.subtitle_font = QtGui.QFont() self.subtitle_font.setPixelSize(12) self.subtitle_font.setBold(True) self.text_font = QtGui.QFont() self.text_font.setPixelSize(10) self.monitor_number_font = QtGui.QFont() self.monitor_number_font.setPixelSize(14) self.monitor_number_font.setBold(True) def moving_stage(self, direction): if direction is None: self.stageMoveTimer.stop() else: self.moveStageDirection = direction self.stageMoveTimer.start(100) def on_stage_move_timer(self): if self.moveStageDirection == "+": newPos = self.currentStagePosition + self.moveStageStep.value() elif self.moveStageDirection == "-": newPos = self.currentStagePosition - self.moveStageStep.value() self.move_stage_to(newPos) @QtCore.pyqtSlot() def set_n_of_averages(self, nAvg): self.n_of_averages = nAvg @QtCore.pyqtSlot() def set_time_axis(self): """ Uses the values given for the time ranges to define the time scale and corresponding stage positions for the scan.""" startPoints = [] steps = [] for i in range(self.timeRanges): varName_from = 'timeRange' + str(i) + '_from' startPoints.append(np.float64(getattr(self, varName_from).cleanText())) varName_step = 'timeRange' + str(i) + '_step' steps.append(np.float64(getattr(self, varName_step).cleanText())) timescale = [] stagePositions = [] for i in range(len(startPoints) - 1): start = startPoints[i] stop = startPoints[i + 1] step = steps[i] range_points = np.arange(start, stop, step) for j in range_points: timescale.append(j) stagePositions.append(j * 0.299792458 * 2) if utils.monotonically_increasing(timescale): self.scan.timeScale = timescale self.scan.stagePositions = stagePositions else: print('time scale defined is not monotonous! check again!!') print('StepScan contains {0} points, ranging from {1} to {2} ps.'.format(len(self.scan.timeScale), self.scan.timeScale[0], self.scan.timeScale[-1])) @QtCore.pyqtSlot() def on_monitor_timer(self): if testMode: self.X = np.random.rand(1)[0] * 0.001 self.Y = np.random.rand(1)[0] * 0.001 else: self.X = self.instruments['lockin'].readValue('X') self.Y = self.instruments['lockin'].readValue('Y') self.lockin_X_monitor.setText('{:.3E} V'.format(self.X)) self.lockin_Y_monitor.setText('{:.3E} V'.format(self.Y)) @QtCore.pyqtSlot() def move_stage_to_spinbox_value(self): newPos = self.moveStageToSpinBox.value() if testMode: print('Stage moved to: {}'.format(newPos)) else: self.instruments['stage'].MoveTo(newPos) @QtCore.pyqtSlot(float) def move_stage_to(self, pos): self.currentStagePosition = pos if testMode: print('Stage moved to: {}'.format(pos)) else: self.instruments['stage'].MoveTo(pos) @QtCore.pyqtSlot() def startstop_scan(self): if self.scanning: self.stop_scan_after_current() self.scanning = False else: self.monitor_timer.stop() print('scan started') for parameter in self.lockinParameters: self.scan.data[parameter] = pd.DataFrame(np.zeros(len(self.scan.timeScale)), columns=['avg'], index=self.scan.timeScale) self.plotData['avg'] = pd.DataFrame(np.zeros(len(self.scan.timeScale)), columns=['avg'], index=self.scan.timeScale) self.scanNumber = 0 self.make_single_scan() self.scanning = True @QtCore.pyqtSlot() def make_single_scan(self): """ performs a single scan with the given stagePositions""" for parameter in self.plotParameters: self.plotData[parameter] = {self.scanNumber: []} self.scan_thread = QtCore.QThread() print( 'scanning for {0} with {1} dwelltime'.format(self.lockinParameters, self.scan.settings_lockIn['dwellTime'], self.instruments)) self.w = StepScanWorker(self.scan.stagePositions, self.lockinParameters, self.scan.settings_lockIn['dwellTime'], self.instruments) self.w.finished[pd.DataFrame].connect(self.on_finished) self.w.newData.connect(self.append_new_data) self.w.moveToThread(self.scan_thread) self.scan_thread.started.connect(self.w.work) self.scan_thread.start() @QtCore.pyqtSlot(dict) def on_finished(self, dict): """ Prints the threads's output and starts a new one until total number of averages is reached""" # print(dict) print('average n {}'.format(self.scanNumber)) time.sleep(1) for key, item in dict.items(): self.scan.data[key][self.scanNumber] = item self.scan.data['avg'][key] = self.scan.data[key].mean(axis=1) try: self.clear_plot() for key in self.plotParameters: ya = self.scan.data['avg'][key] xa = self.scan.timeScale pen = self.plotPen['{}a'.format(key)] self.mainPlot.plot(xa, ya, pen=pen) except: pass self.scanNumber += 1 if self.scanNumber >= self.n_of_averages: print('done scanning') for key, value in self.scan.data.items(): print(key) print(value) self.scanning = False else: self.make_single_scan() @QtCore.pyqtSlot() def stop_scan_after_current(self): print('scan will stop after current run.') self.n_of_averages = self.scanNumber self.n_of_averages_box.setValue(self.scanNumber) @QtCore.pyqtSlot(int, dict) def append_new_data(self, index, value): for key in self.plotParameters: self.plotData[key][self.scanNumber].append(value[key]) self.plot_parameters() @QtCore.pyqtSlot() def save_to_HDF5(self): self.scan.save_to_HDF5() self.scan.save_to_csv() # todo: implement following code for plot refreshing # def set_plotdata(self, name, dataset_x, dataset_y): # # self.canvas = self.win.addPlot(title='bla') # # if name in self.traces: # self.tracesname.setData(dataset_x,dataset_y) # else: # self.traces[name] = self.canvas.plot(pen='y') @QtCore.pyqtSlot() def plot_parameters(self): try: for key in self.plotParameters: pen = self.plotPen[key] y = self.plotData[key][self.scanNumber] x = self.scan.timeScale[0:len(y)] self.mainPlot.plot(x, y, pen=pen) except Exception as error: self.rise_error('plotting', error) @QtCore.pyqtSlot() def clear_plot(self): self.mainPlot.clear() @QtCore.pyqtSlot() def print_parameters(self): print(self.scan.parameters) @QtCore.pyqtSlot(str, str) def rise_error(self, doingWhat, errorHandle, type='Warning', popup=True): """ opens a dialog window showing the error""" errorMessage = 'Error while {0}:\n{1}'.format(doingWhat, errorHandle) print(errorMessage) if popup: errorDialog = QtWidgets.QMessageBox() errorDialog.setText(errorMessage) if type == 'Warning': errorDialog.setIcon(QtWidgets.QMessageBox.Warning) elif type == 'Critical': errorDialog.setIcon(QtWidgets.QMessageBox.Critical) errorDialog.setStandardButtons(QtWidgets.QMessageBox.Ok) errorDialog.exec_() def closeEvent(self): # todo: implement correct closing procedure for name, inst in self.instruments.items(): inst.close() print('{} closed'.format(name)) QtCore.QCoreApplication.instance().quit()
class Ui_MainWindow(object): def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(978, 711) icon = QtGui.QIcon() icon.addPixmap( QtGui.QPixmap(_fromUtf8(":/exterminator/icons/program_icon.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off) MainWindow.setWindowIcon(icon) MainWindow.setToolTip(_fromUtf8("")) MainWindow.setWindowFilePath(_fromUtf8("")) MainWindow.setTabShape(QtGui.QTabWidget.Rounded) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.verticalLayout_5 = QtGui.QVBoxLayout(self.centralwidget) self.verticalLayout_5.setObjectName(_fromUtf8("verticalLayout_5")) self.label_4 = QtGui.QLabel(self.centralwidget) font = QtGui.QFont() font.setBold(True) font.setWeight(75) self.label_4.setFont(font) self.label_4.setObjectName(_fromUtf8("label_4")) self.verticalLayout_5.addWidget(self.label_4) self.overviewComboBox = QtGui.QComboBox(self.centralwidget) font = QtGui.QFont() font.setBold(True) font.setItalic(True) font.setWeight(75) self.overviewComboBox.setFont(font) self.overviewComboBox.setObjectName(_fromUtf8("overviewComboBox")) self.verticalLayout_5.addWidget(self.overviewComboBox) self.line = QtGui.QFrame(self.centralwidget) self.line.setLineWidth(17) self.line.setObjectName(_fromUtf8("line")) self.verticalLayout_5.addWidget(self.line) self.tabWidget = QtGui.QTabWidget(self.centralwidget) self.tabWidget.setEnabled(True) self.tabWidget.setFocusPolicy(QtCore.Qt.TabFocus) self.tabWidget.setAcceptDrops(False) self.tabWidget.setAutoFillBackground(False) self.tabWidget.setTabPosition(QtGui.QTabWidget.North) self.tabWidget.setTabShape(QtGui.QTabWidget.Rounded) self.tabWidget.setElideMode(QtCore.Qt.ElideNone) self.tabWidget.setDocumentMode(False) self.tabWidget.setTabsClosable(False) self.tabWidget.setMovable(True) self.tabWidget.setObjectName(_fromUtf8("tabWidget")) self.tab_tiles = QtGui.QWidget() self.tab_tiles.setObjectName(_fromUtf8("tab_tiles")) self.horizontalLayout = QtGui.QHBoxLayout(self.tab_tiles) self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout")) self.splitter = QtGui.QSplitter(self.tab_tiles) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setObjectName(_fromUtf8("splitter")) self.treeDataTiles = QtGui.QTreeWidget(self.splitter) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.treeDataTiles.sizePolicy().hasHeightForWidth()) self.treeDataTiles.setSizePolicy(sizePolicy) self.treeDataTiles.setWhatsThis( _fromUtf8( "This is widget where in tree maner all input data are presented.\n" "This can be composed just from one detector (in. example BSE) images, or can be complicated more than ten element mappings.\n" "This is not interactive view. If this doesn\'t work after importing or appending data something is broken." )) self.treeDataTiles.setObjectName(_fromUtf8("treeDataTiles")) self.treeDataTiles.headerItem().setText(0, _fromUtf8("data files")) self.verticalLayoutWidget = QtGui.QWidget(self.splitter) self.verticalLayoutWidget.setObjectName( _fromUtf8("verticalLayoutWidget")) self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget) self.verticalLayout.setMargin(0) self.verticalLayout.setObjectName(_fromUtf8("verticalLayout")) self.label_2 = QtGui.QLabel(self.verticalLayoutWidget) self.label_2.setObjectName(_fromUtf8("label_2")) self.verticalLayout.addWidget(self.label_2) self.plainTextEdit = QtGui.QPlainTextEdit(self.verticalLayoutWidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(1) sizePolicy.setVerticalStretch(1) sizePolicy.setHeightForWidth( self.plainTextEdit.sizePolicy().hasHeightForWidth()) self.plainTextEdit.setSizePolicy(sizePolicy) self.plainTextEdit.setMinimumSize(QtCore.QSize(200, 100)) self.plainTextEdit.setWhatsThis( _fromUtf8( "Not inteactive text widget which gets and presents statistics of widget above (data widget)" )) self.plainTextEdit.setReadOnly(True) self.plainTextEdit.setPlainText(_fromUtf8("")) self.plainTextEdit.setObjectName(_fromUtf8("plainTextEdit")) self.verticalLayout.addWidget(self.plainTextEdit) self.horizontalLayout.addWidget(self.splitter) self.tabWidget.addTab(self.tab_tiles, _fromUtf8("")) self.tab_param = QtGui.QWidget() self.tab_param.setEnabled(True) self.tab_param.setObjectName(_fromUtf8("tab_param")) self.gridLayout_4 = QtGui.QGridLayout(self.tab_param) self.gridLayout_4.setObjectName(_fromUtf8("gridLayout_4")) self.splitter_2 = QtGui.QSplitter(self.tab_param) self.splitter_2.setOrientation(QtCore.Qt.Horizontal) self.splitter_2.setObjectName(_fromUtf8("splitter_2")) self.gridLayoutWidget = QtGui.QWidget(self.splitter_2) self.gridLayoutWidget.setObjectName(_fromUtf8("gridLayoutWidget")) self.gridLayout_3 = QtGui.QGridLayout(self.gridLayoutWidget) self.gridLayout_3.setMargin(0) self.gridLayout_3.setObjectName(_fromUtf8("gridLayout_3")) self.treeParameters = ParameterTree(self.gridLayoutWidget) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.treeParameters.sizePolicy().hasHeightForWidth()) self.treeParameters.setSizePolicy(sizePolicy) self.treeParameters.setMinimumSize(QtCore.QSize(280, 0)) self.treeParameters.setObjectName(_fromUtf8("treeParameters")) self.gridLayout_3.addWidget(self.treeParameters, 0, 0, 1, 1) self.setAsDefault = QtGui.QPushButton(self.gridLayoutWidget) self.setAsDefault.setObjectName(_fromUtf8("setAsDefault")) self.gridLayout_3.addWidget(self.setAsDefault, 1, 0, 1, 1) self.gridLayout_4.addWidget(self.splitter_2, 0, 0, 1, 1) self.tabWidget.addTab(self.tab_param, _fromUtf8("")) self.tab_filters = QtGui.QWidget() self.tab_filters.setObjectName(_fromUtf8("tab_filters")) self.verticalLayout_7 = QtGui.QVBoxLayout(self.tab_filters) self.verticalLayout_7.setObjectName(_fromUtf8("verticalLayout_7")) self.splitter_3 = QtGui.QSplitter(self.tab_filters) self.splitter_3.setOrientation(QtCore.Qt.Vertical) self.splitter_3.setObjectName(_fromUtf8("splitter_3")) self.filtersTreeView = ParameterTree(self.splitter_3) self.filtersTreeView.setEditTriggers( QtGui.QAbstractItemView.NoEditTriggers) self.filtersTreeView.setAlternatingRowColors(True) self.filtersTreeView.setObjectName(_fromUtf8("filtersTreeView")) self.filterParamView = ParameterTree(self.splitter_3) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.filterParamView.sizePolicy().hasHeightForWidth()) self.filterParamView.setSizePolicy(sizePolicy) self.filterParamView.setMinimumSize(QtCore.QSize(0, 40)) self.filterParamView.setMaximumSize(QtCore.QSize(16777215, 100)) self.filterParamView.setObjectName(_fromUtf8("filterParamView")) self.verticalLayout_7.addWidget(self.splitter_3) self.tabWidget.addTab(self.tab_filters, _fromUtf8("")) self.tab_finish = QtGui.QWidget() self.tab_finish.setObjectName(_fromUtf8("tab_finish")) self.verticalLayout_3 = QtGui.QVBoxLayout(self.tab_finish) self.verticalLayout_3.setObjectName(_fromUtf8("verticalLayout_3")) self.treeFinalWidget = QtGui.QTreeWidget(self.tab_finish) self.treeFinalWidget.setObjectName(_fromUtf8("treeFinalWidget")) self.treeFinalWidget.headerItem().setText( 0, _fromUtf8("stuff (do not edit!)")) self.treeFinalWidget.headerItem().setText( 1, _fromUtf8("final names and titles (editable)")) self.verticalLayout_3.addWidget(self.treeFinalWidget) self.tabWidget.addTab(self.tab_finish, _fromUtf8("")) self.verticalLayout_5.addWidget(self.tabWidget) MainWindow.setCentralWidget(self.centralwidget) self.menubar = QtGui.QMenuBar(MainWindow) self.menubar.setGeometry(QtCore.QRect(0, 0, 978, 20)) self.menubar.setFocusPolicy(QtCore.Qt.NoFocus) self.menubar.setObjectName(_fromUtf8("menubar")) self.menuFile = QtGui.QMenu(self.menubar) self.menuFile.setObjectName(_fromUtf8("menuFile")) self.menuEdit = QtGui.QMenu(self.menubar) self.menuEdit.setObjectName(_fromUtf8("menuEdit")) self.menuHelp = QtGui.QMenu(self.menubar) self.menuHelp.setObjectName(_fromUtf8("menuHelp")) self.menuView = QtGui.QMenu(self.menubar) self.menuView.setObjectName(_fromUtf8("menuView")) MainWindow.setMenuBar(self.menubar) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.toolBar = QtGui.QToolBar(MainWindow) self.toolBar.setMouseTracking(False) self.toolBar.setFocusPolicy(QtCore.Qt.NoFocus) self.toolBar.setWhatsThis( _fromUtf8("Toolbar, what else did you expect?")) self.toolBar.setMovable(True) self.toolBar.setIconSize(QtCore.QSize(64, 64)) self.toolBar.setObjectName(_fromUtf8("toolBar")) MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar) self.overviewWidget = QtGui.QDockWidget(MainWindow) self.overviewWidget.setEnabled(True) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.overviewWidget.sizePolicy().hasHeightForWidth()) self.overviewWidget.setSizePolicy(sizePolicy) self.overviewWidget.setMinimumSize(QtCore.QSize(350, 150)) self.overviewWidget.setToolTip( _fromUtf8("widget with vector\n" "representation of the tiles")) self.overviewWidget.setAccessibleName(_fromUtf8("")) self.overviewWidget.setAccessibleDescription(_fromUtf8("")) self.overviewWidget.setFloating(True) self.overviewWidget.setFeatures( QtGui.QDockWidget.AllDockWidgetFeatures) self.overviewWidget.setWindowTitle( _fromUtf8("graphical overview of the tiles")) self.overviewWidget.setObjectName(_fromUtf8("overviewWidget")) self.dockWidgetContents = QtGui.QWidget() sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.dockWidgetContents.sizePolicy().hasHeightForWidth()) self.dockWidgetContents.setSizePolicy(sizePolicy) self.dockWidgetContents.setObjectName(_fromUtf8("dockWidgetContents")) self.verticalLayout_2 = QtGui.QVBoxLayout(self.dockWidgetContents) self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2")) self.graphicalOverview = GraphicsLayoutWidget(self.dockWidgetContents) self.graphicalOverview.setObjectName(_fromUtf8("graphicalOverview")) self.verticalLayout_2.addWidget(self.graphicalOverview) self.overviewWidget.setWidget(self.dockWidgetContents) MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1), self.overviewWidget) self.consoleWidget = QtGui.QDockWidget(MainWindow) self.consoleWidget.setWindowTitle(_fromUtf8("python console / debug")) self.consoleWidget.setObjectName(_fromUtf8("consoleWidget")) self.dockWidgetContents_2 = QtGui.QWidget() self.dockWidgetContents_2.setObjectName( _fromUtf8("dockWidgetContents_2")) self.verticalLayout_4 = QtGui.QVBoxLayout(self.dockWidgetContents_2) self.verticalLayout_4.setObjectName(_fromUtf8("verticalLayout_4")) self.pythonConsole = ConsoleWidget(self.dockWidgetContents_2) self.pythonConsole.setObjectName(_fromUtf8("pythonConsole")) self.verticalLayout_4.addWidget(self.pythonConsole) self.consoleWidget.setWidget(self.dockWidgetContents_2) MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(8), self.consoleWidget) self.stitchWidget = QtGui.QDockWidget(MainWindow) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.stitchWidget.sizePolicy().hasHeightForWidth()) self.stitchWidget.setSizePolicy(sizePolicy) self.stitchWidget.setFloating(False) self.stitchWidget.setFeatures(QtGui.QDockWidget.AllDockWidgetFeatures) self.stitchWidget.setWindowTitle(_fromUtf8("image stitching preview")) self.stitchWidget.setObjectName(_fromUtf8("stitchWidget")) self.dockWidgetContents_5 = QtGui.QWidget() self.dockWidgetContents_5.setObjectName( _fromUtf8("dockWidgetContents_5")) self.horizontalLayout_2 = QtGui.QHBoxLayout(self.dockWidgetContents_5) self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2")) self.graphicsView = GraphicsView(self.dockWidgetContents_5) self.graphicsView.setObjectName(_fromUtf8("graphicsView")) self.horizontalLayout_2.addWidget(self.graphicsView) self.stitchWidget.setWidget(self.dockWidgetContents_5) MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.stitchWidget) self.filterDockWidget = QtGui.QDockWidget(MainWindow) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( self.filterDockWidget.sizePolicy().hasHeightForWidth()) self.filterDockWidget.setSizePolicy(sizePolicy) self.filterDockWidget.setMinimumSize(QtCore.QSize(300, 242)) self.filterDockWidget.setObjectName(_fromUtf8("filterDockWidget")) self.dockWidgetContents_3 = QtGui.QWidget() self.dockWidgetContents_3.setObjectName( _fromUtf8("dockWidgetContents_3")) self.gridLayout = QtGui.QGridLayout(self.dockWidgetContents_3) self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.label_3 = QtGui.QLabel(self.dockWidgetContents_3) self.label_3.setObjectName(_fromUtf8("label_3")) self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1) self.originalView = ImageView(self.dockWidgetContents_3) self.originalView.setObjectName(_fromUtf8("originalView")) self.gridLayout.addWidget(self.originalView, 1, 0, 1, 1) self.filteredView = ImageView(self.dockWidgetContents_3) self.filteredView.setObjectName(_fromUtf8("filteredView")) self.gridLayout.addWidget(self.filteredView, 3, 0, 1, 1) self.label = QtGui.QLabel(self.dockWidgetContents_3) self.label.setObjectName(_fromUtf8("label")) self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.filterDockWidget.setWidget(self.dockWidgetContents_3) MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2), self.filterDockWidget) self.actionAbout = QtGui.QAction(MainWindow) self.actionAbout.setObjectName(_fromUtf8("actionAbout")) self.actionImportDataFolder = QtGui.QAction(MainWindow) self.actionImportDataFolder.setEnabled(True) icon1 = QtGui.QIcon() icon1.addPixmap( QtGui.QPixmap( _fromUtf8(":/exterminator/icons/import_from_dir.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionImportDataFolder.setIcon(icon1) self.actionImportDataFolder.setObjectName( _fromUtf8("actionImportDataFolder")) self.actionImportMetadata = QtGui.QAction(MainWindow) self.actionImportMetadata.setEnabled(False) icon2 = QtGui.QIcon() icon2.addPixmap( QtGui.QPixmap(_fromUtf8(":/exterminator/icons/import_rtj.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionImportMetadata.setIcon(icon2) self.actionImportMetadata.setObjectName( _fromUtf8("actionImportMetadata")) self.actionExportHdf5 = QtGui.QAction(MainWindow) self.actionExportHdf5.setEnabled(False) icon3 = QtGui.QIcon() icon3.addPixmap( QtGui.QPixmap(_fromUtf8(":/exterminator/icons/export_hdf5.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionExportHdf5.setIcon(icon3) self.actionExportHdf5.setObjectName(_fromUtf8("actionExportHdf5")) self.actionExportImages = QtGui.QAction(MainWindow) self.actionExportImages.setEnabled(False) icon4 = QtGui.QIcon() icon4.addPixmap( QtGui.QPixmap(_fromUtf8(":/exterminator/icons/export_images.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionExportImages.setIcon(icon4) self.actionExportImages.setObjectName(_fromUtf8("actionExportImages")) self.actionQuit = QtGui.QAction(MainWindow) icon5 = QtGui.QIcon() icon5.addPixmap( QtGui.QPixmap( _fromUtf8(":/exterminator/icons/system-log-out.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionQuit.setIcon(icon5) self.actionQuit.setShortcutContext(QtCore.Qt.ApplicationShortcut) self.actionQuit.setObjectName(_fromUtf8("actionQuit")) self.actionClear = QtGui.QAction(MainWindow) icon6 = QtGui.QIcon() icon6.addPixmap( QtGui.QPixmap(_fromUtf8(":/exterminator/icons/edit-delete.svg")), QtGui.QIcon.Normal, QtGui.QIcon.Off) self.actionClear.setIcon(icon6) self.actionClear.setObjectName(_fromUtf8("actionClear")) self.actionChangelog = QtGui.QAction(MainWindow) self.actionChangelog.setObjectName(_fromUtf8("actionChangelog")) self.actionAbout_Qt = QtGui.QAction(MainWindow) self.actionAbout_Qt.setObjectName(_fromUtf8("actionAbout_Qt")) self.actionDynamicWidgets = QtGui.QAction(MainWindow) self.actionDynamicWidgets.setCheckable(True) self.actionDynamicWidgets.setChecked(True) self.actionDynamicWidgets.setText( _fromUtf8("toggle dynamic visibility of widgets")) self.actionDynamicWidgets.setToolTip( _fromUtf8( "uncheck to prevent closing/showing graphical dockable widgets by changing tabs in main window" )) self.actionDynamicWidgets.setObjectName( _fromUtf8("actionDynamicWidgets")) self.menuFile.addAction(self.actionImportDataFolder) self.menuFile.addAction(self.actionImportMetadata) self.menuFile.addAction(self.actionExportImages) self.menuFile.addAction(self.actionExportHdf5) self.menuFile.addSeparator() self.menuFile.addAction(self.actionQuit) self.menuEdit.addAction(self.actionClear) self.menuHelp.addAction(self.actionAbout) self.menuHelp.addAction(self.actionChangelog) self.menuHelp.addSeparator() self.menuHelp.addAction(self.actionAbout_Qt) self.menuView.addAction(self.actionDynamicWidgets) self.menuView.addSeparator() self.menubar.addAction(self.menuFile.menuAction()) self.menubar.addAction(self.menuEdit.menuAction()) self.menubar.addAction(self.menuView.menuAction()) self.menubar.addAction(self.menuHelp.menuAction()) self.toolBar.addAction(self.actionImportDataFolder) self.toolBar.addAction(self.actionImportMetadata) self.toolBar.addAction(self.actionExportImages) self.toolBar.addAction(self.actionExportHdf5) self.toolBar.addAction(self.actionClear) self.retranslateUi(MainWindow) self.tabWidget.setCurrentIndex(0) QtCore.QObject.connect(self.actionQuit, QtCore.SIGNAL(_fromUtf8("triggered()")), MainWindow.close) QtCore.QMetaObject.connectSlotsByName(MainWindow) MainWindow.setTabOrder(self.overviewComboBox, self.tabWidget) MainWindow.setTabOrder(self.tabWidget, self.treeDataTiles) MainWindow.setTabOrder(self.treeDataTiles, self.plainTextEdit) MainWindow.setTabOrder(self.plainTextEdit, self.treeParameters) MainWindow.setTabOrder(self.treeParameters, self.setAsDefault) MainWindow.setTabOrder(self.setAsDefault, self.filtersTreeView) MainWindow.setTabOrder(self.filtersTreeView, self.filterParamView) MainWindow.setTabOrder(self.filterParamView, self.treeFinalWidget) MainWindow.setTabOrder(self.treeFinalWidget, self.graphicalOverview) MainWindow.setTabOrder(self.graphicalOverview, self.graphicsView) MainWindow.setTabOrder(self.graphicsView, self.originalView) MainWindow.setTabOrder(self.originalView, self.filteredView) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle( _translate("MainWindow", "Exterminator-Stitchinator", None)) MainWindow.setWhatsThis( _translate( "MainWindow", "dont be silly, what is this? what is that? Are you serious?", None)) self.label_4.setText(_translate("MainWindow", "SAMPLE:", None)) self.label_2.setText(_translate("MainWindow", "data overview", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_tiles), _translate("MainWindow", "data", None)) self.setAsDefault.setText( _translate("MainWindow", "values to new temporary default", None)) self.tabWidget.setTabText( self.tabWidget.indexOf(self.tab_param), _translate("MainWindow", "stitching parameters", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_filters), _translate("MainWindow", "filters", None)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_finish), _translate("MainWindow", "finish", None)) self.menuFile.setTitle(_translate("MainWindow", "File", None)) self.menuEdit.setTitle(_translate("MainWindow", "Edit", None)) self.menuHelp.setTitle(_translate("MainWindow", "Help", None)) self.menuView.setTitle(_translate("MainWindow", "View", None)) self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar", None)) self.filterDockWidget.setWindowTitle( _translate("MainWindow", "Filtering preview:", None)) self.label_3.setText(_translate("MainWindow", "filtered:", None)) self.label.setText(_translate("MainWindow", "original:", None)) self.actionAbout.setText(_translate("MainWindow", "About", None)) self.actionImportDataFolder.setText( _translate("MainWindow", "import data folder", None)) self.actionImportDataFolder.setShortcut( _translate("MainWindow", "Ctrl+O", None)) self.actionImportMetadata.setText( _translate("MainWindow", "import metadata", None)) self.actionImportMetadata.setShortcut( _translate("MainWindow", "Ctrl+B", None)) self.actionExportHdf5.setText( _translate("MainWindow", "export as hdf5", None)) self.actionExportHdf5.setShortcut( _translate("MainWindow", "Ctrl+5", None)) self.actionExportImages.setText( _translate("MainWindow", "export as plain images", None)) self.actionExportImages.setShortcut( _translate("MainWindow", "Ctrl+I", None)) self.actionQuit.setText(_translate("MainWindow", "close", None)) self.actionQuit.setShortcut(_translate("MainWindow", "Ctrl+Q", None)) self.actionClear.setText( _translate("MainWindow", "clear everything", None)) self.actionChangelog.setText( _translate("MainWindow", "Changelog", None)) self.actionAbout_Qt.setText(_translate("MainWindow", "About Qt", None))
class GuiManager(QtGui.QMainWindow): def __init__(self): super(GuiManager, self).__init__() self.createLayout() def closeEvent(self, event): print 'User asked to close the app' self.stopAcquisition() Parameters.isAppKilled = True #time.sleep(0.1) #Wait for the worker death event.accept() # let the window close def startAcquisition(self): if Parameters.isConnected == False: return Parameters.isSaving = Parameters.paramObject.child( "Saving parameters", "saveResults").value() if Parameters.isSaving == True: theDate = datetime.datetime.today().strftime('%Y%m%d') theTime = datetime.datetime.today().strftime('%H%M%S') theName = Parameters.paramObject.child("Saving parameters", "Experiment name").value() #Check counter increment folderParent = 'C:/InterferometryResults/' + theDate counter = 1 folderFound = False theFolder = folderParent + '/' + theName + '_' + str( counter).zfill(3) if not os.path.exists(folderParent): #Make sure parent exist os.makedirs(folderParent) while folderFound == False and counter < 1000: #Loop until folder is found if not os.path.exists(theFolder): #Make sure parent exist os.makedirs(theFolder) folderFound = True else: counter = counter + 1 theFolder = folderParent + '/' + theName + '_' + str( counter).zfill(3) if counter < 1000: Parameters.savingFolder = theFolder if not os.path.exists(theFolder): os.makedirs(theFolder) else: Parameters.isSaving = False #Should not happen. self.btStart.setEnabled(False) self.btStop.setEnabled(True) self.btOpen.setEnabled(False) #Get the parameter values Parameters.nSamples = Parameters.paramObject.child( "Acquisition Parameters", "Number of samples to acquire").value() acqMode = Parameters.paramObject.child("Trigger Options", "Acquisition mode").value() triggerAmplitude = Parameters.paramObject.child( "Trigger Options", "Trigger amplitude").value() motorSpeed = Parameters.paramObject.child( "Acquisition Parameters", "Rotation speed (%)").value() + 28 #28 is calibration nBlocks = int(math.ceil(float(Parameters.nSamples) / 512)) #Must be a multiple of 512 Parameters.nSamples = nBlocks * 512 Parameters.paramObject.child("Acquisition Parameters", "Number of samples to acquire").setValue( Parameters.nSamples) #Set frequency in free mode. These settings could be optimized depending on the computer. freq = 2500000 #10im/s if Parameters.nSamples > 100352: freq = 5000000 #5im/s if Parameters.nSamples > 300032: freq = 12500000 #2im/s if Parameters.nSamples > 1000000: freq = 25000000 #1im/s if Parameters.nSamples > 2000000: freq = 50000000 #0.5im/s #Start the acquisition on the FPGA data = [] data = array('i') data.append(1) data.append(freq) data.append(2) data.append(acqMode) data.append(3) data.append(nBlocks) data.append(4) data.append(motorSpeed) data.append(5) data.append(triggerAmplitude) data.append(6) data.append(0) theBytes = struct.pack('i' * len(data), *data) buf = bytearray(theBytes) Parameters.dev.WriteToPipeIn(128, buf) Parameters.dev.SetWireInValue(0, 1 + 2 + 8, 1 + 2 + 8) Parameters.dev.UpdateWireIns( ) #Enable DDR2 reading and writing and activate memory. time.sleep(0.1) #Wait to make sure everything is ready. TODO: Reduce this. Parameters.dev.SetWireInValue(0, 4, 4) Parameters.dev.UpdateWireIns() #Start acquisition clock. #self.plotTr.enableAutoRange('xy', True) ## stop auto-scaling after the first data set is plotted Parameters.theQueue = Queue.Queue() #Create the queue #self.DisplayUpdater(0) self.workThread.start() #Start the display worker def stopAcquisition(self): print 'Stopping...' if hasattr(self, 'tDisplay'): self.tDisplay.cancel() self.workThread.exitWorker() while self.workThread.isRunning == True: time.sleep( 0.01) #Wait for the worker death, before resetting the board Parameters.dev.SetWireInValue(0, 0, 1 + 2 + 4 + 8) Parameters.dev.UpdateWireIns() #Reset board. #Save format: Results / YYMMDD / ExperimentName_Counter. Could also use the time. if Parameters.isSaving == True: #global state state = Parameters.paramObject.saveState() file = open(Parameters.savingFolder + '\Parameters.txt', 'w') pickle.dump(state, file) file.close() print 'Stopped.' self.btStart.setEnabled(True) self.btStop.setEnabled(False) self.btOpen.setEnabled(True) ''' def DisplayUpdater(self,dummy): if Parameters.isAppKilled == True: return; if Parameters.theQueue.empty(): print 'no data...' while not Parameters.theQueue.empty(): #Empty the display queue data = Parameters.theQueue.get() #print 'data available!' if 'data' in locals(): #print 'display data' + str(data[2]) self.setDataCurveTr(data) tDisplay = Timer(2, self.DisplayUpdater, [0],{}) tDisplay.start() ''' def motorSpeedChanged(self, value): newSpeed = Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").value() newSpeed = newSpeed + 28 #Calibration #Debug #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(enabled=False) #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(visible=False) #Parameters.paramObject.child("Acquisition Parameters", "Rotation speed (%)").setOpts(value=200) data = [] data = array('i') data.append(4) data.append(newSpeed) data.append(0) #Minimum size is 8 'int' data.append(0) data.append(0) data.append(0) data.append(0) data.append(0) theBytes = struct.pack('i' * len(data), *data) Parameters.bufferToDev = bytearray(theBytes) Parameters.bufferToDevReady = True def triggerChanged(self, value): acqMode = Parameters.paramObject.child("Trigger Options", "Acquisition mode").value() triggerAmplitude = Parameters.paramObject.child( "Trigger Options", "Trigger amplitude").value() data = [] data = array('i') data.append(2) data.append(acqMode) data.append(5) data.append(triggerAmplitude) data.append(0) data.append(0) data.append(0) data.append(0) theBytes = struct.pack('i' * len(data), *data) print str(theBytes) Parameters.bufferToDev = bytearray(theBytes) Parameters.bufferToDevReady = True def triggerHalfSwitch(self): Parameters.triggerToDev = True def saveParam(self): #global state state = Parameters.paramObject.saveState() file = open('dump.txt', 'w') pickle.dump(state, file) file.close() def restoreParam(self): #lobal state file = open('dump.txt', 'r') state = pickle.load(file) #add = Parameters.paramObject['Save/Restore functionality', 'Restore State', 'Add missing items'] #rem = Parameters.paramObject['Save/Restore functionality', 'Restore State', 'Remove extra items'] Parameters.paramObject.restoreState(state, addChildren=False, removeChildren=False) #Set the status text (system connected or not) def setStatus(self, isConnected, isError=False): def dotChange( item, nDots ): #Timer function to display a varying number of dots after "retrying" if Parameters.isConnected == True: return if Parameters.isAppKilled == True: return textNotConnected = "System not connected, retrying" item.setText(textNotConnected + ".") #Number of dots varies from 1 to 5 if nDots == 1: textDots = "." nDots = 2 elif nDots == 2: textDots = ".." nDots = 3 elif nDots == 3: textDots = "..." nDots = 4 elif nDots == 4: textDots = "...." nDots = 5 else: textDots = "....." nDots = 1 item.setForeground(QtGui.QColor("red")) item.setText(textNotConnected + textDots) self.timerDotChange = Timer(0.25, dotChange, [self.itemStatus, nDots]) self.timerDotChange.start() if (isError == True): #System not connected print "Error" if hasattr(self, 'timerDotChange'): self.timerDotChange.cancel() time.sleep(0.5) self.itemStatus.setForeground(QtGui.QColor("red")) self.itemStatus.setText( "Error with system. Please restart the application and the system." ) elif (isConnected == False): #System not connected nDots = 1 if hasattr(self, 'timerDotChange'): self.timerDotChange.cancel() self.timerDotChange = Timer(0.25, dotChange, [self.itemStatus, nDots]) self.timerDotChange.start() else: print "Connected" if hasattr(self, 'timerDotChange'): self.timerDotChange.cancel() time.sleep(0.1) self.itemStatus.setForeground(QtGui.QColor("green")) self.itemStatus.setText("System connected.") print "Connected2" #Set the status text (system connected or not) def setCameraStatus(self, isConnected): def dotChange( item, nDots ): #Timer function to display a varying number of dots after "retrying" if Parameters.isCameraConnected == True: return if Parameters.isAppKilled == True: return textNotConnected = "Camera not connected, retrying" item.setText(textNotConnected + ".") #Number of dots varies from 1 to 5 if nDots == 1: textDots = "." nDots = 2 elif nDots == 2: textDots = ".." nDots = 3 elif nDots == 3: textDots = "..." nDots = 4 elif nDots == 4: textDots = "...." nDots = 5 else: textDots = "....." nDots = 1 item.setForeground(QtGui.QColor("red")) item.setText(textNotConnected + textDots) self.timerDotChangeCamera = Timer(0.25, dotChange, [self.itemCameraStatus, nDots]) self.timerDotChangeCamera.start() if (isConnected == False): #System not connected print 'cam oups' nDots = 1 if hasattr(self, 'timerDotChangeCamera'): self.timerDotChangeCamera.cancel() self.timerDotChangeCamera = Timer(0.25, dotChange, [self.itemCameraStatus, nDots]) self.timerDotChangeCamera.start() else: print "Camera connected" if hasattr(self, 'timerDotChangeCamera'): self.timerDotChangeCamera.cancel() time.sleep(0.1) self.itemCameraStatus.setForeground(QtGui.QColor("green")) self.itemCameraStatus.setText("Camera connected.") print "Camera connected2" #Set the status text (system connected or not) def setInfo(self, text): self.tbInfo.append(text) #Set the status text (system connected or not) def setWire(self, mem1, mem2, mem3, mem4, maxValPos): self.itemMemory.setText("Acquisition board memory usage:\nDDR2: " + str(mem1) + " bytes.\nFIFO in: " + str(mem2) + " bytes.\nFIFO out: " + str(mem3) + " bytes.\nFIFO out (minimum): " + str(mem4) + " bytes.") self.itemMaxValPos.setText("Maximum RF value position: " + str(maxValPos)) def createLayout(self): print 'Creating layout...' self.setWindowTitle('Interferometry Acquisition GUI') #self.widget = QtGui.QWidget() #self.setCentralWidget(self.widget) self.layout = pg.LayoutWidget() #self.widget.setLayout(self.layout) self.setCentralWidget(self.layout) #Create GUI sizePolicyBt = QtGui.QSizePolicy(1, 1) sizePolicyBt.setHorizontalStretch(0) sizePolicyBt.setVerticalStretch(0) self.btOpen = QtGui.QPushButton("Open\nprevious results") sizePolicyBt.setHeightForWidth( self.btOpen.sizePolicy().hasHeightForWidth()) self.btOpen.setSizePolicy(sizePolicyBt) self.btOpen.setStyleSheet( "background-color: yellow; font-size: 16px; font: bold") self.btStart = QtGui.QPushButton("Start\nacquisition") sizePolicyBt.setHeightForWidth( self.btStart.sizePolicy().hasHeightForWidth()) self.btStart.setSizePolicy(sizePolicyBt) self.btStart.setStyleSheet( "background-color: green; font-size: 16px; font: bold") self.btStart.clicked.connect(self.startAcquisition) self.btStop = QtGui.QPushButton("Stop\nacquisition") sizePolicyBt.setHeightForWidth( self.btStop.sizePolicy().hasHeightForWidth()) self.btStop.setSizePolicy(sizePolicyBt) self.btStop.setStyleSheet( "background-color: red; font-size: 16px; font: bold") self.btStop.clicked.connect(self.stopAcquisition) self.btStop.setEnabled(False) self.paramTree = ParameterTree() self.paramTree.setParameters(Parameters.paramObject, showTop=False) self.paramTree.setWindowTitle('pyqtgraph example: Parameter Tree') self.paramTree.setMinimumWidth(350) self.paramTree.setMaximumWidth(350) sizePolicyPt = QtGui.QSizePolicy(1, 1) sizePolicyPt.setHorizontalStretch(QtGui.QSizePolicy.Fixed) sizePolicyPt.setVerticalStretch(1) self.paramTree.setSizePolicy(sizePolicyPt) ## Create random 2D data data = np.random.normal(size=( 512, 512)) + pg.gaussianFilter(np.random.normal(size=(512, 512)), (5, 5)) * 20 + 100 data = data[:, :, np.newaxis] data = data.repeat(3, 2) self.plotTl = pg.GraphicsView() self.plotTlImage = pg.ImageItem(data[:, :, :]) #parent=self.plotTl self.plotTlViewBox = pg.ViewBox() self.plotTl.setCentralWidget(self.plotTlViewBox) self.plotTlViewBox.addItem(self.plotTlImage) self.plotTr = pg.PlotWidget(title="Interferometry", labels={ 'left': 'Signal amplitude (A.U.)', 'bottom': 'Distance (mm)' }) #self.plotTlViewBox2.addItem(self.plotTr) self.plotTrCurve = self.plotTr.plot(pen=(255, 0, 0), name='C1') #Red self.plotTrCurve2 = self.plotTr.plot(pen=(0, 255, 0), name='C2') #Green #self.plotTlViewBox2.enableAutoRange('xy', True) ## stop auto-scaling after the first data set is plotted #self.plotTr.addLegend('Test') self.plotTr.setYRange(-1000, 1000) self.plotBl = pg.PlotWidget(title="Distance", labels={ 'left': 'Distance (mm)', 'bottom': 'Number of acquisitions' }) self.plotBlCurve = self.plotBl.plot(pen=(255, 0, 0), name='C1') self.plotBl.enableAutoRange( 'xy', True) ## stop auto-scaling after the first data set is plotted self.plotBl.setMaximumWidth(3500) self.tbInfo = QtGui.QTextEdit() self.tbInfo.setEnabled(False) palette = self.tbInfo.palette() palette.setColor(QtGui.QPalette.Base, QtGui.QColor("white")) #White background self.tbInfo.setPalette(palette) self.tbInfo.setTextColor(QtGui.QColor("black")) self.tbInfo.insertPlainText("Useful information will appear here.") #Create list view of multiple items self.tbStatus = QtGui.QListView() self.tbStatus.setEnabled(False) palette = self.tbStatus.palette() palette.setColor(QtGui.QPalette.Base, QtGui.QColor("white")) #White background self.tbStatus.setPalette(palette) itemModelStatus = QtGui.QStandardItemModel(self.tbStatus) self.tbStatus.setModel(itemModelStatus) #Add system status self.itemStatus = QtGui.QStandardItem() self.setStatus(False) itemModelStatus.appendRow(self.itemStatus) #Add camera status self.itemCameraStatus = QtGui.QStandardItem() self.setCameraStatus(False) itemModelStatus.appendRow(self.itemCameraStatus) #Add memory usage self.itemMemory = QtGui.QStandardItem( "Acquisition board memory usage: N/A") self.itemMemory.setForeground(QtGui.QColor("black")) itemModelStatus.appendRow(self.itemMemory) #Add max value position self.itemMaxValPos = QtGui.QStandardItem( "Maximum RF value position: N/A") self.itemMaxValPos.setForeground(QtGui.QColor("black")) itemModelStatus.appendRow(self.itemMaxValPos) #layout.addWidget(QtGui.QLabel("These are two views of the same data. They should always display the same values."), 0, 0, 1, 2) self.layout.addWidget(self.btOpen, 9, 6, 1, 1) self.layout.addWidget(self.btStart, 9, 7, 1, 1) self.layout.addWidget(self.btStop, 9, 8, 1, 1) self.layout.addWidget(self.paramTree, 0, 0, 10, 3) self.layout.addWidget(self.plotTl, 0, 3, 5, 3) self.layout.addWidget(self.plotTr, 0, 6, 5, 3) self.layout.addWidget(self.plotBl, 5, 3, 5, 3) self.layout.addWidget(self.tbInfo, 5, 6, 2, 3) self.layout.addWidget(self.tbStatus, 7, 6, 2, 3) self.layout.layout.setColumnStretch(3, 1) self.layout.layout.setColumnStretch(4, 1) self.layout.layout.setColumnStretch(5, 1) self.layout.layout.setColumnStretch(6, 1) self.layout.layout.setColumnStretch(7, 1) self.layout.layout.setColumnStretch(8, 1) self.show() self.resize(1500, 800) self.move(100, 100) Parameters.paramObject.param('Save/Restore functionality', 'Save State').sigActivated.connect( self.saveParam) Parameters.paramObject.param('Save/Restore functionality', 'Restore State').sigActivated.connect( self.restoreParam) Parameters.paramObject.child( "Acquisition Parameters", "Rotation speed (%)").sigValueChanged.connect( self.motorSpeedChanged) Parameters.paramObject.child( "Trigger Options", "Acquisition mode").sigValueChanged.connect(self.triggerChanged) Parameters.paramObject.child( "Trigger Options", "Trigger amplitude").sigValueChanged.connect(self.triggerChanged) Parameters.paramObject.child( "Trigger Options", "Trigger switch 1/2").sigActivated.connect(self.triggerHalfSwitch) # adding by emitting signal in different thread self.workThread = AcquisitionWorker() self.workThread.updateDataCamera.connect(self.setDataCurveTl) self.workThread.updateDataInterf.connect(self.setDataCurveTr) self.workThread.updateDataDistance.connect(self.setDataCurveBl) self.workThread.updateDataDistance2.connect(self.setDataCurveBl2) self.workThread.updateWire.connect(self.setWire) self.workThread.setStatus.connect(self.setStatus) self.workThread.setInfo.connect(self.setInfo) self.testCount = 0 #Fill the plots with dummy data self.data = np.random.normal(size=(10, 1000)) self.plotTrXAxis = np.arange(1000) * (0.01) self.plotBlXAxis = np.arange(1000) * (1) self.plotTrCurve.setData(x=self.plotTrXAxis, y=self.data[2 % 10], name='C1') self.plotTrCurve2.setData(x=self.plotTrXAxis, y=self.data[3 % 10], name='C2') self.plotBlCurve.setData(x=self.plotBlXAxis, y=self.data[4 % 10], name='C1') self.valueTest = 1 def setDataCurveTl(self, data): self.dataImage1 = data self.plotTlImage.setImage(data) self.testCount = self.testCount + 1 def setDataCurveTr(self, dataIn): self.plotTrCurve.setData(dataIn[0:len(dataIn):2], name='C1') self.plotTrCurve2.setData(dataIn[1:len(dataIn):2], name='C2') def setDataCurveBl(self, dataIn): self.plotBlCurve.setData(dataIn, name='C1') def setDataCurveBl2(self, xIn, dataIn): self.plotBlCurve.setData(x=xIn, y=dataIn, name='C1')