def openFile(self, filename): filename = str(filename) traceCollection = TraceCollection() traceCollection.filename = filename traceCollection.filepath, traceCollection.fileleaf = os.path.split(filename) self.settings.lastDir = traceCollection.filepath traceCollection.name = traceCollection.fileleaf traceCollection.saved = True traceCollection.loadTrace(filename) if traceCollection.description["name"] != "": traceCollection.name = traceCollection.description["name"] for node in list(self.model.traceDict.values()): dataNode=self.model.getFirstDataNode(node) existingTraceCollection=dataNode.content.traceCollection if existingTraceCollection.fileleaf==traceCollection.fileleaf and str(existingTraceCollection.traceCreation)==str(traceCollection.traceCreation): return #If the filename and creation dates are the same, you're trying to open an existing trace. plottedTraceList = list() category = None if len(traceCollection.tracePlottingList)==1 else self.getUniqueCategory(filename) for plotting in traceCollection.tracePlottingList: windowName = plotting.windowName if plotting.windowName in self.graphicsViewDict else list(self.graphicsViewDict.keys())[0] name = plotting.name plottedTrace = PlottedTrace(traceCollection, self.graphicsViewDict[windowName]['view'], pens.penList, -1, tracePlotting=plotting, windowName=windowName, name=name) plottedTrace.category = category plottedTraceList.append(plottedTrace) self.addTrace(plottedTrace, -1) if self.expandNew: self.expand(plottedTraceList[0]) self.resizeColumnsToContents() return plottedTraceList
def startLogging(self): self.trace = TraceCollection() # self.trace.addColumn('voltage_2') # self.trace.addColumn('voltage_3') # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_3', penList=pens.penList ) self.voltagePlottedTrace = PlottedTrace( self.trace, self.plotDict['Voltage']['view'], yColumn='voltage', penList=pens.penList) # self.voltagePlottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_2', penList=pens.penList ) # self.voltagePlottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) self.voltagePlottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot(0, self.takeLoggingPoint) self.loggingActive = True self.startTime = time.time()
def onData(self, data): if data.errorSig and data.frequency: errorSig = list(map( binToVoltageV, data.errorSig )) if self.trace is None: self.trace = TraceCollection() self.trace.name = "Scope" self.trace.x = numpy.arange(len(errorSig)) * (sampleTime.m_as('us') * (1 + int(self.traceSettings.subsample))) self.trace.y = numpy.array( errorSig ) if self.errorSigCurve is None: self.errorSigCurve = PlottedTrace(self.trace, self.plotDict[self.traceSettings.errorSigPlot]['view'], pen=-1, style=PlottedTrace.Styles.lines, name="Error Signal", #@UndefinedVariable windowName=self.traceSettings.errorSigPlot) self.errorSigCurve.plot() self.traceui.addTrace( self.errorSigCurve, pen=-1 ) else: self.errorSigCurve.replot() self.newDataAvailable.emit( self.trace ) frequency = list(map( binToFreqHz, data.frequency )) self.trace['freq'] = numpy.array( frequency ) if self.freqCurve is None: self.freqCurve = PlottedTrace(self.trace, self.plotDict[self.traceSettings.frequencyPlot]['view'], pen=-1, style=PlottedTrace.Styles.lines, name="Frequency", #@UndefinedVariable xColumn='x', yColumn='freq', windowName=self.traceSettings.frequencyPlot ) self.freqCurve.plot() self.traceui.addTrace( self.freqCurve, pen=-1 ) else: self.freqCurve.replot() if self.state==self.StateOptions.running: QtCore.QTimer.singleShot(10, self.delayedArm ) # wait 10ms before re-arming else: self.setState(self.StateOptions.stopped)
def startScan(self): if not self.scanRunning: self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) if self.meterState.scanType in [4, 5]: index = find_index_nearest(self.scanList, self.meterState.voltage) self.scanList = numpy.roll(self.scanList, -index) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) # self.meter_2.setZeroCheck(False) # self.meter_3.setZeroCheck(False) self.meter.voltageEnable(True) # self.meter_2.voltageEnable(True) # self.meter_3.voltageEnable(True) self.stopRequested = False print("startScan") self.scanRunning = True QtCore.QTimer.singleShot(0, self.initPoint)
def startLogging(self): self.trace = TraceCollection() self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot( 0, self.takeLoggingPoint ) self.loggingActive = True self.startTime = time.time()
def startScan(self): self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) self.meter.voltageEnable(True) self.stopRequested = False QtCore.QTimer.singleShot(0, self.initPoint )
def addPoint(self, traceui, plot, data, source): takentime, value, minval, maxval = data if is_Q(value): value, unit = value.m, "{:~}".format(value.units) if is_Q(minval): minval = minval.m, "{:~}".format(minval.units) if is_Q(maxval): maxval = maxval.m, "{:~}".format(maxval.units) if not isinstance(value, str): #ignore erroneous values like 'oor' if self.trace is None: self.trace = TraceCollection(record_timestamps=True) self.trace.name = source self.trace.x = numpy.array([takentime]) self.trace.y = numpy.array([value]) if maxval is not None: self.trace.top = numpy.array([maxval - value]) if minval is not None: self.trace.bottom = numpy.array([value - minval]) self.plottedTrace = PlottedTrace(self.trace, plot, pens.penList, xAxisUnit="s", xAxisLabel="time", windowName=self.plotName) # self.plottedTrace.trace.filenameCallback = functools.partial( WeakMethod.ref(self.plottedTrace.traceFilename), self.filename ) traceui.addTrace(self.plottedTrace, pen=-1) traceui.resizeColumnsToContents() else: if self.maximumPoints == 0 or len( self.trace.x) < self.maximumPoints: self.trace.x = numpy.append(self.trace.x, takentime) self.trace.y = numpy.append(self.trace.y, value) if maxval is not None: self.trace.top = numpy.append(self.trace.top, maxval - value) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom, value - minval) else: maxPoints = int(self.maximumPoints) self.trace.x = numpy.append(self.trace.x[-maxPoints:], takentime) self.trace.y = numpy.append(self.trace.y[-maxPoints:], value) if maxval is not None: self.trace.top = numpy.append( self.trace.top[-maxPoints:], maxval - value) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom[-maxPoints:], value - minval) self.plottedTrace.replot()
def onCreateTrace(self, traceCreationData): traceCreationData = list(map(str, traceCreationData)) [traceName, plotName, xUnit, xLabel, comment] = traceCreationData if plotName not in self.scanExperiment.plotDict: message = "plot {0} does not exist".format(plotName) error = True else: traceCollection = TraceCollection() yColumnName = 'y0' plottedTrace = PlottedTrace( traceCollection, self.scanExperiment.plotDict[plotName]["view"], pens.penList, xColumn='x', yColumn=yColumnName, name=traceName, xAxisUnit=xUnit, xAxisLabel=xLabel, windowName=plotName) self.scanExperiment.plotDict[plotName]["view"].enableAutoRange( axis=ViewBox.XAxis) plottedTrace.traceCollection.name = self.script.shortname commentIntro = "Created by script {0}".format( self.script.shortname) plottedTrace.traceCollection.comment = commentIntro + " -- " + comment if comment else commentIntro plottedTrace.traceCollection.autoSave = True plottedTrace.traceCollection.filenamePattern = traceName self.scriptTraces[traceName] = plottedTrace self.traceAlreadyCreated[ traceName] = False #Keep track of whether the trace has already been added error = False message = "Added trace {0}\n plot: {1}\n xUnit: {2}\n xLabel: {3}\n comment: {4}".format( traceName, plotName, xUnit, xLabel, comment) return (error, message)
def startScan(self): if not self.scanRunning: self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) if self.meterState.scanType in [4, 5]: index = find_index_nearest(self.scanList, self.meterState.voltage) self.scanList = numpy.roll( self.scanList, -index) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList ) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) # self.meter_2.setZeroCheck(False) # self.meter_3.setZeroCheck(False) self.meter.voltageEnable(True) # self.meter_2.voltageEnable(True) # self.meter_3.voltageEnable(True) self.stopRequested = False print("startScan") self.scanRunning = True QtCore.QTimer.singleShot(0, self.initPoint )
def doCreatePlot(self, space, parameter, fromTime, toTime, plotName, steps, forceUpdate=False ): ref, _ = self.cache.get( ( space, parameter ), (lambda: None, None)) plottedTrace = ref() if (self.parameters.updatePrevious or forceUpdate) else None # get plottedtrace from the weakref if exists result = self.connection.getHistory( space, parameter, fromTime, toTime ) if not result: logging.getLogger(__name__).warning("Database query returned empty set") elif len(result)>0: #time = [(pytz.utc.localize(e.upd_date) - datetime(1970,1,1, tzinfo=pytz.utc)).total_seconds() for e in result] if result[0].upd_date.tzinfo is not None: time = [(e.upd_date - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds() for e in result] else: time = [(e.upd_date-datetime.fromtimestamp(0)).total_seconds() for e in result] value = [e.value for e in result] bottom = [e.value - e.bottom if e.bottom is not None else e.value for e in result] top = [e.top -e.value if e.top is not None else e.value for e in result] if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = parameter + "_Query" trace.y = numpy.array( value ) if plotName is None: plotName = str(self.comboBoxPlotName.currentText()) if steps: trace.x = numpy.array( time+[time[-1]] ) plottedTrace = PlottedTrace( trace, self.plotDict[plotName]["view"], xAxisLabel = "local time", plotType=PlottedTrace.Types.steps, fill=False, windowName=plotName) #@UndefinedVariable else: trace.x = numpy.array( time ) trace.top = numpy.array( top ) trace.bottom = numpy.array( bottom ) plottedTrace = PlottedTrace( trace, self.plotDict[plotName]["view"], xAxisLabel = "local time", windowName=plotName) plottedTrace.trace.autoSave = self.traceui.autoSaveTraces plottedTrace.name = trace.name plottedTrace.trace.filenamePattern = trace.name if not plottedTrace.trace.autoSave: self.unsavedTraceCount+=1 self.traceui.addTrace( plottedTrace, pen=-1) self.traceui.resizeColumnsToContents() self.cache[(space, parameter)] = ( weakref.ref(plottedTrace), (space, parameter, fromTime, toTime, plotName, steps) ) else: # update the existing plotted trace trace = plottedTrace.trace trace.y = numpy.array( value ) if steps: trace.x = numpy.array( time+[time[-1]] ) else: trace.x = numpy.array( time ) trace.top = numpy.array( top ) trace.bottom = numpy.array( bottom ) plottedTrace.replot()
def plotData(self): if len(self.lastLockData)>0: to_plot = list(zip(*(attrgetter('errorSigAvg', 'errorSigMin', 'errorSigMax', 'time')(e) for e in self.lastLockData))) x = numpy.arange( self.lastXValue, self.lastXValue+len(to_plot[0] )) self.lastXValue += len(to_plot[0] ) y = numpy.array([v.m_as('V') for v in to_plot[0]]) bottom = numpy.array([(v0 - v1).m_as('V') for v0, v1 in zip(to_plot[0], to_plot[1])]) top = numpy.array([(v2 - v0).m_as('V') for v0, v2 in zip(to_plot[0], to_plot[2])]) if self.trace is None: self.trace = TraceCollection() self.trace['x'] = x self.trace['y'] = y self.trace['bottom'] = bottom self.trace['top'] = top self.trace.name = "History" else: self.trace['x'] = rollingUpdate(self.trace['x'], x, self.settings.maxSamples) self.trace['y'] = rollingUpdate(self.trace['y'], y, self.settings.maxSamples) self.trace['bottom'] = rollingUpdate(self.trace['bottom'], bottom, self.settings.maxSamples) self.trace['top'] = rollingUpdate(self.trace['top'], top, self.settings.maxSamples) if self.errorSigCurve is None: self.errorSigCurve = PlottedTrace(self.trace, self.plotDict[self.settings.errorSigPlot]['view'], pen=-1, style=PlottedTrace.Styles.points, name="Error Signal", windowName=self.settings.errorSigPlot) #@UndefinedVariable self.errorSigCurve.plot() self.traceui.addTrace( self.errorSigCurve, pen=-1 ) else: self.errorSigCurve.replot() to_plot = list(zip(*(attrgetter('regulatorFrequency', 'referenceFrequencyMin', 'referenceFrequencyMax')(e) for e in self.lastLockData))) y = numpy.array([v.m_as('Hz') for v in to_plot[0]]) bottom = numpy.array([(v0 - v1).m_as('Hz') for v0, v1 in zip(to_plot[0], to_plot[1])]) top = numpy.array([(v2 - v0).m_as('Hz') for v0, v2 in zip(to_plot[0], to_plot[2])]) self.trace['freq'] = rollingUpdate(self.trace['freq'], y, self.settings.maxSamples) self.trace['freqBottom'] = rollingUpdate(self.trace['freqBottom'], bottom, self.settings.maxSamples) self.trace['freqTop'] = rollingUpdate(self.trace['freqTop'], top, self.settings.maxSamples) if self.freqCurve is None: self.freqCurve = PlottedTrace(self.trace, self.plotDict[self.settings.frequencyPlot]['view'], pen=-1, style=PlottedTrace.Styles.points, name="Repetition rate", #@UndefinedVariable xColumn='x', yColumn='freq', topColumn='freqTop', bottomColumn='freqBottom', windowName=self.settings.frequencyPlot) self.freqCurve.plot() self.traceui.addTrace( self.freqCurve, pen=-1 ) else: self.freqCurve.replot()
def openFile(self, filename): filename = str(filename) traceCollection = TraceCollection() traceCollection.filename = filename traceCollection.filepath, traceCollection.fileleaf = os.path.split( filename) self.settings.lastDir = traceCollection.filepath traceCollection.name = traceCollection.fileleaf traceCollection.saved = True traceCollection.loadTrace(filename) if traceCollection.description["name"] != "": traceCollection.name = traceCollection.description["name"] for node in list(self.model.traceDict.values()): dataNode = self.model.getFirstDataNode(node) existingTraceCollection = dataNode.content.traceCollection if existingTraceCollection.fileleaf == traceCollection.fileleaf and str( existingTraceCollection.traceCreation) == str( traceCollection.traceCreation): return #If the filename and creation dates are the same, you're trying to open an existing trace. plottedTraceList = list() category = None if len(traceCollection.tracePlottingList ) == 1 else self.getUniqueCategory(filename) for plotting in traceCollection.tracePlottingList: windowName = plotting.windowName if plotting.windowName in self.graphicsViewDict else list( self.graphicsViewDict.keys())[0] name = plotting.name plottedTrace = PlottedTrace( traceCollection, self.graphicsViewDict[windowName]['view'], pens.penList, -1, tracePlotting=plotting, windowName=windowName, name=name) plottedTrace.category = category plottedTraceList.append(plottedTrace) self.addTrace(plottedTrace, -1) if self.expandNew: self.expand(plottedTraceList[0]) self.resizeColumnsToContents() return plottedTraceList
def startScan(self): if self.plottedTrace is not None and self.traceui.unplotLastTrace(): self.plottedTrace.plot(0) self.plottedTrace = PlottedTrace(TraceCollection(), self._graphicsView, pens.penList) self.xvalue = 0 self.phase = 0 #random.uniform(0,2*numpy.pi) self.plottedTrace.trace.x = numpy.array([self.xvalue]) c = numpy.sin( self.xvalue + self.phase)**2 self.plottedTrace.trace.y = numpy.array([random.gauss(c, 0.1)])#c*(1-c))]) self.plottedTrace.trace.top = numpy.array([0.05]) self.plottedTrace.trace.bottom = numpy.array([0.05]) self.plottedTrace.trace.filenameCallback = functools.partial( self.traceFilename, '' ) if self.scanType == 0: self.plottedTrace.trace.name = "test trace" self.plottedTrace.trace.description["comment"] = "My Comment" self.traceui.addTrace(self.plottedTrace, pen=-1) #start added elif self.scanType == 1: self.traceui.addTrace(self.plottedTrace, pen=-1, parentTrace=self.averagePlottedTrace) self.plottedTrace.trace.name = "test trace {0}".format(self.averagePlottedTrace.childCount()) self.plottedTrace.trace.description["comment"] = "My Comment {0}".format(self.averagePlottedTrace.childCount())
def startLogging(self): self.trace = TraceCollection() # self.trace.addColumn('voltage_2') # self.trace.addColumn('voltage_3') # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList ) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_3', penList=pens.penList ) self.voltagePlottedTrace = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage', penList=pens.penList ) # self.voltagePlottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_2', penList=pens.penList ) # self.voltagePlottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.voltagePlottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot( 0, self.takeLoggingPoint ) self.loggingActive = True self.startTime = time.time()
def addPoint(self, traceui, plot, data, source ): takentime, value, minval, maxval = data if is_Q(value): value, unit = value.m, "{:~}".format(value.units) if is_Q(minval): minval = minval.m, "{:~}".format(minval.units) if is_Q(maxval): maxval = maxval.m, "{:~}".format(maxval.units) if not isinstance(value, str): #ignore erroneous values like 'oor' if self.trace is None: self.trace = TraceCollection(record_timestamps=True) self.trace.name = source self.trace.x = numpy.array( [takentime] ) self.trace.y = numpy.array( [value] ) if maxval is not None: self.trace.top = numpy.array( [maxval - value]) if minval is not None: self.trace.bottom = numpy.array( [value - minval]) self.plottedTrace = PlottedTrace(self.trace, plot, pens.penList, xAxisUnit = "s", xAxisLabel = "time", windowName=self.plotName) # self.plottedTrace.trace.filenameCallback = functools.partial( WeakMethod.ref(self.plottedTrace.traceFilename), self.filename ) traceui.addTrace( self.plottedTrace, pen=-1) traceui.resizeColumnsToContents() else: if self.maximumPoints==0 or len(self.trace.x)<self.maximumPoints: self.trace.x = numpy.append( self.trace.x, takentime ) self.trace.y = numpy.append( self.trace.y, value ) if maxval is not None: self.trace.top = numpy.append( self.trace.top, maxval - value ) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom, value - minval ) else: maxPoints = int(self.maximumPoints) self.trace.x = numpy.append( self.trace.x[-maxPoints:], takentime ) self.trace.y = numpy.append( self.trace.y[-maxPoints:], value ) if maxval is not None: self.trace.top = numpy.append( self.trace.top[-maxPoints:], maxval - value ) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom[-maxPoints:], value - minval ) self.plottedTrace.replot()
def doCreatePlot(self, xDataDef, yDataDef, plotName, update=False ): ref, _ = self.cache.get( ( xDataDef, yDataDef ), (lambda: None, None)) plottedTrace = ref() if update else None # get plottedtrace from the weakref if exists # Assemble data xData, yData, bottomData, topData = self.getData(xDataDef, yDataDef) if len(xData)==0: logging.getLogger(__name__).warning("Nothing to plot") else: if xDataDef==('measurement', None, 'startDate'): epoch = datetime(1970, 1, 1) - timedelta(seconds=self.utcOffset) if xData[0].tzinfo is None else datetime(1970, 1, 1).replace(tzinfo=pytz.utc) time = numpy.array([(value - epoch).total_seconds() for value in xData]) if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = "{0} versus {1}".format( yDataDef[2], xDataDef[2 ]) _, yUnit = (None, self.settings.yUnit) if self.settings.yUnit else (yData[0].m, "{:~}".format(yData[0].units)) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = time if topData is not None and bottomData is not None: trace.top = numpy.array([d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array([d.m_as(yUnit) for d in bottomData]) traceui, item, view = self.plotWindowIndex[plotName] plottedTrace = PlottedTrace( trace, view, xAxisLabel = "local time", windowName=item) #plottedTrace.trace.filenameCallback = partial( WeakMethod.ref(plottedTrace.traceFilename), "" ) traceui.addTrace( plottedTrace, pen=-1) traceui.resizeColumnsToContents() self.cache[(xDataDef, yDataDef)] = ( weakref.ref(plottedTrace), (xDataDef, yDataDef, plotName) ) trace.description["traceFinalized"] = datetime.now(pytz.utc) else: # update the existing plotted trace trace = plottedTrace.trace _, yUnit = (None, self.settings.yUnit) if self.settings.yUnit else mag_unit(yData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = time if topData is not None and bottomData is not None: trace.top = numpy.array([d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array([d.m_as(yUnit) for d in bottomData]) trace.description["traceFinalized"] = datetime.now(pytz.utc) plottedTrace.replot() else: if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = "{0} versus {1}".format( yDataDef[2], xDataDef[2 ]) _, yUnit = (None, self.settings.yUnit) if self.settings.yUnit else mag_unit(yData[0]) _, xUnit = (None, self.settings.xUnit) if self.settings.xUnit else mag_unit(xData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = numpy.array([d.m_as(xUnit) for d in xData]) if topData is not None and bottomData is not None: trace.top = numpy.array([d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array([d.m_as(yUnit) for d in bottomData]) traceui, item, view = self.plotWindowIndex[plotName] plottedTrace = PlottedTrace( trace, view, xAxisLabel = xDataDef[2], windowName=item) traceui.addTrace( plottedTrace, pen=-1) traceui.resizeColumnsToContents() self.cache[(xDataDef, yDataDef)] = ( weakref.ref(plottedTrace), (xDataDef, yDataDef, plotName) ) trace.description["traceFinalized"] = datetime.now(pytz.utc) else: # update the existing plotted trace trace = plottedTrace.trace _, yUnit = (None, self.settings.yUnit) if self.settings.yUnit else mag_unit(yData[0]) _, xUnit = (None, self.settings.xUnit) if self.settings.xUnit else mag_unit(xData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = numpy.array([d.m_as(xUnit) for d in xData]) if topData is not None and bottomData is not None: trace.top = numpy.array([d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array([d.m_as(yUnit) for d in bottomData]) plottedTrace.replot() trace.description["traceFinalized"] = datetime.now(pytz.utc)
class DataHandling(object): def __init__(self): self.calibration = None self.decimation = None self.persistenceDecimation = None self.plotName = None self.persistence = None self.calibrationCache = dict() self.decimationCache = dict() self.persistenceCache = dict() self.persistenceDecimationCache = dict() self.trace = None self.plottedTrace = None self.filename = None self.maximumPoints = 0 @property def decimationClass(self): return self.decimation.name if self.decimation else 'None' @decimationClass.setter def decimationClass(self, name): if self.decimation is not None: self.decimationCache[self.decimation.name] = self.decimation self.decimation = self.decimationCache.get( name, decimationDict[name]()) if name != 'None' else None self.trace = None @property def persistenceDecimationClass(self): return self.persistenceDecimation.name if self.persistenceDecimation else 'None' @persistenceDecimationClass.setter def persistenceDecimationClass(self, name): if self.persistenceDecimation is not None: self.persistenceDecimationCache[ self.persistenceDecimation.name] = self.persistenceDecimation self.persistenceDecimation = self.persistenceDecimationCache.get( name, decimationDict[name]()) if name != 'None' else None @property def calibrationClass(self): return self.decimation.name if self.calibration else 'None' @calibrationClass.setter def calibrationClass(self, name): if self.calibration is not None: self.calibrationCache[self.calibration.name] = self.calibration self.calibration = self.calibrationCache.get( name, calibrationDict[name]()) if name != 'None' else None @property def persistenceClass(self): return self.persistence.name if self.persistence else 'None' @persistenceClass.setter def persistenceClass(self, name): if self.persistence is not None: self.persistenceCache[self.persistence.name] = self.persistence self.persistence = self.persistenceCache.get( name, persistenceDict[name]()) if name != 'None' else None def __getstate__(self): odict = self.__dict__.copy() del odict['trace'] del odict['plottedTrace'] return odict def __setstate__(self, state): self.__dict__.update(state) self.trace = None self.plottedTrace = None def finishTrace(self): self.trace = None def decimate(self, takentime, value, callback): if value is not None: if self.decimation is None: callback((takentime, value, None, None)) else: self.decimation.decimate(takentime, value, callback) def persistenceDecimate(self, takentime, value, callback): if self.persistenceDecimation is None: callback((takentime, value, None, None)) else: self.persistenceDecimation.decimate(takentime, value, callback) def persist(self, space, source, time, value, minvalue, maxvalue): if self.persistence is not None: self.persistence.persist(space, source, time, value, minvalue, maxvalue) def convert(self, data): takentime, value, minVal, maxVal = data if self.calibration is None: return data calMin = self.calibration.convertMagnitude(minVal) calMax = self.calibration.convertMagnitude(maxVal) calValue = self.calibration.convertMagnitude(value) return (takentime, calValue, calMin, calMax) def addPoint(self, traceui, plot, data, source): takentime, value, minval, maxval = data if is_Q(value): value, unit = value.m, "{:~}".format(value.units) if is_Q(minval): minval = minval.m, "{:~}".format(minval.units) if is_Q(maxval): maxval = maxval.m, "{:~}".format(maxval.units) if not isinstance(value, str): #ignore erroneous values like 'oor' if self.trace is None: self.trace = TraceCollection(record_timestamps=True) self.trace.name = source self.trace.x = numpy.array([takentime]) self.trace.y = numpy.array([value]) if maxval is not None: self.trace.top = numpy.array([maxval - value]) if minval is not None: self.trace.bottom = numpy.array([value - minval]) self.plottedTrace = PlottedTrace(self.trace, plot, pens.penList, xAxisUnit="s", xAxisLabel="time", windowName=self.plotName) # self.plottedTrace.trace.filenameCallback = functools.partial( WeakMethod.ref(self.plottedTrace.traceFilename), self.filename ) traceui.addTrace(self.plottedTrace, pen=-1) traceui.resizeColumnsToContents() else: if self.maximumPoints == 0 or len( self.trace.x) < self.maximumPoints: self.trace.x = numpy.append(self.trace.x, takentime) self.trace.y = numpy.append(self.trace.y, value) if maxval is not None: self.trace.top = numpy.append(self.trace.top, maxval - value) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom, value - minval) else: maxPoints = int(self.maximumPoints) self.trace.x = numpy.append(self.trace.x[-maxPoints:], takentime) self.trace.y = numpy.append(self.trace.y[-maxPoints:], value) if maxval is not None: self.trace.top = numpy.append( self.trace.top[-maxPoints:], maxval - value) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom[-maxPoints:], value - minval) self.plottedTrace.replot()
class TraceControl(Form, Base): StateOptions = enum('stopped', 'running', 'single') newDataAvailable = QtCore.pyqtSignal( object ) def __init__(self,controller,config,traceui,plotDict,parent=None): Base.__init__(self, parent) Form.__init__(self) self.controller = controller self.config = config self.traceSettings = self.config.get("TraceControl.Settings", TraceSettings()) self.state = self.StateOptions.stopped self.traceui = traceui self.plotDict = plotDict self.controller.scopeDataAvailable.connect( self.onData ) self.trace = None self.trace = None self.errorSigCurve = None self.freqCurve = None self.lockSettings = None def setupSpinBox(self, localname, settingsname, updatefunc, unit ): box = getattr(self, localname) value = getattr(self.traceSettings, settingsname) box.setValue( value ) box.dimension = unit box.valueChanged.connect( updatefunc ) updatefunc( value ) def setupUi(self): Form.setupUi(self, self) self.setupSpinBox('magNumberSamples', 'samples', self.setSamples, '') self.setupSpinBox('magSubsample', 'subsample', self.setSubSample, '') self.setupSpinBox('magTriggerLevel', 'triggerLevel', self.setTriggerLevel, 'V') self.comboTriggerMode.currentIndexChanged[int].connect( self.setTriggerMode ) self.comboTriggerMode.setCurrentIndex( self.traceSettings.triggerMode ) self.runButton.clicked.connect( self.onRun ) self.singleButton.clicked.connect( self.onSingle ) self.stopButton.clicked.connect(self.onStop) self.addTraceButton.clicked.connect( self.onAddTrace ) self.initPlotCombo( self.frequencyPlotCombo, 'frequencyPlot', self.onChangeFrequencyPlot) self.initPlotCombo( self.errorSigPlotCombo, 'errorSigPlot', self.onChangeErrorSigPlot) def initPlotCombo(self, combo, plotAttrName, onChange ): combo.addItems( list(self.plotDict.keys()) ) plotName = getattr(self.traceSettings, plotAttrName) if plotName is not None and plotName in self.plotDict: combo.setCurrentIndex( combo.findText(plotName)) else: setattr( self.traceSettings, plotAttrName, str( combo.currentText()) ) combo.currentIndexChanged[str].connect( onChange ) def onChangeFrequencyPlot(self, name): name = str(name) if name!=self.traceSettings.frequencyPlot and name in self.plotDict: self.traceSettings.frequencyPlot = name if self.freqCurve is not None: self.freqCurve.setView( self.plotDict[name]['view']) def onChangeErrorSigPlot(self, name): name = str(name) if name!=self.traceSettings.errorSigPlot and name in self.plotDict: self.traceSettings.errorSigPlot = name if self.errorSigCurve is not None: self.errorSigCurve.setView( self.plotDict[name]['view']) def onControlChanged(self, value): self.lockSettings = value def setState(self, state): self.state = state self.statusLabel.setText( self.StateOptions.reverse_mapping[self.state] ) def onData(self, data): if data.errorSig and data.frequency: errorSig = list(map( binToVoltageV, data.errorSig )) if self.trace is None: self.trace = TraceCollection() self.trace.name = "Scope" self.trace.x = numpy.arange(len(errorSig)) * (sampleTime.m_as('us') * (1 + int(self.traceSettings.subsample))) self.trace.y = numpy.array( errorSig ) if self.errorSigCurve is None: self.errorSigCurve = PlottedTrace(self.trace, self.plotDict[self.traceSettings.errorSigPlot]['view'], pen=-1, style=PlottedTrace.Styles.lines, name="Error Signal", #@UndefinedVariable windowName=self.traceSettings.errorSigPlot) self.errorSigCurve.plot() self.traceui.addTrace( self.errorSigCurve, pen=-1 ) else: self.errorSigCurve.replot() self.newDataAvailable.emit( self.trace ) frequency = list(map( binToFreqHz, data.frequency )) self.trace['freq'] = numpy.array( frequency ) if self.freqCurve is None: self.freqCurve = PlottedTrace(self.trace, self.plotDict[self.traceSettings.frequencyPlot]['view'], pen=-1, style=PlottedTrace.Styles.lines, name="Frequency", #@UndefinedVariable xColumn='x', yColumn='freq', windowName=self.traceSettings.frequencyPlot ) self.freqCurve.plot() self.traceui.addTrace( self.freqCurve, pen=-1 ) else: self.freqCurve.replot() if self.state==self.StateOptions.running: QtCore.QTimer.singleShot(10, self.delayedArm ) # wait 10ms before re-arming else: self.setState(self.StateOptions.stopped) def delayedArm(self): self.controller.armScope() def onAddTrace(self): if self.errorSigCurve: self.errorSigCurve = None self.trace = None if self.freqCurve: self.freqCurve = None self.trace = None def onPlotConfigurationChanged(self, plotDict): self.plotDict = plotDict if self.traceSettings.frequencyPlot not in self.plotDict: self.traceSettings.frequencyPlot = list(self.plotDict.keys())[0] if self.traceSettings.errorSigPlot not in self.plotDict: self.traceSettings.errorSigPlot = list(self.plotDict.keys())[0] updateComboBoxItems( self.frequencyPlotCombo, list(self.plotDict.keys()) ) updateComboBoxItems( self.errorSigPlotCombo, list(self.plotDict.keys()) ) def onRun(self): self.controller.armScope() self.setState(self.StateOptions.running) def onStop(self): self.setState( self.StateOptions.stopped) def onSingle(self): self.controller.armScope() self.setState( self.StateOptions.single ) def setTriggerMode(self, mode): self.traceSettings.triggerMode = mode self.controller.setTriggerMode(mode) def setTriggerLevel(self, value): self.traceSettings.triggerLevel = value self.controller.setTriggerLevel( voltageToBin(value) ) def setSamples(self, samples): self.traceSettings.samples = samples self.controller.setSamples(int(samples)) def setSubSample(self, subsample): self.traceSettings.subsample = subsample self.controller.setSubSample(int(subsample)) def saveConfig(self): self.config["TraceControl.Settings"] = self.traceSettings
def doCreatePlot(self, space, parameter, fromTime, toTime, plotName, steps, forceUpdate=False): ref, _ = self.cache.get((space, parameter), (lambda: None, None)) plottedTrace = ref() if ( self.parameters.updatePrevious or forceUpdate ) else None # get plottedtrace from the weakref if exists result = self.connection.getHistory(space, parameter, fromTime, toTime) if not result: logging.getLogger(__name__).warning( "Database query returned empty set") elif len(result) > 0: #time = [(pytz.utc.localize(e.upd_date) - datetime(1970,1,1, tzinfo=pytz.utc)).total_seconds() for e in result] if result[0].upd_date.tzinfo is not None: time = [ (e.upd_date - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds() for e in result ] else: time = [ (e.upd_date - datetime.fromtimestamp(0)).total_seconds() for e in result ] value = [e.value for e in result] bottom = [ e.value - e.bottom if e.bottom is not None else e.value for e in result ] top = [ e.top - e.value if e.top is not None else e.value for e in result ] if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = parameter + "_Query" trace.y = numpy.array(value) if plotName is None: plotName = str(self.comboBoxPlotName.currentText()) if steps: trace.x = numpy.array(time + [time[-1]]) plottedTrace = PlottedTrace( trace, self.plotDict[plotName]["view"], xAxisLabel="local time", plotType=PlottedTrace.Types.steps, fill=False, windowName=plotName) #@UndefinedVariable else: trace.x = numpy.array(time) trace.top = numpy.array(top) trace.bottom = numpy.array(bottom) plottedTrace = PlottedTrace( trace, self.plotDict[plotName]["view"], xAxisLabel="local time", windowName=plotName) plottedTrace.trace.autoSave = self.traceui.autoSaveTraces plottedTrace.name = trace.name plottedTrace.trace.filenamePattern = trace.name if not plottedTrace.trace.autoSave: self.unsavedTraceCount += 1 self.traceui.addTrace(plottedTrace, pen=-1) self.traceui.resizeColumnsToContents() self.cache[(space, parameter)] = (weakref.ref(plottedTrace), (space, parameter, fromTime, toTime, plotName, steps)) else: # update the existing plotted trace trace = plottedTrace.trace trace.y = numpy.array(value) if steps: trace.x = numpy.array(time + [time[-1]]) else: trace.x = numpy.array(time) trace.top = numpy.array(top) trace.bottom = numpy.array(bottom) plottedTrace.replot()
class PicoampMeterControl(Base, Form): def __init__(self,config, traceui, plotdict, parent, meter, meter_2 = None, meter_3 = None): self.config = config self.traceui = traceui self.plotDict = plotdict self.parent = parent self.meter = meter self.meter_2 = meter_2 self.meter_3 = meter_3 super(PicoampMeterControl, self).__init__() self.meterState = self.config.get("PicoampMeterState", MeterState() ) self.trace = None self.stopRequested = False self.scanMode = "V" self.loggingActive = False self.startTime = datetime.now() self.scanRunning = False def writeAll(self): self.onVoltage(self.meterState.voltage) self.onEnableOutput( self.meterState.voltageEnabled ) self.onCurrentLimit( self.meterState.currentLimit ) self.onVoltageRange( self.meterState.voltageRange ) self.onZeroCheck(self.meterState.zeroCheck ) self.onAutoRange( self.meterState.autoRange) def writeAll_2(self): self.onVoltage_2(self.meterState.voltage_2) self.onEnableOutput_2( self.meterState.voltageEnabled_2 ) self.onCurrentLimit_2( self.meterState.currentLimit_2 ) self.onVoltageRange_2( self.meterState.voltageRange_2 ) self.onZeroCheck_2(self.meterState.zeroCheck_2 ) self.onAutoRange_2( self.meterState.autoRange_2 ) def writeAll_3(self): self.onVoltage_3(self.meterState.voltage_3) self.onEnableOutput_3( self.meterState.voltageEnabled_3 ) self.onCurrentLimit_3( self.meterState.currentLimit_3 ) self.onVoltageRange_3( self.meterState.voltageRange_3 ) self.onZeroCheck_3(self.meterState.zeroCheck_3 ) self.onAutoRange_3( self.meterState.autoRange_3 ) def setupUi(self, parent): super(PicoampMeterControl, self).setupUi(parent) self.instrumentEdit.setText( self.meterState.instrument ) self.instrumentEdit.returnPressed.connect( self.openInstrument ) self.instrumentEdit_2.setText( self.meterState.instrument_2 ) self.instrumentEdit_2.returnPressed.connect( self.openInstrument_2 ) self.instrumentEdit_3.setText( self.meterState.instrument_3 ) self.instrumentEdit_3.returnPressed.connect( self.openInstrument_3 ) self.enableMeasurementBox.stateChanged.connect( self.onZeroCheck ) self.enableMeasurementBox.setChecked( not self.meterState.zeroCheck ) self.enableMeasurementBox_2.stateChanged.connect( self.onZeroCheck_2 ) self.enableMeasurementBox_2.setChecked( not self.meterState.zeroCheck_2 ) self.enableMeasurementBox_3.stateChanged.connect( self.onZeroCheck_3 ) self.enableMeasurementBox_3.setChecked( not self.meterState.zeroCheck_3 ) self.autoRangeBox.stateChanged.connect( self.onAutoRange ) self.autoRangeBox.setChecked( self.meterState.autoRange ) self.autoRangeBox_2.stateChanged.connect( self.onAutoRange_2 ) self.autoRangeBox_2.setChecked( self.meterState.autoRange_2 ) self.autoRangeBox_3.stateChanged.connect( self.onAutoRange_3 ) self.autoRangeBox_3.setChecked( self.meterState.autoRange_3 ) self.voltageRangeSelect.currentIndexChanged[int].connect( self.onVoltageRange ) self.voltageRangeSelect.setCurrentIndex( self.voltageRangeSelect.findText("{0}".format(self.meterState.voltageRange))) self.voltageRangeSelect_2.currentIndexChanged[int].connect( self.onVoltageRange_2 ) self.voltageRangeSelect_2.setCurrentIndex( self.voltageRangeSelect_2.findText("{0}".format(self.meterState.voltageRange_2))) self.voltageRangeSelect_3.currentIndexChanged[int].connect( self.onVoltageRange_3 ) self.voltageRangeSelect_3.setCurrentIndex( self.voltageRangeSelect_3.findText("{0}".format(self.meterState.voltageRange_3))) self.currentLimitSelect.currentIndexChanged[int].connect( self.onCurrentLimit ) self.currentLimitSelect.setCurrentIndex( self.meterState.currentLimit) self.currentLimitSelect_2.currentIndexChanged[int].connect( self.onCurrentLimit_2 ) self.currentLimitSelect_2.setCurrentIndex( self.meterState.currentLimit_2) self.currentLimitSelect_3.currentIndexChanged[int].connect( self.onCurrentLimit_3 ) self.currentLimitSelect_3.setCurrentIndex( self.meterState.currentLimit_3) self.enableOutputBox.stateChanged.connect( self.onEnableOutput ) self.enableOutputBox.setChecked(False) self.enableOutputBox_2.stateChanged.connect( self.onEnableOutput ) self.enableOutputBox_2.setChecked(False) self.enableOutputBox_3.stateChanged.connect( self.onEnableOutput_2 ) self.enableOutputBox_3.setChecked(False) self.voltageEdit.valueChanged.connect( self.onVoltage ) self.voltageEdit.setValue( self.meterState.voltage ) self.voltageEdit_2.valueChanged.connect( self.onVoltage_2 ) self.voltageEdit_2.setValue( self.meterState.voltage_2 ) self.voltageEdit_3.valueChanged.connect( self.onVoltage_3 ) self.voltageEdit_3.setValue( self.meterState.voltage_3 ) self.startEdit.setValue( self.meterState.start ) self.startEdit.valueChanged.connect( partial( self.onValueChanged, 'start') ) self.stopEdit.setValue( self.meterState.stop ) self.stopEdit.valueChanged.connect( partial( self.onValueChanged, 'stop') ) self.stepsEdit.setValue( self.meterState.steps ) self.stepsEdit.valueChanged.connect( partial( self.onValueChanged, 'steps') ) self.settlingDelayEdit.setValue( self.meterState.settlingDelay ) self.settlingDelayEdit.valueChanged.connect( partial( self.onValueChanged, 'settlingDelay') ) self.timeDeltaEdit.setValue( self.meterState.timeDelta ) self.timeDeltaEdit.valueChanged.connect( partial( self.onValueChanged, 'timeDelta') ) self.zeroButton.clicked.connect( self.onZero ) self.measureButton.clicked.connect( self.onMeasure ) self.scanButton.clicked.connect( self.onScan ) self.scanTypeCombo.setCurrentIndex( self.meterState.scanType ) self.scanTypeCombo.currentIndexChanged[int].connect( partial(self.onValueChanged, 'scanType') ) self.filenameEdit.setText( self.meterState.filename ) self.filenameEdit.textChanged.connect( partial(self.onStringValueChanged, 'filename')) self.logButton.clicked.connect( self.onLogging ) def onLogging(self, checked): if checked: if not self.loggingActive: self.startLogging() else: self.stopLogging() def startLogging(self): self.trace = TraceCollection() # self.trace.addColumn('voltage_2') # self.trace.addColumn('voltage_3') # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList ) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_3', penList=pens.penList ) self.voltagePlottedTrace = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage', penList=pens.penList ) # self.voltagePlottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_2', penList=pens.penList ) # self.voltagePlottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.voltagePlottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot( 0, self.takeLoggingPoint ) self.loggingActive = True self.startTime = time.time() def takeLoggingPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append( self.trace.x, time.time()-self.startTime ) self.trace.y = numpy.append( self.trace.y, value ) self.trace['voltage'] = numpy.append( self.trace['voltage'], self.meterState.voltage.m_as('V') ) # self.trace.voltage_2 = numpy.append( self.trace.voltage_2, self.meterState.voltage_2.m_as('V') ) # self.trace.voltage_3 = numpy.append( self.trace.voltage_3, self.meterState.voltage_3.m_as('V') ) if not self.traceAdded: self.traceui.addTrace( self.plottedTrace, pen=-1) self.traceui.addTrace( self.voltagePlottedTrace, pen=0 ) # self.traceui.addTrace( self.plottedTrace_2, pen=-1) # self.traceui.addTrace( self.voltagePlottedTrace_2, pen=0 ) # self.traceui.addTrace( self.plottedTrace_3, pen=-1) # self.traceui.addTrace( self.voltagePlottedTrace_3, pen=0 ) self.traceAdded = True else: self.plottedTrace.replot() self.voltagePlottedTrace.replot() # self.plottedTrace_2.replot() # self.voltagePlottedTrace_3.replot() # self.plottedTrace_2.replot() # self.voltagePlottedTrace_3.replot() if self.stopRequested: self.finalizeScan() self.loggingActive = False else: QtCore.QTimer.singleShot(self.meterState.timeDelta.m_as('ms'), self.takeLoggingPoint ) def stopLogging(self): self.stopRequested = True def onScan(self): self.startScan() def onStop(self): self.stopRequested = True def startScan(self): if not self.scanRunning: self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) if self.meterState.scanType in [4, 5]: index = find_index_nearest(self.scanList, self.meterState.voltage) self.scanList = numpy.roll( self.scanList, -index) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList ) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) # self.meter_2.setZeroCheck(False) # self.meter_3.setZeroCheck(False) self.meter.voltageEnable(True) # self.meter_2.voltageEnable(True) # self.meter_3.voltageEnable(True) self.stopRequested = False print("startScan") self.scanRunning = True QtCore.QTimer.singleShot(0, self.initPoint ) def initPoint(self): if self.currentIndex<len(self.scanList) and not self.stopRequested: self.meter.setVoltage( self.scanList[self.currentIndex] ) QtCore.QTimer.singleShot(self.meterState.settlingDelay.m_as('ms'), self.takeScanPoint ) else: self.meter.setVoltage( self.meterState.voltage ) self.finalizeScan() def takeScanPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append( self.trace.x, self.scanList[self.currentIndex].m_as('V') ) self.trace.y = numpy.append( self.trace.y, value ) # self.trace.current_2 = numpy.append( self.trace.current_2, float( self.meter_2.read() ) ) # self.trace.current_3 = numpy.append( self.trace.current_3, float( self.meter_3.read() ) ) if not self.traceAdded: self.traceui.addTrace( self.plottedTrace, pen=-1) # self.traceui.addTrace( self.plottedTrace_2, pen=-1) # self.traceui.addTrace( self.plottedTrace_3, pen=-1) self.traceAdded = True else: self.plottedTrace.replot() # self.plottedTrace_2.replot() # self.plottedTrace_3.replot() self.currentIndex += 1 QtCore.QTimer.singleShot(0, self.initPoint ) def finalizeScan(self): self.trace.description["traceFinalized"] = datetime.now() self.trace.resave(saveIfUnsaved=False) self.scanRunning = False def onMeasure(self): value = float(self.meter.read()) self.currentLabel.setText(str(value)) def onMeasure_2(self): value = float(self.meter_2.read()) self.currentLabel_2.setText(str(value)) def onMeasure_3(self): value = float(self.meter_3.read()) self.currentLabel_3.setText(str(value)) def onZero(self): self.meter.zero() def onZero_2(self): self.meter_2.zero() def onZero_3(self): self.meter_3.zero() def onValueChanged(self, attr, value): setattr( self.meterState, attr, value ) def onStringValueChanged(self, attr, value): setattr( self.meterState, attr, str(value) ) def onVoltage(self, value): raw = value.m_as("V") self.meter.setVoltage(raw) self.meterState.voltage = value def onVoltage_2(self, value): raw = value.m_as("V") self.meter_2.setVoltage(raw) self.meterState.voltage_2 = value def onVoltage_3(self, value): raw = value.m_as("V") self.meter_3.setVoltage(raw) self.meterState.voltage_3 = value def onEnableOutput(self, value): enable = value == QtCore.Qt.Checked self.meter.voltageEnable(enable) self.meterState.voltageEnabled = enable def onEnableOutput_2(self, value): enable = value == QtCore.Qt.Checked self.meter_2.voltageEnable(enable) self.meterState.voltageEnabled_2 = enable def onEnableOutput_3(self, value): enable = value == QtCore.Qt.Checked self.meter_3.voltageEnable(enable) self.meterState.voltageEnabled_3 = enable currentLimits = [2.5e-5, 2.5e-4, 2.5e-3, 2.5e-2] def onCurrentLimit(self, index): limit = self.currentLimits[index] self.meter.setCurrentLimit(limit) self.meterState.currentLimit = index def onCurrentLimit_2(self, index): limit = self.currentLimits[index] self.meter_2.setCurrentLimit(limit) self.meterState.currentLimit_2 = index def onCurrentLimit_3(self, index): limit = self.currentLimits[index] self.meter_3.setCurrentLimit(limit) self.meterState.currentLimit_3 = index voltageRanges = [10, 50, 500] def onVoltageRange(self, index): vrange = self.voltageRanges[index] self.meter.setVoltageRange( vrange ) self.meterState.voltageRange = index def onVoltageRange_2(self, index): vrange = self.voltageRanges[index] self.meter_2.setVoltageRange( vrange ) self.meterState.voltageRange_2 = index def onVoltageRange_3(self, index): vrange = self.voltageRanges[index] self.meter_3.setVoltageRange( vrange ) self.meterState.voltageRange_3 = index def onZeroCheck(self, value): enable = value != QtCore.Qt.Checked self.meter.setZeroCheck(enable) self.meterState.zeroCheck = enable def onZeroCheck_2(self, value): enable = value != QtCore.Qt.Checked self.meter_2.setZeroCheck(enable) self.meterState.zeroCheck_2 = enable def onZeroCheck_3(self, value): enable = value != QtCore.Qt.Checked self.meter_3.setZeroCheck(enable) self.meterState.zeroCheck_3 = enable def onAutoRange(self, value): enable = value == QtCore.Qt.Checked self.meter.setAutoRange(enable) self.meterState.autoRange = enable def onAutoRange_2(self, value): enable = value == QtCore.Qt.Checked self.meter_2.setAutoRange(enable) self.meterState.autoRange_2 = enable def onAutoRange_3(self, value): enable = value == QtCore.Qt.Checked self.meter_3.setAutoRange(enable) self.meterState.autoRange_3 = enable def openInstrument(self): self.meterState.instrument = str(self.instrumentEdit.text()) self.meter.open( self.meterState.instrument ) self.meter.reset() self.writeAll() def openInstrument_2(self): self.meterState.instrument_2 = str(self.instrumentEdit_2.text()) self.meter_2.open( self.meterState.instrument_2 ) self.meter_2.reset() self.writeAll_2() def openInstrument_3(self): self.meterState.instrument_3 = str(self.instrumentEdit_3.text()) self.meter_3.open( self.meterState.instrument_3 ) self.meter_3.reset() self.writeAll_3() def saveConfig(self): self.config["PicoampMeterState"] = self.meterState
class LockStatus(Form, Base): newDataAvailable = QtCore.pyqtSignal( object ) def __init__(self, controller, config, traceui, plotDict, settings, parent=None): Base.__init__(self, parent) Form.__init__(self) self.controller = controller self.config = config self.lockSettings = None self.lastLockData = list() self.traceui = traceui self.errorSigCurve = None self.trace = None self.freqCurve = None self.plotDict = plotDict self.settings = self.config.get("LockStatus.settings", Settings()) self.lastXValue = 0 self.logFile = None self.hardwareSettings = settings def setupSpinBox(self, localname, settingsname, updatefunc, unit ): box = getattr(self, localname) value = getattr(self.settings, settingsname) box.setValue( value ) box.dimension = unit box.valueChanged.connect( updatefunc ) updatefunc( value ) def setupUi(self): Form.setupUi(self, self) self.setupSpinBox('magHistoryAccum', 'averageTime', self.setAverageTime, 'ms') self.setupSpinBox('magMaxHistory', 'maxSamples', self.setMaxSamples, '') self.controller.streamDataAvailable.connect( self.onData ) self.controller.lockStatusChanged.connect( self.onLockChange ) self.addTraceButton.clicked.connect( self.onAddTrace ) self.controller.setStreamEnabled(True) self.initPlotCombo( self.frequencyPlotCombo, 'frequencyPlot', self.onChangeFrequencyPlot) self.initPlotCombo( self.errorSigPlotCombo, 'errorSigPlot', self.onChangeErrorSigPlot) self.clearButton.clicked.connect( self.onClear ) def initPlotCombo(self, combo, plotAttrName, onChange ): combo.addItems( list(self.plotDict.keys()) ) plotName = getattr(self.settings, plotAttrName) if plotName is not None and plotName in self.plotDict: combo.setCurrentIndex( combo.findText(plotName)) else: setattr( self.settings, plotAttrName, str( combo.currentText()) ) combo.currentIndexChanged[str].connect( onChange ) def onPlotConfigurationChanged(self, plotDict): self.plotDict = plotDict if self.settings.frequencyPlot not in self.plotDict: self.settings.frequencyPlot = list(self.plotDict.keys())[0] if self.settings.errorSigPlot not in self.plotDict: self.settings.errorSigPlot = list(self.plotDict.keys())[0] updateComboBoxItems( self.frequencyPlotCombo, list(self.plotDict.keys()) ) updateComboBoxItems( self.errorSigPlotCombo, list(self.plotDict.keys()) ) def onChangeFrequencyPlot(self, name): name = str(name) if name!=self.settings.frequencyPlot and name in self.plotDict: self.settings.frequencyPlot = name if self.freqCurve is not None: self.freqCurve.setView( self.plotDict[name]['view']) def onChangeErrorSigPlot(self, name): name = str(name) if name!=self.settings.errorSigPlot and name in self.plotDict: self.settings.errorSigPlot = name if self.errorSigCurve is not None: self.errorSigCurve.setView( self.plotDict[name]['view']) def setAverageTime(self, value): self.settings.averageTime = value mySampleTime = sampleTime.copy() if self.lockSettings is not None and self.lockSettings.filter >0: mySampleTime *= 2 accumNumber = int(value / mySampleTime) self.controller.setStreamAccum(accumNumber) def setMaxSamples(self, samples): self.settings.maxSamples = samples def onLockChange(self, data=None): pass def onControlChanged(self, value): self.lockSettings = value self.setAverageTime(self.settings.averageTime) self.onLockChange() def convertStatus(self, item): logger = logging.getLogger(__name__) if self.lockSettings is None: return None status = StatusData() status.regulatorFrequency = binToFreq(item.freqSum / float(item.samples)) # setSignificantDigits(status.regulatorFrequency, frequencyQuantum) status.referenceFrequency = self.lockSettings.referenceFrequency + status.regulatorFrequency # setSignificantDigits(status.referenceFrequency, frequencyQuantum) status.outputFrequency = self.lockSettings.outputFrequency + binToFreq(item.freqSum / float(item.samples) )* self.lockSettings.harmonic # setSignificantDigits(status.outputFrequency, frequencyQuantum) binvalue = (item.freqMax - item.freqMin) status.referenceFrequencyDelta = binToFreq(binvalue) # setSignificantDigits(status.referenceFrequencyDelta, frequencyQuantum) status.referenceFrequencyMax = binToFreq(item.freqMax) # setSignificantDigits(status.referenceFrequencyMax, frequencyQuantum) status.referenceFrequencyMin = binToFreq(item.freqMin) # setSignificantDigits(status.referenceFrequencyMin, frequencyQuantum) binvalue *= self.lockSettings.harmonic status.outputFrequencyDelta = abs(binToFreq(binvalue)) # setSignificantDigits(status.outputFrequencyDelta, frequencyQuantum*self.lockSettings.harmonic) status.outputFrequencyMax = self.lockSettings.outputFrequency + binToFreq(item.freqMax)* self.lockSettings.harmonic # setSignificantDigits(status.outputFrequencyMax, frequencyQuantum) status.outputFrequencyMin = self.lockSettings.outputFrequency + binToFreq(item.freqMin)* self.lockSettings.harmonic # setSignificantDigits(status.outputFrequencyMin, frequencyQuantum) status.errorSigAvg = binToVoltage( item.errorSigSum/float(item.samples) ) # setSignificantDigits( status.errorSigAvg, voltageQuantum ) binvalue = item.errorSigMax - item.errorSigMin status.errorSigDelta = binToVoltage(binvalue ) # setSignificantDigits( status.errorSigDelta, voltageQuantum ) status.errorSigMax = binToVoltage(item.errorSigMax) # setSignificantDigits( status.errorSigMax, voltageQuantum ) status.errorSigMin = binToVoltage(item.errorSigMin) # setSignificantDigits( status.errorSigMin, voltageQuantum ) status.errorSigRMS = binToVoltage( math.sqrt(item.errorSigSumSq/float(item.samples)) ) # setSignificantDigits( status.errorSigRMS, voltageQuantum ) status.externalMin = decodeMg(item.externalMin, self.hardwareSettings.onBoardADCEncoding) # setSignificantDigits( status.externalMin, voltageQuantumExternal ) status.externalMax = decodeMg(item.externalMax, self.hardwareSettings.onBoardADCEncoding) # setSignificantDigits( status.externalMax, voltageQuantumExternal ) if item.externalCount>0: status.externalAvg = decodeMg( item.externalSum / float(item.externalCount), self.hardwareSettings.onBoardADCEncoding ) # setSignificantDigits( status.externalAvg, voltageQuantumExternal/(math.sqrt(item.externalCount) if item.externalCount>0 else 1)) status.externalDelta = abs(status.externalMax - status.externalMin) # setSignificantDigits( status.externalDelta, voltageQuantumExternal ) else: status.externalAvg = None status.externalDelta = None status.lockStatus = item.lockStatus if self.lockSettings.mode & 1 else -1 logger.debug("External min: {0} max: {1} samples: {2} sum: {3}".format(item.externalMin, item.externalMax, item.externalCount, item.externalSum)) status.time = item.samples * sampleTime.m_as('s') return status logFrequency = ['regulatorFrequency', 'referenceFrequency', 'referenceFrequencyMin', 'referenceFrequencyMax', 'outputFrequency', 'outputFrequencyMin', 'outputFrequencyMax'] logVoltage = ['errorSigAvg', 'errorSigMin', 'errorSigMax', 'errorSigRMS', 'externalAvg', 'externalMin', 'externalMax'] def writeToLogFile(self, status): if self.lockSettings and self.lockSettings.mode & 1 == 1: # if locked if not self.logFile: self.logFile = open( DataDirectory().sequencefile("LockLog.txt")[0], "w" ) self.logFile.write( " ".join( self.logFrequency + self.logVoltage ) ) self.logFile.write( "\n" ) self.logFile.write( "{0} ".format(datetime.now())) self.logFile.write( " ".join( map( repr, list(map( methodcaller('m_as', 'Hz'), (getattr(status, field) for field in self.logFrequency) )) ) ) ) self.logFile.write( " ".join( map( repr, list(map( methodcaller('m_as', 'mV'), (getattr(status, field) for field in self.logVoltage) )) ) ) ) self.logFile.write("\n") self.logFile.flush() background = { -1: "#eeeeee", 0: "#ff0000", 3: "#00ff00", 1:"#ffff00", 2:"#ffff00" } statusText = { -1: "Unlocked", 0:"No Light", 3: "Locked", 1: "Partly no light", 2: "Partly no light"} def onData(self, data=None ): logger = logging.getLogger() logger.debug( "received streaming data {0} {1}".format(len(data), data[-1] if len(data)>0 else "")) if data is not None: self.lastLockData = list() for item in data: converted = self.convertStatus(item) if converted is not None: self.lastLockData.append( converted ) if converted.lockStatus==3: self.writeToLogFile(converted) if self.lastLockData is not None: self.plotData() if self.lastLockData: item = self.lastLockData[-1] self.referenceFreqLabel.setText( str(item.referenceFrequency) ) self.referenceFreqRangeLabel.setText( str(item.referenceFrequencyDelta) ) self.outputFreqLabel.setText( str(item.outputFrequency)) self.outputFreqRangeLabel.setText( str(item.outputFrequencyDelta)) self.errorSignalLabel.setText( str(item.errorSigAvg)) self.errorSignalRangeLabel.setText( str(item.errorSigDelta)) self.errorSignalRMSLabel.setText( str(item.errorSigRMS)) self.externalSignalLabel.setText( str(item.externalAvg)) self.externalSignalRangeLabel.setText( str(item.externalDelta) ) logger.debug("error signal min {0} max {1}".format(item.errorSigMin, item.errorSigMax )) self.statusLabel.setStyleSheet( "QLabel {{ background: {0} }}".format( self.background[item.lockStatus]) ) self.statusLabel.setText( self.statusText[item.lockStatus] ) self.newDataAvailable.emit( item ) else: logger.info("no lock control information") def plotData(self): if len(self.lastLockData)>0: to_plot = list(zip(*(attrgetter('errorSigAvg', 'errorSigMin', 'errorSigMax', 'time')(e) for e in self.lastLockData))) x = numpy.arange( self.lastXValue, self.lastXValue+len(to_plot[0] )) self.lastXValue += len(to_plot[0] ) y = numpy.array([v.m_as('V') for v in to_plot[0]]) bottom = numpy.array([(v0 - v1).m_as('V') for v0, v1 in zip(to_plot[0], to_plot[1])]) top = numpy.array([(v2 - v0).m_as('V') for v0, v2 in zip(to_plot[0], to_plot[2])]) if self.trace is None: self.trace = TraceCollection() self.trace['x'] = x self.trace['y'] = y self.trace['bottom'] = bottom self.trace['top'] = top self.trace.name = "History" else: self.trace['x'] = rollingUpdate(self.trace['x'], x, self.settings.maxSamples) self.trace['y'] = rollingUpdate(self.trace['y'], y, self.settings.maxSamples) self.trace['bottom'] = rollingUpdate(self.trace['bottom'], bottom, self.settings.maxSamples) self.trace['top'] = rollingUpdate(self.trace['top'], top, self.settings.maxSamples) if self.errorSigCurve is None: self.errorSigCurve = PlottedTrace(self.trace, self.plotDict[self.settings.errorSigPlot]['view'], pen=-1, style=PlottedTrace.Styles.points, name="Error Signal", windowName=self.settings.errorSigPlot) #@UndefinedVariable self.errorSigCurve.plot() self.traceui.addTrace( self.errorSigCurve, pen=-1 ) else: self.errorSigCurve.replot() to_plot = list(zip(*(attrgetter('regulatorFrequency', 'referenceFrequencyMin', 'referenceFrequencyMax')(e) for e in self.lastLockData))) y = numpy.array([v.m_as('Hz') for v in to_plot[0]]) bottom = numpy.array([(v0 - v1).m_as('Hz') for v0, v1 in zip(to_plot[0], to_plot[1])]) top = numpy.array([(v2 - v0).m_as('Hz') for v0, v2 in zip(to_plot[0], to_plot[2])]) self.trace['freq'] = rollingUpdate(self.trace['freq'], y, self.settings.maxSamples) self.trace['freqBottom'] = rollingUpdate(self.trace['freqBottom'], bottom, self.settings.maxSamples) self.trace['freqTop'] = rollingUpdate(self.trace['freqTop'], top, self.settings.maxSamples) if self.freqCurve is None: self.freqCurve = PlottedTrace(self.trace, self.plotDict[self.settings.frequencyPlot]['view'], pen=-1, style=PlottedTrace.Styles.points, name="Repetition rate", #@UndefinedVariable xColumn='x', yColumn='freq', topColumn='freqTop', bottomColumn='freqBottom', windowName=self.settings.frequencyPlot) self.freqCurve.plot() self.traceui.addTrace( self.freqCurve, pen=-1 ) else: self.freqCurve.replot() def onClear(self): if self.trace: self.trace['x'] = numpy.array([]) self.trace['y'] = numpy.array([]) self.trace['bottom'] = numpy.array([]) self.trace['top'] = numpy.array([]) self.trace['freq'] = numpy.array([]) self.trace['freqBottom'] = numpy.array([]) self.trace['freqTop'] = numpy.array([]) def onAddTrace(self): self.trace = None self.errorSigCurve = None self.freqCurve = None def saveConfig(self): self.config["LockStatus.settings"] = self.settings
class ReadInstrumentControl(Base, Form): def __init__(self, config, traceui, plotdict, parent, meter): self.config = config self.traceui = traceui self.plotDict = plotdict self.parent = parent super(ReadInstrumentControl, self).__init__() self.state = self.config.get("PicoampMeterState", ReadInstrumentState() ) def setupUi(self, parent): super(ReadInstrumentControl, self).setupUi(parent) self.instrumentEdit.setText( self.meterState.instrument ) self.instrumentEdit.returnPressed.connect( self.openInstrument ) # if self.meterState.instrument: # self.openInstrument() self.enableMeasurementBox.stateChanged.connect( self.onZeroCheck ) self.enableMeasurementBox.setChecked( not self.meterState.zeroCheck ) self.autoRangeBox.stateChanged.connect( self.onAutoRange ) self.autoRangeBox.setChecked( self.meterState.autoRange ) self.voltageRangeSelect.currentIndexChanged[int].connect( self.onVoltageRange ) self.voltageRangeSelect.setCurrentIndex( self.voltageRangeSelect.findText("{0}".format(self.meterState.voltageRange))) self.currentLimitSelect.currentIndexChanged[int].connect( self.onCurrentLimit ) self.currentLimitSelect.setCurrentIndex( self.meterState.currentLimit) self.enableOutputBox.stateChanged.connect( self.onEnableOutput ) self.enableOutputBox.setChecked(False) self.voltageEdit.valueChanged.connect( self.onVoltage ) self.voltageEdit.setValue( self.meterState.voltage ) self.startEdit.setValue( self.meterState.start ) self.startEdit.valueChanged.connect( partial( self.onValueChanged, 'start') ) self.stopEdit.setValue( self.meterState.stop ) self.stopEdit.valueChanged.connect( partial( self.onValueChanged, 'stop') ) self.stepsEdit.setValue( self.meterState.steps ) self.stepsEdit.valueChanged.connect( partial( self.onValueChanged, 'steps') ) self.timeDeltaEdit.setValue( self.meterState.timeDelta ) self.timeDeltaEdit.valueChanged.connect( partial( self.onValueChanged, 'timeDelta') ) self.zeroButton.clicked.connect( self.onZero ) self.measureButton.clicked.connect( self.onMeasure ) self.scanButton.clicked.connect( self.onScan ) self.scanTypeCombo.setCurrentIndex( self.meterState.scanType ) self.scanTypeCombo.currentIndexChanged[int].connect( partial(self.onValueChanged, 'scanType') ) self.filenameEdit.setText( self.meterState.filename ) self.filenameEdit.textChanged.connect( partial(self.onValueChanged, 'filename')) self.logButton.clicked.connect( self.onLogging ) def onLogging(self, checked): if checked: if not self.loggingActive: self.startLogging() else: self.stopLogging() def startLogging(self): self.trace = TraceCollection() self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot( 0, self.takeLoggingPoint ) self.loggingActive = True self.startTime = time.time() def takeLoggingPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append( self.trace.x, time.time()-self.startTime ) self.trace.y = numpy.append( self.trace.y, value ) if not self.traceAdded: self.traceui.addTrace( self.plottedTrace, pen=-1) self.traceAdded = True else: self.plottedTrace.replot() if self.stopRequested: self.finalizeScan() self.loggingActive = False else: QtCore.QTimer.singleShot(self.meterState.timeDelta.m_as('ms'), self.takeLoggingPoint ) def stopLogging(self): self.stopRequested = True def onScan(self): self.startScan() def onStop(self): self.stopRequested = True def startScan(self): self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) self.meter.voltageEnable(True) self.stopRequested = False QtCore.QTimer.singleShot(0, self.initPoint ) def initPoint(self): if self.currentIndex<len(self.scanList) and not self.stopRequested: self.meter.setVoltage( self.scanList[self.currentIndex] ) QtCore.QTimer.singleShot(0, self.takeScanPoint ) else: self.meter.setVoltage( self.meterState.voltage ) self.finalizeScan() def takeScanPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append( self.trace.x, self.scanList[self.currentIndex].m_as('V') ) self.trace.y = numpy.append( self.trace.y, value ) if not self.traceAdded: self.traceui.addTrace( self.plottedTrace, pen=-1) self.traceAdded = True else: self.plottedTrace.replot() self.currentIndex += 1 QtCore.QTimer.singleShot(0, self.initPoint ) def finalizeScan(self): self.trace.description["traceFinalized"] = datetime.now() self.trace.resave(saveIfUnsaved=False) def onMeasure(self): value = float(self.meter.read()) self.currentLabel.setText(str(value)) def onZero(self): self.meter.zero() def onValueChanged(self, attr, value): setattr( self.meterState, attr, value ) def onVoltage(self, value): raw = value.m_as("V") self.meter.setVoltage(raw) self.meterState.voltage = value def onEnableOutput(self, value): enable = value == QtCore.Qt.Checked self.meter.voltageEnable(enable) self.meterState.voltageEnabled = enable currentLimits = [2.5e-5, 2.5e-4, 2.5e-3, 2.5e-2] def onCurrentLimit(self, index): limit = self.currentLimits[index] self.meter.setCurrentLimit(limit) self.meterState.currentLimit = index voltageRanges = [10, 50, 500] def onVoltageRange(self, index): vrange = self.voltageRanges[index] self.meter.setVoltageRange( vrange ) self.meterState.voltageRange = index def onZeroCheck(self, value): enable = value != QtCore.Qt.Checked self.meter.setZeroCheck(enable) self.meterState.zeroCheck = enable def onAutoRange(self, value): enable = value == QtCore.Qt.Checked self.meter.setAutoRange(enable) self.meterState.autoRange = enable def openInstrument(self): self.meterState.instrument = str(self.instrumentEdit.text()) self.meter.open( self.meterState.instrument ) self.meter.reset() self.writeAll() def saveConfig(self): self.config["PicoampMeterState"] = self.meterState
class test(testForm, MainWindowWidget.MainWindowWidget): StatusMessage = QtCore.pyqtSignal( str ) ClearStatusMessage = QtCore.pyqtSignal() experimentName = 'Test Scan' def __init__(self,globalVariablesUi, parent=None, measurementLog=None): MainWindowWidget.MainWindowWidget.__init__(self, parent) testForm.__init__(self) self.globalVariablesUi = globalVariablesUi self.measurementLog = measurementLog # pyqtgraph.setConfigOption('background', 'w') # pyqtgraph.setConfigOption('foreground', 'k') def setupUi(self, MainWindow, config): testForm.setupUi(self, MainWindow) self.config = config self.plottedTrace = None self._graphicsView = self.graphicsLayout._graphicsView self.penicons = pens.penicons().penicons() self.traceui = Traceui(self.penicons, self.config, "testExperiment", { "Plot Window": {'view': self._graphicsView}}) self.traceui.setupUi(self.traceui) self.dockWidget.setWidget( self.traceui ) self.dockWidgetList.append(self.dockWidget) self.fitWidget = FitUi(self.traceui, self.config, "testExperiment", globalDict = self.globalVariablesUi.variables ) self.fitWidget.setupUi(self.fitWidget) self.dockWidgetFitUi.setWidget( self.fitWidget ) self.dockWidgetList.append(self.dockWidgetFitUi ) self.displayUi = AverageViewTable(self.config) self.displayUi.setupUi() self.displayDock = QtWidgets.QDockWidget("Average") self.displayDock.setObjectName("Average") self.displayDock.setWidget( self.displayUi ) self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.displayDock) self.dockWidgetList.append(self.displayDock ) if 'testWidget.MainWindow.State' in self.config: QtWidgets.QMainWindow.restoreState(self, self.config['testWidget.MainWindow.State']) #start added self.scanControlWidget = ScanControl(config, self.globalVariablesUi, self.experimentName) self.scanControlWidget.setupUi(self.scanControlWidget) self.scanControlUi.setWidget(self.scanControlWidget ) self.dockWidgetList.append(self.scanControlUi) #end added self.tabifyDockWidget( self.dockWidgetFitUi, self.scanControlUi ) def addPushDestination(self, name, destination): # self.fitWidget.addPushDestination(name, destination) pass def setPulseProgramUi(self, pulseProgramUi): self.pulseProgramUi = pulseProgramUi self.pulseProgramUi.addExperiment('Sequence') def onClear(self): self.dockWidget.setShown(True) self.StatusMessage.emit("test Clear not implemented") def onSave(self): self.StatusMessage.emit("test Save not implemented") def onStart(self): self.scanType = self.scanControlWidget.scanRepeatComboBox.currentIndex() #start added if self.scanType == 0: self.startScan() elif self.scanType == 1: self.createAverageScan() self.startScan() #end added self.timer = QtCore.QTimer() self.timer.setInterval(10) self.timer.timeout.connect( self.onData ) self.timer.start(10) self.displayUi.onClear() #start added def createAverageScan(self): self.averagePlottedTrace = PlottedTrace(TraceCollection(), self._graphicsView, pens.penList) self.averagePlottedTrace.trace.name = "test average trace" self.averagePlottedTrace.trace.description["comment"] = "average trace comment" self.averagePlottedTrace.trace.filenameCallback = functools.partial(self.traceFilename, '') self.traceui.addTrace(self.averagePlottedTrace, pen=0) #end added def startScan(self): if self.plottedTrace is not None and self.traceui.unplotLastTrace(): self.plottedTrace.plot(0) self.plottedTrace = PlottedTrace(TraceCollection(), self._graphicsView, pens.penList) self.xvalue = 0 self.phase = 0 #random.uniform(0,2*numpy.pi) self.plottedTrace.trace.x = numpy.array([self.xvalue]) c = numpy.sin( self.xvalue + self.phase)**2 self.plottedTrace.trace.y = numpy.array([random.gauss(c, 0.1)])#c*(1-c))]) self.plottedTrace.trace.top = numpy.array([0.05]) self.plottedTrace.trace.bottom = numpy.array([0.05]) self.plottedTrace.trace.filenameCallback = functools.partial( self.traceFilename, '' ) if self.scanType == 0: self.plottedTrace.trace.name = "test trace" self.plottedTrace.trace.description["comment"] = "My Comment" self.traceui.addTrace(self.plottedTrace, pen=-1) #start added elif self.scanType == 1: self.traceui.addTrace(self.plottedTrace, pen=-1, parentTrace=self.averagePlottedTrace) self.plottedTrace.trace.name = "test trace {0}".format(self.averagePlottedTrace.childCount()) self.plottedTrace.trace.description["comment"] = "My Comment {0}".format(self.averagePlottedTrace.childCount()) #end added def onData(self): self.xvalue += 0.05 self.plottedTrace.trace.x = numpy.append( self.plottedTrace.trace.x, self.xvalue ) c = numpy.sin( self.xvalue + self.phase)**2 value = random.gauss(c, 0.1)#c*(1-c)) self.plottedTrace.trace.y = numpy.append( self.plottedTrace.trace.y, value ) self.plottedTrace.trace.top = numpy.append( self.plottedTrace.trace.top, 0.05) self.plottedTrace.trace.bottom = numpy.append( self.plottedTrace.trace.bottom, 0.05) self.displayUi.add( [value] ) self.plottedTrace.replot() if self.xvalue > 500: if self.scanType == 0: self.onStop() #start added elif self.scanType == 1: self.averagePlottedTrace.averageChildren() self.averagePlottedTrace.plot(7) #average plot is in black self.startScan() #end added def onStop(self): if hasattr(self, 'timer'): self.timer.stop() def onPause(self): self.StatusMessage.emit("test Pause not implemented") def activate(self): self.StatusMessage.emit("test active") MainWindowWidget.MainWindowWidget.activate(self) def deactivate(self): self.StatusMessage.emit("test not active") MainWindowWidget.MainWindowWidget.deactivate(self) def saveConfig(self): self.config['testWidget.MainWindow.State'] = QtWidgets.QMainWindow.saveState(self) self.traceui.saveConfig() self.fitWidget.saveConfig() def traceFilename(self, pattern): directory = DataDirectory.DataDirectory() path, _ = QtWidgets.QFileDialog.getSaveFileName(self, 'Save file', directory.path()) return path def setGlobalVariablesUi(self, globalVariablesUi ): self.globalVariables = globalVariablesUi.variables self.globalVariablesChanged = globalVariablesUi.valueChanged self.globalVariablesUi = globalVariablesUi
def createAverageScan(self): self.averagePlottedTrace = PlottedTrace(TraceCollection(), self._graphicsView, pens.penList) self.averagePlottedTrace.trace.name = "test average trace" self.averagePlottedTrace.trace.description["comment"] = "average trace comment" self.averagePlottedTrace.trace.filenameCallback = functools.partial(self.traceFilename, '') self.traceui.addTrace(self.averagePlottedTrace, pen=0)
def doCreatePlot(self, xDataDef, yDataDef, plotName, update=False): ref, _ = self.cache.get((xDataDef, yDataDef), (lambda: None, None)) plottedTrace = ref( ) if update else None # get plottedtrace from the weakref if exists # Assemble data xData, yData, bottomData, topData = self.getData(xDataDef, yDataDef) if len(xData) == 0: logging.getLogger(__name__).warning("Nothing to plot") else: if xDataDef == ('measurement', None, 'startDate'): epoch = datetime(1970, 1, 1) - timedelta( seconds=self.utcOffset ) if xData[0].tzinfo is None else datetime(1970, 1, 1).replace( tzinfo=pytz.utc) time = numpy.array([(value - epoch).total_seconds() for value in xData]) if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = "{0} versus {1}".format( yDataDef[2], xDataDef[2]) _, yUnit = ( None, self.settings.yUnit) if self.settings.yUnit else ( yData[0].m, "{:~}".format(yData[0].units)) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = time if topData is not None and bottomData is not None: trace.top = numpy.array( [d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array( [d.m_as(yUnit) for d in bottomData]) traceui, item, view = self.plotWindowIndex[plotName] plottedTrace = PlottedTrace(trace, view, xAxisLabel="local time", windowName=item) #plottedTrace.trace.filenameCallback = partial( WeakMethod.ref(plottedTrace.traceFilename), "" ) traceui.addTrace(plottedTrace, pen=-1) traceui.resizeColumnsToContents() self.cache[(xDataDef, yDataDef)] = (weakref.ref(plottedTrace), (xDataDef, yDataDef, plotName)) trace.description["traceFinalized"] = datetime.now( pytz.utc) else: # update the existing plotted trace trace = plottedTrace.trace _, yUnit = (None, self.settings.yUnit ) if self.settings.yUnit else mag_unit( yData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = time if topData is not None and bottomData is not None: trace.top = numpy.array( [d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array( [d.m_as(yUnit) for d in bottomData]) trace.description["traceFinalized"] = datetime.now( pytz.utc) plottedTrace.replot() else: if plottedTrace is None: # make a new plotted trace trace = TraceCollection(record_timestamps=False) trace.name = "{0} versus {1}".format( yDataDef[2], xDataDef[2]) _, yUnit = (None, self.settings.yUnit ) if self.settings.yUnit else mag_unit( yData[0]) _, xUnit = (None, self.settings.xUnit ) if self.settings.xUnit else mag_unit( xData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = numpy.array([d.m_as(xUnit) for d in xData]) if topData is not None and bottomData is not None: trace.top = numpy.array( [d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array( [d.m_as(yUnit) for d in bottomData]) traceui, item, view = self.plotWindowIndex[plotName] plottedTrace = PlottedTrace(trace, view, xAxisLabel=xDataDef[2], windowName=item) traceui.addTrace(plottedTrace, pen=-1) traceui.resizeColumnsToContents() self.cache[(xDataDef, yDataDef)] = (weakref.ref(plottedTrace), (xDataDef, yDataDef, plotName)) trace.description["traceFinalized"] = datetime.now( pytz.utc) else: # update the existing plotted trace trace = plottedTrace.trace _, yUnit = (None, self.settings.yUnit ) if self.settings.yUnit else mag_unit( yData[0]) _, xUnit = (None, self.settings.xUnit ) if self.settings.xUnit else mag_unit( xData[0]) trace.y = numpy.array([d.m_as(yUnit) for d in yData]) trace.x = numpy.array([d.m_as(xUnit) for d in xData]) if topData is not None and bottomData is not None: trace.top = numpy.array( [d.m_as(yUnit) for d in topData]) trace.bottom = numpy.array( [d.m_as(yUnit) for d in bottomData]) plottedTrace.replot() trace.description["traceFinalized"] = datetime.now( pytz.utc)
class PicoampMeterControl(Base, Form): def __init__(self, config, traceui, plotdict, parent, meter, meter_2=None, meter_3=None): self.config = config self.traceui = traceui self.plotDict = plotdict self.parent = parent self.meter = meter self.meter_2 = meter_2 self.meter_3 = meter_3 super(PicoampMeterControl, self).__init__() self.meterState = self.config.get("PicoampMeterState", MeterState()) self.trace = None self.stopRequested = False self.scanMode = "V" self.loggingActive = False self.startTime = datetime.now() self.scanRunning = False def writeAll(self): self.onVoltage(self.meterState.voltage) self.onEnableOutput(self.meterState.voltageEnabled) self.onCurrentLimit(self.meterState.currentLimit) self.onVoltageRange(self.meterState.voltageRange) self.onZeroCheck(self.meterState.zeroCheck) self.onAutoRange(self.meterState.autoRange) def writeAll_2(self): self.onVoltage_2(self.meterState.voltage_2) self.onEnableOutput_2(self.meterState.voltageEnabled_2) self.onCurrentLimit_2(self.meterState.currentLimit_2) self.onVoltageRange_2(self.meterState.voltageRange_2) self.onZeroCheck_2(self.meterState.zeroCheck_2) self.onAutoRange_2(self.meterState.autoRange_2) def writeAll_3(self): self.onVoltage_3(self.meterState.voltage_3) self.onEnableOutput_3(self.meterState.voltageEnabled_3) self.onCurrentLimit_3(self.meterState.currentLimit_3) self.onVoltageRange_3(self.meterState.voltageRange_3) self.onZeroCheck_3(self.meterState.zeroCheck_3) self.onAutoRange_3(self.meterState.autoRange_3) def setupUi(self, parent): super(PicoampMeterControl, self).setupUi(parent) self.instrumentEdit.setText(self.meterState.instrument) self.instrumentEdit.returnPressed.connect(self.openInstrument) self.instrumentEdit_2.setText(self.meterState.instrument_2) self.instrumentEdit_2.returnPressed.connect(self.openInstrument_2) self.instrumentEdit_3.setText(self.meterState.instrument_3) self.instrumentEdit_3.returnPressed.connect(self.openInstrument_3) self.enableMeasurementBox.stateChanged.connect(self.onZeroCheck) self.enableMeasurementBox.setChecked(not self.meterState.zeroCheck) self.enableMeasurementBox_2.stateChanged.connect(self.onZeroCheck_2) self.enableMeasurementBox_2.setChecked(not self.meterState.zeroCheck_2) self.enableMeasurementBox_3.stateChanged.connect(self.onZeroCheck_3) self.enableMeasurementBox_3.setChecked(not self.meterState.zeroCheck_3) self.autoRangeBox.stateChanged.connect(self.onAutoRange) self.autoRangeBox.setChecked(self.meterState.autoRange) self.autoRangeBox_2.stateChanged.connect(self.onAutoRange_2) self.autoRangeBox_2.setChecked(self.meterState.autoRange_2) self.autoRangeBox_3.stateChanged.connect(self.onAutoRange_3) self.autoRangeBox_3.setChecked(self.meterState.autoRange_3) self.voltageRangeSelect.currentIndexChanged[int].connect( self.onVoltageRange) self.voltageRangeSelect.setCurrentIndex( self.voltageRangeSelect.findText("{0}".format( self.meterState.voltageRange))) self.voltageRangeSelect_2.currentIndexChanged[int].connect( self.onVoltageRange_2) self.voltageRangeSelect_2.setCurrentIndex( self.voltageRangeSelect_2.findText("{0}".format( self.meterState.voltageRange_2))) self.voltageRangeSelect_3.currentIndexChanged[int].connect( self.onVoltageRange_3) self.voltageRangeSelect_3.setCurrentIndex( self.voltageRangeSelect_3.findText("{0}".format( self.meterState.voltageRange_3))) self.currentLimitSelect.currentIndexChanged[int].connect( self.onCurrentLimit) self.currentLimitSelect.setCurrentIndex(self.meterState.currentLimit) self.currentLimitSelect_2.currentIndexChanged[int].connect( self.onCurrentLimit_2) self.currentLimitSelect_2.setCurrentIndex( self.meterState.currentLimit_2) self.currentLimitSelect_3.currentIndexChanged[int].connect( self.onCurrentLimit_3) self.currentLimitSelect_3.setCurrentIndex( self.meterState.currentLimit_3) self.enableOutputBox.stateChanged.connect(self.onEnableOutput) self.enableOutputBox.setChecked(False) self.enableOutputBox_2.stateChanged.connect(self.onEnableOutput) self.enableOutputBox_2.setChecked(False) self.enableOutputBox_3.stateChanged.connect(self.onEnableOutput_2) self.enableOutputBox_3.setChecked(False) self.voltageEdit.valueChanged.connect(self.onVoltage) self.voltageEdit.setValue(self.meterState.voltage) self.voltageEdit_2.valueChanged.connect(self.onVoltage_2) self.voltageEdit_2.setValue(self.meterState.voltage_2) self.voltageEdit_3.valueChanged.connect(self.onVoltage_3) self.voltageEdit_3.setValue(self.meterState.voltage_3) self.startEdit.setValue(self.meterState.start) self.startEdit.valueChanged.connect( partial(self.onValueChanged, 'start')) self.stopEdit.setValue(self.meterState.stop) self.stopEdit.valueChanged.connect(partial(self.onValueChanged, 'stop')) self.stepsEdit.setValue(self.meterState.steps) self.stepsEdit.valueChanged.connect( partial(self.onValueChanged, 'steps')) self.settlingDelayEdit.setValue(self.meterState.settlingDelay) self.settlingDelayEdit.valueChanged.connect( partial(self.onValueChanged, 'settlingDelay')) self.timeDeltaEdit.setValue(self.meterState.timeDelta) self.timeDeltaEdit.valueChanged.connect( partial(self.onValueChanged, 'timeDelta')) self.zeroButton.clicked.connect(self.onZero) self.measureButton.clicked.connect(self.onMeasure) self.scanButton.clicked.connect(self.onScan) self.scanTypeCombo.setCurrentIndex(self.meterState.scanType) self.scanTypeCombo.currentIndexChanged[int].connect( partial(self.onValueChanged, 'scanType')) self.filenameEdit.setText(self.meterState.filename) self.filenameEdit.textChanged.connect( partial(self.onStringValueChanged, 'filename')) self.logButton.clicked.connect(self.onLogging) def onLogging(self, checked): if checked: if not self.loggingActive: self.startLogging() else: self.stopLogging() def startLogging(self): self.trace = TraceCollection() # self.trace.addColumn('voltage_2') # self.trace.addColumn('voltage_3') # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.trace.name = "scan" self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Time']['view'], pens.penList) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Time']['view'], yColumn='current_3', penList=pens.penList ) self.voltagePlottedTrace = PlottedTrace( self.trace, self.plotDict['Voltage']['view'], yColumn='voltage', penList=pens.penList) # self.voltagePlottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_2', penList=pens.penList ) # self.voltagePlottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Voltage']['view'], yColumn='voltage_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) self.voltagePlottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.voltagePlottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.stopRequested = False QtCore.QTimer.singleShot(0, self.takeLoggingPoint) self.loggingActive = True self.startTime = time.time() def takeLoggingPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append(self.trace.x, time.time() - self.startTime) self.trace.y = numpy.append(self.trace.y, value) self.trace['voltage'] = numpy.append(self.trace['voltage'], self.meterState.voltage.m_as('V')) # self.trace.voltage_2 = numpy.append( self.trace.voltage_2, self.meterState.voltage_2.m_as('V') ) # self.trace.voltage_3 = numpy.append( self.trace.voltage_3, self.meterState.voltage_3.m_as('V') ) if not self.traceAdded: self.traceui.addTrace(self.plottedTrace, pen=-1) self.traceui.addTrace(self.voltagePlottedTrace, pen=0) # self.traceui.addTrace( self.plottedTrace_2, pen=-1) # self.traceui.addTrace( self.voltagePlottedTrace_2, pen=0 ) # self.traceui.addTrace( self.plottedTrace_3, pen=-1) # self.traceui.addTrace( self.voltagePlottedTrace_3, pen=0 ) self.traceAdded = True else: self.plottedTrace.replot() self.voltagePlottedTrace.replot() # self.plottedTrace_2.replot() # self.voltagePlottedTrace_3.replot() # self.plottedTrace_2.replot() # self.voltagePlottedTrace_3.replot() if self.stopRequested: self.finalizeScan() self.loggingActive = False else: QtCore.QTimer.singleShot(self.meterState.timeDelta.m_as('ms'), self.takeLoggingPoint) def stopLogging(self): self.stopRequested = True def onScan(self): self.startScan() def onStop(self): self.stopRequested = True def startScan(self): if not self.scanRunning: self.scanList = scanList(self.meterState.start, self.meterState.stop, self.meterState.steps, self.meterState.scanType) if self.meterState.scanType in [4, 5]: index = find_index_nearest(self.scanList, self.meterState.voltage) self.scanList = numpy.roll(self.scanList, -index) self.currentIndex = 0 self.trace = TraceCollection() self.trace.name = "scan" # self.trace.addColumn('current_2') # self.trace.addColumn('current_3') self.plottedTrace = PlottedTrace(self.trace, self.plotDict['Scan']['view'], pens.penList) # self.plottedTrace_2 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_2', penList=pens.penList ) # self.plottedTrace_3 = PlottedTrace(self.trace, self.plotDict['Scan']['view'], yColumn='current_3', penList=pens.penList ) self.plottedTrace.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename) # self.plottedTrace_2.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) # self.plottedTrace_3.trace.filenameCallback = partial( self.plottedTrace.traceFilename, self.meterState.filename ) self.traceAdded = False self.meter.setZeroCheck(False) # self.meter_2.setZeroCheck(False) # self.meter_3.setZeroCheck(False) self.meter.voltageEnable(True) # self.meter_2.voltageEnable(True) # self.meter_3.voltageEnable(True) self.stopRequested = False print("startScan") self.scanRunning = True QtCore.QTimer.singleShot(0, self.initPoint) def initPoint(self): if self.currentIndex < len(self.scanList) and not self.stopRequested: self.meter.setVoltage(self.scanList[self.currentIndex]) QtCore.QTimer.singleShot(self.meterState.settlingDelay.m_as('ms'), self.takeScanPoint) else: self.meter.setVoltage(self.meterState.voltage) self.finalizeScan() def takeScanPoint(self): value = float(self.meter.read()) self.trace.x = numpy.append(self.trace.x, self.scanList[self.currentIndex].m_as('V')) self.trace.y = numpy.append(self.trace.y, value) # self.trace.current_2 = numpy.append( self.trace.current_2, float( self.meter_2.read() ) ) # self.trace.current_3 = numpy.append( self.trace.current_3, float( self.meter_3.read() ) ) if not self.traceAdded: self.traceui.addTrace(self.plottedTrace, pen=-1) # self.traceui.addTrace( self.plottedTrace_2, pen=-1) # self.traceui.addTrace( self.plottedTrace_3, pen=-1) self.traceAdded = True else: self.plottedTrace.replot() # self.plottedTrace_2.replot() # self.plottedTrace_3.replot() self.currentIndex += 1 QtCore.QTimer.singleShot(0, self.initPoint) def finalizeScan(self): self.trace.description["traceFinalized"] = datetime.now() self.trace.resave(saveIfUnsaved=False) self.scanRunning = False def onMeasure(self): value = float(self.meter.read()) self.currentLabel.setText(str(value)) def onMeasure_2(self): value = float(self.meter_2.read()) self.currentLabel_2.setText(str(value)) def onMeasure_3(self): value = float(self.meter_3.read()) self.currentLabel_3.setText(str(value)) def onZero(self): self.meter.zero() def onZero_2(self): self.meter_2.zero() def onZero_3(self): self.meter_3.zero() def onValueChanged(self, attr, value): setattr(self.meterState, attr, value) def onStringValueChanged(self, attr, value): setattr(self.meterState, attr, str(value)) def onVoltage(self, value): raw = value.m_as("V") self.meter.setVoltage(raw) self.meterState.voltage = value def onVoltage_2(self, value): raw = value.m_as("V") self.meter_2.setVoltage(raw) self.meterState.voltage_2 = value def onVoltage_3(self, value): raw = value.m_as("V") self.meter_3.setVoltage(raw) self.meterState.voltage_3 = value def onEnableOutput(self, value): enable = value == QtCore.Qt.Checked self.meter.voltageEnable(enable) self.meterState.voltageEnabled = enable def onEnableOutput_2(self, value): enable = value == QtCore.Qt.Checked self.meter_2.voltageEnable(enable) self.meterState.voltageEnabled_2 = enable def onEnableOutput_3(self, value): enable = value == QtCore.Qt.Checked self.meter_3.voltageEnable(enable) self.meterState.voltageEnabled_3 = enable currentLimits = [2.5e-5, 2.5e-4, 2.5e-3, 2.5e-2] def onCurrentLimit(self, index): limit = self.currentLimits[index] self.meter.setCurrentLimit(limit) self.meterState.currentLimit = index def onCurrentLimit_2(self, index): limit = self.currentLimits[index] self.meter_2.setCurrentLimit(limit) self.meterState.currentLimit_2 = index def onCurrentLimit_3(self, index): limit = self.currentLimits[index] self.meter_3.setCurrentLimit(limit) self.meterState.currentLimit_3 = index voltageRanges = [10, 50, 500] def onVoltageRange(self, index): vrange = self.voltageRanges[index] self.meter.setVoltageRange(vrange) self.meterState.voltageRange = index def onVoltageRange_2(self, index): vrange = self.voltageRanges[index] self.meter_2.setVoltageRange(vrange) self.meterState.voltageRange_2 = index def onVoltageRange_3(self, index): vrange = self.voltageRanges[index] self.meter_3.setVoltageRange(vrange) self.meterState.voltageRange_3 = index def onZeroCheck(self, value): enable = value != QtCore.Qt.Checked self.meter.setZeroCheck(enable) self.meterState.zeroCheck = enable def onZeroCheck_2(self, value): enable = value != QtCore.Qt.Checked self.meter_2.setZeroCheck(enable) self.meterState.zeroCheck_2 = enable def onZeroCheck_3(self, value): enable = value != QtCore.Qt.Checked self.meter_3.setZeroCheck(enable) self.meterState.zeroCheck_3 = enable def onAutoRange(self, value): enable = value == QtCore.Qt.Checked self.meter.setAutoRange(enable) self.meterState.autoRange = enable def onAutoRange_2(self, value): enable = value == QtCore.Qt.Checked self.meter_2.setAutoRange(enable) self.meterState.autoRange_2 = enable def onAutoRange_3(self, value): enable = value == QtCore.Qt.Checked self.meter_3.setAutoRange(enable) self.meterState.autoRange_3 = enable def openInstrument(self): self.meterState.instrument = str(self.instrumentEdit.text()) self.meter.open(self.meterState.instrument) self.meter.reset() self.writeAll() def openInstrument_2(self): self.meterState.instrument_2 = str(self.instrumentEdit_2.text()) self.meter_2.open(self.meterState.instrument_2) self.meter_2.reset() self.writeAll_2() def openInstrument_3(self): self.meterState.instrument_3 = str(self.instrumentEdit_3.text()) self.meter_3.open(self.meterState.instrument_3) self.meter_3.reset() self.writeAll_3() def saveConfig(self): self.config["PicoampMeterState"] = self.meterState
class DataHandling(object): def __init__(self): self.calibration = None self.decimation = None self.persistenceDecimation = None self.plotName = None self.persistence = None self.calibrationCache = dict() self.decimationCache = dict() self.persistenceCache = dict() self.persistenceDecimationCache = dict() self.trace = None self.plottedTrace = None self.filename = None self.maximumPoints = 0 @property def decimationClass(self): return self.decimation.name if self.decimation else 'None' @decimationClass.setter def decimationClass(self, name): if self.decimation is not None: self.decimationCache[self.decimation.name] = self.decimation self.decimation = self.decimationCache.get(name, decimationDict[name]() ) if name != 'None' else None self.trace = None @property def persistenceDecimationClass(self): return self.persistenceDecimation.name if self.persistenceDecimation else 'None' @persistenceDecimationClass.setter def persistenceDecimationClass(self, name): if self.persistenceDecimation is not None: self.persistenceDecimationCache[self.persistenceDecimation.name] = self.persistenceDecimation self.persistenceDecimation = self.persistenceDecimationCache.get(name, decimationDict[name]() ) if name != 'None' else None @property def calibrationClass(self): return self.decimation.name if self.calibration else 'None' @calibrationClass.setter def calibrationClass(self, name): if self.calibration is not None: self.calibrationCache[self.calibration.name] = self.calibration self.calibration = self.calibrationCache.get(name, calibrationDict[name]() ) if name != 'None' else None @property def persistenceClass(self): return self.persistence.name if self.persistence else 'None' @persistenceClass.setter def persistenceClass(self, name): if self.persistence is not None: self.persistenceCache[self.persistence.name] = self.persistence self.persistence = self.persistenceCache.get(name, persistenceDict[name]() ) if name != 'None' else None def __getstate__(self): odict = self.__dict__.copy() del odict['trace'] del odict['plottedTrace'] return odict def __setstate__(self, state): self.__dict__.update(state) self.trace = None self.plottedTrace = None def finishTrace(self): self.trace = None def decimate(self, takentime, value, callback): if value is not None: if self.decimation is None: callback( (takentime, value, None, None) ) else: self.decimation.decimate( takentime, value, callback ) def persistenceDecimate(self, takentime, value, callback ): if self.persistenceDecimation is None: callback( (takentime, value, None, None) ) else: self.persistenceDecimation.decimate(takentime, value, callback) def persist(self, space, source, time, value, minvalue, maxvalue): if self.persistence is not None: self.persistence.persist(space, source, time, value, minvalue, maxvalue) def convert(self, data ): takentime, value, minVal, maxVal = data if self.calibration is None: return data calMin = self.calibration.convertMagnitude(minVal) calMax = self.calibration.convertMagnitude(maxVal) calValue = self.calibration.convertMagnitude(value) return (takentime, calValue, calMin, calMax) def addPoint(self, traceui, plot, data, source ): takentime, value, minval, maxval = data if is_Q(value): value, unit = value.m, "{:~}".format(value.units) if is_Q(minval): minval = minval.m, "{:~}".format(minval.units) if is_Q(maxval): maxval = maxval.m, "{:~}".format(maxval.units) if not isinstance(value, str): #ignore erroneous values like 'oor' if self.trace is None: self.trace = TraceCollection(record_timestamps=True) self.trace.name = source self.trace.x = numpy.array( [takentime] ) self.trace.y = numpy.array( [value] ) if maxval is not None: self.trace.top = numpy.array( [maxval - value]) if minval is not None: self.trace.bottom = numpy.array( [value - minval]) self.plottedTrace = PlottedTrace(self.trace, plot, pens.penList, xAxisUnit = "s", xAxisLabel = "time", windowName=self.plotName) # self.plottedTrace.trace.filenameCallback = functools.partial( WeakMethod.ref(self.plottedTrace.traceFilename), self.filename ) traceui.addTrace( self.plottedTrace, pen=-1) traceui.resizeColumnsToContents() else: if self.maximumPoints==0 or len(self.trace.x)<self.maximumPoints: self.trace.x = numpy.append( self.trace.x, takentime ) self.trace.y = numpy.append( self.trace.y, value ) if maxval is not None: self.trace.top = numpy.append( self.trace.top, maxval - value ) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom, value - minval ) else: maxPoints = int(self.maximumPoints) self.trace.x = numpy.append( self.trace.x[-maxPoints:], takentime ) self.trace.y = numpy.append( self.trace.y[-maxPoints:], value ) if maxval is not None: self.trace.top = numpy.append( self.trace.top[-maxPoints:], maxval - value ) if minval is not None: self.trace.bottom = numpy.append( self.trace.bottom[-maxPoints:], value - minval ) self.plottedTrace.replot()