def bwm_block(Tmin, Tmax, amp_prior='log-uniform', skyloc=None, logmin=-18, logmax=-11, name='bwm'): """ Returns deterministic GW burst with memory model: 1. Burst event parameterized by time, sky location, polarization angle, and amplitude :param Tmin: Min time to search, probably first TOA (MJD). :param Tmax: Max time to search, probably last TOA (MJD). :param amp_prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :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 name: Name of BWM signal. """ # BWM parameters amp_name = '{}_log10_A'.format(name) if amp_prior == 'uniform': log10_A_bwm = parameter.LinearExp(logmin, logmax)(amp_name) elif amp_prior == 'log-uniform': log10_A_bwm = parameter.Uniform(logmin, logmax)(amp_name) pol_name = '{}_pol'.format(name) pol = parameter.Uniform(0, np.pi)(pol_name) t0_name = '{}_t0'.format(name) t0 = parameter.Uniform(Tmin, Tmax)(t0_name) costh_name = '{}_costheta'.format(name) phi_name = '{}_phi'.format(name) if skyloc is None: costh = parameter.Uniform(-1, 1)(costh_name) phi = parameter.Uniform(0, 2 * np.pi)(phi_name) else: costh = parameter.Constant(skyloc[0])(costh_name) phi = parameter.Constant(skyloc[1])(phi_name) # BWM signal bwm_wf = ee_deterministic.bwm_delay(log10_h=log10_A_bwm, t0=t0, cos_gwtheta=costh, gwphi=phi, gwpol=pol) bwm = deterministic_signals.Deterministic(bwm_wf, name=name) return bwm
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 white_noise_block(vary=False): """ Returns the white noise block of the model: 1. EFAC per backend/receiver system 2. EQUAD per backend/receiver system 3. ECORR per backend/receiver system :param vary: If set to true we vary these parameters with uniform priors. Otherwise they are set to constants with values to be set later. """ # define selection by observing backend selection = selections.Selection(selections.by_backend) # white noise parameters if vary: efac = parameter.Uniform(0.01, 10.0) equad = parameter.Uniform(-8.5, -5) ecorr = parameter.Uniform(-8.5, -5) else: efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() # white noise signals ef = white_signals.MeasurementNoise(efac=efac, selection=selection) eq = white_signals.EquadNoise(log10_equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) # combine signals s = ef + eq + ec return s
def gwb(self,option="hd_vary_gamma"): """ Spatially-correlated quadrupole signal from the nanohertz stochastic gravitational-wave background. """ name = 'gw' if "_nfreqs" in option: split_idx_nfreqs = option.split('_').index('nfreqs') - 1 nfreqs = int(option.split('_')[split_idx_nfreqs]) else: nfreqs = self.determine_nfreqs(sel_func_name=None, common_signal=True) if "_gamma" in option: amp_name = '{}_log10_A'.format(name) if self.params.gwb_lgA_prior == "uniform": gwb_log10_A = parameter.Uniform(self.params.gwb_lgA[0], self.params.gwb_lgA[1])(amp_name) elif self.params.gwb_lgA_prior == "linexp": gwb_log10_A = parameter.LinearExp(self.params.gwb_lgA[0], self.params.gwb_lgA[1])(amp_name) gam_name = '{}_gamma'.format(name) if "vary_gamma" in option: gwb_gamma = parameter.Uniform(self.params.gwb_gamma[0], self.params.gwb_gamma[1])(gam_name) elif "fixed_gamma" in option: gwb_gamma = parameter.Constant(4.33)(gam_name) else: split_idx_gamma = option.split('_').index('gamma') - 1 gamma_val = float(option.split('_')[split_idx_gamma]) gwb_gamma = parameter.Constant(gamma_val)(gam_name) gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma) elif "freesp" in option: amp_name = '{}_log10_rho'.format(name) log10_rho = parameter.Uniform(self.params.gwb_lgrho[0], self.params.gwb_lgrho[1], size=nfreqs)(amp_name) gwb_pl = gp_priors.free_spectrum(log10_rho=log10_rho) if "hd" in option: orf = utils.hd_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name='gwb', Tspan=self.params.Tspan) else: gwb = gp_signals.FourierBasisGP(gwb_pl, components=nfreqs, name='gwb', Tspan=self.params.Tspan) return gwb
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 interpret_white_noise_prior(prior): """ Interpret prior distribution parameters, passed from parameter file. Adding only one numbers sets prior to be a constant, while two numbers are interpreted as Uniform prior bounds. """ if not np.isscalar(prior): return parameter.Uniform(prior[0], prior[1]) else: return parameter.Constant()
def dpdm_block_constant(DP_pars): # This block is for single pulsar analysis in the Frequentist scheme, therefore 5 common parameters are constants. name = 'x_dp_' log10_ma = parameter.Constant(DP_pars[name + 'log10_ma'])(name + 'const_log10_ma') log10_eps = parameter.Constant( DP_pars[name + 'log10_eps'])(name + 'const_log10_eps') dec_dp = parameter.Constant(DP_pars[name + 'Dec'])(name + 'const_Dec') ra_dp = parameter.Constant(DP_pars[name + 'Ra'])(name + 'const_Ra') phase_e = parameter.Constant(DP_pars[name + 'phase_e'])(name + 'const_phase_e') dphase = parameter.Uniform(-np.pi, np.pi)(name + 'vary_dphase') delay = dpdm_delay(log10_ma=log10_ma, log10_eps=log10_eps, ra_dp=ra_dp, dec_dp=dec_dp, phase_e=phase_e, dphase=dphase) dpdm = deterministic_signals.Deterministic(delay, name='x_dp') return dpdm
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 gwb(self,option="common_pl"): """ Spatially-correlated quadrupole signal from the nanohertz stochastic gravitational-wave background. """ gwb_log10_A = parameter.Uniform(params.gwb_lgA[0],params.gwb_lgA[1]) if option=="common_pl": gwb_gamma = parameter.Uniform(params.gwb_gamma[0],params.gwb_gamma[1]) elif option=="fixed_gamma": gwb_gamma = parameter.Constant(4.33) gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma) nfreqs = self.determine_nfreqs(sel_func_name=None) orf = utils.hd_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, \ name='gwb', Tspan=self.params.Tspan) return gwb
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 gwb(self,option="hd_vary_gamma"): """ Spatially-correlated quadrupole signal from the nanohertz stochastic gravitational-wave background. """ name = 'gw' optsp = option.split('+') for option in optsp: if "_nfreqs" in option: split_idx_nfreqs = option.split('_').index('nfreqs') - 1 nfreqs = int(option.split('_')[split_idx_nfreqs]) else: nfreqs = self.determine_nfreqs(sel_func_name=None, common_signal=True) print('Number of Fourier frequencies for the GWB/CPL signal: ', nfreqs) if "_gamma" in option: amp_name = '{}_log10_A'.format(name) if (len(optsp) > 1 and 'hd' in option) or ('namehd' in option): amp_name += '_hd' elif (len(optsp) > 1 and ('varorf' in option or \ 'interporf' in option)) \ or ('nameorf' in option): amp_name += '_orf' if self.params.gwb_lgA_prior == "uniform": gwb_log10_A = parameter.Uniform(self.params.gwb_lgA[0], self.params.gwb_lgA[1])(amp_name) elif self.params.gwb_lgA_prior == "linexp": gwb_log10_A = parameter.LinearExp(self.params.gwb_lgA[0], self.params.gwb_lgA[1])(amp_name) gam_name = '{}_gamma'.format(name) if "vary_gamma" in option: gwb_gamma = parameter.Uniform(self.params.gwb_gamma[0], self.params.gwb_gamma[1])(gam_name) elif "fixed_gamma" in option: gwb_gamma = parameter.Constant(4.33)(gam_name) else: split_idx_gamma = option.split('_').index('gamma') - 1 gamma_val = float(option.split('_')[split_idx_gamma]) gwb_gamma = parameter.Constant(gamma_val)(gam_name) gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma) elif "freesp" in option: amp_name = '{}_log10_rho'.format(name) log10_rho = parameter.Uniform(self.params.gwb_lgrho[0], self.params.gwb_lgrho[1], size=nfreqs)(amp_name) gwb_pl = gp_priors.free_spectrum(log10_rho=log10_rho) if "hd" in option: print('Adding HD ORF') if "noauto" in option: print('Removing auto-correlation') orf = hd_orf_noauto() else: orf = utils.hd_orf() if len(optsp) > 1 or 'namehd' in option: gwname = 'gw_hd' else: gwname = 'gw' gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name=gwname, Tspan=self.params.Tspan) elif "mono" in option: print('Adding monopole ORF') orf = utils.monopole_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name='gw', Tspan=self.params.Tspan) elif "dipo" in option: print('Adding dipole ORF') orf = utils.dipole_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name='gw', Tspan=self.params.Tspan) else: gwb = gp_signals.FourierBasisGP(gwb_pl, components=nfreqs, name='gw', Tspan=self.params.Tspan) if 'gw_total' in locals(): gwb_total += gwb else: gwb_total = gwb return gwb_total
with open(args.noisefile, "rb") as f: noise_params = pickle.load(f) print("loaded pickles") ################# ## PTA model ## ################# 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 selection = selections.Selection(selections.by_backend) efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() ef = white_signals.MeasurementNoise(efac=efac, selection=selection) eq = white_signals.EquadNoise(log10_equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) wn = ef + eq + ec # Red Noise if args.UL: rn_log10_A = parameter.LinearExp(-20, -11) else: rn_log10_A = parameter.Uniform(-20, -11) rn_gamma = parameter.Uniform(0, 7)
theta, idx) simtimfile = 'simulated_data/outlier/{}/{}/J1713+0747.tim'.format( theta, idx) psr = Pulsar(simparfile, simtimfile) simparfile = 'simulated_data/no_outlier/{}/{}/J1713+0747.par'.format( theta, idx) simtimfile = 'simulated_data/no_outlier/{}/{}/J1713+0747.tim'.format( theta, idx) psr2 = Pulsar(simparfile, simtimfile) psrs = [psr, psr2] ## Set up enterprise model ## # white noise efac = parameter.Constant(1.0) equad = parameter.Uniform(-10, -5) # backend selection selection = selections.Selection(selections.no_selection) ef = white_signals.MeasurementNoise(efac=efac, selection=selection) eq = white_signals.EquadNoise(log10_equad=equad, selection=selection) # red noise pl = utils.powerlaw(log10_A=parameter.Uniform(-18, -12), gamma=parameter.Uniform(1, 7)) rn = gp_signals.FourierBasisGP(spectrum=pl, components=30) # timing model basis = svd_tm_basis()
modes, wgts = model_utils.linBinning(Tspan_PTA, 0, 1.0 / fmin / Tspan_PTA, 14, 5) # wgts = wgts**2.0 # timing model s = gp_signals.MarginalizingTimingModel() s += blocks.white_noise_block(vary=False, inc_ecorr=True, select='backend') rn_low = blocks.red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=Tspan_PTA, modes=modes, wgts=wgts,) rn_std = blocks.red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=Tspan_PTA, components=30) gamma_gw = parameter.Constant(4.3333)('gw_gamma') log10_Agw = parameter.Uniform(-18, -14)('gw_log10_A') plaw_low = gpp.powerlaw_genmodes(log10_A=log10_Agw, gamma=gamma_gw, wgts=wgts) plaw_std = gpp.powerlaw(log10_A=log10_Agw, gamma=gamma_gw) gw_std = gp_signals.FourierBasisCommonGP(plaw_std, model_orfs.hd_orf(), components=14, Tspan=Tspan_PTA, name='gw') gw_low = gp_signals.FourierBasisCommonGP(plaw_low, model_orfs.hd_orf(),
def cw_block_circ(amp_prior='log-uniform', dist_prior=None, skyloc=None, log10_fgw=None, psrTerm=False, tref=0, name='cw'): """ Returns deterministic, cirular orbit continuous GW model: :param amp_prior: Prior on log10_h. Default is "log-uniform." Use "uniform" for upper limits, or "None" to search over log10_dist instead. :param dist_prior: Prior on log10_dist. Default is "None," meaning that the search is over log10_h instead of log10_dist. Use "log-uniform" to search over log10_h with a log-uniform prior. :param skyloc: Fixed sky location of CW signal search as [cos(theta), phi]. Search over sky location if ``None`` given. :param log10_fgw: Fixed log10 GW frequency of CW signal search. Search over GW frequency if ``None`` given. :param ecc: Fixed log10 distance to SMBHB search. Search over distance or strain if ``None`` given. :param psrTerm: Boolean for whether to include the pulsar term. Default is False. :param name: Name of CW signal. """ if dist_prior is None: log10_dist = None if amp_prior == 'uniform': log10_h = parameter.LinearExp(-18.0, -11.0)('{}_log10_h'.format(name)) elif amp_prior == 'log-uniform': log10_h = parameter.Uniform(-18.0, -11.0)('{}_log10_h'.format(name)) elif dist_prior == 'log-uniform': log10_dist = parameter.Uniform(-2.0, 4.0)('{}_log10_dL'.format(name)) log10_h = None # chirp mass [Msol] log10_Mc = parameter.Uniform(6.0, 10.0)('{}_log10_Mc'.format(name)) # GW frequency [Hz] if log10_fgw is None: log10_fgw = parameter.Uniform(-9.0, -7.0)('{}_log10_fgw'.format(name)) else: log10_fgw = parameter.Constant(log10_fgw)('{}_log10_fgw'.format(name)) # orbital inclination angle [radians] cosinc = parameter.Uniform(-1.0, 1.0)('{}_cosinc'.format(name)) # initial GW phase [radians] phase0 = parameter.Uniform(0.0, np.pi)('{}_phase0'.format(name)) # polarization psi_name = '{}_psi'.format(name) psi = parameter.Uniform(0, np.pi)(psi_name) # sky location costh_name = '{}_costheta'.format(name) phi_name = '{}_phi'.format(name) if skyloc is None: costh = parameter.Uniform(-1, 1)(costh_name) phi = parameter.Uniform(0, 2 * np.pi)(phi_name) else: costh = parameter.Constant(skyloc[0])(costh_name) phi = parameter.Constant(skyloc[1])(phi_name) if psrTerm: p_phase = parameter.Uniform(0, 2 * np.pi) p_dist = parameter.Normal(0, 1) else: p_phase = None p_dist = 0 # continuous wave signal wf = cw_delay(cos_gwtheta=costh, gwphi=phi, cos_inc=cosinc, log10_mc=log10_Mc, log10_fgw=log10_fgw, log10_h=log10_h, log10_dist=log10_dist, phase0=phase0, psi=psi, psrTerm=True, p_dist=p_dist, p_phase=p_phase, phase_approx=True, check=False, tref=tref) cw = CWSignal(wf, ecc=False, psrTerm=psrTerm) return cw
s += blocks.red_noise_block(prior='log-uniform', Tspan=Tspan_PTA, components=30) # adding white-noise, separating out Adv Noise Psrs, and acting on psr objects final_psrs = [] psr_models = [] ### Add a stand alone SW deter model bins = np.linspace(53215, 57934, 26) bins *= 24 * 3600 #Convert to secs n_earth = chrom.solar_wind.ACE_SWEPAM_Parameter(size=bins.size - 1)('n_earth') deter_sw = chrom.solar_wind.solar_wind(n_earth=n_earth, n_earth_bins=bins) mean_sw = deterministic_signals.Deterministic(deter_sw, name='sw_r2') np_earth = parameter.Uniform(-4, -2)('np_4p39') sw_power = parameter.Constant(4.39)('sw_power_4p39') deter_sw_p = chrom.solar_wind.solar_wind_r_to_p(n_earth=np_earth, power=sw_power, log10_ne=True) mean_sw += deterministic_signals.Deterministic(deter_sw_p, name='sw_4p39') for psr in pkl_psrs: # Filter out other Adv Noise Pulsars if psr.name in adv_noise_psr_list: ### Get the new pulsar object ## Remember that J1713's pickle is something you made yourself ## filepath = '/gscratch/gwastro/hazboun/nanograv/noise/noise_model_selection/no_dmx_pickles/' filepath += '{0}_ng12p5yr_v3_nodmx_ePSR.pkl'.format(psr.name) with open(filepath, 'rb') as fin: new_psr = pickle.load(fin) ### Get kwargs dictionary
def dm_noise_block(gp_kernel='diag', psd='powerlaw', nondiag_kernel='periodic', prior='log-uniform', Tspan=None, components=30, gamma_val=None): """ Returns DM noise model: 1. DM noise modeled as a power-law with 30 sampling frequencies :param psd: PSD function [e.g. powerlaw (default), turnover, free spectrum] :param prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :param Tspan: Sets frequency sampling f_i = i / Tspan. Default will use overall time span for indivicual pulsar. :param components: Number of frequencies in sampling of DM-variations. :param gamma_val: If given, this is the fixed slope of the power-law for powerlaw or turnover DM-variations """ # dm noise parameters that are common if gp_kernel == 'diag': if psd in ['powerlaw', 'turnover']: # parameters shared by PSD functions if prior == 'uniform': log10_A_dm = parameter.LinearExp(-20, -11) elif prior == 'log-uniform' and gamma_val is not None: if np.abs(gamma_val - 4.33) < 0.1: log10_A_dm = parameter.Uniform(-20, -11) else: log10_A_dm = parameter.Uniform(-20, -11) else: log10_A_dm = parameter.Uniform(-20, -11) if gamma_val is not None: gamma_dm = parameter.Constant(gamma_val) else: gamma_dm = parameter.Uniform(0, 7) # different PSD function parameters if psd == 'powerlaw': dm_prior = utils.powerlaw(log10_A=log10_A_dm, gamma=gamma_dm) elif psd == 'turnover': kappa_dm = parameter.Uniform(0, 7) lf0_dm = parameter.Uniform(-9, -7) dm_prior = utils.turnover(log10_A=log10_A_dm, gamma=gamma_dm, lf0=lf0_dm, kappa=kappa_dm) if psd == 'spectrum': if prior == 'uniform': log10_rho_dm = parameter.LinearExp(-10, -4, size=components) elif prior == 'log-uniform': log10_rho_dm = parameter.Uniform(-10, -4, size=components) dm_prior = free_spectrum(log10_rho=log10_rho_dm) dm_basis = utils.createfourierdesignmatrix_dm(nmodes=components, Tspan=Tspan) elif gp_kernel == 'nondiag': if nondiag_kernel == 'periodic': # Periodic GP kernel for DM log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) period = parameter.Uniform(0.2, 5.0) gam_p = parameter.Uniform(0.1, 30.0) dm_basis = linear_interp_basis_dm(dt=15 * const.day) dm_prior = periodic_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, gam_p=gam_p, p=period) elif nondiag_kernel == 'periodic_rfband': # Periodic GP kernel for DM with RQ radio-frequency dependence log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) log10_ell2 = parameter.Uniform(2, 7) alpha_wgt = parameter.Uniform(0.2, 6) period = parameter.Uniform(0.2, 5.0) gam_p = parameter.Uniform(0.1, 30.0) dm_basis = get_tf_quantization_matrix(df=200, dt=15 * const.day, dm=True) dm_prior = tf_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, gam_p=gam_p, p=period, alpha_wgt=alpha_wgt, log10_ell2=log10_ell2) elif nondiag_kernel == 'dmx_like': # DMX-like signal log10_sigma = parameter.Uniform(-10, -4) dm_basis = linear_interp_basis_dm(dt=30 * const.day) dm_prior = dmx_ridge_prior(log10_sigma=log10_sigma) dmgp = gp_signals.BasisGP(dm_prior, dm_basis, name='dm_gp') return dmgp
def test_single_pulsar(self): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt") # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ms = white_signals.MeasurementNoise(efac=efac, log10_t2equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) s = ms + ec + rn m = s(self.psrs[0]) # set parameters m.set_default_params(params) # get parameters efacs = [params[key] for key in sorted(params.keys()) if "efac" in key] equads = [ params[key] for key in sorted(params.keys()) if "equad" in key ] ecorrs = [ params[key] for key in sorted(params.keys()) if "ecorr" in key ] log10_A = params["B1855+09_red_noise_log10_A"] gamma = params["B1855+09_red_noise_gamma"] # correct value flags = ["430_ASP", "430_PUPPI", "L-wide_ASP", "L-wide_PUPPI"] nvec0 = np.zeros_like(self.psrs[0].toas) for ct, flag in enumerate(np.unique(flags)): ind = flag == self.psrs[0].backend_flags nvec0[ind] = efacs[ct]**2 * ( self.psrs[0].toaerrs[ind]**2 + 10**(2 * equads[ct]) * np.ones(np.sum(ind))) # get the basis bflags = self.psrs[0].backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(self.psrs[0].toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(self.psrs[0].toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2 * np.log(np.diag(cf[0]))) # test msg = "EFAC/ECORR logdet incorrect." N = m.get_ndiag(params) assert np.allclose(N.solve(self.psrs[0].residuals, logdet=True)[1], logdet, rtol=1e-10), msg msg = "EFAC/ECORR D1 solve incorrect." assert np.allclose(N.solve(self.psrs[0].residuals), sl.cho_solve(cf, self.psrs[0].residuals), rtol=1e-10), msg msg = "EFAC/ECORR 1D1 solve incorrect." assert np.allclose( N.solve(self.psrs[0].residuals, left_array=self.psrs[0].residuals), np.dot(self.psrs[0].residuals, sl.cho_solve(cf, self.psrs[0].residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D1 solve incorrect." T = m.get_basis(params) assert np.allclose( N.solve(self.psrs[0].residuals, left_array=T), np.dot(T.T, sl.cho_solve(cf, self.psrs[0].residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D2 solve incorrect." assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, sl.cho_solve(cf, T)), rtol=1e-10), msg F, f2 = utils.createfourierdesignmatrix_red(self.psrs[0].toas, nmodes=20) # spectrum test phi = utils.powerlaw(f2, log10_A=log10_A, gamma=gamma) msg = "Spectrum incorrect for GP Fourier signal." assert np.all(m.get_phi(params) == phi), msg # inverse spectrum test msg = "Spectrum inverse incorrect for GP Fourier signal." assert np.all(m.get_phiinv(params) == 1 / phi), msg
def test_pta(self): # get parameters from PAL2 style noise files params = get_noise_from_pal2(datadir + "/B1855+09_noise.txt") params2 = get_noise_from_pal2(datadir + "/J1909-3744_noise.txt") params.update(params2) # setup basic model efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() log10_A = parameter.Constant() gamma = parameter.Constant() selection = Selection(selections.by_backend) ms = white_signals.MeasurementNoise(efac=efac, log10_t2equad=equad, selection=selection) ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=selection) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl) s = ms + ec + rn pta = s(self.psrs[0]) + s(self.psrs[1]) # set parameters pta.set_default_params(params) # get parameters efacs, equads, ecorrs, log10_A, gamma = [], [], [], [], [] for pname in [p.name for p in self.psrs]: efacs.append([ params[key] for key in sorted(params.keys()) if "efac" in key and pname in key ]) equads.append([ params[key] for key in sorted(params.keys()) if "equad" in key and pname in key ]) ecorrs.append([ params[key] for key in sorted(params.keys()) if "ecorr" in key and pname in key ]) log10_A.append(params["{}_red_noise_log10_A".format(pname)]) gamma.append(params["{}_red_noise_gamma".format(pname)]) # correct value tflags = [sorted(list(np.unique(p.backend_flags))) for p in self.psrs] cfs, logdets, phis = [], [], [] for ii, (psr, flags) in enumerate(zip(self.psrs, tflags)): nvec0 = np.zeros_like(psr.toas) for ct, flag in enumerate(flags): ind = psr.backend_flags == flag nvec0[ind] = efacs[ii][ct]**2 * ( psr.toaerrs[ind]**2 + 10**(2 * equads[ii][ct]) * np.ones(np.sum(ind))) # get the basis bflags = psr.backend_flags Umats = [] for flag in np.unique(bflags): mask = bflags == flag Umats.append( utils.create_quantization_matrix(psr.toas[mask])[0]) nepoch = sum(U.shape[1] for U in Umats) U = np.zeros((len(psr.toas), nepoch)) jvec = np.zeros(nepoch) netot = 0 for ct, flag in enumerate(np.unique(bflags)): mask = bflags == flag nn = Umats[ct].shape[1] U[mask, netot:nn + netot] = Umats[ct] jvec[netot:nn + netot] = 10**(2 * ecorrs[ii][ct]) netot += nn # get covariance matrix cov = np.diag(nvec0) + np.dot(U * jvec[None, :], U.T) cf = sl.cho_factor(cov) logdet = np.sum(2 * np.log(np.diag(cf[0]))) cfs.append(cf) logdets.append(logdet) F, f2 = utils.createfourierdesignmatrix_red(psr.toas, nmodes=20) phi = utils.powerlaw(f2, log10_A=log10_A[ii], gamma=gamma[ii]) phis.append(phi) # tests Ns = pta.get_ndiag(params) pphis = pta.get_phi(params) pphiinvs = pta.get_phiinv(params) Ts = pta.get_basis(params) zipped = zip(logdets, cfs, phis, self.psrs, Ns, pphis, pphiinvs, Ts) for logdet, cf, phi, psr, N, pphi, pphiinv, T in zipped: msg = "EFAC/ECORR logdet incorrect." assert np.allclose(N.solve(psr.residuals, logdet=True)[1], logdet, rtol=1e-10), msg msg = "EFAC/ECORR D1 solve incorrect." assert np.allclose(N.solve(psr.residuals), sl.cho_solve(cf, psr.residuals), rtol=1e-10), msg msg = "EFAC/ECORR 1D1 solve incorrect." assert np.allclose( N.solve(psr.residuals, left_array=psr.residuals), np.dot(psr.residuals, sl.cho_solve(cf, psr.residuals)), rtol=1e-10, ), msg msg = "EFAC/ECORR 2D1 solve incorrect." assert np.allclose(N.solve(psr.residuals, left_array=T), np.dot(T.T, sl.cho_solve(cf, psr.residuals)), rtol=1e-10), msg msg = "EFAC/ECORR 2D2 solve incorrect." assert np.allclose(N.solve(T, left_array=T), np.dot(T.T, sl.cho_solve(cf, T)), rtol=1e-10), msg # spectrum test msg = "Spectrum incorrect for GP Fourier signal." assert np.all(pphi == phi), msg # inverse spectrum test msg = "Spectrum inverse incorrect for GP Fourier signal." assert np.all(pphiinv == 1 / phi), msg
Tspan = tmax - tmin # Red noise parameter priors log10_A = parameter.Uniform(-20, -11) gamma = parameter.Uniform(0, 7) # GW parameter priors if args.gamma_gw is None: gw_log10_A = parameter.Uniform(-18, -11)('gw_log10_A') gw_gamma = parameter.Uniform(0, 7)('gw_gamma') else: if np.abs(args.gamma_gw - 4.33) < 0.1: gw_log10_A = parameter.Uniform(-18, -14)('gw_log10_A') else: gw_log10_A = parameter.Uniform(-18, -11)('gw_log10_A') gw_gamma = parameter.Constant(args.gamma_gw)('gw_gamma') # White noise parameter priors efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() Nf = args.nfreqs freqs = np.linspace(1 / Tspan, Nf / Tspan, Nf) # # white noise selection = selections.Selection(selections.nanograv_backends) ef = white_signals.MeasurementNoise(efac=efac, log10_t2equad=equad, selection=selection)
def common_red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=None, gamma_val=None, orf=None, name='gwb'): """ Returns common red noise model: 1. Red noise modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover' 'spectrum'] :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover' 'spectrum'] :param prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :param Tspan: Sets frequency sampling f_i = i / Tspan. Default will use overall time span for indivicual pulsar. :param gamma_val: Value of spectral index for power-law and turnover models. By default spectral index is varied of 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 name: Name of common red process """ orfs = { 'hd': utils.hd_orf(), 'dipole': utils.dipole_orf(), 'monopole': utils.monopole_orf() } # common red noise parameters if psd in ['powerlaw', 'turnover']: amp_name = '{}_log10_A'.format(name) if prior == 'uniform': log10_Agw = parameter.LinearExp(-18, -11)(amp_name) elif prior == 'log-uniform' and gamma_val is not None: if np.abs(gamma_val - 4.33) < 0.1: log10_Agw = parameter.Uniform(-18, -14)(amp_name) else: log10_Agw = parameter.Uniform(-18, -11)(amp_name) else: log10_Agw = parameter.Uniform(-18, -11)(amp_name) gam_name = '{}_gamma'.format(name) if gamma_val is not None: gamma_gw = parameter.Constant(gamma_val)(gam_name) else: gamma_gw = parameter.Uniform(0, 7)(gam_name) # common red noise PSD if psd == 'powerlaw': cpl = utils.powerlaw(log10_A=log10_Agw, gamma=gamma_gw) elif psd == 'turnover': kappa_name = '{}_kappa'.format(name) lf0_name = '{}_log10_fbend'.format(name) kappa_gw = parameter.Uniform(0, 7)(kappa_name) lf0_gw = parameter.Uniform(-9, -7)(lf0_name) cpl = utils.turnover(log10_A=log10_Agw, gamma=gamma_gw, lf0=lf0_gw, kappa=kappa_gw) if orf is None: crn = gp_signals.FourierBasisGP(cpl, components=30, Tspan=Tspan) elif orf in orfs.keys(): crn = gp_signals.FourierBasisCommonGP(cpl, orfs[orf], components=30, Tspan=Tspan) else: raise ValueError('ORF {} not recognized'.format(orf)) return crn
tmax = [p.toas.max() for p in psrs] Tspan = np.max(tmax) - np.min(tmin) ##### parameters and priors ##### # white noise parameters efac = parameter.Uniform(0.5, 4.0) log10_equad = parameter.Uniform(-8.5, 5) # red noise parameters red_noise_log10_A = parameter.Uniform(-20, -11) red_noise_gamma = parameter.Uniform(0, 7) # GW parameters (initialize with names here to use parameters in common across pulsars) log10_A_gw = parameter.Uniform(-20, -11)('zlog10_A_gw') gamma_gw = parameter.Constant(13 / 3)('zgamma_gw') ##### Set up signals ##### # timing model tm = gp_signals.TimingModel() # white noise ef = white_signals.MeasurementNoise(efac=efac) eq = white_signals.EquadNoise(log10_equad=log10_equad) # red noise (powerlaw with 30 frequencies) pl = utils.powerlaw(log10_A=red_noise_log10_A, gamma=red_noise_gamma) rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, Tspan=Tspan) cpl = utils.powerlaw(log10_A=log10_A_gw, gamma=gamma_gw)
# find the maximum time span to set GW frequency sampling selection = Selection(selections.by_backend) tmin = [p.toas.min() for p in psrs] tmax = [p.toas.max() for p in psrs] Tspan = np.max(tmax) - np.min(tmin) ##### parameters and priors ##### # white noise parameters ''' efac = parameter.Uniform(0.5,4.0) log10_equad = parameter.Uniform(-10,-5) log10_ecorr = parameter.Uniform(-10,-5) ''' efac = parameter.Constant() log10_equad = parameter.Constant() log10_ecorr = parameter.Constant() # red noise parameters red_noise_log10_A = parameter.Uniform(-18, -13) red_noise_gamma = parameter.Uniform(0, 7) # GW parameters (initialize with names here to use parameters in common across pulsars) log10_A_gw_1 = parameter.Uniform(-18, -13)('zlog10_A_gw') gamma_gw_1 = parameter.Constant(13 / 3)('zgamma_gw') # Second GW parameters log10_A_gw_2 = parameter.Uniform(-18, -13)('zlog10_A_other_gw') gamma_gw_2 = parameter.Constant(7 / 3)('zgamma_other_gw')
def red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=None, components=30, gamma_val=None, coefficients=False, select=None, modes=None, wgts=None, break_flat=False, break_flat_fq=None): """ Returns red noise model: 1. Red noise modeled as a power-law with 30 sampling frequencies :param psd: PSD function [e.g. powerlaw (default), turnover, spectrum, tprocess] :param prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :param Tspan: Sets frequency sampling f_i = i / Tspan. Default will use overall time span for indivicual pulsar. :param components: Number of frequencies in sampling of red noise :param gamma_val: If given, this is the fixed slope of the power-law for powerlaw, turnover, or tprocess red noise :param coefficients: include latent coefficients in GP model? """ # red noise parameters that are common if psd in [ 'powerlaw', 'powerlaw_genmodes', 'turnover', 'tprocess', 'tprocess_adapt', 'infinitepower' ]: # parameters shared by PSD functions if prior == 'uniform': log10_A = parameter.LinearExp(-20, -11) elif prior == 'log-uniform' and gamma_val is not None: if np.abs(gamma_val - 4.33) < 0.1: log10_A = parameter.Uniform(-20, -11) else: log10_A = parameter.Uniform(-20, -11) else: log10_A = parameter.Uniform(-20, -11) if gamma_val is not None: gamma = parameter.Constant(gamma_val) else: gamma = parameter.Uniform(0, 7) # different PSD function parameters if psd == 'powerlaw': pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) elif psd == 'powerlaw_genmodes': pl = gpp.powerlaw_genmodes(log10_A=log10_A, gamma=gamma, wgts=wgts) elif psd == 'turnover': kappa = parameter.Uniform(0, 7) lf0 = parameter.Uniform(-9, -7) pl = utils.turnover(log10_A=log10_A, gamma=gamma, lf0=lf0, kappa=kappa) elif psd == 'tprocess': df = 2 alphas = gpp.InvGamma(df / 2, df / 2, size=components) pl = gpp.t_process(log10_A=log10_A, gamma=gamma, alphas=alphas) elif psd == 'tprocess_adapt': df = 2 alpha_adapt = gpp.InvGamma(df / 2, df / 2, size=1) nfreq = parameter.Uniform(-0.5, 10 - 0.5) pl = gpp.t_process_adapt(log10_A=log10_A, gamma=gamma, alphas_adapt=alpha_adapt, nfreq=nfreq) elif psd == 'infinitepower': pl = gpp.infinitepower() if psd == 'spectrum': if prior == 'uniform': log10_rho = parameter.LinearExp(-10, -4, size=components) elif prior == 'log-uniform': log10_rho = parameter.Uniform(-10, -4, size=components) pl = gpp.free_spectrum(log10_rho=log10_rho) if select == 'backend': # define selection by observing backend selection = selections.Selection(selections.by_backend) elif select == 'band' or select == 'band+': # define selection by observing band selection = selections.Selection(selections.by_band) else: # define no selection selection = selections.Selection(selections.no_selection) if break_flat: log10_A_flat = parameter.Uniform(-20, -11) gamma_flat = parameter.Constant(0) pl_flat = utils.powerlaw(log10_A=log10_A_flat, gamma=gamma_flat) freqs = 1.0 * np.arange(1, components + 1) / Tspan components_low = sum(f < break_flat_fq for f in freqs) if components_low < 1.5: components_low = 2 rn = gp_signals.FourierBasisGP(pl, components=components_low, Tspan=Tspan, coefficients=coefficients, selection=selection) rn_flat = gp_signals.FourierBasisGP(pl_flat, modes=freqs[components_low:], coefficients=coefficients, selection=selection, name='red_noise_hf') rn = rn + rn_flat else: rn = gp_signals.FourierBasisGP(pl, components=components, Tspan=Tspan, coefficients=coefficients, selection=selection, modes=modes) if select == 'band+': # Add the common component as well rn = rn + gp_signals.FourierBasisGP( pl, components=components, Tspan=Tspan, coefficients=coefficients) return rn
def cw_block_ecc(amp_prior='log-uniform', skyloc=None, log10_F=None, ecc=None, psrTerm=False, tref=0, name='cw'): """ Returns deterministic, eccentric orbit continuous GW model: :param amp_prior: Prior on log10_h and log10_Mc/log10_dL. Default is "log-uniform" with log10_Mc and log10_dL searched over. Use "uniform" for upper limits, log10_h searched over. :param skyloc: Fixed sky location of CW signal search as [cos(theta), phi]. Search over sky location if ``None`` given. :param log10_F: Fixed log-10 orbital frequency of CW signal search. Search over orbital frequency if ``None`` given. :param ecc: Fixed eccentricity of SMBHB search. Search over eccentricity if ``None`` given. :param psrTerm: Boolean for whether to include the pulsar term. Default is False. :param name: Name of CW signal. """ if amp_prior == 'uniform': log10_h = parameter.LinearExp(-18.0, -11.0)('{}_log10_h'.format(name)) elif amp_prior == 'log-uniform': log10_h = None # chirp mass [Msol] log10_Mc = parameter.Uniform(6.0, 10.0)('{}_log10_Mc'.format(name)) # luminosity distance [Mpc] log10_dL = parameter.Uniform(-2.0, 4.0)('{}_log10_dL'.format(name)) # orbital frequency [Hz] if log10_F is None: log10_Forb = parameter.Uniform(-9.0, -7.0)('{}_log10_Forb'.format(name)) else: log10_Forb = parameter.Constant(log10_F)('{}_log10_Forb'.format(name)) # orbital inclination angle [radians] cosinc = parameter.Uniform(-1.0, 1.0)('{}_cosinc'.format(name)) # periapsis position angle [radians] gamma_0 = parameter.Uniform(0.0, np.pi)('{}_gamma0'.format(name)) # Earth-term eccentricity if ecc is None: e_0 = parameter.Uniform(0.0, 0.99)('{}_e0'.format(name)) else: e_0 = parameter.Constant(ecc)('{}_e0'.format(name)) # initial mean anomaly [radians] l_0 = parameter.Uniform(0.0, 2.0 * np.pi)('{}_l0'.format(name)) # mass ratio = M_2/M_1 q = parameter.Constant(1.0)('{}_q'.format(name)) # polarization pol_name = '{}_pol'.format(name) pol = parameter.Uniform(0, np.pi)(pol_name) # sky location costh_name = '{}_costheta'.format(name) phi_name = '{}_phi'.format(name) if skyloc is None: costh = parameter.Uniform(-1, 1)(costh_name) phi = parameter.Uniform(0, 2 * np.pi)(phi_name) else: costh = parameter.Constant(skyloc[0])(costh_name) phi = parameter.Constant(skyloc[1])(phi_name) # continuous wave signal wf = compute_eccentric_residuals(cos_gwtheta=costh, gwphi=phi, log10_mc=log10_Mc, log10_dist=log10_dL, log10_h=log10_h, log10_F=log10_Forb, cos_inc=cosinc, psi=pol, gamma0=gamma_0, e0=e_0, l0=l_0, q=q, nmax=400, pdist=None, pphase=None, pgam=None, tref=tref, check=False) cw = CWSignal(wf, ecc=True, psrTerm=psrTerm) return cw
def dm_noise_block(gp_kernel='diag', psd='powerlaw', nondiag_kernel='periodic', prior='log-uniform', dt=15, df=200, Tspan=None, components=30, gamma_val=None, coefficients=False): """ Returns DM noise model: 1. DM noise modeled as a power-law with 30 sampling frequencies :param psd: PSD function [e.g. powerlaw (default), spectrum, tprocess] :param prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :param dt: time-scale for linear interpolation basis (days) :param df: frequency-scale for linear interpolation basis (MHz) :param Tspan: Sets frequency sampling f_i = i / Tspan. Default will use overall time span for indivicual pulsar. :param components: Number of frequencies in sampling of DM-variations. :param gamma_val: If given, this is the fixed slope of the power-law for powerlaw, turnover, or tprocess DM-variations """ # dm noise parameters that are common if gp_kernel == 'diag': if psd in ['powerlaw', 'turnover', 'tprocess', 'tprocess_adapt']: # parameters shared by PSD functions if prior == 'uniform': log10_A_dm = parameter.LinearExp(-20, -11) elif prior == 'log-uniform' and gamma_val is not None: if np.abs(gamma_val - 4.33) < 0.1: log10_A_dm = parameter.Uniform(-20, -11) else: log10_A_dm = parameter.Uniform(-20, -11) else: log10_A_dm = parameter.Uniform(-20, -11) if gamma_val is not None: gamma_dm = parameter.Constant(gamma_val) else: gamma_dm = parameter.Uniform(0, 7) # different PSD function parameters if psd == 'powerlaw': dm_prior = utils.powerlaw(log10_A=log10_A_dm, gamma=gamma_dm) elif psd == 'turnover': kappa_dm = parameter.Uniform(0, 7) lf0_dm = parameter.Uniform(-9, -7) dm_prior = utils.turnover(log10_A=log10_A_dm, gamma=gamma_dm, lf0=lf0_dm, kappa=kappa_dm) elif psd == 'tprocess': df = 2 alphas_dm = gpp.InvGamma(df / 2, df / 2, size=components) dm_prior = gpp.t_process(log10_A=log10_A_dm, gamma=gamma_dm, alphas=alphas_dm) elif psd == 'tprocess_adapt': df = 2 alpha_adapt_dm = gpp.InvGamma(df / 2, df / 2, size=1) nfreq_dm = parameter.Uniform(-0.5, 10 - 0.5) dm_prior = gpp.t_process_adapt(log10_A=log10_A_dm, gamma=gamma_dm, alphas_adapt=alpha_adapt_dm, nfreq=nfreq_dm) if psd == 'spectrum': if prior == 'uniform': log10_rho_dm = parameter.LinearExp(-10, -4, size=components) elif prior == 'log-uniform': log10_rho_dm = parameter.Uniform(-10, -4, size=components) dm_prior = gpp.free_spectrum(log10_rho=log10_rho_dm) dm_basis = utils.createfourierdesignmatrix_dm(nmodes=components, Tspan=Tspan) elif gp_kernel == 'nondiag': if nondiag_kernel == 'periodic': # Periodic GP kernel for DM log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) log10_p = parameter.Uniform(-4, 1) log10_gam_p = parameter.Uniform(-3, 2) dm_basis = gpk.linear_interp_basis_dm(dt=dt * const.day) dm_prior = gpk.periodic_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, log10_gam_p=log10_gam_p, log10_p=log10_p) elif nondiag_kernel == 'periodic_rfband': # Periodic GP kernel for DM with RQ radio-frequency dependence log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) log10_ell2 = parameter.Uniform(2, 7) log10_alpha_wgt = parameter.Uniform(-4, 1) log10_p = parameter.Uniform(-4, 1) log10_gam_p = parameter.Uniform(-3, 2) dm_basis = gpk.get_tf_quantization_matrix(df=df, dt=dt * const.day, dm=True) dm_prior = gpk.tf_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, log10_gam_p=log10_gam_p, log10_p=log10_p, log10_alpha_wgt=log10_alpha_wgt, log10_ell2=log10_ell2) elif nondiag_kernel == 'sq_exp': # squared-exponential GP kernel for DM log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) dm_basis = gpk.linear_interp_basis_dm(dt=dt * const.day) dm_prior = gpk.se_dm_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell) elif nondiag_kernel == 'sq_exp_rfband': # Sq-Exp GP kernel for DM with RQ radio-frequency dependence log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) log10_ell2 = parameter.Uniform(2, 7) log10_alpha_wgt = parameter.Uniform(-4, 1) dm_basis = gpk.get_tf_quantization_matrix(df=df, dt=dt * const.day, dm=True) dm_prior = gpk.sf_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, log10_alpha_wgt=log10_alpha_wgt, log10_ell2=log10_ell2) elif nondiag_kernel == 'dmx_like': # DMX-like signal log10_sigma = parameter.Uniform(-10, -4) dm_basis = gpk.linear_interp_basis_dm(dt=dt * const.day) dm_prior = gpk.dmx_ridge_prior(log10_sigma=log10_sigma) dmgp = gp_signals.BasisGP(dm_prior, dm_basis, name='dm_gp', coefficients=coefficients) return dmgp
def __init__(self, psr): super(WidebandTimingModel, self).__init__(psr) self.name = self.psrname + "_" + self.signal_id # make selection for DMEFACs dmefac_select = dmefac_selection(psr) self._dmefac_keys = list(sorted(dmefac_select.masks.keys())) self._dmefac_masks = [dmefac_select.masks[key] for key in self._dmefac_keys] # make selection for DMEQUADs log10_dmequad_select = log10_dmequad_selection(psr) self._log10_dmequad_keys = list(sorted(log10_dmequad_select.masks.keys())) self._log10_dmequad_masks = [log10_dmequad_select.masks[key] for key in self._log10_dmequad_keys] # make selection for DMJUMPs dmjump_select = dmjump_selection(psr) self._dmjump_keys = list(sorted(dmjump_select.masks.keys())) self._dmjump_masks = [dmjump_select.masks[key] for key in self._dmjump_keys] if self._dmjump_keys == [""] and dmjump is not None: raise ValueError("WidebandTimingModel: can only do DMJUMP with more than one selection.") # collect parameters self._params = {} self._dmefacs = [] for key in self._dmefac_keys: pname = "_".join([n for n in [psr.name, key, "dmefac"] if n]) param = dmefac(pname) self._dmefacs.append(param) self._params[param.name] = param self._log10_dmequads = [] for key in self._log10_dmequad_keys: pname = "_".join([n for n in [psr.name, key, "log10_dmequad"] if n]) param = log10_dmequad(pname) self._log10_dmequads.append(param) self._params[param.name] = param self._dmjumps = [] if dmjump is not None: for key in self._dmjump_keys: pname = "_".join([n for n in [psr.name, key, "dmjump"] if n]) if dmjump_ref is not None: if pname == psr.name + "_" + dmjump_ref + "_dmjump": fixed_dmjump = parameter.Constant(val=0.0) param = fixed_dmjump(pname) else: param = dmjump(pname) else: param = dmjump(pname) self._dmjumps.append(param) self._params[param.name] = param # copy psr quantities self._ntoas = len(psr.toas) self._npars = len(psr.fitpars) self._freqs = psr.freqs # collect DMX information (will be used to make phi and delay) self._dmpar = psr.dm self._dm = np.array(psr.flags["pp_dm"], "d") self._dmerr = np.array(psr.flags["pp_dme"], "d") check = np.zeros_like(psr.toas, "i") # assign TOAs to DMX bins self._dmx, self._dmindex, self._dmwhich = [], [], [] for index, key in enumerate(sorted(psr.dmx)): dmx = psr.dmx[key] if not dmx["fit"]: raise ValueError("WidebandTimingModel: all DMX parameters must be estimated.") self._dmx.append(dmx["DMX"]) self._dmindex.append(psr.fitpars.index(key)) self._dmwhich.append((dmx["DMXR1"] <= psr.stoas / 86400) & (psr.stoas / 86400 < dmx["DMXR2"])) check += self._dmwhich[-1] if np.sum(check) != self._ntoas: raise ValueError("WidebandTimingModel: cannot account for all TOAs in DMX intervals.") if "DM" in psr.fitpars: raise ValueError("WidebandTimingModel: DM must not be estimated.") self._ndmx = len(self._dmx)
def white_noise_block(vary=False, inc_ecorr=False, gp_ecorr=False, efac1=False, select='backend', name=None): """ Returns the white noise block of the model: 1. EFAC per backend/receiver system 2. EQUAD per backend/receiver system 3. ECORR per backend/receiver system :param vary: If set to true we vary these parameters with uniform priors. Otherwise they are set to constants with values to be set later. :param inc_ecorr: include ECORR, needed for NANOGrav channelized TOAs :param gp_ecorr: whether to use the Gaussian process model for ECORR :param efac1: use a strong prior on EFAC = Normal(mu=1, stdev=0.1) """ if select == 'backend': # define selection by observing backend backend = selections.Selection(selections.by_backend) # define selection by nanograv backends backend_ng = selections.Selection(selections.nanograv_backends) else: # define no selection backend = selections.Selection(selections.no_selection) # white noise parameters if vary: if efac1: efac = parameter.Normal(1.0, 0.1) else: efac = parameter.Uniform(0.01, 10.0) equad = parameter.Uniform(-8.5, -5) if inc_ecorr: ecorr = parameter.Uniform(-8.5, -5) else: efac = parameter.Constant() equad = parameter.Constant() if inc_ecorr: ecorr = parameter.Constant() # white noise signals ef = white_signals.MeasurementNoise(efac=efac, selection=backend, name=name) eq = white_signals.EquadNoise(log10_equad=equad, selection=backend, name=name) if inc_ecorr: if gp_ecorr: if name is None: ec = gp_signals.EcorrBasisModel(log10_ecorr=ecorr, selection=backend_ng) else: ec = gp_signals.EcorrBasisModel(log10_ecorr=ecorr, selection=backend_ng, name=name) else: ec = white_signals.EcorrKernelNoise(log10_ecorr=ecorr, selection=backend_ng, name=name) # combine signals if inc_ecorr: s = ef + eq + ec elif not inc_ecorr: s = ef + eq return s
psrs = [] for p, t in zip(parfiles, timfiles): psr = Pulsar(p, t) psrs.append(psr) save1 = np.load('noisepars.npy') save2 = np.load('noisepardict.npy') save3 = np.load('dpdmpars-maxposprob.npy') save4 = np.load('dpdmpardict.npy') Dict = {save2[i]: save1[i] for i in range(len(save2))} Dict.update({save4[i]: save3[i] for i in range(len(save4))}) # The Big Model # dm noise log10_A_dm = parameter.Constant() gamma_dm = parameter.Constant() pl_dm = utils.powerlaw(log10_A=log10_A_dm, gamma=gamma_dm) dm_basis = utils.createfourierdesignmatrix_dm(nmodes=50, Tspan=None) dmn = gp_signals.BasisGP(pl_dm, dm_basis, name='dm_gp', coefficients=False) # spin noise log10_A = parameter.Constant() gamma = parameter.Constant() pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) selection = selections.Selection(selections.no_selection) spn = gp_signals.FourierBasisGP(pl, components=50, Tspan=None, coefficients=False, selection=selection, modes=None)
def common_red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=None, components=30, log10_A_val=None, gamma_val=None, delta_val=None, orf=None, orf_ifreq=0, leg_lmax=5, name='gw', coefficients=False, pshift=False, pseed=None): """ Returns common red noise model: 1. Red noise modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover' 'spectrum'] :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover' 'spectrum', 'broken_powerlaw'] :param prior: Prior on log10_A. Default if "log-uniform". Use "uniform" for upper limits. :param Tspan: Sets frequency sampling f_i = i / Tspan. Default will use overall time span for individual pulsar. :param log10_A_val: Value of log10_A parameter for fixed amplitude analyses. :param gamma_val: Value of spectral index for power-law and turnover models. By default spectral index is varied of range [0,7] :param delta_val: Value of spectral index for high frequencies in broken power-law and turnover models. By default spectral index is varied in 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 orf_ifreq: Frequency bin at which to start the Hellings & Downs function with numbering beginning at 0. Currently only works with freq_hd orf. :param leg_lmax: Maximum multipole of a Legendre polynomial series representation of the overlap reduction function [default=5] :param pshift: Option to use a random phase shift in design matrix. For testing the null hypothesis. :param pseed: Option to provide a seed for the random phase shift. :param name: Name of common red process """ orfs = { 'crn': None, 'hd': utils.hd_orf(), 'dipole': utils.dipole_orf(), 'monopole': utils.monopole_orf(), 'param_hd': model_orfs.param_hd_orf(a=parameter.Uniform(-1.5, 3.0)('gw_orf_param0'), b=parameter.Uniform(-1.0, 0.5)('gw_orf_param1'), c=parameter.Uniform(-1.0, 1.0)('gw_orf_param2')), 'spline_orf': model_orfs.spline_orf( params=parameter.Uniform(-0.9, 0.9, size=7)('gw_orf_spline')), 'bin_orf': model_orfs.bin_orf( params=parameter.Uniform(-1.0, 1.0, size=7)('gw_orf_bin')), 'zero_diag_hd': model_orfs.zero_diag_hd(), 'zero_diag_bin_orf': model_orfs.zero_diag_bin_orf(params=parameter.Uniform( -1.0, 1.0, size=7)('gw_orf_bin_zero_diag')), 'freq_hd': model_orfs.freq_hd(params=[components, orf_ifreq]), 'legendre_orf': model_orfs.legendre_orf( params=parameter.Uniform(-1.0, 1.0, size=leg_lmax + 1)('gw_orf_legendre')), 'zero_diag_legendre_orf': model_orfs.zero_diag_legendre_orf( params=parameter.Uniform(-1.0, 1.0, size=leg_lmax + 1)('gw_orf_legendre_zero_diag')) } # common red noise parameters if psd in ['powerlaw', 'turnover', 'turnover_knee', 'broken_powerlaw']: amp_name = '{}_log10_A'.format(name) if log10_A_val is not None: log10_Agw = parameter.Constant(log10_A_val)(amp_name) else: if prior == 'uniform': log10_Agw = parameter.LinearExp(-18, -11)(amp_name) elif prior == 'log-uniform' and gamma_val is not None: if np.abs(gamma_val - 4.33) < 0.1: log10_Agw = parameter.Uniform(-18, -14)(amp_name) else: log10_Agw = parameter.Uniform(-18, -11)(amp_name) else: log10_Agw = parameter.Uniform(-18, -11)(amp_name) gam_name = '{}_gamma'.format(name) if gamma_val is not None: gamma_gw = parameter.Constant(gamma_val)(gam_name) else: gamma_gw = parameter.Uniform(0, 7)(gam_name) # common red noise PSD if psd == 'powerlaw': cpl = utils.powerlaw(log10_A=log10_Agw, gamma=gamma_gw) elif psd == 'broken_powerlaw': delta_name = '{}_delta'.format(name) kappa_name = '{}_kappa'.format(name) log10_fb_name = '{}_log10_fb'.format(name) kappa_gw = parameter.Uniform(0.01, 0.5)(kappa_name) log10_fb_gw = parameter.Uniform(-10, -7)(log10_fb_name) if delta_val is not None: delta_gw = parameter.Constant(delta_val)(delta_name) else: delta_gw = parameter.Uniform(0, 7)(delta_name) cpl = gpp.broken_powerlaw(log10_A=log10_Agw, gamma=gamma_gw, delta=delta_gw, log10_fb=log10_fb_gw, kappa=kappa_gw) elif psd == 'turnover': kappa_name = '{}_kappa'.format(name) lf0_name = '{}_log10_fbend'.format(name) kappa_gw = parameter.Uniform(0, 7)(kappa_name) lf0_gw = parameter.Uniform(-9, -7)(lf0_name) cpl = utils.turnover(log10_A=log10_Agw, gamma=gamma_gw, lf0=lf0_gw, kappa=kappa_gw) elif psd == 'turnover_knee': kappa_name = '{}_kappa'.format(name) lfb_name = '{}_log10_fbend'.format(name) delta_name = '{}_delta'.format(name) lfk_name = '{}_log10_fknee'.format(name) kappa_gw = parameter.Uniform(0, 7)(kappa_name) lfb_gw = parameter.Uniform(-9.3, -8)(lfb_name) delta_gw = parameter.Uniform(-2, 0)(delta_name) lfk_gw = parameter.Uniform(-8, -7)(lfk_name) cpl = gpp.turnover_knee(log10_A=log10_Agw, gamma=gamma_gw, lfb=lfb_gw, lfk=lfk_gw, kappa=kappa_gw, delta=delta_gw) if psd == 'spectrum': rho_name = '{}_log10_rho'.format(name) if prior == 'uniform': log10_rho_gw = parameter.LinearExp(-9, -4, size=components)(rho_name) elif prior == 'log-uniform': log10_rho_gw = parameter.Uniform(-9, -4, size=components)(rho_name) cpl = gpp.free_spectrum(log10_rho=log10_rho_gw) if orf is None: crn = gp_signals.FourierBasisGP(cpl, coefficients=coefficients, components=components, Tspan=Tspan, name=name, pshift=pshift, pseed=pseed) elif orf in orfs.keys(): if orf == 'crn': crn = gp_signals.FourierBasisGP(cpl, coefficients=coefficients, components=components, Tspan=Tspan, name=name, pshift=pshift, pseed=pseed) else: crn = gp_signals.FourierBasisCommonGP(cpl, orfs[orf], components=components, Tspan=Tspan, name=name, pshift=pshift, pseed=pseed) elif isinstance(orf, types.FunctionType): crn = gp_signals.FourierBasisCommonGP(cpl, orf, components=components, Tspan=Tspan, name=name, pshift=pshift, pseed=pseed) else: raise ValueError('ORF {} not recognized'.format(orf)) return crn