diff --git a/pyfstat/grid_based_searches.py b/pyfstat/grid_based_searches.py index 0e163910cd2c71aae0e94830c7a6b685242576a3..8f4a9bea14bd1de81ea64731dea3153e8fcfb560 100644 --- a/pyfstat/grid_based_searches.py +++ b/pyfstat/grid_based_searches.py @@ -180,23 +180,31 @@ class GridSearch(BaseSearchClass): m = self.convert_F1_to_mismatch(y, yhat, Tseg) axY.set_ylim(m[0], m[-1]) - def plot_1D(self, xkey, ax=None, x0=None, savefig=True): + def plot_1D(self, xkey, ax=None, x0=None, xrescale=1, savefig=True, + xlabel=None, ylabel='$\widetilde{2\mathcal{F}}$'): if ax is None: fig, ax = plt.subplots() xidx = self.keys.index(xkey) x = np.unique(self.data[:, xidx]) if x0: x = x - x0 + x = x * xrescale z = self.data[:, -1] ax.plot(x, z) if x0: ax.set_xlabel(self.tex_labels[xkey]+self.tex_labels0[xkey]) else: ax.set_xlabel(self.tex_labels[xkey]) + + if xlabel: + ax.set_xlabel(xlabel) + + ax.set_ylabel(ylabel) if savefig: + fig.tight_layout() fig.savefig('{}/{}_1D.png'.format(self.outdir, self.label)) else: - return ax + return fig, ax def plot_2D(self, xkey, ykey, ax=None, save=True, vmin=None, vmax=None, add_mismatch=None, xN=None, yN=None, flat_keys=[], @@ -624,6 +632,82 @@ class FrequencySlidingWindow(GridSearch): return ax +class EarthTest(GridSearch): + """ """ + tex_labels = {'deltaRadius': '$\Delta R$ [m]', + 'phaseOffset': 'phase-offset [rad]', + 'deltaPspin': '$\Delta P_\mathrm{spin}$ [s]'} + + @helper_functions.initializer + def __init__(self, label, outdir, sftfilepattern, deltaRadius, + phaseOffset, deltaPspin, F0, F1, F2, Alpha, + Delta, tref=None, minStartTime=None, maxStartTime=None, + BSGL=False, minCoverFreq=None, maxCoverFreq=None, + detectors=None, injectSources=None, + assumeSqrtSX=None): + """ + Parameters + ---------- + label, outdir: str + A label and directory to read/write data from/to + sftfilepattern: str + Pattern to match SFTs using wildcards (*?) and ranges [0-9]; + mutiple patterns can be given separated by colons. + F0, F1, F2, Alpha, Delta: float + tref, minStartTime, maxStartTime: int + GPS seconds of the reference time, start time and end time + + For all other parameters, see `pyfstat.ComputeFStat` for details + """ + self.nsegs = 1 + self.F0s = [F0] + self.F1s = [F1] + self.F2s = [F2] + self.Alphas = [Alpha] + self.Deltas = [Delta] + self.deltaRadius = np.atleast_1d(deltaRadius) + self.phaseOffset = np.atleast_1d(phaseOffset) + self.deltaPspin = np.atleast_1d(deltaPspin) + self.set_out_file() + self.SSBprec = lalpulsar.SSBPREC_RELATIVISTIC + self.keys = ['deltaRadius', 'phaseOffset', 'deltaPspin'] + + def get_input_data_array(self): + logging.info("Generating input data array") + coord_arrays = [self.deltaRadius, self.phaseOffset, self.deltaPspin] + input_data = [] + for vals in itertools.product(*coord_arrays): + input_data.append(vals) + self.input_data = np.array(input_data) + self.coord_arrays = coord_arrays + + def run(self): + self.get_input_data_array() + old_data = self.check_old_data_is_okay_to_use() + if old_data is not False: + self.data = old_data + return + + if hasattr(self, 'search') is False: + self.inititate_search_object() + + data = [] + vals = [self.minStartTime, self.maxStartTime, self.F0, self.F1, + self.F2, self.Alpha, self.Delta] + for (dR, dphi, dP) in tqdm(self.input_data): + rescaleRadius = (1 + dR / lal.REARTH_SI) + rescalePeriod = (1 + dP / lal.DAYSID_SI) + lalpulsar.BarycenterModifyEarthRotation( + rescaleRadius, dphi, rescalePeriod, self.tref) + FS = self.search.get_det_stat(*vals) + data.append(list([dR, dphi, dP]) + [FS]) + + data = np.array(data, dtype=np.float) + logging.info('Saving data to {}'.format(self.out_file)) + np.savetxt(self.out_file, data, delimiter=' ') + self.data = data + + class DMoff_NO_SPIN(GridSearch): """ DMoff test using SSBPREC_NO_SPIN """ @helper_functions.initializer