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 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)
Beispiel #3
0
 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()
Beispiel #4
0
 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 )
Beispiel #5
0
 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 loadReferenceData(self):
     for name in ['ZeroBright', 'OneBright', 'TwoBright']:
         filename = path.join(self.settings['Path'], self.settings[name])
         if filename:
             if path.exists(filename):
                 t = TraceCollection()
                 t.loadTrace(filename)
                 yColumnName = t.tracePlottingList[0].yColumn
                 setattr(self.fitFunction, name, self.normalizeHistogram(t[yColumnName]))
             else:
                 logging.getLogger(__name__).error("Reference data file '{0}' does not exist.".format(filename))
         else:
             logging.getLogger(__name__).error("Reference filename invalid.")
     self.dataLoaded = 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 )
Beispiel #8
0
 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)    
Beispiel #9
0
 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)
Beispiel #10
0
 def onSave(self):
     logger = logging.getLogger(__name__)
     self.plotDisplayData = self.settingsUi.settings.plotDisplayData
     for plotName in self.plotDisplayData.keys():
         for n in range(20):
             if len(self.xData[n])>0 and len(self.yData[n])>0:
                 trace = TraceCollection()
                 trace.x = self.xData[n]
                 trace.y = self.yData[n]
                 if n < 16:
                     trace.description["counter"] = str(plotName)
                 else:
                     trace.description["ADC"] = str(plotName)
                 filename, _ = DataDirectory().sequencefile("DedicatedCounter_{0}.txt".format(n))
                 trace.addTracePlotting( TracePlotting(name="Counter {0}".format(n)) )
                 trace.save()
     logger.info("saving dedicated counters")
Beispiel #11
0
 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()
Beispiel #12
0
 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
Beispiel #13
0
 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 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()
Beispiel #16
0
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
 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)
Beispiel #18
0
 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 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 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)
Beispiel #21
0
        self.lastPlotTime = time.time()
        self.needsReplot = False

    def setView(self, graphicsView ):
        self.removePlots()
        self._graphicsView = graphicsView
        self.plot(-1)
            
    @property
    def fitFunction(self):
        return self.tracePlotting.fitFunction if self.tracePlotting else None
    
    @fitFunction.setter
    def fitFunction(self, fitfunction):
        self.tracePlotting.fitFunction = fitfunction

#     def __del__(self):
#         super(PlottedTrace, self)__del__()

if __name__=="__main__":
    from trace.TraceCollection import TraceCollection
    import gc
    import sys
    plottedTrace = PlottedTrace(TraceCollection(), None, pens.penList)
    print(sys.getrefcount(plottedTrace))
    plottedTrace = None
    del plottedTrace
    gc.collect()
    input("Press Enter")
                
Beispiel #22
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 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