def plot_psd(datas, cs=None, ylims=None, titlestr=''): f = figure(figsize=figsize) for data, c in zip(datas, cs): data = filter.notch(data)[ 0] # remove 60 Hz mains noise, as for SI calc # convert data from uV to mV. I think P is in mV^2?: P, freqs = mpl.mlab.psd(data / 1e3, NFFT=NFFT, Fs=SAMPFREQ, noverlap=NOVERLAP) # keep only freqs between F0 and F1: f0, f1 = F0, F1 # need to set different local names, since they're not read-only if f0 == None: f0 = freqs[0] if f1 == None: f1 = freqs[-1] lo, hi = freqs.searchsorted([f0, f1]) P, freqs = P[lo:hi], freqs[lo:hi] # check for and replace zero power values (ostensibly due to gaps in recording) # before attempting to convert to dB: zis = np.where( P == 0.0) # row and column indices where P has zero power if len(zis[0]) > 0: # at least one hit P[zis] = np.finfo( np.float64).max # temporarily replace zeros with max float minnzval = P.min() # get minimum nonzero value P[zis] = minnzval # replace with min nonzero values P = 10. * np.log10(P) # convert power to dB wrt 1 mV^2? # for better visualization, clip power values to within (P0, P1) dB if P0 != None: P[P < P0] = P0 if P1 != None: P[P > P1] = P1 plot(freqs, P, c=c, ls='-', marker=None) # demarcate SI power ratio frequency bands with horizontal lines: hlines(y=-50, xmin=LFPPRLOBAND[0], xmax=LFPPRLOBAND[1], colors='e', linestyles='-', lw=5) hlines(y=-30, xmin=LFPPRHIBAND[0], xmax=LFPPRHIBAND[1], colors='e', linestyles='-', lw=5) axis('tight') xscale(XSCALE) ylim(ylims) xlabel("frequency (Hz)") ylabel("power (dB)") gcfm().window.setWindowTitle(titlestr + ' ' + XSCALE) f.tight_layout(pad=0.3) # crop figure to contents
def notch(self, chanis=None, freq=60, bw=0.25, gpass=0.01, gstop=30, ftype='ellip'): """Filter out frequencies centered on freq (Hz), of bandwidth +/- bw (Hz) on data row indices chanis, in-place. ftype: 'ellip', 'butter', 'cheby1', 'cheby2', 'bessel' """ data = self.get_data() if chanis == None: chanis = np.arange(len(data)) data = data[chanis] data, b, a = filter.notch(data, self.sampfreq, freq, bw, gpass, gstop, ftype) self.data[chanis] = data return b, a
def plot_psd(data, titlestr): data = filter.notch(data)[0] # remove 60 Hz mains noise, as for SI calc # convert data from uV to mV. I think P is in mV^2?: P, freqs = mpl.mlab.psd(data/1e3, NFFT=NFFT, Fs=SAMPFREQ, noverlap=NOVERLAP) # keep only freqs between F0 and F1: f0, f1 = F0, F1 # need to set different local names, since they're not read-only if f0 == None: f0 = freqs[0] if f1 == None: f1 = freqs[-1] lo, hi = freqs.searchsorted([f0, f1]) P, freqs = P[lo:hi], freqs[lo:hi] # check for and replace zero power values (ostensibly due to gaps in recording) # before attempting to convert to dB: zis = np.where(P == 0.0) # row and column indices where P has zero power if len(zis[0]) > 0: # at least one hit P[zis] = np.finfo(np.float64).max # temporarily replace zeros with max float minnzval = P.min() # get minimum nonzero value P[zis] = minnzval # replace with min nonzero values P = 10. * np.log10(P) # convert power to dB wrt 1 mV^2? # for better visualization, clip power values to within (P0, P1) dB if P0 != None: P[P < P0] = P0 if P1 != None: P[P > P1] = P1 f = pl.figure(figsize=figsize) a = f.add_subplot(111) a.plot(freqs, P, 'k-') # add SI frequency band limits: a.axvline(x=LFPSILOWBAND[0], c='r', ls='--') a.axvline(x=LFPSILOWBAND[1], c='r', ls='--') a.axvline(x=LFPSIHIGHBAND[0], c='b', ls='--') a.axvline(x=LFPSIHIGHBAND[1], c='b', ls='--') a.axis('tight') a.set_xscale(XSCALE) a.set_ylim(ymin=P[-1]) # use last power value to set ymin a.set_xlabel("frequency (Hz)") a.set_ylabel("power (dB)") gcfm().window.setWindowTitle(titlestr+' '+XSCALE) f.tight_layout(pad=0.3) # crop figure to contents
def plot_psd(datas, cs=None, ylims=None, titlestr=''): f = figure(figsize=figsize) for data, c in zip(datas, cs): data = filter.notch(data)[0] # remove 60 Hz mains noise, as for SI calc # convert data from uV to mV. I think P is in mV^2?: P, freqs = mpl.mlab.psd(data/1e3, NFFT=NFFT, Fs=SAMPFREQ, noverlap=NOVERLAP) # keep only freqs between F0 and F1: f0, f1 = F0, F1 # need to set different local names, since they're not read-only if f0 == None: f0 = freqs[0] if f1 == None: f1 = freqs[-1] lo, hi = freqs.searchsorted([f0, f1]) P, freqs = P[lo:hi], freqs[lo:hi] # check for and replace zero power values (ostensibly due to gaps in recording) # before attempting to convert to dB: zis = np.where(P == 0.0) # row and column indices where P has zero power if len(zis[0]) > 0: # at least one hit P[zis] = np.finfo(np.float64).max # temporarily replace zeros with max float minnzval = P.min() # get minimum nonzero value P[zis] = minnzval # replace with min nonzero values P = 10. * np.log10(P) # convert power to dB wrt 1 mV^2? # for better visualization, clip power values to within (P0, P1) dB if P0 != None: P[P < P0] = P0 if P1 != None: P[P > P1] = P1 plot(freqs, P, c=c, ls='-', marker=None) # demarcate SI frequency bands with horizontal lines: hlines(y=-50, xmin=LFPSILOWBAND[0], xmax=LFPSILOWBAND[1], colors='e', linestyles='-', lw=5) hlines(y=-30, xmin=LFPSIHIGHBAND[0], xmax=LFPSIHIGHBAND[1], colors='e', linestyles='-', lw=5) axis('tight') xscale(XSCALE) ylim(ylims) xlabel("frequency (Hz)") ylabel("power (dB)") gcfm().window.setWindowTitle(titlestr+' '+XSCALE) f.tight_layout(pad=0.3) # crop figure to contents
def si(self, kind=None, chani=-1, width=None, tres=None, lfpwidth=None, lfptres=None, loband=None, hiband=None, plot=True, showstates='auto', statelinepos=[0.2], lw=4, alpha=1, relative2t0=False, lim2stim=False, showxlabel=True, showylabel=True, showtitle=True, title=None, reclabel=True, swapaxes=False, figsize=None): """Calculate an LFP synchrony index, using potentially overlapping windows of width and tres, in sec, from the LFP spectrogram, itself composed of bins of lfpwidth and lfptres. relative2t0 controls whether to plot relative to t0, or relative to start of ADC clock. lim2stim limits the time range only to when a stimulus was presented, i.e. to the outermost times of non-NULL din. Note that for power ratio methods (kind: L/(L+H) or L/H), width and tres are not used, only lfpwidth and lfptres. Options for kind are: 'L/(L+H)': fraction of power in low band vs total power (Saleem2010) 'L/H': low to highband power ratio (Li, Poo, Dan 2009) 'cv': coefficient of variation (std / mean) of all power 'ncv': normalized CV: (std - mean) / (std + mean) 'nstdmed': normalized stdmed: (std - med) / (std + med) 'n2stdmean': normalized 2stdmean: (2*std - mean) / (2*std + mean) 'n3stdmean': normalized 3stdmean: (3*std - mean) / (3*std + mean) """ uns = get_ipython().user_ns if kind == None: kind = uns['LFPSIKIND'] if kind in ['L/(L+H)', 'L/H', 'nLH']: # it's a power ratio measure pr = True else: pr = False data = self.get_data() ts = self.get_tssec() # full set of timestamps, in sec t0, t1 = ts[0], ts[-1] if lim2stim: t0, t1 = self.apply_lim2stim(t0, t1) dt = t1 - t0 if figsize == None: # convert from recording duration time to width in inches, 0.87 accommodates # padding around the SI plot: figwidth = (dt / 1000) * 5 + 0.87 figheight = 2.5 # inches figsize = figwidth, figheight t0i, t1i = ts.searchsorted((t0, t1)) x = data[chani, t0i:t1i] / 1e3 # slice data, convert from uV to mV x = filter.notch(x)[0] # remove 60 Hz mains noise try: rr = self.r.e0.I['REFRESHRATE'] except AttributeError: # probably a recording with no experiment rr = 200 # assume 200 Hz refresh rate if rr <= 100: # CRT was at low vertical refresh rate print('filtering out %d Hz from LFP in %s' % (intround(rr), self.r.name)) x = filter.notch(x, freq=rr)[0] # remove CRT interference if width == None: width = uns['LFPSIWIDTH'] # sec if tres == None: tres = uns['LFPSITRES'] # sec if lfpwidth == None: lfpwidth = uns['LFPPRWIDTH'] if pr else uns['LFPSPECGRAMWIDTH'] # sec if lfptres == None: lfptres = uns['LFPPRTRES'] if pr else uns['LFPSPECGRAMTRES'] # sec if loband == None: loband = uns['LFPPRLOBAND'] f0, f1 = loband if hiband == None: hiband = uns['LFPPRHIBAND'] f2, f3 = hiband assert lfptres <= lfpwidth NFFT = intround(lfpwidth * self.sampfreq) noverlap = intround(NFFT - lfptres * self.sampfreq) #print('len(x), NFFT, noverlap: %d, %d, %d' % (len(x), NFFT, noverlap)) # t is midpoints of timebins in sec from start of data. P is in mV^2?: P, freqs, Pt = mpl.mlab.specgram(x, NFFT=NFFT, Fs=self.sampfreq, noverlap=noverlap) # don't convert power to dB, just washes out the signal in the ratio: #P = 10. * np.log10(P) if not relative2t0: Pt += t0 # convert t to time from start of ADC clock: nfreqs = len(freqs) # keep only freqs between f0 and f1, and f2 and f3: f0i, f1i, f2i, f3i = freqs.searchsorted([f0, f1, f2, f3]) lP = P[f0i:f1i] # nsubfreqs x nt hP = P[f2i:f3i] # nsubfreqs x nt lP = lP.sum(axis=0) # nt hP = hP.sum(axis=0) # nt if pr: t = Pt ylabel = 'SI (%s)' % kind else: # potentially overlapping bin time ranges: trange = Pt[0], Pt[-1] tranges = split_tranges([trange], width, tres) # in sec ntranges = len(tranges) tis = Pt.searchsorted(tranges) # ntranges x 2 array # number of timepoints to use for each trange, almost all will be the same width: binnt = intround((tis[:, 1] - tis[:, 0]).mean()) binhP = np.zeros((ntranges, binnt)) # init appropriate array for trangei, t0i in enumerate(tis[:, 0]): binhP[trangei] = hP[t0i:t0i+binnt] # get midpoint of each trange: t = tranges.mean(axis=1) #old_settings = np.seterr(all='ignore') # suppress div by 0 errors # plot power signal to be analyzed #self.si_plot(hP, Pt, t0=0, t1=t[-1], ylim=None, ylabel='highband power', # title=lastcmd()+' highband power', text=self.r.name) # set some plotting defaults: hlines = [] if pr: ylim = 0, 1 yticks = 0, 0.2, 0.4, 0.6, 0.8, 1 else: ylim = -1, 1 yticks = -1, 0, 1 hlines = [0] # calculate some metric of each column, i.e. each bin: if kind == 'L/(L+H)': si = lP/(lP + hP) elif kind == 'L/H': si = lP/hP elif kind == 'nLH': t = Pt si = (lP - hP) / (lP + hP) ylabel = 'LFP (L - H) / (L + H)' elif kind == 'cv': si = binhP.std(axis=1) / binhP.mean(axis=1) ylim = 0, 2 ytiks = 0, 1, 2 ylabel = 'LFP power CV' elif kind == 'ncv': s = binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s - mean) / (s + mean) ylabel = 'LFP power (std - mean) / (std + mean)' #pl.plot(t, s) #pl.plot(t, mean) elif kind == 'n2stdmean': s2 = 2 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s2 - mean) / (s2 + mean) ylabel = 'LFP power (2*std - mean) / (2*std + mean)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s2) #pl.plot(t, mean) elif kind == 'n3stdmean': s3 = 3 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s3 - mean) / (s3 + mean) ylabel = 'LFP power (3*std - mean) / (3*std + mean)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s3) #pl.plot(t, mean) elif kind == 'n4stdmean': s4 = 4 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s4 - mean) / (s4 + mean) ylabel = 'LFP power (4*std - mean) / (4*std + mean)' #pl.plot(t, s4) #pl.plot(t, mean) elif kind == 'nstdmed': s = binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s - med) / (s + med) ylabel = 'LFP power (std - med) / (std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s) #pl.plot(t, med) elif kind == 'n2stdmed': s2 = 2 * binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s2 - med) / (s2 + med) ylabel = 'LFP power (2*std - med) / (2*std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s2) #pl.plot(t, med) elif kind == 'n3stdmed': s3 = 3 * binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s3 - med) / (s3 + med) ylabel = 'LFP power (3*std - med) / (3*std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s3) #pl.plot(t, med) elif kind == 'nstdmin': s = binhP.std(axis=1) min = binhP.min(axis=1) si = (s - min) / (s + min) ylabel = 'LFP power (std - min) / (std + min)' #pl.plot(t, s) #pl.plot(t, min) elif kind == 'nmadmean': mean = binhP.mean(axis=1) mad = (np.abs(binhP - mean[:, None])).mean(axis=1) si = (mad - mean) / (mad + mean) ylabel = 'MUA (MAD - mean) / (MAD + mean)' #pl.plot(t, mad) #pl.plot(t, mean) elif kind == 'nmadmed': med = np.median(binhP, axis=1) mad = (np.abs(binhP - med[:, None])).mean(axis=1) si = (mad - med) / (mad + med) ylabel = 'MUA (MAD - median) / (MAD + median)' #pl.plot(t, mad) #pl.plot(t, med) elif kind == 'nvarmin': v = binhP.var(axis=1) min = binhP.min(axis=1) si = (v - min) / (v + min) ylabel = 'LFP power (std - min) / (std + min)' #pl.plot(t, v) #pl.plot(t, min) elif kind == 'nptpmean': ptp = binhP.ptp(axis=1) mean = binhP.mean(axis=1) si = (ptp - mean) / (ptp + mean) ylabel = 'MUA (ptp - mean) / (ptp + mean)' #pl.plot(t, ptp) #pl.plot(t, mean) elif kind == 'nptpmed': ptp = binhP.ptp(axis=1) med = np.median(binhP, axis=1) si = (ptp - med) / (ptp + med) ylabel = 'MUA (ptp - med) / (ptp + med)' #pl.plot(t, ptp) #pl.plot(t, med) elif kind == 'nptpmin': ptp = binhP.ptp(axis=1) min = binhP.min(axis=1) si = (ptp - min) / (ptp + min) ylabel = 'MUA (ptp - min) / (ptp + min)' #pl.plot(t, ptp) #pl.plot(t, min) elif kind == 'nmaxmin': max = binhP.max(axis=1) min = binhP.min(axis=1) si = (max - min) / (max + min) ylabel = 'MUA (max - min) / (max + min)' #pl.plot(t, max) #pl.plot(t, min) else: raise ValueError('unknown kind %r' % kind) if plot: # calculate xlim, always start from 0, add half a bin width to xmax: if pr: xlim = (0, t[-1]+lfpwidth/2) else: xlim = (0, t[-1]+width/2) self.si_plot(si, t, t0=t0, t1=t1, xlim=xlim, ylim=ylim, yticks=yticks, ylabel=ylabel, showxlabel=showxlabel, showylabel=showylabel, showtitle=showtitle, title=title, reclabel=reclabel, hlines=hlines, showstates=showstates, statelinepos=statelinepos, lw=lw, alpha=alpha, swapaxes=swapaxes, figsize=figsize) #np.seterr(**old_settings) # restore old settings return si, t # t are midpoints of bins, offset depends on relative2t0
def si(self, kind=None, chani=-1, width=None, tres=None, lfpwidth=None, lfptres=None, loband=None, hiband=None, plot=True, showstates='auto', statelinepos=[0.2], lw=4, alpha=1, relative2t0=False, lim2stim=False, showxlabel=True, showylabel=True, showtitle=True, title=None, reclabel=True, swapaxes=False, figsize=None): """Calculate an LFP synchrony index, using potentially overlapping windows of width and tres, in sec, from the LFP spectrogram, itself composed of bins of lfpwidth and lfptres. relative2t0 controls whether to plot relative to t0, or relative to start of ADC clock. lim2stim limits the time range only to when a stimulus was presented, i.e. to the outermost times of non-NULL din. Note that for power ratio methods (kind: L/(L+H) or L/H), width and tres are not used, only lfpwidth and lfptres. Options for kind are: 'L/(L+H)': fraction of power in low band vs total power (Saleem2010) 'L/H': low to highband power ratio (Li, Poo, Dan 2009) 'cv': coefficient of variation (std / mean) of all power 'ncv': normalized CV: (std - mean) / (std + mean) 'nstdmed': normalized stdmed: (std - med) / (std + med) 'n2stdmean': normalized 2stdmean: (2*std - mean) / (2*std + mean) 'n3stdmean': normalized 3stdmean: (3*std - mean) / (3*std + mean) """ uns = get_ipython().user_ns if kind == None: kind = uns['LFPSIKIND'] if kind in ['L/(L+H)', 'L/H', 'nLH']: # it's a power ratio measure pr = True else: pr = False data = self.get_data() ts = self.get_tssec() # full set of timestamps, in sec t0, t1 = ts[0], ts[-1] if lim2stim: t0, t1 = self.apply_lim2stim(t0, t1) dt = t1 - t0 if figsize == None: # convert from recording duration time to width in inches, 0.87 accommodates # padding around the SI plot: figwidth = (dt / 1000) * 5 + 0.87 figheight = 2.5 # inches figsize = figwidth, figheight t0i, t1i = ts.searchsorted((t0, t1)) x = data[chani, t0i:t1i] / 1e3 # slice data, convert from uV to mV x = filter.notch(x)[0] # remove 60 Hz mains noise try: rr = self.r.e0.I['REFRESHRATE'] except AttributeError: # probably a recording with no experiment rr = 200 # assume 200 Hz refresh rate if rr <= 100: # CRT was at low vertical refresh rate print('filtering out %d Hz from LFP in %s' % (intround(rr), self.r.name)) x = filter.notch(x, freq=rr)[0] # remove CRT interference if width == None: width = uns['LFPSIWIDTH'] # sec if tres == None: tres = uns['LFPSITRES'] # sec if lfpwidth == None: lfpwidth = uns['LFPPRWIDTH'] if pr else uns[ 'LFPSPECGRAMWIDTH'] # sec if lfptres == None: lfptres = uns['LFPPRTRES'] if pr else uns['LFPSPECGRAMTRES'] # sec if loband == None: loband = uns['LFPPRLOBAND'] f0, f1 = loband if hiband == None: hiband = uns['LFPPRHIBAND'] f2, f3 = hiband assert lfptres <= lfpwidth NFFT = intround(lfpwidth * self.sampfreq) noverlap = intround(NFFT - lfptres * self.sampfreq) #print('len(x), NFFT, noverlap: %d, %d, %d' % (len(x), NFFT, noverlap)) # t is midpoints of timebins in sec from start of data. P is in mV^2?: P, freqs, Pt = mpl.mlab.specgram(x, NFFT=NFFT, Fs=self.sampfreq, noverlap=noverlap) # don't convert power to dB, just washes out the signal in the ratio: #P = 10. * np.log10(P) if not relative2t0: Pt += t0 # convert t to time from start of ADC clock: nfreqs = len(freqs) # keep only freqs between f0 and f1, and f2 and f3: f0i, f1i, f2i, f3i = freqs.searchsorted([f0, f1, f2, f3]) lP = P[f0i:f1i] # nsubfreqs x nt hP = P[f2i:f3i] # nsubfreqs x nt lP = lP.sum(axis=0) # nt hP = hP.sum(axis=0) # nt if pr: t = Pt ylabel = 'SI (%s)' % kind else: # potentially overlapping bin time ranges: trange = Pt[0], Pt[-1] tranges = split_tranges([trange], width, tres) # in sec ntranges = len(tranges) tis = Pt.searchsorted(tranges) # ntranges x 2 array # number of timepoints to use for each trange, almost all will be the same width: binnt = intround((tis[:, 1] - tis[:, 0]).mean()) binhP = np.zeros((ntranges, binnt)) # init appropriate array for trangei, t0i in enumerate(tis[:, 0]): binhP[trangei] = hP[t0i:t0i + binnt] # get midpoint of each trange: t = tranges.mean(axis=1) #old_settings = np.seterr(all='ignore') # suppress div by 0 errors # plot power signal to be analyzed #self.si_plot(hP, Pt, t0=0, t1=t[-1], ylim=None, ylabel='highband power', # title=lastcmd()+' highband power', text=self.r.name) # set some plotting defaults: hlines = [] if pr: ylim = 0, 1 yticks = 0, 0.2, 0.4, 0.6, 0.8, 1 else: ylim = -1, 1 yticks = -1, 0, 1 hlines = [0] # calculate some metric of each column, i.e. each bin: if kind == 'L/(L+H)': si = lP / (lP + hP) elif kind == 'L/H': si = lP / hP elif kind == 'nLH': t = Pt si = (lP - hP) / (lP + hP) ylabel = 'LFP (L - H) / (L + H)' elif kind == 'cv': si = binhP.std(axis=1) / binhP.mean(axis=1) ylim = 0, 2 ytiks = 0, 1, 2 ylabel = 'LFP power CV' elif kind == 'ncv': s = binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s - mean) / (s + mean) ylabel = 'LFP power (std - mean) / (std + mean)' #pl.plot(t, s) #pl.plot(t, mean) elif kind == 'n2stdmean': s2 = 2 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s2 - mean) / (s2 + mean) ylabel = 'LFP power (2*std - mean) / (2*std + mean)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s2) #pl.plot(t, mean) elif kind == 'n3stdmean': s3 = 3 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s3 - mean) / (s3 + mean) ylabel = 'LFP power (3*std - mean) / (3*std + mean)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s3) #pl.plot(t, mean) elif kind == 'n4stdmean': s4 = 4 * binhP.std(axis=1) mean = binhP.mean(axis=1) si = (s4 - mean) / (s4 + mean) ylabel = 'LFP power (4*std - mean) / (4*std + mean)' #pl.plot(t, s4) #pl.plot(t, mean) elif kind == 'nstdmed': s = binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s - med) / (s + med) ylabel = 'LFP power (std - med) / (std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s) #pl.plot(t, med) elif kind == 'n2stdmed': s2 = 2 * binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s2 - med) / (s2 + med) ylabel = 'LFP power (2*std - med) / (2*std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s2) #pl.plot(t, med) elif kind == 'n3stdmed': s3 = 3 * binhP.std(axis=1) med = np.median(binhP, axis=1) si = (s3 - med) / (s3 + med) ylabel = 'LFP power (3*std - med) / (3*std + med)' hlines = [-0.1, 0, 0.1] # demarcate desynched and synched thresholds #pl.plot(t, s3) #pl.plot(t, med) elif kind == 'nstdmin': s = binhP.std(axis=1) min = binhP.min(axis=1) si = (s - min) / (s + min) ylabel = 'LFP power (std - min) / (std + min)' #pl.plot(t, s) #pl.plot(t, min) elif kind == 'nmadmean': mean = binhP.mean(axis=1) mad = (np.abs(binhP - mean[:, None])).mean(axis=1) si = (mad - mean) / (mad + mean) ylabel = 'MUA (MAD - mean) / (MAD + mean)' #pl.plot(t, mad) #pl.plot(t, mean) elif kind == 'nmadmed': med = np.median(binhP, axis=1) mad = (np.abs(binhP - med[:, None])).mean(axis=1) si = (mad - med) / (mad + med) ylabel = 'MUA (MAD - median) / (MAD + median)' #pl.plot(t, mad) #pl.plot(t, med) elif kind == 'nvarmin': v = binhP.var(axis=1) min = binhP.min(axis=1) si = (v - min) / (v + min) ylabel = 'LFP power (std - min) / (std + min)' #pl.plot(t, v) #pl.plot(t, min) elif kind == 'nptpmean': ptp = binhP.ptp(axis=1) mean = binhP.mean(axis=1) si = (ptp - mean) / (ptp + mean) ylabel = 'MUA (ptp - mean) / (ptp + mean)' #pl.plot(t, ptp) #pl.plot(t, mean) elif kind == 'nptpmed': ptp = binhP.ptp(axis=1) med = np.median(binhP, axis=1) si = (ptp - med) / (ptp + med) ylabel = 'MUA (ptp - med) / (ptp + med)' #pl.plot(t, ptp) #pl.plot(t, med) elif kind == 'nptpmin': ptp = binhP.ptp(axis=1) min = binhP.min(axis=1) si = (ptp - min) / (ptp + min) ylabel = 'MUA (ptp - min) / (ptp + min)' #pl.plot(t, ptp) #pl.plot(t, min) elif kind == 'nmaxmin': max = binhP.max(axis=1) min = binhP.min(axis=1) si = (max - min) / (max + min) ylabel = 'MUA (max - min) / (max + min)' #pl.plot(t, max) #pl.plot(t, min) else: raise ValueError('unknown kind %r' % kind) if plot: # calculate xlim, always start from 0, add half a bin width to xmax: if pr: xlim = (0, t[-1] + lfpwidth / 2) else: xlim = (0, t[-1] + width / 2) self.si_plot(si, t, t0=t0, t1=t1, xlim=xlim, ylim=ylim, yticks=yticks, ylabel=ylabel, showxlabel=showxlabel, showylabel=showylabel, showtitle=showtitle, title=title, reclabel=reclabel, hlines=hlines, showstates=showstates, statelinepos=statelinepos, lw=lw, alpha=alpha, swapaxes=swapaxes, figsize=figsize) #np.seterr(**old_settings) # restore old settings return si, t # t are midpoints of bins, offset depends on relative2t0