def __init__(self, dev, cmd, parentTask): self.cmd = cmd self.dev = dev ## this happens in DAQGeneric initialization, but we need it here too since it is used in making the waveforms that go into DaqGeneric.__init__ if 'shutterMode' not in cmd: cmd['shutterMode'] = 'auto' ## create task structure to pass to daqGeneric, and retain a pointer to it here; DAQGeneric tasks will get filled in from LaserTask when self.configure() gets called cmd['daqProtocol'] = {} if 'shutter' in dev.config: cmd['daqProtocol']['shutter'] = {} if 'qSwitch' in dev.config: cmd['daqProtocol']['qSwitch'] = {} if 'pCell' in dev.config: cmd['daqProtocol']['pCell'] = {} #cmd['daqProtocol']['power'] = {} if cmd.get('alignMode', False): alignConfig = self.dev.config.get('alignmentMode', None) #if alignConfig is None: # raise Exception("Laser alignment mode requested, but this laser has no 'alignmentMode' in its configuration.") if alignConfig is not None: if 'shutter' in alignConfig: cmd['daqProtocol']['shutter']['preset'] = 1 if alignConfig['shutter'] else 0 if 'qSwitch' in alignConfig: cmd['daqProtocol']['qSwitch']['preset'] = 1 if alignConfig['qSwitch'] else 0 if 'pCell' in alignConfig: cmd['daqProtocol']['pCell']['preset'] = alignConfig['pCell'] elif 'power' in alignConfig: raise Exception("Alignment mode by power not implemented yet.") DAQGenericTask.__init__(self, dev, cmd['daqProtocol'], parentTask)
def stop(self, abort=False): ## Stop DAQ first #print "Stop camera task" DAQGenericTask.stop(self, abort=abort) with self.lock: self.stopRecording = True if 'popState' in self.camCmd: self.dev.popState(self.camCmd['popState']) ## restores previous settings, stops/restarts camera if needed
def configure(self): ### Record initial state or set initial value ##if 'holding' in self.cmd: ## self.dev.setHolding(self.cmd['mode'], self.cmd['holding']) if 'mode' in self.cmd: self.dev.setMode(self.cmd['mode']) self.ampState = {'mode': self.dev.getMode()} ### Do not configure daq until mode is set. Otherwise, holding values may be incorrect. DAQGenericTask.configure(self)
def start(self): ## arm recording self.frames = [] self.stopRecording = False self.recording = True if not self.dev.isRunning(): self.dev.start(block=True) ## wait until camera is actually ready to acquire ## Last I checked, this does nothing. It should be here anyway, though.. DAQGenericTask.start(self)
def stop(self, abort=False): ## Stop DAQ first #print "Stop camera task" DAQGenericTask.stop(self, abort=abort) with self.lock: self.stopRecording = True self._stopTime = time.time() if 'popState' in self.camCmd: self.dev.popState(self.camCmd['popState']) ## restores previous settings, stops/restarts camera if needed
def configure(self): ## Record initial state or set initial value # if 'holding' in self.cmd: # self.dev.setHolding(self.cmd['mode'], self.cmd['holding']) if "mode" in self.cmd: self.dev.setMode(self.cmd["mode"]) self.ampState = {"mode": self.dev.getMode(), "LPF": self.dev.getLPF(), "gain": self.dev.getGain()} ## Do not configure daq until mode is set. Otherwise, holding values may be incorrect. DAQGenericTask.configure(self) self.mapping.setMode(self.ampState["mode"])
def start(self): ## arm recording self.frames = [] self.stopRecording = False self.recording = True if not self.dev.isRunning(): self.dev.start( block=True) ## wait until camera is actually ready to acquire ## Last I checked, this does nothing. It should be here anyway, though.. DAQGenericTask.start(self)
def __init__(self, dev, cmd, parentTask): #print "Camera task:", cmd daqCmd = {} if 'channels' in cmd: daqCmd = cmd['channels'] DAQGenericTask.__init__(self, dev, daqCmd, parentTask) self.__startOrder = [], [] self.camCmd = cmd self.lock = Mutex() self.recordHandle = None self.stopAfter = False self.stoppedCam = False self.returnState = {} self.frames = [] self.recording = False self.stopRecording = False self.resultObj = None
def getResult(self): if self.resultObj is None: daqResult = DAQGenericTask.getResult(self) while self.recording and time.time() - self._stopTime < 1: # Wait up to 1 second for all frames to arrive from camera thread before returning results. # In some cases, acquisition thread can get bogged down and we may need to wait for it # to catch up. time.sleep(0.05) self.resultObj = CameraTaskResult(self, self.frames[:], daqResult) return self.resultObj
def isDone(self): ## If camera stopped, then probably there was a problem and we are finished. if not self.dev.isRunning(): return True ## should return false if recording is required to run for a specific time. if 'minFrames' in self.camCmd: with self.lock: if len(self.frames) < self.camCmd['minFrames']: return False return DAQGenericTask.isDone(self) ## Should return True.
def __init__(self, dev, cmd, parentTask): ## make a few changes for compatibility with multiclamp if 'daqProtocol' not in cmd: cmd['daqProtocol'] = {} daqP = cmd['daqProtocol'] if 'command' in cmd: if 'holding' in cmd: daqP['command'] = {'command': cmd['command'], 'holding': cmd['holding']} else: daqP['command'] = {'command': cmd['command']} daqP['command']['lowLevelConf'] = {'mockFunc': self.write} cmd['daqProtocol']['primary'] = {'record': True, 'lowLevelConf': {'mockFunc': self.read}} DAQGenericTask.__init__(self, dev, cmd['daqProtocol'], parentTask) self.cmd = cmd modPath = os.path.abspath(os.path.split(__file__)[0])
def __init__(self, dev, cmd, parentTask): ## make a few changes for compatibility with multiclamp if "daqProtocol" not in cmd: cmd["daqProtocol"] = {} if "command" in cmd: if "holding" in cmd: cmd["daqProtocol"]["command"] = {"command": cmd["command"], "holding": cmd["holding"]} else: cmd["daqProtocol"]["command"] = {"command": cmd["command"]} ## Make sure we're recording from the correct secondary channel if dev.hasSecondaryChannel: if "mode" in cmd: mode = cmd["mode"] else: mode = dev.getMode() dev.reconfigureSecondaryChannel(mode) cmd["daqProtocol"]["secondary"] = {"record": True} cmd["daqProtocol"]["primary"] = {"record": True} DAQGenericTask.__init__(self, dev, cmd["daqProtocol"], parentTask) self.cmd = cmd
def __init__(self, dev, cmd, parentTask): ## make a few changes for compatibility with multiclamp if 'daqProtocol' not in cmd: cmd['daqProtocol'] = {} if 'command' in cmd: if 'holding' in cmd: cmd['daqProtocol']['command'] = {'command': cmd['command'], 'holding': cmd['holding']} else: cmd['daqProtocol']['command'] = {'command': cmd['command']} ## Make sure we're recording from the correct secondary channel if dev.hasSecondaryChannel: if 'mode' in cmd: mode = cmd['mode'] else: mode = dev.getMode() dev.reconfigureSecondaryChannel(mode) cmd['daqProtocol']['secondary'] = {'record': True} cmd['daqProtocol']['primary'] = {'record': True} DAQGenericTask.__init__(self, dev, cmd['daqProtocol'], parentTask) self.cmd = cmd
def getResult(self): ## getResult from DAQGeneric, then add in command waveform result = DAQGenericTask.getResult(self) if result is None: return None arr = result.view(np.ndarray) daqInfo = result._info[-1]['DAQ'] ## find DAQ info for any output channel for ch in ['shutter', 'qSwitch', 'pCell']: if ch in daqInfo: ds = daqInfo[ch].get('downsampling', 1) break if 'powerWaveform' in self.cmd: ## downsample power waveform to match other channels power = self.cmd['powerWaveform'] if ds > 1: power = NiDAQ.meanResample(power, ds) arr = np.append(arr, power[np.newaxis, :], axis=0) #result = np.append(result, self.cmd['powerWaveform'][np.newaxis, :], axis=0) result._info[0]['cols'].append({'name': 'power', 'units': 'W'}) elif 'switchWaveform' in self.cmd: switch = self.cmd['switchWaveform'] if ds > 1: switch = NiDAQ.meanResample(switch, ds) arr = np.append(arr, switch[np.newaxis, :], axis=0) #result = np.append(result, self.cmd['switchWaveform'][np.newaxis, :], axis=0) result._info[0]['cols'].append({'name': 'switch'}) #elif 'power' in self.cmd: #arr = np.append(arr, self.cmd['power']['command'][np.newaxis, :], axis=0) #result._info[0]['cols'].append({'name': str(self.cmd['power']['type'])}) info = {'currentPower': self.currentPower, 'expectedPower': self.expectedPower, 'requestedWavelength':self.cmd.get('wavelength', None), 'shutterMode':self.cmd['shutterMode'], 'powerCheckRequested':self.cmd.get('checkPower', False), 'pulsesCmd': self.cmd.get('pulses', None) } result._info[-1]['Laser'] = info result = metaarray.MetaArray(arr, info=result._info) self.dev.lastResult = result return result
def getResult(self): ## getResult from DAQGeneric, then add in command waveform result = DAQGenericTask.getResult(self) if result is None: return None arr = result.view(np.ndarray) daqInfo = result._info[-1]['DAQ'] ## find DAQ info for any output channel for ch in ['shutter', 'qSwitch', 'pCell']: if ch in daqInfo: ds = daqInfo[ch].get('downsampling', 1) break if 'powerWaveform' in self.cmd: ## downsample power waveform to match other channels power = self.cmd['powerWaveform'] if ds > 1: power = NiDAQ.meanResample(power, ds) arr = np.append(arr, power[np.newaxis, :], axis=0) #result = np.append(result, self.cmd['powerWaveform'][np.newaxis, :], axis=0) result._info[0]['cols'].append({'name': 'power', 'units': 'W'}) elif 'switchWaveform' in self.cmd: switch = self.cmd['switchWaveform'] if ds > 1: switch = NiDAQ.meanResample(switch, ds) arr = np.append(arr, switch[np.newaxis, :], axis=0) #result = np.append(result, self.cmd['switchWaveform'][np.newaxis, :], axis=0) result._info[0]['cols'].append({'name': 'switch'}) #elif 'power' in self.cmd: #arr = np.append(arr, self.cmd['power']['command'][np.newaxis, :], axis=0) #result._info[0]['cols'].append({'name': str(self.cmd['power']['type'])}) info = { 'currentPower': self.currentPower, 'expectedPower': self.expectedPower, 'requestedWavelength': self.cmd.get('wavelength', None), 'shutterMode': self.cmd['shutterMode'], 'powerCheckRequested': self.cmd.get('checkPower', False), 'pulsesCmd': self.cmd.get('pulses', None) } result._info[-1]['Laser'] = info result = metaarray.MetaArray(arr, info=result._info) self.dev.lastResult = result return result
def __init__(self, dev, cmd, parentTask): self.cmd = cmd self.dev = dev ## this happens in DAQGeneric initialization, but we need it here too since it is used in making the waveforms that go into DaqGeneric.__init__ if 'shutterMode' not in cmd: cmd['shutterMode'] = 'auto' ## create task structure to pass to daqGeneric, and retain a pointer to it here; DAQGeneric tasks will get filled in from LaserTask when self.configure() gets called cmd['daqProtocol'] = {} if 'shutter' in dev.config: cmd['daqProtocol']['shutter'] = {} if 'qSwitch' in dev.config: cmd['daqProtocol']['qSwitch'] = {} if 'pCell' in dev.config: cmd['daqProtocol']['pCell'] = {} #cmd['daqProtocol']['power'] = {} if cmd.get('alignMode', False): alignConfig = self.dev.config.get('alignmentMode', None) #if alignConfig is None: # raise Exception("Laser alignment mode requested, but this laser has no 'alignmentMode' in its configuration.") if alignConfig is not None: if 'shutter' in alignConfig: cmd['daqProtocol']['shutter'][ 'preset'] = 1 if alignConfig['shutter'] else 0 if 'qSwitch' in alignConfig: cmd['daqProtocol']['qSwitch'][ 'preset'] = 1 if alignConfig['qSwitch'] else 0 if 'pCell' in alignConfig: cmd['daqProtocol']['pCell']['preset'] = alignConfig[ 'pCell'] elif 'power' in alignConfig: raise Exception( "Alignment mode by power not implemented yet.") DAQGenericTask.__init__(self, dev, cmd['daqProtocol'], parentTask)
def getResult(self): if self.resultObj is None: daqResult = DAQGenericTask.getResult(self) self.resultObj = CameraTaskResult(self, self.frames[:], daqResult) return self.resultObj
def configure(self): ## Get rate: first get name of DAQ, then ask the DAQ task for its rate daqName, ch = self.dev.getDAQName() if daqName is None: return tasks = self.parentTask().tasks daqTask = tasks[daqName] rate = daqTask.getChanSampleRate(self.dev.config[ch]['channel'][1]) ### do a power check if requested if self.cmd.get('checkPower', False): self.dev.outputPower() ### set wavelength if 'wavelength' in self.cmd: self.dev.setWavelength(self.cmd['wavelength']) ### send power/switch waveforms to device for pCell/qSwitch/shutter cmd calculation #print "Cmd:", self.cmd if 'powerWaveform' in self.cmd and not self.cmd.get('ignorePowerWaveform', False): calcCmds = self.dev.getChannelCmds({'powerWaveform':self.cmd['powerWaveform']}, rate) elif 'switchWaveform' in self.cmd: calcCmds = self.dev.getChannelCmds({'switchWaveform':self.cmd['switchWaveform']}, rate) elif 'pulse' in self.cmd: raise Exception('Support for (pulseTime/energy) pair commands is not yet implemented.') else: calcCmds = {} ### set up shutter, qSwitch and pCell -- self.cmd['daqProtocol'] points to the command structure that the DAQGeneric will use, don't set self.cmd['daqProtocol'] equal to something else! if 'shutter' in self.cmd: self.cmd['daqProtocol']['shutter'] = self.cmd['shutter'] self.cmd['daqProtocol']['shutter']['command'][-1] = 0 elif 'shutterMode' in self.cmd: if self.cmd['shutterMode'] is 'auto': if 'shutter' in calcCmds: self.cmd['daqProtocol']['shutter'] = {'command': calcCmds['shutter']} elif self.cmd['shutterMode'] is 'closed': #self.cmd['daqProtocol']['shutter']['command'] = np.zeros(len(calcCmds['shutter']), dtype=np.byte) self.cmd['daqProtocol']['shutter'] = {'preset': 0} elif self.cmd['shutterMode'] is 'open': self.cmd['daqProtocol']['shutter'] = {'command': np.ones(len(calcCmds['shutter']), dtype=np.byte)} ## set to holding value, not 0 self.cmd['daqProtocol']['shutter']['command'][-1] = 0 if 'pCell' in self.cmd: self.cmd['daqProtocol']['pCell'] = self.cmd['pCell'] elif 'pCell' in calcCmds: self.cmd['daqProtocol']['pCell']['command'] = calcCmds['pCell'] if 'qSwitch' in self.cmd: self.cmd['daqProtocol']['qSwitch'] = self.cmd['qSwitch'] self.cmd['daqProtocol']['qSwitch']['command'][-1] = 0 elif 'qSwitch' in calcCmds: self.cmd['daqProtocol']['qSwitch']['command'] = calcCmds['qSwitch'] self.cmd['daqProtocol']['qSwitch']['command'][-1] = 0 #if 'powerWaveform' in self.cmd: ## send powerWaveform into daqProtocol so it can be downsampled with the other data #self.cmd['daqProtocol']['power']['command'] = self.cmd['powerWaveform'] self.currentPower = self.dev.getParam('currentPower') self.expectedPower = self.dev.getParam('expectedPower') DAQGenericTask.configure(self) ## DAQGenericTask will use self.cmd['daqProtocol']
def getStartOrder(self): order = DAQGenericTask.getStartOrder(self) return order[0] + self.__startOrder[0], order[1] + self.__startOrder[1]
def configure(self): ## Merge command into default values: prof = Profiler('Camera.CameraTask.configure', disabled=True) #print "CameraTask.configure" ## set default parameters, load params from command params = { 'triggerMode': 'Normal', } params.update(self.camCmd['params']) if 'pushState' in self.camCmd: stateName = self.camCmd['pushState'] self.dev.pushState(stateName) prof.mark('collect params') ## If we are sending a one-time trigger to start the camera, then it must be restarted to arm the trigger ## (bulb and strobe modes only require a restart if the trigger mode is not already set; this is handled later) if params['triggerMode'] == 'TriggerStart': restart = True ## If the DAQ is triggering the camera, then the camera must start before the DAQ if params['triggerMode'] != 'Normal': daqName = self.dev.camConfig['triggerInChannel']['device'] self.__startOrder[1].append(daqName) ## Make sure we haven't requested something stupid.. if self.camCmd.get( 'triggerProtocol', False ) and self.dev.camConfig['triggerOutChannel']['device'] == daqName: raise Exception( "Task requested camera to trigger and be triggered by the same device." ) (newParams, restart) = self.dev.setParams( params, autoCorrect=True, autoRestart=False) ## we'll restart in a moment if needed.. prof.mark('set params') ## If the camera is triggering the daq, stop acquisition now and request that it starts after the DAQ ## (daq must be started first so that it is armed to received the camera trigger) name = self.dev.name() if self.camCmd.get('triggerProtocol', False): restart = True daqName = self.dev.camConfig['triggerOutChannel']['device'] self.__startOrder = [daqName], [] #startOrder.remove(name) #startOrder.insert(startOrder.index(daqName)+1, name) prof.mark('conf 1') ## If we are not triggering the daq, request that we start before everyone else ## (no need to stop, we will simply record frames as they are collected) #else: #startOrder.remove(name) #startOrder.insert(0, name) #prof.mark('conf 2') ## We want to avoid this if at all possible since it may be very expensive if restart: self.dev.stop(block=True) prof.mark('stop') ## connect using acqThread's connect method because there may be no event loop ## to deliver signals here. self.dev.acqThread.connectCallback(self.newFrame) ## Call the DAQ configure DAQGenericTask.configure(self) prof.mark('DAQ configure') prof.finish()
def configure(self): ## Merge command into default values: prof = Profiler('Camera.CameraTask.configure', disabled=True) #print "CameraTask.configure" ## set default parameters, load params from command params = { 'triggerMode': 'Normal', } params.update(self.camCmd['params']) if 'pushState' in self.camCmd: stateName = self.camCmd['pushState'] self.dev.pushState(stateName) prof.mark('collect params') ## If we are sending a one-time trigger to start the camera, then it must be restarted to arm the trigger ## (bulb and strobe modes only require a restart if the trigger mode is not already set; this is handled later) if params['triggerMode'] == 'TriggerStart': restart = True ## If the DAQ is triggering the camera, then the camera must start before the DAQ if params['triggerMode'] != 'Normal': daqName = self.dev.camConfig['triggerInChannel']['device'] self.__startOrder[1].append(daqName) ## Make sure we haven't requested something stupid.. if self.camCmd.get('triggerProtocol', False) and self.dev.camConfig['triggerOutChannel']['device'] == daqName: raise Exception("Task requested camera to trigger and be triggered by the same device.") (newParams, restart) = self.dev.setParams(params, autoCorrect=True, autoRestart=False) ## we'll restart in a moment if needed.. prof.mark('set params') ## If the camera is triggering the daq, stop acquisition now and request that it starts after the DAQ ## (daq must be started first so that it is armed to received the camera trigger) name = self.dev.name() if self.camCmd.get('triggerProtocol', False): restart = True daqName = self.dev.camConfig['triggerOutChannel']['device'] self.__startOrder = [daqName], [] #startOrder.remove(name) #startOrder.insert(startOrder.index(daqName)+1, name) prof.mark('conf 1') ## If we are not triggering the daq, request that we start before everyone else ## (no need to stop, we will simply record frames as they are collected) #else: #startOrder.remove(name) #startOrder.insert(0, name) #prof.mark('conf 2') ## We want to avoid this if at all possible since it may be very expensive if restart: self.dev.stop(block=True) prof.mark('stop') ## connect using acqThread's connect method because there may be no event loop ## to deliver signals here. self.dev.acqThread.connectCallback(self.newFrame) ## Call the DAQ configure DAQGenericTask.configure(self) prof.mark('DAQ configure') prof.finish()
def stop(self, abort=False): DAQGenericTask.stop(self, abort)
def getStartOrder(self): order = DAQGenericTask.getStartOrder(self) return order[0]+self.__startOrder[0], order[1]+self.__startOrder[1]
def configure(self): ## Get rate: first get name of DAQ, then ask the DAQ task for its rate daqName, ch = self.dev.getDAQName() if daqName is None: return tasks = self.parentTask().tasks daqTask = tasks[daqName] rate = daqTask.getChanSampleRate(self.dev.config[ch]['channel'][1]) ### do a power check if requested if self.cmd.get('checkPower', False): self.dev.outputPower() ### set wavelength if 'wavelength' in self.cmd: self.dev.setWavelength(self.cmd['wavelength']) ### send power/switch waveforms to device for pCell/qSwitch/shutter cmd calculation #print "Cmd:", self.cmd if 'powerWaveform' in self.cmd and not self.cmd.get( 'ignorePowerWaveform', False): calcCmds = self.dev.getChannelCmds( {'powerWaveform': self.cmd['powerWaveform']}, rate) elif 'switchWaveform' in self.cmd: calcCmds = self.dev.getChannelCmds( {'switchWaveform': self.cmd['switchWaveform']}, rate) elif 'pulse' in self.cmd: raise Exception( 'Support for (pulseTime/energy) pair commands is not yet implemented.' ) else: calcCmds = {} ### set up shutter, qSwitch and pCell -- self.cmd['daqProtocol'] points to the command structure that the DAQGeneric will use, don't set self.cmd['daqProtocol'] equal to something else! if 'shutter' in self.cmd: self.cmd['daqProtocol']['shutter'] = self.cmd['shutter'] self.cmd['daqProtocol']['shutter']['command'][-1] = 0 elif 'shutterMode' in self.cmd: if self.cmd['shutterMode'] is 'auto': if 'shutter' in calcCmds: self.cmd['daqProtocol']['shutter'] = { 'command': calcCmds['shutter'] } elif self.cmd['shutterMode'] is 'closed': #self.cmd['daqProtocol']['shutter']['command'] = np.zeros(len(calcCmds['shutter']), dtype=np.byte) self.cmd['daqProtocol']['shutter'] = {'preset': 0} elif self.cmd['shutterMode'] is 'open': self.cmd['daqProtocol']['shutter'] = {'preset': 1} # self.cmd['daqProtocol']['shutter'] = {'command': np.ones(len(calcCmds['shutter']), dtype=np.byte)} # ## set to holding value, not 0 # self.cmd['daqProtocol']['shutter']['command'][-1] = 0 if 'pCell' in self.cmd: self.cmd['daqProtocol']['pCell'] = self.cmd['pCell'] elif 'pCell' in calcCmds: self.cmd['daqProtocol']['pCell']['command'] = calcCmds['pCell'] if 'qSwitch' in self.cmd: self.cmd['daqProtocol']['qSwitch'] = self.cmd['qSwitch'] self.cmd['daqProtocol']['qSwitch']['command'][-1] = 0 elif 'qSwitch' in calcCmds: self.cmd['daqProtocol']['qSwitch']['command'] = calcCmds['qSwitch'] self.cmd['daqProtocol']['qSwitch']['command'][-1] = 0 #if 'powerWaveform' in self.cmd: ## send powerWaveform into daqProtocol so it can be downsampled with the other data #self.cmd['daqProtocol']['power']['command'] = self.cmd['powerWaveform'] self.currentPower = self.dev.getParam('currentPower') self.expectedPower = self.dev.getParam('expectedPower') DAQGenericTask.configure( self) ## DAQGenericTask will use self.cmd['daqProtocol']