Esempio n. 1
0
File: DBCtrl.py Progetto: ablot/acq4
 def listMaps(self, cells):
     """List all maps associated with the file handle for each cell in a list"""
     self.ui.mapTable.clear()
     self.maps = []
     
     for cell in cells:
         
         dbui = self.host.getElement('Database')
         db = dbui.getDb()
         if db is None:
             logMsg("No database loaded in Data Manager.", msgType='error')
             
         ident = self.dbIdentity+'.maps'
         table = dbui.getTableName(ident)
         if not db.hasTable(table):
             return
         if db.tableOwner(table) != ident:
             raise Exception("Table %s not owned by %s" % (table, ident))
         
         #row = db.getDirRowID(cell)
         #if row is None:
             #return
             
         maps = db.select(table, ['rowid','*'], where={'cell': cell})
         #print maps
         for rec in maps:
             scans = []
             for rowid in rec['scans']:
                 if isinstance(rowid, tuple):
                     fh = db.getDir(rowid[0], rowid[1])  ## single-spot maps specify the Protocol table instead
                 else:
                     fh = db.getDir('ProtocolSequence', rowid)    ## NOTE: single-spot maps use a different table!
                 scans.append((fh, rowid))
             rec['scans'] = scans
             self.newMap(rec)
Esempio n. 2
0
 def newFolder(self):
     if self.ui.newFolderList.currentIndex() < 1:
         return
         
     ftype = str(self.ui.newFolderList.currentText())
     self.ui.newFolderList.setCurrentIndex(0)
     
     cdir = self.manager.getCurrentDir()
     if not cdir.isManaged():
         cdir.createIndex()
     
     if ftype == 'Folder':
         nd = cdir.mkdir('NewFolder', autoIncrement=True)
         #item = self.model.handleIndex(nd)
         self.ui.fileTreeWidget.editItem(nd)
     else:
         spec = self.manager.config['folderTypes'][ftype]
         name = time.strftime(spec['name'])
             
         ## Determine where to put the new directory
         parent = cdir
         try:
             checkDir = cdir
             for i in range(5):
                 if not checkDir.isManaged():
                     break
                 inf = checkDir.info()
                 if 'dirType' in inf and inf['dirType'] == ftype:
                     parent = checkDir.parent()
                     break
                 #else:
                     #print "dir no match:", spec, inf
                 checkDir = checkDir.parent()
         except:
             printExc("Error while deciding where to put new folder (using currentDir by default)")
         
         ## make
         nd = parent.mkdir(name, autoIncrement=True)
         
         ## Add meta-info
         info = {'dirType': ftype}
         if spec.get('experimentalUnit', False):
             info['expUnit'] = True
         nd.setInfo(info)
         
         ## set display to info
         #self.showFileInfo(nd)
         
         #index = self.model.handleIndex(nd)
         #self.ui.fileTreeView.selectionModel().select(index, QtGui.QItemSelectionModel.Clear)
         #self.ui.fileTreeView.selectionModel().select(index, QtGui.QItemSelectionModel.Select)
         self.ui.fileTreeWidget.refresh(parent)  ## fileTreeWidget waits a while before updating; force it to refresh immediately.
         self.ui.fileTreeWidget.select(nd)
         ##self.ui.fileInfo.setCurrentFile(nd)
         
     logMsg("Created new folder: %s" %nd.name(relativeTo=self.baseDir), msgType='status', importance=7)   
     self.manager.setCurrentDir(nd)
Esempio n. 3
0
 def setCommand(self, vals):
     """Requests to set the command output to the mirrors.
     (The request is denied if the virtual shutter is closed)"""
     with self.lock:
         self.currentCommand = vals
         if self.getShutterOpen():
             ## make sure we have not requested a command outside the allowed limits
             (mn, mx) = self.config['commandLimits']
             v0 = max(mn, min(mx, vals[0]))
             v1 = max(mn, min(mx, vals[1]))
             self.setVoltage([v0, v1])
         else:
             logMsg("Virtual shutter closed, not setting mirror position.", msgType='warning')
Esempio n. 4
0
 def startTask(self, task, paramSpace=None):
     #print "TaskThread:startTask", self.lock.depth(), self.lock
     with MutexLocker(self.lock):
         #print "TaskThread:startTask got lock", self.lock.depth(), "    tracebacks follow:\n==========="
         #print "\n\n".join(self.lock.traceback())
         #print "======================"
         while self.isRunning():
             #l.unlock()
             raise Exception("Already running another task")
         self.task = task
         self.paramSpace = paramSpace
         self.lastRunTime = None
         #l.unlock()
         #print "TaskThread:startTask starting..", self.lock.depth()
         self.start() ### causes self.run() to be called from somewhere in C code
         #name = '' if task.fileName is None else task.fileName
         logMsg("Task started.", importance=1)
Esempio n. 5
0
 def getCalibration(self, laser, opticState=None):
     with self.lock:
         index = self.getCalibrationIndex()
         
     if opticState is None:
         opticState = self.getDeviceStateKey() ## this tells us about objectives, filters, etc
     
     if laser in index:
         index1 = index[laser]
     else:
         logMsg("Warning: No calibration found for laser %s" % laser, msgType='warning')
         return None
         
     if opticState in index1:
         index2 = index1[opticState]
     else:
         logMsg("Warning: No calibration found for state: %s" % opticState, msgType='warning')
         return None
     
     return index2.copy()
Esempio n. 6
0
    def mcUpdate(self, state=None, mode=None):
        """MC state (or internal holding state) has changed, handle the update."""
        with self.stateLock:
            if state is None:
                state = self.lastState[mode]
            mode = state['mode']
            state['holding'] = self.holding[mode]
            self.lastState[mode] = state.copy()
            if self.lastMode != state['mode']:
                if self.lastMode is not None and state[
                        'mode'] != self._switchingToMode and state[
                            'mode'] != 'I=0':
                    # User changed the mode manually; we need to update the holding value immediately.
                    self.setHolding(state['mode'])
                    logMsg(
                        "Warning: MultiClamp mode should be changed from ACQ4, not from the MultiClamp Commander window.",
                        msgType='error')

                self.lastMode = state['mode']
                self._switchingToMode = None

        self.sigStateChanged.emit(state)
Esempio n. 7
0
    def getCalibration(self, laser, opticState=None):
        with self.lock:
            index = self.getCalibrationIndex()

        if opticState is None:
            opticState = self.getDeviceStateKey(
            )  ## this tells us about objectives, filters, etc

        if laser in index:
            index1 = index[laser]
        else:
            logMsg("Warning: No calibration found for laser %s" % laser,
                   msgType='warning')
            return None

        if opticState in index1:
            index2 = index1[opticState]
        else:
            logMsg("Warning: No calibration found for state: %s" % opticState,
                   msgType='warning')
            return None

        return index2.copy()
Esempio n. 8
0
    def newFolder(self):
        if self.ui.newFolderList.currentIndex() < 1:
            return

        ftype = str(self.ui.newFolderList.currentText())
        self.ui.newFolderList.setCurrentIndex(0)

        cdir = self.manager.getCurrentDir()
        if not cdir.isManaged():
            cdir.createIndex()

        if ftype == 'Folder':
            nd = cdir.mkdir('NewFolder', autoIncrement=True)
            #item = self.model.handleIndex(nd)
            self.ui.fileTreeWidget.editItem(nd)
        else:
            spec = self.manager.config['folderTypes'][ftype]
            name = time.strftime(spec['name'])

            ## Determine where to put the new directory
            parent = cdir
            try:
                checkDir = cdir
                for i in range(5):
                    if not checkDir.isManaged():
                        break
                    inf = checkDir.info()
                    if 'dirType' in inf and inf['dirType'] == ftype:
                        parent = checkDir.parent()
                        break
                    #else:
                    #print "dir no match:", spec, inf
                    checkDir = checkDir.parent()
            except:
                printExc(
                    "Error while deciding where to put new folder (using currentDir by default)"
                )

            ## make
            nd = parent.mkdir(name, autoIncrement=True)

            ## Add meta-info
            info = {'dirType': ftype}
            if spec.get('experimentalUnit', False):
                info['expUnit'] = True
            nd.setInfo(info)

            ## set display to info
            #self.showFileInfo(nd)

            #index = self.model.handleIndex(nd)
            #self.ui.fileTreeView.selectionModel().select(index, QtGui.QItemSelectionModel.Clear)
            #self.ui.fileTreeView.selectionModel().select(index, QtGui.QItemSelectionModel.Select)
            self.ui.fileTreeWidget.refresh(
                parent
            )  ## fileTreeWidget waits a while before updating; force it to refresh immediately.
            self.ui.fileTreeWidget.select(nd)
            ##self.ui.fileInfo.setCurrentFile(nd)

        logMsg("Created new folder: %s" % nd.name(relativeTo=self.baseDir),
               msgType='status',
               importance=7)
        self.manager.setCurrentDir(nd)
Esempio n. 9
0
    def runSequence(self, store=True):
        ## Disable all start buttons
        self.enableStartBtns(False)
        
        # good time to collect garbage
        gc.collect()
        
        ## Find all top-level items in the sequence parameter list
        try:
            ## make sure all devices are reporting their correct sequence lists
            
            
            items = self.ui.sequenceParamList.listParams()
            #for i in self.ui.sequenceParamList.topLevelItems:
                #items.append(i)
            ## Generate parameter space
            params = OrderedDict()
            paramInds = OrderedDict()
            linkedParams = {}
            pLen = 1
            for i in items:
                key = i[:2]
                params[key] = i[2]
                paramInds[key] = range(len(i[2]))
                pLen *= len(i[2])
                linkedParams[key] = i[3]
                
            ## Set storage dir
            if store:
                currentDir = self.manager.getCurrentDir()
                name = self.currentTask.name()
                if name is None:
                    name = 'protocol'
                info = self.taskInfo(params)
                info['dirType'] = 'ProtocolSequence'
                dh = currentDir.mkdir(name, autoIncrement=True, info=info)
            else:
                dh = None
                
            ## Tell devices to prepare for task start.
            for d in self.currentTask.devices:
                if self.currentTask.deviceEnabled(d):
                    self.docks[d].widget().prepareTaskStart()
                    
            #print params, linkedParams
            ## Generate the complete array of command structures. This can take a long time, so we start a progress dialog.
            with pg.ProgressDialog("Generating task commands..", 0, pLen) as progressDlg:
                #progressDlg.setMinimumDuration(500)  ## If this takes less than 500ms, progress dialog never appears.
                self.lastQtProcessTime = ptime.time()
                prot = runSequence(lambda p: self.generateTask(dh, p, progressDlg), paramInds, paramInds.keys(), linkedParams=linkedParams)
                #progressDlg.setValue(pLen)
            if dh is not None:
                dh.flushSignals()  ## do this now rather than later as task is running
            
            #print "==========Sequence Task=============="
            #print prot
            #self.emit(QtCore.SIGNAL('taskSequenceStarted'), {})
            self.sigTaskSequenceStarted.emit({})
            logMsg('Started %s task sequence of length %i' %(self.currentTask.name(),pLen), importance=6)
            #print 'PR task positions:
            self.taskThread.startTask(prot, paramInds)
            
        except:
            self.enableStartBtns(True)

            raise
Esempio n. 10
0
    def _measurePower(self):
        if self.hasPowerIndicator:
            ## run a task that checks the power
            daqName = self.getDAQName('shutter')
            powerInd = self.config['powerIndicator']['channel']
            rate = self.config['powerIndicator']['rate']

            pConfig = getManager().getDevice(
                self.config['powerIndicator']['channel'][0]).listChannels()[
                    self.config['powerIndicator']['channel'][1]]
            sTime = pConfig.get('settlingTime', None)
            mTime = pConfig.get('measurementTime', None)

            if mTime is None or sTime is None:
                raise Exception(
                    "The power indicator (%s) specified for %s needs to be configured with both a 'settlingTime' value and a 'measurementTime' value."
                    % (self.config['powerIndicator']['channel'], self.name()))

            dur = 0.1 + (sTime + mTime)
            nPts = int(dur * rate)

            ### create a waveform that flashes the QSwitch(or other way of turning on) the number specified by reps
            waveform = np.zeros(nPts, dtype=np.byte)
            #for i in range(reps):
            #waveform[(i+1)/10.*rate:((i+1)/10.+sTime+mTime)*rate] = 1 ## divide i+1 by 10 to increment by hundreds of milliseconds
            waveform[0.1 * rate:-2] = 1

            measureMode = self.measurementMode()
            cmd = {
                'protocol': {
                    'duration': dur
                },
                self.name(): {
                    'switchWaveform': waveform,
                    'shutterMode': measureMode['shutter']
                },
                powerInd[0]: {
                    powerInd[1]: {
                        'record': True,
                        'recordInit': False
                    }
                },
                daqName: {
                    'numPts': nPts,
                    'rate': rate
                }
            }
            #print "outputPowerCmd: ", cmd
            task = getManager().createTask(cmd)
            task.execute(
                processEvents=False
            )  # disable event processing to prevent recurrent requests
            result = task.getResult()

            ## pull out time that laser was on and off so that power can be measured in each state -- discard the settlingTime around each state change
            #onMask = np.zeros(nPts, dtype=np.byte)
            #offMask = np.zeros(nPts, dtype=np.byte)
            #for i in range(reps):
            #onMask[((i+1)/10+sTime)*rate:((i+1)/10+sTime+mTime)*rate] = 1
            #offMask[(i/10.+2*sTime+mTime)*rate:(i+1/10.)*rate] = 1
            powerIndTrace = result[powerInd[0]]
            if powerIndTrace is None:
                raise Exception("No data returned from power indicator")
            laserOn = powerIndTrace[0][0.1 * rate:-2].asarray()
            laserOff = powerIndTrace[0][:0.1 * rate].asarray()

            t, prob = stats.ttest_ind(laserOn, laserOff)
            if prob < 0.01:  ### if powerOn is statistically different from powerOff
                powerOn = laserOn.mean()
                if powerOn < 0:
                    powerOn = 0.0
                powerOff = laserOff.mean()
                #self.devGui.ui.outputPowerLabel.setText(siFormat(powerOn, suffix='W')) ## NO! device does not talk to GUI!
                self.setParam(currentPower=powerOn)
                powerOk = self.checkPowerValidity(powerOn)
                self.sigOutputPowerChanged.emit(powerOn, powerOk)
                self.updateSamplePower()
                return powerOn
            else:
                logMsg(
                    "No laser pulse detected by power indicator '%s' while measuring Laser.outputPower()"
                    % powerInd[0],
                    msgType='warning')
                self.setParam(currentPower=0.0)
                self.updateSamplePower()
                return 0.0

        ## return the power specified in the config file if there's no powerIndicator
        else:
            return self.config.get('power', None)
Esempio n. 11
0
    def runSequence(self, store=True):
        ## Disable all start buttons
        self.enableStartBtns(False)

        # good time to collect garbage
        gc.collect()

        ## Find all top-level items in the sequence parameter list
        try:
            ## make sure all devices are reporting their correct sequence lists
            items = self.ui.sequenceParamList.listParams()
            ## Generate parameter space
            params = OrderedDict()
            paramInds = OrderedDict()
            linkedParams = {}
            pLen = 1
            for i in items:
                key = i[:2]
                params[key] = i[2]
                paramInds[key] = range(len(i[2]))
                pLen *= len(i[2])
                linkedParams[key] = i[3]

            ## Set storage dir
            if store:
                currentDir = self.manager.getCurrentDir()
                name = self.currentTask.name()
                if name is None:
                    name = 'protocol'
                info = self.taskInfo(params)
                info['dirType'] = 'ProtocolSequence'
                dh = currentDir.mkdir(name, autoIncrement=True, info=info)
            else:
                dh = None

            ## Tell devices to prepare for task start.
            for d in self.currentTask.devices:
                if self.currentTask.deviceEnabled(d):
                    self.docks[d].widget().prepareTaskStart()

            #print params, linkedParams
            ## Generate the complete array of command structures. This can take a long time, so we start a progress dialog.
            with pg.ProgressDialog("Generating task commands..", 0,
                                   pLen) as progressDlg:
                self.lastQtProcessTime = ptime.time()
                prot = runSequence(
                    lambda p: self.generateTask(dh, p, progressDlg),
                    paramInds,
                    list(paramInds.keys()),
                    linkedParams=linkedParams)
            if dh is not None:
                dh.flushSignals(
                )  ## do this now rather than later when task is running

            self.sigTaskSequenceStarted.emit({})
            logMsg('Started %s task sequence of length %i' %
                   (self.currentTask.name(), pLen),
                   importance=6)
            #print 'PR task positions:
            self.taskThread.startTask(prot, paramInds)

        except:
            self.enableStartBtns(True)

            raise
Esempio n. 12
0
    def outputPower(self):
        """
        Return a tuple: (current output power, bool power within expected range)
        The output power returned excludes the effect of pockel cell, shutter, etc.
        This information is determined in one of a few ways:
           1. The laser directly reports its power output (function needs to be reimplemented in subclass)
           2. A photodiode receves a small fraction of the beam and reports an estimated power
           3. The output power is specified in the config file
        """
        
        if self.hasPowerIndicator:
            ## run a task that checks the power
            daqName =  self.getDAQName('shutter')
            powerInd = self.config['powerIndicator']['channel']
            rate = self.config['powerIndicator']['rate']
            
            pConfig = getManager().getDevice(self.config['powerIndicator']['channel'][0]).listChannels()[self.config['powerIndicator']['channel'][1]]
            sTime = pConfig.get('settlingTime', None)
            mTime = pConfig.get('measurementTime', None)
            
            if mTime is None or sTime is None:
                raise Exception("The power indicator (%s) specified for %s needs to be configured with both a 'settlingTime' value and a 'measurementTime' value." %(self.config['powerIndicator']['channel'], self.name()))
            
            dur = 0.1 + (sTime+mTime)
            nPts = int(dur*rate)
            
            ### create a waveform that flashes the QSwitch(or other way of turning on) the number specified by reps
            waveform = np.zeros(nPts, dtype=np.byte)
            #for i in range(reps):
                #waveform[(i+1)/10.*rate:((i+1)/10.+sTime+mTime)*rate] = 1 ## divide i+1 by 10 to increment by hundreds of milliseconds
            waveform[0.1*rate:-2] = 1
            
            cmd = {
                'protocol': {'duration': dur},
                self.name(): {'switchWaveform':waveform, 'shutterMode':'closed'},
                powerInd[0]: {powerInd[1]: {'record':True, 'recordInit':False}},
                daqName: {'numPts': nPts, 'rate': rate}
            }
            #print "outputPowerCmd: ", cmd
            task = getManager().createTask(cmd)
            task.execute()
            result = task.getResult()
            
            ## pull out time that laser was on and off so that power can be measured in each state -- discard the settlingTime around each state change
            #onMask = np.zeros(nPts, dtype=np.byte)
            #offMask = np.zeros(nPts, dtype=np.byte)
            #for i in range(reps):
                #onMask[((i+1)/10+sTime)*rate:((i+1)/10+sTime+mTime)*rate] = 1
                #offMask[(i/10.+2*sTime+mTime)*rate:(i+1/10.)*rate] = 1
            powerIndTrace = result[powerInd[0]]
            if powerIndTrace is None:
                raise Exception("No data returned from power indicator")
            laserOn = powerIndTrace[0][0.1*rate:-2].asarray()
            laserOff = powerIndTrace[0][:0.1*rate].asarray()
            
            t, prob = stats.ttest_ind(laserOn, laserOff)
            if prob < 0.01: ### if powerOn is statistically different from powerOff
                powerOn = laserOn.mean()
                if powerOn < 0:
                    powerOn = 0.0
                powerOff = laserOff.mean()
                #self.devGui.ui.outputPowerLabel.setText(siFormat(powerOn, suffix='W')) ## NO! device does not talk to GUI!
                self.setParam(currentPower=powerOn)
                powerOk = self.checkPowerValidity(powerOn)
                self.sigOutputPowerChanged.emit(powerOn, powerOk)
                self.updateSamplePower()
                return powerOn, powerOk
            else:
                logMsg("No laser pulse detected by power indicator '%s' while measuring Laser.outputPower()" % powerInd[0], msgType='warning')
                self.setParam(currentPower=0.0)
                self.updateSamplePower()
                return 0.0, self.checkPowerValidity(0.0)

            
        ## return the power specified in the config file if there's no powerIndicator
        else:
            power = self.config.get('power', None)
            if power is None:
                return None, None
            else:
                return power, self.checkPowerValidity(power)