def test_compare_ecorr_likelihood(self): """Compare basis and kernel ecorr methods.""" selection = Selection(selections.nanograv_backends) ef = white_signals.MeasurementNoise() ec = white_signals.EcorrKernelNoise(selection=selection) ec2 = gp_signals.EcorrBasisModel(selection=selection) tm = gp_signals.TimingModel() m = ef + ec + tm m2 = ef + ec2 + tm pta1 = signal_base.PTA([m(p) for p in self.psrs]) pta2 = signal_base.PTA([m2(p) for p in self.psrs]) params = parameter.sample(pta1.params) l1 = pta1.get_lnlikelihood(params) # need to translate some names for EcorrBasis basis_params = {} for parname, parval in params.items(): if "log10_ecorr" in parname: toks = parname.split("_") basisname = toks[0] + "_basis_ecorr_" + "_".join(toks[1:]) basis_params[basisname] = parval params.update(basis_params) l2 = pta2.get_lnlikelihood(params) msg = "Likelihood mismatch between ECORR methods" assert np.allclose(l1, l2), msg
def test_ephemeris(self): """Test physical-ephemeris delay, made three ways: from marginalized GP, from coefficient-based GP, from deterministic model.""" ef = white_signals.MeasurementNoise( efac=parameter.Uniform(0.1, 5.0)) eph = gp_signals.FourierBasisCommonGP_physicalephem( sat_orb_elements=None) ephc = gp_signals.FourierBasisCommonGP_physicalephem( sat_orb_elements=None, coefficients=True) ephd = deterministic_signals.PhysicalEphemerisSignal( sat_orb_elements=False) model = ef + eph modelc = ef + ephc modeld = ef + ephd pta = signal_base.PTA([model(self.psr), model(self.psr2)]) ptac = signal_base.PTA([modelc(self.psr), modelc(self.psr2)]) ptad = signal_base.PTA([modeld(self.psr), modeld(self.psr2)]) cf = 1e-3 * np.random.randn(11) cf[0] = 1e-5 # this is more sensitive to linearity bs = pta.get_basis() da = [np.dot(bs[0], cf), np.dot(bs[1], cf)] params = { "B1855+09_efac": 1, "B1937+21_efac": 1, "B1855+09_phys_ephem_gp_coefficients": cf, "B1937+21_phys_ephem_gp_coefficients": cf, } db = ptac.get_delay(params=params) dparams = { "B1855+09_efac": 1, "B1937+21_efac": 1, "frame_drift_rate": cf[0], "d_jupiter_mass": cf[1], "d_saturn_mass": cf[2], "d_uranus_mass": cf[3], "d_neptune_mass": cf[4], "jup_orb_elements": cf[5:], } dc = ptad.get_delay(params=dparams) msg = "Reconstructed ephemeris signals differ!" assert np.allclose(da[0], db[0]), msg assert np.allclose(da[1], db[1]), msg # we don't expect an exact match since we are linearizing assert np.allclose(da[0], dc[0], atol=1e-3), msg assert np.allclose(da[1], dc[1], atol=1e-3), msg
def test_formalism(self): # create marginalized model ef = white_signals.MeasurementNoise( efac=parameter.Uniform(0.1, 5.0)) tm = gp_signals.TimingModel() ec = gp_signals.EcorrBasisModel( log10_ecorr=parameter.Uniform(-10, -5)) pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7)) rn = gp_signals.FourierBasisGP(spectrum=pl, components=10) model = ef + tm + ec + rn pta = signal_base.PTA([model(self.psr)]) # create hierarchical model tmc = gp_signals.TimingModel(coefficients=True) ecc = gp_signals.EcorrBasisModel(log10_ecorr=parameter.Uniform( -10, -5), coefficients=True) rnc = gp_signals.FourierBasisGP(spectrum=pl, components=10, coefficients=True) modelc = ef + tmc + ecc + rnc ptac = signal_base.PTA([modelc(self.psr)]) ps = { "B1855+09_efac": 1, "B1855+09_basis_ecorr_log10_ecorr": -6, "B1855+09_red_noise_log10_A": -14, "B1855+09_red_noise_gamma": 3, } psc = utils.get_coefficients(pta, ps) d1 = ptac.get_delay(psc)[0] d2 = (np.dot(pta.pulsarmodels[0].signals[1].get_basis(ps), psc["B1855+09_linear_timing_model_coefficients"]) + np.dot(pta.pulsarmodels[0].signals[2].get_basis(ps), psc["B1855+09_basis_ecorr_coefficients"]) + np.dot(pta.pulsarmodels[0].signals[3].get_basis(ps), psc["B1855+09_red_noise_coefficients"])) msg = "Implicit and explicit PTA delays are different." assert np.allclose(d1, d2), msg l1 = pta.get_lnlikelihood(ps) l2 = ptac.get_lnlikelihood(psc) # I don't know how to integrate l2 to match l1... msg = "Marginal and hierarchical likelihoods should be different." assert l1 != l2, msg
def __init__(self, psrs, params=None): print('Initializing the model...') efac = parameter.Constant() equad = parameter.Constant() ef = white_signals.MeasurementNoise(efac=efac) eq = white_signals.EquadNoise(log10_equad=equad) tm = gp_signals.TimingModel(use_svd=True) s = eq + ef + tm model = [] for p in psrs: model.append(s(p)) self.pta = signal_base.PTA(model) # set white noise parameters if params is None: print('No noise dictionary provided!...') else: self.pta.set_default_params(params) self.psrs = psrs self.params = params self.Nmats = None
def model_1(psr): """ Reads in enterprise Pulsar instance and returns a PTA instantiated with the standard NANOGrav noise model: 1. EFAC per backend/receiver system 2. EQUAD per backend/receiver system 3. ECORR per backend/receiver system 4. Red noise modeled as a power-law with 30 sampling frequencies 5. Linear timing model. """ # white noise s = white_noise_block(vary=True) # red noise s += red_noise_block() # timing model s += gp_signals.TimingModel() # set up PTA of one pta = signal_base.PTA([s(psr)]) return pta
def get_All_results(): # Modeling each pulsar. tm = gp_signals.TimingModel() wnb = models.white_noise_block(vary=True) dmn = models.dm_noise_block(components=30) spn = models.red_noise_block(components=30) model = tm + wnb + dmn + spn ptas = [signal_base.PTA(model(psr)) for psr in psrs] # Multiprocessing. jobs = [] RETs={} for i in range(len(psrs)): RETs[i] = multiprocessing.Manager().Value('i',0) p = multiprocessing.Process(target=get_pulsar_noise, args=(ptas[i],RETs[i])) jobs.append(p) p.start() for p in jobs: p.join() # Return the sum of the Ln Maximal Likelihood values. MLHselect = [RET.value for RET in RETs.values()] return MLHselect
def __init__(self, psrs, params=None, psrTerm=True, bayesephem=True, pta=None): if pta is None: # initialize standard model with fixed white noise # and powerlaw red noise # uses the implementation of ECORR in gp_signals print('Initializing the model...') tmin = np.min([p.toas.min() for p in psrs]) tmax = np.max([p.toas.max() for p in psrs]) Tspan = tmax - tmin s = deterministic.cw_block_circ(amp_prior='log-uniform', psrTerm=psrTerm, tref=tmin, name='cw') s += gp_signals.TimingModel() s += blocks.red_noise_block(prior='log-uniform', psd='powerlaw', Tspan=Tspan, components=30) if bayesephem: s += deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) # adding white-noise, and acting on psr objects models = [] for p in psrs: if 'NANOGrav' in p.flags['pta']: s2 = s + blocks.white_noise_block(vary=False, inc_ecorr=True, gp_ecorr=True) models.append(s2(p)) else: s3 = s + blocks.white_noise_block(vary=False, inc_ecorr=False) models.append(s3(p)) pta = signal_base.PTA(models) # set white noise parameters if params is None: print('No noise dictionary provided!') else: pta.set_default_params(params) self.pta = pta else: # user can specify their own pta object # if ECORR is included, use the implementation in gp_signals self.pta = pta self.psrs = psrs self.params = params self.Nmats = self.get_Nmats()
def test_vector_parameter_like(self): """Test vector parameter in a likelihood""" # white noise efac = parameter.Uniform(0.5, 2) ef = white_signals.MeasurementNoise(efac=efac) # red noise nf = 3 spec = free_spectrum(log10_rho=parameter.Uniform(-20, -10, size=nf)) rn = gp_signals.FourierBasisGP(spec, components=nf) # timing model tm = gp_signals.TimingModel() # combined signal s = ef + rn + tm # PTA pta = signal_base.PTA([s(self.psr)]) # parameters xs = np.hstack(p.sample() for p in pta.params) params = { "B1855+09_red_noise_log10_rho": xs[1:], "B1855+09_efac": xs[0] } # test log likelihood msg = "Likelihoods do not match" assert pta.get_lnlikelihood(xs) == pta.get_lnlikelihood(params), msg # test log prior msg = "Priors do not match" assert pta.get_lnprior(xs) == pta.get_lnprior(params), msg # test prior value prior = 1 / (2 - 0.5) * (1 / 10)**3 msg = "Prior value incorrect." assert np.allclose(pta.get_lnprior(xs), np.log(prior)), msg # test PTA level parameter names pnames = [ "B1855+09_efac", "B1855+09_red_noise_log10_rho_0", "B1855+09_red_noise_log10_rho_1", "B1855+09_red_noise_log10_rho_2", ] msg = "Incorrect parameter names" assert pta.param_names == pnames
def initialize_pta_sim(psrs, fgw): # continuous GW signal s = models.cw_block_circ(log10_fgw=np.log10(fgw), psrTerm=True) # white noise efac = parameter.Constant(1.0) s += white_signals.MeasurementNoise(efac=efac) # linearized timing model s += gp_signals.TimingModel(use_svd=True) model = [s(psr) for psr in psrs] pta = signal_base.PTA(model) return pta
def initialize_pta_sim(psrs, fgw, inc_efac=True, inc_equad=False, inc_ecorr=False, selection=None, inc_red_noise=False, noisedict=None): # continuous GW signal s = models.cw_block_circ(log10_fgw=np.log10(fgw), psrTerm=True) # linearized timing model s += gp_signals.TimingModel(use_svd=True) # white noise if selection == 'backend': selection = selections.Selection(selections.by_backend) if inc_efac: efac = parameter.Constant() s += white_signals.MeasurementNoise(efac=efac, selection=selection) if inc_equad: equad = parameter.Constant() s += white_signals.EquadNoise(log10_equad=equad, selection=selection) if inc_ecorr: ecorr = parameter.Constant() s += gp_signals.EcorrBasisModel(log10_ecorr=ecorr, selection=selection) if inc_red_noise: log10_A = parameter.Constant() gamma = parameter.Constant() pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) s += gp_signals.FourierBasisGP(pl, components=30) model = [s(psr) for psr in psrs] pta = signal_base.PTA(model) # set white noise parameters if noisedict is None: print('No noise dictionary provided!...') else: pta.set_default_params(noisedict) return pta
def pta_pshift(dmx_psrs, caplog): Tspan = model_utils.get_tspan(dmx_psrs) tm = gp_signals.TimingModel() wn = blocks.white_noise_block(inc_ecorr=True, tnequad=True) rn = blocks.red_noise_block(Tspan=Tspan) pseed = parameter.Uniform(0, 10000)('gw_pseed') gw_log10_A = parameter.Uniform(-18, -14)('gw_log10_A') gw_gamma = parameter.Constant(13. / 3)('gw_gamma') gw_pl = utils.powerlaw(log10_A=gw_log10_A, gamma=gw_gamma) gw_pshift = gp_signals.FourierBasisGP(spectrum=gw_pl, components=5, Tspan=Tspan, name='gw', pshift=True, pseed=pseed) model = tm + wn + rn + gw_pshift pta_pshift = signal_base.PTA([model(p) for p in dmx_psrs]) pta_pshift.set_default_params(noise_dict) return pta_pshift
def test_model_2a_altpol_spectrum(nodmx_psrs, caplog): log10_A_tt = parameter.LinearExp(-18, -12)('log10_A_tt') log10_A_st = parameter.LinearExp(-18, -12)('log10_A_st') log10_A_vl = parameter.LinearExp(-18, -15)('log10_A_vl') log10_A_sl = parameter.LinearExp(-18, -16)('log10_A_sl') kappa = parameter.Uniform(0, 15)('kappa') p_dist = parameter.Normal(1.0, 0.2) pl = model_orfs.generalized_gwpol_psd(log10_A_tt=log10_A_tt, log10_A_st=log10_A_st, log10_A_vl=log10_A_vl, log10_A_sl=log10_A_sl, kappa=kappa, p_dist=p_dist, alpha_tt=-2 / 3, alpha_alt=-1) s = models.white_noise_block(vary=False, inc_ecorr=True) s += models.red_noise_block(prior='log-uniform') s += gp_signals.FourierBasisGP(spectrum=pl, name='gw') s += gp_signals.TimingModel() m = signal_base.PTA([s(psr) for psr in nodmx_psrs]) m.set_default_params(noise_dict) for param in m.params: if 'gw_p_dist' in str(param): # get pulsar name and distance psr_name = str(param).split('_')[0].strip('"') psr_dist = [p._pdist for p in nodmx_psrs if psr_name in p.name][0] # edit prior settings param._prior = parameter.Normal(mu=psr_dist[0], sigma=psr_dist[1]) param._mu = psr_dist[0] param._sigma = psr_dist[1] assert hasattr(m, 'get_lnlikelihood')
crn_2 = gp_signals.FourierBasisGP(spectrum=cpl_2, components=30, Tspan=Tspan, name='other_gw') # gwb with Hellings and Downs correlations # Hellings and Downs ORF #orf = utils.hd_orf() #gwb_1 = gp_signals.FourierBasisCommonGP(cpl_1, orf, components=30, name='gw', Tspan=Tspan) #gwb_2 = gp_signals.FourierBasisCommonGP(cpl_2, orf, components=30, name='other_gw', Tspan=Tspan) # full model is sum of components model = ef + eq + ec + rn + tm + crn_1 + crn_2 #+ crn # initialize PTA pta = signal_base.PTA([model(psr) for psr in psrs]) with open(outdir + '/parameters.json', 'w') as fp: json.dump(pta.param_names, fp) #Set Default PTA parameters to the ones in the noisefiles pta.set_default_params(noise_params) #Pick random initial sampling xs = {par.name: par.sample() for par in pta.params} # dimension of parameter space ndim = len(xs) # initial jump covariance matrix cov = np.diag(np.ones(ndim) * 0.01**2)
### GWB ### gw = models.common_red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=Tspan, gamma_val=13 / 3., name='gw') base_model = wn if args.bayes_ephem: base_model += deterministic_signals.PhysicalEphemerisSignal( use_epoch_toas=True) model_1 = base_model + rn_plaw model_2a = model_1 + gw pta_noise = signal_base.PTA([model_1(p) for p in psrs]) pta_noise.set_default_params(noise) pta_gw = signal_base.PTA([model_2a(p) for p in psrs]) pta_gw.set_default_params(noise) ptas = {0: pta_noise, 1: pta_gw} hm = model_utils.HyperModel(models=ptas) sampler = hm.setup_sampler(outdir=args.outdir, resume=True) achrom_freqs = get_freqs(ptas[0]) # np.save(args.outdir + 'pars.npy', pta.param_names) # np.save(args.outdir + 'par_model.npy', np.array(pta.params).astype(str)) # np.save(args.outdir + 'signals.npy', list(pta.signals.keys())) np.savetxt(args.outdir + 'achrom_rn_freqs.txt', achrom_freqs, fmt='%.18e')
def model_gwb_bwm(psrs, psd='powerlaw', gamma_common=None, orf=None, Tmin_bwm=None, Tmax_bwm=None, skyloc=None, logmin=-18, logmax=-11, upper_limit=False, bayesephem=False): """ Reads in list of enterprise Pulsar instance and returns a PTA instantiated with both a GWB and a GW BWM model: per pulsar: 1. fixed EFAC per backend/receiver system 2. fixed EQUAD per backend/receiver system 3. fixed ECORR per backend/receiver system 4. Red noise modeled as a power-law with 30 sampling frequencies 5. Linear timing model. global: 1. Common red noise modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover'] 2. Deterministic GW burst with memory signal. 3. Optional physical ephemeris modeling. :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover']. 'powerlaw' is default value. :param gamma_common: Fixed common red process spectral index value. By default we vary the spectral index over the range [0, 7]. :param orf: String representing which overlap reduction function to use. By default we do not use any spatial correlations. Permitted values are ['hd', 'dipole', 'monopole']. :param Tmin_bwm: Min time to search for BWM (MJD). If omitted, uses first TOA. :param Tmax_bwm: Max time to search for BWM (MJD). If omitted, uses last TOA. :param skyloc: Fixed sky location of BWM signal search as [cos(theta), phi]. Search over sky location if ``None`` given. :param logmin: log of minimum BWM amplitude for prior (log10) :param logmax: log of maximum BWM amplitude for prior (log10) :param upper_limit: Perform upper limit on common red noise amplitude. By default this is set to False. Note that when perfoming upper limits it is recommended that the spectral index also be fixed to a specific value. :param bayesephem: Include BayesEphem model. Set to False by default """ amp_prior = 'uniform' if upper_limit else 'log-uniform' # find the maximum time span to set GW frequency sampling tmin = np.min([p.toas.min() for p in psrs]) tmax = np.max([p.toas.max() for p in psrs]) Tspan = tmax - tmin if Tmin_bwm == None: Tmin_bwm = tmin / const.day if Tmax_bwm == None: Tmax_bwm = tmax / const.day # white noise s = white_noise_block(vary=False) # red noise s += red_noise_block(prior=amp_prior, Tspan=Tspan) # GW BWM signal block s += bwm_block(Tmin_bwm, Tmax_bwm, amp_prior=amp_prior, skyloc=skyloc, logmin=logmin, logmax=logmax, name='bwm') # common red noise block s += common_red_noise_block(psd=psd, prior=amp_prior, Tspan=Tspan, gamma_val=gamma_common, name='gwb', orf=orf) # DM variations model if dmgp: s += dm_noise_block(gp_kernel='diag', psd='powerlaw', prior=amp_prior, Tspan=Tspan) s += dm_annual_signal() # DM exponential dip for J1713's DM event dmexp = dm_exponential_dip(tmin=54500, tmax=54900) s2 = s + dmexp # set up PTA mods = [] for p in psrs: if dmgp and 'J1713+0747' == p.name: mods.append(s2(p)) else: mods.append(s(p)) pta = signal_base.PTA(mods) return pta
def model_bwm(psrs, Tmin_bwm=None, Tmax_bwm=None, skyloc=None, logmin=-18, logmax=-11, upper_limit=False, bayesephem=False, sngl_psr=False, dmgp=False, free_rn=False): """ Reads in list of enterprise Pulsar instance and returns a PTA instantiated with BWM model: per pulsar: 1. fixed EFAC per backend/receiver system 2. fixed EQUAD per backend/receiver system 3. fixed ECORR per backend/receiver system 4. Red noise modeled as a power-law with 30 sampling frequencies 5. Linear timing model. global: 1. Deterministic GW burst with memory signal. 2. Optional physical ephemeris modeling. :param Tmin_bwm: Min time to search for BWM (MJD). If omitted, uses first TOA. :param Tmax_bwm: Max time to search for BWM (MJD). If omitted, uses last TOA. :param skyloc: Fixed sky location of BWM signal search as [cos(theta), phi]. Search over sky location if ``None`` given. :param logmin: log of minimum BWM amplitude for prior (log10) :param logmax: log of maximum BWM amplitude for prior (log10) :param upper_limit: Perform upper limit on common red noise amplitude. By default this is set to False. Note that when perfoming upper limits it is recommended that the spectral index also be fixed to a specific value. :param bayesephem: Include BayesEphem model. Set to False by default :param sngl_psr: run on a single pulsar only. Uses different BWM parameterization to avoid problem with sky nulls. Set to False by default. :param free_rn: Use free red noise spectrum model. Set to False by default. """ amp_prior = 'uniform' if upper_limit else 'log-uniform' # find the maximum time span to set GW frequency sampling tmin = np.min([p.toas.min() for p in psrs]) tmax = np.max([p.toas.max() for p in psrs]) Tspan = tmax - tmin if Tmin_bwm == None: Tmin_bwm = tmin / const.day if Tmax_bwm == None: Tmax_bwm = tmax / const.day # white noise s = white_noise_block(vary=False) # red noise if free_rn: s += free_noise_block(prior=amp_prior, Tspan=Tspan) else: s += red_noise_block(prior=amp_prior, Tspan=Tspan) # GW BWM signal block s += bwm_block(Tmin_bwm, Tmax_bwm, amp_prior=amp_prior, skyloc=skyloc, logmin=logmin, logmax=logmax, sngl=sngl_psr, name='bwm') # ephemeris model if bayesephem: s += deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) # timing model s += gp_signals.TimingModel(use_svd=True) # set up PTA pta = signal_base.PTA([s(psr) for psr in psrs]) return pta
def model_gwb(psrs, psd='powerlaw', gamma_common=None, orf=None, upper_limit=False, bayesephem=False): """ Reads in list of enterprise Pulsar instance and returns a PTA instantiated with GWB model: per pulsar: 1. fixed EFAC per backend/receiver system 2. fixed EQUAD per backend/receiver system 3. fixed ECORR per backend/receiver system 4. Red noise modeled as a power-law with 30 sampling frequencies 5. Linear timing model. global: 1.Common red noise modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover'] 2. Optional physical ephemeris modeling. :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover']. 'powerlaw' is default value. :param gamma_common: Fixed common red process spectral index value. By default we vary the spectral index over the range [0, 7]. :param orf: String representing which overlap reduction function to use. By default we do not use any spatial correlations. Permitted values are ['hd', 'dipole', 'monopole']. :param upper_limit: Perform upper limit on common red noise amplitude. By default this is set to False. Note that when perfoming upper limits it is recommended that the spectral index also be fixed to a specific value. :param bayesephem: Include BayesEphem model. Set to False by default """ amp_prior = 'uniform' if upper_limit else 'log-uniform' # find the maximum time span to set GW frequency sampling tmin = np.min([p.toas.min() for p in psrs]) tmax = np.max([p.toas.max() for p in psrs]) Tspan = tmax - tmin # white noise s = white_noise_block(vary=False) # red noise s += red_noise_block(prior=amp_prior, Tspan=Tspan) # common red noise block s += common_red_noise_block(psd=psd, prior=amp_prior, Tspan=Tspan, gamma_val=gamma_common, name='gwb', orf=orf) # ephemeris model if bayesephem: s += deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) # timing model s += gp_signals.TimingModel() # set up PTA pta = signal_base.PTA([s(psr) for psr in psrs]) return pta
base_model += deterministic_signals.PhysicalEphemerisSignal( use_epoch_toas=True) model_plaw = base_model + rn_plaw model_list = [] noise = {} for psr in psrs: if psr.name in args.free_spec_psrs: model_list.append(model_fs(psr)) noise.update(noise_fs[psr.name]) else: model_list.append(model_plaw(psr)) noise.update(noise_plaw[psr.name]) pta = signal_base.PTA(model_list) pta.set_default_params(noise) x0 = np.hstack(p.sample() for p in pta.params) ndim = x0.size # initial jump covariance matrix cov = np.diag(np.ones(ndim) * 0.01**2) # set up jump groups by red noise groups groups = model_utils.get_parameter_groups(pta) if args.bayes_ephem: eph_pars = [ 'd_jupiter_mass', 'd_neptune_mass', 'd_saturn_mass', 'd_uranus_mass', 'frame_drift_rate', 'jup_orb_elements_0', 'jup_orb_elements_1',
cos_gwtheta=costh, gwphi=phi, gwpol=pol) # BWM signal bwm = deterministic_signals.Deterministic(bwm_wf, name='bwm') # Timing Model tm = gp_signals.TimingModel(use_svd=True) # BayesEphem be = deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) # construct PTA mod = tm + wn + rn + bwm if args.BE: mod += be pta = signal_base.PTA([mod(p) for p in psrs]) pta.set_default_params(noise_params) sumfile = os.path.join(outdir, 'summary.txt') with open(sumfile, 'w') as f: f.write(pta.summary()) print("generated model") outfile = os.path.join(outdir, 'params.txt') with open(outfile, 'w') as f: for pname in pta.param_names: f.write(pname+'\n') ###############
# timing model tm = gp_signals.TimingModel() # full model is sum of components model = ef + rn + tm + eq psr_dict = {} for psr in psrs: print('Working on ' + psr.name) psroutdir = outdir + '/' + psr.name + '/' if not os.path.exists(psroutdir): os.mkdir(psroutdir) # initialize PTA pta = signal_base.PTA([model(psr)]) #Pick random initial sampling xs = {par.name: par.sample() for par in pta.params} # dimension of parameter space ndim = len(xs) # initial jump covariance matrix cov = np.diag(np.ones(ndim) * 0.01**2) # Now we figure out which indices the red noise parameters have rn_idx1 = pta.param_names.index(psr.name + '_red_noise_log10_A') rn_idx2 = pta.param_names.index(psr.name + '_red_noise_gamma') # set up jump groups by red noise groups
def init_pta(params_all): """ Initiate enterprise signal models and enterprise.signals.signal_base.PTA. """ ptas = dict.fromkeys(params_all.models) for ii, params in params_all.models.items(): allpsr_model = params_all.noise_model_obj(psr=params_all.psrs, params=params) models = list() from_par_file = list() ecorrexists = np.zeros(len(params_all.psrs)) # Including parameters common for all pulsars if params.tm == 'default': tm = gp_signals.TimingModel() elif params.tm == 'ridge_regression': log10_variance = parameter.Uniform(-20, -10) basis = scaled_tm_basis() prior = ridge_prior(log10_variance=log10_variance) tm = gp_signals.BasisGP(prior, basis, name='ridge') # Adding common noise terms for all pulsars # Only those common signals are added that are listed in the noise model # file, getting Enterprise models from the noise model object. if 'm_all' in locals(): del m_all for psp, option in params.common_signals.items(): if 'm_all' in locals(): m_all += getattr(allpsr_model, psp)(option=option) else: m_all = tm + getattr(allpsr_model, psp)(option=option) # Including single pulsar noise models for pnum, psr in enumerate(params_all.psrs): singlepsr_model = params_all.noise_model_obj(psr=psr, params=params) # Determine if ecorr is mentioned in par file try: for key, val in psr.t2pulsar.noisemodel.items(): if key.startswith('ecorr') or key.startswith('ECORR'): ecorrexists[pnum] = True except Exception as pint_problem: print(pint_problem) ecorrexists[pnum] = False # Add noise models if psr.name in params.noisemodel.keys(): noise_model_dict_psr = params.noisemodel[psr.name] else: noise_model_dict_psr = params.universal for psp, option in noise_model_dict_psr.items(): if 'm_sep' in locals(): m_sep += getattr(singlepsr_model, psp)(option=option) elif 'm_all' in locals(): m_sep = m_all + getattr(singlepsr_model, psp)(option=option) else: m_sep = tm + getattr(singlepsr_model, psp)(option=option) models.append(m_sep(psr)) del m_sep pta = signal_base.PTA(models) if 'noisefiles' in params.__dict__.keys(): noisedict = get_noise_dict(psrlist=[p.name for p in params_all.psrs],\ noisefiles=params.noisefiles) print('For constant parameters using noise files in PAL2 format') pta.set_default_params(noisedict) print('Model',ii,'params (',len(pta.param_names),') in order: ', \ pta.param_names) if params.opts.mpi_regime != 2: np.savetxt(params.output_dir + '/pars.txt', pta.param_names, fmt='%s') ptas[ii] = pta return ptas
modes=modes, wgts=wgts, ) gamma_gw = parameter.Uniform(0, 7)('gw_gamma') log10_Agw = parameter.Uniform(-18, -11)('gw_log10_A') cpl = gpp.powerlaw_genmodes(log10_A=log10_Agw, gamma=gamma_gw, wgts=wgts) s += gp_signals.FourierBasisGP(cpl, modes=modes, name='gw_crn') # gw = blocks.common_red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=Tspan_PTA, # components=5, gamma_val=4.33, name='gw', orf='hd') crn_models = [s(psr) for psr in pkl_psrs] # gw_models = [(m + gw)(psr) for psr,m in zip(final_psrs,psr_models)] pta_crn = signal_base.PTA(crn_models) # pta_gw = signal_base.PTA(gw_models) # # delta_common=0., # ptas = {0:pta_crn, # 1:pta_gw} pta_crn.set_default_params(noise) with open(args.pta_pkl, 'wb') as fout: cloudpickle.dump(pta_crn, fout) groups = sampler.get_parameter_groups(pta_crn) groups.extend(sampler.get_psr_groups(pta_crn)) Sampler = sampler.setup_sampler(pta_crn, outdir=args.outdir,
##### parameters and priors ##### # Uniform prior on EFAC # efac = parameter.Uniform(0.1, 5.0) efac = parameter.LinearExp(0.1, 5.0) # white noise ef = white_signals.MeasurementNoise(efac=efac) # timing model tm = gp_signals.TimingModel() # full model is sum of components model = ef + tm # initialize PTA pta = signal_base.PTA([model(psrs[0])]) priors = bilby_warp.get_bilby_prior_dict(pta) print(priors) parameters = dict.fromkeys(priors.keys()) likelihood = bilby_warp.PTABilbyLikelihood(pta, parameters) label = 'test_bilby' # bilby.run_sampler(likelihood=likelihood, priors=priors, outdir='out/', label=label, sampler='dynesty', resume=False, nwalkers=500) bilby.run_sampler(likelihood=likelihood, priors=priors, outdir='out/', label=label, sampler='nestle')
def test_pta_phiinv_methods(self): ef = white_signals.MeasurementNoise(efac=parameter.Uniform(0.1, 5)) span = np.max(self.psrs[0].toas) - np.min(self.psrs[0].toas) pl = utils.powerlaw(log10_A=parameter.Uniform(-16, -13), gamma=parameter.Uniform(1, 7)) orf = utils.hd_orf() vrf = utils.dipole_orf() rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, Tspan=span) hdrn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=orf, components=20, Tspan=span, name='gw') vrn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=vrf, components=20, Tspan=span, name='vec') vrn2 = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=vrf, components=20, Tspan=span * 1.234, name='vec2') # two common processes, sharing basis partially model = ef + rn + hdrn # + vrn pta = signal_base.PTA([model(psr) for psr in self.psrs]) ps = parameter.sample(pta.params) phi = pta.get_phi(ps) ldp = np.linalg.slogdet(phi)[1] inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True) inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True) inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True) if not isinstance(inv3, np.ndarray): inv3 = inv3.toarray() for ld in [ld1, ld2, ld3]: msg = "Wrong phi log determinant for two common processes" assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg for inv in [inv1, inv2, inv3]: msg = "Wrong phi inverse for two common processes" assert np.allclose(np.dot(phi, inv), np.eye(phi.shape[0]), rtol=1e-15, atol=1e-6), msg for inva, invb in itertools.combinations([inv1, inv2, inv3], 2): assert np.allclose(inva, invb) # two common processes, no sharing basis model = ef + rn + vrn2 pta = signal_base.PTA([model(psr) for psr in self.psrs]) ps = parameter.sample(pta.params) phi = pta.get_phi(ps) ldp = np.linalg.slogdet(phi)[1] inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True) inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True) inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True) if not isinstance(inv3, np.ndarray): inv3 = inv3.toarray() for ld in [ld1, ld2, ld3]: msg = "Wrong phi log determinant for two common processes" assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg for inv in [inv1, inv2, inv3]: msg = "Wrong phi inverse for two processes" assert np.allclose(np.dot(phi, inv), np.eye(phi.shape[0]), rtol=1e-15, atol=1e-6), msg for inva, invb in itertools.combinations([inv1, inv2, inv3], 2): assert np.allclose(inva, invb) # three common processes, sharing basis partially model = ef + rn + hdrn + vrn pta = signal_base.PTA([model(psr) for psr in self.psrs]) ps = parameter.sample(pta.params) phi = pta.get_phi(ps) ldp = np.linalg.slogdet(phi)[1] inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True) inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True) inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True) if not isinstance(inv3, np.ndarray): inv3 = inv3.toarray() for ld in [ld1, ld3]: msg = "Wrong phi log determinant for two common processes" assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg for inv in [inv1, inv3]: msg = "Wrong phi inverse for three common processes" assert np.allclose(np.dot(phi, inv), np.eye(phi.shape[0]), rtol=1e-15, atol=1e-6), msg for inva, invb in itertools.combinations([inv1, inv3], 2): assert np.allclose(inva, invb) # four common processes, three sharing basis partially model = ef + rn + hdrn + vrn + vrn2 pta = signal_base.PTA([model(psr) for psr in self.psrs]) ps = parameter.sample(pta.params) phi = pta.get_phi(ps) ldp = np.linalg.slogdet(phi)[1] inv1, ld1 = pta.get_phiinv(ps, method='cliques', logdet=True) inv2, ld2 = pta.get_phiinv(ps, method='partition', logdet=True) inv3, ld3 = pta.get_phiinv(ps, method='sparse', logdet=True) if not isinstance(inv3, np.ndarray): inv3 = inv3.toarray() for ld in [ld1, ld3]: msg = "Wrong phi log determinant for two common processes" assert np.allclose(ldp, ld, rtol=1e-15, atol=1e-6), msg for inv in [inv1, inv3]: msg = "Wrong phi inverse for four processes" assert np.allclose(np.dot(phi, inv), np.eye(phi.shape[0]), rtol=1e-15, atol=1e-6), msg for inva, invb in itertools.combinations([inv1, inv3], 2): assert np.allclose(inva, invb)
# timing model tm = gp_signals.TimingModel() # gw (powerlaw with 5 frequencies) gw_pl = utils.powerlaw(log10_A=gw_log10_A, gamma=gw_gamma) gw_pshift = gp_signals.FourierBasisGP( spectrum=gw_pl, modes=freqs[:args.n_gwbfreqs], name='gw_crn', pshift=True, pseed=parameter.Uniform(0, 100000000)('pseed')) #args.process) model_pshift = tm + ef + ec + rn + gw_pshift pta_pshift = signal_base.PTA([model_pshift(p) for p in psrs]) with open(args.noisepath, 'r') as fin: noise = json.load(fin) pta_pshift.set_default_params(noise) if args.mk_ptapkl: with open(args.pta_pkl, "wb") as f: cloudpickle.dump(pta_pshift, f) os_pshift = OS(psrs=psrs, pta=pta_pshift, orf=args.orf, gamma_common=args.gamma_gw) c0 = co.Core(corepath=args.corepath)
def test_common_red_noise(self): """Test of a coefficient-based common GP.""" pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7)) ef = white_signals.MeasurementNoise( efac=parameter.Uniform(0.1, 5.0)) Tspan = max(self.psr.toas.max(), self.psr2.toas.max()) - min( self.psr.toas.max(), self.psr2.toas.max()) pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7)) rn = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=utils.hd_orf(), components=20, Tspan=Tspan) model = ef + rn rnc = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=utils.hd_orf(), components=20, Tspan=Tspan, coefficients=True) modelc = ef + rnc pta = signal_base.PTA([model(self.psr), model(self.psr2)]) ptac = signal_base.PTA([modelc(self.psr), modelc(self.psr2)]) params = { "B1855+09_efac": 1.0, "B1937+21_efac": 1.0, "common_fourier_gamma": 5, "common_fourier_log10_A": -15, } # get GP delays in two different ways cf, cf2 = np.random.randn(40), np.random.randn(40) bs = pta.get_basis(params) da = [np.dot(bs[0], cf), np.dot(bs[1], cf2)] params.update({ "B1855+09_common_fourier_coefficients": cf, "B1937+21_common_fourier_coefficients": cf2 }) db = ptac.get_delay(params) msg = "Implicit and explicit GP delays are different." assert np.allclose(da[0], db[0]), msg assert np.allclose(da[1], db[1]), msg cpar = [p for p in ptac.params if "coefficients" in p.name] def shouldfail(): return cpar[0].get_logpdf(params) self.assertRaises(NotImplementedError, shouldfail)
model_orfs.hd_orf(), components=14, Tspan=Tspan_PTA, name='gw') gw_low = gp_signals.FourierBasisCommonGP(plaw_low, model_orfs.hd_orf(), modes=modes, name='gw') std_models = [(s + rn_std + gw_std)(psr) for psr in pkl_psrs] low_models = [(s + rn_low + gw_low)(psr) for psr in pkl_psrs] pta_std = signal_base.PTA(std_models) pta_low = signal_base.PTA(low_models) ptas = {0:pta_std, 1:pta_low} pta_std.set_default_params(noise) pta_low.set_default_params(noise) with open(args.pta_pkl,'wb') as fout: cloudpickle.dump(ptas,fout) hm = hypermodel.HyperModel(models=ptas) sampler = hm.setup_sampler(outdir=args.outdir, resume=True, empirical_distr = args.emp_distr)
# timing model tm = gp_signals.TimingModel(use_svd=False) model = tm + ef + eq + ec + rn if args.dm_gp_psrs[0] == args.psr: dm_basis = utils.createfourierdesignmatrix_dm(Tspan=Tspan, nmodes=args.nfreqs, logf=args.logf) dm_gp = gp_signals.BasisGP(priorFunction=pl, basisFunction=dm_basis, name='dm_gp') model += dm_gp pta = signal_base.PTA(model(psr)) x0 = np.hstack(p.sample() for p in pta.params) ndim = len(x0) pta.get_lnlikelihood(x0) groups = model_utils.get_parameter_groups(pta) groups.extend([[pta.param_names.index(p) for p in pta.param_names if fl in p] for fl in ef_flags]) if args.dm_gp_psrs[0] == args.psr: gp_pars = [ '{0}_dm_gp_gamma'.format(args.psr), '{0}_dm_gp_log10_A'.format(args.psr), '{0}_red_noise_gamma'.format(args.psr),
modes=None) dp = DPDM.dpdm_block(type_='Bayes') tm = gp_signals.TimingModel() eph = deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) wnb = models.white_noise_block(vary=False) model = tm + dp + wnb + dmn + spn + eph nparams = [] # Get the number of parameters of each pulsar signals = [] for psr in psrs: signal = model(psr) nparams.append(len(signal.params) - 5) # Subtracting common DPDM params signals.append(signal) PTA = signal_base.PTA(signals) ndim = len(PTA.params) + 5 # Use the best fit noise parameters! PTA.set_default_params(Dict) # Set starting points at the already-known best fit points! xs = {par.name: par.sample() for par in PTA.params} for parname in Dict.keys(): if parname in xs.keys(): xs[parname] = Dict[parname] x0 = np.hstack([xs[key] for key in sorted(xs.keys())]) sampler = PTSampler( ndim, PTA.get_lnlikelihood,
rn = gp_signals.FourierBasisGP(spectrum=pl, components=30) # timing model basis = svd_tm_basis() prior = tm_prior() tm = gp_signals.BasisGP(prior, basis) # combined signal s = ef + eq + rn + tm outdirs = ['output_outlier', 'output_no_outlier'] for psr, outdir in zip(psrs, outdirs): # PTA pta = signal_base.PTA([s(psr)]) ## Set up different outlier models ## mdls = {} # emulate Vallisneri and van Haasteren mixture model gibbs = Gibbs(pta, model='vvh17', vary_df=False, theta_prior='uniform', vary_alpha=False, alpha=1e10, pspin=0.00457) mdls['vvh17'] = gibbs # uniform theta distribution