def test_grid_search(self): search = pyfstat.GridSearch( "grid_search", self.outdir, self.sftfilepath, F0s=self.F0s, F1s=[0], F2s=[0], Alphas=[0], Deltas=[0], tref=self.tref, ) search.run() self.assertTrue(os.path.isfile(search.out_file))
def test_semicoherent_grid_search(self): # FIXME this one doesn't check the results at all yet self.search = pyfstat.GridSearch( "sc_grid_search", self.outdir, self.Writer.sftfilepath, F0s=self.F0s, F1s=[self.Writer.F1], F2s=[self.Writer.F2], Alphas=[self.Writer.Alpha], Deltas=[self.Writer.Delta], tref=self.tref, nsegs=2, BSGL=self.BSGL, ) self.search.run() self.assertTrue(os.path.isfile(self.search.out_file)) search_keys = ["F0"] # only the ones that aren't 0-width self._test_plots(search_keys)
def test_grid_search_2D(self): self.search = pyfstat.GridSearch( "grid_search_F0F1", self.outdir, self.Writer.sftfilepath, F0s=self.F0s, F1s=self.F1s, F2s=[self.Writer.F2], Alphas=[self.Writer.Alpha], Deltas=[self.Writer.Delta], tref=self.tref, BSGL=self.BSGL, ) self.search.run() self.assertTrue(os.path.isfile(self.search.out_file)) max2F_point = self.search.get_max_twoF() self.assertTrue( np.all(max2F_point["twoF"] >= self.search.data["twoF"])) search_keys = ["F0", "F1"] # only the ones that aren't 0-width self._test_plots(search_keys)
DeltaF0 = 100 * dF0 F0s = [data.F0 - DeltaF0 / 2.0, data.F0 + DeltaF0 / 2.0, dF0] F1s = [data.F1] F2s = [data.F2] Alphas = [data.Alpha] Deltas = [data.Delta] BSGL = False print("Standard CW search:") search1 = pyfstat.GridSearch( label="CW" + ("_BSGL" if BSGL else ""), outdir=data.outdir, sftfilepattern=os.path.join(data.outdir, "*simulated_transient_signal*sft"), F0s=F0s, F1s=F1s, F2s=F2s, Alphas=Alphas, Deltas=Deltas, tref=data.tref, BSGL=BSGL, ) search1.run() search1.print_max_twoF() search1.plot_1D(xkey="F0", xlabel="freq [Hz]", ylabel="$2\\mathcal{F}$") print("with t0,tau bands:") search2 = pyfstat.TransientGridSearch( label="tCW" + ("_BSGL" if BSGL else ""), outdir=data.outdir, sftfilepattern=os.path.join(data.outdir, "*simulated_transient_signal*sft"), F0s=F0s,
DeltaSky = 10 * dSky Alphas = [inj["Alpha"] - DeltaSky / 2.0, inj["Alpha"] + DeltaSky / 2.0, dSky] Deltas = [inj["Delta"] - DeltaSky / 2.0, inj["Delta"] + DeltaSky / 2.0, dSky] search_keys += ["Alpha", "Delta"] else: Alphas = [inj["Alpha"]] Deltas = [inj["Delta"]] search_keys_label = "".join(search_keys) print("Performing GridSearch...") gridsearch = pyfstat.GridSearch( label="grid_search_" + search_keys_label, outdir=outdir, sftfilepattern=os.path.join(outdir, "*simulated_signal*sft"), F0s=F0s, F1s=F1s, F2s=F2s, Alphas=Alphas, Deltas=Deltas, tref=inj["tref"], ) gridsearch.run() gridsearch.print_max_twoF() # do some plots of the GridSearch results if not sky: # this plotter can't currently deal with too large result arrays print("Plotting 1D 2F distributions...") for key in search_keys: gridsearch.plot_1D(xkey=key, xlabel=labels[key], ylabel=labels["2F"]) print("Making GridSearch {:s} corner plot...".format("-".join(search_keys)))
dF2 = 1e-17 N = 100 DeltaF0 = N * dF0 DeltaF1 = N * dF1 F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1 - DeltaF1 / 2.0, F1 + DeltaF1 / 2.0, dF1] F2s = [F2] Alphas = [Alpha] Deltas = [Delta] search = pyfstat.GridSearch( label, outdir, data.sftfilepath, F0s, F1s, F2s, Alphas, Deltas, tref, tstart, tend, ) search.run() print("Plotting 2F(F0)...") search.plot_1D(xkey="F0", xlabel="freq [Hz]", ylabel="$2\\mathcal{F}$") print("Plotting 2F(F1)...") search.plot_1D(xkey="F1") print("Plotting 2F(F0,F1)...") search.plot_2D(xkey="F0", ykey="F1", colorbar=True)
def test_grid_search_against_CFSv2(self): self.search = pyfstat.GridSearch( "grid_search", self.outdir, self.Writer.sftfilepath, F0s=self.F0s, F1s=[self.Writer.F1], F2s=[self.Writer.F2], Alphas=[self.Writer.Alpha], Deltas=[self.Writer.Delta], tref=self.tref, ) self.search.run() self.assertTrue(os.path.isfile(self.search.out_file)) pyfstat_out = pyfstat.helper_functions.read_txt_file_with_header( self.search.out_file, comments="#") CFSv2_out_file = os.path.join(self.outdir, "CFSv2_Fstat_out.txt") CFSv2_loudest_file = os.path.join(self.outdir, "CFSv2_Fstat_loudest.txt") cl_CFSv2 = [] cl_CFSv2.append("lalapps_ComputeFstatistic_v2") cl_CFSv2.append("--Alpha {} --AlphaBand 0".format(self.Alpha)) cl_CFSv2.append("--Delta {} --DeltaBand 0".format(self.Delta)) cl_CFSv2.append("--Freq {}".format(self.F0s[0])) cl_CFSv2.append("--FreqBand {}".format(self.F0s[1] - self.F0s[0])) cl_CFSv2.append("--dFreq {}".format(self.F0s[2])) cl_CFSv2.append("--f1dot {} --f1dotBand 0".format(self.F1)) cl_CFSv2.append("--DataFiles '{}'".format(self.Writer.sftfilepath)) cl_CFSv2.append("--refTime {}".format(self.tref)) cl_CFSv2.append("--outputFstat " + CFSv2_out_file) cl_CFSv2.append("--outputLoudest " + CFSv2_loudest_file) # to match ComputeFstat default (and hence PyFstat) defaults on older # lalapps_CFSv2 versions, set the RngMedWindow manually: cl_CFSv2.append("--RngMedWindow=101") cl_CFSv2 = " ".join(cl_CFSv2) pyfstat.helper_functions.run_commandline(cl_CFSv2) self.assertTrue(os.path.isfile(CFSv2_out_file)) self.assertTrue(os.path.isfile(CFSv2_loudest_file)) CFSv2_out = pyfstat.helper_functions.read_txt_file_with_header( CFSv2_out_file, comments="%") self.assertTrue( len(np.atleast_1d(CFSv2_out["2F"])) == len( np.atleast_1d(pyfstat_out["twoF"]))) self.assertTrue( np.max(np.abs(CFSv2_out["freq"] - pyfstat_out["F0"]) < 1e-16)) self.assertTrue( np.max(np.abs(CFSv2_out["2F"] - pyfstat_out["twoF"]) < 1)) self.assertTrue(np.max(CFSv2_out["2F"]) == np.max(pyfstat_out["twoF"])) self.search.generate_loudest() self.assertTrue(os.path.isfile(self.search.loudest_file)) loudest = {} for run, f in zip(["CFSv2", "PyFstat"], [CFSv2_loudest_file, self.search.loudest_file]): loudest[run] = pyfstat.helper_functions.read_par( filename=f, suffix="loudest", raise_error=False, ) for key in ["Alpha", "Delta", "Freq", "f1dot", "f2dot", "f3dot"]: self.assertTrue( np.abs(loudest["CFSv2"][key] - loudest["PyFstat"][key]) < 1e-16) self.assertTrue( np.abs(loudest["CFSv2"]["twoF"] - loudest["PyFstat"]["twoF"]) < 1)
def test_grid_search_on_data_with_line(self): # We reuse the default multi-IFO SFTs # but add an additional single-detector artifact to H1 only. # For simplicity, this is modelled here as a fully modulated CW-like signal, # just restricted to the single detector. SFTs_H1 = self.Writer.sftfilepath.split(";")[0] SFTs_L1 = self.Writer.sftfilepath.split(";")[1] extra_writer = pyfstat.Writer( label=self.label + "_with_line", outdir=self.outdir, tref=self.tref, F0=self.Writer.F0 + 0.0005, F1=self.Writer.F1, F2=self.Writer.F2, Alpha=self.Writer.Alpha, Delta=self.Writer.Delta, h0=10 * self.Writer.h0, cosi=self.Writer.cosi, sqrtSX=0, # don't add yet another set of Gaussian noise noiseSFTs=SFTs_H1, SFTWindowType=self.Writer.SFTWindowType, SFTWindowBeta=self.Writer.SFTWindowBeta, ) extra_writer.make_data() data_with_line = ";".join([SFTs_L1, extra_writer.sftfilepath]) # now run a standard F-stat search over this data searchF = pyfstat.GridSearch( label="grid_search", outdir=self.outdir, sftfilepattern=data_with_line, F0s=self.F0s, F1s=[self.Writer.F1], F2s=[self.Writer.F2], Alphas=[self.Writer.Alpha], Deltas=[self.Writer.Delta], tref=self.tref, BSGL=False, ) searchF.run() self.assertTrue(os.path.isfile(searchF.out_file)) max2F_point_searchF = searchF.get_max_twoF() self.assertTrue( np.all(max2F_point_searchF["twoF"] >= searchF.data["twoF"])) # also run a BSGL search over the same data searchBSGL = pyfstat.GridSearch( label="grid_search", outdir=self.outdir, sftfilepattern=data_with_line, F0s=self.F0s, F1s=[self.Writer.F1], F2s=[self.Writer.F2], Alphas=[self.Writer.Alpha], Deltas=[self.Writer.Delta], tref=self.tref, BSGL=True, ) searchBSGL.run() self.assertTrue(os.path.isfile(searchBSGL.out_file)) max2F_point_searchBSGL = searchBSGL.get_max_twoF() self.assertTrue( np.all(max2F_point_searchBSGL["twoF"] >= searchBSGL.data["twoF"])) # Since we search the same grids and store all output, # the twoF from both searches should be the same. self.assertTrue( max2F_point_searchBSGL["twoF"] == max2F_point_searchF["twoF"]) maxBSGL_point = searchBSGL.get_max_det_stat() self.assertTrue( np.all(maxBSGL_point["log10BSGL"] >= searchBSGL.data["log10BSGL"])) # The BSGL search should produce a lower max2F value than the F search. self.assertTrue(maxBSGL_point["twoF"] < max2F_point_searchF["twoF"]) # But the maxBSGL_point should be the true multi-IFO signal # while max2F_point_searchF should have fallen for the single-IFO line. self.assertTrue( np.abs(maxBSGL_point["F0"] - self.F0) < np.abs(max2F_point_searchF["F0"] - self.F0))
dF2 = 1e-17 N = 100 DeltaF0 = N * dF0 DeltaF1 = N * dF1 F0s = [inj["F0"] - DeltaF0 / 2.0, inj["F0"] + DeltaF0 / 2.0, dF0] F1s = [inj["F1"] - DeltaF1 / 2.0, inj["F1"] + DeltaF1 / 2.0, dF1] F2s = [inj["F2"]] Alphas = [inj["Alpha"]] Deltas = [inj["Delta"]] search = pyfstat.GridSearch( label=label, outdir=outdir, sftfilepattern=data.sftfilepath, F0s=F0s, F1s=F1s, F2s=F2s, Alphas=Alphas, Deltas=Deltas, tref=tref, minStartTime=tstart, maxStartTime=tend, ) search.run() # report details of the maximum point max_dict = search.get_max_twoF() print("max2F={:.4f} from GridSearch, offsets from injection: {:s}.".format( max_dict["twoF"], ", ".join([ "{:.4e} in {:s}".format(max_dict[key] - inj[key], key) for key in max_dict.keys() if not key == "twoF"
N = 100 DeltaF0 = N * dF0 DeltaF1 = N * dF1 DeltaF2 = N * dF2 F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1 - DeltaF1 / 2.0, F1 + DeltaF1 / 2.0, dF1] F2s = [F2 - DeltaF2 / 2.0, F2 + DeltaF2 / 2.0, dF2] Alphas = [Alpha] Deltas = [Delta] search = pyfstat.GridSearch( "grid_F0F1F2", "data", data.sftfilepath, F0s, F1s, F2s, Alphas, Deltas, tref, tstart, tend, ) search.run() F0_vals = np.unique(search.data[:, 2]) - F0 F1_vals = np.unique(search.data[:, 3]) - F1 F2_vals = np.unique(search.data[:, 4]) - F2 twoF = search.data[:, -1].reshape((len(F0_vals), len(F1_vals), len(F2_vals))) xyz = [F0_vals, F1_vals, F2_vals] labels = [ "$f - f_0$",
m = 0.001 dF0 = np.sqrt(12 * m) / (np.pi * duration) DeltaF0 = 800 * dF0 F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1] F2s = [F2] Alphas = [Alpha] Deltas = [Delta] search = pyfstat.GridSearch( "grided_frequency_search", "data", "data/*" + data_label + "*sft", F0s, F1s, F2s, Alphas, Deltas, tref, tstart, tend, ) search.run() fig, ax = plt.subplots() xidx = search.keys.index("F0") frequencies = np.unique(search.data[:, xidx]) twoF = search.data[:, -1] # mismatch = np.sign(x-F0)*(duration * np.pi * (x - F0))**2 / 12.0 ax.plot(frequencies, twoF, "k", lw=1)
F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1] F2s = [F2] Alphas = [Alpha] Deltas = [Delta] # first search: standard F-statistic # This should show a weak peak from the coherent signal # and a larger one from the "line artifact" at higher frequency. searchF = pyfstat.GridSearch( label + "_twoF", outdir, os.path.join(outdir, "*" + label + "*sft"), F0s, F1s, F2s, Alphas, Deltas, tref, tstart, tend, ) searchF.run() print("Plotting 2F(F0)...") searchF.plot_1D(xkey="F0") # second search: line-robust statistic BSGL activated searchBSGL = pyfstat.GridSearch( label + "_BSGL", outdir,
m = 0.001 dF0 = np.sqrt(12 * m) / (np.pi * duration) DeltaF0 = 800 * dF0 F0s = [inj["F0"] - DeltaF0 / 2.0, inj["F0"] + DeltaF0 / 2.0, dF0] F1s = [inj["F1"]] F2s = [inj["F2"]] Alphas = [inj["Alpha"]] Deltas = [inj["Delta"]] search = pyfstat.GridSearch( label=label, outdir=outdir, sftfilepattern=os.path.join(outdir, "*" + label + "*sft"), F0s=F0s, F1s=F1s, F2s=F2s, Alphas=Alphas, Deltas=Deltas, tref=tref, minStartTime=tstart, maxStartTime=tend, ) search.run() # report details of the maximum point max_dict = search.get_max_twoF() print("max2F={:.4f} from GridSearch, offsets from injection: {:s}.".format( max_dict["twoF"], ", ".join([ "{:.4e} in {:s}".format(max_dict[key] - inj[key], key) for key in max_dict.keys() if not key == "twoF"
m = 0.001 dF0 = np.sqrt(12 * m) / (np.pi * duration) DeltaF0 = 800 * dF0 F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1] F2s = [F2] Alphas = [Alpha] Deltas = [Delta] search = pyfstat.GridSearch( label, outdir, os.path.join(outdir, "*" + label + "*sft"), F0s, F1s, F2s, Alphas, Deltas, tref, tstart, tend, ) search.run() print("Plotting 2F(F0)...") fig, ax = plt.subplots() frequencies = search.data["F0"] twoF = search.data["twoF"] # mismatch = np.sign(x-F0)*(duration * np.pi * (x - F0))**2 / 12.0 ax.plot(frequencies, twoF, "k", lw=1) DeltaF = frequencies - F0
dF0 = np.sqrt(12 * m) / (np.pi * Tspan) DeltaF0 = 100 * dF0 F0s = [F0 - DeltaF0 / 2.0, F0 + DeltaF0 / 2.0, dF0] F1s = [F1] F2s = [F2] Alphas = [Alpha] Deltas = [Delta] print("Standard CW search:") search1 = pyfstat.GridSearch( label="CW", outdir=datadir, sftfilepattern=os.path.join(datadir, "*simulated_transient_signal*sft"), F0s=F0s, F1s=F1s, F2s=F2s, Alphas=Alphas, Deltas=Deltas, tref=tref, minStartTime=minStartTime, maxStartTime=maxStartTime, BSGL=False, ) search1.run() search1.print_max_twoF() search1.plot_1D(xkey="F0", xlabel="freq [Hz]", ylabel="$2\mathcal{F}$") print("with t0,tau bands:") search2 = pyfstat.TransientGridSearch( label="tCW", outdir=datadir,