예제 #1
0
    def StartExposure(self):
        self.nReadOut = 0
        self._n_frames_leftover = 0
        self._frameRate = self.getCamPropValue('INTERNAL FRAME RATE')
        # From parent
        HamamatsuDCAM.StartExposure(self)

        # Allocate buffers (2 seconds of buffers)
        self.bs = int(max(int(2.0 * self._frameRate), 1))
        self.checkStatus(
            dcam.dcambuf_alloc(self.handle, ctypes.c_int32(self.bs)),
            "dcambuf_alloc")

        self._image_frame_bytes = int(self.getCamPropValue('IMAGE FRAMEBYTES'))

        if self._mode == self.MODE_SOFTWARE_TRIGGER:
            self.setCamPropValue('TRIGGER SOURCE',
                                 DCAMPROP_TRIGGERSOURCE_SOFTWARE)
        else:
            #continuous mode, internal trigger
            self.setCamPropValue('TRIGGER SOURCE',
                                 DCAMPROP_TRIGGERSOURCE_INTERNAL)

        eventLog.logEvent('StartAq', '')

        # Start the capture
        #print str(self.getCamPropValue('SENSOR MODE'))
        #TODO - this is probably where we would need to deal with continuous vs single shot modes.
        self.checkStatus(
            dcam.dcamcap_start(self.handle, DCAMCAP_START_SEQUENCE),
            "dcamcap_start")

        self._aq_active = True
        return 0
예제 #2
0
    def OnFrame(self, frameNum):
        if frameNum > self.startFrame:
            fn = int(
                floor((frameNum - self.startFrame) / self.dwellTime) %
                len(self.zPoss))
            if not fn == self.pos:
                self.pos = fn
                #self.piezo.MoveTo(self.piezoChan, self.zPoss[self.pos])
                scope.state.setItem(self.piezoName,
                                    self.zPoss[self.pos],
                                    stopCamera=self.require_camera_restart)
                eventLog.logEvent(
                    'ProtocolFocus',
                    '%d, %3.3f' % (frameNum, self.zPoss[self.pos]))

        TaskListProtocol.OnFrame(self, frameNum)

        if frameNum == -1:
            # Make move to initial position **after** all other -1 setup tasks have been performed (in super-class
            # OnFrame() call above).
            # This is currently required as a work-around on the HTSMS system which needs to unlock the focus
            # lock before changing focus (issue 766).
            scope.state.setItem(self.piezoName,
                                self.zPoss[self.pos],
                                stopCamera=self.require_camera_restart)
            eventLog.logEvent('ProtocolFocus',
                              '%d, %3.3f' % (-1, self.zPoss[self.pos]))
예제 #3
0
 def StartExposure(self):
     eventLog.logEvent('StartAq', '')
     self.compT.StartExp()
     #self.compTOld = self.compTCur
     #self.compTCur = compThread(self.XVals, self.YVals, (self.zPiezo.GetPos() - self.zOffset)*1e3,self.fluors, self.noiseMaker, laserPowers=self.laserPowers, intTime=self.intTime*1e-3)
     #self.compTCur.start()
     return 0
예제 #4
0
 def StartExposure(self):
     eventLog.logEvent('StartAq', '')
     self.compT.StartExp()
     #self.compTOld = self.compTCur
     #self.compTCur = compThread(self.XVals, self.YVals, (self.zPiezo.GetPos() - self.zOffset)*1e3,self.fluors, self.noiseMaker, laserPowers=self.laserPowers, intTime=self.intTime*1e-3)
     #self.compTCur.start()
     return 0
예제 #5
0
    def start(self):
        self.running = True
        
        #pixels = np.array(pixels)

#        if np.isscalar(self.pixels):
#            #constant - use as number of pixels
#            #center on current piezo position
#            self.xp = self.pixelsize*np.arange(-self.pixels/2, self.pixels/2 +1) + self.xpiezo[0].GetPos(self.xpiezo[1])
#            self.yp = self.pixelsize*np.arange(-self.pixels/2, self.pixels/2 +1) + self.ypiezo[0].GetPos(self.ypiezo[1])
#        elif np.isscalar(self.pixels[0]):
#            #a 1D array - numbers in either direction centered on piezo pos
#            self.xp = self.pixelsize*np.arange(-self.pixels[0]/2, self.pixels[0]/2 +1) + self.xpiezo[0].GetPos(self.xpiezo[1])
#            self.yp = self.pixelsize*np.arange(-self.pixels[1]/2, self.pixels[1]/2 +1) + self.ypiezo[0].GetPos(self.ypiezo[1])
#        else:
#            #actual pixel positions
#            self.xp = self.pixels[0]
#            self.yp = self.pixels[1]
#
#        self.nx = len(self.xp)
#        self.ny = len(self.yp)
#
#        self.imsize = self.nx*self.ny

        self.genCoords()

        self.callNum = 0

        if self.avg:
            self.image = np.zeros((self.nx, self.ny))

            #self.ds = scope.frameWrangler.currentFrame

            self.view = View3D(self.image)

        #self.xpiezo[0].MoveTo(self.xpiezo[1], self.xp[0])
        #self.ypiezo[0].MoveTo(self.ypiezo[1], self.yp[0])

        #self.scope.SetPos(x=self.xp[0], y = self.yp[0])
        self.scope.frameWrangler.stop()
        self.scope.state.setItems({'Positioning.x' : self.xp[0], 'Positioning.y' : self.yp[0]}, stopCamera = True)
        if self.trigger:
            self.scope.cam.SetAcquisitionMode(self.scope.cam.MODE_SOFTWARE_TRIGGER)
        self.scope.frameWrangler.start()

        #if self.sync:
        #    while not self.xpiezo[0].IsOnTarget(): #wait for stage to move
        #        time.sleep(.05)
        
        if self.evtLog:
                eventLog.logEvent('ScannerXPos', '%3.6f' % self.xp[0])
                eventLog.logEvent('ScannerYPos', '%3.6f' % self.yp[0])


        #self.scope.frameWrangler.WantFrameNotification.append(self.tick)
        self.scope.frameWrangler.onFrame.connect(self.tick, dispatch_uid=self._uuid)

        if self.trigger:
            self.scope.cam.FireSoftwareTrigger()
예제 #6
0
 def OnFinish(self):
     while not self.listPos >= len(self.taskList):
         t = self.taskList[self.listPos]
         self.listPos += 1
         t.what(*t.params)
         eventLog.logEvent(
             'ProtocolTask', '%s, ' % (t.what.__name__, ) +
             ', '.join(['%s' % p for p in t.params]))
예제 #7
0
    def _Loop(self):
        while self.loopActive:
            self.lock.acquire()
            try:
                # check position
                time.sleep(self._update_rate)

                self.position[0] = float(gcs.qPOS(self.id, b'A')[0])+ self.osen

                self.errCode = int(gcs.qERR(self.id))

                if not self.errCode == 0:
                    logging.info(('Stage Error: %d' % self.errCode))

                # print self.targetPosition, self.stopMove
                if not np.all(self.targetPosition == self.lastTargetPosition):
                    # update our target position
                    pos = np.clip(self.targetPosition, 0, self.max_travel)

                    gcs.MOV(self.id, b'A', pos[:1])
                    self.lastTargetPosition = pos.copy()
                    # print('p')
                    # logging.debug('Moving piezo to target: %f' % (pos[0],))

                if np.allclose(self.position, self.targetPosition, atol=self._target_tol):
                    if not self.onTarget:
                        logEvent('PiezoOnTarget', '%.3f' % self.position[0], time.time())
                        self.onTarget = True

                # check to see if we're on target
                #self.ser_port.write('ONT? A\n')
                #self.ser_port.flushOutput()
                #time.sleep(0.005)
                #res1 = self.ser_port.readline()

                #if res1 == '':
                #    time.sleep(.5)
                #    res1 = self.ser_port.readline()

                #try:
                #    self.onTarget = int(res1) == 1
                #except ValueError:
                #    self.onTarget = False
                #    logging.exception('Value error on response from ONT')

                # time.sleep(.1)


            except IndexError:
                print('IndexException')
            finally:
                self.stopMove = False
                self.lock.release()

        # close port on loop exit
        gcs.CloseConnection(self.id)
        logging.info("Piezo USB connection closed")
예제 #8
0
 def OnFrame(self, frameNum):
     if frameNum > self.startFrame:
         fn = floor((frameNum - self.startFrame)/self.dwellTime) % len(self.zPoss)
         if not fn == self.pos:
             self.pos = fn
             self.piezo.MoveTo(self.piezoChan, self.zPoss[self.pos])
             eventLog.logEvent('ProtocolFocus', '%d, %3.3f' % (frameNum, self.zPoss[self.pos]))
             
     TaskListProtocol.OnFrame(self, frameNum)
예제 #9
0
 def OnFrame(self, frameNum):
     while not self.listPos >= len(
             self.taskList) and frameNum >= self.taskList[
                 self.listPos].when:
         t = self.taskList[self.listPos]
         t.what(*t.params)
         eventLog.logEvent(
             'ProtocolTask', '%d, %s, ' % (frameNum, t.what.__name__) +
             ', '.join(['%s' % p for p in t.params]))
         self.listPos += 1
예제 #10
0
    def StartExposure(self):
        self.__selectCamera()
        self._GetCCDTemp()
        self._GetAcqTimings()
        self._GetBufferSize()

        eventLog.logEvent('StartAq', '')
        ret = ac.StartAcquisition()
        if not ret == ac.DRV_SUCCESS:
            raise RuntimeError('Error starting acquisition: %s' % ac.errorCodes[ret])
        return 0
    def StartExposure(self):
        #make sure no acquisiton is running
        self.StopAq()
        self._temp = self.SensorTemperature.getValue()
        self._frameRate = self.FrameRate.getValue()
        
        eventLog.logEvent('StartAq', '')
        self._flush()
        self.InitBuffers()
        self.AcquisitionStart()

        return 0
예제 #12
0
    def StartExposure(self):
        #make sure no acquisiton is running
        self.StopAq()
        self._temp = self.SensorTemperature.getValue()
        self._frameRate = self.FrameRate.getValue()

        eventLog.logEvent('StartAq', '')
        self._flush()
        self.InitBuffers()
        self.AcquisitionStart()

        return 0
예제 #13
0
    def OnFrame(self, frameNum):
        if frameNum > self.startFrame:
            fn = floor((frameNum - self.startFrame) / self.dwellTime) % len(
                self.zPoss)
            if not fn == self.pos:
                self.pos = fn
                self.piezo.MoveTo(self.piezoChan, self.zPoss[self.pos])
                eventLog.logEvent(
                    'ProtocolFocus',
                    '%d, %3.3f' % (frameNum, self.zPoss[self.pos]))

        TaskListProtocol.OnFrame(self, frameNum)
예제 #14
0
    def StartExposure(self):
        self._get_temps()
        if self._recording == False:
            self._init_buffers()

        eventLog.logEvent('StartAq', '')
        self._recording = True

        if (self._mode == self.MODE_SINGLE_SHOT) or (self._mode == self.MODE_SOFTWARE_TRIGGER):
            self.TriggerAq()

        return 0
예제 #15
0
 def MoveTo(self, iChannel, fPos, bTimeOut=True):
     stepPos = round(fPos/self.stepsize)
     print(stepPos)
     if (stepPos >= self.hardMin):
         if (fPos < self.max_travel):
             nik.ZDrive.Position = int(stepPos)
         else:
              nik.ZDrive.Position = int(round(self.max_travel/self.stepsize))
     else:
         nik.ZDrive.Position = self.hardMin
         
     eventLog.logEvent('Focus Change', 'New z-pos = %f' % stepPos)
예제 #16
0
    def StartExposure(self):
        self.__selectCamera()
        self._GetCCDTemp()
        self._GetAcqTimings()
        self._GetBufferSize()

        eventLog.logEvent('StartAq', '')
        ret = ac.StartAcquisition()
        if not ret == ac.DRV_SUCCESS:
            raise RuntimeError('Error starting acquisition: %s' %
                               ac.errorCodes[ret])
        return 0
예제 #17
0
    def StartExposure(self):

        if self.doPoll:
            print('StartAq')
            self.StopAq()
        self.InitBuffers()

        eventLog.logEvent('StartAq', '')
        ret = uc480.CALL('CaptureVideo', self.boardHandle, uc480.IS_DONT_WAIT)
        if not ret == 0:
            raise RuntimeError('Error starting exposure: %d: %s' %
                               GetError(self.boardHandle))
        return 0
예제 #18
0
    def MoveTo(self, iChannel, fPos, bTimeOut=True):
        stepPos = round(fPos / self.stepsize)
        print(stepPos)
        if (stepPos >= self.hardMin):
            if (fPos < self.max_travel):
                nik.ZDrive.Position = int(stepPos)
            else:
                nik.ZDrive.Position = int(
                    round(self.max_travel / self.stepsize))
        else:
            nik.ZDrive.Position = self.hardMin

        eventLog.logEvent('Focus Change', 'New z-pos = %f' % stepPos)
예제 #19
0
    def _poll_loop(self, sleep_interval=.01):
        """
        This loop runs in a background thread to continuously poll the camera and deal with frames as they arrive.

        Parameters
        ----------
        sleep_interval : float
            length of time to sleep within the polling thread

        Returns
        -------

        """
        while (self._poll_camera):
            if (not self.cam.CamReady()):  # and self.piezoReady())):
                # Stop the aquisition if there is a hardware error
                wx.CallAfter(self.stop)
            else:
                #is there a picture waiting for us?
                #if so do the relevant processing
                #otherwise do nothing ...

                #nFrames = 0 #number of frames grabbed this pass

                #bufferOverflowed = False

                while (self.cam.ExpReady()
                       ):  #changed to deal with multiple frames being ready
                    if 'GetNumImsBuffered' in dir(self.cam):
                        bufferOverflowing = self.cam.GetNumImsBuffered() >= (
                            self.cam.GetBufferSize() - 2)
                    else:
                        bufferOverflowing = False

                    if bufferOverflowing:
                        self.bufferOverflowed = True
                        print(
                            'Warning: Camera buffer overflowing - purging buffer'
                        )
                        eventLog.logEvent('Camera Buffer Overflow')
                        #stop the aquisition - we're going to restart after we're read out to purge the buffer
                        #doing it this way _should_ stop the black frames which I guess are being caused by the reading the frame which is
                        #currently being written to
                        wx.CallAfter(self.cam.StopAq)
                        #self.needExposureStart = True

                    self.onExpReady()
                    self.n_frames_in_group += 1

            time.sleep(sleep_interval)
예제 #20
0
    def StartExposure(self):
        logger.debug('StartAq')
        if self._poll:
            # stop, we'll allocate buffers and restart
            self.StopAq()
        # allocate at least 2 seconds of buffers
        buffer_size = int(max(2 * self.GetFPS(), 50))
        self.InitBuffers(buffer_size, buffer_size)

        event_log.logEvent('StartAq', '')
        if self._cont_mode:
            self.check_success(ueye.is_CaptureVideo(self.h, ueye.IS_DONT_WAIT))
        else:
            self.check_success(ueye.is_FreezeVideo(self.h, ueye.IS_DONT_WAIT))
        return 0
예제 #21
0
    def OnFrame(self, frameNum):
        if frameNum > self.startFrame:
            fn = int(
                floor((frameNum - self.startFrame) / self.dwellTime) %
                len(self.zPoss))
            if not fn == self.pos:
                self.pos = fn
                #self.piezo.MoveTo(self.piezoChan, self.zPoss[self.pos])
                scope.state.setItem(self.piezoName,
                                    self.zPoss[self.pos],
                                    stopCamera=self.require_camera_restart)
                eventLog.logEvent(
                    'ProtocolFocus',
                    '%d, %3.3f' % (frameNum, self.zPoss[self.pos]))

        TaskListProtocol.OnFrame(self, frameNum)
예제 #22
0
    def _thread_target(self):
        fast_pz, fast_chan, mult = self.scope.positioning[self.fast_axis]
        mult = abs(mult)
        old_vel = fast_pz.GetVelocity(fast_chan)  #remember the old velocity
        fast_pz.SetVelocity(
            fast_chan,
            self.vel / abs(mult))  #set velocity to give desired pixel sampling

        slow_pz, slow_chan, smult = self.scope.positioning[self.slow_axis]
        smult = abs(smult)

        #do stripes, alternating direction
        for i, slow_v in enumerate(self.slow_steps):
            if (i % 2):
                fs, fe = self.fast_max, self.fast_min
            else:
                fe, fs = self.fast_max, self.fast_min

            #self.scope.pa.stop()
            print('Moving to %f, %f' % (fs, slow_v))
            fast_pz.MoveTo(fast_chan, fs / mult)
            slow_pz.MoveTo(slow_chan, slow_v / smult)

            # wait for the slow axis to get there
            print('waiting for stage [slow move]')
            while not slow_pz.onTarget:
                time.sleep(0.1)

            if self.log_events:
                #TODO - fixme for axis selection
                eventLog.logEvent('ScannerXPos', '%3.6f' % slow_v)
                eventLog.logEvent('ScannerYPos', '%3.6f' % fs)

            #self.scope.pa.start()

            print('Slow move done, making fast move')

            #start the move with acquisition running
            fast_pz.MoveTo(fast_chan, fe / mult)

            print('waiting for stage [fast move]')
            while not fast_pz.onTarget:
                #wait for the fast axis to get there
                time.sleep(.1)

        fast_pz.SetVelocity(fast_chan, old_vel)  #restore old velocity
        print('Scan complete')
예제 #23
0
    def StartExposure(self):
        # self.StopAq()
        self.n_read = 0
        d = self.cam.sdk.get_delay_exposure_time()
        self._cycle_time = d['exposure']*timebase[d['exposure timebase']] \
                           + d['delay']*timebase[d['delay timebase']]
        if self._mode == self.MODE_SINGLE_SHOT:
            self.cam.record(number_of_images=1, mode='sequence')
        elif self._mode == self.MODE_CONTINUOUS:
            # Allocate buffer (2 seconds of buffer)
            self.buffer_size = int(max(int(2.0 * self.GetFPS()), 1))
            self.cam.record(number_of_images=self.buffer_size,
                            mode='ring buffer')
        self.recording = True

        eventLog.logEvent('StartAq', '')

        return 0
예제 #24
0
    def StartExposure(self):
        #make sure no acquisiton is running
        self.StopAq()
        self._temp = self.SensorTemperature.getValue()
        self._frameRate = self.FrameRate.getValue()
        self.tKin = 1.0 / self._frameRate

        self._frame_wait_time = ctypes.c_uint(int(max(2*1000*self.tKin, 100)))

        self.hardware_overflowed = False
        self._n_timeouts = 0
        #logger.debug('StartAq')
        eventLog.logEvent('StartAq', '')
        self._flush()
        self.InitBuffers()
        self.AcquisitionStart()

        return 0
예제 #25
0
    def StartExposure(self):
        
        if self.doPoll:
            print('StartAq')
            self.StopAq()
        # allocate at least 2 seconds of buffers
        buffer_size = int(max(2 * self.GetFPS(), 50))
        self.InitBuffers(buffer_size, buffer_size)
        
        

        eventLog.logEvent('StartAq', '')
        if self._cont_mode:
            ret = uc480.CALL('CaptureVideo', self.boardHandle, uc480.IS_DONT_WAIT)
        else:
            ret = uc480.CALL('FreezeVideo', self.boardHandle, uc480.IS_DONT_WAIT)
        if not ret == 0:
            raise RuntimeError('Error starting exposure: %d: %s' % GetError(self.boardHandle))
        return 0
예제 #26
0
    def _poll_loop(self):
        """
        This loop runs in a background thread to continuously poll the camera 
        and deal with frames as they arrive. `FrameWrangler._polling_interval`
        is used to set the delay between loops.
        """
        while (self._poll_camera):
            if (not self.cam.CamReady()):# and self.piezoReady())):
                # Stop the aquisition if there is a hardware error
                self._event_loop.call_in_main_thread(self.stop)
            else:
                #is there a picture waiting for us?
                #if so do the relevant processing
                #otherwise do nothing ...
        
                #nFrames = 0 #number of frames grabbed this pass
        
                #bufferOverflowed = False
        
                while (self.cam.ExpReady()): #changed to deal with multiple frames being ready
                    if 'GetNumImsBuffered' in dir(self.cam):
                        bufferOverflowing = self.cam.GetNumImsBuffered() >= (self.cam.GetBufferSize() - 2)
                    else:
                        bufferOverflowing = False

                    if bufferOverflowing:
                        with self._notify_lock:
                            #acquire lock before flagging the buffer as overflowed so that we can be sure that StopAq
                            # gets called before StartAq in Notify()
                            
                            self.bufferOverflowed = True
                            logger.warning('Camera buffer overflowing - purging buffer')
                            eventLog.logEvent('Camera Buffer Overflow')
                            #stop the aquisition - we're going to restart after we're read out to purge the buffer
                            #doing it this way _should_ stop the black frames which I guess are being caused by the reading the frame which is
                            #currently being written to
                            self._event_loop.call_in_main_thread(self.cam.StopAq)
                        #self.needExposureStart = True
            
                    self.onExpReady()
                    self.n_frames_in_group += 1
        
            time.sleep(self._polling_interval)
예제 #27
0
    def Init(self, spooler):
        self.zPoss = np.arange(
            scope.stackSettings.GetStartPos(),
            scope.stackSettings.GetEndPos() +
            .95 * scope.stackSettings.GetStepSize(),
            scope.stackSettings.GetStepSize() *
            scope.stackSettings.GetDirection())

        if self.slice_order != 'saw':
            if self.slice_order == 'random':
                self.zPoss = self.zPoss[np.argsort(
                    np.random.rand(len(self.zPoss)))]
            elif self.slice_order == 'triangle':
                if len(self.zPoss) % 2:
                    # odd
                    self.zPoss = np.concatenate(
                        [self.zPoss[1::2], self.zPoss[::-2]])
                else:
                    # even
                    self.zPoss = np.concatenate(
                        [self.zPoss[::2], self.zPoss[-1::-2]])

        self.piezoName = 'Positioning.%s' % scope.stackSettings.GetScanChannel(
        )
        self.startPos = scope.state[
            self.piezoName +
            '_target']  #FIXME - _target positions shouldn't be part of scope state
        self.pos = 0

        spooler.md.setEntry('Protocol.PiezoStartPos', self.startPos)
        spooler.md.setEntry('Protocol.ZStack', True)

        scope.state.setItem(self.piezoName,
                            self.zPoss[self.pos],
                            stopCamera=self.require_camera_restart)
        eventLog.logEvent('ProtocolFocus',
                          '%d, %3.3f' % (0, self.zPoss[self.pos]))

        TaskListProtocol.Init(self, spooler)
예제 #28
0
    def tick(self, frameData, **kwargs):
        with self._rlock:
            if not self.running:
                return

            try:
                cam_trigger = self.scope.cam.GetAcquisitionMode() == self.scope.cam.MODE_SOFTWARE_TRIGGER
            except AttributeError:
                cam_trigger = False

            #logger.debug('Cam_trigger: %s' % repr(cam_trigger))

            #print self.callNum
            if (self.callNum % self.dwellTime) == 0:
                #record pixel in overview
                callN = int(self.callNum/self.dwellTime)
                if self.avg:
                    self.image[callN % self.nx, int((callN % (self.image.size))/self.nx)] = self.scope.currentFrame.mean() - self.background
                    self.view.Refresh()
            
            if self.callNum >= self.dwellTime * self.imsize - 1:
                # we've acquired the last frame
                if self._stop_on_complete:
                    self._stop()
                    return

            if ((self.callNum +1) % self.dwellTime) == 0:
                #move piezo
                callN = int((self.callNum+1)/self.dwellTime)
                new_x, new_y = self._position_for_index(callN)

                self.scope.state.setItems({'Positioning.x' : new_x,
                                           'Positioning.y' : new_y
                                           }, stopCamera = not cam_trigger)

                #print 'SetP'

                if self.evtLog:
                    #eventLog.logEvent('ScannerXPos', '%3.6f' % self.xp[callN % self.nx])
                    #eventLog.logEvent('ScannerYPos', '%3.6f' % self.yp[(callN % (self.imsize))/self.nx])
                    eventLog.logEvent('ScannerXPos', '%3.6f' % self.scope.state['Positioning.x'])
                    eventLog.logEvent('ScannerYPos', '%3.6f' % self.scope.state['Positioning.y'])

            if cam_trigger:
                #logger.debug('Firing camera trigger')
                self.scope.cam.FireSoftwareTrigger()
                if self.evtLog:
                    eventLog.logEvent('StartAq',"")
#
        #
        #if self.sync:
#                while not self.xpiezo[0].IsOnTarget(): #wait for stage to move
#                    time.sleep(.05)

        self.callNum += 1
예제 #29
0
    def start(self):

        #pixels = np.array(pixels)

#        if np.isscalar(self.pixels):
#            #constant - use as number of pixels
#            #center on current piezo position
#            self.xp = self.pixelsize*np.arange(-self.pixels/2, self.pixels/2 +1) + self.xpiezo[0].GetPos(self.xpiezo[1])
#            self.yp = self.pixelsize*np.arange(-self.pixels/2, self.pixels/2 +1) + self.ypiezo[0].GetPos(self.ypiezo[1])
#        elif np.isscalar(self.pixels[0]):
#            #a 1D array - numbers in either direction centered on piezo pos
#            self.xp = self.pixelsize*np.arange(-self.pixels[0]/2, self.pixels[0]/2 +1) + self.xpiezo[0].GetPos(self.xpiezo[1])
#            self.yp = self.pixelsize*np.arange(-self.pixels[1]/2, self.pixels[1]/2 +1) + self.ypiezo[0].GetPos(self.ypiezo[1])
#        else:
#            #actual pixel positions
#            self.xp = self.pixels[0]
#            self.yp = self.pixels[1]
#
#        self.nx = len(self.xp)
#        self.ny = len(self.yp)
#
#        self.imsize = self.nx*self.ny

        self.genCoords()

        self.callNum = -1

        if self.avg:
            self.image = np.zeros((self.nx, self.ny, self.nz))

            self.ds = self.scope.frameWrangler.currentFrame

            self.view = View3D(self.image)

        self.xpiezo[0].MoveTo(self.xpiezo[1], self.xp[0])
        self.ypiezo[0].MoveTo(self.ypiezo[1], self.yp[0])
        self.zpiezo[0].MoveTo(self.zpiezo[1], self.zp[0])

        self.ix_o = 0
        self.iy_o = 0

        #if self.sync:
        #    while not self.xpiezo[0].IsOnTarget(): #wait for stage to move
        #        time.sleep(.05)

        if self.evtLog:
                eventLog.logEvent('ScannerXPos', '%3.6f' % self.xp[0])
                eventLog.logEvent('ScannerYPos', '%3.6f' % self.yp[0])
                eventLog.logEvent('ScannerZPos', '%3.6f' % self.zp[0])


        self.scope.frameWrangler.WantFrameNotification.append(self.tick)

        if self.sync:
            self.scope.frameWrangler.HardwareChecks.append(self.onTarget)
예제 #30
0
    def tick(self, caller=None):
        #print self.callNum
        
        if self.callNum > 0  and (self.callNum % self.dwellTime) == 0:
            #record pixel in overview
            callN = int(self.callNum/self.dwellTime)

            #vary z fastest
            iz = callN % self.nz
            ix = (callN/self.nz) % self.nx
            iy = (callN/(self.nz*self.nx)) % self.ny

            if self.avg:
                self.image[ix, iy, iz] = self.ds.mean() - self.background
                self.view.Refresh()

        if ((self.callNum +1) % self.dwellTime) == 0:
            #move piezo
            callN = int((self.callNum+1)/self.dwellTime)

            #vary z fastest
            iz = callN % self.nz
            ix = (callN/self.nz) % self.nx
            iy = (callN/(self.nz*self.nx)) % self.ny

            self.zpiezo[0].MoveTo(self.zpiezo[1], self.zp[iz])
            if self.evtLog:
                eventLog.logEvent('ScannerZPos', '%3.6f' % self.zp[iz])

            if not ix == self.ix_o:
                self.xpiezo[0].MoveTo(self.xpiezo[1], self.xp[ix])
                self.ix_o = ix
                if self.evtLog:
                    eventLog.logEvent('ScannerXPos', '%3.6f' % self.xp[ix])
                    
            if not iy == self.iy_o:
                self.ypiezo[0].MoveTo(self.ypiezo[1], self.yp[iy])
                self.iy_o = iy
                if self.evtLog:
                    eventLog.logEvent('ScannerYPos', '%3.6f' % self.yp[iy])

                        

#            if self.sync:
#                while not self.xpiezo[0].IsOnTarget(): #wait for stage to move
#                    time.sleep(.05)

        self.callNum += 1
예제 #31
0
    def _Loop(self):
        while self.loopActive:
            self.lock.acquire()
            try:
                # check position
                time.sleep(self._update_rate)

                self.position[0] = float(gcs.qPOS(self.id, b'A')[0])+ self.osen

                self.errCode = int(gcs.qERR(self.id))

                if not self.errCode == 0:  # I have yet to see this work
                    logging.info(('Stage Error: %d' % self.errCode))

                # print self.targetPosition, self.stopMove
                if not np.all(self.targetPosition == self.lastTargetPosition):
                    # update our target position
                    pos = np.clip(self.targetPosition, 0, self.max_travel)

                    gcs.MOV(self.id, b'A', pos[:1])
                    self.lastTargetPosition = pos.copy()
                    # print('p')
                    # logging.debug('Moving piezo to target: %f' % (pos[0],))

                if np.allclose(self.position, self.targetPosition, atol=self._target_tol):
                    if not self.onTarget:
                        logEvent('PiezoOnTarget', '%.3f' % self.position[0], time.time())
                        self.onTarget = True

                # check to see if we're on target
                #self.ser_port.write('ONT? A\n')
                #self.ser_port.flushOutput()
                #time.sleep(0.005)
                #res1 = self.ser_port.readline()

                #if res1 == '':
                #    time.sleep(.5)
                #    res1 = self.ser_port.readline()

                #try:
                #    self.onTarget = int(res1) == 1
                #except ValueError:
                #    self.onTarget = False
                #    logging.exception('Value error on response from ONT')

                # time.sleep(.1)
            except RuntimeError as e:
                # gcs.fcnWrap.HandleError throws Runtimes for everything
                logger.error(str(e))
                try:
                    self.errCode = int(gcs.qERR(self.id))
                    logger.error('error code: %s' % str(self.errCode))
                except:
                    logger.error('no error code retrieved')
                if '-1' in str(e):
                    logger.debug('reinitializing GCS connection, 10 s pause')
                    gcs.CloseConnection(self.id)
                    time.sleep(10.0)  # this takes at least more than 1 s
                    try:
                        self.id = gcs.ConnectUSB(self._identifier)
                        logger.debug('restablished connection to piezo')
                    except RuntimeError as e:
                        logger.error('trying to get new device ID')
                        devices = get_connected_devices()
                        self._identifier = devices[0]
                        logger.debug('new device ID acquired')
                        self.id = gcs.ConnectUSB(self._identifier)
                    time.sleep(1.0)
                    logger.debug('turning on servo')
                    gcs.SVO(self.id, b'A', [1])
                    time.sleep(1.0)
            finally:
                self.lock.release()

        # close port on loop exit
        gcs.CloseConnection(self.id)
        logging.info("Piezo USB connection closed")
    def Notify(self, event=None):
        """Callback which is called regularly by a system timer to poll the
        camera"""

        #check to see if we are already running
        if self.inNotify:
            print('Already in notify, skip for now')
            return

        try:
            self.inNotify = True
            "Should be called on each timer tick"
            self.te = time.clock()
            #print self.te - self.tl
            self.tl = self.te
            #print "Notify"

            #self.loopnuf = self.loopnuf + 1

            if (True):  #check that we are aquiring

                if (not (self.cam.CamReady() and self.piezoReady())):
                    # Stop the aquisition if there is a hardware error
                    self.stop()
                    return

                #is there a picture waiting for us?
                #if so do the relevant processing
                #otherwise do nothing ...

                nFrames = 0  #number of frames grabbed this pass

                bufferOverflowed = False

                while (self.cam.ExpReady()
                       ):  #changed to deal with multiple frames being ready
                    if 'GetNumImsBuffered' in dir(self.cam):
                        bufferOverflowing = self.cam.GetNumImsBuffered() >= (
                            self.cam.GetBufferSize() - 1)
                    else:
                        bufferOverflowing = False
                    if bufferOverflowing:
                        bufferOverflowed = True
                        print(
                            'Warning: Camera buffer overflowing - purging buffer'
                        )
                        eventLog.logEvent('Camera Buffer Overflow')
                        #stop the aquisition - we're going to restart after we're read out to purge the buffer
                        #doing it this way _should_ stop the black frames which I guess are being caused by the reading the frame which is
                        #currently being written to
                        self.cam.StopAq()

                    self.onExpReady()
                    nFrames += 1
                    #te= time.clock()

                    #If we can't deal with the data fast enough (e.g. due to file i/o limitations) this can turn into an infinite loop -
                    #avoid this by bailing out with a warning if nFrames exceeds a certain value. This will probably lead to buffer overflows
                    #and loss of data, but is arguably better than an unresponsive app.
                    #This value is (currently) chosen fairly arbitrarily, taking the following facts into account:
                    #the buffer has enough storage for ~3s when running flat out,
                    #we're polling at ~5hz, and we should be able to get more frames than would be expected during the polling intervall to
                    #allow us to catch up following glitches of one form or another, although not too many more.
                    if ('GetNumImsBuffered' in dir(self.cam)) and (
                            nFrames > self.cam.GetBufferSize() / 2):
                        print((
                            'Warning: not keeping up with camera, giving up with %d frames still in buffer'
                            % self.cam.GetNumImsBuffered()))
                        break

                if bufferOverflowed:
                    print('nse')
                    self.needExposureStart = True

                if self.needExposureStart and self.checkHardware():
                    self.needExposureStart = False
                    self.cam.StartExposure(
                    )  #restart aquisition - this should purge buffer

                #if 'nQueued' in dir(self.cam):
                #    print '\n', nFrames, self.cam.nQueued, self.cam.nFull , self.cam.doPoll
                if nFrames > 0:
                    self.n_Frames += nFrames

                    self.tLastFrame = self.tThisFrame
                    self.nFrames = nFrames
                    self.tThisFrame = time.clock()

                    self.onFrameGroup.send_robust(self)
            else:
                self._stop()
        except:
            traceback.print_exc()
        finally:
            self.inNotify = False
            #self.timer.StartOnce(self.tiint)
            self.timer.Start(self.tiint, wx.TIMER_ONE_SHOT)
예제 #33
0
 def OnFrame(self, frameNum):
     while not self.listPos >= len(self.taskList) and frameNum >= self.taskList[self.listPos].when:
         t = self.taskList[self.listPos]
         t.what(*t.params)
         eventLog.logEvent('ProtocolTask', '%d, %s, ' % (frameNum, t.what.__name__) + ', '.join(['%s' % p for p in t.params]))
         self.listPos += 1
예제 #34
0
 def OnFinish(self):
     while not  self.listPos >= len(self.taskList):
         t = self.taskList[self.listPos]
         t.what(*t.params)
         eventLog.logEvent('ProtocolTask', '%s, ' % ( t.what.__name__,) + ', '.join(['%s' % p for p in t.params]))
         self.listPos += 1
예제 #35
0
 def Notify(self):
     #check to see if we are already running
     if self.inNotify:
         print('Already in notify, skip for now')
         return
         
     try:
         self.inNotify = True
         "Should be called on each timer tick"
         self.te = time.clock()
         #print self.te - self.tl
         self.tl = self.te
         #print "Notify"
 
         #self.loopnuf = self.loopnuf + 1
         
         if (True): #check that we are aquiring
         
 	
             if(not (self.cam.CamReady() and self.piezoReady())):
                 # Stop the aquisition if there is a hardware error
                 self.stop()
                 return
 
             #is there a picture waiting for us?
             #if so do the relevant processing
             #otherwise do nothing ...
         	
             nFrames = 0 #number of frames grabbed this pass
             
             bufferOverflowed = False
 
             while(self.cam.ExpReady()): #changed to deal with multiple frames being ready
                 if 'GetNumImsBuffered' in dir(self.cam):
                     bufferOverflowing  = self.cam.GetNumImsBuffered() >= (self.cam.GetBufferSize() - 1)
                 else:
                     bufferOverflowing = False
                 if bufferOverflowing:
                     bufferOverflowed = True
                     print('Warning: Camera buffer overflowing - purging buffer')
                     eventLog.logEvent('Camera Buffer Overflow')
                     #stop the aquisition - we're going to restart after we're read out to purge the buffer
                     #doing it this way _should_ stop the black frames which I guess are being caused by the reading the frame which is
                     #currently being written to
                     self.cam.StopAq()
  
                 self.onExpReady()
                 nFrames += 1
                 #te= time.clock()
                 
                 #If we can't deal with the data fast enough (e.g. due to file i/o limitations) this can turn into an infinite loop -
                 #avoid this by bailing out with a warning if nFrames exceeds a certain value. This will probably lead to buffer overflows
                 #and loss of data, but is arguably better than an unresponsive app.
                 #This value is (currently) chosen fairly arbitrarily, taking the following facts into account: 
                 #the buffer has enough storage for ~3s when running flat out,
                 #we're polling at ~5hz, and we should be able to get more frames than would be expected during the polling intervall to
                 #allow us to catch up following glitches of one form or another, although not too many more.
                 if ('GetNumImsBuffered' in dir(self.cam)) and (nFrames > self.cam.GetBufferSize()/2):
                     print(('Warning: not keeping up with camera, giving up with %d frames still in buffer' % self.cam.GetNumImsBuffered()))
                     break
 
             if bufferOverflowed:
                 print('nse')
                 self.needExposureStart = True
 
             if self.needExposureStart and self.checkHardware():
                 self.needExposureStart = False
                 self.cam.StartExposure() #restart aquisition - this should purge buffer
                 
 
             #if 'nQueued' in dir(self.cam):
             #    print '\n', nFrames, self.cam.nQueued, self.cam.nFull , self.cam.doPoll
             if nFrames > 0:
                 self.n_Frames += nFrames
                 
                 self.tLastFrame = self.tThisFrame
                 self.nFrames = nFrames
                 self.tThisFrame = time.clock()
 
                 for a in self.WantFrameGroupNotification:
                 	a(self)
         else:
              self._stop()
     except:
         traceback.print_exc()
     finally:     
         self.inNotify = False
예제 #36
0
    def tick(self, **kwargs):
        targetZ = self.piezo.GetTargetPos(0)

        if not 'mask' in dir(
                self
        ) or not self.scope.frameWrangler.currentFrame.shape[:
                                                             2] == self.mask.shape[:
                                                                                   2]:
            self.initialise()

        #called on a new frame becoming available
        if self.calibState == 0:
            #print "cal init"
            #redefine our positions for the calibration
            self.homePos = self.piezo.GetPos(0)
            self.calPositions = self.homePos + self.deltaZ * np.arange(
                -float(self.stackHalfSize), float(self.stackHalfSize + 1))
            self.NCalibStates = len(self.calPositions)

            self.refImages = np.zeros(self.mask.shape[:2] +
                                      (self.NCalibStates, ))
            self.calImages = np.zeros(self.mask.shape[:2] +
                                      (self.NCalibStates, ))
            self.calFTs = np.zeros(self.mask.shape[:2] + (self.NCalibStates, ),
                                   dtype='complex64')

            self.piezo.MoveTo(0, self.calPositions[0])

            #self.piezo.SetOffset(0)
            self.calibState += .5
        elif self.calibState < self.NCalibStates:
            # print "cal proceed"
            if (self.calibState % 1) == 0:
                #full step - record current image and move on to next position
                self.setRefN(int(self.calibState - 1))
                self.piezo.MoveTo(0, self.calPositions[int(self.calibState)])

            #increment our calibration state
            self.calibState += 0.5

        elif (self.calibState == self.NCalibStates):
            # print "cal finishing"
            self.setRefN(int(self.calibState - 1))

            #perform final bit of calibration - calcuate gradient between steps
            #self.dz = (self.refC - self.refB).ravel()
            #self.dzn = 2./np.dot(self.dz, self.dz)
            self.dz = np.gradient(self.calImages)[2].reshape(
                -1, self.NCalibStates)
            self.dzn = np.hstack([
                1. / np.dot(self.dz[:, i], self.dz[:, i])
                for i in range(self.NCalibStates)
            ])

            self.piezo.MoveTo(0, self.homePos)

            #reset our history log
            self.history = []
            self.historyCorrections = []

            self.calibState += 1

        elif (self.calibState > self.NCalibStates) and np.allclose(
                self._last_target_z, targetZ):
            # print "fully calibrated"
            dx, dy, dz, cCoeff, dzcorr, nomPos, posInd, calPos, posDelta = self.compare(
            )

            self.corrRef = max(self.corrRef, cCoeff)

            #print dx, dy, dz

            #FIXME: logging shouldn't call piezo.GetOffset() etc ... for performance reasons
            self.history.append((time.time(), dx, dy, dz, cCoeff, self.corrRef,
                                 self.piezo.GetOffset(), self.piezo.GetPos(0)))
            eventLog.logEvent('PYME2ShiftMeasure',
                              '%3.4f, %3.4f, %3.4f' % (dx, dy, dz))

            self.lockActive = self.lockFocus and (cCoeff > .5 * self.corrRef)
            if self.lockActive:
                if abs(self.piezo.GetOffset()) > 20.0:
                    self.lockFocus = False
                    logger.info("focus lock released")
                if abs(
                        dz
                ) > self.focusTolerance and self.lastAdjustment >= self.minDelay:
                    zcorr = self.piezo.GetOffset() - dz
                    if zcorr < -self.maxfac * self.focusTolerance:
                        zcorr = -self.maxfac * self.focusTolerance
                    if zcorr > self.maxfac * self.focusTolerance:
                        zcorr = self.maxfac * self.focusTolerance
                    self.piezo.SetOffset(zcorr)

                    #FIXME: this shouldn't be needed as it is logged during LogShifts anyway
                    self.piezo.LogFocusCorrection(
                        zcorr)  #inject offset changing into 'Events'
                    eventLog.logEvent('PYME2UpdateOffset', '%3.4f' % (zcorr))

                    self.historyCorrections.append((time.time(), dz))
                    self.lastAdjustment = 0
                else:
                    self.lastAdjustment += 1

            if self.logShifts:
                self.piezo.LogShifts(dx, dy, dz, self.lockActive)

        self._last_target_z = targetZ