def apodization(mzs, intensities, w_size=10): import scipy.signal as signal win = signal.hann(w_size) win = signal.slepian(w_size, 0.3) intensities = signal.fftconvolve(intensities, win, mode='same') / sum(win) intensities[intensities < 1e-6] = 0 return intensities
def apodization(mzs,intensities,w_size=10): import scipy.signal as signal win = signal.hann(w_size) win = signal.slepian(w_size,0.3) intensities = signal.fftconvolve(intensities, win, mode='same') / sum(win) intensities[intensities<1e-6]=0 return intensities
def update_descriptors(self): if not self.kernel_type: raise ValueError("Integrator was passed kernel None") logger.debug( 'Updating WindowIntegrator "%s" descriptors based on input descriptor: %s.', self.name, self.sink.descriptor) record_length = self.sink.descriptor.axes[-1].num_points() time_pts = self.sink.descriptor.axes[-1].points time_step = time_pts[1] - time_pts[0] kernel = np.zeros(record_length, dtype=np.complex128) sample_start = int(self.box_car_start.value / time_step) sample_stop = int(self.box_car_stop.value / time_step) + 1 if self.kernel_type == 'boxcar': kernel[sample_start:sample_stop] = 1.0 elif self.kernel_type == 'chebwin': # create a Dolph-Chebyshev window with 100 dB attenuation kernel[sample_start:sample_stop] = \ chebwin(sample_start-sample_stop, at=100) elif self.kernel_type == 'blackman': kernel[sample_start:sample_stop] = \ blackman(sample_start-sample_stop) elif self.kernel_type == 'slepian': # create a Slepian window with 0.2 bandwidth kernel[sample_start:sample_stop] = \ slepian(sample_start-sample_stop, width=0.2) # add modulation kernel *= np.exp(2j * np.pi * self.frequency.value * time_step * time_pts) # pad or truncate the kernel to match the record length if kernel.size < record_length: self.aligned_kernel = np.append( kernel, np.zeros(record_length - kernel.size, dtype=np.complex128)) else: self.aligned_kernel = np.resize(kernel, record_length) # Integrator reduces and removes axis on output stream # update output descriptors output_descriptor = DataStreamDescriptor() # TODO: handle reduction to single point output_descriptor.axes = self.sink.descriptor.axes[:-1] output_descriptor._exp_src = self.sink.descriptor._exp_src output_descriptor.dtype = np.complex128 for os in self.source.output_streams: os.set_descriptor(output_descriptor) os.end_connector.update_descriptors()
def apodization(mzs, intensities, w_size=10): """ apodization with slepian window :param mzs: numpy array numpy array of mz values :param counts: numpy array numpy array of values to smooth :param w_size: int window size :return: mzs: numpy array :return: counts: numpy array """ import scipy.signal as signal win = signal.hann(w_size) win = signal.slepian(w_size, 0.3) intensities = signal.fftconvolve(intensities, win, mode='same') / sum(win) intensities[intensities < 1e-6] = 0 return mzs, intensities
def slepian(N, tau, N_MAX=1000): """ return the slepian window of size N with main lobe end at +/- tau the result is normalized by its mean. """ ## NOTES ## MemoryError si N grand ## signal.slepian is bugged and need a factor 2 on its second arg ## the factor 4 is here to get the half band width ## scipy 1.1 introduce signal.windows.dpss which is more standard if N <= N_MAX: res = signal.slepian(N, (4./N) * tau) # factor 2 pour coller a la definition +/- tau res /= res.mean() else: a = float(N) / float(N_MAX) ref = slepian(N_MAX, tau) res = np.interp(np.arange(N), a * np.arange(N_MAX), ref) return res
def show_old_vs_new( args: Namespace, name: str, start_date: int, end_date: int, people: List[str], days: Dict[int, Dict[int, DevDay]], ) -> None: from scipy.signal import convolve, slepian start_date = datetime.fromtimestamp(start_date) start_date = datetime(start_date.year, start_date.month, start_date.day) end_date = datetime.fromtimestamp(end_date) end_date = datetime(end_date.year, end_date.month, end_date.day) new_lines = numpy.zeros((end_date - start_date).days + 2) old_lines = numpy.zeros_like(new_lines) for day, devs in days.items(): for stats in devs.values(): new_lines[day] += stats.Added old_lines[day] += stats.Removed + stats.Changed resolution = 32 window = slepian(max(len(new_lines) // resolution, 1), 0.5) new_lines = convolve(new_lines, window, "same") old_lines = convolve(old_lines, window, "same") matplotlib, pyplot = import_pyplot(args.backend, args.style) plot_x = [start_date + timedelta(days=i) for i in range(len(new_lines))] pyplot.fill_between(plot_x, new_lines, color="#8DB843", label="Changed new lines") pyplot.fill_between( plot_x, old_lines, color="#E14C35", label="Changed existing lines" ) pyplot.legend(loc=2, fontsize=args.font_size) for tick in chain( pyplot.gca().xaxis.get_major_ticks(), pyplot.gca().yaxis.get_major_ticks() ): tick.label.set_fontsize(args.font_size) if args.mode == "all" and args.output: output = get_plot_path(args.output, "old_vs_new") else: output = args.output deploy_plot("Additions vs changes", output, args.background)
# Plot the window and its frequency response: from scipy import signal from scipy.fftpack import fft, fftshift import matplotlib.pyplot as plt window = signal.slepian(51, width=0.3) plt.plot(window) plt.title("Slepian (DPSS) window (BW=0.3)") plt.ylabel("Amplitude") plt.xlabel("Sample") plt.figure() A = fft(window, 2048) / (len(window)/2.0) freq = np.linspace(-0.5, 0.5, len(A)) response = 20 * np.log10(np.abs(fftshift(A / abs(A).max()))) plt.plot(freq, response) plt.axis([-0.5, 0.5, -120, 0]) plt.title("Frequency response of the Slepian window (BW=0.3)") plt.ylabel("Normalized magnitude [dB]") plt.xlabel("Normalized frequency [cycles per sample]")
def show_devs_efforts( args: Namespace, name: str, start_date: int, end_date: int, people: List[str], days: Dict[int, Dict[int, DevDay]], max_people: int, ) -> None: from scipy.signal import convolve, slepian start_date = datetime.fromtimestamp(start_date) start_date = datetime(start_date.year, start_date.month, start_date.day) end_date = datetime.fromtimestamp(end_date) end_date = datetime(end_date.year, end_date.month, end_date.day) efforts_by_dev = defaultdict(int) for day, devs in days.items(): for dev, stats in devs.items(): efforts_by_dev[dev] += stats.Added + stats.Removed + stats.Changed if len(efforts_by_dev) > max_people: chosen = { v for k, v in sorted( ((v, k) for k, v in efforts_by_dev.items()), reverse=True )[:max_people] } print("Warning: truncated people to the most active %d" % max_people) else: chosen = set(efforts_by_dev) chosen_efforts = sorted(((efforts_by_dev[k], k) for k in chosen), reverse=True) chosen_order = {k: i for i, (_, k) in enumerate(chosen_efforts)} efforts = numpy.zeros( (len(chosen) + 1, (end_date - start_date).days + 1), dtype=numpy.float32 ) for day, devs in days.items(): if day < efforts.shape[1]: for dev, stats in devs.items(): dev = chosen_order.get(dev, len(chosen_order)) efforts[dev][day] += stats.Added + stats.Removed + stats.Changed efforts_cum = numpy.cumsum(efforts, axis=1) window = slepian(10, 0.5) window /= window.sum() for e in (efforts, efforts_cum): for i in range(e.shape[0]): ending = e[i][-len(window) * 2 :].copy() e[i] = convolve(e[i], window, "same") e[i][-len(ending) :] = ending matplotlib, pyplot = import_pyplot(args.backend, args.style) plot_x = [start_date + timedelta(days=i) for i in range(efforts.shape[1])] people = [people[k] for _, k in chosen_efforts] + ["others"] for i, name in enumerate(people): if len(name) > 40: people[i] = name[:37] + "..." polys = pyplot.stackplot(plot_x, efforts_cum, labels=people) if len(polys) == max_people + 1: polys[-1].set_hatch("/") polys = pyplot.stackplot(plot_x, -efforts * efforts_cum.max() / efforts.max()) if len(polys) == max_people + 1: polys[-1].set_hatch("/") yticks = [] for tick in pyplot.gca().yaxis.iter_ticks(): if tick[1] >= 0: yticks.append(tick[1]) pyplot.gca().yaxis.set_ticks(yticks) legend = pyplot.legend(loc=2, ncol=2, fontsize=args.font_size) apply_plot_style( pyplot.gcf(), pyplot.gca(), legend, args.background, args.font_size, args.size or "16,10", ) if args.mode == "all" and args.output: output = get_plot_path(args.output, "efforts") else: output = args.output deploy_plot("Efforts through time (changed lines of code)", output, args.background)
def show_devs( args: Namespace, name: str, start_date: int, end_date: int, people: List[str], days: Dict[int, Dict[int, DevDay]], max_people: int = 50, ) -> None: from scipy.signal import convolve, slepian if len(people) > max_people: print("Picking top %s developers by commit count" % max_people) # pick top N developers by commit count commits = defaultdict(int) for devs in days.values(): for dev, stats in devs.items(): commits[dev] += stats.Commits commits = sorted(((v, k) for k, v in commits.items()), reverse=True) chosen_people = {people[k] for _, k in commits[:max_people]} else: chosen_people = set(people) dists, devseries, devstats, route = order_commits(chosen_people, days, people) route_map = {v: i for i, v in enumerate(route)} # determine clusters clusters = hdbscan_cluster_routed_series(dists, route) keys = list(devseries.keys()) route = [keys[node] for node in route] print("Plotting") # smooth time series start_date = datetime.fromtimestamp(start_date) start_date = datetime(start_date.year, start_date.month, start_date.day) end_date = datetime.fromtimestamp(end_date) end_date = datetime(end_date.year, end_date.month, end_date.day) size = (end_date - start_date).days + 1 plot_x = [start_date + timedelta(days=i) for i in range(size)] resolution = 64 window = slepian(size // resolution, 0.5) final = numpy.zeros((len(devseries), size), dtype=numpy.float32) for i, s in enumerate(devseries.values()): arr = numpy.array(s).transpose() full_history = numpy.zeros(size, dtype=numpy.float32) mask = arr[0] < size full_history[arr[0][mask]] = arr[1][mask] final[route_map[i]] = convolve(full_history, window, "same") matplotlib, pyplot = import_pyplot(args.backend, args.style) pyplot.rcParams["figure.figsize"] = (32, 16) pyplot.rcParams["font.size"] = args.font_size prop_cycle = pyplot.rcParams["axes.prop_cycle"] colors = prop_cycle.by_key()["color"] fig, axes = pyplot.subplots(final.shape[0], 1) backgrounds = ( ("#C4FFDB", "#FFD0CD") if args.background == "white" else ("#05401C", "#40110E") ) max_cluster = numpy.max(clusters) for ax, series, cluster, dev_i in zip(axes, final, clusters, route): if cluster >= 0: color = colors[cluster % len(colors)] i = 1 while color == "#777777": color = colors[(max_cluster + i) % len(colors)] i += 1 else: # outlier color = "#777777" ax.fill_between(plot_x, series, color=color) ax.set_axis_off() author = people[dev_i] ax.text( 0.03, 0.5, author[:36] + (author[36:] and "..."), horizontalalignment="right", verticalalignment="center", transform=ax.transAxes, fontsize=args.font_size, color="black" if args.background == "white" else "white", ) ds = devstats[dev_i] stats = "%5d %8s %8s" % ( ds[0], _format_number(ds[1] - ds[2]), _format_number(ds[3]), ) ax.text( 0.97, 0.5, stats, horizontalalignment="left", verticalalignment="center", transform=ax.transAxes, fontsize=args.font_size, family="monospace", backgroundcolor=backgrounds[ds[1] <= ds[2]], color="black" if args.background == "white" else "white", ) axes[0].text( 0.97, 1.75, " cmts delta changed", horizontalalignment="left", verticalalignment="center", transform=axes[0].transAxes, fontsize=args.font_size, family="monospace", color="black" if args.background == "white" else "white", ) axes[-1].set_axis_on() target_num_labels = 12 num_months = ( (end_date.year - start_date.year) * 12 + end_date.month - start_date.month ) interval = int(numpy.ceil(num_months / target_num_labels)) if interval >= 8: interval = int(numpy.ceil(num_months / (12 * target_num_labels))) axes[-1].xaxis.set_major_locator( matplotlib.dates.YearLocator(base=max(1, interval // 12)) ) axes[-1].xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Y")) else: axes[-1].xaxis.set_major_locator( matplotlib.dates.MonthLocator(interval=interval) ) axes[-1].xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Y-%m")) for tick in axes[-1].xaxis.get_major_ticks(): tick.label.set_fontsize(args.font_size) axes[-1].spines["left"].set_visible(False) axes[-1].spines["right"].set_visible(False) axes[-1].spines["top"].set_visible(False) axes[-1].get_yaxis().set_visible(False) axes[-1].set_facecolor((1.0,) * 3 + (0.0,)) title = ("%s commits" % name) if not args.output else "" if args.mode == "all" and args.output: output = get_plot_path(args.output, "time_series") else: output = args.output deploy_plot(title, output, args.background)
from scipy import signal from matplotlib import pyplot as plt from matplotlib import style import mysignals as sigs import numpy as np from scipy.fftpack import fft, fftshift window = signal.slepian(51, width=3) plt.plot(window) plt.title("Slepian Window") plt.ylabel("Amplitude") plt.xlabel("Sample") plt.show() #frequency response plt.figure() A = fft(window, 2048) / (len(window) / 2.0) freq = np.linspace(-0.5, 0.5, len(A)) response = 20 * np.log10(np.abs(fftshift(A / abs(A).max()))) plt.plot(freq, response) plt.axis([-0.5, 0.5, -120, 0]) plt.title("Frequency Response of Slepian Window") plt.ylabel("Normalized Magnitude(dB)") plt.xlabel("Normalized Frequency in cycles/sample") plt.show()
def show_sentiment_stats(args, name, resample, start_date, data): from scipy.signal import convolve, slepian matplotlib, pyplot = import_pyplot(args.backend, args.style) start_date = datetime.fromtimestamp(start_date) data = sorted(data.items()) mood = numpy.zeros(data[-1][0] + 1, dtype=numpy.float32) timeline = numpy.array( [start_date + timedelta(days=i) for i in range(mood.shape[0])] ) for d, val in data: mood[d] = (0.5 - val.Value) * 2 resolution = 32 window = slepian(len(timeline) // resolution, 0.5) window /= window.sum() mood_smooth = convolve(mood, window, "same") pos = mood_smooth.copy() pos[pos < 0] = 0 neg = mood_smooth.copy() neg[neg >= 0] = 0 resolution = 4 window = numpy.ones(len(timeline) // resolution) window /= window.sum() avg = convolve(mood, window, "same") pyplot.fill_between(timeline, pos, color="#8DB843", label="Positive") pyplot.fill_between(timeline, neg, color="#E14C35", label="Negative") pyplot.plot(timeline, avg, color="grey", label="Average", linewidth=5) legend = pyplot.legend(loc=1, fontsize=args.font_size) pyplot.ylabel("Comment sentiment") pyplot.xlabel("Time") apply_plot_style( pyplot.gcf(), pyplot.gca(), legend, args.background, args.font_size, args.size ) pyplot.xlim( parse_date(args.start_date, timeline[0]), parse_date(args.end_date, timeline[-1]), ) locator = pyplot.gca().xaxis.get_major_locator() # set the optimal xticks locator if "M" not in resample: pyplot.gca().xaxis.set_major_locator(matplotlib.dates.YearLocator()) locs = pyplot.gca().get_xticks().tolist() if len(locs) >= 16: pyplot.gca().xaxis.set_major_locator(matplotlib.dates.YearLocator()) locs = pyplot.gca().get_xticks().tolist() if len(locs) >= 16: pyplot.gca().xaxis.set_major_locator(locator) if locs[0] < pyplot.xlim()[0]: del locs[0] endindex = -1 if len(locs) >= 2 and pyplot.xlim()[1] - locs[-1] > (locs[-1] - locs[-2]) / 2: locs.append(pyplot.xlim()[1]) endindex = len(locs) - 1 startindex = -1 if len(locs) >= 2 and locs[0] - pyplot.xlim()[0] > (locs[1] - locs[0]) / 2: locs.append(pyplot.xlim()[0]) startindex = len(locs) - 1 pyplot.gca().set_xticks(locs) # hacking time! labels = pyplot.gca().get_xticklabels() if startindex >= 0: labels[startindex].set_text(timeline[0].date()) labels[startindex].set_text = lambda _: None labels[startindex].set_rotation(30) labels[startindex].set_ha("right") if endindex >= 0: labels[endindex].set_text(timeline[-1].date()) labels[endindex].set_text = lambda _: None labels[endindex].set_rotation(30) labels[endindex].set_ha("right") overall_pos = sum(2 * (0.5 - d[1].Value) for d in data if d[1].Value < 0.5) overall_neg = sum(2 * (d[1].Value - 0.5) for d in data if d[1].Value > 0.5) title = "%s sentiment +%.1f -%.1f δ=%.1f" % ( name, overall_pos, overall_neg, overall_pos - overall_neg, ) if args.mode == "all" and args.output: output = get_plot_path(args.output, "sentiment") else: output = args.output deploy_plot(title, output, args.background)
def aposlepian(theta,sz): from scipy import signal slp = signal.slepian(1001,0.019) flp = nm.interp(theta,nm.linspace(0,sz/180.*nm.pi,501),slp[500:]) return 1-nm.where(theta<sz/180.*nm.pi,flp,0)
def seasons_study(file='challenge-data-v2.csv'): sns.set_style("whitegrid") # ***************************************************** # Loading the data data = pd.read_csv('challenge-data-v2.csv', index_col='event_date', parse_dates=True) # ***************************************************** # Changing the name of the colums to a more suitable (shorter) form data.columns = ['sups', 'moff', 'mon', 'hd'] # ***************************************************** # Scaling the values to work in a more suitable way (avoiding super-high values) for feature in data.columns: if data[feature].values.dtype != 'object': scale_factor = np.round(np.log10(np.mean(data[feature]))) data[feature] = data[feature] / 10**scale_factor print Fore.BLUE + 'The feature: ' + feature + ' was rescaled by a factor of ' + str( 10**scale_factor) print 'IMPORTANT: Take these rescaling in account when reading the plots' print(Style.RESET_ALL) # ***************************************************** # Computation of the distributions per year for sign ups years = np.unique(data.index.year) # Definition of the figure. figid = plt.figure('Temporal Sign-ups distributions by year', figsize=(20, 10)) # Definition of the matrix of plots. In this case the situation is more complex that is why I need to define a # matrix. It will be a dim[2x3] matrix. col = len(data.columns[data.columns == 'sups']) gs = grds.GridSpec(3, col) for i in range(col): ax1 = plt.subplot(gs[0, i]) ax2 = plt.subplot(gs[1, i]) legend = [] for y in years: dat = data[data.columns[i]][str(y)].values ax1.plot(np.arange(len(dat)), dat, '-') legend.append(str(y)) ax1.set_title('Daily ' + data.columns[i]) legend = [] for y in years: dat = data[data.columns[i]][str(y)].resample('M').values ax2.plot(np.arange(len(dat)) + 1, dat, '-o') legend.append(str(y)) ax2.set_title('Monthly ' + data.columns[i]) plt.xlim([1, 12]) ax3 = plt.subplot(gs[2, i]) legend = [] for y in years: dat = data[data.columns[i]][str(y)] dat1 = dat.groupby(dat.index.dayofweek).mean() dat1.index = ['Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat', 'Sun'] dat1.plot(style='-o') legend.append(str(y)) ax3.set_title('Day week ' + data.columns[i]) if i == 0: ax1.legend(years, bbox_to_anchor=(1, 1), loc='best', borderaxespad=0., ncol=1, fancybox=True, frameon=True) # ***************************************************** # Computation of different spectral estimators per year for sign ups years = np.unique(data.index.year) # Definition of the figure. figid = plt.figure('Spectral estimators per year', figsize=(20, 10)) # Definition of the matrix of plots. col = 3 rows = len(years) gs = grds.GridSpec(rows, col) # Spectral parameters Window_length = 32 # in days # This is equivalent to multitaper estimation but just one taper. window = sgn.slepian(Window_length, width=0.3) overlap = 0.85 for r in range(rows): ax1 = plt.subplot(gs[r, 0]) ax2 = plt.subplot(gs[r, 1]) ax3 = plt.subplot(gs[r, 2]) dat = data['sups'][str(years[r])].values spec = np.fft.fft(dat) n = dat.size f = np.fft.fftfreq(n) ax1.plot(f[1:round(len(spec) / 2)], np.abs(spec[1:round(len(spec) / 2)])) f, t, Sxx = sgn.spectrogram(dat, nperseg=Window_length, window=window, noverlap=np.round(Window_length * overlap)) # print 'Spectrogram size',Sxx.shape # print 't',t.shape # print 'f',f.shape # print 'f',f spec = np.abs(Sxx) ax2.imshow(spec, vmax=np.percentile(spec, 98), aspect='auto', cmap='viridis', interpolation='none', origin='lower', extent=[np.min(t), np.max(t), np.min(f), np.max(f)]) ax3.imshow(np.log(spec), vmax=np.percentile(np.log(spec), 98), aspect='auto', cmap='viridis', interpolation='none', origin='lower', extent=[np.min(t), np.max(t), np.min(f), np.max(f)]) ax2.set_ylabel('Year: ' + str(years[r]) + '\nf[Hz]', multialignment='center') if r == 0: ax1.set_title('PSD[n.u.]') ax2.set_title('Spectrogram[n.u.]') ax3.set_title('Spectrogram[log10]') if r == rows - 1: ax1.set_xlabel('f[Hz]') ax2.set_xlabel('Time[days of the year]') ax3.set_xlabel('Time[days of the year]') return True
def __init__(self, ref=None, nperseg=None, noverlap=None, freq_cutoffs=None, window=None, filter_func=None, spect_func=None, log_transform_spect=True): """Spectrogram.__init__ function Parameters ---------- ref : str {'tachibana','koumura'} Use spectrogram parameters from a reference. 'tachibana' uses spectrogram parameters from [1]_, 'koumura' uses spectrogram parameters from [2]_. nperseg : int numper of samples per segment for FFT, e.g. 512 noverlap : int number of overlapping samples in each segment Either ref or nperseg and noverlap are required for __init__ Other Parameters ---------------- freq_cutoffs : two-element list of integers limits of frequency band to keep, e.g. [1000,8000] Spectrogram.make keeps the band: freq_cutoffs[0] >= spectrogram > freq_cutoffs[1] Default is None. window : str window to apply to segments valid strings are 'Hann', 'dpss', None Hann -- Uses np.Hanning with parameter M (window width) set to value of nperseg dpss -- Discrete prolate spheroidal sequence AKA Slepian. Uses scipy.signal.slepian with M parameter equal to nperseg and width parameter equal to 4/nperseg, as in [2]_. Default is None. filter_func : str filter to apply to raw audio. valid strings are 'diff' or None 'diff' -- differential filter, literally np.diff applied to signal as in [1]_. Default is None. spect_func : str which function to use for spectrogram. valid strings are 'scipy' or 'mpl'. 'scipy' uses scipy.signal.spectrogram, 'mpl' uses matplotlib.matlab.specgram. Default is 'scipy'. log_transform_spect : bool if True, applies np.log10 to spectrogram to increase range. Default is True. References ---------- .. [1] Tachibana, Ryosuke O., Naoya Oosugi, and Kazuo Okanoya. "Semi- automatic classification of birdsong elements using a linear support vector machine." PloS one 9.3 (2014): e92584. .. [2] Koumura, Takuya, and Kazuo Okanoya. "Automatic recognition of element classes and boundaries in the birdsong with variable sequences." PloS one 11.7 (2016): e0159188. """ # check for 'reference' parameter first since it takes precedence if ref is not None: if ref not in ('tachibana', 'koumura'): raise ValueError('{} is not a valid value for reference argument'. format(ref)) # warn if called with 'ref' and with other params if any(param is not None for param in [nperseg, noverlap, freq_cutoffs, filter_func, spect_func]): warnings.warn('Spectrogram class received ref ' 'parameter but also received other parameters, ' 'will over-write those with defaults for reference.') else: if ref == 'tachibana': self.nperseg = 256 self.noverlap = 192 self.window = np.hanning(self.nperseg) #Hann window self.freqCutoffs = None self.filterFunc = 'diff' self.spectFunc = 'mpl' self.logTransformSpect = False # see tachibana feature docs self.ref = ref elif ref == 'koumura': self.nperseg = 512 self.noverlap = 480 self.window = slepian(self.nperseg, 4 / self.nperseg) #dpss self.freqCutoffs = [1000, 8000] self.filterFunc = None self.spectFunc = 'scipy' self.logTransformSpect = True self.ref = ref else: raise ValueError('{} is not a valid value for \'ref\' argument. ' 'Valid values: {\'tachibana\',\'koumura\',None}' .format(ref)) elif ref is None: if nperseg is None: raise ValueError('nperseg requires a value for Spectrogram.__init__') if noverlap is None: raise ValueError('noverlap requires a value for Spectrogram.__init__') if spect_func is None: # switch to default # can't have in args list because need to check above for # conflict with default spectrogram functions for each ref spect_func = 'scipy' if type(nperseg) != int: raise TypeError('type of nperseg must be int, but is {}'. format(type(nperseg))) else: self.nperseg = nperseg if type(noverlap) != int: raise TypeError('type of noverlap must be int, but is {}'. format(type(noverlap))) else: self.noverlap = noverlap if window is not None and type(window) != str: raise TypeError('type of window must be str, but is {}'. format(type(window))) else: if window not in ['Hann','dpss',None]: raise ValueError('{} is not a valid specification for window'. format(window)) else: if window == 'Hann': self.window = np.hanning(self.nperseg) elif window == 'dpss': self.window = slepian(self.nperseg, 4 / self.nperseg) elif window is None: self.window = None if type(freq_cutoffs) != list: raise TypeError('type of freq_cutoffs must be list, but is {}'. format(type(freq_cutoffs))) elif len(freq_cutoffs) != 2: raise ValueError('freq_cutoffs list should have length 2, but length is {}'. format(len(freq_cutoffs))) elif not all([type(val) == int for val in freq_cutoffs]): raise ValueError('all values in freq_cutoffs list must be ints') else: self.freqCutoffs = freq_cutoffs if filter_func is not None and type(filter_func) != str: raise TypeError('type of filter_func must be str, but is {}'. format(type(filter_func))) elif filter_func not in ['diff',None]: raise ValueError('string \'{}\' is not valid for filter_func. ' 'Valid values are: \'diff\' or None.'. format(filter_func)) else: self.filterFunc = filter_func if type(spect_func) != str: raise TypeError('type of spect_func must be str, but is {}'. format(type(spect_func))) elif spect_func not in ['scipy','mpl']: raise ValueError('string \'{}\' is not valid for filter_func. ' 'Valid values are: \'scipy\' or \'mpl\'.'. format(spect_func)) else: self.spectFunc = spect_func if type(log_transform_spect) is not bool: raise ValueError('Value for log_transform_spect is {}, but' ' it must be bool.' .format(type(log_transform_spect))) else: self.logTransformSpect = log_transform_spect
def smooth(self, a, filter_n=51, width=0.5): W = signal.slepian(filter_n, width=width) W = W/np.sum(W) s = signal.convolve(a, W, mode='valid') return np.hstack([[s[0]]*(filter_n//2), s, [s[-1]]*(filter_n//2)])