Ejemplo n.º 1
0
 def __init__(self, deviceManager, config, name):
     QtCore.QObject.__init__(self)
     self._lock_ = Mutex(QtCore.QMutex.Recursive)  ## no, good idea
     self._lock_tb_ = None
     self.dm = deviceManager
     self.dm.declareInterface(name, ['device'], self)
     self._name = name
Ejemplo n.º 2
0
 def __init__(self, dev, driver, lock):
     Thread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.dev = dev
     self.driver = driver
     self.driverLock = lock
     self.cmds = {}
Ejemplo n.º 3
0
    def __init__(self, manager, config, name):
        self.config = config
        self.manager = manager
        self.hasPowerIndicator = False
        self.hasShutter = False
        self.hasTriggerableShutter = False
        self.hasQSwitch = False
        self.hasPCell = False
        self.hasTunableWavelength = False

        self.params = {
            'expectedPower': config.get('power', None),  ## Expected output
            'currentPower': None,  ## Last measured output power
            'scopeTransmission':
            None,  ## percentage of output power that is transmitted to slice
            'tolerance': 10.0,  ## in %
            'useExpectedPower': True,
            'powerAlert':
            True  ## set True if you want changes in output power to raise an error
        }

        daqConfig = {
        }  ### DAQ generic needs to know about powerIndicator, pCell, shutter, qswitch
        if 'powerIndicator' in config:
            self.hasPowerIndicator = True
            #### name of powerIndicator is config['powerIndicator']['channel'][0]
            #daqConfig['powerInd'] = {'channel': config['powerIndicator']['channel'], 'type': 'ai'}
        if 'shutter' in config:
            daqConfig['shutter'] = config['shutter']
            self.hasTriggerableShutter = True
            self.hasShutter = True
        if 'qSwitch' in config:
            daqConfig['qSwitch'] = config['qSwitch']
            self.hasQSwitch = True
        if 'pCell' in config:
            daqConfig['pCell'] = config['pCell']
            self.hasPCell = True

        daqConfig['power'] = {
            'type': 'ao',
            'units': 'W'
        }  ## virtual channel used for creating control widgets
        DAQGeneric.__init__(self, manager, daqConfig, name)
        OptomechDevice.__init__(self, manager, config, name)

        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.variableLock = Mutex(QtCore.QMutex.Recursive)
        self.calibrationIndex = None
        self.pCellCalibration = None
        self.getPowerHistory()

        #self.scope = manager.getDevice(self.config['scope'])
        #self.scope.sigObjectiveChanged.connect(self.objectiveChanged)
        self.sigGlobalSubdeviceChanged.connect(
            self.opticStateChanged
        )  ## called when objectives/filters have been switched

        manager.declareInterface(name, ['laser'], self)
        manager.sigAbortAll.connect(self.closeShutter)
Ejemplo n.º 4
0
 def __init__(self, dev, startState=None):
     Thread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.dev = dev
     self.port = self.dev.port
     if startState is None:
         self.pos = [0, 0]
         self.btns = [0, 0]
     else:
         self.pos = startState['pos']
         self.btns = startState['btns']
Ejemplo n.º 5
0
    def __init__(self, deviceManager, config, name):
        QtCore.QObject.__init__(self)

        # task reservation lock -- this is a recursive lock to allow a task to run its own subtasks
        # (for example, setting a holding value before exiting a task).
        # However, under some circumstances we might try to run two concurrent tasks from the same
        # thread (eg, due to calling processEvents() while waiting for the task to complete). We
        # don't have a good solution for this problem at present..
        self._lock_ = Mutex(QtCore.QMutex.Recursive)
        self._lock_tb_ = None
        self.dm = deviceManager
        self.dm.declareInterface(name, ['device'], self)
        self._name = name
Ejemplo n.º 6
0
    def __init__(self, manager):
        Qt.QMainWindow.__init__(self)
        self.setWindowTitle("Log")
        path = os.path.dirname(__file__)
        self.setWindowIcon(Qt.QIcon(os.path.join(path, 'logIcon.png')))
        self.wid = LogWidget(self, manager)
        self.wid.ui.input = Qt.QLineEdit()
        self.wid.ui.gridLayout.addWidget(self.wid.ui.input, 2, 0, 1, 3)
        self.wid.ui.dirLabel.setText("Current Storage Directory: None")
        self.setCentralWidget(self.wid)
        self.resize(1000, 500)
        self.manager = manager
        #global WIN
        global WIN
        WIN = self
        self.msgCount = 0
        self.logCount = 0
        self.logFile = None
        configfile.writeConfigFile(
            '', self.fileName()
        )  ## start a new temp log file, destroying anything left over from the last session.
        self.buttons = [
        ]  ## weak references to all Log Buttons get added to this list, so it's easy to make them all do things, like flash red.
        self.lock = Mutex()
        self.errorDialog = ErrorDialog()

        self.wid.ui.input.returnPressed.connect(self.textEntered)
        self.sigLogMessage.connect(self.queuedLogMsg, Qt.Qt.QueuedConnection)
Ejemplo n.º 7
0
    def __init__(self, manager, config, name):
        try:
            import MMCorePy
        except ImportError:
            if sys.platform != 'win32':
                raise
            # MM does not install itself to standard path. User should take care of this,
            # but we can make a guess..
            path = config.get('path', 'C:\\Program Files\\Micro-Manager-1.4')
            sys.path.append(path)
            os.environ['PATH'] = os.environ['PATH'] + ';' + path
            try:
                import MMCorePy
            finally:
                sys.path.pop()

        self.camName = str(name)  # we will use this name as the handle to the MM camera
        self.mmc = MMCorePy.CMMCore()

        self._triggerProp = None  # the name of the property for setting trigger mode
        self._triggerModes = ({}, {})  # forward and reverse mappings for the names of trigger modes
        self._binningMode = None  # 'x' or 'xy' for binning strings like '1' and '1x1', respectively
        self.camLock = Mutex(Mutex.Recursive)  ## Lock to protect access to camera
        self._config = config
        Camera.__init__(self, manager, config, name)  ## superclass will call setupCamera when it is ready.
        self.acqBuffer = None
        self.frameId = 0
        self.lastFrameTime = None
Ejemplo n.º 8
0
 def __init__(self, dev):
     self.dev = dev
     self.lock = Mutex(recursive=True)
     self.stopped = False
     self.interval = 0.3
     
     Thread.__init__(self)
Ejemplo n.º 9
0
    def __init__(self, dm, config, name):
        Device.__init__(self, dm, config, name)
        OptomechDevice.__init__(self, dm, config, name)

        self.config = config
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.switchDevice = None
        self.currentSwitchPosition = None
        self.currentObjective = None
        self._focusDevice = None
        self._positionDevice = None
        self._surfaceDepth = None

        self.objectives = collections.OrderedDict()
        ## Format of self.objectives is:
        ## {
        ##    switchPosition1: {objName1: objective1, objName2: objective, ...},
        ##    switchPosition2: {objName1: objective1, objName2: objective, ...},
        ## }

        for k1, objs in config['objectives'].iteritems(
        ):  ## Set default values for each objective
            self.objectives[k1] = collections.OrderedDict()
            for k2, o in objs.iteritems():
                obj = Objective(o, self, (k1, k2))
                self.objectives[k1][k2] = obj
                #obj.sigTransformChanged.connect(self.objectiveTransformChanged)

        ## Keep track of the objective currently in use for each position
        ## Format is: { switchPosition1: objective1,  ... }
        self.selectedObjectives = collections.OrderedDict([
            (i, self.objectives[i].values()[0]) for i in self.objectives
        ])
        for obj in self.selectedObjectives.values():
            self.addSubdevice(obj)

        ## if there is a light source, configure it here
        if 'lightSource' in config:
            self.lightSource = dm.getDevice(config['lightSource'])
            self.lightSource.sigLightChanged.connect(self._lightChanged)
        else:
            self.lightSource = None

        ## If there is a switch device, configure it here
        if 'objectiveSwitch' in config:
            self.switchDevice = dm.getDevice(
                config['objectiveSwitch'][0])  ## Switch device
            self.objSwitchId = config['objectiveSwitch'][1]  ## Switch ID
            #self.currentSwitchPosition = str(self.switchDevice.getSwitch(self.objSwitchId))
            self.switchDevice.sigSwitchChanged.connect(
                self.objectiveSwitchChanged)
            self.objectiveSwitchChanged()
        else:
            self.setObjectiveIndex(0)

        cal = self.readConfigFile('calibration')
        if 'surfaceDepth' in cal:
            self.setSurfaceDepth(cal['surfaceDepth'])

        dm.declareInterface(name, ['microscope'], self)
Ejemplo n.º 10
0
 def __init__(self, dev, driver, lock):
     QtCore.QThread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.dev = dev
     self.driver = driver
     self.driverLock = lock
     self.cmds = {}
Ejemplo n.º 11
0
 def __init__(self):
     Thread.__init__(self)
     self.prot = None
     self._stop = False
     self._frame = None
     self._paused = False
     self.lock = Mutex(recursive=True)
Ejemplo n.º 12
0
    def __init__(self):
        self.cams = {}
        self.lock = Mutex()

        #self.pvcam = windll.Pvcam32
        if _PVCamClass.PVCAM_CREATED:
            raise Exception(
                "Will not create another pvcam instance--use the pre-existing PVCam object."
            )
        init = LIB.pvcam_init()()
        if init < 1:
            raise Exception(
                "Could not initialize pvcam library (pl_pvcam_init): %s" %
                self.error())
        # This should happen before every new exposure (?)
        if LIB.exp_init_seq()() < 1:
            raise Exception(
                "Could not initialize pvcam library (pl_exp_init_seq): %s" %
                self.error())
        _PVCamClass.PVCAM_CREATED = True

        global externalParams

        self.paramTable = OrderedDict()
        for p in externalParams:
            self.paramTable[p] = self.paramFromString(p)

        atexit.register(self.quit)
Ejemplo n.º 13
0
    def __init__(self, dm, config, name):
        Device.__init__(self, dm, config, name)
        self.config = config
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.port = config['port']
        self.scale = config['scale']
        self.pos = [0, 0]
        self.buttons = [0, 0]

        ## Reload the last known state of the mouse if it was last modified recently enough
        self.stateFile = os.path.join('devices', self.name + "_last_state.cfg")
        state = dm.readConfigFile(self.stateFile)
        if state != {} and time.time() - state.get('time', 0) < 36000:
            self.pos = state['pos']
            self.buttons = state['buttons']

        self.mThread = MouseThread(self, {
            'pos': self.pos[:],
            'btns': self.buttons[:]
        })
        self.mThread.sigPositionChanged.connect(self.posChanged)
        self.mThread.sigButtonChanged.connect(self.btnChanged)
        #self.proxy1 = proxyConnect(None, self.sigPositionChanged, self.storeState, 3.0) ## wait 3 seconds before writing changes
        #self.proxy2 = proxyConnect(None, self.sigSwitchChanged, self.storeState, 3.0)
        self.proxy1 = SignalProxy(self.sigPositionChanged,
                                  slot=self.storeState,
                                  delay=3.0)
        self.proxy2 = SignalProxy(self.sigSwitchChanged,
                                  slot=self.storeState,
                                  delay=3.0)

        self.mThread.start()
Ejemplo n.º 14
0
    def __init__(self, dm, config, name):
        Device.__init__(self, dm, config, name)
        OptomechDevice.__init__(self, dm, config, name)

        # total device transform will be composed of a base transform (defined in the config)
        # and a dynamic translation provided by the hardware.
        self._baseTransform = Qt.QMatrix4x4(self.deviceTransform())
        self._stageTransform = Qt.QMatrix4x4()
        self._invStageTransform = Qt.QMatrix4x4()

        self.config = config
        self.lock = Mutex(Qt.QMutex.Recursive)
        self.pos = [0] * 3
        self._defaultSpeed = 'fast'
        self.pitch = config.get('pitch', 27)
        self.setFastSpeed(config.get('fastSpeed', 1e-3))
        self.setSlowSpeed(config.get('slowSpeed', 10e-6))

        # used to emit signal when position passes a threshold
        self.switches = {}
        self.switchThresholds = {}
        for name, spec in config.get('switches', {}).items():
            self.switches[name] = None
            self.switchThresholds[name] = spec

        self._limits = [(None, None), (None, None), (None, None)]

        self._progressDialog = None
        self._progressTimer = Qt.QTimer()
        self._progressTimer.timeout.connect(self.updateProgressDialog)

        dm.declareInterface(name, ['stage'], self)
Ejemplo n.º 15
0
 def __init__(self):
     QtCore.QObject.__init__(self)
     if DataManager.INSTANCE is not None:
         raise Exception("Attempted to create more than one DataManager!")
     DataManager.INSTANCE = self
     self.cache = {}
     self.lock = Mutex(QtCore.QMutex.Recursive)
Ejemplo n.º 16
0
    def __init__(self, dm, config, name):

        Device.__init__(self, dm, config, name)
        OptomechDevice.__init__(self, dm, config, name)

        self.scopeDev = None
        self.currentFilter = None
        p = self
        while p is not None:
            p = p.parentDevice()
            if isinstance(p, Microscope):
                self.scopeDev = p

        self.port = config[
            'port']  ## windows com ports start at COM1, pyserial ports start at 0
        self.baud = config.get('baud', 115200)
        #self.positionLabels = config.get('postionLabels')

        self.driver = FilterWheelDriver(self.port, self.baud)
        self.driverLock = Mutex(
            QtCore.QMutex.Recursive)  ## access to low level driver calls
        self.filterWheelLock = Mutex(
            QtCore.QMutex.Recursive)  ## access to self.attributes

        self.filters = OrderedDict()
        ## Format of self.filters is:
        ## {
        ##    filterWheelPosition1: {filterName: filter},
        ##    filterWheelPosition2: {filterName: filter},
        ## }
        nPos = self.getPositionCount()
        for k in range(nPos):  ## Set value for each filter
            filt = Filter(config['filters'], self, k)
            self.filters[k] = filt

        #print self.filters.values()
        #print self.filters[1].name(), self.filters[1].description()
        #if len(self.positionLabels) != self.getPositionCount():
        #    raise Exception("Number of FilterWheel positions %s must correspond to number of labels!" % self.getPositionCount())

        with self.driverLock:
            self.currentFWPosition = self.driver.getPos()
            self.currentFilter = self.getFilter()

        self.fwThread = FilterWheelThread(self, self.driver, self.driverLock)
        self.fwThread.fwPosChanged.connect(self.positionChanged)
        self.fwThread.start()
Ejemplo n.º 17
0
 def __init__(self, ui):
     self.ui = ui
     self.manager = ui.manager
     self.clampName = ui.clampName
     Thread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.stopThread = True
     self.paramsUpdated = True
Ejemplo n.º 18
0
 def __init__(self, dev, driver, driverLock, scale, limits, maxSpd):
     Thread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.scale = scale
     self.mp285 = driver
     self.driverLock = driverLock
     #self.monitor = True
     self.update = False
     self.resolution = 'fine'
     self.dev = dev
     #self.port = port
     #self.pos = [0, 0, 0]
     #self.baud = baud
     self.velocity = [0, 0, 0]
     self.limits = deepcopy(limits)
     self.limitChanged = False
     self.maxSpeed = maxSpd
Ejemplo n.º 19
0
 def __init__(self, path, manager):
     QtCore.QObject.__init__(self)
     self.manager = manager
     self.delayedChanges = []
     self.path = os.path.abspath(path)
     self.parentDir = None
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.sigproxy = SignalProxy(self.sigChanged, slot=self.delayedChange)
Ejemplo n.º 20
0
 def __init__(self, deviceManager, config, name):
     QtCore.QObject.__init__(self)
     self._lock_ = Mutex(QtCore.QMutex.Recursive)  ## no, good idea
     self._lock_tb_ = None
     self.dm = deviceManager
     self.dm.declareInterface(name, ['device'], self)
     #self.config = config
     self._name = name
Ejemplo n.º 21
0
 def __init__(self, task, frames, daqResult):
     self.lock = Mutex(recursive=True)
     self._task = task
     self._frames = frames
     self._daqResult = daqResult
     self._marr = None
     self._arr = None
     self._frameTimes = None
     self._frameTimesPrecise = False
Ejemplo n.º 22
0
 def __init__(self, laserDev, scannerDev):
     Thread.__init__(self)
     self._abort = False
     self._video = True
     self._closeShutter = True  # whether to close shutter at end of acquisition
     self.lock = Mutex(recursive=True)
     self.manager = acq4.Manager.getManager()
     self.laserDev = laserDev
     self.scannerDev = scannerDev
Ejemplo n.º 23
0
 def __init__(self, *args, **kargs):
     self.camLock = Mutex(Mutex.Recursive)  ## Lock to protect access to camera
     self.ringSize = 50
     Camera.__init__(self, *args, **kargs)  ## superclass will call setupCamera when it is ready.
     self.acqBuffer = None
     self.frameId = 0
     self.lastIndex = None
     self.lastFrameTime = None
     self.stopOk = False
Ejemplo n.º 24
0
    def __init__(self, dev, cmd, parentTask):
        DeviceTask.__init__(self, dev, cmd, parentTask)
        self.cmd = cmd
        self.daqTasks = []
        self.spotSize = None

        # We use this flag to exit from the sleep loop in start() in case the
        # task is aborted during that time.
        self.aborted = False
        self.abortLock = Mutex(recursive=True)
Ejemplo n.º 25
0
 def __init__(self, ui):
     Thread.__init__(self)
     self.ui = ui
     self.dm = self.ui.manager
     self.lock = Mutex(Qt.QMutex.Recursive)
     self.stopThread = True
     self.abortThread = False
     self.paused = False
     self._currentTask = None
     self._systrace = None
Ejemplo n.º 26
0
    def __init__(self, dev):
        self.dev = dev
        self.lock = Mutex(recursive=True)
        self.stopped = False
        self.interval = 0.3

        self.nextMoveId = 0
        self.moveRequest = None
        self._moveStatus = {}

        Thread.__init__(self)
Ejemplo n.º 27
0
    def __init__(self, dev):
        Thread.__init__(self)
        self.dev = dev
        #self.cam = self.dev.getCamera()
        self.camLock = self.dev.camLock
        #size = self.cam.getSize()
        #self.state = {'binning': 1, 'exposure': .001, 'region': [0, 0, size[0]-1, size[1]-1], 'mode': 'No Trigger'}
        #self.state = self.dev.getParams(['binning', 'exposure', 'region', 'triggerMode'])
        self.stopThread = False
        self.lock = Mutex()
        self.acqBuffer = None
        #self.frameId = 0
        self.bufferTime = 5.0
        #self.ringSize = 30
        self.tasks = []

        ## This thread does not run an event loop,
        ## so we may need to deliver frames manually to some places
        self.connections = set()
        self.connectMutex = Mutex()
Ejemplo n.º 28
0
 def __init__(self, dev, startState=None):
     QtCore.QThread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.dev = dev
     self.port = self.dev.port
     if startState is None:
         self.pos = [0, 0]
         self.btns = [0, 0]
     else:
         self.pos = startState['pos']
         self.btns = startState['btns']
Ejemplo n.º 29
0
 def __init__(self):
     self.pos = np.zeros(3)
     self.target = None
     self.speed = None
     self.velocity = None
     self._quit = False
     self.lock = Mutex()
     self.interval = 30e-3
     self.lastUpdate = None
     self.currentMove = None
     Thread.__init__(self)
Ejemplo n.º 30
0
    def __init__(self, dm, config, name):
        self.port = config[
            'port'] - 1  ## windows com ports start at COM1, pyserial ports start at 0
        self.baud = config.get('baud', 19200)
        self.driver = Coherent(self.port, self.baud)
        self.driverLock = Mutex(
            QtCore.QMutex.Recursive)  ## access to low level driver calls

        self.coherentLock = Mutex(
            QtCore.QMutex.Recursive)  ## access to self.attributes
        self.coherentPower = 0
        self.coherentWavelength = 0

        self.mThread = CoherentThread(self, self.driver, self.driverLock)
        self.mThread.sigPowerChanged.connect(self.powerChanged)
        self.mThread.sigWavelengthChanged.connect(self.wavelengthChanged)
        self.mThread.start()
        Laser.__init__(self, dm, config, name)

        self.hasShutter = True
        self.hasTunableWavelength = True
Ejemplo n.º 31
0
    def __init__(self, dm, config, name):
        Device.__init__(self, dm, config, name)
        OptomechDevice.__init__(self, dm, config, name)
        self.config = config
        self.configFile = os.path.join('devices', name + '_config.cfg')
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.port = config[
            'port']  ## windows com ports start at COM1, pyserial ports start at 0

        # whether this device has an arduino interface protecting it from roe/serial collisions
        # (see acq4/drivers/SutterMP285/mp285_hack)
        # If not, then position monitoring is disabled.
        self.useArduino = config.get('useArduino', False)

        self.scale = config.pop('scale', (1, 1, 1))
        # Interpret "COM1" as port 0
        if isinstance(self.port,
                      basestring) and self.port.lower()[:3] == 'com':
            self.port = int(self.port[3:]) - 1

        self.baud = config.get('baud',
                               9600)  ## 9600 is probably factory default
        self.pos = [0, 0, 0]
        self.limits = [[[0, False], [0, False]], [[0, False], [0, False]],
                       [[0, False], [0, False]]]
        self.maxSpeed = 1e-3
        self.loadConfig()

        self.mp285 = SutterMP285Driver(self.port, self.baud)
        self.driverLock = Mutex(QtCore.QMutex.Recursive)

        self.mThread = SutterMP285Thread(self, self.mp285, self.driverLock,
                                         self.scale, self.limits,
                                         self.maxSpeed)
        self.mThread.sigPositionChanged.connect(self.posChanged)
        if self.useArduino:
            self.mThread.start()

        dm.declareInterface(name, ['stage'], self)
Ejemplo n.º 32
0
class CoherentThread(QtCore.QThread):

    sigPowerChanged = QtCore.Signal(object)
    sigWavelengthChanged = QtCore.Signal(object)
    sigError = QtCore.Signal(object)

    def __init__(self, dev, driver, lock):
        QtCore.QThread.__init__(self)
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.dev = dev
        self.driver = driver
        self.driverLock = lock
        self.cmds = {}
        
        
    def setWavelength(self, wl):
        pass
        
    def setShutter(self, opened):
        wait = QtCore.QWaitCondition()
        cmd = ['setShutter', opened]
        with self.lock:
            self.cmds.append(cmd)
            
        
        
    def run(self):
        self.stopThread = False
        with self.driverLock:
            self.sigWavelengthChanged.emit(self.driver.getWavelength()*1e-9)
        while True:
            try:
                with self.driverLock:
                    power = self.driver.getPower() * 1e-3
                    wl = self.driver.getWavelength()*1e-9
                self.sigPowerChanged.emit(power)
                self.sigWavelengthChanged.emit(wl)
                time.sleep(0.5)
            except:
                debug.printExc("Error in Coherent laser communication thread:")
                
            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)


        self.driver.close()

    def stop(self, block=False):
        with self.lock:
            self.stopThread = True
        if block:
            if not self.wait(10000):
                raise Exception("Timed out while waiting for thread exit!")
Ejemplo n.º 33
0
    def __init__(self, dm, config, name):
        Device.__init__(self, dm, config, name)
        self._DGLock = Mutex(
            Qt.QMutex.Recursive)  ## protects access to _DGHolding, _DGConfig
        ## Do some sanity checks here on the configuration

        # 'channels' key is expected; for backward compatibility we just use the top-level config.
        config = config.get('channels', config)
        self._DGConfig = config
        self._DGHolding = {}
        for ch in config:
            if config[ch]['type'][0] != 'a' and ('scale' in config[ch]
                                                 or 'offset' in config[ch]):
                raise Exception(
                    "Scale/offset only allowed for analog channels. (%s.%s)" %
                    (name, ch))

            if 'scale' not in config[ch]:
                config[ch][
                    'scale'] = 1  ## must be int to prevent accidental type conversion on digital data
            if 'offset' not in config[ch]:
                config[ch]['offset'] = 0
            if config[ch].get('invert', False):
                if config[ch]['type'][0] != 'd':
                    raise Exception(
                        "Inversion only allowed for digital channels. (%s.%s)"
                        % (name, ch))
                config[ch]['scale'] = -1
                config[ch]['offset'] = -1

            #print "chan %s scale %f" % (ch, config[ch]['scale'])
            if 'holding' not in config[ch]:
                config[ch]['holding'] = 0.0

            ## It is possible to create virtual channels with no real hardware connection
            if 'device' not in config[ch]:
                #print "Assuming channel %s is virtual:" % ch, config[ch]
                config[ch]['virtual'] = True

            ## set holding value for all output channels now
            if config[ch]['type'][1] == 'o':
                self.setChanHolding(ch, config[ch]['holding'])
            #self._DGHolding[ch] = config[ch]['holding']

        dm.declareInterface(name, ['daqChannelGroup'], self)
        for ch in config:
            dm.declareInterface(name + "." + ch, ['daqChannel'],
                                ChannelHandle(self, ch))
Ejemplo n.º 34
0
 def __init__(self, dm, config, name):
     Device.__init__(self, dm, config, name)
     OptomechDevice.__init__(self, dm, config, name)
     
     self.config = config
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.devGui = None
     self.lastRunTime = None
     self.calibrationIndex = None
     self.targetList = [1.0, {}]  ## stores the grids and points used by TaskGui so that they persist
     self.currentCommand = [0,0] ## The last requested voltage values (but not necessarily the current voltage applied to the mirrors)
     self.currentVoltage = [0, 0]
     self.shutterOpen = True ## indicates whether the virtual shutter is closed (the beam is steered to its 'off' position).
     if 'offVoltage' in config:
         self.setShutterOpen(False)
     dm.declareInterface(name, ['scanner'], self)
Ejemplo n.º 35
0
 def __init__(self, dev, driver, driverLock, scale, limits, maxSpd):
     QtCore.QThread.__init__(self)
     self.lock = Mutex(QtCore.QMutex.Recursive)
     self.scale = scale
     self.mp285 = driver
     self.driverLock = driverLock
     #self.monitor = True
     self.update = False
     self.resolution = 'fine'
     self.dev = dev
     #self.port = port
     #self.pos = [0, 0, 0]
     #self.baud = baud
     self.velocity = [0,0,0]
     self.limits = deepcopy(limits)
     self.limitChanged = False
     self.maxSpeed = maxSpd
Ejemplo n.º 36
0
Archivo: Camera.py Proyecto: hiuwo/acq4
 def __init__(self, dev):
     QtCore.QThread.__init__(self)
     self.dev = dev
     #self.cam = self.dev.getCamera()
     self.camLock = self.dev.camLock
     #size = self.cam.getSize()
     #self.state = {'binning': 1, 'exposure': .001, 'region': [0, 0, size[0]-1, size[1]-1], 'mode': 'No Trigger'}
     #self.state = self.dev.getParams(['binning', 'exposure', 'region', 'triggerMode'])
     self.stopThread = False
     self.lock = Mutex()
     self.acqBuffer = None
     #self.frameId = 0
     self.bufferTime = 5.0
     #self.ringSize = 30
     self.tasks = []
     
     ## This thread does not run an event loop,
     ## so we may need to deliver frames manually to some places
     self.connections = set()
     self.connectMutex = Mutex()
Ejemplo n.º 37
0
Archivo: Camera.py Proyecto: hiuwo/acq4
class AcquireThread(QtCore.QThread):
    
    sigNewFrame = QtCore.Signal(object)
    sigShowMessage = QtCore.Signal(object)
    
    def __init__(self, dev):
        QtCore.QThread.__init__(self)
        self.dev = dev
        #self.cam = self.dev.getCamera()
        self.camLock = self.dev.camLock
        #size = self.cam.getSize()
        #self.state = {'binning': 1, 'exposure': .001, 'region': [0, 0, size[0]-1, size[1]-1], 'mode': 'No Trigger'}
        #self.state = self.dev.getParams(['binning', 'exposure', 'region', 'triggerMode'])
        self.stopThread = False
        self.lock = Mutex()
        self.acqBuffer = None
        #self.frameId = 0
        self.bufferTime = 5.0
        #self.ringSize = 30
        self.tasks = []
        
        ## This thread does not run an event loop,
        ## so we may need to deliver frames manually to some places
        self.connections = set()
        self.connectMutex = Mutex()
    
    def __del__(self):
        if hasattr(self, 'cam'):
            #self.cam.stop()
            self.dev.stopCamera()
    
    def start(self, *args):
        self.lock.lock()
        self.stopThread = False
        self.lock.unlock()
        QtCore.QThread.start(self, *args)
        
    
    def connectCallback(self, method):
        with self.connectMutex:
            self.connections.add(method)
    
    def disconnectCallback(self, method):
        with self.connectMutex:
            if method in self.connections:
                self.connections.remove(method)
    #
    #def setParam(self, param, value):
    #    #print "PVCam:setParam", param, value
    #    start = False
    #    if self.isRunning():
    #        start = True
    #        #print "Camera.setParam: Stopping camera before setting parameter.."
    #        self.stop(block=True)
    #        #print "Camera.setParam: camera stopped"
    #    with self.lock:
    #        self.state[param] = value
    #    if start:
    #        #self.start(QtCore.QThread.HighPriority)
    #        self.start()
    #    
    
    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
            #print "Camera ACQ thread exited."
        
    def stop(self, block=False):
        #print "AcquireThread.stop: Requesting thread stop, acquiring lock first.."
        with self.lock:
            self.stopThread = True
        #print "AcquireThread.stop: got lock, requested stop."
        #print "AcquireThread.stop: Unlocked, waiting for thread exit (%s)" % block
        if block:
            if not self.wait(10000):
                raise Exception("Timed out waiting for thread exit!")
        #print "AcquireThread.stop: thread exited"

    def reset(self):
        if self.isRunning():
            self.stop()
            if not self.wait(10000):
                raise Exception("Timed out while waiting for thread exit!")
            #self.start(QtCore.QThread.HighPriority)
            self.start()
Ejemplo n.º 38
0
class SutterMP285Thread(QtCore.QThread):

    sigPositionChanged = QtCore.Signal(object)
    sigError = QtCore.Signal(object)

    def __init__(self, dev, driver, driverLock, scale, limits, maxSpd):
        QtCore.QThread.__init__(self)
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.scale = scale
        self.mp285 = driver
        self.driverLock = driverLock
        #self.monitor = True
        self.update = False
        self.resolution = 'fine'
        self.dev = dev
        #self.port = port
        #self.pos = [0, 0, 0]
        #self.baud = baud
        self.velocity = [0,0,0]
        self.limits = deepcopy(limits)
        self.limitChanged = False
        self.maxSpeed = maxSpd
        
        #self.posxyz = [ 0, 0, 0]
        
    def setResolution(self, res):
        with self.lock:
            self.resolution = res
        
    def setLimits(self, limits):
        with self.lock:
            self.limits = deepcopy(limits)
            self.limitChanged = True
            
    def setMaxSpeed(self, s):
        with self.lock:
            self.maxSpeed = s
            
    #def setMonitor(self, mon):
        #with self.lock:
            #self.monitor = mon
    def updatePos(self):
        with self.lock:
            self.update = True
        
    def setVelocity(self, v):
        with self.lock:
            self.velocity = v
        
    def run(self):
        self.stopThread = False
        #self.sp = serial.Serial(int(self.port), baudrate=self.baud, bytesize=serial.EIGHTBITS)
        #time.sleep(3) ## Wait a few seconds for the mouse to say hello
        ## clear buffer before starting
        #if self.sp.inWaiting() > 0:
            #print "Discarding %d bytes" % self.sp.inWaiting()
            #self.sp.read(self.sp.inWaiting())
        #import wingdbstub
        print "  Starting MP285 thread: 0x%x" % int(QtCore.QThread.currentThreadId())
        #import sip
        #print "    also known as 0x%x" % sip.unwrapinstance(self)
        velocity = np.array([0,0,0])
        pos = [0,0,0]
        
        try:
            self.getImmediatePos()
            monitor = True
        except:
            debug.printExc("Sutter MP285: Cannot determine position:")
            monitor = False
        
        while True:
            try:
                ## Lock and copy state to local variables
                with self.lock:
                    update = self.update
                    self.update = False
                    limits = deepcopy(self.limits)
                    maxSpeed = self.maxSpeed
                    newVelocity = np.array(self.velocity[:])
                    resolution = self.resolution
                    limitChanged = self.limitChanged
                    self.limitChanged = False
                    
                ## if limits have changed, inform the device
                if monitor and limitChanged:   ## monitor is only true if this is a customized device with limit checking
                    self.sendLimits()
                
                ## If requested velocity is different from the current velocity, handle that.
                if np.any(newVelocity != velocity):
                    speed = np.clip(np.sum(newVelocity**2)**0.5, 0., 1.)   ## should always be 0.0-1.0
                    #print "new velocity:", newVelocity, "speed:", speed
                    
                    if speed == 0:
                        nv = np.array([0,0,0])
                    else:
                        nv = newVelocity/speed
                        
                    speed = np.clip(speed, 0, maxSpeed)
                    #print "final speed:", speed
                    
                    ## stop current move, get position, start new move
                    #print "stop.."
                    self.stopMove()
                    #print "stop done."
                    
                    #print "getpos..."
                    pos1 = self.readPosition()
                    if pos1 is not None:
                        
                        if speed > 0:
                            #print "   set new velocity"
                            self.writeVelocity(speed, nv, limits=limits, pos=pos1, resolution=resolution)
                            #print "   done"
                            
                        ## report current position
                        
                            
                        velocity = newVelocity
                    #print "done"
                
                ## If velocity is 0, we can do some position checks
                if np.all(velocity == 0):
                    newPos = None
                    if update:
                        newPos = self.readPosition()
                    elif monitor:
                        newPos = self.getImmediatePos()
    
                    if newPos is not None: ## If position has changed, emit a signal.
        
                        change = [newPos[i] - pos[i] for i in range(len(newPos))]
                        pos = newPos
        
                        if any(change):
                            #self.emit(QtCore.SIGNAL('positionChanged'), {'rel': change, 'abs': self.pos})
                            self.sigPositionChanged.emit({'rel': change, 'abs': pos})
                else:
                    ## moving; make a guess about the current position
                    pass
            except:
                pass
                debug.printExc("Error in MP285 thread:")
                
            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(0.02)


        self.mp285.close()

    def stop(self, block=False):
        #print "  stop: locking"
        with self.lock:
            #print "  stop: requesting stop"
            self.stopThread = True
        if block:
            #print "  stop: waiting"
            if not self.wait(10000):
                raise Exception("Timed out while waiting for thread exit!")
        #print "  stop: done"


    def readPosition(self):
        try:
            with self.driverLock:
                pos = np.array(self.mp285.getPos())
            return pos*self.scale
        except TimeoutError:
            self.sigError.emit("Read timeout--press reset button on MP285.")
            return None
        except:
            self.sigError.emit("Read error--see console.")
            debug.printExc("Error getting packet:")
            return None
        
    def writeVelocity(self, spd, v, limits, pos, resolution):
        if not self.checkLimits(pos, limits):
            return
        
        ## check all limits for closest stop point
        pt = self.vectorLimit(pos, v, limits)
        if pt is None:
            return
        
        ## set speed
        #print "      SPD:", spd, "POS:", pt
        self._setSpd(spd, fineStep=(resolution=='fine'))
        self._setPos(pt, block=False)
        
                
    def vectorLimit(self, pos, v, limits):
        ## return position of closest limit intersection given starting point and vector
        pts = []
        pos = np.array(pos)
        v = np.array(v)
        for i in  [0,1,2]:
            if v[i] < 0:
                p = self.intersect(pos, v, limits[i][0], i)
            else:
                p = self.intersect(pos, v, limits[i][1], i)
            if p is not None:
                pts.append(p)
        if len(pts) == 0:
            return None
        lengths = [np.sum((p-pos)**2)**0.5 for p in pts]
        i = np.argmin(lengths)
        return pts[i]
        
            
    def intersect(self, pos, v, x, ax):
        ## return the point where vector pos->v intersects plane x along axis ax
        if v[ax] == 0:
            return None
        dx = x-pos[ax]
        return pos + dx * v/v[ax]
            
    def checkLimits(self, pos, limits):
        for i in [0,1,2]:
            #print 'pos, limits', pos[i]
            #print limits[i]
            #print limits[i][0]
            #print limits[i][1]
            if pos[i] < limits[i][0] or pos[i] > limits[i][1]:
                return False
        return True
        
    def sendLimits(self):
        limits = []
        for ax in [0,1,2]:
            for lim in [1,0]:
                pos, en = self.limits[ax][lim]
                limits.append(pos/self.scale[ax] if en else None)
        with self.driverLock:
            self.mp285.setLimits(limits)
        
    def _setPos(self, pos, block=True):
        pos = np.array(pos) / self.scale
        with self.driverLock:
            self.mp285.setPos(pos, block=block)
    
    def stopMove(self):
        with self.driverLock:
            self.mp285.stop()
            
    def _setSpd(self, v, fineStep=True):
        ## This should be done with a calibrated speed table instead.
        v = int(v*1e6)
        with self.driverLock:
            self.mp285.setSpeed(v, fineStep)
            
        
    def getImmediatePos(self):
        with self.driverLock:
            pos = np.array(self.mp285.getImmediatePos())
        return pos*self.scale
Ejemplo n.º 39
0
class MouseThread(QtCore.QThread):
    
    sigButtonChanged = QtCore.Signal(object)
    sigPositionChanged = QtCore.Signal(object)
    
    def __init__(self, dev, startState=None):
        QtCore.QThread.__init__(self)
        self.lock = Mutex(QtCore.QMutex.Recursive)
        self.dev = dev
        self.port = self.dev.port
        if startState is None:
            self.pos = [0, 0]
            self.btns = [0, 0]
        else:
            self.pos = startState['pos']
            self.btns = startState['btns']
        
    def run(self):
        self.stopThread = False
        self.sp = serial.Serial(int(self.port), baudrate=1200, bytesize=serial.SEVENBITS)
        time.sleep(3) ## Wait a few seconds for the mouse to say hello
        if self.sp.inWaiting() > 0:
            #print "Discarding %d bytes" % self.sp.inWaiting()
            self.sp.read(self.sp.inWaiting())
        while True:
            tdx = tdy = 0
            if self.sp.inWaiting() > 0:
                if self.sp.inWaiting() < 3:  ## could be in the middle of a packet, wait for more bytes to arrive
                    time.sleep(100e-3)
                    
                bytesWaiting = self.sp.inWaiting()
                if bytesWaiting < 3:  ## More bytes have not arrived, probably there is data corruption!
                    print "WARNING: possible corrupt data from serial mouse."
                    self.sp.read(bytesWaiting)
                    
                elif self.sp.inWaiting() >= 3: ## at least one packet is available.
                    while self.sp.inWaiting() >= 3:
                        (dx, dy, b0, b1) = self.readPacket()
                        tdx += dx
                        tdy += dy
                    self.pos = [self.pos[0] + tdx, self.pos[1] + tdy]
                    if tdx != 0 or tdy != 0:
                        #self.emit(QtCore.SIGNAL('positionChanged'), {'rel': (tdx, tdy), 'abs': self.pos})
                        self.sigPositionChanged.emit({'rel': (tdx, tdy), 'abs': self.pos})
                    if b0 != self.btns[0] or b1 != self.btns[1]:
                        self.btns = [b0, b1]
                        #self.emit(QtCore.SIGNAL('buttonChanged'), self.btns)
                        self.sigButtonChanged.emit(self.btns)
                        
            self.lock.lock()
            if self.stopThread:
                self.lock.unlock()
                break
            self.lock.unlock()
            time.sleep(1e-3)
        self.sp.close()
            
    ## convert byte to signed byte
    @staticmethod
    def sint(x):
        return ((x+128)%256)-128

    def readPacket(self):
        d = self.sp.read(3)
        #print "%s %s %s" % (bin(ord(d[0])), bin(ord(d[1])), bin(ord(d[2])))
        b0 = (ord(d[0]) & 32) >> 5
        b1 = (ord(d[0]) & 16) >> 4
        xh = (ord(d[0]) & 3) << 6
        yh = (ord(d[0]) & 12) << 4
        xl = (ord(d[1]) & 63)
        yl = (ord(d[2]) & 63)
        
        #print "%s %s %s %s" % (bin(xh), bin(xl), bin(yh), bin(yl))
        return (MouseThread.sint(xl | xh), MouseThread.sint(yl | yh), b0, b1)
    
    def stop(self, block=False):
        #print "  stop: locking"
        with MutexLocker(self.lock):
            #print "  stop: requesting stop"
            self.stopThread = True
        if block:
            #print "  stop: waiting"
            if not self.wait(10000):
                raise Exception("Timed out while waiting for thread exit!")
Ejemplo n.º 40
0
class Device(QtCore.QObject):
    """Abstract class defining the standard interface for Device subclasses."""
    def __init__(self, deviceManager, config, name):
        QtCore.QObject.__init__(self)
        self._lock_ = Mutex(QtCore.QMutex.Recursive)  ## no, good idea
        self._lock_tb_ = None
        self.dm = deviceManager
        self.dm.declareInterface(name, ['device'], self)
        #self.config = config
        self._name = name
    
    def name(self):
        return self._name
    
    def createTask(self, cmd, task):
        ### Read configuration, configure tasks
        ### Return a handle unique to this task
        pass
    
    #def __del__(self):
        #self.quit()
        
    def quit(self):
        pass
    
    def deviceInterface(self, win):
        """Return a widget with a UI to put in the device rack"""
        return None
        
    def taskInterface(self, task):
        """Return a widget with a UI to put in the task rack"""
        return TaskGui(self, task)
        

    def reserve(self, block=True, timeout=20):
        #print "Device %s attempting lock.." % self.name()
        if block:
            l = self._lock_.tryLock(int(timeout*1000))
            if not l:
                print "Timeout waiting for device lock for %s" % self.name()
                print "  Device is currently locked from:"
                print self._lock_tb_
                raise Exception("Timed out waiting for device lock for %s" % self.name())
        else:
            l = self._lock_.tryLock()
            if not l:
                #print "Device %s lock failed." % self.name()
                return False
                #print "  Device is currently locked from:"
                #print self._lock_tb_
                #raise Exception("Could not acquire lock", 1)  ## 1 indicates failed non-blocking attempt
        self._lock_tb_ = ''.join(traceback.format_stack()[:-1])
        #print "Device %s lock ok" % self.name()
        return True
        
    def release(self):
        try:
            self._lock_.unlock()
            self._lock_tb_ = None
        except:
            printExc("WARNING: Failed to release device lock for %s" % self.name())
            
    def getTriggerChannel(self, daq):
        """Return the name of the channel on daq that this device raises when it starts.
        Allows the DAQ to trigger off of this device."""
        return None