def getLaserBlueCommand(self): """ Get the command waveform for the blue laser data for the current protocol """ # non threaded dirs = self.subDirs(self.protocol) index = self._readIndex() trx = [] cmd = [] sequence_values = None if 'sequenceParams' in index['.'].keys(): self.sequence = index['.']['sequenceParams'] else: self.sequence = [] # building command voltages or currents - get amplitudes to clamp reps = ('protocol', 'repetitions') foundLaser = False self.LaserBlueRaw = [] self.LaserBlue_pCell = [] self.LBR_sample_rate = [] self.LBR_time_base = [] for i, d in enumerate(dirs): fn = os.path.join(d, 'Laser-Blue-raw.ma') if not os.path.isfile(fn): print(' acq4read.getLaserBlueCommand: File not found: ', fn) return False lbr = EM.MetaArray(file=fn) info = lbr[0].infoCopy() self.LaserBlueRaw.append(lbr.view(np.ndarray)[0]) # shutter try: self.LaserBlue_pCell.append(lbr.view(np.ndarray)[1]) # pCell except: # see if have a PockelCell as a seprate thing fn = os.path.join(d, 'PockelCell.ma') if not os.path.isfile(fn): print(' acq4read.getLaserBlueCommand: File not found: ', fn) self.LaserBlue_pCell.append(None) else: pcell = EM.MetaArray(file=fn) self.LaserBlue_pCell.append(pcell.view(np.ndarray)[0]) self.LBR_time_base.append(lbr.xvals('Time')) try: sr = info[1]['DAQ']['Shutter']['rate'] except: print(info[1]['DAQ'].keys()) exit(1) self.LBR_sample_rate.append(sr) self.LaserBlue_info = info self.LaserBlueRaw = np.array(self.LaserBlueRaw) self.LaserBlue_pCell = np.array(self.LaserBlue_pCell) self.LBR_sample_rate = np.array(self.LBR_sample_rate) self.LBR_time_base = np.array(self.LBR_time_base) return True
def getImage(self, filename): """ getImage Returns the image file in the dataname Requires full path to the data Can also read a video (.ma) file, returning the stack """ fn = Path(filename) print('fn: ',fn) print('filename: ',filename) if fn.suffix in ['.tif', '.tiff']: self.imageData = tf.imread(str(filename)) elif fn.suffix in ['.ma']: self.imageData = EM.MetaArray(file=filename) d = str(fn.name) self.Image_filename = d cindex = self._readIndex(Path(fn.parent)) if 'userTransform' in list(cindex[d].keys()) and cindex[d]['userTransform']['pos'] != (0., 0.): z = np.vstack(cindex[d]['userTransform']['pos'] + cindex[d]['transform']['pos']).ravel() self.Image_pos = ((z[0]+z[2]), (z[1]+z[3]), z[4]) else: self.Image_pos = cindex[d]['transform']['pos'] self.Image_scale = cindex[d]['transform']['scale'] self.Image_region = cindex[d]['region'] self.Image_binning = cindex[d]['binning'] return(self.imageData)
def getClampCommand(self, data, generateEmpty=True): """Returns the command data from a clamp MetaArray. If there was no command specified, the function will return all zeros if generateEmpty=True (default). """ if data.hasColumn('Channel', 'Command'): # hascolumn is a metaarray method return data['Channel':'Command'] elif data.hasColumn('Channel', 'command'): return data['Channel':'command'] else: if generateEmpty: tVals = data.xvals('Time') # mode = getClampMode(data) print('Mode: ', self.mode) if 'v' in self.mode.lower(): units = 'V' else: units = 'A' return EM.MetaArray(np.zeros(tVals.shape), info=[{ 'name': 'Time', 'values': tVals, 'units': 's' }, { 'units': units }]) return None
def getDeviceData(self, device='Photodiode', devicename='Photodiode'): """ Get the data from a device Parameters ---------- device : str (default: 'Photodiode') The base name of the file holding the data. '.ma' will be appended to the name devicename : str (default: 'Photodiode') The name of the device as set in the config (might be 'pCell', etc) This might or might not be the same as the device Returns ------- Success : boolean The results are stored data for the current protocol """ # non threaded dirs = self.subDirs(self.protocol) index = self._readIndex() trx = [] cmd = [] sequence_values = None if 'sequenceParams' in index['.'].keys(): self.sequence = index['.']['sequenceParams'] else: self.sequence = [] # building command voltages or currents - get amplitudes to clamp reps = ('protocol', 'repetitions') foundLaser = False self.Device_data = [] self.Device_sample_rate = [] self.Device_time_base = [] for i, d in enumerate(dirs): fn = Path(d, device + '.ma') if not fn.is_file(): print(' acq4read.getDeviceData: File not found: ', fn) return None try: lbr = EM.MetaArray(file=fn) except: print(' acq4read.getDeviceData: Corrupt Metaarray: ', fn) return None info = lbr[0].infoCopy() self.Device_data.append(lbr.view(np.ndarray)[0]) self.Device_time_base.append(lbr.xvals('Time')) sr = info[1]['DAQ'][devicename]['rate'] self.Device_sample_rate.append(sr) self.Device_data = np.array(self.Device_data) self.Device_sample_rate = np.array(self.Device_sample_rate) self.Device_time_base = np.array(self.Device_time_base) return {'data': self.Device_data, 'time_base': self.Device_time_base, 'sample_rate': self.Device_sample_rate}
def getDataInfo(self, fn): """ Get the index info for a record, without reading the trace data """ info = None if (os.path.isfile(fn)): try: tr = EM.MetaArray(file=fn, readAllData=False) except: return info info = tr[0].infoCopy() # print ('info: ', info) self.parseClampInfo(info) return (info)
def convertfiles(): # define path to data basepath = Path("/Volumes/Pegasus/ManisLab_Data3/Kasten_Michael/NF107Ai32Het/2017.12.13_000/slice_001/cell_000") # Documents/data/MRK_Pyramidal/2017.10.04_000/slice_000" bpexists = basepath.is_dir() print(bpexists) matches = list(basepath.glob('**/video_*.ma')) print('files: ', matches) for m in matches: fullfile = str(m) data = MA.MetaArray(file=fullfile) ofile = Path(m.parent, m.name).with_suffix('.tif') # cleaner with pathlib... print('output file: ', ofile) # print(data.shape) data = np.max(data, axis=0) # print(' > ', data.shape) fh = open(ofile, 'wb') tf.imsave(fh, data.view(np.ndarray).astype('float32'), imagej=True, bigtiff=False, software='acq4') fh.close()
def getPhotodiode(self): """ Get the command waveform for the blue laser data for the current protocol """ # non threaded dirs = self.subDirs(self.protocol) index = self._readIndex() trx = [] cmd = [] sequence_values = None if 'sequenceParams' in index['.'].keys(): self.sequence = index['.']['sequenceParams'] else: self.sequence = [] # building command voltages or currents - get amplitudes to clamp reps = ('protocol', 'repetitions') foundPhotodiode = False self.Photodiode = [] self.Photodiode_time_base = [] self.Photodiode_sample_rate = [] self.Photodiode_command = [] for i, d in enumerate(dirs): fn = Path(d, 'Photodiode.ma') if not fn.is_file(): print(' acq4read.getPhotodiode: File not found: ', fn) return False pdr = EM.MetaArray(file=fn) info = pdr[0].infoCopy() self.Photodiode.append(pdr.view(np.ndarray)[0]) self.Photodiode_time_base.append(pdr.xvals('Time')) sr = info[1]['DAQ']['Photodiode']['rate'] self.Photodiode_sample_rate.append(sr) self.Photodiode = np.array(self.Photodiode) self.Photodiode_sample_rate = np.array(self.Photodiode_sample_rate) self.Photodiode_time_base = np.array(self.Photodiode_time_base) return True
def getClampData(self, verbose=False): """ Translates fields as best as we can from the original DATAC structure create a Clamp structure for use in SpikeAnalysis and RMTauAnalysis. Fills in the fields that are returned by PatchEPhys getClamps: clampInfo['dirs] clampInfo['missingData'] self.time_base self.values self.traceStartTimes = np.zeros(0) self.sequence self.clampValues (sequence) self.nclamp = len(self.clmapVlaues self.repc self.nrepc self.data_mode self.model_mode = False self.command_scale_factor self.command_units self.devicesUsed self.clampDevices self.holding self.clampState self.sample_interval self.RSeriesUncomp self.amplifeirSettings['WCCompValid', 'WCEmabled', 'CompEnabled', 'WCSeriesResistance'] self.cmd_wave self.commandLevels (np.array(self.values)) self.traces = MetaArray(traces, info=info) self.tstart self.tdur self.tend self.spikecount = np.zeros(len...) if in vcmode. Info from an example data file: [{'name': 'Channel', 'cols': [{'units': 'A', 'name': 'Command'}, {'units': 'V', 'name': 'primary'}, {'units': 'A', 'name': 'secondary'}]}, {'units': 's', 'values': array([ 0.00000000e+00, 2.50000000e-05, 5.00000000e-05, ..., 6.99925000e-01, 6.99950000e-01, 6.99975000e-01]), 'name': 'Time'}, {'ClampState': {'primaryGain': 10.0, 'ClampParams': {'OutputZeroEnable': 0, 'PipetteOffset': 0.05197399854660034, 'Holding': -1.525747063413352e-11, 'PrimarySignalHPF': 0.0, 'BridgeBalResist': 20757020.0, 'PrimarySignalLPF': 20000.0, 'RsCompBandwidth': 8.413395979806202e-42, 'WholeCellCompResist': 8.413395979806202e-42, 'WholeCellCompEnable': 6004, 'LeakSubResist': 8.413395979806202e-42, 'HoldingEnable': 1, 'FastCompTau': 8.413395979806202e-42, 'SlowCompCap': 8.413395979806202e-42, 'WholeCellCompCap': 8.413395979806202e-42, 'LeakSubEnable': 6004, 'NeutralizationCap': 1.9578947837994853e-12, 'BridgeBalEnable': 1, 'RsCompCorrection': 8.413395979806202e-42, 'NeutralizationEnable': 1, 'RsCompEnable': 6004, 'OutputZeroAmplitude': -0.0009990156395360827, 'FastCompCap': 8.413395979806202e-42, 'SlowCompTau': 8.413395979806202e-42}, 'secondarySignal': 'Command Current', 'secondaryGain': 1.0, 'secondaryScaleFactor': 2e-09, 'primarySignal': 'Membrane Potential', 'extCmdScale': 4e-10, 'mode': 'IC', 'holding': 0.0, 'primaryUnits': 'V', 'LPFCutoff': 20000.0, 'secondaryUnits': 'A', 'primaryScaleFactor': 0.1, 'membraneCapacitance': 0.0}, 'Protocol': {'recordState': True, 'secondary': None, 'primary': None, 'mode': 'IC'}, 'DAQ': {'command': {'numPts': 28000, 'rate': 40000.0, 'type': 'ao', 'startTime': 1296241556.7347913}, 'primary': {'numPts': 28000, 'rate': 40000.0, 'type': 'ai', 'startTime': 1296241556.7347913}, 'secondary': {'numPts': 28000, 'rate': 40000.0, 'type': 'ai', 'startTime': 1296241556.7347913}}, 'startTime': 1296241556.7347913}] ) """ if self.data is None: raise ValueError('No data has been set') protocol = '' self.sample_interval = self.rate[0] * 1e-6 # express in seconds self.traces = np.array(self.data) points = self.data.shape[1] recs = range(self.data.shape[0]) nchannels = self.data.shape[0] dt = self.sample_interval # make assumption that rate is constant in a block self.time_base = self.time[:self.traces.shape[1]] # in seconds if self.dmode == 'CC': # use first channel mainch = 0 cmdch = 1 else: # assumption is swapped - for this data, that means voltage clamp mode. mainch = 1 cmdch = 0 cmds = self.cmddata # elf.traces[:,cmdch,:] self.tstart = self.tstart_tdur[ 0] # could be pulled from protocol/stimulus information self.tdur = self.tstart_tdur[1] self.tend = self.tstart + self.tdur t0 = int(self.tstart / dt) t1 = int(self.tend / dt) self.cmd_wave = self.cmddata # np.squeeze(self.traces[:, cmdch, :]) diffpts = self.traces.shape[1] - self.cmd_wave.shape[1] ntr = self.cmd_wave.shape[0] self.cmd_wave = np.pad(self.cmd_wave, (0, diffpts), 'constant', constant_values=0.)[:ntr, :] # awkward if cmds.shape[0] > 1: self.values = np.nanmean(self.cmd_wave[:, t0:t1], axis=1) # express values in amps else: self.values = np.zeros_like(self.traces.shape[1:2]) self.commandLevels = self.values # for i in range(self.traces.shape[0]): # mpl.plot(self.time, self.traces[i]) # mpl.plot(self.time[:self.cmd_wave[i].shape[0]], self.cmd_wave[i]) # mpl.show() info = [ { 'units': 'A', 'values': self.values, 'name': 'Command' }, { 'name': 'Time', 'units': 's', 'values': self.time_base }, { 'ClampState': # note that many of these values are just defaults and cannot be relied upon { 'primaryGain': 1.0, 'ClampParams': { 'OutputZeroEnable': 0, 'PipetteOffset': 0.0, 'Holding': 0., 'PrimarySignalHPF': 0.0, 'BridgeBalResist': 0.0, 'PrimarySignalLPF': 20000.0, 'RsCompBandwidth': 0.0, 'WholeCellCompResist': 0.0, 'WholeCellCompEnable': 6004, 'LeakSubResist': 0.0, 'HoldingEnable': 1, 'FastCompTau': 0.0, 'SlowCompCap': 0.0, 'WholeCellCompCap': 0., 'LeakSubEnable': 6004, 'NeutralizationCap': 0., 'BridgeBalEnable': 0, 'RsCompCorrection': 0.0, 'NeutralizationEnable': 1, 'RsCompEnable': 6004, 'OutputZeroAmplitude': 0., 'FastCompCap': 0., 'SlowCompTau': 0.0 }, 'secondarySignal': 'Command Current', 'secondaryGain': 1.0, 'secondaryScaleFactor': 2e-09, 'primarySignal': 'Membrane Potential', 'extCmdScale': 4e-10, 'mode': self.dmode, 'holding': 0.0, 'primaryUnits': 'V', 'LPFCutoff': 10000., 'secondaryUnits': 'A', 'primaryScaleFactor': 0.1, 'membraneCapacitance': 0.0 }, 'Protocol': { 'recordState': True, 'secondary': None, 'primary': None, 'mode': 'IC' }, 'DAQ': { 'command': { 'numPts': points, 'rate': self.sample_interval, 'type': 'ao', 'startTime': 0. }, ' primary': { 'numPts': points, 'rate': self.sample_interval, 'type': 'ai', 'startTime': 0. }, 'secondary': { 'numPts': points, 'rate': self.sample_interval, 'type': 'ai', 'startTime': 0. } }, 'startTime': 0. } ] # filled, automatically with default values self.repc = 1 self.nrepc = 1 self.model_mode = False self.command_scale_factor = 1 self.command_units = 'A' self.devicesUsed = None self.clampDevices = None self.holding = 0. self.amplfierSettings = { 'WCCompValid': False, 'WCEnabled': False, 'CompEnabled': False, 'WCSeriesResistance': 0. } self.WCComp = 0. self.CCComp = 0. self.traces = EM.MetaArray(self.traces, info=info) self.cmd_wave = EM.MetaArray(self.cmd_wave, info=[{ 'name': 'Command', 'units': 'A', 'values': np.array(self.values) }, self.traces.infoCopy('Time'), self.traces.infoCopy(-1)]) self.spikecount = np.zeros(len(recs)) self.rgnrmp = [0, 0.004]
def getData(self, pos=1, check=False): """ Get the data for the current protocol if check is True, we just check that the requested file exists and return True if it does and false if it does not """ # non threaded dirs = self.subDirs(self.protocol) index = self._readIndex() self.clampInfo['dirs'] = dirs self.clampInfo['missingData'] = [] self.traces = [] self.trace_index = [] self.trace_important = [] self.data_array = [] self.commandLevels = [] self.cmd_wave = [] self.time_base = [] self.values = [] self.trace_StartTimes = np.zeros(0) self.sample_rate = [] info = self.getIndex() #self.protocol) holdcheck = info['devices'][self.shortdname]['holdingCheck'] holdvalue = info['devices'][self.shortdname]['holdingSpin'] if holdcheck: self.holding = holdvalue else: self.holding = 0. trx = [] cmd = [] self.protocol_important = self._getImportant(info) # save the protocol importance flag sequence_values = None if 'sequenceParams' in index['.'].keys(): self.sequence = index['.']['sequenceParams'] else: self.sequence = [] # building command voltages or currents - get amplitudes to clamp reps = ('protocol', 'repetitions') foundclamp = False for clamp in self.clamps: if clamp in self.sequence: foundclamp = True self.clampValues = self.sequence[clamp] self.nclamp = len(self.clampValues) if sequence_values is not None: sequence_values = [x for x in self.clampValues for y in sequence_values] else: sequence_values = [x for x in self.clampValues] self.mode = None self.protoDirs = [] # get traces marked "important" # if no such traces exist, then accept ALL traces important = [] for i, d in enumerate(dirs): if self.importantFlag: important.append(self._getImportant(self.getIndex(d))) else: important.append(True) if sum(important) % 2 == 0: # even number of "True", fill in between. state = False for i in range(len(important)): if important[i] is True and state is False: state = True continue if important[i] is False and state is True: # transistion to True important[i] = state continue if important[i] is True and state is True: # next one goes back to false state = False continue if important[i] is False and state is False: # no change... continue if not any(important): important = [True for i in range(len(important))] # set all true self.trace_important = important j = 0 # get traces. # if traces are not marked (or computed above) to be "important", then they # are skipped self.nprotodirs = len(dirs) # save this... for i, d in enumerate(dirs): fn = Path(d, self.dataname) if not fn.is_file(): # print(' acq4read.getData: File not found: ', fn) if check: return False else: continue if check: return True if not important[i]: # only return traces marked "important" continue # try: self.protoDirs.append(Path(d).name) # keep track of valid protocol directories here tr = EM.MetaArray(file=fn) # except: # continue tr_info = tr[0].infoCopy() self.parseClampInfo(tr_info) self.WCComp = self.parseClampWCCompSettings(tr_info) self.CCComp = self.parseClampCCCompSettings(tr_info) # if i == 0: # pp.pprint(info) cmd = self.getClampCommand(tr) self.traces.append(tr) self.trace_index.append(i) trx.append(tr.view(np.ndarray)) self.data_array.append(tr.view(np.ndarray)[self.tracepos]) self.cmd_wave.append(tr.view(np.ndarray)[self.cmdpos]) if sequence_values is not None: if j >= len(sequence_values): j = 0 self.values.append(sequence_values[j]) j += 1 self.time_base.append(tr.xvals('Time')) sr = tr_info[1]['DAQ']['primary']['rate'] self.sample_rate.append(self.samp_rate) #print ('i: %d cmd: %f' % (i, sequence_values[i]*1e12)) if self.mode is None: print (' >> No directories processed for this protocol') return False if 'v' in self.mode.lower(): units = 'V' else: units = 'A' try: self.traces = np.array(trx) except: print('?data does not have consistent shape in the dataset') print(len(trx)) for i in range(len(trx)): print(trx[i].shape) return False if len(self.values) == 0: ntr = len(self.traces) self.traces = self.traces[:ntr] self.values = np.zeros(ntr) # fake else: ntr = len(self.values) self.traces = EM.MetaArray(self.data_array, info=[{'name': 'Command', 'units': cmd.axisUnits(-1), 'values': np.array(self.values)}, tr.infoCopy('Time'), tr.infoCopy(-1)]) self.cmd_wave = EM.MetaArray(self.cmd_wave, info=[{'name': 'Command', 'units': cmd.axisUnits(-1), 'values': np.array(self.values)}, tr.infoCopy('Time'), tr.infoCopy(-1)]) self.sample_interval = 1./self.sample_rate[0] self.data_array = np.array(self.data_array) self.time_base = np.array(self.time_base[0]) protoreps = ('protocol', 'repetitions') mclamppulses = (self.shortdname, 'Pulse_amplitude') seqparams = index['.']['sequenceParams'] # print('sequence params: ', seqparams) #self.printIndex(index) stimuli = index['.']['devices'][self.shortdname]['waveGeneratorWidget']['stimuli'] if 'Pulse' in list(stimuli.keys()): self.tstart = stimuli['Pulse']['start']['value'] self.tend = self.tstart + stimuli['Pulse']['length']['value'] else: self.tstart = 0. self.tend = np.max(self.time_base) seqkeys = list(seqparams.keys()) if mclamppulses in seqkeys: self.repetitions = len(seqparams[mclamppulses]) self.commandLevels = np.array(seqparams[mclamppulses]) function = index['.']['devices'][self.shortdname]['waveGeneratorWidget']['function'] elif protoreps in seqkeys: self.repetitions = len(seqparams[protoreps]) # WE probably should reshape the data arrays here (traces, cmd_wave, data_array) #data = np.reshape(self.AR.traces, (self.AR.repetitions, int(self.AR.traces.shape[0]/self.AR.repetitions), self.AR.traces.shape[1])) elif ('Scanner', 'targets') in seqkeys and protoreps not in seqkeys: # no depth, just one flat rep self.repetitions = 1 else: print('sequence parameter keys: ', seqkeys) raise ValueError(" cannot determine the protocol repetitions") return True
def getAverageScannerImages(self, dataname='Camera/frames.ma', mode='average', firstonly=False, limit=None, filter=True): """ Average (or max or std) the images across the scanner camera files the images are collected into a stack prior to any operation Parameters ---------- dataname : str (default: 'Camera/frames.ma') Name of the camera data file (metaarray format) mode : str (default: 'average') Operation to do on the collected images average : compute the average image max : compute the max projection across the stack std : compute the standard deviation across the stack limit : maximum # of images in stack to combine (starting with first) Returns ------- a single image frame that is the result of the specified operation """ assert mode in ['average', 'max', 'std'] print('average scanner images') dirs = self.subDirs(self.protocol) rep = 0 tar = 0 supindex = self._readIndex() ntargets = len(supindex['.']['sequenceParams'][('Scanner', 'targets')]) pars={} pars['sequence1'] = {} pars['sequence2'] = {} try: reps = supindex['.']['sequenceParams'][('protocol', 'repetitions')] except: reps = [0] pars['sequence1']['index'] = reps pars['sequence2']['index'] = ntargets scannerImages = [] self.sequenceparams = pars self.scannerinfo = {} if limit is None: nmax = len(dirs) else: nmax = min(limit, len(dirs)) for i, d in enumerate(dirs): if i == nmax: # check limit here first break index = self._readIndex(d) imageframe = EM.MetaArray(file=Path(d, dataname)) cindex = self._readIndex(Path(d, 'Camera')) frsize = cindex['frames.ma']['region'] binning = cindex['frames.ma']['binning'] # print ('image shape: ', imageframe.shape) if imageframe.ndim == 3 and imageframe.shape[0] > 1: imageframed = imageframe[1] if imageframe.ndim == 3 and imageframe.shape[0] == 1: imageframed = imageframe[0] imageframed = imageframed.view(np.ndarray) if filter: imageframed = SND.gaussian_filter(imageframed, 3) if firstonly: return imageframed if i == 0: scannerImages = np.zeros((nmax, int(frsize[2]/binning[0]), int(frsize[3]/binning[1]))) # import matplotlib.pyplot as mpl # mpl.imshow(imageframed) # mpl.show() # if i > 3: # exit() scannerImages[i] = imageframed resultframe = np.zeros((scannerImages.shape[1], scannerImages.shape[2])) # simple maximum projection print('mode: %s' % mode) print('scanner images: ', scannerImages.shape) print('binning: ', binning) if mode == 'max': for i in range(scannerImages.shape[0]): resultframe = np.maximum(resultframe, scannerImages[i]) elif mode == 'average': resultframe = np.mean(scannerImages, axis=0) elif mode == 'std': resultframe = np.std(scannerImages, axis=0) return resultframe.T # must transpose to match other data...
def getData(self, pos=1, check=False): """ Get the data for the current protocol if check is True, we just check that the requested file exists and return True if it does and false if it does not """ # non threaded dirs = self.subDirs(self.protocol) index = self._readIndex() self.clampInfo['dirs'] = dirs self.clampInfo['missingData'] = [] self.traces = [] self.data_array = [] self.commandLevels = [] self.cmd_wave = [] self.time_base = [] self.values = [] self.trace_StartTimes = np.zeros(0) self.sample_rate = [] info = self.getIndex() #self.protocol) # print('Info: ', info, self.protocol) holdcheck = info['devices']['MultiClamp1']['holdingCheck'] holdvalue = info['devices']['MultiClamp1']['holdingSpin'] if holdcheck: self.holding = holdvalue else: self.holding = 0. trx = [] cmd = [] sequence_values = None if 'sequenceParams' in index['.'].keys(): self.sequence = index['.']['sequenceParams'] else: self.sequence = [] # building command voltages or currents - get amplitudes to clamp reps = ('protocol', 'repetitions') foundclamp = False for clamp in self.clamps: if clamp in self.sequence: foundclamp = True self.clampValues = self.sequence[clamp] self.nclamp = len(self.clampValues) if sequence_values is not None: sequence_values = [ x for x in self.clampValues for y in sequence_values ] else: sequence_values = [x for x in self.clampValues] self.mode = None for i, d in enumerate(dirs): fn = os.path.join(d, self.dataname) if not os.path.isfile(fn): print(' acq4read.getData: File not found: ', fn) if check: return False else: continue if check: return True try: tr = EM.MetaArray(file=fn) except: continue info = tr[0].infoCopy() self.parseClampInfo(info) self.WCComp = self.parseClampWCCompSettings(info) self.CCComp = self.parseClampCCCompSettings(info) # if i == 0: # pp.pprint(info) cmd = self.getClampCommand(tr) self.traces.append(tr) trx.append(tr.view(np.ndarray)) self.data_array.append(tr.view(np.ndarray)[self.tracepos]) self.cmd_wave.append(tr.view(np.ndarray)[self.cmdpos]) if sequence_values is not None: self.values.append(sequence_values[i]) self.time_base.append(tr.xvals('Time')) sr = info[1]['DAQ']['primary']['rate'] self.sample_rate.append(self.samp_rate) #print ('i: %d cmd: %f' % (i, sequence_values[i]*1e12)) if self.mode is None: print(' >> No directories processed for this protocol') return False if 'v' in self.mode.lower(): units = 'V' else: units = 'A' try: self.traces = np.array(trx) except: print('?data does not have consistent shape in the dataset') print(len(trx)) for i in range(len(trx)): print(trx[i].shape) return False if len(self.values) == 0: ntr = len(self.traces) self.traces = self.traces[:ntr] self.values = np.zeros(ntr) # fake else: ntr = len(self.values) self.traces = EM.MetaArray(self.data_array, info=[{ 'name': 'Command', 'units': cmd.axisUnits(-1), 'values': np.array(self.values) }, tr.infoCopy('Time'), tr.infoCopy(-1)]) self.cmd_wave = EM.MetaArray(self.cmd_wave, info=[{ 'name': 'Command', 'units': cmd.axisUnits(-1), 'values': np.array(self.values) }, tr.infoCopy('Time'), tr.infoCopy(-1)]) self.sample_interval = 1. / self.sample_rate[0] self.data_array = np.array(self.data_array) self.time_base = np.array(self.time_base[0]) protoreps = ('protocol', 'repetitions') mclamppulses = ('MultiClamp1', 'Pulse_amplitude') seqparams = index['.']['sequenceParams'] #self.printIndex(index) stimuli = index['.']['devices']['MultiClamp1']['waveGeneratorWidget'][ 'stimuli'] if 'Pulse' in list(stimuli.keys()): self.tstart = stimuli['Pulse']['start']['value'] self.tend = self.tstart + stimuli['Pulse']['length']['value'] else: self.tstart = 0. self.tend = np.max(self.time_base) if mclamppulses in seqparams.keys(): self.repetitions = len(seqparams[mclamppulses]) self.commandLevels = np.array(seqparams[mclamppulses]) function = index['.']['devices']['MultiClamp1'][ 'waveGeneratorWidget']['function'] elif protoreps in seqparams.keys(): self.repetitions = seqparams[protoreps][0] + 1 else: protoreps = 1 self.repetitions = 1 return True
def vcss_analysis(self, region=None): """ compute steady-state IV curve - from the mean current across the stimulus set over the defined time region (this usually will be the last half or third of the trace) Parameters ---------- region : list or tuple Start and end times for the analysis """ data1 = self.Clamps.traces['Time':region[0]:region[1]] icmds = EM.MetaArray( self.Clamps. cmd_wave, # easiest = turn in to a matching metaarray... info=[{ 'name': 'Command', 'units': 'A', 'values': np.array(self.Clamps.clampValues) }, self.Clamps.traces.infoCopy('Time'), self.Clamps.traces.infoCopy(-1)]) self.vcss_vcmd = icmds['Time':region[0]:region[1]].mean(axis=1) self.r_in = np.nan self.analysis_summary['Rin'] = np.nan self.vcss_v = [] if data1.shape[1] == 0 or data1.shape[0] == 1: return # skip it ntr = len(self.Clamps.traces) self.vcss_Im = data1.mean(axis=1) # steady-state, all traces self.analysis_summary['Rin'] = np.NaN # self.Clamps.plotClampData() isort = np.argsort(self.vcss_vcmd) self.vcss_Im = self.vcss_Im[isort] self.vcss_vcmd = self.vcss_vcmd[isort] bl = self.vcbaseline[isort] self.vcss_bl = bl # compute Rin from the SS IV: # this makes the assumption that: # successive trials are in order so we sort above # commands are not repeated... if len(self.vcss_vcmd) > 1 and len(self.vcss_v) > 1: pf = np.polyfit(self.vcss_vcmd, self.vcss_v, 3, rcond=None, full=False, w=None, cov=False) pval = np.polyval(pf, self.vcss_vcmd) #print('pval: ', pval) slope = np.diff(pval) / np.diff(self.vcss_vcmd) # local slopes imids = np.array((self.vcss_vcmd[1:] + self.vcss_vcmd[:-1]) / 2.) self.rss_fit = {'I': imids, 'V': np.polyval(pf, imids)} #print('fit V: ', self.rss_fit['V']) #slope = slope[[slope > 0 ] and [self.vcss_vcmd[:-1] > -0.8] ] # only consider positive slope points l = int(len(slope) / 2) maxloc = np.argmax(slope[l:]) + l self.r_in = slope[maxloc] self.r_in_loc = [ self.vcss_vcmd[maxloc], self.vcss_v[maxloc], maxloc ] # where it was found minloc = np.argmin(slope[:l]) self.r_in_min = slope[minloc] self.r_in_minloc = [ self.vcss_vcmd[minloc], self.vcss_v[minloc], minloc ] # where it was found self.analysis_summary['Rin'] = self.r_in * 1.0e-6
def getData(self, chmap=None): """ create a Clamp structure for use in SpikeAnalysis and RMTauAnalysis from acq4. Fills in the fields that are returned by PatchEPhys getClamps: clampInfo['dirs] clampInfo['missingData'] self.time_base self.values self.traceStartTimes = np.zeros(0) self.sequence self.clampValues (sequence) self.nclamp = len(self.clmapVlaues self.repc self.nrepc self.data_mode self.model_mode = False self.command_scale_factor self.command_units self.devicesUsed self.clampDevices self.holding self.clampState self.sample_interval self.RSeriesUncomp self.amplifeirSettings['WCCompValid', 'WCEmabled', 'CompEnabled', 'WCSeriesResistance'] self.cmd_wave self.commandLevels (np.array(self.values)) self.traces = MetaArray(traces, info=info) self.tstart self.tdur self.tend self.spikecount = np.zeros(len...) if in vcmode. Info from an example data file: [{'name': 'Channel', 'cols': [{'units': 'A', 'name': 'Command'}, {'units': 'V', 'name': 'primary'}, {'units': 'A', 'name': 'secondary'}]}, {'units': 's', 'values': array([ 0.00000000e+00, 2.50000000e-05, 5.00000000e-05, ..., 6.99925000e-01, 6.99950000e-01, 6.99975000e-01]), 'name': 'Time'}, {'ClampState': {'primaryGain': 10.0, 'ClampParams': {'OutputZeroEnable': 0, 'PipetteOffset': 0.05197399854660034, 'Holding': -1.525747063413352e-11, 'PrimarySignalHPF': 0.0, 'BridgeBalResist': 20757020.0, 'PrimarySignalLPF': 20000.0, 'RsCompBandwidth': 8.413395979806202e-42, 'WholeCellCompResist': 8.413395979806202e-42, 'WholeCellCompEnable': 6004, 'LeakSubResist': 8.413395979806202e-42, 'HoldingEnable': 1, 'FastCompTau': 8.413395979806202e-42, 'SlowCompCap': 8.413395979806202e-42, 'WholeCellCompCap': 8.413395979806202e-42, 'LeakSubEnable': 6004, 'NeutralizationCap': 1.9578947837994853e-12, 'BridgeBalEnable': 1, 'RsCompCorrection': 8.413395979806202e-42, 'NeutralizationEnable': 1, 'RsCompEnable': 6004, 'OutputZeroAmplitude': -0.0009990156395360827, 'FastCompCap': 8.413395979806202e-42, 'SlowCompTau': 8.413395979806202e-42}, 'secondarySignal': 'Command Current', 'secondaryGain': 1.0, 'secondaryScaleFactor': 2e-09, 'primarySignal': 'Membrane Potential', 'extCmdScale': 4e-10, 'mode': 'IC', 'holding': 0.0, 'primaryUnits': 'V', 'LPFCutoff': 20000.0, 'secondaryUnits': 'A', 'primaryScaleFactor': 0.1, 'membraneCapacitance': 0.0}, 'Protocol': {'recordState': True, 'secondary': None, 'primary': None, 'mode': 'IC'}, 'DAQ': {'command': {'numPts': 28000, 'rate': 40000.0, 'type': 'ao', 'startTime': 1296241556.7347913}, 'primary': {'numPts': 28000, 'rate': 40000.0, 'type': 'ai', 'startTime': 1296241556.7347913}, 'secondary': {'numPts': 28000, 'rate': 40000.0, 'type': 'ai', 'startTime': 1296241556.7347913}}, 'startTime': 1296241556.7347913}] ) """ item = self.protocol if item is None: return False protocol = self.datac.items[item].type # print('protocol: ', protocol) try: rate, recs = self.datac.items[item].data() except: return False rate = self.datac.items[item].dfile['Sample_Rate']['v']*1e-6 # convert to seconds self.dfile = self.datac.items[item].dfile (ddir, fname) = os.path.split(self.datac.fname) points = self.dfile['Points']['v'] nchannels = len(self.dfile['Channels']['v']) dt = nchannels * float(rate) #print(nchannels, points, rate, dt) data_mode = self.getDataMode() self.data_mode = data_mode[0] self.time_base = np.arange(points)*dt datac_traces = np.zeros((len(recs), nchannels+1, points)) self.recs = recs if len(recs) < 16: return False for i in range(len(recs)): for j in range(nchannels+1): if j == 2: # pull the stimulus only # print len(recs[i][j]) # print len(np.arange(0, len(recs[i][j]))) cmd = np.interp(self.time_base, np.arange(0, len(recs[i][j]))/1000., recs[i][j]) datac_traces[i, j, :] = cmd else: # channels 0 and 1 # print 'i,j', i, j if len(recs[i][j]) != datac_traces.shape[2]: return False # (cannot match, something is wrong... ) datac_traces[i, j, :] = recs[i][j] if j == 1: datac_traces[i, j, :] *= 1e-3 # convert to V from mV self.traces = np.array(datac_traces) #np.array([[x[chmap[i]] for x in recs] for i in range(len(chmap))]) # remap channels #self.values = np.array([np.mean(datac_traces[1,i]) for i in range(len(recs))]) # print self.values self.repc = 1 self.nrepc = 1 self.model_mode = False self.command_scale_factor = 1 self.command_units = 'A' self.devicesUsed = None self.clampDevices = None self.holding = 0. self.amplfierSettings = {'WCCompValid': False, 'WCEnabled': False, 'CompEnabled': False, 'WCSeriesResistance': 0.} self.clampState = None self.sample_interval = dt # in seconds self.sample_rate = (1./dt)*np.ones(len(recs)) self.RSeriesUncomp = 0. self.cmd_wave = np.squeeze(self.traces[:, 0, :])*1e-12 self.protoTimes = {'drugtestiv': [0.21, 0.5], 'ap-iv2': [0.01, 0.5], 'cciv': [0.005, 0.100]} # in seconds self.tstart = 0.01 self.tdur = 0.500 if protocol in self.protoTimes: self.tstart = self.protoTimes[protocol][0] self.tdur = self.protoTimes[protocol][1]-self.tstart # check how the command wave is doing: cmds = np.mean(np.abs(self.cmd_wave), axis=0) dcmds = np.diff(cmds) # import matplotlib.pyplot as mpl # mpl.plot(self.time_base[:-1], dcmds) # mpl.show() start = np.where(dcmds > 1e-11)[0] if len(start) > 1: start = start[0] end = np.where(dcmds < -1e-11)[0] if len(end) > 1: end = end[0] # print('start, end: ', start, end) # print(self.time_base[start], self.time_base[end]) self.tend = self.tstart + self.tdur # print('self.tstart, end, dur: ', self.tstart, self.tend, self.tdur) t0 = int(self.tstart/dt) t1 = int(self.tend/dt) self.values = np.mean(self.cmd_wave[:, t0:t1], axis=1) # express values in amps self.commandLevels = self.values info = [{'units': 'A', 'values': self.values, 'name': 'Command'}, {'name': 'Time', 'units': 's', 'values': self.time_base}, {'ClampState': {'primaryGain': 10.0, 'ClampParams': {'OutputZeroEnable': 0, 'PipetteOffset': 0.0, 'Holding': 0.0, 'PrimarySignalHPF': 0.0, 'BridgeBalResist': 0.0, 'PrimarySignalLPF': 20000.0, 'RsCompBandwidth': 0.0, 'WholeCellCompResist': 0.0, 'WholeCellCompEnable': 6004, 'LeakSubResist': 0.0, 'HoldingEnable': 1, 'FastCompTau': 0.0, 'SlowCompCap': 0.0, 'WholeCellCompCap': 0., 'LeakSubEnable': 6004, 'NeutralizationCap': 0., 'BridgeBalEnable': 0, 'RsCompCorrection': 0.0, 'NeutralizationEnable': 1, 'RsCompEnable': 6004, 'OutputZeroAmplitude': 0., 'FastCompCap': 0., 'SlowCompTau': 0.0}, 'secondarySignal': 'Command Current', 'secondaryGain': 1.0, 'secondaryScaleFactor': 2e-09, 'primarySignal': 'Membrane Potential', 'extCmdScale': 4e-10, 'mode': 'IC', 'holding': 0.0, 'primaryUnits': 'V', 'LPFCutoff': 20000.0, 'secondaryUnits': 'A', 'primaryScaleFactor': 0.1, 'membraneCapacitance': 0.0}, 'Protocol': {'recordState': True, 'secondary': None, 'primary': None, 'mode': 'IC'}, 'DAQ': {'command': {'numPts': 10000, 'rate': 10000.0, 'type': 'ao', 'startTime': 0.}, 'primary': {'numPts': 10000, 'rate': 10000.0, 'type': 'ai', 'startTime': 0.}, 'secondary': {'numPts': 1000, 'rate': 10000.0, 'type': 'ai', 'startTime': 0.}}, 'startTime': 0.}] self.WCComp = self.parseClampWCCompSettings(info) self.CCComp = self.parseClampCCCompSettings(info) self.traces = np.squeeze(self.traces[:,1,:]) self.traces = EM.MetaArray(self.traces, info=info) self.cmd_wave = EM.MetaArray(self.cmd_wave, info=[{'name': 'Command', 'units': 'A', 'values': np.array(self.values)}, self.traces.infoCopy('Time'), self.traces.infoCopy(-1)]) self.spikecount = np.zeros(len(recs)) self.rgnrmp = [0, 0.005] # print('getclamps got it all') return True