def test_write_text_data(self): """ Test that data can be correctly written (and re-read) from a text file. """ times = np.linspace(1000000000.0, 1000086340.0, 1440) data = np.random.normal(0.0, 1e-25, size=(1440, 2)) het = HeterodynedData(data, times=times) for suffix in ["txt", "txt.gz"]: datafile = "testdata.{}".format(suffix) het.write(datafile) # read in data hetnew = HeterodynedData.read(datafile) assert np.array_equal(het.data, hetnew.data) assert np.array_equal(het.times, hetnew.times) # check things that the read-in data should not contain assert hetnew.detector is None assert hetnew.par is None os.remove(datafile) # clean up file
def test_write_csv_data_std(self): """ Test that data can be correctly written (and re-read) from a CSV file with the standard deviations also output. """ times = np.linspace(1000000000.0, 1000086340.0, 1440) data = np.random.normal(0.0, 1e-25, size=(1440, 2)) stds = 1e-25 * np.ones_like(times) data = np.column_stack((data, stds)) het = HeterodynedData(data, times=times) datafile = "testdata.csv" het.write(datafile) # read in data hetnew = HeterodynedData.read(datafile) assert np.array_equal(het.data, hetnew.data) assert np.array_equal(het.times, hetnew.times) assert np.array_equal(het.stds, hetnew.stds) # check things that the read-in data should not contain assert hetnew.detector is None assert hetnew.par is None os.remove(datafile) # clean up file
def test_write_hdf_data(self): """ Test that data can be correctly written (and re-read) from a HDF5 file. """ times = np.linspace(1000000000.0, 1000086340.0, 1440) data = np.random.normal(0.0, 1e-25, size=(1440, 2)) det = "H1" parcontent = """\ PSRJ J0123+3456 RAJ 01:23:45.6789 DECJ 34:56:54.321 F0 567.89 F1 -1.2e-12 PEPOCH 56789 H0 9.87e-26 COSIOTA 0.3 PSI 1.1 PHI0 2.4 """ parfile = "J0123+3456.par" # add content to the par file with open(parfile, "w") as fp: fp.write(parcontent) het = HeterodynedData(data, times=times, detector=det, par=parfile) for suffix in ["hdf5", "hdf", "h5"]: datafile = "testdata.{}".format(suffix) het.write(datafile, overwrite=True) # read in data hetnew = HeterodynedData.read(datafile) assert np.array_equal(het.data, hetnew.data) assert np.array_equal(het.times, hetnew.times) # check that detector and par file are read in correctly assert hetnew.detector == det for key in het.par.as_dict(): if isinstance(hetnew.par[key], str): assert hetnew.par[key] == het.par[key] else: assert np.allclose(hetnew.par[key], het.par[key]) # check version information is stored assert het.cwinpy_version == hetnew.cwinpy_version assert het.cwinpy_version == cwinpy.__version__ os.remove(datafile) # clean up file os.remove(parfile)
def test_merge_data(self): """ Test merging multiple data sets during reading. """ # create three sets of data times1 = np.linspace(1000000000.0, 1000086340.0, 1440) data1 = np.random.normal(0.0, 1e-25, size=(len(times1), 2)) stds = 1e-25 * np.ones_like(times1) data1 = np.column_stack((data1, stds)) times2 = np.linspace(999913600.0, 999999940.0, 1440) data2 = np.random.normal(0.0, 1e-25, size=(len(times2), 2)) stds = 1e-25 * np.ones_like(times2) data2 = np.column_stack((data2, stds)) # don't add standard deviations to third data set for now times3 = np.linspace(1000186400.0, 1000359140.0, 2880) data3 = np.random.normal(0.0, 1e-25, size=(len(times3), 2)) parcontent1 = """\ PSRJ J0123+3456 RAJ 01:23:45.6789 DECJ 34:56:54.321 F0 567.89 F1 -1.2e-12 PEPOCH 56789 H0 9.87e-26 COSIOTA 0.3 PSI 1.1 PHI0 2.4 """ parfile1 = "J0123+3456.par" parcontent2 = """\ PSRJ J0123+3457 RAJ 01:23:45.6789 DECJ 34:56:54.321 F0 567.89 F1 -1.2e-12 PEPOCH 56789 H0 9.87e-26 COSIOTA 0.3 PSI 1.1 PHI0 2.4 """ parfile2 = "J0123+3457.par" # add content to the par file for parfile, parcontent in zip([parfile1, parfile2], [parcontent1, parcontent2]): with open(parfile, "w") as fp: fp.write(parcontent) # test for overlapping times datafiles = [] datalist = [data1, data2, data1] timeslist = [times1, times2, times1] N = len(datalist) for i in range(N): datafile = "testdata_H1_{}.hdf5".format(i) datafiles.append(datafile) # write out data het = HeterodynedData(datalist[i], times=timeslist[i], detector="H1", par=parfile1) het.write(datafile, overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Cannot merge overlapping data" in str(e) datalist = [data1, data2, data3] timeslist = [times1, times2, times3] # test for inconsistent detectors when merging for i, det in enumerate(["H1", "H1", "L1"]): # write out data het = HeterodynedData(datalist[i], times=timeslist[i], detector=det, par=parfile1) het.write(datafiles[i], overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Incompatible detectors" in str(e) # test for inconsistent pulsars for i in range(N): # write out data het = HeterodynedData( datalist[i], times=timeslist[i], detector="H1", par=(parfile1 if i == 0 else parfile2), ) het.write(datafiles[i], overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Incompatible pulsars" in str(e) # test for inconsistent frequency scale factors for i in range(N): # write out data het = HeterodynedData( datalist[i], times=timeslist[i], detector="H1", par=parfile1, freqfactor=(2 if i == 0 else 1), ) het.write(datafiles[i], overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Incompatible frequency factors" in str(e) # check for inconsistencies in whether variances were set or not for i in range(N): # write out data het = HeterodynedData( datalist[i], times=timeslist[i], detector="H1", par=parfile1, freqfactor=2, ) het.write(datafiles[i], overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Incompatible setting of variances" in str(e) # make data sets have compatible variances settings stds = 1e-25 * np.ones_like(times3) data3 = np.column_stack((data3, stds)) datalist[-1] = data3 # check for inconsistent injection of a signal for i in range(N): # write out data het = HeterodynedData( datalist[i], times=timeslist[i], detector="H1", par=parfile1, freqfactor=2, inject=(True if i < (N - 1) else False), ) het.write(datafiles[i], overwrite=True) # read in data with pytest.raises(ValueError) as e: _ = HeterodynedData.read(datafiles) assert "Incompatible injection times" in str(e) # create consistent files for merging and check the output hets = [] for i in range(N): # write out data het = HeterodynedData( datalist[i], times=timeslist[i], detector="H1", par=parfile1, freqfactor=2, inject=True, ) # add dummy heterodyne_arguments for testing het.heterodyne_arguments = {"dummy": "argument"} het.write(datafiles[i], overwrite=True) hets.append(het) # store for comparisons # read in data newhet = HeterodynedData.read(datafiles) # test times are correct and sorted times = np.concatenate((times2, times1, times3)) # correct time order assert len(newhet) == len(times) assert np.array_equal(times, newhet.times.value) assert newhet.dt.value == np.min(np.diff(times)) # test data is correct assert np.array_equal( newhet.data, np.concatenate([hets[i].data for i in [1, 0, 2]])) # test injection data assert newhet.injtimes.shape == (N, 2) assert np.allclose( newhet.injection_data, np.concatenate([hets[i].injection_data for i in [1, 0, 2]]), ) # test heterodyne arguments assert len(newhet.heterodyne_arguments) == N assert all([ hetargs == { "dummy": "argument" } for hetargs in newhet.heterodyne_arguments ]) # remove par files for parfile in [parfile1, parfile2]: os.remove(parfile) # remove data files for datafile in datafiles: os.remove(datafile)
def test_write_hdf_data_std(self): """ Test that data can be correctly written (and re-read) from a HDF5 file with the standard deviations also output. Also, add an injection! """ times = np.linspace(1000000000.0, 1000086340.0, 1440) data = np.random.normal(0.0, 1e-25, size=(1440, 2)) stds = 1e-25 * np.ones_like(times) data = np.column_stack((data, stds)) det = "H1" parcontent = """\ PSRJ J0123+3456 RAJ 01:23:45.6789 DECJ 34:56:54.321 F0 567.89 F1 -1.2e-12 PEPOCH 56789 H0 9.87e-26 COSIOTA 0.3 PSI 1.1 PHI0 2.4 """ parfile = "J0123+3456.par" # add content to the par file with open(parfile, "w") as fp: fp.write(parcontent) het = HeterodynedData(data, times=times, detector=det, par=parfile, inject=True) for suffix in ["hdf5", "hdf", "h5"]: datafile = "testdata.{}".format(suffix) het.write(datafile, overwrite=True) # read in data hetnew = HeterodynedData.read(datafile) assert np.array_equal(het.data, hetnew.data) assert np.array_equal(het.times, hetnew.times) assert np.array_equal(het.stds, hetnew.stds) assert hetnew.injection is True assert np.array_equal(het.injection_data, hetnew.injection_data) # check that detector and par file are read in correctly assert hetnew.detector == det for key in het.par.as_dict(): if key in hetnew.par.as_dict(): if isinstance(hetnew.par[key], str): assert hetnew.par[key] == het.par[key] assert hetnew.injpar[key] == het.injpar[key] else: assert np.allclose(hetnew.par[key], het.par[key]) assert np.allclose(hetnew.injpar[key], het.injpar[key]) os.remove(datafile) # clean up file os.remove(parfile)
def test_heterodyne(self): """ Test heterodyning on fake data. """ segments = [(self.fakedatastarts[i], self.fakedatastarts[i] + self.fakedataduration[i]) for i in range(len(self.fakedatastarts))] het = Heterodyne( pulsarfiles=self.fakeparfile, pulsars=["J0000+0000"], segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], ) with pytest.raises(TypeError): het.stride = "ksgdk" with pytest.raises(TypeError): het.stride = 4.5 with pytest.raises(ValueError): het.stride = -1 with pytest.raises(TypeError): het.filterknee = "lshdl" with pytest.raises(ValueError): het.filterknee = 0 with pytest.raises(TypeError): het.freqfactor = "ldkme" with pytest.raises(ValueError): het.freqfactor = -2.3 # test that output directory has defaulted to cwd assert os.path.split(list( het.outputfiles.values())[0])[0] == os.getcwd() # test setting an output directory outdir = os.path.join(self.fakedatadir, "heterodyne_output") het.outputfiles = outdir assert len(het.outputfiles) == 1 assert list(het.outputfiles.keys()) == ["J0000+0000"] assert list(het.outputfiles.values()) == [ os.path.join( outdir, het.label.format(psr="J0000+0000", gpsstart=None, gpsend=None, det="H1", freqfactor=2), ) ] with pytest.raises(ValueError): # attempt to include glitch evolution without setting includessb to True het.heterodyne(includeglitch=True) # perform first stage heterodyne het = heterodyne( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=86400 // 2, output=outdir, resamplerate=1, ) # expected length (after cropping) uncroppedsegs = [ seg for seg in segments if (seg[1] - seg[0]) > het.crop ] length = (het.resamplerate * np.diff(uncroppedsegs).sum() - 2 * len(uncroppedsegs) * het.crop) # expected start time (after cropping) t0 = segments[0][0] + het.crop + 0.5 / het.resamplerate # expected end time (after croppping) tend = segments[-1][-1] - het.crop - 0.5 / het.resamplerate # check output for psr in ["J0000+0000", "J1111+1111", "J2222+2222"]: assert os.path.isfile(het.outputfiles[psr]) hetdata = HeterodynedData.read(het.outputfiles[psr]) assert len(hetdata) == length assert het.resamplerate == hetdata.dt.value assert t0 == hetdata.times.value[0] assert tend == hetdata.times.value[-1] assert het.detector == hetdata.detector # perform second stage of heterodyne with pytest.raises(TypeError): Heterodyne(heterodyneddata=0) fineoutdir = os.path.join(self.fakedatadir, "fine_heterodyne_output") # first heterodyne without SSB het2 = heterodyne( detector=self.fakedatadetectors[0], heterodyneddata=outdir, # pass previous output directory pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=False, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) models = [] lengthnew = int( np.sum([ np.floor( ((seg[1] - seg[0]) - 2 * het2.crop) * het2.resamplerate) for seg in uncroppedsegs ])) for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het2.outputfiles[psr]) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == lengthnew # set expected model sim = HeterodynedCWSimulator( hetdata.par, hetdata.detector, times=hetdata.times.value, earth_ephem=hetdata.ephemearth, sun_ephem=hetdata.ephemsun, ) # due to how the HeterodynedCWSimulator works we need to set # updateglphase = True for the glitching signal to generate a # signal without the glitch phase included! models.append( sim.model( freqfactor=hetdata.freq_factor, updateglphase=(True if psr == "J2222+2222" else False), )) # without inclusion of SSB model should not match assert np.any(relative_difference(hetdata.data, models[i]) > 5e-3) # now heterodyne with SSB del het2 het2 = heterodyne( detector=self.fakedatadetectors[0], heterodyneddata=outdir, # pass previous output directory pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", overwrite=True, ) for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het2.outputfiles[psr]) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == lengthnew # check output matches model to within 2% if psr == "J0000+0000": # isolated pulsar assert np.all( relative_difference(hetdata.data, models[i]) < 0.02) else: # without inclusion of BSB/glitch phase model should not match assert np.any( relative_difference(hetdata.data, models[i]) > 0.02) # now heterodyne with SSB and BSB del het2 het2 = heterodyne( detector=self.fakedatadetectors[0], heterodyneddata={ psr: het.outputfiles[psr] for psr in ["J0000+0000", "J1111+1111", "J2222+2222"] }, # test using dictionary pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, includebsb=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", overwrite=True, ) for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het2.outputfiles[psr]) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == lengthnew if psr in [ "J0000+0000", "J1111+1111", ]: # isolated and binary pulsar (non-glitching) assert np.all( relative_difference(hetdata.data, models[i]) < 0.02) else: # without inclusion glitch phase model should not match assert np.any( relative_difference(hetdata.data, models[i]) > 0.02) # now heterodyne with SSB, BSB and glitch phase del het2 het2 = heterodyne( detector=self.fakedatadetectors[0], heterodyneddata={ psr: het.outputfiles[psr] for psr in ["J0000+0000", "J1111+1111", "J2222+2222"] }, # test using dictionary pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, includebsb=True, includeglitch=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", overwrite=True, ) for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het2.outputfiles[psr]) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == lengthnew assert np.all(relative_difference(hetdata.data, models[i]) < 0.02)
def test_knope(self): """ Test full knope pipeline. """ segments = [(self.fakedatastarts[i], self.fakedatastarts[i] + self.fakedataduration[i]) for i in range(len(self.fakedatastarts))] fulloutdir = os.path.join(self.fakedatadir, "full_heterodyne_output") # USING KEYWORD ARGUMENTS # heterodyned keyword arguments hetkwargs = dict( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=86400 // 2, resamplerate=1 / 60, includessb=True, output=fulloutdir, label="heterodyne_kwargs_{psr}_{det}_{freqfactor}.hdf5", ) # parameter estimation keyword arguments prior = PriorDict( {"h0": Uniform(name="h0", minimum=0.0, maximum=5e-25)}) pekwargs = dict(prior=prior, grid=True, grid_kwargs={ "grid_size": 100, "label": "pe_kwargs" }) # run knope hetkw, perunkw = knope(hetkwargs=hetkwargs, pekwargs=pekwargs) # USING CONFIGURATION FILES hetconfigstr = ( "detector = {}\n" "starttime = {}\n" "endtime = {}\n" "pulsarfiles = {}\n" "framecache = {}\n" "channel = {}\n" "segmentlist = {}\n" "output = {}\n" "stride = {}\n" "freqfactor = {}\n" "resamplerate = {}\n" "includessb = {}\n" "label = heterodyne_config_{{psr}}_{{det}}_{{freqfactor}}.hdf5\n") # create segment list file seglistfile = "segments.txt" with open(seglistfile, "w") as fp: for segment in segments: fp.write(f"{segment[0]} {segment[1]}\n") hetconfigfile = "hetconfig.ini" with open(hetconfigfile, "w") as fp: fp.write( hetconfigstr.format( self.fakedatadetectors[0], hetkwargs["starttime"], hetkwargs["endtime"], hetkwargs["pulsarfiles"][0], hetkwargs["framecache"], hetkwargs["channel"], seglistfile, hetkwargs["output"], hetkwargs["stride"], hetkwargs["freqfactor"], hetkwargs["resamplerate"], hetkwargs["includessb"], )) prior.to_file(outdir=".", label="knope_test") peconfigstr = ("prior = knope_test.prior\n" "grid = {}\n" "grid_kwargs = {}\n" "label = pe_config\n") peconfigfile = "peconfig.ini" pekwargs["grid_kwargs"]["label"] = "pe_config" with open(peconfigfile, "w") as fp: fp.write( peconfigstr.format(pekwargs["grid"], pekwargs["grid_kwargs"])) # run knope hetcon, peruncon = knope(heterodyne_config=hetconfigfile, pe_config=peconfigfile) # check for consistent heterodyne outputs hkw = HeterodynedData.read( hetkw[2.0][0].outputfiles[self.fakepulsarpar[0]["PSRJ"]]) hc = HeterodynedData.read( hetcon[2.0][0].outputfiles[self.fakepulsarpar[0]["PSRJ"]]) assert np.array_equal(hkw.times.value, hc.times.value) assert np.array_equal(hkw.data, hc.data) # check for consistent parameter estimation outputs assert (perunkw[self.fakepulsarpar[0]["PSRJ"]].grid.ln_evidence == peruncon[self.fakepulsarpar[0]["PSRJ"]].grid.ln_evidence) assert np.array_equal( perunkw[self.fakepulsarpar[0]["PSRJ"]].grid.mesh_grid[0], peruncon[self.fakepulsarpar[0]["PSRJ"]].grid.mesh_grid[0], ) assert np.array_equal( perunkw[self.fakepulsarpar[0]["PSRJ"]].grid.ln_posterior, peruncon[self.fakepulsarpar[0]["PSRJ"]].grid.ln_posterior, ) os.remove("knope_test.prior") os.remove(seglistfile) os.remove(hetconfigfile) os.remove(peconfigfile)
def test_full_heterodyne_tempo2(self): """ Test heterodyning on fake data, performing the heterodyne in one step, using TEMPO2 for the phase calculation. """ segments = [(self.fakedatastarts[i], self.fakedatastarts[i] + self.fakedataduration[i]) for i in range(len(self.fakedatastarts))] # perform heterodyne in one step fulloutdir = os.path.join(self.fakedatadir, "full_heterodyne_output_tempo2") inputkwargs = dict( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=86400 // 2, resamplerate=1 / 60, usetempo2=True, output=fulloutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het = heterodyne(**inputkwargs) # compare against model for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het.outputfiles[psr]) assert het.resamplerate == 1 / hetdata.dt.value # check heterodyne_arguments were stored and retrieved correctly assert isinstance(hetdata.heterodyne_arguments, dict) for param in inputkwargs: if param == "pulsarfiles": assert inputkwargs[param][ i] == hetdata.heterodyne_arguments[param] assert hetdata.heterodyne_arguments["pulsars"] == psr else: assert inputkwargs[param] == hetdata.heterodyne_arguments[ param] # set expected model sim = HeterodynedCWSimulator( hetdata.par, hetdata.detector, times=hetdata.times.value, earth_ephem=hetdata.ephemearth, sun_ephem=hetdata.ephemsun, ) # due to how the HeterodynedCWSimulator works we need to set # updateglphase = True for the glitching signal to generate a # signal without the glitch phase included! model = sim.model( freqfactor=hetdata.freq_factor, updateglphase=(True if psr == "J2222+2222" else False), ) # increase tolerance for acceptance due to small outliers (still # equivalent at the ~2% level) if psr == "J0000+0000": assert np.all(relative_difference(hetdata.data, model) < 0.02) # check that the models match to within 1e-5 assert mismatch(hetdata.data, model) < 1e-5 # for binary signals the initial phase when using tempo2 will # be shifted, but check that the shift is approximately # constant (maximum variation within 1.5 degs and standard # deviation within 0.1 degs) phasedata = np.angle(hetdata.data, deg=True) phasemodel = np.angle(model, deg=True) phasediff = phasedata - phasemodel # add on 180 degs so that J0000+0000, which should have zero phase shift, # passes the tests (otherwise there are point around 0 and 360 degs) phasediff = np.mod(phasediff + 180, 360) assert np.std(phasediff) < 0.1 assert phasediff.max() - phasediff.min() < 1.5
def test_full_heterodyne(self): """ Test heterodyning on fake data, performing the heterodyne in one step. """ segments = [(self.fakedatastarts[i], self.fakedatastarts[i] + self.fakedataduration[i]) for i in range(len(self.fakedatastarts))] # perform heterodyne in one step fulloutdir = os.path.join(self.fakedatadir, "full_heterodyne_output") inputkwargs = dict( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=86400 // 2, resamplerate=1 / 60, includessb=True, includebsb=True, includeglitch=True, output=fulloutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het = heterodyne(**inputkwargs) # compare against model for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read(het.outputfiles[psr]) assert het.resamplerate == 1 / hetdata.dt.value # check heterodyne_arguments were stored and retrieved correctly assert isinstance(hetdata.heterodyne_arguments, dict) for param in inputkwargs: if param == "pulsarfiles": assert inputkwargs[param][ i] == hetdata.heterodyne_arguments[param] assert hetdata.heterodyne_arguments["pulsars"] == psr else: assert inputkwargs[param] == hetdata.heterodyne_arguments[ param] # set expected model sim = HeterodynedCWSimulator( hetdata.par, hetdata.detector, times=hetdata.times.value, earth_ephem=hetdata.ephemearth, sun_ephem=hetdata.ephemsun, ) # due to how the HeterodynedCWSimulator works we need to set # updateglphase = True for the glitching signal to generate a # signal without the glitch phase included! model = sim.model( freqfactor=hetdata.freq_factor, updateglphase=(True if psr == "J2222+2222" else False), ) # increase tolerance for acceptance due to small outliers (still # equivalent at the ~2% level) assert np.all(relative_difference(hetdata.data, model) < 0.02)
def test_optimal_snr(self): with pytest.raises(TypeError): # invalid input type for results directory optimal_snr(9.8, self.hetdir) with pytest.raises(TypeError): # invalid input type for heterodyned data directory optimal_snr(self.resdir, 1.6) with pytest.raises(ValueError): # invalid "which" value optimal_snr(self.resdir, self.hetdir, which="blah") resfiles = find_results_files(self.resdir) hetfiles = find_heterodyned_files(self.hetdir) # get single detector, single source SNR snr = optimal_snr(resfiles[self.pnames[0]]["H1"], hetfiles[self.pnames[0]]["H1"]) assert isinstance(snr, float) # use a dictionary instead snr = optimal_snr(resfiles[self.pnames[0]]["H1"], {"H1": hetfiles[self.pnames[0]]["H1"]}) assert isinstance(snr, float) # check using likelihood gives same value as posterior (a flat prior was used to produce the files) snrl = optimal_snr( resfiles[self.pnames[0]]["H1"], hetfiles[self.pnames[0]]["H1"], which="likelihood", ) assert snr == snrl # pass remove outliers flag snr = optimal_snr( resfiles[self.pnames[0]]["H1"], {"H1": hetfiles[self.pnames[0]]["H1"]}, remove_outliers=True, ) assert isinstance(snr, float) # pass result as Result object snr = optimal_snr( read_in_result(resfiles[self.pnames[0]]["H1"]), hetfiles[self.pnames[0]]["H1"], ) assert isinstance(snr, float) and snr == snrl # pass heterodyned data as HeterodynedData object snr = optimal_snr( resfiles[self.pnames[0]]["H1"], HeterodynedData.read(hetfiles[self.pnames[0]]["H1"]), ) assert isinstance(snr, float) # get single joint multi-detector result snr = optimal_snr(resfiles[self.pnames[0]]["H1L1"], hetfiles[self.pnames[0]]) assert isinstance(snr, float) # do the same, but with MultiHeterodynedData object snr = optimal_snr( resfiles[self.pnames[0]]["H1L1"], MultiHeterodynedData(hetfiles[self.pnames[0]]), ) assert isinstance(snr, float) # get results for all pulsars and all detectors combination snr = optimal_snr(self.resdir, self.hetdir) assert isinstance(snr, dict) assert sorted(snr.keys()) == sorted(self.pnames) for k in snr: assert sorted(snr[k].keys()) == sorted(self.dets) assert all([isinstance(v, float) for v in snr[k].values()]) # pass in par files directory snr = optimal_snr(self.resdir, self.hetdir, par=self.pardir) assert isinstance(snr, dict) assert sorted(snr.keys()) == sorted(self.pnames) for k in snr: assert sorted(snr[k].keys()) == sorted(self.dets) assert all([isinstance(v, float) for v in snr[k].values()]) # get results for a single detector snr = optimal_snr(self.resdir, self.hetdir, det="H1") assert isinstance(snr, dict) assert sorted(snr.keys()) == sorted(self.pnames) assert all([isinstance(v, float) for v in snr.values()])
def test_heterodyne(self): """ Test heterodyning on fake data. """ segments = [(time, time + self.fakedataduration) for time in self.fakedatastarts] het = Heterodyne( pulsarfiles=self.fakeparfile, pulsars=["J0000+0000"], segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], ) with pytest.raises(TypeError): het.stride = "ksgdk" with pytest.raises(TypeError): het.stride = 4.5 with pytest.raises(ValueError): het.stride = -1 with pytest.raises(TypeError): het.filterknee = "lshdl" with pytest.raises(ValueError): het.filterknee = 0 with pytest.raises(TypeError): het.freqfactor = "ldkme" with pytest.raises(ValueError): het.freqfactor = -2.3 with pytest.raises(ValueError): # test that not setting an output gives a error het.heterodyne() # test setting an output directory outdir = os.path.join(self.fakedatadir, "heterodyne_output") het.outputfiles = outdir assert len(het.outputfiles) == 1 assert list(het.outputfiles.keys()) == ["J0000+0000"] assert list( het.outputfiles.values()) == [os.path.join(outdir, het.label)] with pytest.raises(ValueError): # attempt to include glitch evolution without setting includessb to True het.heterodyne(includeglitch=True) # perform first stage heterodyne het = Heterodyne( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=self.fakedataduration // 2, output=outdir, resamplerate=1, ) het.heterodyne() labeldict = { "det": het.detector, "gpsstart": int(het.starttime), "gpsend": int(het.endtime), "freqfactor": int(het.freqfactor), } # expected length (after cropping) length = (het.resamplerate * np.diff(segments).sum() - 2 * len(segments) * het.crop) # expected start time (after cropping) t0 = segments[0][0] + het.crop + 0.5 / het.resamplerate # expected end time (after croppping) tend = segments[-1][-1] - het.crop - 0.5 / het.resamplerate # check output for psr in ["J0000+0000", "J1111+1111", "J2222+2222"]: assert os.path.isfile(het.outputfiles[psr].format(**labeldict, psr=psr)) hetdata = HeterodynedData.read( het.outputfiles[psr].format(**labeldict, psr=psr)) assert len(hetdata) == length assert het.resamplerate == hetdata.dt.value assert t0 == hetdata.times.value[0] assert tend == hetdata.times.value[-1] assert het.detector == hetdata.detector # perform second stage of heterodyne with pytest.raises(TypeError): Heterodyne(heterodyneddata=0) fineoutdir = os.path.join(self.fakedatadir, "fine_heterodyne_output") # first heterodyne without SSB het2 = Heterodyne( detector=self.fakedatadetectors[0], heterodyneddata=outdir, # pass previous output directory pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=False, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het2.heterodyne() models = [] for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read( het2.outputfiles[psr].format(**labeldict, psr=psr)) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == int(length * het2.resamplerate) # set expected model sim = HeterodynedCWSimulator( hetdata.par, hetdata.detector, times=hetdata.times.value, earth_ephem=hetdata.ephemearth, sun_ephem=hetdata.ephemsun, ) # due to how the HeterodynedCWSimulator works we need to set # updateglphase = True for the glitching signal to generate a # signal without the glitch phase included! models.append( sim.model( usephase=True, freqfactor=hetdata.freq_factor, updateglphase=(True if psr == "J2222+2222" else False), )) # without inclusion of SSB model should not match assert np.any( np.abs(hetdata.data - models[i]) / np.abs(models[i]) > 5e-3) # now heterodyne with SSB del het2 het2 = Heterodyne( detector=self.fakedatadetectors[0], heterodyneddata=outdir, # pass previous output directory pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het2.heterodyne() for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read( het2.outputfiles[psr].format(**labeldict, psr=psr)) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == int(length * het2.resamplerate) if psr == "J0000+0000": # isolated pulsar assert np.all( np.abs(hetdata.data - models[i]) / np.abs(models[i]) < 5e-3) else: # without inclusion of BSB/glitch phase model should not match assert np.any( np.abs(hetdata.data - models[i]) / np.abs(models[i]) > 5e-3) # now heterodyne with SSB and BSB del het2 het2 = Heterodyne( detector=self.fakedatadetectors[0], heterodyneddata={ psr: het.outputfiles[psr].format(**labeldict, psr=psr) for psr in ["J0000+0000", "J1111+1111", "J2222+2222"] }, # test using dictionary pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, includebsb=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het2.heterodyne() for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read( het2.outputfiles[psr].format(**labeldict, psr=psr)) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == int(length * het2.resamplerate) if psr in [ "J0000+0000", "J1111+1111", ]: # isolated and binary pulsar (non-glitching) assert np.all( np.abs(hetdata.data - models[i]) / np.abs(models[i]) < 1e-2) else: # without inclusion glitch phase model should not match assert np.any( np.abs(hetdata.data - models[i]) / np.abs(models[i]) > 1e-2) # now heterodyne with SSB, BSB and glitch phase del het2 het2 = Heterodyne( detector=self.fakedatadetectors[0], heterodyneddata={ psr: het.outputfiles[psr].format(**labeldict, psr=psr) for psr in ["J0000+0000", "J1111+1111", "J2222+2222"] }, # test using dictionary pulsarfiles=self.fakeparfile, freqfactor=2, resamplerate=1 / 60, includessb=True, includebsb=True, includeglitch=True, output=fineoutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het2.heterodyne() for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read( het2.outputfiles[psr].format(**labeldict, psr=psr)) assert het2.resamplerate == 1 / hetdata.dt.value assert len(hetdata) == int(length * het2.resamplerate) # increase tolerance for acceptance due to small outliers (still # equivalent at the ~2% level) assert np.all( np.abs(hetdata.data - models[i]) / np.abs(models[i]) < 2e-2)
def test_full_heterodyne(self): """ Test heterodyning on fake data, performing the heterodyne in one step. """ segments = [(time, time + self.fakedataduration) for time in self.fakedatastarts] # perform heterodyne in one step fulloutdir = os.path.join(self.fakedatadir, "full_heterodyne_output") het = Heterodyne( starttime=segments[0][0], endtime=segments[-1][-1], pulsarfiles=self.fakeparfile, segmentlist=segments, framecache=self.fakedatadir, channel=self.fakedatachannels[0], freqfactor=2, stride=self.fakedataduration // 2, resamplerate=1 / 60, includessb=True, includebsb=True, includeglitch=True, output=fulloutdir, label="heterodyne_{psr}_{det}_{freqfactor}.hdf5", ) het.heterodyne() labeldict = { "det": het.detector, "gpsstart": int(het.starttime), "gpsend": int(het.endtime), "freqfactor": int(het.freqfactor), } # compare against model for i, psr in enumerate(["J0000+0000", "J1111+1111", "J2222+2222"]): # load data hetdata = HeterodynedData.read( het.outputfiles[psr].format(**labeldict, psr=psr)) assert het.resamplerate == 1 / hetdata.dt.value # set expected model sim = HeterodynedCWSimulator( hetdata.par, hetdata.detector, times=hetdata.times.value, earth_ephem=hetdata.ephemearth, sun_ephem=hetdata.ephemsun, ) # due to how the HeterodynedCWSimulator works we need to set # updateglphase = True for the glitching signal to generate a # signal without the glitch phase included! model = sim.model( usephase=True, freqfactor=hetdata.freq_factor, updateglphase=(True if psr == "J2222+2222" else False), ) # increase tolerance for acceptance due to small outliers (still # equivalent at the ~2% level) assert np.all(np.abs(hetdata.data - model) / np.abs(model) < 2e-2)