def __init__(self, dm, config, name): self.omConf = {} for k in ['parentDevice', 'transform']: if k in config: self.omConf[k] = config.pop(k) OptomechDevice.__init__(self, dm, config, name) DAQGeneric.__init__(self, dm, config, name)
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)
def quit(self): #print "quit() called from Camera" if hasattr(self, 'acqThread') and self.isRunning(): self.stop() if not self.wait(10000): raise Exception("Timed out while waiting for thread exit!") #self.cam.close() DAQGeneric.quit(self)
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._configDir = os.path.join('devices', self.name() + '_config') 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)
def getDAQName(self, channel=None): if channel is None: if self.hasTriggerableShutter: ch = 'shutter' daqName = DAQGeneric.getDAQName(self, 'shutter') elif self.hasPCell: ch = 'pCell' daqName = DAQGeneric.getDAQName(self, 'pCell') elif self.hasQSwitch: ch = 'qSwitch' daqName = DAQGeneric.getDAQName(self, 'qSwitch') else: return (None, None) #raise HelpfulException("LaserTask can't find name of DAQ device to use for this task.") return (daqName, ch) else: return DAQGeneric.getDAQName(self, channel)
def setHolding(self, mode=None, value=None, force=False): # print "setHolding", mode, value global ivModes with self.devLock: currentMode = self.getMode() if mode is None: mode = currentMode ivMode = ivModes[mode] ## determine vc/ic if value is None: value = self.holding[ivMode] else: self.holding[ivMode] = value if ivMode == ivModes[currentMode] or force: mapping = self.getMapping(mode=mode) ## override the scale since getChanScale won't necessarily give the correct value ## (we may be about to switch modes) DAQGeneric.setChanHolding(self, "command", value, mapping=mapping) self.sigHoldingChanged.emit("primary", self.holding.copy())
def setHolding(self, mode=None, value=None, force=False): #print "setHolding", mode, value #global ivModes with self.devLock: currentMode = self.getMode() if mode is None: mode = currentMode ivMode = self.ivModes[mode] ## determine vc/ic if value is None: value = self.holding[ivMode] else: self.holding[ivMode] = value if ivMode == self.ivModes[currentMode] or force: mapping = self.getMapping(mode=mode) ## override the scale since getChanScale won't necessarily give the correct value ## (we may be about to switch modes) DAQGeneric.setChanHolding(self, 'command', value, mapping=mapping) self.sigHoldingChanged.emit('primary', self.holding.copy())
def __init__(self, dm, config, name): # Generate config to use for DAQ self.devLock = Mutex(Mutex.Recursive) daqConfig = { 'command': config['Command'], 'primary': config['ScaledSignal'], } self.holding = { 'vc': config.get('vcHolding', -0.05), 'ic': config.get('icHolding', 0.0) } self.mode = 'i=0' self.config = config DAQGeneric.__init__(self, dm, daqConfig, name) try: self.setHolding() except: printExc("Error while setting holding value:") # Start a remote process to run the simulation. self.process = mp.Process() rsys = self.process._import('sys') rsys._setProxyOptions( returnType='proxy' ) # need to access remote path by proxy, not by value rsys.path.append(os.path.abspath(os.path.dirname(__file__))) if config['simulator'] == 'builtin': self.simulator = self.process._import('hhSim') elif config['simulator'] == 'neuron': self.simulator = self.process._import('neuronSim') dm.declareInterface(name, ['clamp'], self)
def __init__(self, dm, config, name): # Generate config to use for DAQ daqConfig = {} self.devLock = Mutex(Mutex.Recursive) daqConfig = { 'command': config['Command'], 'primary': config['ScaledSignal'], } self.holding = { 'vc': config.get('vcHolding', -0.05), 'ic': config.get('icHolding', 0.0) } self.mode = 'i=0' self.config = config DAQGeneric.__init__(self, dm, daqConfig, name) try: self.setHolding() except: printExc("Error while setting holding value:") # Start a remote process to run the simulation. self.process = mp.Process() rsys = self.process._import('sys') rsys._setProxyOptions(returnType='proxy') # need to access remote path by proxy, not by value rsys.path.append(os.path.abspath(os.path.dirname(__file__))) if config['simulator'] == 'builtin': self.simulator = self.process._import('hhSim') elif config['simulator'] == 'neuron': self.simulator = self.process._import('neuronSima') dm.declareInterface(name, ['clamp'], self)
def setChanHolding(self, chan, value=None): if chan == 'command': self.setHolding(value=value) else: DAQGeneric.setChanHolding(self, chan, value)
def quit(self): #self.process.send(None) self.process.close() DAQGeneric.quit(self)
def getChanHolding(self, chan): if chan == 'command': return self.getHolding() else: return DAQGeneric.getChanHolding(self, chan)
def __init__(self, dm, config, name): # Generate config to use for DAQ daqConfig = {} for ch in ['GainChannel', 'LPFChannel', 'ModeChannel']: if ch not in config: continue daqConfig[ch] = config[ch].copy() #if 'GainChannel' in config: # daqConfig['gain'] = {'type': 'ai', 'channel': config['GainChannel']} #if 'LPFChannel' in config: # daqConfig['LPF'] = {'type': 'ai', 'channel': config['LPFChannel'], 'units': 'Hz'} if 'ScaledSignal' in config: #daqConfig['primary'] = {'type': 'ai', 'channel': config['ScaledSignal']} daqConfig['primary'] = config['ScaledSignal'] if config['ScaledSignal'].get('type', None) != 'ai': raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ai'") if 'Command' in config: #daqConfig['command'] = {'type': 'ao', 'channel': config['Command']} daqConfig['command'] = config['Command'] if config['Command'].get('type', None) != 'ao': raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ao'") ## Note that both of these channels can be present, but we will only ever record from one at a time. ## Usually, we'll record from "I OUTPUT" in current clamp and "10 Vm OUTPUT" in voltage clamp. if 'SecondaryVCSignal' in config: self.hasSecondaryChannel = True #daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryVCSignal']} daqConfig['secondary'] = config['SecondaryVCSignal'] if config['SecondaryVCSignal'].get('type', None) != 'ai': raise Exception("AxoPatch200: SecondaryVCSignal configuration must have type:'ai'") elif 'SecondaryICSignal' in config: self.hasSecondaryChannel = True #daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryICSignal']} daqConfig['secondary'] = config['SecondaryICSignal'] if config['SecondaryICSignal'].get('type', None) != 'ai': raise Exception("AxoPatch200: SecondaryICSignal configuration must have type:'ai'") else: self.hasSecondaryChannel = False self.version = config.get('version', '200B') # Axopatch gain telegraph # telegraph should not read below 2 V in CC mode self.gain_tel = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5]) self.gain_vm = np.array([0.5, 0.5, 0.5, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500]) * 1e9 ## values in mv/pA self.gain_im = np.array([0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500]) ## values in mV/mV # Axopatch Lowpass Bessel Filter self.lpf_tel = np.array([2.0, 4.0, 6.0, 8.0, 10.0]) self.lpf_freq = np.array([1.0, 2.0, 5.0, 10.0, 50.0]) if self.version == '200': # telegraph voltage/output translation from the Axopatch 200 amplifier self.mode_tel = np.array([6, 4, 2]) self.modeNames = OrderedDict([(0, 'V-Clamp'), (1, 'Track'), (2, 'I-Clamp')]) self.ivModes = {'V-Clamp':'vc', 'Track':'ic', 'I-Clamp':'ic', 'vc':'vc', 'ic':'ic'} self.modeAliases = {'ic': 'I-Clamp', 'i=0': 'Track', 'vc': 'V-Clamp'} elif self.version == '200A': # telegraph voltage/output translation from the Axopatch 200 amplifier self.mode_tel = np.array([6, 4, 2, 1]) self.modeNames = OrderedDict([(0, 'V-Clamp'), (1, 'Track'), (2, 'I-Clamp Normal'), (3, 'I-Clamp Fast'), ]) self.ivModes = {'V-Clamp':'vc', 'Track':'vc', 'I-Clamp Fast':'ic', 'I-Clamp Normal':'ic', 'vc':'vc', 'ic':'ic'} self.modeAliases = {'ic': 'I-Clamp Fast', 'i=0': 'Track', 'vc': 'V-Clamp'} elif self.version == '200B': # telegraph voltage/output translation from the Axopatch 200 amplifier self.mode_tel = np.array([6, 4, 3, 2, 1]) self.modeNames = OrderedDict([(0, 'V-Clamp'), (2, 'I=0'), (4, 'I-Clamp Fast'), (3, 'I-Clamp Normal'), (1, 'Track'), ]) self.ivModes = {'V-Clamp':'vc', 'Track':'vc', 'I=0':'ic', 'I-Clamp Fast':'ic', 'I-Clamp Normal':'ic', 'vc':'vc', 'ic':'ic'} self.modeAliases = {'ic': 'I-Clamp Fast', 'i=0': 'I=0', 'vc': 'V-Clamp'} self.lpf_freq[-1] = 100.0 # 200B's highest LPF value is 100kHz instead of 50. else: raise Exception("AxoPatch200: version must be '200', '200A' or '200B' (got %r)" % version) self.holding = { 'vc': config.get('vcHolding', -0.05), 'ic': config.get('icHolding', 0.0) } self.config = config self.modeLock = Mutex(Mutex.Recursive) ## protects self.mdCanceled self.devLock = Mutex(Mutex.Recursive) ## protects self.holding, possibly self.config, ..others, perhaps? self.mdCanceled = False DAQGeneric.__init__(self, dm, daqConfig, name) self.modeDialog = QtGui.QMessageBox() self.modeDialog.hide() self.modeDialog.setModal(False) self.modeDialog.setWindowTitle("Mode Switch Request") self.modeDialog.addButton(self.modeDialog.Cancel) self.modeDialog.buttonClicked.connect(self.modeDialogClicked) self.sigShowModeDialog.connect(self.showModeDialog) self.sigHideModeDialog.connect(self.hideModeDialog) try: self.setHolding() except: printExc("Error while setting holding value:") dm.declareInterface(name, ['clamp'], self)
def __init__(self, dm, config, name): OptomechDevice.__init__(self, dm, config, name) self.lock = Mutex(Mutex.Recursive) # Generate config to use for DAQ daqConfig = {} if 'exposeChannel' in config: daqConfig['exposure'] = config['exposeChannel'] if 'triggerInChannel' in config: daqConfig['trigger'] = config['triggerInChannel'] DAQGeneric.__init__(self, dm, daqConfig, name) self.camConfig = config self.stateStack = [] if 'scaleFactor' not in self.camConfig: self.camConfig['scaleFactor'] = [1., 1.] ## Default values for scope state. These will be used if there is no scope defined. self.scopeState = { 'id': 0, } self.scopeDev = None p = self while p is not None: p = p.parentDevice() if isinstance(p, Microscope): self.scopeDev = p self.scopeDev.sigObjectiveChanged.connect( self.objectiveChanged) break self.transformChanged() if self.scopeDev is not None: self.objectiveChanged() self.setupCamera() #print "Camera: setupCamera returned, about to create acqThread" self.sensorSize = self.getParam('sensorSize') tr = pg.SRTTransform3D() tr.translate(-self.sensorSize[0] * 0.5, -self.sensorSize[1] * 0.5) self.setDeviceTransform(self.deviceTransform() * tr) self.acqThread = AcquireThread(self) #print "Camera: acqThread created, about to connect signals." self.acqThread.finished.connect(self.acqThreadFinished) self.acqThread.started.connect(self.acqThreadStarted) self.acqThread.sigShowMessage.connect(self.showMessage) self.acqThread.sigNewFrame.connect(self.newFrame) #print "Camera: signals connected:" self.sigGlobalTransformChanged.connect(self.transformChanged) if config != None: # look for 'defaults', then 'params' to preserve backward compatibility. defaults = config.get('defaults', config.get('params', {})) #print "Camera: setting configuration params." try: self.setParams(defaults) except: printExc("Error default setting camera parameters:") #print "Camera: no config params to set." dm.declareInterface(name, ['camera'], self)
def __init__(self, dm, config, name): OptomechDevice.__init__(self, dm, config, name) self.lock = Mutex(Mutex.Recursive) # Generate config to use for DAQ daqConfig = {} if 'exposeChannel' in config: daqConfig['exposure'] = config['exposeChannel'] if 'triggerInChannel' in config: daqConfig['trigger'] = config['triggerInChannel'] DAQGeneric.__init__(self, dm, daqConfig, name) self.camConfig = config self.stateStack = [] if 'scaleFactor' not in self.camConfig: self.camConfig['scaleFactor'] = [1., 1.] ## Default values for scope state. These will be used if there is no scope defined. self.scopeState = { 'id': 0, #'scopePosition': [0, 0], ## position of scope in global coords #'centerPosition': [0, 0], ## position of objective in global coords (objective may be offset from center of scope) #'offset': [0, 0], #'objScale': 1, #'pixelSize': (1, 1), #'objective': '', #'transform': None, } self.scopeDev = None p = self while p is not None: p = p.parentDevice() if isinstance(p, Microscope): self.scopeDev = p self.scopeDev.sigObjectiveChanged.connect(self.objectiveChanged) break #if 'scopeDevice' in config: #self.scopeDev = self.dm.getDevice(config['scopeDevice']) #self.scopeDev.sigPositionChanged.connect(self.positionChanged) ### Cache microscope state for fast access later #self.objectiveChanged() #self.positionChanged() #else: #self.scopeDev = None self.transformChanged() if self.scopeDev is not None: self.objectiveChanged() self.setupCamera() #print "Camera: setupCamera returned, about to create acqThread" self.sensorSize = self.getParam('sensorSize') tr = pg.SRTTransform3D() tr.translate(-self.sensorSize[0]*0.5, -self.sensorSize[1]*0.5) self.setDeviceTransform(self.deviceTransform() * tr) self.acqThread = AcquireThread(self) #print "Camera: acqThread created, about to connect signals." self.acqThread.finished.connect(self.acqThreadFinished) self.acqThread.started.connect(self.acqThreadStarted) self.acqThread.sigShowMessage.connect(self.showMessage) self.acqThread.sigNewFrame.connect(self.newFrame) #print "Camera: signals connected:" self.sigGlobalTransformChanged.connect(self.transformChanged) if config != None: # look for 'defaults', then 'params' to preserve backward compatibility. defaults = config.get('defaults', config.get('params', {})) #print "Camera: setting configuration params." try: self.setParams(defaults) except: printExc("Error default setting camera parameters:") #print "Camera: no config params to set." dm.declareInterface(name, ['camera'], self)
def __init__(self, dm, config, name): # Generate config to use for DAQ daqConfig = {} for ch in ["GainChannel", "LPFChannel", "ModeChannel"]: if ch not in config: continue daqConfig[ch] = config[ch].copy() # if 'GainChannel' in config: # daqConfig['gain'] = {'type': 'ai', 'channel': config['GainChannel']} # if 'LPFChannel' in config: # daqConfig['LPF'] = {'type': 'ai', 'channel': config['LPFChannel'], 'units': 'Hz'} if "ScaledSignal" in config: # daqConfig['primary'] = {'type': 'ai', 'channel': config['ScaledSignal']} daqConfig["primary"] = config["ScaledSignal"] if config["ScaledSignal"].get("type", None) != "ai": raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ai'") if "Command" in config: # daqConfig['command'] = {'type': 'ao', 'channel': config['Command']} daqConfig["command"] = config["Command"] if config["Command"].get("type", None) != "ao": raise Exception("AxoPatch200: ScaledSignal configuration must have type:'ao'") ## Note that both of these channels can be present, but we will only ever record from one at a time. ## Usually, we'll record from "I OUTPUT" in current clamp and "10 Vm OUTPUT" in voltage clamp. if "SecondaryVCSignal" in config: self.hasSecondaryChannel = True # daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryVCSignal']} daqConfig["secondary"] = config["SecondaryVCSignal"] if config["SecondaryVCSignal"].get("type", None) != "ai": raise Exception("AxoPatch200: SecondaryVCSignal configuration must have type:'ai'") elif "SecondaryICSignal" in config: self.hasSecondaryChannel = True # daqConfig['secondary'] = {'type': 'ai', 'channel': config['SecondaryICSignal']} daqConfig["secondary"] = config["SecondaryICSignal"] if config["SecondaryICSignal"].get("type", None) != "ai": raise Exception("AxoPatch200: SecondaryICSignal configuration must have type:'ai'") else: self.hasSecondaryChannel = False self.holding = {"vc": config.get("vcHolding", -0.05), "ic": config.get("icHolding", 0.0)} self.config = config self.modeLock = Mutex(Mutex.Recursive) ## protects self.mdCanceled self.devLock = Mutex(Mutex.Recursive) ## protects self.holding, possibly self.config, ..others, perhaps? self.mdCanceled = False DAQGeneric.__init__(self, dm, daqConfig, name) self.modeDialog = QtGui.QMessageBox() self.modeDialog.hide() self.modeDialog.setModal(False) self.modeDialog.setWindowTitle("Mode Switch Request") self.modeDialog.addButton(self.modeDialog.Cancel) self.modeDialog.buttonClicked.connect(self.modeDialogClicked) self.sigShowModeDialog.connect(self.showModeDialog) self.sigHideModeDialog.connect(self.hideModeDialog) try: self.setHolding() except: printExc("Error while setting holding value:") dm.declareInterface(name, ["clamp"], self)