onset_list[cellNum - 1][curr_key] = curr_transient np.save(data_loc + onsetName, onset_list) print( 'Saved onset transient for cell #%d, onset duration of %dms and sliding psth with half-width of %dms' % (cellNum, onsetDur, halfWidth)) if toPlot: nrow, ncol = 3, 1 f, ax = plt.subplots(nrow, ncol, figsize=(ncol * 25, nrow * 20)) f.suptitle('Cell #%d -- PSTH for %d trials' % (cellNum, nTrials)) # 1 ms bins psth, bins = hf.make_psth([allSpikes], binWidth=1e-3) rate = psth[0] / nTrials # - init params (we'll fit a Gaussian to the first X ms) toFit = 100 # in mS psth_floor = np.min(rate) wherePeak = np.argmax(rate) max_rate = np.max(rate) ax[0].plot([0, cycleDur_mask], [1.05 * max_rate, 1.05 * max_rate], 'k-', label='Mask cycle') ax[0].plot([0, cycleDur_base], [1.025 * max_rate, 1.025 * max_rate], 'r-', label='Base cycle')
def phase_by_cond(which_cell, data, expInd, disp, con, sf, sv_loc=save_loc, dir=-1, cycle_fold=2, n_bins_fold=8, dp=dataPath, expName=expName, date_suffix=''): ''' Given a cell and the disp/con/sf indices, plot the spike raster for each trial, a folded PSTH, and finally the response phase - first relative to trial onset, and finally relative to the stimulus phase dir = -1 or +1 (i.e. stimulus moving left or right?) cycle_fold = over how many stimulus cycles to fold when creating folded psth? n_bins_fold = how many bins per stimulus period when folding? ''' dataList = hf.np_smart_load(str(dp + expName)) save_base = sv_loc + 'phasePlots_%s/' % date_suffix val_trials, allDisps, allCons, allSfs = hf.get_valid_trials( data, disp, con, sf, expInd) if not np.any( val_trials[0] ): # val_trials[0] will be the array of valid trial indices --> if it's empty, leave! warnings.warn('this condition is not valid') return ### SINGLE GRATINGS if disp == 0: # get the phase relative to the stimulus ph_rel_stim, stim_ph, resp_ph, all_tf = hf.get_true_phase( data, val_trials, expInd, dir) # compute the fourier amplitudes stimDur = hf.get_exp_params(expInd).stimDur psth_val, _ = hf.make_psth(data['spikeTimes'][val_trials], stimDur=stimDur) _, rel_amp, full_fourier = hf.spike_fft(psth_val, all_tf, stimDur) # now plot! f, ax = plt.subplots(3, 2, figsize=(20, 30)) relSpikes = data['spikeTimes'][val_trials] colors = cm.rainbow(np.linspace(0, 1, len(val_trials[0]))) ##### # plot spike raster - trial-by-trial ##### # only works for SINGLE GRATINGS # draw the beginning of each cycle for each trial ax = plt.subplot(3, 1, 1) for i in range(len(relSpikes)): ax.scatter(relSpikes[i], i * np.ones_like(relSpikes[i]), s=45, color=colors[i]) stimPh = stim_ph[i] stimPeriod = np.divide(1.0, all_tf[i]) stimDur = hf.get_exp_params(expInd).stimDur # i.e. at what point during the trial (in s) does the stimulus component first begin a cycle? firstPh0 = hf.first_ph0(stimPh, all_tf[i])[1] for j in range(len(all_tf[i])): allPh0 = [ stimPeriod[j] * np.arange(-1, stimDur * all_tf[i][j]) + firstPh0[j] ] allPh90 = allPh0 + stimPeriod[j] / 4 allPh180 = allPh90 + stimPeriod[j] / 4 allPh270 = allPh180 + stimPeriod[j] / 4 ax.errorbar(allPh0[0], i * np.ones_like(allPh0[0]), 0.25, linestyle='none', color='k', linewidth=1) ax.errorbar(allPh90[0], i * np.ones_like(allPh0[0]), 0.05, linestyle='none', color='k', linewidth=1) ax.errorbar(allPh180[0], i * np.ones_like(allPh0[0]), 0.05, linestyle='none', color='k', linewidth=1) ax.errorbar(allPh270[0], i * np.ones_like(allPh0[0]), 0.05, linestyle='none', color='k', linewidth=1) ax.set_xlabel('time (s)') ax.set_ylabel('repetition #') ax.set_title('Spike rasters') ##### # plot PSTH - per trial, but folded over N cycles ##### # only works for SINGLE GRATINGS ax = plt.subplot(3, 1, 2) for i in range(len(relSpikes)): _, bin_edges, psth_norm = hf.fold_psth(relSpikes[i], all_tf[i], stim_ph[i], cycle_fold, n_bins_fold, dir=dir) plt.plot(bin_edges[0:-1], i - 0.5 + psth_norm, color=colors[i]) stimPeriod = np.divide(1.0, all_tf[i]) for j in range(cycle_fold): cycStart = plt.axvline(j * stimPeriod[0]) cycHalf = plt.axvline((j + 0.5) * stimPeriod[0], linestyle='--') ax.set_xlabel('time (s)') ax.set_ylabel('spike count (normalized by trial)') ax.set_title('PSTH folded') ax.set_xlim( [-stimPeriod[0] / 4.0, (cycle_fold + 0.25) * stimPeriod[0]]) ax.legend((cycStart, cycHalf), ('ph = 0', 'ph = 180')) ##### # plot response phase - without accounting for stimulus phase ##### ax = plt.subplot(3, 2, 5, projection='polar') ax.scatter(np.radians(resp_ph), rel_amp, s=60, color=colors, clip_on=False) ax.set_title('Stimulus-blind') ax.set_ylim(auto='True') polar_ylim = ax.get_ylim() # now, compute the average amplitude/phase over all trials [avg_r, avg_ph, _, _] = hf.polar_vec_mean([rel_amp], [ph_rel_stim]) avg_r = avg_r[0] # just get it out of the array! avg_ph = avg_ph[0] # just get it out of the array! ##### # plot response phase - relative to stimulus phase ##### ax = plt.subplot(3, 2, 6, projection='polar') ax.scatter(np.radians(ph_rel_stim), rel_amp, s=60, color=colors, clip_on=False) ax.plot([0, np.radians(avg_ph)], [0, avg_r], color='k', linestyle='--', clip_on=False) ax.set_ylim(polar_ylim) ax.set_title('Stimulus-accounted') ### MIXTURE STIMULI elif disp > 0: nComp = hf.get_exp_params(expInd).nStimComp # a useful function for swapping inside/outside of nested list... switch_inner_outer = lambda arr: [[x[i] for x in arr] for i in range(len(arr[0]))] ### first, gather the isolated component responses from the mixture val_trials, allDisp, allCons, allSfs = hf.get_valid_trials( data, disp, con, sf, expInd) # outer-most list (for ph_rel_stim, stim_phase, resp_phase) is trial/repetition, inner lists are by component ph_rel_stim, stim_phase, resp_phase, all_tf = hf.get_true_phase( data, val_trials, expInd, dir=dir) # f1all is nComp lists, each with nReps/nTrials values _, _, _, f1all, conByComp, sfByComp = hf.get_isolated_response( data, val_trials) # need to switch ph_rel_stim (and resp_phase) to be lists of phases by component (rather than list of phases by trial) ph_rel_stim = switch_inner_outer(ph_rel_stim) resp_phase = switch_inner_outer(resp_phase) # compute vector means r_comp, th_comp, _, _ = hf.polar_vec_mean(f1all, ph_rel_stim) nrow = 1 + nComp ncol = 2 f, ax = plt.subplots(nrow, ncol, figsize=(ncol * 10, nrow * 10)) # in-mixture response phase - NOT stimulus-aligned; just demonstrate for 1st component colors = cm.rainbow(np.linspace(0, 1, len(val_trials[0]))) ax = plt.subplot( nrow, 1, 1, projection='polar' ) # pretend only one column, i.e. take up whole top row ax.scatter(np.radians(resp_phase[0]), hf.flatten(f1all[0]), s=45, color=colors, clip_on=False) ax.set_ylim([0, 1.1 * np.max(hf.flatten(f1all[0]))]) ax.set_title('Stimulus-blind (compound; comp #1)') for i in range(nComp): # compute the isolated response # Then, pick one of the components and get the response (when presented in isolation) # phases/amplitudes and align relative to the stimulus phase isolConInd = np.where(allCons == conByComp[i])[0][0] # unwrap fully (will be only one value...) isolSfInd = np.where(allSfs == sfByComp[i])[0][0] val_trials_isol, _, _, _ = hf.get_valid_trials(data, disp=0, con=isolConInd, sf=isolSfInd, expInd=expInd) ph_rel_stim_isol, stim_phase_isol, resp_phase_isol, all_tf_isol = hf.get_true_phase( data, val_trials_isol, expInd, dir=dir) stimDur = hf.get_exp_params(expInd).stimDur psth_val, _ = hf.make_psth(data['spikeTimes'][val_trials_isol], stimDur=stimDur) _, rel_amp_isol, _ = hf.spike_fft(psth_val, all_tf_isol, stimDur) # and compute vector mean r_isol, th_isol, _, _ = hf.polar_vec_mean([rel_amp_isol], [ph_rel_stim_isol]) # isolated response phase - relative to stimulus phase colors = cm.rainbow(np.linspace(0, 1, len(val_trials[0]))) ax = plt.subplot(nrow, ncol, 2 * (i + 1) + 1, projection='polar') ax.scatter(np.radians(ph_rel_stim_isol), rel_amp_isol, s=45, color=colors, clip_on=False) ax.plot([0, np.radians(th_isol[0])], [0, r_isol[0]], ls='--', color='k') ax.set_ylim([0, 1.1 * np.max(rel_amp_isol)]) ax.set_title('isolated (r, phi) = (%.2f, %.2f)' % (r_isol[0], th_isol[0])) # in-mixture response phase - relative to stimulus phase colors = cm.rainbow(np.linspace(0, 1, len(val_trials[0]))) ax = plt.subplot(nrow, ncol, 2 * (i + 2), projection='polar') ax.scatter(np.radians(ph_rel_stim[i]), hf.flatten(f1all[i]), s=45, color=colors, clip_on=False) ax.plot([0, np.radians(th_comp[i])], [0, r_comp[i]], ls='--', color='k') ax.set_ylim([0, 1.1 * np.max(rel_amp_isol)]) ax.set_title('compound (r, phi) = (%.2f, %.2f)' % (r_comp[i], th_comp[i])) ## Common to all f.subplots_adjust(wspace=0.2, hspace=0.25) f1f0_ratio = hf.compute_f1f0(data, which_cell, expInd, dp, descrFitName_f0=descrFit_f0)[0] try: # not always exists cell_label = dataList['unitType'][which_cell - 1] except: # always works cell_label = dataList['unitArea'][which_cell - 1] f.suptitle('%s (f1f0: %.2f) #%d: disp %d, con %.2f, sf %.2f' % (cell_label, f1f0_ratio, which_cell, allDisps[disp], allCons[con], allSfs[sf])) saveName = "/cell_%03d_d%dsf%dcon%d_phase.pdf" % (which_cell, disp, sf, con) save_loc = save_base + "cell_%03d/" % which_cell full_save = os.path.dirname(str(save_loc)) if not os.path.exists(full_save): os.makedirs(full_save) pdfSv = pltSave.PdfPages(full_save + saveName) pdfSv.savefig(f) plt.close(f) pdfSv.close()
def plot_phase_advance(which_cell, disp, sv_loc=save_loc, dir=-1, dp=dataPath, expName=expName, phAdvStr=phAdvName, rvcStr=rvcName, date_suffix=''): ''' RVC, resp-X-phase, phase advance model split by SF within each cell/dispersion condition 1. response-versus-contrast; shows original and adjusted response 2. polar plot of response amplitude and phase with phase advance model fit 3. response amplitude (x) vs. phase (y) with the linear phase advance model fit ''' # basics dataList = hf.np_smart_load(str(dp + expName)) cellName = dataList['unitName'][which_cell - 1] expInd = hf.get_exp_ind(dp, cellName)[0] cellStruct = hf.np_smart_load(str(dp + cellName + '_sfm.npy')) rvcFits = hf.np_smart_load(str(dp + hf.phase_fit_name(rvcStr, dir))) rvcFits = rvcFits[which_cell - 1] rvc_model = hf.get_rvc_model() phAdvFits = hf.np_smart_load(str(dp + hf.phase_fit_name(phAdvStr, dir))) phAdvFits = phAdvFits[which_cell - 1] phAdv_model = hf.get_phAdv_model() save_base = sv_loc + 'phasePlots_%s/' % date_suffix # gather/compute everything we need data = cellStruct['sfm']['exp']['trial'] _, stimVals, val_con_by_disp, validByStimVal, _ = hf.tabulate_responses( data, expInd) valDisp = validByStimVal[0] valCon = validByStimVal[1] valSf = validByStimVal[2] allDisps = stimVals[0] allCons = stimVals[1] allSfs = stimVals[2] con_inds = val_con_by_disp[disp] # now get ready to plot fPhaseAdv = [] # we will summarize for all spatial frequencies for a given cell! for j in range(len(allSfs)): # first, get the responses and phases that we need: amps = [] phis = [] sf = j for i in con_inds: val_trials = np.where(valDisp[disp] & valCon[i] & valSf[sf]) # get the phase of the response relative to the stimulus (ph_rel_stim) ph_rel_stim, stim_ph, resp_ph, all_tf = hf.get_true_phase( data, val_trials, expInd, dir=dir) phis.append(ph_rel_stim) # get the relevant amplitudes (i.e. the amplitudes at the stimulus TF) stimDur = hf.get_exp_params(expInd).stimDur psth_val, _ = hf.make_psth(data['spikeTimes'][val_trials], stimDur=stimDur) _, rel_amp, _ = hf.spike_fft(psth_val, all_tf, stimDur=stimDur) amps.append(rel_amp) r, th, _, _ = hf.polar_vec_mean(amps, phis) # mean amp/phase (outputs 1/2); std/var for amp/phase (outputs 3/4) # get the models/fits that we need: con_values = allCons[con_inds] ## phase advance opt_params_phAdv = phAdvFits['params'][sf] ph_adv = phAdvFits['phAdv'][sf] ## rvc opt_params_rvc = rvcFits[disp]['params'][sf] con_gain = rvcFits[disp]['conGain'][sf] adj_means = rvcFits[disp]['adjMeans'][sf] if disp == 1: # then sum adj_means (saved by component) adj_means = [np.sum(x, 1) if x else [] for x in adj_means] # (Above) remember that we have to project the amp/phase vector onto the "correct" phase for estimate of noiseless response ## now get ready to plot! f, ax = plt.subplots(2, 2, figsize=(20, 10)) fPhaseAdv.append(f) n_conds = len(r) colors = cm.viridis(np.linspace(0, 0.95, n_conds)) ##### ## 1. now for plotting: first, response amplitude (with linear contrast) ##### plot_cons = np.linspace(0, 1, 100) mod_fit = rvc_model(opt_params_rvc[0], opt_params_rvc[1], opt_params_rvc[2], plot_cons) ax = plt.subplot(2, 2, 1) plot_amp = adj_means plt_measured = ax.scatter(allCons[con_inds], plot_amp, s=100, color=colors, label='ph. corr') plt_og = ax.plot(allCons[con_inds], r, linestyle='None', marker='o', markeredgecolor='k', markerfacecolor='None', alpha=0.5, label='vec. mean') plt_fit = ax.plot(plot_cons, mod_fit, linestyle='--', color='k', label='rvc fit') ax.set_xlabel('contrast') ax.set_ylabel('response (f1)') ax.set_title('response versus contrast') ax.legend(loc='upper left') # also summarize the model fit on this plot ymax = np.maximum(np.max(r), np.max(mod_fit)) plt.text(0.8, 0.30 * ymax, 'b: %.2f' % (opt_params_rvc[0]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.8, 0.20 * ymax, 'slope:%.2f' % (opt_params_rvc[1]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.8, 0.10 * ymax, 'c0: %.2f' % (opt_params_rvc[2]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.8, 0.0 * ymax, 'con gain: %.2f' % (con_gain), fontsize=12, horizontalalignment='center', verticalalignment='center') ##### ## 3. then the fit/plot of phase as a function of ampltude ##### plot_amps = np.linspace(0, np.max(r), 100) mod_fit = phAdv_model(opt_params_phAdv[0], opt_params_phAdv[1], plot_amps) ax = plt.subplot(2, 1, 2) plt_measured = ax.scatter(r, th, s=100, color=colors, clip_on=False, label='vec. mean') plt_fit = ax.plot(plot_amps, mod_fit, linestyle='--', color='k', clip_on=False, label='phAdv model') ax.set_xlabel('response amplitude') if phAdv_set_ylim: ax.set_ylim([0, 360]) ax.set_ylabel('response phase') ax.set_title('phase advance with amplitude') ax.legend(loc='upper left') ## and again, summarize the model fit on the plot xmax = np.maximum(np.max(r), np.max(plot_amps)) ymin = np.minimum(np.min(th), np.min(mod_fit)) ymax = np.maximum(np.max(th), np.max(mod_fit)) yrange = ymax - ymin if phAdv_set_ylim: if mod_fit[-1] > 260: # then start from ymin and go dwn start, sign = mod_fit[-1] - 30, -1 else: start, sign = mod_fit[-1] + 30, 1 plt.text(0.9 * xmax, start + 1 * 30 * sign, 'phi0: %.2f' % (opt_params_phAdv[0]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.9 * xmax, start + 2 * 30 * sign, 'slope:%.2f' % (opt_params_phAdv[1]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.9 * xmax, start + 3 * 30 * sign, 'phase advance: %.2f ms' % (ph_adv), fontsize=12, horizontalalignment='center', verticalalignment='center') else: plt.text(0.8 * xmax, ymin + 0.25 * yrange, 'phi0: %.2f' % (opt_params_phAdv[0]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.8 * xmax, ymin + 0.15 * yrange, 'slope:%.2f' % (opt_params_phAdv[1]), fontsize=12, horizontalalignment='center', verticalalignment='center') plt.text(0.8 * xmax, ymin + 0.05 * yrange, 'phase advance: %.2f ms' % (ph_adv), fontsize=12, horizontalalignment='center', verticalalignment='center') #center_phi = lambda ph1, ph2: np.arcsin(np.sin(np.deg2rad(ph1) - np.deg2rad(ph2))); ##### ## 2. now the polar plot of resp/phase together ##### ax = plt.subplot(2, 2, 2, projection='polar') th_center = np.rad2deg(np.radians(-90) + np.radians(th[np.argmax(r)])) # "anchor" to the phase at the highest amplitude response #data_centered = center_phi(th, th_center); #model_centered = center_phi(mod_fit, th_center); #ax.scatter(data_centered, r, s=50, color=colors); #ax.plot(model_centered, plot_amps, linestyle='--', color='k'); data_centered = np.mod(th - th_center, 360) model_centered = np.mod(mod_fit - th_center, 360) ax.scatter(np.deg2rad(data_centered), r, s=50, color=colors) ax.plot(np.deg2rad(model_centered), plot_amps, linestyle='--', color='k') ax.set_ylim(0, 1.25 * np.max(r)) ax.set_title('phase advance') # overall title f.subplots_adjust(wspace=0.2, hspace=0.25) f1f0_ratio = hf.compute_f1f0(data, which_cell, expInd, dp, descrFitName_f0=descrFit_f0)[0] try: f.suptitle('%s (%.2f) #%d: disp %d, sf %.2f cpd' % (dataList['unitType'][which_cell - 1], f1f0_ratio, which_cell, allDisps[disp], allSfs[sf])) except: f.suptitle('%s (%.2f) #%d: disp %d, sf %.2f cpd' % (dataList['unitArea'][which_cell - 1], f1f0_ratio, which_cell, allDisps[disp], allSfs[sf])) saveName = "/cell_%03d_d%d_phaseAdv.pdf" % (which_cell, disp) save_loc = save_base + 'summary/' full_save = os.path.dirname(str(save_loc)) if not os.path.exists(full_save): os.makedirs(full_save) pdfSv = pltSave.PdfPages(full_save + saveName) for f in fPhaseAdv: pdfSv.savefig(f) plt.close(f) pdfSv.close()
#save_loc = '/Users/paulgerald/work/sfDiversity/sfDiv-OriModel/sfDiv-python/LGN/analysis/figures/'; # prince cluster dataPath = '/home/pl1465/SF_diversity/LGN/analysis/structures/'; save_loc = '/home/pl1465/SF_diversity/LGN/analysis/figures/'; expName = 'dataList.npy' dataList = hf.np_smart_load(str(dataPath + expName)); loadName = str(dataPath + dataList['unitName'][which_cell-1] + '_sfm.npy'); cellStruct = hf.np_smart_load(loadName); data = cellStruct['sfm']['exp']['trial']; allSpikes = data['spikeTimes']; # Create PSTH, spectrum for all cells psth_all, _ = hf.make_psth(allSpikes, binWidth, stimDur); spect_all, _, _ = hf.spike_fft(psth_all); # now for valid trials (i.e. non-blanks), compute the stimulus-relevant power n_stim_comp = np.max(data['num_comps']); n_tr = len(psth_all); stim_power = np.array(np.nan*np.zeros(n_tr, ), dtype='O'); # object dtype; more flexible val_trials = np.where(~np.isnan(data['tf'][0]))[0]; # nan in TF means a blank all_tfs = np.vstack((data['tf'][0], data['tf'][1], data['tf'][2], data['tf'][3], data['tf'][4])); all_tfs = np.transpose(all_tfs)[val_trials]; all_tfs = all_tfs.astype(int) rel_tfs = [[x[0]] if x[0] == x[1] else x for x in all_tfs]; psth_val, _ = hf.make_psth(allSpikes[val_trials], binWidth, stimDur);
expInfo['trial']['tf'][maskInd, :])[0] baseTf = np.unique( expInfo['trial']['tf'][baseInd, :])[0] cycleDur_mask = 1e3 / maskTf # guaranteed only one TF value cycleDur_base = 1e3 / baseTf # guaranteed only one TF value # get the spikes msTenthToS = 1e-4 # the spike times are in 1/10th ms, so multiply by 1e-4 to convert to S spikeTimes = [ expInfo['spikeTimes'][trNum] * msTenthToS for trNum in val_trials ] # -- compute PSTH psth, bins = hf.make_psth(spikeTimes, stimDur=stimDur) # -- compute FFT (manual), then start to unpack - [matrix, coeffs, spectrum, amplitudes] man_fft = [ hf.manual_fft(psth_curr, tfs=np.array([ int(np.unique(maskTf)), int(np.unique(baseTf)) ]), onsetTransient=onsetTransient, stimDur=stimDur) for psth_curr in psth ] man_fft_noTransient = [ hf.manual_fft(psth_curr, tfs=np.array([ int(np.unique(maskTf)),
def get_vec_avg_response(expInfo, val_trials, dir=1, psth_binWidth=1e-3, stimDur=1, onsetTransient=None, refPhi=None): ''' Return [r_mean, phi_mean, r_std, phi_var], [resp_amp, phase_rel_stim], rel_amps, phase_rel_stim, stimPhs, resp_phase -- Note that the above values are at mask/base TF, respectively (i.e. not DC) If onsetTransient is not None, we'll do the manual FFT Given the data and the set of valid trials, first compute the response phase and stimulus phase - then determine the response phase relative to the stimulus phase ''' # organize the spikes msTenthToS = 1e-4 # the spike times are in 1/10th ms, so multiply by 1e-4 to convert to S spikeTimes = [ expInfo['spikeTimes'][trNum] * msTenthToS for trNum in val_trials ] # -- get stimulus info byTrial = expInfo['trial'] maskInd, baseInd = get_mask_base_inds() baseTf, maskTf = byTrial['tf'][baseInd, val_trials], byTrial['tf'][maskInd, val_trials] basePh, maskPh = byTrial['ph'][baseInd, val_trials], byTrial['ph'][maskInd, val_trials] baseSf, maskSf = byTrial['sf'][baseInd, val_trials], byTrial['sf'][maskInd, val_trials] baseCon, maskCon = byTrial['con'][baseInd, val_trials], byTrial['con'][maskInd, val_trials] # -- compute PSTH psth, bins = hf.make_psth(spikeTimes, stimDur=stimDur) tfAsInts = np.zeros((len(val_trials), 2), dtype='int32') tfAsInts[:, maskInd] = maskTf tfAsInts[:, baseInd] = baseTf if onsetTransient is None: # then just do this normally... amps, rel_amps, full_fourier = hf.spike_fft(psth, tfs=tfAsInts, stimDur=stimDur) # get the phase of the response resp_phase = np.array([ np.angle(full_fourier[x][tfAsInts[x, :]], True) for x in range(len(full_fourier)) ]) # true --> in degrees resp_amp = np.array( [amps[tfAsInts[ind, :]] for ind, amps in enumerate(amps)]) # after correction of amps (19.08.06) else: man_fft = [ hf.manual_fft(psth_curr, tfs=np.array( [int(np.unique(maskTf)), int(np.unique(baseTf))]), onsetTransient=onsetTransient, stimDur=stimDur) for psth_curr in psth ] # -- why [2]? That's the full spectrum; then [1:] is to get mask,base resp_phases respectively // [0] is DC resp_phase = np.squeeze( np.array([np.angle(curr_fft[2][1:], True) for curr_fft in man_fft])) # true --> in degrees # -- why [3]? That's the array of amplitudes; then [1:] is to get mask,base respectively // [0] is DC resp_amp = np.squeeze( np.array([curr_fft[3][1:] for curr_fft in man_fft])) # true --> in degrees rel_amps = np.copy(resp_amp) # they're the same... stimPhs = np.zeros_like(resp_amp) try: stimPhs[:, maskInd] = maskPh stimPhs[:, baseInd] = basePh except: # why would this happen? If we passed in val_trials for "subset of the data analysis" and this condition is empty... pass phase_rel_stim = np.mod(np.multiply(dir, np.add(resp_phase, stimPhs)), 360) r_mean, phi_mean, r_sem, phi_var = hf.polar_vec_mean( np.transpose(resp_amp), np.transpose(phase_rel_stim), sem=1) # return s.e.m. rather than std (default) if refPhi is not None: # then do the phase projection here! TODO: CHECK IF PHI_MEAN/refPhi in deg or rad r_mean = np.multiply(r_mean, np.cos(np.deg2rad(refPhi) - np.deg2rad(phi_mean))) return [r_mean, phi_mean, r_sem, phi_var], [resp_amp, phase_rel_stim ], rel_amps, phase_rel_stim, stimPhs, resp_phase