def tifInfo(filePath): """ Given the path to a tif file recorded returns the number of image frames within as well as number of image channels """ import numpy as np with tff.TiffFile(filePath) as tf: nChannels = np.size( tf.scanimage_metadata['FrameData']['SI.hChannels.channelSave']) nImgs = int(np.size(tf.pages) / nChannels) nImgs = np.size(tf.pages) keys = list(tf.scanimage_metadata['FrameData'].keys()) idx = util.findStrInList('numFramesPerVolume', keys) if len(idx) > 0: idx = idx[0] numFramesPerVol = tf.scanimage_metadata['FrameData'][keys[idx]] if np.size(numFramesPerVol) == 0: numFramesPerVol = 1 else: numFramesPerVol = 1 idx = util.findStrInList('numVolumes', keys) if len(idx) > 0: idx = idx[0] numVols = tf.scanimage_metadata['FrameData'][keys[idx]] else: numVols = 1 return (nChannels, nImgs, numFramesPerVol, numVols)
def mergeRois(roiNames, roiNames_old, roiName_new, roiMat, axis=0): """ Consolidates a list of provided roi names into a single roi name sums their timeries and returns new roi matrix Parameters ---------- roiNames: list/array of strings All the roi names roiNames_old: list/array of strings Roi names to consolidate roiName_new : string New roi name after consolidation roiMat: array Array where one axis corresponds to rois axis: int Axis corresponding to the Rois Returns ------- d: dictionary Dictionary with new roi names and relevant array """ from apCode import util import numpy as np inds = [] for rn in roiNames_old: inds.extend(util.findStrInList(rn, roiNames)) inds = np.unique(np.array(inds)) roiMat_keep = np.delete(roiMat, inds, axis=0) roiNames_keep = np.delete(roiNames, inds) inds_diff = np.setdiff1d(np.arange(len(roiNames)), inds) roiMat_diff = np.delete(roiMat, inds_diff, axis=axis) roiNames_diff = np.delete(roiNames, inds_diff) preDotStrings = [] for rn in roiNames_diff: preDotStrings.append(rn.split('.')[0]) preDotStrings = np.unique(preDotStrings) d = {} sigs, names = [], [] for ps in preDotStrings: inds = util.findStrInList(ps, roiNames_diff) sig = np.take(roiMat_diff, inds, axis=axis) sig = sig.mean(axis=axis) * np.sqrt(sig.shape[axis]) sigs.append(sig) name = f'{ps}.{roiName_new}' names.append(name) if not isinstance(roiNames_keep, list): roiNames_keep = np.array(roiNames_keep).tolist() roiNames_keep.extend(names) d['roiNames'] = np.array(roiNames_keep) d['roiMat'] = np.concatenate((roiMat_keep, np.array(sigs)), axis=axis) d['rois_consolidated'] = roiNames_diff return d
def mNormDffAndConsolidateRois(df_fish, n_preStim = 30, perc = 20, roiNames_core = ['Mauthner', 'MiD2c','MiD2i','MiD3c', 'MiD3i',\ 'CaD', 'RoL1', 'RoL2', 'RoM1', 'RoM2M','RoM2L','RoM3',\ 'MiM1','MiM1MiV1','MiV1','MiV2','RoV3','CaV',\ 'nMLF','ves', 'MiR1', 'MiR2']): import apCode.util as util import numpy as np ca_trl = np.array([np.array(ca_) for ca_ in df_fish.ca_trl]) roiNames = df_fish.iloc[0].roiName ind_back = util.findStrInList('background', roiNames)[0] back = np.expand_dims(ca_trl[:, ind_back, :], axis=1) ca_trl = ca_trl - back F = np.expand_dims(np.percentile(ca_trl[..., :n_preStim], perc, axis=2), axis=2) ind_m = util.findStrInList('R.Mauthner', roiNames)[0] m_norm = np.expand_dims(np.expand_dims(ca_trl[:, ind_m, :], axis=1).max(axis=2), axis=2).mean(axis=0)[np.newaxis, ...] df_trl = (ca_trl - F) ca_trl_mNorm = df_trl / m_norm roiNames_strip = stripRoiNames(roiNames) lRois = np.array([len(_) for _ in roiNames_strip]) inds_del = np.where(lRois == 0) if len(inds_del) > 0: inds_del = inds_del[0] ind_unknown = util.findStrInList('unknown', roiNames) if len(ind_unknown) > 0: ind_unknown = ind_unknown[0] inds_del = np.union1d(inds_del, ind_unknown) roiNames_new = np.delete(roiNames_strip, inds_del, axis=0) ca_trl_new = list(np.delete(ca_trl, inds_del, axis=1)) ca_trl_mNorm = np.delete(ca_trl_mNorm, inds_del, axis=1) x = np.swapaxes(ca_trl_mNorm, 0, 1) roiNames_con, x = consolidateNMlfRois(roiNames_new, x) roiNames_match, x = matchRoiNamesAndSignalsToCore(roiNames_con, x,\ roiNames_core = roiNames_core) roiNames_split, x = splitRoisToLR(roiNames_match, x) ca_trl_mNorm = list(np.transpose(x, (2, 0, 1, 3))) x = np.swapaxes(ca_trl_new, 0, 1) _, x = consolidateNMlfRois(roiNames_new, x) _, x = matchRoiNamesAndSignalsToCore(_, x,\ roiNames_core = roiNames_core) _, x = splitRoisToLR(_, x) ca_trl_short = list(np.transpose(x, (2, 0, 1, 3))) df_fish_new = df_fish.copy() nRows = len(df_fish_new) df_fish_new = df_fish_new.assign(ca_trl=ca_trl_new) df_fish_new = df_fish_new.assign(ca_trl_mNorm=ca_trl_mNorm) df_fish_new = df_fish_new.assign(ca_trl_short=ca_trl_short) df_fish_new = df_fish_new.assign(roiName_new=[roiNames_split] * nRows) return df_fish_new
def basToDf(bas, n_pre_bas=200e-3, n_post_bas=1.5): import apCode.SignalProcessingTools as spt import pandas as pd import numpy as np import apCode.util as util df = {} dt = bas['t'][1] - bas['t'][0] Fs = int(1 / dt) inds_stim, amps_stim, ch_stim = getStimInfo(bas) keys = list(bas.keys()) ind_mtr = util.findStrInList('den', keys)[-1] x = np.squeeze(np.array(bas[keys[ind_mtr]])) if x.shape[0] == 2: x = x.T motor_trl = spt.segmentByEvents(spt.zscore(x, axis=0), inds_stim, int(n_pre_bas * Fs), int(n_post_bas * Fs)) motorTime_trl = spt.segmentByEvents(bas['t'], inds_stim, int(n_pre_bas * Fs), int(n_post_bas * Fs)) trlNum = np.arange(len(inds_stim)) + 1 df['trlNum'] = trlNum df['stimInd'] = inds_stim df['stimAmp'] = amps_stim df['stimHT'] = ch_stim df['motorActivity'] = motor_trl df['motorTime'] = motorTime_trl return pd.DataFrame(df)
def getRootsAndFiles(rootDir, ext): r, f = [], [] for root, dirs, files in os.walk(rootDir): inds = util.findStrInList('.' + ext, files) if (len(inds) == len(files)) & (len(inds) > 0): r.append(root) f.append(files) return r, f
def omitRois(roiNames, omitList): import apCode.util as util import numpy as np inds_del = [] for o in omitList: inds = util.findStrInList(o, roiNames) if len(inds) > 0: inds_del.extend(inds) inds_del = np.array(inds_del) inds_all = np.arange(len(roiNames)) inds_keep = np.setdiff1d(inds_all, inds_del) return np.unique(inds_keep)
def apply_to_imgs_and_save(imgDir, func='fliplr', splitStr='Fish'): """ Apply some function to images in specified directory and save. After function is applied the output must still be 2D/3D. Parameters ---------- imgDir: str Image directory func: str or function Function to apply to images. If str, then must be a function in numpy splitStr: str Substring where to split path. The images will be saved at the level above where the path is split. Returns ------- saveDir: str Directory where images were saved """ from apCode import util import apCode.FileTools as ft import apCode.volTools as volt if isinstance(func, str): func = eval(f'np.{func}') strList = os.path.abspath(imgDir).split("\\") ind = util.findStrInList(splitStr, strList, case_sensitive=False)[0] strRep = strList[ind] rootDir = os.path.join(*np.array(strList)[:ind]) fn = ft.subDirsInDir(rootDir) nDir = len(fn) sfx = strRep.replace(splitStr, f'{splitStr}{nDir+1}') saveDir = os.path.join(rootDir, sfx) os.makedirs(saveDir, exist_ok=True) print('Reading images into dask array...') imgs = volt.dask_array_from_image_sequence(imgDir) print(f'{imgs.shape[0]} images!') blockSize = np.minimum(750, (imgs.shape[0] // 10) + 1) print(f'Block size = {blockSize}') print(f'Transforming and saving images to\n{saveDir}') inds = np.arange(len(imgs)) inds_list = ft.sublistsFromList(inds, blockSize) nBlocks = len(inds_list) for iBlock, inds_ in enumerate(inds_list): print(f'Block # {iBlock+1}/{nBlocks}') inds_now = np.array(inds_) imgs_ = imgs[inds_now].compute() imgs_ = np.array([func(img) for img in imgs_]) imgNames = [ r'f{}_{:06d}.bmp'.format(nDir + 1, ind) for ind in inds_now ] volt.img.saveImages(imgs_, imgDir=saveDir, imgNames=imgNames) return saveDir
def consolidateNMlfRois(roiNames, roi_ts): """ Assumes all nMLF neurons have names starting with 'Me'. Then, inds roi indices for consolidation of both sides. Only consolidates along the first axis, so make sure roi_ts has ROIs as first axis Parameters ---------- roi_ts: array, (nRois, ...) """ import numpy as np from apCode import util sideInds = [[], []] roiNames_unique = np.unique(roiNames) inds_mlf_left = util.findStrInList('L.Me', roiNames_unique) inds_mlf_right = util.findStrInList('R.Me', roiNames_unique) inds_mlf_both = [inds_mlf_left, inds_mlf_right] for iSide in range(2): inds_side = inds_mlf_both[iSide] for iRoi in inds_side: roi = roiNames_unique[iRoi] ind = util.findStrInList(roi, roiNames) sideInds[iSide].extend(ind) si = [] roiNames_new = np.array(roiNames.copy()) for iSide, side in enumerate(sideInds): if side == 0: prefix = 'L' else: prefix = 'R' roiNames_new[side] = f'{prefix}.nMLF' si.append(np.array(side)) roi_ts_new = [] roiNames_new_unique = np.unique(roiNames_new) for rn in roiNames_new_unique: inds = util.findStrInList(rn, roiNames_new) roi_ts_new.append(roi_ts[inds].mean(axis=0)) roi_ts_new = np.array(roi_ts_new) # dic = dict(roiNames = roiNames_new_unique, roi_ts = roi_ts_new) return roiNames_new_unique, roi_ts_new
def motorFromBas(bas): keys = list(bas.keys()) ind_mtr = util.findStrInList('den', keys) if len(ind_mtr) > 0: ind_mtr = ind_mtr[-1] x = np.squeeze(np.array(bas[keys[ind_mtr]])) else: if 'ch3' in bas: x = np.array([bas['ch3'], bas['ch4']]) else: x = np.array([bas['ch1'], bas['ch2']]) if x.shape[0] < x.shape[1]: x = x.T return x
def readProcTableInPath(path): from apCode import util from apCode.FileTools import findAndSortFilesInDir import pandas as pd import os fn = findAndSortFilesInDir(path) ind = util.findStrInList('procTable', fn) procTable = None if len(ind) > 0: ind = ind[-1] try: procTable = pd.read_excel(os.path.join(path, fn[ind])) except: print('Could not read procTable. Make sure it is not open') else: print(f'No procTable in {path}') return procTable
def recursively_find_paths_with_searchStr(searchDir, searchStr): """ Walks down the directory tree for a specified search directory and returns the paths to all files or folders with specified search string. Parameters ---------- searchDir: str Path to search directory searchStr: str Search string to use in looking for files/folders Returns ------- paths: list or str List of paths returned by the search """ roots, dirs, files = zip(*[out for out in os.walk(searchDir)]) inds = util.findStrInList(searchStr, roots) return np.array(roots)[inds]