Example #1
0
    def outputPower(self, forceUpdate=False):
        """
        Return the output power of the laser in Watts.
        
        The power returned does not account for the effects of pockels 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
           
        Use checkPowerValidity(power) to determine whether this level is within the expected range.

        Subsequent calls to outputPower() may return a cached value (the maximum age of this value is
        determined by the powerUpdateInterval config parameter). Use forceUpdate=True to ignore any
        cached values.
        """
        now = ptime.time()
        needUpdate = (forceUpdate is True
                      or self.params['currentPower'] is None
                      or self._lastPowerMeasureTime is None
                      or now - self._lastPowerMeasureTime >
                      self.params['powerUpdateInterval'])

        if needUpdate:
            self.params['currentPower'] = self._measurePower()
            self._lastPowerMeasureTime = ptime.time()
        return self.params['currentPower']
Example #2
0
File: pvcam.py Project: ablot/acq4
 def call(self, fn, *args, **kargs):
     t = ptime.time()
     ret = LIB('functions', fn)(*args, **kargs)
     t2 = ptime.time()
     if t2-t > 4.0:
         print backtrace()
         print "function took %f sec:" % (t2-t), fn, args, kargs
     return ret
Example #3
0
 def run(self):
     """Main loop for patch thread. This is where protocols are executed and data collected."""
     try:
         with MutexLocker(self.lock) as l:
             self.stopThread = False
             clamp = self.manager.getDevice(self.clampName)
             daqName = clamp.listChannels().values()[0]['device']  ## Just guess the DAQ by checking one of the clamp's channels
             clampName = self.clampName
             self.paramsUpdated = True
             l.unlock()
             
             lastTime = None
             while True:
                 ## copy in parameters from GUI
                 updateCommand = False
                 l.relock()
                 if self.paramsUpdated:
                     with self.ui.paramLock:
                         params = self.ui.params.copy()
                         self.paramsUpdated = False
                     updateCommand = True
                 l.unlock()
                 
                 ## run protocol and analysis
                 try:
                     self.runOnce(params, l, clamp, daqName, clampName)
                 except:
                     printExc("Error running/analyzing patch protocol")
                 
                 
                 
                 lastTime = ptime.time()-params['recordTime'] ## This is not a proper 'cycle time', but instead enforces a minimum interval between cycles (but this can be very important for performance)
                 
                 ## sleep until it is time for the next run
                 c = 0
                 stop = False
                 while True:
                     ## check for stop button every 100ms
                     if c % 10 == 0:
                         l.relock()
                         if self.stopThread:
                             l.unlock()
                             stop = True
                             break
                         l.unlock()
                     now = ptime.time()
                     if now >= (lastTime+params['cycleTime']):
                         break
                     
                     time.sleep(10e-3) ## Wake up every 10ms
                     c += 1
                 if stop:
                     break
     except:
         printExc("Error in patch acquisition thread, exiting.")
Example #4
0
File: test.py Project: ablot/acq4
def contReadTest():
    print "::::::::::::::::::  Continuous Read Test  :::::::::::::::::::::"
    task = n.createTask()
    task.CreateAIVoltageChan("/Dev1/ai0", "", n.Val_RSE, -10., 10., n.Val_Volts, None)
    task.CfgSampClkTiming(None, 10000.0, n.Val_Rising, n.Val_ContSamps, 4000)
    task.start()
    t = ptime.time()
    for i in range(0, 10):
        data, size = task.read(1000)
        print "Cont read %d - %d samples, %fsec" % (i, size, ptime.time() - t)
        t = ptime.time()
    task.stop()
Example #5
0
def contReadTest():
    print "::::::::::::::::::  Continuous Read Test  :::::::::::::::::::::"
    task = n.createTask()
    task.CreateAIVoltageChan("/Dev1/ai0", "", n.Val_RSE, -10., 10., n.Val_Volts, None)
    task.CfgSampClkTiming(None, 10000.0, n.Val_Rising, n.Val_ContSamps, 4000)
    task.start()
    t = ptime.time()
    for i in range(0, 10):
        data, size = task.read(1000)
        print "Cont read %d - %d samples, %fsec" % (i, size, ptime.time() - t)
        t = ptime.time()
    task.stop()
Example #6
0
    def run(self):
        """Main loop for patch thread. This is where protocols are executed and data collected."""
        try:
            with self.lock:
                self.stopThread = False
                clamp = self.manager.getDevice(self.clampName)
                daqName = clamp.listChannels().values()[0][
                    'device']  ## Just guess the DAQ by checking one of the clamp's channels
                clampName = self.clampName
                self.paramsUpdated = True

            lastTime = None
            while True:
                ## copy in parameters from GUI
                updateCommand = False
                with self.lock:
                    if self.paramsUpdated:
                        with self.ui.paramLock:
                            params = self.ui.params.copy()
                            self.paramsUpdated = False
                        updateCommand = True

                ## run protocol and analysis
                try:
                    self.runOnce(params, clamp, daqName, clampName)
                except:
                    printExc("Error running/analyzing patch protocol")

                lastTime = ptime.time() - params[
                    'recordTime']  ## This is not a proper 'cycle time', but instead enforces a minimum interval between cycles (but this can be very important for performance)

                ## sleep until it is time for the next run
                c = 0
                stop = False
                while True:
                    ## check for stop button every 100ms
                    if c % 10 == 0:
                        with self.lock:
                            if self.stopThread:
                                stop = True
                                break
                    now = ptime.time()
                    if now >= (lastTime + params['cycleTime']):
                        break

                    time.sleep(10e-3)  ## Wake up every 10ms
                    c += 1
                if stop:
                    break
        except:
            printExc("Error in patch acquisition thread, exiting.")
Example #7
0
 def mark(self, msg=None):
     if self.disabled: 
         return
     
     if msg is None:
         msg = str(self.markCount)
     self.markCount += 1
     
     t1 = ptime.time()
     msg2 = "  "+self.msg+" "+msg+" "+"%gms" % ((t1-self.t1)*1000)
     if self.delayed:
         self.msgs.append(msg2)
     else:
         print msg2
     self.t1 = ptime.time()  ## don't measure time it took to print
Example #8
0
    def start(self):
        self.writeTaskData()  ## Only writes if needed.
        
        self.result = None
        ## TODO: Reserve all hardware needed before starting tasks
        
        keys = list(self.tasks.keys())
        ## move clock task key to the end
        if self.clockSource in keys:
            #print "  Starting %s last" % str(tt) 
            keys.remove(self.clockSource)
            keys.append(self.clockSource)
        for k in keys[:-1]:
            #print "starting task", k
            self.tasks[k].start()
        #self.startTime = time.clock()
        self.startTime = ptime.time()
        #print "start time:", self.startTime
        self.tasks[keys[-1]].start()
        #print "starting clock task:", keys[-1]
        
#        for k in keys:
#          if not self.tasks[k].isRunning():
#            print "Warning: task %s didn't start" % str(k)
        
        if self.triggerChannel is not None:
            ## Set up callback to record time when trigger starts
            pass
Example #9
0
    def handleFrame(self, frame):

        ## Request each device handles its own data
        ## Note that this is only used to display results; data storage is handled by Manager and the individual devices.
        #print "got frame", frame
        prof = Profiler('TaskRunner.handleFrame', disabled=True)
        for d in frame['result']:
            try:
                if d != 'protocol':
                    self.docks[d].widget().handleResult(
                        frame['result'][d], frame['params'])
                    prof.mark('finished %s' % d)
            except:
                printExc("Error while handling result from device '%s'" % d)

        self.sigNewFrame.emit(frame)
        prof.mark('emit newFrame')

        ## If this is a single-mode task and looping is turned on, schedule the next run
        if self.loopEnabled:
            ct = self.protoStateGroup.state()['loopCycleTime']
            t = max(0, ct - (ptime.time() - self.lastProtoTime))
            Qt.QTimer.singleShot(int(t * 1000.), self.loop)
        prof.finish()

        # good time to collect garbage
        gc.collect()
Example #10
0
    def newFrames(self):
        """Return a list of all frames acquired since the last call to newFrames."""

        with self.camLock:
            nFrames = self.mmc.getRemainingImageCount()
            if nFrames == 0:
                return []

        now = ptime.time()
        if self.lastFrameTime is None:
            self.lastFrameTime = now

        dt = (now - self.lastFrameTime) / nFrames
        frames = []
        with self.camLock:
            for i in range(nFrames):
                frame = {}
                frame['time'] = self.lastFrameTime + (dt * (i + 1))
                frame['id'] = self.frameId
                frame['data'] = self.mmc.popNextImage().T
                frames.append(frame)
                self.frameId += 1

        self.lastFrame = frame
        self.lastFrameTime = now
        return frames
Example #11
0
    def start(self):
        self.writeTaskData()  ## Only writes if needed.
        
        self.result = None
        ## TODO: Reserve all hardware needed before starting tasks
        
        keys = self.tasks.keys()
        ## move clock task key to the end
        if self.clockSource in keys:
            #print "  Starting %s last" % str(tt) 
            keys.remove(self.clockSource)
            keys.append(self.clockSource)
        for k in keys[:-1]:
            #print "starting task", k
            self.tasks[k].start()
        #self.startTime = time.clock()
        self.startTime = ptime.time()
        #print "start time:", self.startTime
        self.tasks[keys[-1]].start()
        #print "starting clock task:", keys[-1]
        
#        for k in keys:
#          if not self.tasks[k].isRunning():
#            print "Warning: task %s didn't start" % str(k)
        
        if self.triggerChannel is not None:
            ## Set up callback to record time when trigger starts
            pass
Example #12
0
    def generateTask(self, dh, params=None, progressDlg=None):
        #prof = Profiler("Generate Task: %s" % str(params))
        ## Never put {} in the function signature
        if params is None:
            params = {}
        prot = {'protocol': self.protoStateGroup.state()}

        # Disable timeouts for these tasks because we don't know how long to wait
        # for external triggers. TODO: use the default timeout, but also allow devices
        # in the task to modify the default.
        prot['protocol']['timeout'] = None

        #prof.mark('protocol state')
        store = (dh is not None)
        prot['protocol']['storeData'] = store
        if store:
            if params != {}:
                name = '_'.join(map(lambda i: '%03d'%i, params.values()))
                #print "mkdir", name
                info = params.copy()
                info['dirType'] = 'Protocol'
                dh1 = dh.mkdir(name, info=info)
                #prof.mark('create storage dir')
            else:
                dh1 = dh
            prot['protocol']['storageDir'] = dh1
        #prof.mark('selected storage dir.')
        prot['protocol']['name'] = self.currentTask.fileName
        
        for d in self.currentTask.devices:
            if self.currentTask.deviceEnabled(d):
                ## select out just the parameters needed for this device
                p = dict([(i[1], params[i]) for i in params.keys() if i[0] == d])
                ## Ask the device to generate its task command
                if d not in self.docks:
                    raise HelpfulException("The device '%s' currently has no dock loaded." % d,
                                           reasons=[
                                               "This device name does not exist in the system's configuration",
                                               "There was an error when creating the device at program startup",
                                               ],
                                           tags={},
                                           importance=8,

                                           docSections=['userGuide/modules/TaskRunner/loadingNonexistentDevices']
                                           )
                prot[d] = self.docks[d].widget().generateTask(p)
                #prof.mark("get task from %s" % d)
        #print prot['protocol']['storageDir'].name()
        
        if progressDlg is not None:
            progressDlg.setValue(progressDlg.value()+1)
            ## only do UI updates every 1 sec.
            now = ptime.time()
            if now - self.lastQtProcessTime > 1.0:
                self.lastQtProcessTime = now
                QtGui.QApplication.processEvents()
            if progressDlg.wasCanceled():
                raise Exception("Target sequence computation canceled by user.")
        #prof.mark('done')
        return prot
Example #13
0
 def callBack1(self, *args):
     #print "Callback1: args:", args
     if args[3] == lib.qcCallbackExposeDone:
         now = ptime.time()
         self.frameTimes[args[1]] = now
         #print "Exposure done. Time: %f, Duration: %f" %
         return
     if args[2] != 0:
         for x in lib('enums', 'QCam_Err'):
             if lib('enums', 'QCam_Err')[x] == args[2]:
                 raise QCamFunctionError(args[2], "There was an error during QueueFrame/Callback. Error code = %s" %(x))
     #self.mutex.lock()
     with self.mutex:
         #print "Mutex locked from qcam.callBack1()"
         #print "set last index", args[1]
         self.lastImages.append({'id':self.counter, 'data':self.arrays[args[1]].copy(), 'time': self.frameTimes[args[1]], 'exposeDoneTime':self.frameTimes[args[1]]})
         self.counter += 1
         
         if self.stopSignal == False:
             #self.mutex.unlock()
             #size = self.getImageSize()
             #if len(self.arrays[self.i]) != size/2:
                 #self.frames[self.i],self.arrays[self.i] = self.mkFrame()
             #### Need to check that frame is the right size given settings, and if not, make a new frame.
             self.call(lib.QueueFrame, self.handle, self.frames[self.i], self.fnp1, lib.qcCallbackDone|lib.qcCallbackExposeDone, 0, self.i)
             self.i = ( self.i+1) % self.ringSize
Example #14
0
 def handleFrame(self, frame):
     
     ## Request each device handles its own data
     ## Note that this is only used to display results; data storage is handled by Manager and the individual devices.
     #print "got frame", frame
     prof = Profiler('TaskRunner.handleFrame', disabled=True)
     for d in frame['result']:
         try:
             if d != 'protocol':
                 self.docks[d].widget().handleResult(frame['result'][d], frame['params'])
                 prof.mark('finished %s' % d)
         except:
             printExc("Error while handling result from device '%s'" % d)
             
     #self.emit(QtCore.SIGNAL('newFrame'), frame)
     self.sigNewFrame.emit(frame)
     prof.mark('emit newFrame')
             
     ## If this is a single-mode task and looping is turned on, schedule the next run
     if self.loopEnabled:
         ct = self.protoStateGroup.state()['loopCycleTime']
         t = max(0, ct - (ptime.time() - self.lastProtoTime))
         QtCore.QTimer.singleShot(int(t*1000.), self.loop)
     prof.finish()
     
     # good time to collect garbage
     gc.collect()
Example #15
0
    def newFrames(self):
        """Return a list of all frames acquired since the last call to newFrames."""
        now = ptime.time()

        dt = now - self.lastFrameTime
        exp = self.getParam('exposure')
        bin = self.getParam('binning')
        fps = 1.0 / (exp + (40e-3 / (bin[0] * bin[1])))
        nf = int(dt * fps)
        if nf == 0:
            return []

        region = self.getParam('region')
        bg = self.getBackground()[region[0]:region[0] + region[2],
                                  region[1]:region[1] + region[3]]

        ## update cells
        spikes = np.random.poisson(min(dt, 0.4) * self.cells['rate'])
        self.cells['value'] *= np.exp(-dt / self.cells['decayTau'])
        self.cells['value'] = np.clip(self.cells['value'] + spikes * 0.2, 0, 1)
        shape = region[2:]
        self.lastFrameTime = now + exp
        data = self.getNoise(shape)
        data[data < 0] = 0

        data += bg * (exp * 1000)

        ## draw cells
        px = (self.pixelVectors()[0]**2).sum()**0.5

        ## Generate transform that maps grom global coordinates to image coordinates
        cameraTr = pg.SRTTransform3D(self.inverseGlobalTransform())
        # note we use binning=(1,1) here because the image is downsampled later.
        frameTr = self.makeFrameTransform(region, [1, 1]).inverted()[0]
        tr = pg.SRTTransform(frameTr * cameraTr)

        for cell in self.cells:
            w = cell['size'] / px
            pos = pg.Point(cell['x'], cell['y'])
            imgPos = tr.map(pos)
            start = (int(imgPos.x()), int(imgPos.y()))
            stop = (int(start[0] + w), int(start[1] + w))
            val = cell['intensity'] * cell['value'] * self.getParam('exposure')
            data[max(0, start[0]):max(0, stop[0]),
                 max(0, start[1]):max(0, stop[1])] += val

        data = fn.downsample(data, bin[0], axis=0)
        data = fn.downsample(data, bin[1], axis=1)
        data = data.astype(np.uint16)

        self.frameId += 1
        frames = []
        for i in range(nf):
            frames.append({
                'data': data,
                'time': now + (i / fps),
                'id': self.frameId
            })
        return frames
Example #16
0
 def newFrames(self):
     """Return a list of all frames acquired since the last call to newFrames."""
     now = ptime.time()
     
     dt = now - self.lastFrameTime
     exp = self.getParam('exposure')
     region = self.getParam('region') 
     bg = self.getBackground()[region[0]:region[0]+region[2], region[1]:region[1]+region[3]]
     
     ## update cells
     spikes = np.random.poisson(max(dt, 0.4) * self.cells['rate'])
     self.cells['value'] *= np.exp(-dt / self.cells['decayTau'])
     self.cells['value'] = np.clip(self.cells['value'] + spikes * 0.2, 0, 1)
     
     shape = region[2:]
     bin = self.getParam('binning')
     nf = int(dt / (exp+(40e-3/(bin[0]*bin[1]))))
     if nf > 0:
         self.lastFrameTime = now
         #data = np.random.normal(size=(shape[0], shape[1]), loc=100, scale=50)
         data = self.getNoise(shape)
         data[data<0] = 0
         
         #sig = self.signal[region[0]:region[0]+region[2], region[1]:region[1]+region[3]]
         data += bg * (exp*1000)
         
         ## draw cells
         px = (self.pixelVectors()[0]**2).sum() ** 0.5
         
         ## Generate transform that maps grom global coordinates to image coordinates
         cameraTr = pg.SRTTransform3D(self.inverseGlobalTransform())
         frameTr = self.makeFrameTransform(region, [1, 1]).inverted()[0] # note we use binning=(1,1) here because the image is downsampled later.
         tr = pg.SRTTransform(frameTr * cameraTr)
         
         for cell in self.cells:
             w = cell['size'] / px
             pos = pg.Point(cell['x'], cell['y'])
             imgPos = tr.map(pos)
             start = (int(imgPos.x()), int(imgPos.y()))
             stop = (start[0]+w, start[1]+w)
             val = cell['intensity'] * cell['value'] * self.getParam('exposure')
             data[max(0,start[0]):max(0,stop[0]), max(0,start[1]):max(0,stop[1])] += val
         
         
         data = fn.downsample(data, bin[0], axis=0)
         data = fn.downsample(data, bin[1], axis=1)
         data = data.astype(np.uint16)
         
         
         
         
         self.frameId += 1
         frames = []
         for i in range(nf):
             frames.append({'data': data, 'time': now, 'id': self.frameId})
         return frames
         
     else:
         return []
Example #17
0
 def collectBgClicked(self, checked):
     if checked:
         if not self.ui.contAvgBgCheck.isChecked():
             self.backgroundFrame = None ## reset background frame
             self.bgFrameCount = 0
             self.bgStartTime = ptime.time()
         self.ui.collectBgBtn.setText("Collecting...")
     else:
         self.ui.collectBgBtn.setText("Collect Background")
Example #18
0
 def stop(self, abort=False):
     if abort:
         with self.abortLock:
             print "Abort!"
             self.aborted = True
     with MutexLocker(self.dev.lock):
         for t in self.daqTasks:
             t.stop(abort=abort)
         self.dev.lastRunTime = ptime.time()
Example #19
0
 def stop(self, abort=False):
     if abort:
         with self.abortLock:
             print("Abort!")
             self.aborted = True
     with self.dev.lock:
         for t in self.daqTasks:
             t.stop(abort=abort)
         self.dev.lastRunTime = ptime.time()
Example #20
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, 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
Example #21
0
 def start(self, block=True):
     #print "PVCam: start"
     if not self.isRunning():
         self.lastIndex = None
         #print "  not running already; start camera"
         Camera.start(self, block)  ## Start the acquisition thread
         self.startTime = ptime.time()
         
     ## pvcams can take a long time 
     if block:
         tm = self.getParam('triggerMode')
         if tm != 'Normal':
             #print "  waiting for trigger to arm"
             waitTime = 0.3  ## trigger needs about 300ms to prepare (?)
         else:
             waitTime = 0
         
         sleepTime = (self.startTime + waitTime) - ptime.time()
         if sleepTime > 0:
             #print "  sleep for", sleepTime
             time.sleep(sleepTime)
Example #22
0
File: PVCam.py Project: ablot/acq4
 def start(self, block=True):
     #print "PVCam: start"
     if not self.isRunning():
         self.lastIndex = None
         #print "  not running already; start camera"
         Camera.start(self, block)  ## Start the acquisition thread
         self.startTime = ptime.time()
         
     ## pvcams can take a long time 
     if block:
         tm = self.getParam('triggerMode')
         if tm != 'Normal':
             #print "  waiting for trigger to arm"
             waitTime = 0.3  ## trigger needs about 300ms to prepare (?)
         else:
             waitTime = 0
         
         sleepTime = (self.startTime + waitTime) - ptime.time()
         if sleepTime > 0:
             #print "  sleep for", sleepTime
             time.sleep(sleepTime)
Example #23
0
    def runSingle(self, store=True):
        
        if self.protoStateGroup.state()['loop']:
            self.loopEnabled = True
            
        # good time to collect garbage
        gc.collect()
        #print "RunSingle"
        #if self.taskThread.isRunning():
            #import traceback
            #traceback.print_stack()
            #print "Task already running."

        self.lastProtoTime = ptime.time()
        ## Disable all start buttons
        self.enableStartBtns(False)
        
        ## Set storage dir
        try:
            if store:
                currentDir = self.manager.getCurrentDir()
                name = self.currentTask.name()
                if name is None:
                    name = 'protocol'
                info = self.taskInfo()
                info['dirType'] = 'Protocol'
                ## Create storage directory with all information about the task to be executed
                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()
            
            ## Generate executable conf from task object
            prot = self.generateTask(dh)
            #print prot
            self.sigTaskSequenceStarted.emit({})
            #print "runSingle: Starting taskThread.."
            self.taskThread.startTask(prot)
            #print "runSingle: taskThreadStarted"
        except:
            exc = sys.exc_info()
            self.enableStartBtns(True)
            self.loopEnabled = False
            #print "Error starting task. "
            raise HelpfulException("Error occurred while starting task", exc=exc)      
Example #24
0
 def newFrame(self, frame):
     
     lf = None
     if self.nextFrame is not None:
         lf = self.nextFrame
     elif self.currentFrame is not None:
         lf = self.currentFrame
     
     if lf is not None:
         fps = frame.info()['fps']
         if fps is not None:
             self.ui.fpsLabel.setValue(fps)
     
     ## Update ROI plots, if any
     #if self.ui.checkEnableROIs.isChecked():
         #self.addPlotFrame(frame)
     
     ## self.nextFrame gets picked up by drawFrame() at some point
     if self.nextFrame is not None:
         self.ui.displayPercentLabel.setValue(0.)
     else:
         self.ui.displayPercentLabel.setValue(100.)
     
     self.nextFrame = frame
     
     ## stop collecting bg frames if we are in static mode and time is up
     if self.ui.collectBgBtn.isChecked() and not self.ui.contAvgBgCheck.isChecked():
         timeLeft = self.ui.bgTimeSpin.value() - (ptime.time()-self.bgStartTime)
         if timeLeft > 0:
             self.ui.collectBgBtn.setText("Collecting... (%d)" % int(timeLeft+1))
         else:
             self.ui.collectBgBtn.setChecked(False)
             self.ui.collectBgBtn.setText("Collect Background")
     
     if self.ui.collectBgBtn.isChecked():
         if self.ui.contAvgBgCheck.isChecked():
             x = 1.0 - 1.0 / (self.ui.bgTimeSpin.value()+1.0)
         else:
             x = float(self.bgFrameCount)/(self.bgFrameCount + 1)
             self.bgFrameCount += 1
         
         if self.backgroundFrame == None or self.backgroundFrame.shape != frame.data().shape:
             self.backgroundFrame = frame.data().astype(float)
         else:
             self.backgroundFrame = x * self.backgroundFrame + (1-x)*frame.data().astype(float)
     
     self.sigNewFrame.emit(self, frame)
Example #25
0
    def runSingle(self, store=True):

        if self.protoStateGroup.state()['loop']:
            self.loopEnabled = True

        # good time to collect garbage
        gc.collect()

        self.lastProtoTime = ptime.time()
        ## Disable all start buttons
        self.enableStartBtns(False)

        ## Set storage dir
        try:
            if store:
                currentDir = self.manager.getCurrentDir()
                name = self.currentTask.name()
                if name is None:
                    name = 'protocol'
                info = self.taskInfo()
                info['dirType'] = 'Protocol'
                ## Create storage directory with all information about the task to be executed
                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()

            ## Generate executable conf from task object
            prot = self.generateTask(dh)
            #print prot
            self.sigTaskSequenceStarted.emit({})
            #print "runSingle: Starting taskThread.."
            self.taskThread.startTask(prot)
            #print "runSingle: taskThreadStarted"
        except:
            exc = sys.exc_info()
            self.enableStartBtns(True)
            self.loopEnabled = False
            #print "Error starting task. "
            raise HelpfulException("Error occurred while starting task",
                                   exc=exc)
Example #26
0
 def finish(self, msg=None):
     if self.disabled or self.finished: 
         return
     
     if msg is not None:
         self.mark(msg)
     t1 = ptime.time()
     msg = self.msg + ' <<< Finished, total time: %gms' % ((t1-self.t0)*1000)
     if self.delayed:
         self.msgs.append(msg)
         if self.depth == 0:
             for line in self.msgs:
                 print line
             Profiler.msgs = []
     else:
         print msg
     Profiler.depth = self.depth
     self.finished = True
Example #27
0
 def newFrames(self):
     """Return a list of all frames acquired since the last call to newFrames."""
     
     with self.camLock:
         index = self.cam.lastFrame()
     now = ptime.time()
     if self.lastFrameTime is None:
         self.lastFrameTime = now
         
     if index is None:  ## no frames available yet
         return []
     
     if index == self.lastIndex:  ## no new frames since last check
         return []
     
     self.stopOk = True
     
     ## Determine how many new frames have arrived since last check
     if self.lastIndex is not None:
         diff = (index - self.lastIndex) % self.ringSize
         if diff > (self.ringSize / 2):
             print("Image acquisition buffer is at least half full (possible dropped frames)")
     else:
         self.lastIndex = index-1
         diff = 1
 
     dt = (now - self.lastFrameTime) / diff
     frames = []
     for i in range(diff):
         fInd = (i+self.lastIndex+1) % self.ringSize
         frame = {}
         frame['time'] = self.lastFrameTime + (dt * (i+1))
         frame['id'] = self.frameId
         frame['data'] = self.acqBuffer[fInd].copy()
         #print frame['data']
         frames.append(frame)
         self.frameId += 1
             
     self.lastFrame = frame
     self.lastFrameTime = now
     self.lastIndex = index
     return frames
Example #28
0
File: PVCam.py Project: ablot/acq4
 def newFrames(self):
     """Return a list of all frames acquired since the last call to newFrames."""
     
     with self.camLock:
         index = self.cam.lastFrame()
     now = ptime.time()
     if self.lastFrameTime is None:
         self.lastFrameTime = now
         
     if index is None:  ## no frames available yet
         return []
     
     if index == self.lastIndex:  ## no new frames since last check
         return []
     
     self.stopOk = True
     
     ## Determine how many new frames have arrived since last check
     if self.lastIndex is not None:
         diff = (index - self.lastIndex) % self.ringSize
         if diff > (self.ringSize / 2):
             print "Image acquisition buffer is at least half full (possible dropped frames)"
     else:
         self.lastIndex = index-1
         diff = 1
 
     dt = (now - self.lastFrameTime) / diff
     frames = []
     for i in range(diff):
         fInd = (i+self.lastIndex+1) % self.ringSize
         frame = {}
         frame['time'] = self.lastFrameTime + (dt * (i+1))
         frame['id'] = self.frameId
         frame['data'] = self.acqBuffer[fInd].copy()
         #print frame['data']
         frames.append(frame)
         self.frameId += 1
             
     self.lastFrame = frame
     self.lastFrameTime = now
     self.lastIndex = index
     return frames
Example #29
0
 def __init__(self, msg="Profiler", disabled=False, delayed=True, globalDelay=True):
     self.disabled = disabled
     if disabled: 
         return
     
     self.markCount = 0
     self.finished = False
     self.depth = Profiler.depth 
     Profiler.depth += 1
     if not globalDelay:
         self.msgs = []
     self.delayed = delayed
     self.msg = "  "*self.depth + msg
     msg2 = self.msg + " >>> Started"
     if self.delayed:
         self.msgs.append(msg2)
     else:
         print msg2
     self.t0 = ptime.time()
     self.t1 = self.t0
Example #30
0
 def start(self):
     #print "start"
     with MutexLocker(self.dev.lock):
         lastRunTime = self.dev.lastRunTime
     if lastRunTime is None:
         #print "  no wait"
         return
     
     # Task specifies that we have a minimum wait from the end of the previous
     # task to the start of this one. This is used in photostimulation experiments
     # that require variable downtime depending on the proximity of subsequent
     # stimulations.
     if 'minWaitTime' in self.cmd:
         while True:
             now = ptime.time()
             wait = min(0.1, self.cmd['minWaitTime'] - (now - lastRunTime))
             if wait <= 0:
                 break
             with self.abortLock:
                 if self.aborted:
                     return
             time.sleep(wait)
Example #31
0
    def start(self):
        #print "start"
        with self.dev.lock:
            lastRunTime = self.dev.lastRunTime
        if lastRunTime is None:
            #print "  no wait"
            return

        # Task specifies that we have a minimum wait from the end of the previous
        # task to the start of this one. This is used in photostimulation experiments
        # that require variable downtime depending on the proximity of subsequent
        # stimulations.
        if 'minWaitTime' in self.cmd:
            while True:
                now = ptime.time()
                wait = min(0.1, self.cmd['minWaitTime'] - (now - lastRunTime))
                if wait <= 0:
                    break
                with self.abortLock:
                    if self.aborted:
                        return
                time.sleep(wait)
Example #32
0
    def callBack1(self, *args):
        #print "Callback1: args:", args
        if args[3] == lib.qcCallbackExposeDone:
            now = ptime.time()
            self.frameTimes[args[1]] = now
            #print "Exposure done. Time: %f, Duration: %f" %
            return
        if args[2] != 0:
            for x in lib('enums', 'QCam_Err'):
                if lib('enums', 'QCam_Err')[x] == args[2]:
                    raise QCamFunctionError(
                        args[2],
                        "There was an error during QueueFrame/Callback. Error code = %s"
                        % (x))
        #self.mutex.lock()
        with self.mutex:
            #print "Mutex locked from qcam.callBack1()"
            #print "set last index", args[1]
            self.lastImages.append({
                'id': self.counter,
                'data': self.arrays[args[1]].copy(),
                'time': self.frameTimes[args[1]],
                'exposeDoneTime': self.frameTimes[args[1]]
            })
            self.counter += 1

            if self.stopSignal == False:
                #self.mutex.unlock()
                #size = self.getImageSize()
                #if len(self.arrays[self.i]) != size/2:
                #self.frames[self.i],self.arrays[self.i] = self.mkFrame()
                #### Need to check that frame is the right size given settings, and if not, make a new frame.
                self.call(lib.QueueFrame, self.handle, self.frames[self.i],
                          self.fnp1,
                          lib.qcCallbackDone | lib.qcCallbackExposeDone, 0,
                          self.i)
                self.i = (self.i + 1) % self.ringSize
Example #33
0
 def runOnce(self, params=None):
     # good time to collect garbage
     gc.collect()
     
     #print "TaskThread:runOnce"
     prof = Profiler("TaskRunner.TaskThread.runOnce", disabled=True, delayed=False)
     startTime = ptime.time()
     if params is None:
         params = {}
     with MutexLocker(self.lock) as l:
         l.unlock()
     
         ## Select correct command to execute
         cmd = self.task
         #print "Sequence array:", cmd.shape, cmd.infoCopy()
         if params is not None:
             for p in params:
                 #print "Selecting %s: %s from sequence array" % (str(p), str(params[p]))
                 cmd = cmd[p: params[p]]
         prof.mark('select command')        
         #print "Task:", cmd
                 
         ## Wait before starting if we've already run too recently
         #print "sleep until next run time..", ptime.time(), self.lastRunTime, cmd['protocol']['cycleTime']
         while (self.lastRunTime is not None) and (ptime.time() < self.lastRunTime + cmd['protocol']['cycleTime']):
             l.relock()
             if self.abortThread or self.stopThread:
                 l.unlock()
                 #print "Task run aborted by user"
                 return
             l.unlock()
             time.sleep(1e-3)
         #print "slept until", ptime.time()
         prof.mark('sleep')
         
         # If paused, hang here for a bit.
         emitSig = True
         while True:
             l.relock()
             if self.abortThread or self.stopThread:
                 l.unlock()
                 return
             pause = self.paused
             l.unlock()
             if not pause:
                 break
             if emitSig:
                 emitSig = False
                 #self.emit(QtCore.SIGNAL('paused'))
                 self.sigPaused.emit()
             time.sleep(10e-3)
         
         prof.mark('pause')
         
         #print "BEFORE:\n", cmd
         if type(cmd) is not dict:
             print "========= TaskRunner.runOnce cmd: =================="
             print cmd
             print "========= TaskRunner.runOnce params: =================="
             print "Params:", params
             print "==========================="
             raise Exception("TaskRunner.runOnce failed to generate a proper command structure. Object type was '%s', should have been 'dict'." % type(cmd))
             
         
         task = self.dm.createTask(cmd)
         prof.mark('create task')
         
         self.lastRunTime = ptime.time()
         #self.emit(QtCore.SIGNAL('taskStarted'), params)
         
         try:
             l.relock()
             self._currentTask = task
             l.unlock()
             task.execute(block=False)
             self.sigTaskStarted.emit(params)
             prof.mark('execute')
         except:
             l.relock()
             self._currentTask = None
             l.unlock()
             try:
                 task.stop(abort=True)
             except:
                 pass
             printExc("\nError starting task:")
             exc = sys.exc_info()
             raise HelpfulException("\nError starting task:", exc)
         
         prof.mark('start task')
         ### Do not put code outside of these try: blocks; may cause device lockup
         
         try:
             ## wait for finish, watch for abort requests
             while True:
                 if task.isDone():
                     prof.mark('task done')
                     break
                 l.relock()
                 if self.abortThread:
                     l.unlock()
                     # should be taken care of in TaskThread.abort()
                     #task.stop(abort=True)
                     return
                 l.unlock()
                 time.sleep(1e-3)
                 
             result = task.getResult()
         except:
             ## Make sure the task is fully stopped if there was a failure at any point.
             #printExc("\nError during task execution:")
             print "\nStopping task.."
             task.stop(abort=True)
             print ""
             raise HelpfulException("\nError during task execution:", sys.exc_info())
         finally:
             l.relock()
             self._currentTask = None
             l.unlock()
         #print "\nAFTER:\n", cmd
         prof.mark('getResult')
         
     frame = {'params': params, 'cmd': cmd, 'result': result}
     #self.emit(QtCore.SIGNAL('newFrame'), frame)
     self.sigNewFrame.emit(frame)
     prof.mark('emit newFrame')
     if self.stopThread:
         raise Exception('stop', result)
     #print "Total run time: %gms" % ((ptime.time() - startTime) * 1000 )
     
     ## Give everyone else a chance to catch up
     QtCore.QThread.yieldCurrentThread()
     prof.mark('yield')
     prof.finish()
Example #34
0
    def generateTask(self, dh, params=None, progressDlg=None):
        #prof = Profiler("Generate Task: %s" % str(params))
        ## params should be in the form {(dev, param): value, ...}
        ## Generate executable conf from task object
        #prot = {'protocol': {
            #'duration': self.currentTask.conf['duration'], 
            #'storeData': store,
            #'mode': 'single',
            #'name': self.currentTask.fileName,
            #'cycleTime': self.currentTask.conf['cycleTime'], 
        #}}
        #print "generate:", params
        ## Never put {} in the function signature
        if params is None:
            params = {}
        prot = {'protocol': self.protoStateGroup.state()}
        #prof.mark('protocol state')
        store = (dh is not None)
        prot['protocol']['storeData'] = store
        if store:
            if params != {}:
                name = '_'.join(map(lambda i: '%03d'%i, params.values()))
                #print "mkdir", name
                info = params.copy()
                info['dirType'] = 'Protocol'
                dh1 = dh.mkdir(name, info=info)
                #prof.mark('create storage dir')
            else:
                dh1 = dh
            prot['protocol']['storageDir'] = dh1
        #prof.mark('selected storage dir.')
        prot['protocol']['name'] = self.currentTask.fileName
        
        for d in self.currentTask.devices:
            if self.currentTask.deviceEnabled(d):
                ## select out just the parameters needed for this device
                p = dict([(i[1], params[i]) for i in params.keys() if i[0] == d])
                ## Ask the device to generate its task command
                if d not in self.docks:
                    raise HelpfulException("The device '%s' currently has no dock loaded." % d,
                                           reasons=[
                                               "This device name does not exist in the system's configuration",
                                               "There was an error when creating the device at program startup",
                                               ],
                                           tags={},
                                           importance=8,

                                           docSections=['userGuide/modules/TaskRunner/loadingNonexistentDevices']
                                           )
                prot[d] = self.docks[d].widget().generateTask(p)
                #prof.mark("get task from %s" % d)
        #print prot['protocol']['storageDir'].name()
        
        if progressDlg is not None:
            progressDlg.setValue(progressDlg.value()+1)
            ## only do UI updates every 1 sec.
            now = ptime.time()
            if now - self.lastQtProcessTime > 1.0:
                self.lastQtProcessTime = now
                QtGui.QApplication.processEvents()
            if progressDlg.wasCanceled():
                raise Exception("Target sequence computation canceled by user.")
        #prof.mark('done')
        return prot
Example #35
0
 def startCamera(self):
     self.cameraStarted = True
     self.lastFrameTime = ptime.time()
Example #36
0
    def run(self):
        #import cProfile
        ##cProfile.runctx('self._run()', globals(), locals(), sort='cumulative')
        #pr = cProfile.Profile()
        #pr.enable()
        #self._run()
        #pr.disable()
        #pr.print_stats(sort='cumulative')

        #def _run(self):
        size = self.dev.getParam('sensorSize')
        lastFrame = None
        lastFrameTime = None
        lastFrameId = None
        fps = None

        camState = dict(
            self.dev.getParams(
                ['binning', 'exposure', 'region', 'triggerMode']))
        binning = camState['binning']
        exposure = camState['exposure']
        region = camState['region']
        mode = camState['triggerMode']

        try:
            #self.dev.setParam('ringSize', self.ringSize, autoRestart=False)
            self.dev.startCamera()

            lastFrameTime = lastStopCheck = ptime.time()
            frameInfo = {}
            scopeState = None
            while True:
                ti = 0
                now = ptime.time()
                frames = self.dev.newFrames()

                ## If a new frame is available, process it and inform other threads
                if len(frames) > 0:
                    if lastFrameId is not None:
                        drop = frames[0]['id'] - lastFrameId - 1
                        if drop > 0:
                            print "WARNING: Camera dropped %d frames" % drop

                    ## Build meta-info for this frame(s)
                    info = camState.copy()

                    ss = self.dev.getScopeState()
                    if ss['id'] != scopeState:
                        scopeState = ss['id']
                        ## regenerate frameInfo here
                        ps = ss['pixelSize']  ## size of CCD pixel
                        transform = pg.SRTTransform3D(ss['transform'])

                        frameInfo = {
                            'pixelSize':
                            [ps[0] * binning[0],
                             ps[1] * binning[1]],  ## size of image pixel
                            'objective': ss.get('objective', None),
                            'deviceTransform': transform,
                        }

                    ## Copy frame info to info array
                    info.update(frameInfo)

                    ## Process all waiting frames. If there is more than one frame waiting, guess the frame times.
                    dt = (now - lastFrameTime) / len(frames)
                    if dt > 0:
                        info['fps'] = 1.0 / dt
                    else:
                        info['fps'] = None

                    for frame in frames:
                        frameInfo = info.copy()
                        data = frame.pop('data')
                        frameInfo.update(
                            frame)  # copies 'time' key supplied by camera
                        out = Frame(data, frameInfo)
                        with self.connectMutex:
                            conn = list(self.connections)
                        for c in conn:
                            c(out)
                        self.sigNewFrame.emit(out)

                    lastFrameTime = now
                    lastFrameId = frames[-1]['id']
                    loopCount = 0

                time.sleep(1e-3)

                ## check for stop request every 10ms
                if now - lastStopCheck > 10e-3:
                    lastStopCheck = now

                    ## If no frame has arrived yet, do NOT allow the camera to stop (this can hang the driver)   << bug should be fixed in pvcam driver, not here.
                    self.lock.lock()
                    if self.stopThread:
                        self.stopThread = False
                        self.lock.unlock()
                        break
                    self.lock.unlock()

                    diff = ptime.time() - lastFrameTime
                    if diff > (10 + exposure):
                        if mode == 'Normal':
                            self.dev.noFrameWarning(diff)
                            break
                        else:
                            pass  ## do not exit loop if there is a possibility we are waiting for a trigger

            #from debug import Profiler
            #prof = Profiler()
            with self.camLock:
                #self.cam.stop()
                self.dev.stopCamera()
            #prof.mark('      camera stop:')
        except:
            printExc("Error starting camera acquisition:")
            try:
                with self.camLock:
                    #self.cam.stop()
                    self.dev.stopCamera()
            except:
                pass
            self.sigShowMessage.emit(
                "ERROR starting acquisition (see console output)")
        finally:
            pass
Example #37
0
    def drawFrame(self):
        if self.hasQuit:
            return
        #sys.stdout.write('+')
        try:
            
            ## If we last drew a frame < 1/30s ago, return.
            t = ptime.time()
            if (self.lastDrawTime is not None) and (t - self.lastDrawTime < .033333):
                #sys.stdout.write('-')
                return
            ## if there is no new frame and no controls have changed, just exit
            if not self.updateFrame and self.nextFrame is None:
                #sys.stdout.write('-')
                return
            self.updateFrame = False
            
            ## If there are no new frames and no previous frames, then there is nothing to draw.
            if self.currentFrame is None and self.nextFrame is None:
                #sys.stdout.write('-')
                return
            
            prof = Profiler()
            ## We will now draw a new frame (even if the frame is unchanged)
            if self.lastDrawTime is not None:
                fps = 1.0 / (t - self.lastDrawTime)
                self.ui.displayFpsLabel.setValue(fps)
            self.lastDrawTime = t
            prof()
            
            ## Handle the next available frame, if there is one.
            if self.nextFrame is not None:
                self.currentFrame = self.nextFrame
                self.nextFrame = None
            
            data = self.currentFrame.data()
            info = self.currentFrame.info()
            prof()
            
            
            ## divide the background out of the current frame if needed
            if self.ui.divideBgBtn.isChecked():
                bg = self.getBackgroundFrame()
                if bg is not None and bg.shape == data.shape:
                    data = data / bg
            elif self.ui.subtractBgBtn.isChecked():
                bg = self.getBackgroundFrame()
                if bg is not None and bg.shape == data.shape:
                    data = data - bg
            prof()
            
            ## Set new levels if auto gain is enabled
            if self.ui.btnAutoGain.isChecked():
                cw = self.ui.spinAutoGainCenterWeight.value()
                (w,h) = data.shape
                center = data[w/2.-w/6.:w/2.+w/6., h/2.-h/6.:h/2.+h/6.]
                minVal = data.min() * (1.0-cw) + center.min() * cw
                maxVal = data.max() * (1.0-cw) + center.max() * cw

                ## If there is inf/nan in the image, strip it out before computing min/max
                if any([np.isnan(minVal), np.isinf(minVal),  np.isnan(minVal), np.isinf(minVal)]):
                    nanMask = np.isnan(data)
                    infMask = np.isinf(data)
                    valid = data[~nanMask * ~infMask]
                    minVal = valid.min() * (1.0-cw) + center.min() * cw
                    maxVal = valid.max() * (1.0-cw) + center.max() * cw
                
                ## Smooth min/max range to avoid noise
                if self.lastMinMax is None:
                    minVal = minVal
                    maxVal = maxVal
                else:
                    s = 1.0 - 1.0 / (self.ui.spinAutoGainSpeed.value()+1.0)
                    minVal = self.lastMinMax[0] * s + minVal * (1.0-s)
                    maxVal = self.lastMinMax[1] * s + maxVal * (1.0-s)
                
                self.lastMinMax = [minVal, maxVal]
                
                ## and convert fraction of previous range into new levels
                bl = self.autoGainLevels[0] * (maxVal-minVal) + minVal
                wl = self.autoGainLevels[1] * (maxVal-minVal) + minVal
                
                self.ignoreLevelChange = True
                try:
                    self.ui.histogram.setLevels(bl, wl)
                    self.ui.histogram.setHistogramRange(minVal, maxVal, padding=0.05)
                finally:
                    self.ignoreLevelChange = False
            prof()
            
            ## update image in viewport
            self.imageItem.updateImage(data)#, levels=[bl, wl])
            self.imageItem.setOpacity(self.alpha)
            self.imageItem.setTransform(self.currentFrame.frameTransform().as2D())
            prof()
            
            ## Update viewport to correct for scope movement/scaling
            tr = pg.SRTTransform(self.currentFrame.cameraTransform())
            self.updateTransform(tr)

            self.imageItemGroup.setTransform(tr)
            prof()
            
            prof()
            prof.finish()
        
        
        except:
            printExc('Error while drawing new frames:')
        finally:
            pass
Example #38
0
    def runOnce(self, params=None):
        # good time to collect garbage
        gc.collect()

        prof = Profiler("TaskRunner.TaskThread.runOnce",
                        disabled=True,
                        delayed=False)
        startTime = ptime.time()
        if params is None:
            params = {}

        ## Select correct command to execute
        cmd = self.task
        if params is not None:
            for p in params:
                cmd = cmd[p:params[p]]
        prof.mark('select command')

        ## Wait before starting if we've already run too recently
        while (self.lastRunTime
               is not None) and (ptime.time() < self.lastRunTime +
                                 cmd['protocol']['cycleTime']):
            with self.lock:
                if self.abortThread or self.stopThread:
                    #print "Task run aborted by user"
                    return
            time.sleep(1e-3)
        prof.mark('sleep')

        emitSig = True
        while True:
            with self.lock:
                if self.abortThread or self.stopThread:
                    return
                pause = self.paused
            if not pause:
                break
            if emitSig:
                emitSig = False
                self.sigPaused.emit()
            time.sleep(10e-3)

        prof.mark('pause')

        if type(cmd) is not dict:
            print("========= TaskRunner.runOnce cmd: ==================")
            print(cmd)
            print("========= TaskRunner.runOnce params: ==================")
            print("Params:", params)
            print("===========================")
            raise Exception(
                "TaskRunner.runOnce failed to generate a proper command structure. Object type was '%s', should have been 'dict'."
                % type(cmd))

        task = self.dm.createTask(cmd)
        prof.mark('create task')

        self.lastRunTime = ptime.time()

        try:
            with self.lock:
                self._currentTask = task
            task.execute(block=False)
            # record estimated end time
            endTime = time.time() + cmd['protocol']['duration']
            self.sigTaskStarted.emit(params)
            prof.mark('execute')
        except:
            with self.lock:
                self._currentTask = None
            try:
                task.stop(abort=True)
            except:
                pass
            printExc("\nError starting task:")
            exc = sys.exc_info()
            raise HelpfulException("\nError starting task:", exc)

        prof.mark('start task')
        ### Do not put code outside of these try: blocks; may cause device lockup

        try:
            ## wait for finish, watch for abort requests
            while True:
                if task.isDone():
                    prof.mark('task done')
                    break
                with self.lock:
                    if self.abortThread:
                        # should be taken care of in TaskThread.abort()
                        # NO -- task.stop() is not thread-safe.
                        task.stop(abort=True)
                        return
                # adjust sleep time based on estimated time remaining in the task.
                sleep = np.clip((endTime - time.time()) * 0.5, 1e-3, 20e-3)
                time.sleep(sleep)

            result = task.getResult()
        except:
            ## Make sure the task is fully stopped if there was a failure at any point.
            #printExc("\nError during task execution:")
            print("\nStopping task..")
            task.stop(abort=True)
            print("")
            raise HelpfulException("\nError during task execution:",
                                   sys.exc_info())
        finally:
            with self.lock:
                self._currentTask = None
        prof.mark('getResult')

        frame = {'params': params, 'cmd': cmd, 'result': result}
        self.sigNewFrame.emit(frame)
        prof.mark('emit newFrame')
        if self.stopThread:
            raise Exception('stop', result)

        ## Give everyone else a chance to catch up
        Qt.QThread.yieldCurrentThread()
        prof.mark('yield')
        prof.finish()
Example #39
0
File: Camera.py Project: hiuwo/acq4
 def run(self):
     #import cProfile
     ##cProfile.runctx('self._run()', globals(), locals(), sort='cumulative')
     #pr = cProfile.Profile()
     #pr.enable()
     #self._run()
     #pr.disable()
     #pr.print_stats(sort='cumulative')
     
 #def _run(self):
     size = self.dev.getParam('sensorSize')
     lastFrame = None
     lastFrameTime = None
     lastFrameId = None
     fps = None
     
     camState = dict(self.dev.getParams(['binning', 'exposure', 'region', 'triggerMode']))
     binning = camState['binning']
     exposure = camState['exposure']
     region = camState['region']
     mode = camState['triggerMode']
     
     try:
         #self.dev.setParam('ringSize', self.ringSize, autoRestart=False)
         self.dev.startCamera()
         
         lastFrameTime = lastStopCheck = ptime.time()
         frameInfo = {}
         scopeState = None
         while True:
             ti = 0
             now = ptime.time()
             frames = self.dev.newFrames()
             
             #with self.camLock:
                 #frame = self.cam.lastFrame()
             ## If a new frame is available, process it and inform other threads
             if len(frames) > 0:
                 if lastFrameId is not None:
                     drop = frames[0]['id'] - lastFrameId - 1
                     if drop > 0:
                         print "WARNING: Camera dropped %d frames" % drop
                     
                 ## Build meta-info for this frame(s)
                 info = camState.copy()
                 
                 ## frameInfo includes pixelSize, objective, centerPosition, scopePosition, imagePosition
                 ss = self.dev.getScopeState()
                 if ss['id'] != scopeState:
                     #print "scope state changed"
                     scopeState = ss['id']
                     ## regenerate frameInfo here
                     ps = ss['pixelSize']  ## size of CCD pixel
                     #pos = ss['centerPosition']
                     #pos2 = [pos[0] - size[0]*ps[0]*0.5 + region[0]*ps[0], pos[1] - size[1]*ps[1]*0.5 + region[1]*ps[1]]
                     
                     transform = pg.SRTTransform3D(ss['transform'])
                     #transform.translate(region[0]*ps[0], region[1]*ps[1])  ## correct for ROI here
                     
                     frameInfo = {
                         'pixelSize': [ps[0] * binning[0], ps[1] * binning[1]],  ## size of image pixel
                         #'scopePosition': ss['scopePosition'],
                         #'centerPosition': pos,
                         'objective': ss.get('objective', None),
                         #'imagePosition': pos2
                         #'cameraTransform': ss['transform'],
                         'cameraTransform': transform,
                     }
                     
                 ## Copy frame info to info array
                 info.update(frameInfo)
                 #for k in frameInfo:
                     #info[k] = frameInfo[k]
                 
                 ## Process all waiting frames. If there is more than one frame waiting, guess the frame times.
                 dt = (now - lastFrameTime) / len(frames)
                 if dt > 0:
                     info['fps'] = 1.0/dt
                 else:
                     info['fps'] = None
                 
                 for frame in frames:
                     frameInfo = info.copy()
                     data = frame['data']
                     #print data
                     del frame['data']
                     frameInfo.update(frame)
                     out = Frame(data, frameInfo)
                     with self.connectMutex:
                         conn = list(self.connections)
                     for c in conn:
                         c(out)
                     #self.emit(QtCore.SIGNAL("newFrame"), out)
                     self.sigNewFrame.emit(out)
                     
                 lastFrameTime = now
                 lastFrameId = frames[-1]['id']
                 loopCount = 0
                     
             time.sleep(1e-3)
             
             ## check for stop request every 10ms
             if now - lastStopCheck > 10e-3: 
                 lastStopCheck = now
                 
                 ## If no frame has arrived yet, do NOT allow the camera to stop (this can hang the driver)   << bug should be fixed in pvcam driver, not here.
                 self.lock.lock()
                 if self.stopThread:
                     self.stopThread = False
                     self.lock.unlock()
                     break
                 self.lock.unlock()
                 
                 diff = ptime.time()-lastFrameTime
                 if diff > (10 + exposure):
                     if mode == 'Normal':
                         print "Camera acquisition thread has been waiting %02f sec but no new frames have arrived; shutting down." % diff
                         break
                     else:
                         pass  ## do not exit loop if there is a possibility we are waiting for a trigger
                             
             
         #from debug import Profiler
         #prof = Profiler()
         with self.camLock:
             #self.cam.stop()
             self.dev.stopCamera()
         #prof.mark('      camera stop:')
     except:
         try:
             with self.camLock:
                 #self.cam.stop()
                 self.dev.stopCamera()
         except:
             pass
         printExc("Error starting camera acquisition:")
         #self.emit(QtCore.SIGNAL("showMessage"), "ERROR starting acquisition (see console output)")
         self.sigShowMessage.emit("ERROR starting acquisition (see console output)")
     finally:
         pass
Example #40
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
Example #41
0
 def startCamera(self):
     self.cameraStarted = True
     self.lastFrameTime = ptime.time()