def stripesurround_SVD(exp_name, stimnrs, nrcomponents=5): """ nrcomponents: first N components of singular value decomposition (SVD) will be used to reduce noise. """ exp_dir = iof.exp_dir_fixer(exp_name) if isinstance(stimnrs, int): stimnrs = [stimnrs] for stimnr in stimnrs: data = iof.load(exp_name, stimnr) _, metadata = asc.read_spikesheet(exp_dir) px_size = metadata['pixel_size(um)'] clusters = data['clusters'] stas = data['stas'] max_inds = data['max_inds'] filter_length = data['filter_length'] stx_w = data['stx_w'] exp_name = data['exp_name'] stimname = data['stimname'] frame_duration = data['frame_duration'] quals = data['quals'] # Record which clusters are ignored during analysis try: included = data['included'] except KeyError: included = [True] * clusters.shape[0] # Average STA values 100 ms around the brightest frame to # minimize noise cut_time = int(100 / (frame_duration * 1000) / 2) # Tolerance for distance between center and surround # distributions 60 μm dtol = int((60 / px_size) / 2) clusterids = plf.clusters_to_ids(clusters) fsize = int(700 / (stx_w * px_size)) t = np.arange(filter_length) * frame_duration * 1000 vscale = fsize * stx_w * px_size cs_inds = np.empty(clusters.shape[0]) polarities = np.empty(clusters.shape[0]) savepath = os.path.join(exp_dir, 'data_analysis', stimname) for i in range(clusters.shape[0]): sta = stas[i] max_i = max_inds[i] # From this point on, use the low-rank approximation # version sta_reduced = sumcomponent(nrcomponents, sta) try: sta_reduced, max_i = msc.cutstripe(sta_reduced, max_i, fsize * 2) except ValueError as e: if str(e) == 'Cutting outside the STA range.': included[i] = False continue else: print(f'Error while analyzing {stimname}\n' + f'Index:{i} Cluster:{clusterids[i]}') raise # Isolate the time point from which the fit will # be obtained if max_i[1] < cut_time: max_i[1] = cut_time + 1 fitv = np.mean(sta_reduced[:, max_i[1] - cut_time:max_i[1] + cut_time + 1], axis=1) # Make a space vector s = np.arange(fitv.shape[0]) if np.max(fitv) != np.max(np.abs(fitv)): onoroff = -1 else: onoroff = 1 polarities[i] = onoroff # Determine the peak values for center and surround # to give as initial parameters for curve fitting centerpeak = onoroff * np.max(fitv * onoroff) surroundpeak = onoroff * np.max(fitv * -onoroff) # Define initial guesses for the center and surround gaussians # First set of values are for center, second for surround. p_initial = [centerpeak, max_i[0], 2, surroundpeak, max_i[0], 8] if onoroff == 1: bounds = ([0, -np.inf, -np.inf, 0, max_i[0] - dtol, 4], [ np.inf, np.inf, np.inf, np.inf, max_i[0] + dtol, 20 ]) elif onoroff == -1: bounds = ([ -np.inf, -np.inf, -np.inf, -np.inf, max_i[0] - dtol, 4 ], [0, np.inf, np.inf, 0, max_i[0] + dtol, 20]) try: popt, _ = curve_fit(centersurround_onedim, s, fitv, p0=p_initial, bounds=bounds) except (ValueError, RuntimeError) as e: er = str(e) if (er == "`x0` is infeasible." or er.startswith("Optimal parameters not found")): popt, _ = curve_fit(onedgauss, s, fitv, p0=p_initial[:3]) popt = np.append(popt, [0, popt[1], popt[2]]) elif er == "array must not contain infs or NaNs": included[i] = False continue else: print(f'Error while analyzing {stimname}\n' + f'Index:{i} Cluster:{clusterids[i]}') import pdb pdb.set_trace() raise fit = centersurround_onedim(s, *popt) popt[0] = popt[0] * onoroff popt[3] = popt[3] * onoroff csi = popt[3] / popt[0] cs_inds[i] = csi plt.figure(figsize=(10, 9)) ax = plt.subplot(121) plf.stashow(sta_reduced, ax, extent=[0, t[-1], -vscale, vscale]) ax.set_xlabel('Time [ms]') ax.set_ylabel('Distance [µm]') ax.set_title(f'Using first {nrcomponents} components of SVD', fontsize='small') ax = plt.subplot(122) plf.spineless(ax) ax.set_yticks([]) # We need to flip the vertical axis to match # with the STA next to it plt.plot(onoroff * fitv, -s, label='Data') plt.plot(onoroff * fit, -s, label='Fit') plt.axvline(0, linestyle='dashed', alpha=.5) plt.title(f'Center: a: {popt[0]:4.2f}, μ: {popt[1]:4.2f},' + f' σ: {popt[2]:4.2f}\n' + f'Surround: a: {popt[3]:4.2f}, μ: {popt[4]:4.2f},' + f' σ: {popt[5]:4.2f}' + f'\n CS index: {csi:4.2f}') plt.subplots_adjust(top=.85) plt.suptitle(f'{exp_name}\n{stimname}\n{clusterids[i]} ' + f'Q: {quals[i]:4.2f}') os.makedirs(os.path.join(savepath, 'stripesurrounds_SVD'), exist_ok=True) plt.savefig(os.path.join(savepath, 'stripesurrounds_SVD', clusterids[i] + '.svg'), bbox_inches='tight') plt.close() data.update({ 'cs_inds': cs_inds, 'polarities': polarities, 'included': included }) np.savez(os.path.join(savepath, f'{stimnr}_data_SVD.npz'), **data) print(f'Surround plotted and saved for {stimname}.')
stripesta = np.array(data['stas'])[choose][0] stripemax = np.array(data['max_inds'])[choose][0] stx_w = stx_h frame_duration = data['frame_duration'] fits = np.array(data['fits'])[choose] onoroff = data['polarities'][choose] cut_time = int(100/(frame_duration*1000)/2) fsize_original = int(700/(stx_w*px_size)) fsize = int(400/(stx_w*px_size)) fsize_diff = fsize_original - fsize t = np.arange(filter_length)*frame_duration*1000 vscale = fsize * stx_w*px_size stripesta, stripemax_i = msc.cutstripe(stripesta, stripemax, fsize*2) fitv = np.mean(stripesta[:, stripemax[1]-cut_time:stripemax[1]+cut_time+1], axis=1) s = np.arange(fitv.shape[0]) ax3 = plt.subplot(rows, columns, 3) plf.stashow(stripesta, ax3) plf.subplottext('C', ax3) ax4 = plt.subplot(rows, columns, 4) ax4.plot(onoroff*fitv, -s, color='C2') plf.subplottext('D', ax4, x=-.25, y=1.1) plf.spineless(ax4) ax4.axvline(0, color='k', alpha=.5, linestyle='dashed', linewidth=1)
onoroff = data['polarities'][index] csi = data['cs_inds'][index] fit = fits[index] popt = all_parameters[index] cut_time = int(100/(frame_duration*1000)/2) # Changed width from 700 micrometer to 400 to zoom in on the # region of interest. This shifts where the fit is drawn, # it's fixed when plotting. fsize_original = int(700/(stx_w*px_size)) fsize = int(400/(stx_w*px_size)) fsize_diff = fsize_original - fsize t = np.arange(filter_length)*frame_duration*1000 vscale = fsize * stx_w*px_size sta, max_i = msc.cutstripe(sta, max_i, fsize*2) ax1 = axes[2*j] plf.subplottext(['A', 'C'][j], ax1, x=-.4) plf.subplottext(['Mesopic', 'Photopic'][j], ax1, x=-.5, y=.5, rotation=90, va='center') plf.stashow(sta, ax1, extent=[0, t[-1], -vscale, vscale]) ax1.set_xlabel('Time [ms]') # ax1.set_ylabel(r'Distance [$\upmu$m]') ax1.set_ylabel(r'Distance [μm]') fitv = np.mean(sta[:, max_i[1]-cut_time:max_i[1]+cut_time+1], axis=1) s = np.arange(fitv.shape[0])
""" Created on Thu Feb 1 11:29:37 2018 @author: ycan """ import plotfuncs as plf import matplotlib.pyplot as plt import miscfuncs as msc import iofuncs as iof data = iof.load('20180124', 12) index = 5 sta = data['stas'][index] max_i = data['max_inds'][index] sta, max_i = msc.cutstripe(sta, max_i, 30) a = 'Accent, Accent_r, Blues, Blues_r, BrBG, BrBG_r, BuGn, BuGn_r, BuPu, BuPu_r, CMRmap, CMRmap_r, Dark2, Dark2_r, GnBu, GnBu_r, Greens, Greens_r, Greys, Greys_r, OrRd, OrRd_r, Oranges, Oranges_r, PRGn, PRGn_r, Paired, Paired_r, Pastel1, Pastel1_r, Pastel2, Pastel2_r, PiYG, PiYG_r, PuBu, PuBuGn, PuBuGn_r, PuBu_r, PuOr, PuOr_r, PuRd, PuRd_r, Purples, Purples_r, RdBu, RdBu_r, RdGy, RdGy_r, RdPu, RdPu_r, RdYlBu, RdYlBu_r, RdYlGn, RdYlGn_r, Reds, Reds_r, Set1, Set1_r, Set2, Set2_r, Set3, Set3_r, Spectral, Spectral_r, Vega10, Vega10_r, Vega20, Vega20_r, Vega20b, Vega20b_r, Vega20c, Vega20c_r, Wistia, Wistia_r, YlGn, YlGnBu, YlGnBu_r, YlGn_r, YlOrBr, YlOrBr_r, YlOrRd, YlOrRd_r, afmhot, afmhot_r, autumn, autumn_r, binary, binary_r, bone, bone_r, brg, brg_r, bwr, bwr_r, cool, cool_r, coolwarm, coolwarm_r, copper, copper_r, cubehelix, cubehelix_r, flag, flag_r, gist_earth, gist_earth_r, gist_gray, gist_gray_r, gist_heat, gist_heat_r, gist_ncar, gist_ncar_r, gist_rainbow, gist_rainbow_r, gist_stern, gist_stern_r, gist_yarg, gist_yarg_r, gnuplot, gnuplot2, gnuplot2_r, gnuplot_r, gray, gray_r, hot, hot_r, hsv, hsv_r, inferno, inferno_r, jet, jet_r, magma, magma_r, nipy_spectral, nipy_spectral_r, ocean, ocean_r, pink, pink_r, plasma, plasma_r, prism, prism_r, rainbow, rainbow_r, seismic, seismic_r, spectral, spectral_r, spring, spring_r, summer, summer_r, tab10, tab10_r, tab20, tab20_r, tab20b, tab20b_r, tab20c, tab20c_r, terrain, terrain_r, viridis, viridis_r, winter, winter_r' b = a.split(',') c = [i.strip(' ') for i in b if not i.endswith('_r')] c = ['bwr_r', 'RdBu', 'seismic_r', 'bwr', 'RdBu_r', 'seismic'] dims = plf.numsubplots(len(c)) plt.figure(figsize=(20, 20)) for i, cm in enumerate(c): ax = plt.subplot(dims[0], dims[1], i + 1) im = plf.stashow(sta, ax, cmap=cm, ticks=[]) plt.axis('off') im.axes.get_xaxis().set_visible(False) im.axes.get_yaxis().set_visible(False) ax.set_title(cm, size='x-small')
def stripesurround(exp_name, stimnrs): exp_dir = iof.exp_dir_fixer(exp_name) if isinstance(stimnrs, int): stimnrs = [stimnrs] for stimnr in stimnrs: data = iof.load(exp_name, stimnr) _, metadata = asc.read_spikesheet(exp_dir) px_size = metadata['pixel_size(um)'] clusters = data['clusters'] stas = data['stas'] max_inds = data['max_inds'] filter_length = data['filter_length'] stx_w = data['stx_w'] exp_name = data['exp_name'] stimname = data['stimname'] frame_duration = data['frame_duration'] quals = data['quals'] clusterids = plf.clusters_to_ids(clusters) fsize = int(700 / (stx_w * px_size)) t = np.arange(filter_length) * frame_duration * 1000 vscale = fsize * stx_w * px_size #%% cs_inds = np.empty(clusters.shape[0]) polarities = np.empty(clusters.shape[0]) savepath = os.path.join(exp_dir, 'data_analysis', stimname) for i in range(clusters.shape[0]): sta = stas[i] max_i = max_inds[i] sta, max_i = msc.cutstripe(sta, max_i, fsize * 2) plt.figure(figsize=(12, 10)) ax = plt.subplot(121) plf.stashow(sta, ax) # Isolate the time point from which the fit will # be obtained fitv = sta[:, max_i[1]] # Make a space vector s = np.arange(fitv.shape[0]) if np.max(fitv) != np.max(np.abs(fitv)): onoroff = -1 else: onoroff = 1 polarities[i] = onoroff # Determine the peak values for center and surround # to give as initial parameters for curve fitting centerpeak = -onoroff * np.max(fitv * onoroff) surroundpeak = -onoroff * np.max(fitv * -onoroff) # Define initial guesses for the center and surround gaussians # First set of values are for center, second for surround. p_initial = [centerpeak, max_i[0], 2, surroundpeak, max_i[0], 4] bounds = ([0, -np.inf, -np.inf, 0, -np.inf, -np.inf], np.inf) try: popt, _ = curve_fit(centersurround_onedim, s, fitv, p0=p_initial, bounds=bounds) except ValueError as e: if str(e) == "`x0` is infeasible.": print(e) popt, _ = curve_fit(onedgauss, s, onoroff * fitv, p0=p_initial[:3]) popt = np.append(popt, [0, popt[1], popt[2]]) else: raise fit = centersurround_onedim(s, *popt) # Avoid dividing by zero when calculating center-surround index if popt[3] > 0: csi = popt[0] / popt[3] else: csi = 0 cs_inds[i] = csi ax = plt.subplot(122) plf.spineless(ax) ax.set_yticks([]) # We need to flip the vertical axis to match # with the STA next to it plt.plot(onoroff * fitv, -s, label='Data') plt.plot(onoroff * fit, -s, label='Fit') plt.axvline(0, linestyle='dashed', alpha=.5) plt.title(f'Center: a: {popt[0]:4.2f}, μ: {popt[1]:4.2f},' + f' σ: {popt[2]:4.2f}\n' + f'Surround: a: {popt[3]:4.2f}, μ: {popt[4]:4.2f},' + f' σ: {popt[5]:4.2f}' + f'\n CS index: {csi:4.2f}') plt.subplots_adjust(top=.82) plt.suptitle(f'{exp_name}\n{stimname}\n{clusterids[i]}') os.makedirs(os.path.join(savepath, 'stripesurrounds'), exist_ok=True) plt.savefig( os.path.join(savepath, 'stripesurrounds', clusterids[i] + '.svg')) plt.close() data.update({'cs_inds': cs_inds, 'polarities': polarities}) np.savez(os.path.join(savepath, f'{stimnr}_data.npz'), **data)