示例#1
0
    def createChannelWidget(self, ch, daqName=None):
        conf = self.dev._DGConfig[ch]
        p = PlotWidget(self)

        units = ""
        if "units" in conf:
            units = conf["units"]

        # p.setAxisTitle(PlotWidget.yLeft, ch+units)
        p.setLabel("left", text=ch, units=units)
        # print "Plot label:", ch, units
        self.plots[ch] = p

        p.registerPlot(self.dev.name() + "." + ch)

        if conf["type"] in ["ao", "do"]:
            w = OutputChannelGui(self, ch, conf, p, self.dev, self.task, daqName)
            # QtCore.QObject.connect(w, QtCore.SIGNAL('sequenceChanged'), self.sequenceChanged)
            w.sigSequenceChanged.connect(self.sequenceChanged)
        elif conf["type"] in ["ai", "di"]:
            w = InputChannelGui(self, ch, conf, p, self.dev, self.task, daqName)
        else:
            raise Exception("Unrecognized device type '%s'" % conf["type"])
        # w.setUnits(units)
        self.channels[ch] = w

        return (w, p)
示例#2
0
文件: taskGUI.py 项目: ablot/acq4
 def createChannelWidget(self, ch, daqName=None):
     conf = self.dev._DGConfig[ch]
     p = PlotWidget(self)
     
     units = ''
     if 'units' in conf:
         units = conf['units']
         
     #p.setAxisTitle(PlotWidget.yLeft, ch+units)
     p.setLabel('left', text=ch, units=units)
     #print "Plot label:", ch, units
     self.plots[ch] = p
     
     p.registerPlot(self.dev.name() + '.' + ch)
     
     if conf['type'] in ['ao', 'do']:
         w = OutputChannelGui(self, ch, conf, p, self.dev, self.taskRunner, daqName)
         #QtCore.QObject.connect(w, QtCore.SIGNAL('sequenceChanged'), self.sequenceChanged)
         w.sigSequenceChanged.connect(self.sequenceChanged)
     elif conf['type'] in ['ai', 'di']:
         w = InputChannelGui(self, ch, conf, p, self.dev, self.taskRunner, daqName)
     else:
         raise Exception("Unrecognized device type '%s'" % conf['type'])
     # w.setUnits(units)
     self.channels[ch] = w
     
     return (w, p)
示例#3
0
    def createChannelWidget(self, ch, daqName=None):
        conf = self.dev._DGConfig[ch]
        p = PlotWidget(self)

        units = ''
        if 'units' in conf:
            units = conf['units']

        p.setLabel('left', text=ch, units=units)
        self.plots[ch] = p

        p.registerPlot(self.dev.name() + '.' + ch)

        if conf['type'] in ['ao', 'do']:
            w = OutputChannelGui(self, ch, conf, p, self.dev, self.taskRunner,
                                 daqName)
            w.sigSequenceChanged.connect(self.sequenceChanged)
        elif conf['type'] in ['ai', 'di']:
            w = InputChannelGui(self, ch, conf, p, self.dev, self.taskRunner,
                                daqName)
        else:
            raise Exception("Unrecognized device type '%s'" % conf['type'])
        self.channels[ch] = w

        return (w, p)
示例#4
0
文件: PatchWindow.py 项目: hiuwo/acq4
    def __init__(self, dm, clampName):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle(clampName)
        self.startTime = None
        self.redrawCommand = 1
        
        self.analysisItems = {
            'inputResistance': u'Ω', 
            'accessResistance': u'Ω',
            'capacitance': 'F',
            'restingPotential': 'V', 
            'restingCurrent': 'A', 
            'fitError': ''
        }
        
        self.params = {
            'mode': 'vc',
            'rate': 400000,
            'downsample': 10,
            'cycleTime': .2,
            'recordTime': 0.1,
            'delayTime': 0.03,
            'pulseTime': 0.05,
            'icPulse': -30e-12,
            'vcPulse': -10e-3,
            'icHolding': 0,
            'vcHolding': -65e-3,
            'icHoldingEnabled': False,
            'icPulseEnabled': True,
            'vcHoldingEnabled': False,
            'vcPulseEnabled': True,
            'drawFit': True,
            'average': 1,
        }
        
        
        self.paramLock = Mutex(QtCore.QMutex.Recursive)

        self.manager = dm
        self.clampName = clampName
        self.thread = PatchThread(self)
        self.cw = QtGui.QWidget()
        self.setCentralWidget(self.cw)
        self.ui = Ui_Form()
        self.ui.setupUi(self.cw)
        #self.logBtn = LogButton("Log")
        #self.statusBar().addPermanentWidget(self.logBtn)
        self.setStatusBar(StatusBar())

        self.stateFile = os.path.join('modules', self.clampName + '_ui.cfg')
        uiState = Manager.getManager().readConfigFile(self.stateFile)
        if 'geometry' in uiState:
            geom = QtCore.QRect(*uiState['geometry'])
            self.setGeometry(geom)
        if 'window' in uiState:
            ws = QtCore.QByteArray.fromPercentEncoding(uiState['window'])
            self.restoreState(ws)
            
        self.ui.splitter_2.setSizes([self.width()/4, self.width()*3./4.])


        self.plots = {}
        for k in self.analysisItems:
            p = PlotWidget()
            p.setLabel('left', text=k, units=self.analysisItems[k])
            self.ui.plotLayout.addWidget(p)
            self.plots[k] = p
        #irp = self.plots['inputResistance']
        #irp.setManualYScale()
        #irp.setYLog(True)
        #irp.setYRange(1e6, 1e11)
            
        
        self.ui.icPulseSpin.setOpts(dec=True, step=1, minStep=1e-12, bounds=[None,None], siPrefix=True, suffix='A')
        self.ui.vcPulseSpin.setOpts(dec=True, step=1, minStep=1e-3, bounds=[None,None], siPrefix=True, suffix='V')
        self.ui.icHoldSpin.setOpts(dec=True, step=1, minStep=1e-12, bounds=[None,None], siPrefix=True, suffix='A')
        self.ui.vcHoldSpin.setOpts(dec=True, step=1, minStep=1e-3, bounds=[None,None], siPrefix=True, suffix='V')
        self.ui.cycleTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,None], siPrefix=True, suffix='s')
        self.ui.pulseTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,1.], siPrefix=True, suffix='s')
        self.ui.delayTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,1.], siPrefix=True, suffix='s')
        
        
        self.stateGroup = WidgetGroup([
            (self.ui.icPulseSpin, 'icPulse'),
            (self.ui.vcPulseSpin, 'vcPulse'),
            (self.ui.icHoldSpin, 'icHolding'),
            (self.ui.vcHoldSpin, 'vcHolding'),
            (self.ui.icPulseCheck, 'icPulseEnabled'),
            (self.ui.vcPulseCheck, 'vcPulseEnabled'),
            (self.ui.icHoldCheck, 'icHoldingEnabled'),
            (self.ui.vcHoldCheck, 'vcHoldingEnabled'),
            (self.ui.cycleTimeSpin, 'cycleTime'),
            (self.ui.pulseTimeSpin, 'pulseTime'),
            (self.ui.delayTimeSpin, 'delayTime'),
            (self.ui.drawFitCheck, 'drawFit'),
            (self.ui.averageSpin, 'average'),
        ])
        self.stateGroup.setState(self.params)
        
        self.ui.patchPlot.setLabel('left', text='Primary', units='A')
        self.patchCurve = self.ui.patchPlot.plot(pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))
        self.patchFitCurve = self.ui.patchPlot.plot(pen=QtGui.QPen(QtGui.QColor(0, 100, 200)))
        self.ui.commandPlot.setLabel('left', text='Command', units='V')
        self.commandCurve = self.ui.commandPlot.plot(pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))
        
        self.ui.startBtn.clicked.connect(self.startClicked)
        self.ui.recordBtn.clicked.connect(self.recordClicked)
        self.ui.bathModeBtn.clicked.connect(self.bathMode)
        self.ui.patchModeBtn.clicked.connect(self.patchMode)
        self.ui.cellModeBtn.clicked.connect(self.cellMode)
        self.ui.monitorModeBtn.clicked.connect(self.monitorMode)
        self.ui.resetBtn.clicked.connect(self.resetClicked)
        self.thread.finished.connect(self.threadStopped)
        self.thread.sigNewFrame.connect(self.handleNewFrame)
        self.ui.vcModeRadio.toggled.connect(self.updateParams)
        self.stateGroup.sigChanged.connect(self.updateParams)
                
        ## Configure analysis plots, curves, and data arrays
        self.analysisCurves = {}
        self.analysisData = {'time': []}
        for n in self.analysisItems:
            w = getattr(self.ui, n+'Check')
            w.clicked.connect(self.showPlots)
            p = self.plots[n]
            self.analysisCurves[n] = p.plot(pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))
            for suf in ['', 'Std']:
                self.analysisData[n+suf] = []
        self.showPlots()
        self.updateParams()
        self.show()
        self.bathMode()
示例#5
0
文件: PatchWindow.py 项目: ablot/acq4
    def __init__(self, dm, clampName, modes):
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle(clampName)
        self.startTime = None
        self.redrawCommand = 1
        
        self.analysisItems = {
            'inputResistance': u'Ω', 
            'accessResistance': u'Ω',
            'capacitance': 'F',
            'restingPotential': 'V', 
            'restingCurrent': 'A', 
            'fitError': ''
        }
        
        self.params = modes.pop('default')
        self.modes = modes
        self.stylesheet = {}
        
        self.paramLock = Mutex(QtCore.QMutex.Recursive)
        
        self.manager = dm
        self.clampName = clampName
        self.thread = PatchThread(self)
        self.cw = QtGui.QWidget()
        self.setCentralWidget(self.cw)
        self.ui = Ui_Form()
        self.ui.setupUi(self.cw)
        self.setStatusBar(StatusBar())
        
        # Create one button for each configured mode
        row = None
        self.modeRows = []
        rowLen = 0
        def mkModeCallback(name):
            return lambda: self.setMode(name)
        
        for modeName, mode in modes.items():
            if modeName == 'default':
                continue
            if row is None:
                row = QtGui.QWidget()
                layout = QtGui.QHBoxLayout()
                row.setLayout(layout)
                self.ui.modeLayout.addWidget(row)
                self.modeRows.append(row)
            btn = QtGui.QPushButton(modeName)
            layout.addWidget(btn)
            rowLen += btn.sizeHint().width()
            if rowLen > 200:
                row = None
                rowLen = 0
            btn.clicked.connect(mkModeCallback(modeName))

        self.stateFile = os.path.join('modules', self.clampName + '_ui.cfg')
        uiState = Manager.getManager().readConfigFile(self.stateFile)
        if 'geometry' in uiState:
            geom = QtCore.QRect(*uiState['geometry'])
            self.setGeometry(geom)
        if 'window' in uiState:
            ws = QtCore.QByteArray.fromPercentEncoding(uiState['window'])
            self.restoreState(ws)
            
        self.ui.splitter_2.setSizes([self.width()/4, self.width()*3./4.])


        self.plots = {}
        for k in self.analysisItems:
            p = PlotWidget()
            p.setLabel('left', text=k, units=self.analysisItems[k])
            self.ui.plotLayout.addWidget(p)
            self.plots[k] = p
        
        self.ui.icPulseSpin.setOpts(dec=True, step=1, minStep=1e-12, bounds=[None,None], siPrefix=True, suffix='A')
        self.ui.vcPulseSpin.setOpts(dec=True, step=1, minStep=1e-3, bounds=[None,None], siPrefix=True, suffix='V')
        self.ui.icHoldSpin.setOpts(dec=True, step=1, minStep=1e-12, bounds=[None,None], siPrefix=True, suffix='A')
        self.ui.vcHoldSpin.setOpts(dec=True, step=1, minStep=1e-3, bounds=[None,None], siPrefix=True, suffix='V')
        self.ui.cycleTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,None], siPrefix=True, suffix='s')
        self.ui.pulseTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,1.], siPrefix=True, suffix='s')
        self.ui.delayTimeSpin.setOpts(dec=True, step=1, minStep=1e-6, bounds=[0,1.], siPrefix=True, suffix='s')
        
        
        self.stateGroup = WidgetGroup([
            (self.ui.icPulseSpin, 'icPulse'),
            (self.ui.vcPulseSpin, 'vcPulse'),
            (self.ui.icHoldSpin, 'icHolding'),
            (self.ui.vcHoldSpin, 'vcHolding'),
            (self.ui.icPulseCheck, 'icPulseEnabled'),
            (self.ui.vcPulseCheck, 'vcPulseEnabled'),
            (self.ui.icHoldCheck, 'icHoldingEnabled'),
            (self.ui.vcHoldCheck, 'vcHoldingEnabled'),
            (self.ui.cycleTimeSpin, 'cycleTime'),
            (self.ui.pulseTimeSpin, 'pulseTime'),
            (self.ui.delayTimeSpin, 'delayTime'),
            (self.ui.drawFitCheck, 'drawFit'),
            (self.ui.averageSpin, 'average'),
        ])
        self.stateGroup.setState(self.params)
        
        self.ui.patchPlot.setLabel('left', text='Primary', units='A')
        self.patchCurve = self.ui.patchPlot.plot(pen=QtGui.QPen(QtGui.QColor(200,200,200)))
        self.patchFitCurve = self.ui.patchPlot.plot(pen=QtGui.QPen(QtGui.QColor(0,100,200)))
        self.ui.commandPlot.setLabel('left', text='Command', units='V')
        self.commandCurve = self.ui.commandPlot.plot(pen=QtGui.QPen(QtGui.QColor(200,200,200)))
        
        self.ui.startBtn.clicked.connect(self.startClicked)
        self.ui.recordBtn.clicked.connect(self.recordClicked)
        self.ui.resetBtn.clicked.connect(self.resetClicked)
        self.thread.finished.connect(self.threadStopped)
        self.thread.sigNewFrame.connect(self.handleNewFrame)
        self.ui.vcModeRadio.toggled.connect(self.updateParams)
        self.stateGroup.sigChanged.connect(self.updateParams)
                
        ## Configure analysis plots, curves, and data arrays
        self.analysisCurves = {}
        self.analysisData = {'time': []}
        for n in self.analysisItems:
            w = getattr(self.ui, n+'Check')
            w.clicked.connect(self.showPlots)
            p = self.plots[n]
            self.analysisCurves[n] = p.plot(pen=QtGui.QPen(QtGui.QColor(200,200,200)))
            for suf in ['', 'Std']:
                self.analysisData[n+suf] = []
        self.showPlots()
        self.updateParams()
        self.show()
示例#6
0
    def __init__(self, dm, config):
        clampName = config['clampDev']
        QtGui.QMainWindow.__init__(self)
        self.setWindowTitle(clampName)
        self.startTime = None
        self.redrawCommand = 1

        self.analysisItems = {
            'inputResistance': u'Ω',
            'accessResistance': u'Ω',
            'capacitance': 'F',
            'restingPotential': 'V',
            'restingCurrent': 'A',
            'fitError': ''
        }

        self.params = {
            'mode': 'vc',
            'rate': config.get('sampleRate', 100000),
            'downsample': config.get('downsample', 3),
            'cycleTime': .2,
            'recordTime': 0.1,
            'delayTime': 0.03,
            'pulseTime': 0.05,
            'icPulse': -30e-12,
            'vcPulse': -10e-3,
            'icHolding': 0,
            'vcHolding': -65e-3,
            'icHoldingEnabled': False,
            'icPulseEnabled': True,
            'vcHoldingEnabled': False,
            'vcPulseEnabled': True,
            'drawFit': True,
            'average': 1,
        }

        self.paramLock = Mutex(QtCore.QMutex.Recursive)

        self.manager = dm
        self.clampName = clampName
        self.thread = PatchThread(self)
        self.cw = QtGui.QWidget()
        self.setCentralWidget(self.cw)
        self.ui = Ui_Form()
        self.ui.setupUi(self.cw)
        #self.logBtn = LogButton("Log")
        #self.statusBar().addPermanentWidget(self.logBtn)
        self.setStatusBar(StatusBar())

        self.stateFile = os.path.join('modules', self.clampName + '_ui.cfg')
        uiState = Manager.getManager().readConfigFile(self.stateFile)
        if 'geometry' in uiState:
            geom = QtCore.QRect(*uiState['geometry'])
            self.setGeometry(geom)
        if 'window' in uiState:
            ws = QtCore.QByteArray.fromPercentEncoding(uiState['window'])
            self.restoreState(ws)

        self.ui.splitter_2.setSizes([self.width() / 4, self.width() * 3. / 4.])
        self.ui.splitter.setStretchFactor(0, 30)
        self.ui.splitter.setStretchFactor(1, 10)

        self.plots = {}
        for k in self.analysisItems:
            p = PlotWidget()
            p.setLabel('left', text=k, units=self.analysisItems[k])
            self.ui.plotLayout.addWidget(p)
            self.plots[k] = p
        irp = self.plots['inputResistance']
        irp.setLogMode(y=True, x=False)
        irp.setYRange(6, 11)

        self.ui.icPulseSpin.setOpts(dec=True,
                                    step=1,
                                    minStep=1e-12,
                                    bounds=[None, None],
                                    siPrefix=True,
                                    suffix='A')
        self.ui.vcPulseSpin.setOpts(dec=True,
                                    step=1,
                                    minStep=1e-3,
                                    bounds=[None, None],
                                    siPrefix=True,
                                    suffix='V')
        self.ui.icHoldSpin.setOpts(dec=True,
                                   step=1,
                                   minStep=1e-12,
                                   bounds=[None, None],
                                   siPrefix=True,
                                   suffix='A')
        self.ui.vcHoldSpin.setOpts(dec=True,
                                   step=1,
                                   minStep=1e-3,
                                   bounds=[None, None],
                                   siPrefix=True,
                                   suffix='V')
        self.ui.cycleTimeSpin.setOpts(dec=True,
                                      step=1,
                                      minStep=1e-6,
                                      bounds=[0, None],
                                      siPrefix=True,
                                      suffix='s')
        self.ui.pulseTimeSpin.setOpts(dec=True,
                                      step=1,
                                      minStep=1e-6,
                                      bounds=[0, 1.],
                                      siPrefix=True,
                                      suffix='s')
        self.ui.delayTimeSpin.setOpts(dec=True,
                                      step=1,
                                      minStep=1e-6,
                                      bounds=[0, 1.],
                                      siPrefix=True,
                                      suffix='s')

        self.stateGroup = WidgetGroup([
            (self.ui.icPulseSpin, 'icPulse'),
            (self.ui.vcPulseSpin, 'vcPulse'),
            (self.ui.icHoldSpin, 'icHolding'),
            (self.ui.vcHoldSpin, 'vcHolding'),
            (self.ui.icPulseCheck, 'icPulseEnabled'),
            (self.ui.vcPulseCheck, 'vcPulseEnabled'),
            (self.ui.icHoldCheck, 'icHoldingEnabled'),
            (self.ui.vcHoldCheck, 'vcHoldingEnabled'),
            (self.ui.cycleTimeSpin, 'cycleTime'),
            (self.ui.pulseTimeSpin, 'pulseTime'),
            (self.ui.delayTimeSpin, 'delayTime'),
            (self.ui.drawFitCheck, 'drawFit'),
            (self.ui.averageSpin, 'average'),
        ])
        self.stateGroup.setState(self.params)

        self.ui.patchPlot.setLabel('left', text='Primary', units='A')
        self.patchCurve = self.ui.patchPlot.plot(
            pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))
        self.patchFitCurve = self.ui.patchPlot.plot(
            pen=QtGui.QPen(QtGui.QColor(0, 100, 200)))
        self.ui.commandPlot.setLabel('left', text='Command', units='V')
        self.commandCurve = self.ui.commandPlot.plot(
            pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))

        self.ui.startBtn.clicked.connect(self.startClicked)
        self.ui.recordBtn.clicked.connect(self.recordClicked)
        self.ui.bathModeBtn.clicked.connect(self.bathMode)
        self.ui.patchModeBtn.clicked.connect(self.patchMode)
        self.ui.cellModeBtn.clicked.connect(self.cellMode)
        self.ui.monitorModeBtn.clicked.connect(self.monitorMode)
        self.ui.resetBtn.clicked.connect(self.resetClicked)
        self.thread.finished.connect(self.threadStopped)
        self.thread.sigNewFrame.connect(self.handleNewFrame)
        self.ui.vcModeRadio.toggled.connect(self.updateParams)
        self.stateGroup.sigChanged.connect(self.updateParams)

        ## Configure analysis plots, curves, and data arrays
        self.analysisCurves = {}
        self.analysisData = {'time': []}
        for n in self.analysisItems:
            w = getattr(self.ui, n + 'Check')
            w.clicked.connect(self.showPlots)
            p = self.plots[n]
            self.analysisCurves[n] = p.plot(
                pen=QtGui.QPen(QtGui.QColor(200, 200, 200)))
            for suf in ['', 'Std']:
                self.analysisData[n + suf] = []
        self.showPlots()
        self.updateParams()
        self.show()
        self.bathMode()
示例#7
0
class LaserTaskGui(DAQGenericTaskGui):
    def __init__(self, dev, task):
        DAQGenericTaskGui.__init__(self, dev, task, ownUi=False)
        
        self.ui = taskTemplate.Ui_Form()
        
        
        self.cache = {}
        
        self.layout = QtGui.QGridLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.setLayout(self.layout)
        
        self.splitter1 = QtGui.QSplitter()
        self.splitter1.setOrientation(QtCore.Qt.Horizontal)
        self.layout.addWidget(self.splitter1)
        
        self.ctrlLayout = QtGui.QVBoxLayout()
        wid1 = QtGui.QWidget()
        wid1.setLayout(self.ctrlLayout)
        self.plotSplitter = QtGui.QSplitter()
        self.plotSplitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter1.addWidget(wid1)
        self.splitter1.addWidget(self.plotSplitter)
        #wid = QtGui.QWidget()
        #hLayout = QtGui.QHBoxLayout()
        #wid.setLayout(hLayout)
        #self.ctrlLayout.addLayout(hLayout)
        wid2 = QtGui.QWidget()
        self.ui.setupUi(wid2)
        self.ctrlLayout.addWidget(wid2)

        if not self.dev.hasPowerIndicator:
            self.ui.checkPowerBtn.setEnabled(False)
            self.ui.checkPowerCheck.hide()
            self.ui.checkPowerCheck.setChecked(False)
        if not self.dev.hasTunableWavelength:
            self.ui.wavelengthWidget.hide()
        
        
        self.powerWidget, self.powerPlot = self.createChannelWidget('power', daqName=self.dev.getDAQName()[0])
        
        ## all we want is the function generator
        self.powerFnGenerator = self.powerWidget.ui.waveGeneratorWidget
        self.powerWidget.hide()
        self.ctrlLayout.addWidget(self.powerFnGenerator)
        self.powerFnGenerator.show()
        
        self.plotSplitter.addWidget(self.powerPlot)
        self.powerWidget.setMeta('y', units='W', siPrefix=True, dec=True, step=0.5, minStep=1e-3, limits=(0, None))
        self.powerWidget.setMeta('xy', units='J', siPrefix=True, dec=True, step=0.5, minStep=1e-6, limits=(0, None))
        self.powerWidget.setMeta('x', units='s', siPrefix=True, dec=True, step=0.5, minStep=1e-6, limits=(None, None))
        
        if self.dev.hasTriggerableShutter:
            #(self.shutterWidget, self.shutterPlot) = self.createChannelWidget('shutter')
            self.shutterPlot = PlotWidget(name='%s.shutter'%self.dev.name)
            self.shutterPlot.setLabel('left', text='Shutter')
            self.plotSplitter.addWidget(self.shutterPlot)
            #self.shutterPlot.hide()
        if self.dev.hasQSwitch:
            #self.qSwitchWidget, self.qSwitchPlot = self.createChannelWidget('qSwitch')
            self.qSwitchPlot = PlotWidget(name='%s.qSwitch'%self.dev.name)
            self.qSwitchPlot.setLabel('left', text='Q-Switch')
            self.plotSplitter.addWidget(self.qSwitchPlot)
            #self.qSwitchPlot.hide()
        if self.dev.hasPCell:
            #self.pCellWidget, self.pCellPlot = self.createChannelWidget('pCell')
            self.pCellPlot = PlotWidget(name='%s.pCell'%self.dev.name)
            self.pCellPlot.setLabel('left', text='Pockel Cell', units='V')
            self.plotSplitter.addWidget(self.pCellPlot)
            #self.pCellPlot.hide()
            
            
        ## catch self.powerWidget.sigDataChanged and connect it to functions that calculate and plot raw shutter and qswitch traces
        self.powerWidget.sigDataChanged.connect(self.powerCmdChanged)
        self.ui.checkPowerBtn.clicked.connect(self.dev.outputPower)
        self.dev.sigOutputPowerChanged.connect(self.laserPowerChanged)
        self.dev.sigSamplePowerChanged.connect(self.samplePowerChanged)
        
        
        self.dev.outputPower()
        
        
    def laserPowerChanged(self, power, valid):
        #samplePower = self.dev.samplePower(power)  ## we should get another signal for this later..
        #samplePower = power*self.dev.getParam('scopeTransmission')
            
        
        ## update label
        if power is None:
            self.ui.outputPowerLabel.setText("?")
        else:
            self.ui.outputPowerLabel.setText(siFormat(power, suffix='W'))
            
        if not valid:
            self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #B00}")
        else:
            self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #000}")
        

    
    def samplePowerChanged(self, power):
        if power is None:
            self.ui.samplePowerLabel.setText("?")
            return
        else:
            self.ui.samplePowerLabel.setText(siFormat(power, suffix='W'))

        if self.dev.hasPCell:
            raise Exception('stub')
        else:
            ## adjust length of pulse to correct for new power
            if self.ui.adjustLengthCheck.isChecked():
                en = {}
                for param in self.powerWidget.ui.waveGeneratorWidget.stimParams:
                    en[param.name()] = param['sum']
                self.powerWidget.setMeta('y', value=power, readonly=True)
                for param in self.powerWidget.ui.waveGeneratorWidget.stimParams:
                    param['sum'] = en[param.name()]
            else:
                self.powerWidget.setMeta('y', value=power, readonly=True)
    
    def saveState(self):
        """Return a dictionary representing the current state of the widget."""
        state = {}
        state['daqState'] = DAQGenericTaskGui.saveState(self)
        return state
        
    def restoreState(self, state):
        """Restore the state of the widget from a dictionary previously generated using saveState"""
        return DAQGenericTaskGui.restoreState(self, state['daqState'])
    
    def describe(self, params=None):
        state = self.saveState()
        ps = state['daqState']['channels']['power']
        desc = {'mode': 'power', 'command': ps['waveGeneratorWidget']}
        return desc
    
    def prepareTaskStart(self):
        ## check power before starting task.
        if self.ui.checkPowerCheck.isChecked():
            power, valid = self.dev.outputPower()  ## request current power from laser
            if power is None:
                raise HelpfulException("The current laser power for '%s' is unknown." % self.dev.name)
            if not valid:
                powerStr = siFormat(power, suffix='W')
                raise HelpfulException("The current laser power for '%s' (%s) is outside the expected range." % (self.dev.name, powerStr))
    
    def generateTask(self, params=None):
        """Return a cmd dictionary suitable for passing to LaserTask."""
        
        ## Params looks like: {'amp': 7} where 'amp' is the name of a sequence parameter, and 7 is the 7th value in the list of 'amp'
        for k,v in params.items():
            if k.startswith('power.'):
                del params[k]
                params[k[6:]] = v
        rate = self.powerWidget.rate
        wave = self.powerWidget.getSingleWave(params)
        rawCmds = self.getChannelCmds(wave, rate)
        #rawCmds = self.cache.get(id(wave), self.dev.getChannelCmds({'powerWaveform':wave}, rate)) ## returns {'shutter': array(...), 'qSwitch':array(..), 'pCell':array(...)}
        
        ### structure task in DAQGeneric-compatible way
        cmd = {}
        for k in rawCmds:
            cmd[k] = {}
            cmd[k]['command'] = rawCmds[k]
            
        cmd['powerWaveform'] = wave  ## just to allow the device task to store this data
        cmd['ignorePowerWaveform'] = True
        return  cmd
    
    def getChannelCmds(self, powerWave, rate):
        key = id(powerWave)
        if key in self.cache:
            rawCmds = self.cache[key]
        else:
            rawCmds = self.dev.getChannelCmds({'powerWaveform':powerWave}, rate) ## returns {'shutter': array(...), 'qSwitch':array(..), 'pCell':array(...)}
            self.cache[key] = rawCmds
        return rawCmds
        
    
    def powerCmdChanged(self):
        self.clearRawPlots()
        self.cache = {}
        rate = self.powerWidget.rate
        
        #### calculate, cache and display sequence waves for shutter/qSwitch/pCell
        params = {}
        ps = self.powerWidget.listSequence()
        for k in ps:
            params[k] = range(len(ps[k]))
        ## get power waveforms
        waves = []
        runSequence(lambda p: waves.append(self.powerWidget.getSingleWave(p)), params, params.keys()) ## appends waveforms for the entire parameter space to waves
        
        for w in waves:
            if w is not None:
                ## need to translate w into raw traces, plot them, and cache them (using id(w) as a key)
                rawWaves = self.getChannelCmds(w, rate)
                #rawWaves = self.dev.getChannelCmds({'powerWaveform':w}, rate) ## calculate raw waveforms for shutter/qSwitch/pCell from powerWaveform
                #self.cache[id(w)] = rawWaves ## cache the calculated waveforms
                self.plotRawCurves(rawWaves, color=QtGui.QColor(100, 100, 100)) ## plot the raw waveform in it's appropriate plot in grey
        
        ## calculate (or pull from cache) and display single-mode wave in red
        single = self.powerWidget.getSingleWave()
        if single is not None:
            #rawSingle = self.cache.get(id(single), self.dev.getChannelCmds({'powerWaveform':single}, rate))
            rawSingle = self.getChannelCmds(single, rate)
            self.plotRawCurves(rawSingle, color=QtGui.QColor(200, 100, 100))
    
                      
    def plotRawCurves(self, data, color=QtGui.QColor(100, 100, 100)):
        if 'shutter' in data:
            self.shutterPlot.plot(y=data['shutter'], x=self.powerWidget.timeVals, pen=QtGui.QPen(color))
        if 'qSwitch' in data:
            self.qSwitchPlot.plot(y=data['qSwitch'], x=self.powerWidget.timeVals, pen=QtGui.QPen(color))
        if 'pCell' in data:
            self.pCellPlot.plot(y=data['pCell'], x=self.powerWidget.timeVals, pen=QtGui.QPen(color))
      
    def clearRawPlots(self):
        for p in ['shutterPlot', 'qSwitchPlot', 'pCellPlot']:
            if hasattr(self, p):
                getattr(self, p).clear()
                
    def quit(self):
        self.dev.lastResult = None
        DAQGenericTaskGui.quit(self)
示例#8
0
class LaserTaskGui(DAQGenericTaskGui):
    def __init__(self, dev, taskRunner):
        DAQGenericTaskGui.__init__(self, dev, taskRunner, ownUi=False)

        self.ui = taskTemplate.Ui_Form()

        self.cache = {}

        self.layout = QtGui.QGridLayout()
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.layout)

        self.splitter1 = QtGui.QSplitter()
        self.splitter1.setOrientation(QtCore.Qt.Horizontal)
        self.layout.addWidget(self.splitter1)

        self.ctrlLayout = QtGui.QVBoxLayout()
        wid1 = QtGui.QWidget()
        wid1.setLayout(self.ctrlLayout)
        self.plotSplitter = QtGui.QSplitter()
        self.plotSplitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter1.addWidget(wid1)
        self.splitter1.addWidget(self.plotSplitter)
        #wid = QtGui.QWidget()
        #hLayout = QtGui.QHBoxLayout()
        #wid.setLayout(hLayout)
        #self.ctrlLayout.addLayout(hLayout)
        wid2 = QtGui.QWidget()
        self.ui.setupUi(wid2)
        self.ctrlLayout.addWidget(wid2)

        if not self.dev.hasPowerIndicator:
            self.ui.checkPowerBtn.setEnabled(False)
            self.ui.checkPowerCheck.hide()
            self.ui.checkPowerCheck.setChecked(False)
        if not self.dev.hasTunableWavelength:
            self.ui.wavelengthWidget.hide()

        self.powerWidget, self.powerPlot = self.createChannelWidget(
            'power', daqName=self.dev.getDAQName()[0])

        ## all we want is the function generator
        self.powerFnGenerator = self.powerWidget.ui.waveGeneratorWidget
        self.powerWidget.hide()
        self.ctrlLayout.addWidget(self.powerFnGenerator)
        self.powerFnGenerator.show()

        self.plotSplitter.addWidget(self.powerPlot)
        self.powerWidget.setMeta('y',
                                 units='W',
                                 siPrefix=True,
                                 dec=True,
                                 step=0.5,
                                 minStep=1e-3,
                                 limits=(0, None))
        self.powerWidget.setMeta('xy',
                                 units='J',
                                 siPrefix=True,
                                 dec=True,
                                 step=0.5,
                                 minStep=1e-6,
                                 limits=(0, None))
        self.powerWidget.setMeta('x',
                                 units='s',
                                 siPrefix=True,
                                 dec=True,
                                 step=0.5,
                                 minStep=1e-6,
                                 limits=(None, None))

        if self.dev.hasTriggerableShutter:
            #(self.shutterWidget, self.shutterPlot) = self.createChannelWidget('shutter')
            self.shutterPlot = PlotWidget(name='%s.shutter' % self.dev.name)
            self.shutterPlot.setLabel('left', text='Shutter')
            self.plotSplitter.addWidget(self.shutterPlot)
            #self.shutterPlot.hide()
        if self.dev.hasQSwitch:
            #self.qSwitchWidget, self.qSwitchPlot = self.createChannelWidget('qSwitch')
            self.qSwitchPlot = PlotWidget(name='%s.qSwitch' % self.dev.name)
            self.qSwitchPlot.setLabel('left', text='Q-Switch')
            self.plotSplitter.addWidget(self.qSwitchPlot)
            #self.qSwitchPlot.hide()
        if self.dev.hasPCell:
            #self.pCellWidget, self.pCellPlot = self.createChannelWidget('pCell')
            self.pCellPlot = PlotWidget(name='%s.pCell' % self.dev.name)
            self.pCellPlot.setLabel('left', text='Pockel Cell', units='V')
            self.plotSplitter.addWidget(self.pCellPlot)
            #self.pCellPlot.hide()

        ## catch self.powerWidget.sigDataChanged and connect it to functions that calculate and plot raw shutter and qswitch traces
        self.powerWidget.sigDataChanged.connect(self.powerCmdChanged)
        self.ui.checkPowerBtn.clicked.connect(self.dev.outputPower)
        self.dev.sigOutputPowerChanged.connect(self.laserPowerChanged)
        self.dev.sigSamplePowerChanged.connect(self.samplePowerChanged)

        self.dev.outputPower()

    def laserPowerChanged(self, power, valid):
        #samplePower = self.dev.samplePower(power)  ## we should get another signal for this later..
        #samplePower = power*self.dev.getParam('scopeTransmission')

        ## update label
        if power is None:
            self.ui.outputPowerLabel.setText("?")
        else:
            self.ui.outputPowerLabel.setText(siFormat(power, suffix='W'))

        if not valid:
            self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #B00}")
        else:
            self.ui.outputPowerLabel.setStyleSheet("QLabel {color: #000}")

    def samplePowerChanged(self, power):
        if power is None:
            self.ui.samplePowerLabel.setText("?")
            return
        else:
            self.ui.samplePowerLabel.setText(siFormat(power, suffix='W'))

        if self.dev.hasPCell:
            raise Exception('stub')
        else:
            ## adjust length of pulse to correct for new power
            if self.ui.adjustLengthCheck.isChecked():
                en = {}
                for param in self.powerWidget.ui.waveGeneratorWidget.stimParams:
                    en[param.name()] = param['sum']
                self.powerWidget.setMeta('y', value=power, readonly=True)
                for param in self.powerWidget.ui.waveGeneratorWidget.stimParams:
                    param['sum'] = en[param.name()]
            else:
                self.powerWidget.setMeta('y', value=power, readonly=True)

    def saveState(self):
        """Return a dictionary representing the current state of the widget."""
        state = {}
        state['daqState'] = DAQGenericTaskGui.saveState(self)
        return state

    def restoreState(self, state):
        """Restore the state of the widget from a dictionary previously generated using saveState"""
        return DAQGenericTaskGui.restoreState(self, state['daqState'])

    def describe(self, params=None):
        state = self.saveState()
        ps = state['daqState']['channels']['power']
        desc = {'mode': 'power', 'command': ps['waveGeneratorWidget']}
        return desc

    def prepareTaskStart(self):
        ## check power before starting task.
        if self.ui.checkPowerCheck.isChecked():
            power = self.dev.outputPower()  ## request current power from laser
            valid = self.dev.checkPowerValidity(power)
            if power is None:
                raise HelpfulException(
                    "The current laser power for '%s' is unknown." %
                    self.dev.name)
            if not valid:
                powerStr = siFormat(power, suffix='W')
                raise HelpfulException(
                    "The current laser power for '%s' (%s) is outside the expected range."
                    % (self.dev.name(), powerStr))

    def generateTask(self, params=None):
        """Return a cmd dictionary suitable for passing to LaserTask."""

        ## Params looks like: {'amp': 7} where 'amp' is the name of a sequence parameter, and 7 is the 7th value in the list of 'amp'
        for k, v in params.items():
            if k.startswith('power.'):
                del params[k]
                params[k[6:]] = v
        rate = self.powerWidget.rate
        wave = self.powerWidget.getSingleWave(params)
        rawCmds = self.getChannelCmds(wave, rate)
        #rawCmds = self.cache.get(id(wave), self.dev.getChannelCmds({'powerWaveform':wave}, rate)) ## returns {'shutter': array(...), 'qSwitch':array(..), 'pCell':array(...)}

        ### structure task in DAQGeneric-compatible way
        cmd = {}
        for k in rawCmds:
            cmd[k] = {}
            cmd[k]['command'] = rawCmds[k]

        cmd['powerWaveform'] = wave  ## just to allow the device task to store this data
        cmd['ignorePowerWaveform'] = True
        return cmd

    def getChannelCmds(self, powerWave, rate):
        key = id(powerWave)
        if key in self.cache:
            rawCmds = self.cache[key]
        else:
            rawCmds = self.dev.getChannelCmds(
                {'powerWaveform': powerWave}, rate
            )  ## returns {'shutter': array(...), 'qSwitch':array(..), 'pCell':array(...)}
            self.cache[key] = rawCmds
        return rawCmds

    def powerCmdChanged(self):
        self.clearRawPlots()
        self.cache = {}
        rate = self.powerWidget.rate

        #### calculate, cache and display sequence waves for shutter/qSwitch/pCell
        params = {}
        ps = self.powerWidget.listSequence()
        for k in ps:
            params[k] = range(len(ps[k]))
        ## get power waveforms
        waves = []
        runSequence(
            lambda p: waves.append(self.powerWidget.getSingleWave(p)), params,
            params.keys(
            ))  ## appends waveforms for the entire parameter space to waves

        for w in waves:
            if w is not None:
                ## need to translate w into raw traces, plot them, and cache them (using id(w) as a key)
                rawWaves = self.getChannelCmds(w, rate)
                #rawWaves = self.dev.getChannelCmds({'powerWaveform':w}, rate) ## calculate raw waveforms for shutter/qSwitch/pCell from powerWaveform
                #self.cache[id(w)] = rawWaves ## cache the calculated waveforms
                self.plotRawCurves(
                    rawWaves, color=QtGui.QColor(100, 100, 100)
                )  ## plot the raw waveform in it's appropriate plot in grey

        ## calculate (or pull from cache) and display single-mode wave in red
        single = self.powerWidget.getSingleWave()
        if single is not None:
            #rawSingle = self.cache.get(id(single), self.dev.getChannelCmds({'powerWaveform':single}, rate))
            rawSingle = self.getChannelCmds(single, rate)
            self.plotRawCurves(rawSingle, color=QtGui.QColor(200, 100, 100))

    def plotRawCurves(self, data, color=QtGui.QColor(100, 100, 100)):
        if 'shutter' in data:
            self.shutterPlot.plot(y=data['shutter'],
                                  x=self.powerWidget.timeVals,
                                  pen=QtGui.QPen(color))
        if 'qSwitch' in data:
            self.qSwitchPlot.plot(y=data['qSwitch'],
                                  x=self.powerWidget.timeVals,
                                  pen=QtGui.QPen(color))
        if 'pCell' in data:
            self.pCellPlot.plot(y=data['pCell'],
                                x=self.powerWidget.timeVals,
                                pen=QtGui.QPen(color))

    def clearRawPlots(self):
        for p in ['shutterPlot', 'qSwitchPlot', 'pCellPlot']:
            if hasattr(self, p):
                getattr(self, p).clear()

    def quit(self):
        self.dev.lastResult = None
        DAQGenericTaskGui.quit(self)