def get_timing_vs_ndata_at_const_nfreq(nvals, nharmonics, max_freq, filename=None, overwrite=True, time_slow=True): #if template is None: template = get_default_template(nharmonics=nharmonics) template.precompute() # load saved results results = {} if filename is None: filename = './saved_results/timing_results_nh%d_maxfrq%.1f.pkl' % ( nharmonics, max_freq) if not filename is None and os.path.exists(filename): old_results = pickle.load(open(filename, 'rb')) results.update(old_results) for n in nvals: if n in results: continue x, y, dy = generate_random_signal(n) x[0] = 0 x[-1] = 1 # time FTP print("timing: n = %d, h = %d, ftp" % (n, nharmonics)) model = FastTemplatePeriodogram(template=template) model.fit(x, y, dy) t0 = time() frq, p = model.autopower(maximum_frequency=max_freq) tftp = time() - t0 print(" done in %.4f seconds" % (tftp)) if time_slow: print("timing: n = %d, h = %d, slow" % (n, nharmonics)) model = SlowTemplatePeriodogram(template=template) model.fit(x, y, dy) t0 = time() p = model.power(frq) tslow = time() - t0 print(" done in %.4f seconds" % (tslow)) else: tslow = -1 results[n] = (tftp, tslow) # save if not filename is None and overwrite: pickle.dump(results, open(filename, 'wb')) return zip(*[results[n] for n in nvals])
def get_modeler(ndata, nh, precompute=True): t, y, yerr = get_data(n=ndata) template = get_template(nh=nh) if precompute: template.precompute() modeler = FastTemplatePeriodogram(template=template) modeler.fit(t, y, yerr) return modeler
def get_timing_vs_nharmonics(x, y, yerr, hvals, filename=None, overwrite=True, only_use_saved_data=False): # load old results results = {} if not filename is None and os.path.exists(filename): old_results = pickle.load(open(filename, 'rb')) results.update(old_results) # return if nothing to do if all([h in results for h in hvals]): return hvals, [results[h] for h in hvals] if only_use_saved_data: return zip(*[(h, results[h]) for h in hvals if h in results]) for h in hvals: if h in results: continue print(" H = ", h) template = get_default_template(nharmonics=h) #template.precompute() model = FastTemplatePeriodogram(template=template) model.fit(x, y, yerr) t0 = time() model.autopower() results[h] = time() - t0 print(" %.4f seconds" % (results[h])) if not filename is None and overwrite: pickle.dump(results, open(filename, 'wb')) return hvals, [results[h] for h in hvals]
def plot_templates_and_periodograms(x, y, err, y_temp, freq_val=None, hfac=None, ofac=None, nharms=None, settings=default_settings): p_ftps = [] phi_data = None if freq_val is None else (x * freq_val - settings['phi0']) % 1.0 for i, nharm in enumerate(nharms): #model.templates.values()[0].nharmonics = nharm #model.templates.values()[0].precompute() template = Template.from_sampled(y_temp, nharmonics=nharm) template.precompute() model = FastTemplatePeriodogram(template=template) # Run FTP model.fit(x, y, err) frq, p = model.autopower(samples_per_peak=ofac, nyquist_factor=hfac) p_ftps.append(p) # get axes boundaries bounds_ax_tmp, bounds_ax_pdg = \ get_boundaries_for_axtmp_and_axpdg(max(frq), settings) # initialize figure f = plt.figure(figsize=(2 * settings['axsize'], settings['axsize'])) ax_pdg = f.add_axes(bounds_ax_pdg) ax_tmp = f.add_axes(bounds_ax_tmp) settings = translate_color(ax_pdg, settings) # get full template phi0 = np.linspace(0, 1, len(y_temp)) y0 = y_temp ymin, ymax = min(-y0), max(-y0) # x position for text (H = ...); has to be in ax_tmp data coordinates x0 = settings['annotate_x0'] / bounds_ax_tmp[2] # functions for normalizing templates tmpnorm = settings['tmp_height_frac'] / (ymax - ymin) yoffset = 0.5 * (1 - settings['tmp_height_frac']) tmp_transform = lambda yt, et: ( (-yt - ymin) * tmpnorm + yoffset, et * tmpnorm if not et is None else None) # normalize data and template ydata, edata = tmp_transform(y, err) y0, _ = tmp_transform(y0, None) #colorfunc = lambda i : "%.5f"%(settings['colorfunc_a'] * (float(len(nharms) - i - 1) / float(len(nharms) - 1)) \ # + settings['colorfunc_b']) if i < len(nharms) - 1 \ # else settings['answer_color'] colorfunc = lambda i: settings['answer_color'] for i, (p, h) in enumerate(zip(p_ftps, nharms)): offset = len(p_ftps) - i - 1 ytext = offset + 0.5 lw = 1 if i < len(p_ftps) - 1 else 1 # plot periodogram ax_pdg.plot(frq, p + offset, color=colorfunc(i), lw=lw, zorder=20) ax_pdg.plot(frq, p + offset, color=ax_pdg.get_facecolor(), lw=3, zorder=19) if (i == len(p_ftps) - 1) and settings['plot_bls']: frq_bls, p_bls = get_bls_periodogram(x, y, err, hfac=3, ofac=10) ax_pdg.plot(frq_bls, p_bls + offset, color=settings['color_bls'], alpha=settings['alpha_bls'], zorder=18) ax_pdg.plot(frq_bls, p_bls + offset, color=ax_pdg.get_facecolor(), zorder=17, lw=3) ax_pdg.text(0.02, 0.92, "Box Least Squares", color=settings['color_bls'], ha='left', va='top', bbox=settings['bbox'], fontsize=settings['annotation_fontsize'], transform=ax_pdg.transAxes) if (i > 0 and settings['plot_multiharmonic_periodogram']): # plot multiharmonic periodogram frq_mh, p_mh = get_multiharmonic_periodogram(x, y, err, h) color = settings['color_multiharmonic_periodogram'] alpha = settings['alpha_multiharmonic_periodogram'] ax_pdg.plot(frq_mh, p_mh + offset, color=color, alpha=alpha, zorder=16) ax_pdg.plot(frq_mh, p_mh + offset, color=ax_pdg.get_facecolor(), zorder=15, lw=3) if i == 1: df0 = (2 * freq_val - min(frq_mh)) / (max(frq_mh) - min(frq_mh)) ind = int(df0 * len(frq_mh)) dx = max(ax_pdg.get_xlim()) - min(ax_pdg.get_xlim()) #ax_pdg.annotate('Multiharmonic Lomb Scargle', # xy = (frq_mh[ind], p_mh[ind] + offset + 0.03), # xycoords = 'data', # xytext = (frq_mh[ind] - 0.015 * dx, 1.45 + offset), # textcoords = 'data', # horizontalalignment = 'right', # verticalalignment = 'bottom', # color = settings['font_color'], # arrowprops = dict(ec=ax_pdg.get_facecolor(), fc=settings['font_color'], # lw=1.5, arrowstyle='simple'), # fontsize = settings['annotation_fontsize'], # bbox = settings['bbox']) ax_pdg.text(0.02, 0.98, "Multi-harmonic Lomb Scargle", fontsize=settings['annotation_fontsize'], bbox=settings['bbox'], color=color, ha='left', va='top', transform=ax_pdg.transAxes) # get truncated template #template.nharmonics = h template = Template.from_sampled(y_temp, nharmonics=h) template.precompute() phi = np.linspace(0, 1, 100) ytmp_trunc = template(phi) # normalize truncated template ytmp_trunc, _ = tmp_transform(ytmp_trunc, None) # plot truncated template ax_tmp.plot(phi, ytmp_trunc + offset, color=colorfunc(i), lw=lw) # plot data ax_tmp.errorbar(phi_data, ydata + offset, yerr=edata, **settings['data_params']) # write H = ... ax_tmp.text(x0, ytext, "H = %d" % (h), va='center', ha='left', color=settings['font_color'], fontsize=settings['label_fontsize']) # Write axis labels ax_tmp.set_xlabel('Phase') ax_pdg.set_xlabel('Frequency $[d^{-1}]$') # Draw line for correct frequency if freq_val is not None: ax_pdg.axvline(freq_val, ls=':', color='k') # Write titles ytitle = settings['top'] + settings['title_pad'] xtitle_pdg = settings['left'] + bounds_ax_tmp[2] + settings['wspace'] \ + 0.5 * bounds_ax_pdg[2] xtitle_tmp = settings['left'] + 0.5 * bounds_ax_tmp[2] f.text(xtitle_pdg, ytitle, "Template periodogram", va='bottom', ha='center', color=settings['font_color'], fontsize=settings['title_fontsize']) f.text(xtitle_tmp, ytitle, "Template fits", va='bottom', ha='center', color=settings['font_color'], fontsize=settings['title_fontsize']) # Set other properties ax_pdg.set_xlim(0, int(max(frq) / settings['locator_axpdg'])\ * settings['locator_axpdg']) ax_pdg.set_ylim(0, len(nharms)) ax_pdg.xaxis.set_major_locator(MultipleLocator(settings['locator_axpdg'])) ax_tmp.set_xlim(0, 1) ax_tmp.set_ylim(*ax_pdg.get_ylim()) ax_tmp.set_yticks(ax_pdg.get_yticks()) ax_tmp.xaxis.set_major_locator(MultipleLocator(settings['locator_axtmp'])) # for both axes... for ax in [ax_pdg, ax_tmp]: # turn of ytick labels [label.set_visible(False) for label in ax.get_yticklabels()] ax.yaxis.set_major_locator(MultipleLocator(1)) clean_up_axis(ax, settings) clean_up_figure(f, settings)
def plot_accuracy(x, y, yerr, y_temp, nharmonics, compare_with=10, settings=default_settings): template = Template.from_sampled(y_temp, nharmonics=10) # if comparing to large nharmonics, set template now if isinstance(compare_with, float) or isinstance(compare_with, int): template = Template.from_sampled(y_temp, nharmonics=int(compare_with)) #template.nharmonics = int(compare_with) template.precompute() # Set the reference model true_model = SlowTemplatePeriodogram(template=template) \ if compare_with == 'slow_version' \ else FastTemplatePeriodogram(template=template) # fit data true_model.fit(x, y, yerr) results, frq, p_ans = {}, None, None label_formatter = lambda kind, h=None : \ "$P_{\\rm %s}(\\omega%s)$"\ %(kind, "" if h is None else "|H=%d"%(h)) corrlabel = lambda R: "$R = %.3f$" % (R) # store results from the reference model # (if the reference model is FastTemplatePeriodogram) if isinstance(true_model, FastTemplatePeriodogram): frq, p_ans = true_model.autopower() results = {'ans': (frq, p_ans)} # add results from all desired harmonics for h in nharmonics: # set template harmonics #template.nharmonics = h template = Template.from_sampled(y_temp, nharmonics=h) template.precompute() # create & fit modeler model = FastTemplatePeriodogram(template=template) model.fit(x, y, yerr) # compute periodogram results[h] = model.autopower() # compute results for reference model # (if the reference model is gatspy) if not 'ans' in results and isinstance(true_model, SlowTemplatePeriodogram): frq = results[h][0] p_ans = true_model.power(frq) results['ans'] = (frq, p_ans) # Set up plot geometry nplots = len(nharmonics) if not settings['nrows'] is None: nrows = settings['nrows'] else: nrows = max([int(sqrt(nplots)), 1]) ncols = 1 while ncols * nrows < nplots: ncols += 1 figsize = (settings['axsize'] * ncols, settings['axsize'] * nrows) # create figure f, axes = plt.subplots(nrows, ncols, figsize=figsize) # ensure we have a list of axes if not hasattr(axes, '__iter__'): axes = [axes] # some plotting definitions ans_label = label_formatter('slow') if compare_with == 'slow_version'\ else label_formatter('FTP', int(compare_with)) ax_label_params = dict(fontsize=settings['label_fontsize'], color=settings['font_color']) ax_annotation_params = dict(fontsize=settings['annotation_fontsize'], color=settings['font_color'], bbox=settings['bbox']) scatter_params = settings['scatter_params'] #print scatter_params for i, h in enumerate(nharmonics): # select the axes instance r, c = i / ncols, i % ncols ax = axes[c] if ncols >= 1 and nrows == 1 else axes[r][c] settings = translate_color(ax, settings) p = results[h][1] # scatterplot ax.plot([0, 1], [0, 1], ls=':', color=settings['font_color'], zorder=2) ax.scatter(p, p_ans, **scatter_params) # write the pearson R correlation ax.text(0.05, 0.9, corrlabel(pearsonr(p_ans, p)[0]), transform=ax.transAxes, ha='left', va='bottom', zorder=10, **ax_annotation_params) # many of the gatspy periodogram values are 0; # write pearson R using only non-zero P_gatspy values #if compare_with == 'slow_version': # nonzero_p_ans, nonzero_p = zip(*filter(lambda (Pans, P) : Pans > 0, zip(p_ans, p))) # Rnonzero = pearsonr(nonzero_p_ans, nonzero_p)[0] # ax.text(0.05, 0.9 - 0.03, "%s; $P_{\\rm non-lin. opt.} > 0$"\ # %(corrlabel(Rnonzero)),zorder=10, # transform=ax.transAxes, ha='left', va='top', **ax_annotation_params) # set plot properties ax.set_xlabel(label_formatter('FTP', h), **ax_label_params) if c == 0: ax.set_ylabel(ans_label, **ax_label_params) else: [label.set_visible(False) for label in ax.get_yticklabels()] ax.set_xlim(settings['x_and_y_min'], 1) ax.set_ylim(settings['x_and_y_min'], 1) name_list = ["0", "0.25", "0.5", "0.75", "1"] pos_list = [0, 0.25, 0.5, 0.75, 1] ax.xaxis.set_major_locator(FixedLocator((pos_list))) ax.xaxis.set_major_formatter(FixedFormatter((name_list))) ax.yaxis.set_major_locator(FixedLocator((pos_list))) ax.yaxis.set_major_formatter(FixedFormatter((name_list))) clean_up_axis(ax, settings) adjust_figure(f, settings) clean_up_figure(f, settings)
def plot_timing_vs_ndata_const_freq(settings=default_settings): f, ax = plt.subplots(figsize=(settings['axsize'], settings['axsize'])) settings = translate_color(ax, settings) #fname = os.path.join(settings['results_dir'], settings['timing_filename']) nharms = settings['nharmonics'] if not hasattr(nharms, '__iter__'): nharms = [nharms] x, y, dy = generate_random_signal(10) x[0] = 0 x[-1] = 1 xoffset = 0.08 * (settings['xlim'][1] - settings['xlim'][0]) nfrq = len(FastTemplatePeriodogram().fit( x, y, dy).autofrequency(maximum_frequency=settings['max_freq'])) for i, h in enumerate(nharms): time_slow = (h == 3) tftp, tslow = get_timing_vs_ndata_at_const_nfreq(settings['ndata'], h, settings['max_freq'], time_slow=time_slow) label = None if h < max(nharms) else 'Fast template periodogram' color = settings['scatter_params_ftp']['c'] lw = settings['linewidth'] spars = {} spars.update(settings['scatter_params_ftp']) fudge = 0.7 ls = '-' if h == max(nharms) else ':' #ls = '-' q = 1. if len(nharms) > 1: q = float(h - min(nharms)) / float(max(nharms) - min(nharms)) spars['alpha'] = fudge * q + (1 - fudge) ax.scatter(settings['ndata'], tftp, label=label, **spars) ax.plot(settings['ndata'], tftp, color=color, lw=lw, alpha=spars['alpha'], ls=ls) # now label this ax.text(settings['ndata'][-1] + xoffset, tftp[-1], "$H = %d$" % (h), ha='left', va='center', color=settings['font_color'], fontsize=settings['annotation_fontsize'], bbox=settings['bbox']) if time_slow: ax.scatter(settings['ndata'], tslow, label='Non-linear optimization', **settings['scatter_params_nonlin']) ax.plot(settings['ndata'], tslow, color=settings['scatter_params_nonlin']['c'], lw=settings['linewidth']) ax.text(0.05, 0.7, "$N_f=%d$" % (nfrq), ha='left', va='top', transform=ax.transAxes) ax.set_xlabel('Number of datapoints') ax.set_ylabel("Execution time [s]") ax.set_title('Constant baseline') ax.set_xscale('log') ax.set_yscale('log') ax.set_xlim(*settings['xlim']) ax.set_ylim(*settings['ylim']) ax.legend(loc=settings['legend_loc']) adjust_figure(f, settings) clean_up_axis(ax, settings) clean_up_figure(f, settings)
def get_timing_vs_ndata(nvals, nharmonics, filename=None, overwrite=True, time_gatspy=True, only_use_saved_data=False, time_lomb_scargle=False): #if template is None: template = get_default_template(nharmonics=nharmonics) #template.precompute() # load saved results results = {} if not filename is None and os.path.exists(filename): old_results = pickle.load(open(filename, 'rb')) results.update(old_results) else: results = {name: [] for name in ['nfreqs', 'ndata', 'tftp', 'tgats']} if only_use_saved_data: return select_from_dict(results, nvals) # return if nothing to do if all([n in results for n in nvals]): return [results[n] for n in nvals] for n in nvals: if n in results['ndata']: continue results['ndata'].append(n) x, y, dy = generate_random_signal(n) # time FTP print("timing: n = %d, h = %d, ftp" % (n, nharmonics)) model = FastTemplatePeriodogram(template=template) model.fit(x, y, dy) t0 = time() frq, p = model.autopower() results['tftp'].append(time() - t0) print(" done in %.4f seconds" % (results['tftp'][-1])) results['nfreqs'].append(len(frq)) if time_gatspy: # time GATSPY print("timing: n = %d, gatspy" % (n)) model = SlowTemplatePeriodogram(template=template) model.fit(x, y, dy) t0 = time() p = model.power(frq) results['tgats'].append(time() - t0) print(" done in %.4f seconds" % (results['tgats'][-1])) else: results['tgats'].append(-1) # SORT results results = sort_timing_dict(results) # save if not filename is None and overwrite: pickle.dump(results, open(filename, 'wb')) return select_from_dict(results, nvals)
else: Ttemp, Ytemp = pickle.load( open_results('template_filename', tconf, 'rb')) template = Template.from_sampled(Ytemp, nharmonics=tconf['nharm_answer']) x, y, err = generate_random_signal(ndata, sigma, freq=freq, template=template) template.precompute() # build model model = FastTemplatePeriodogram(template=template) y_temp = template(np.linspace(0, 1, 100)) print("plotting timing vs ndata at constant freq") plot_timing_vs_ndata_const_freq( settings=conf['timing_vs_ndata_const_freq']) print("plotting timing vs nharmonics") plot_timing_vs_nharmonics(conf['timing_vs_nharmonics']) print("plotting timing vs ndata") plot_timing_vs_ndata(conf['timing_vs_ndata']) #print("plotting nobs dt for surveys") #plot_nobs_dt_for_surveys(settings=conf['nobs_dt_for_surveys'])