def red_noise_block(prior='log-uniform', Tspan=None): """ Returns red noise model: 1. Red noise modeled as a power-law with 30 sampling frequencies :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. """ # red noise parameters if prior == 'uniform': log10_A = parameter.LinearExp(-20, -11) elif prior == 'log-uniform': log10_A = parameter.Uniform(-20, -11) elif prior == 'log-normal': log10_A = parameter.Normal(-15, 4) elif prior == 'true-uniform': # use LinearExp for RN... simpler log10_A = parameter.LinearExp(-20, -11) else: raise NotImplementedError('Unknown prior for red noise amplitude!') gamma = parameter.Uniform(0, 7) # red noise signal pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(pl, components=30, Tspan=Tspan) return rn
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 bwm_sglpsr_block(Tmin, Tmax, amp_prior='log-uniform', logmin=-17, logmax=-12, name='ramp', fixed_sign=None): if fixed_sign is None: sign = parameter.Uniform(-1, 1)("sign") else: sign = np.sign(fixed_sign) amp_name = '{}_log10_A'.format(name) if amp_prior == 'uniform': log10_A_ramp = parameter.LinearExp(logmin, logmax)(amp_name) elif amp_prior == 'log-uniform': log10_A_ramp = parameter.Uniform(logmin, logmax)(amp_name) t0_name = '{}_t0'.format(name) t0 = parameter.Uniform(Tmin, Tmax)(t0_name) ramp_wf = ee_deterministic.bwm_sglpsr_delay(log10_A=log10_A_ramp, t0=t0, sign=sign) ramp = deterministic_signals.Deterministic(ramp_wf, name=name) return ramp
def bwm_sngl_block(Tmin, Tmax, amp_prior='log-uniform', logmin=-18, logmax=-9, name='bwm'): """ Returns deterministic single pulsar GW burst with memory model: 1. Burst event parameterized by time, amplitude, and sign (+/-) :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 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) elif amp_prior == 'log-normal': log10_A_bwm = parameter.Normal(logmin, logmax)(amp_name) elif amp_prior == 'true-uniform': amp_name = '{}_A'.format(name) A_bwm = parameter.Uniform(10**logmin, 10**logmax)(amp_name) else: raise NotImplementedError('Unknown prior for BWM amplitude!') t0_name = '{}_t0'.format(name) t0 = parameter.Uniform(Tmin, Tmax)(t0_name) sign_name = '{}_sign'.format(name) sign = parameter.Uniform(-1.0, 1.0)(sign_name) # BWM signal if amp_prior == 'true-uniform': bwm_wf = bwm_sngl_delay(h=A_bwm, t0=t0, sign=sign) else: bwm_wf = bwm_sngl_delay(log10_h=log10_A_bwm, t0=t0, sign=sign) bwm = deterministic_signals.Deterministic(bwm_wf, name=name) return bwm
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 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')
def free_noise_block(prior='log-uniform', Tspan=None): """Returns free spectrum noise model: 1. noise PSD with 30 sampling frequencies :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. """ if prior == 'uniform': log10_rho = parameter.LinearExp(-9, -4, size=30) elif prior == 'log-uniform': log10_rho = parameter.Uniform(-9, -4, size=30) spect = free_spectrum(log10_rho=log10_rho) fn = gp_signals.FourierBasisGP(spect, components=30, Tspan=Tspan) return fn
# 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) rn_pl = utils.powerlaw(log10_A=rn_log10_A, gamma=rn_gamma) rn = gp_signals.FourierBasisGP(rn_pl, components=30, Tspan=Tspan) # GW BWM amp_name = 'bwm_log10_A' if args.UL: bwm_log10_A = parameter.LinearExp(-18, -11)(amp_name) else: bwm_log10_A = parameter.Uniform(-18, -11)(amp_name) t0 = parameter.Constant(args.t0)('bwm_t0')
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
def chromatic_noise_block(gp_kernel='nondiag', psd='powerlaw', nondiag_kernel='periodic', prior='log-uniform', dt=15, df=200, idx=4, include_quadratic=False, Tspan=None, name='chrom', components=30, coefficients=False): """ Returns GP chromatic noise model : 1. Chromatic modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover' 'spectrum'] :param gp_kernel: Whether to use a diagonal kernel for the GP. ['diag','nondiag'] :param nondiag_kernel: Which nondiagonal kernel to use for the GP. ['periodic','sq_exp','periodic_rfband','sq_exp_rfband'] :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover' 'spectrum'] :param prior: What type of prior to use for amplitudes. ['log-uniform','uniform'] :param dt: time-scale for linear interpolation basis (days) :param df: frequency-scale for linear interpolation basis (MHz) :param idx: Index of radio frequency dependence (i.e. DM is 2). Any float will work. :param include_quadratic: Whether to include a quadratic fit. :param name: Name of signal :param Tspan: Tspan from which to calculate frequencies for PSD-based GPs. :param components: Number of frequencies to use in 'diag' GPs. :param coefficients: Whether to keep coefficients of the GP. """ if gp_kernel == 'diag': chm_basis = gpb.createfourierdesignmatrix_chromatic(nmodes=components, Tspan=Tspan) if psd in ['powerlaw', 'turnover']: if prior == 'uniform': log10_A = parameter.LinearExp(-18, -11) elif prior == 'log-uniform': log10_A = parameter.Uniform(-18, -11) gamma = parameter.Uniform(0, 7) # PSD if psd == 'powerlaw': chm_prior = utils.powerlaw(log10_A=log10_A, gamma=gamma) elif psd == 'turnover': kappa = parameter.Uniform(0, 7) lf0 = parameter.Uniform(-9, -7) chm_prior = utils.turnover(log10_A=log10_A, gamma=gamma, lf0=lf0, kappa=kappa) 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) chm_prior = gpp.free_spectrum(log10_rho=log10_rho) 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) chm_basis = gpk.linear_interp_basis_chromatic(dt=dt * const.day) chm_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) chm_basis = gpk.get_tf_quantization_matrix(df=df, dt=dt * const.day, dm=True, idx=idx) chm_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 kernel for DM log10_sigma = parameter.Uniform(-10, -4) log10_ell = parameter.Uniform(1, 4) chm_basis = gpk.linear_interp_basis_chromatic(dt=dt * const.day, idx=idx) chm_prior = gpk.se_dm_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell) elif nondiag_kernel == 'sq_exp_rfband': # Sq-Exp GP kernel for Chrom 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, idx=idx) dm_prior = gpk.sf_kernel(log10_sigma=log10_sigma, log10_ell=log10_ell, log10_alpha_wgt=log10_alpha_wgt, log10_ell2=log10_ell2) cgp = gp_signals.BasisGP(chm_prior, chm_basis, name=name + '_gp', coefficients=coefficients) if include_quadratic: # quadratic piece basis_quad = chrom.chromatic_quad_basis(idx=idx) prior_quad = chrom.chromatic_quad_prior() cquad = gp_signals.BasisGP(prior_quad, basis_quad, name=name + '_quad') cgp += cquad return cgp
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 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 gwb_ul(psrs_cut, num_points): # find the maximum time span to set GW frequency sampling tmin = [p.toas.min() for p in psrs_cut] tmax = [p.toas.max() for p in psrs_cut] Tspan = np.max(tmax) - np.min(tmin) # define selection by observing backend selection = selections.Selection(selections.by_backend) # white noise parameters # we set these ourselves so we know the most likely values! efac = parameter.Constant(1) # quad = parameter.Constant(0) # ecorr = parameter.Constant(0) # red noise parameters log10_A = parameter.LinearExp(-20, -11) gamma = parameter.Uniform(0, 7) # GW parameters (initialize with names here to use parameters in common across pulsars) log10_A_gw = parameter.LinearExp(-18, -12)('log10_A_gw') gamma_gw = parameter.Constant(4.33)('gamma_gw') # white noise 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) # red noise (powerlaw with 30 frequencies) pl = utils.powerlaw(log10_A=log10_A, gamma=gamma) rn = gp_signals.FourierBasisGP(spectrum=pl, components=30, Tspan=Tspan) # gwb (no spatial correlations) cpl = utils.powerlaw(log10_A=log10_A_gw, gamma=gamma_gw) gw = gp_signals.FourierBasisGP(spectrum=cpl, components=30, Tspan=Tspan, name='gw') # timing model tm = gp_signals.TimingModel( use_svd=True) # stabilizing timing model design matrix with SVD s = ef + rn + gw + tm # intialize PTA models = [] for p in psrs_cut: models.append(s(p)) pta = signal_base.PTA(models) outDir = './chains/psrs/{0}'.format(psrs_cut[0].name) sample = sampler.setup_sampler(pta, outdir=outDir) x0 = np.hstack([p.sample() for p in pta.params]) # sampler for N steps N = int( num_points) # normally, we would use 5e6 samples (this will save time) sample.sample( x0, N, SCAMweight=30, AMweight=15, DEweight=50, ) chain = np.loadtxt(os.path.join(outDir, 'chain_1.txt')) pars = np.loadtxt(outDir + '/pars.txt', dtype=np.unicode_) ind = list(pars).index('log10_A_gw') UL, unc = model_utils.ul(chain[:, ind]) return UL, unc
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
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
def model_simple(psrs, psd='powerlaw', efac=False, n_gwbfreqs=30, components=30, freqs=None, vary_gamma=False, upper_limit=False, bayesephem=False, select='backend', red_noise=False, Tspan=None, hd_orf=False, rn_dropout=False, dp_threshold=0.5): """ Reads in list of enterprise Pulsar instance and returns a PTA instantiated with the most simple model allowable for enterprise: per pulsar: 1. fixed EFAC per backend/receiver system at 1.0 2. Linear timing model. 3. Red noise modeled as a power-law with 30 sampling frequencies. Default=False global: 1.Common red noise modeled with user defined PSD with 30 sampling frequencies. Available PSDs are ['powerlaw', 'turnover' 'spectrum'] 2. Optional physical ephemeris modeling. :param psd: PSD to use for common red noise signal. Available options are ['powerlaw', 'turnover' 'spectrum']. '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 upper_limit: Perform upper limit on common red noise amplitude. By default this is set to False. Note that when performing 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 if Tspan is None: Tspan = model_utils.get_tspan(psrs) # timing model model = gp_signals.TimingModel() #Only White Noise is EFAC set to 1.0 selection = selections.Selection(selections.by_backend) if efac: ef = parameter.Uniform(0.1,10.0) else: ef = parameter.Constant(1.00) model += white_signals.MeasurementNoise(efac=ef, selection=selection) # common red noise block if upper_limit: log10_A_gw = parameter.LinearExp(-18,-12)('gw_log10_A') else: log10_A_gw = parameter.Uniform(-18,-12)('gw_log10_A') if vary_gamma: gamma_gw = parameter.Uniform(0,7)('gw_gamma') else: gamma_gw = parameter.Constant(4.33)('gw_gamma') pl = signal_base.Function(utils.powerlaw, log10_A=log10_A_gw, gamma=gamma_gw) if hd_orf: if freqs is None: gw = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=utils.hd_orf(), components=n_gwbfreqs, Tspan=Tspan, name='gw') else: gw = gp_signals.FourierBasisCommonGP(spectrum=pl, orf=utils.hd_orf(), modes=freqs, name='gw') model += gw else: if freqs is None: crn = gp_signals.FourierBasisGP(spectrum=pl, components=n_gwbfreqs, Tspan=Tspan, name='gw') else: crn = gp_signals.FourierBasisGP(spectrum=pl, modes=freqs, name='gw') model += crn if red_noise and rn_dropout: if amp_prior == 'uniform': log10_A = parameter.LinearExp(-20, -11) elif amp_prior == 'log-uniform': log10_A = parameter.Uniform(-20, -11) else: log10_A = parameter.Uniform(-20, -11) gamma = parameter.Uniform(0, 7) k_drop = parameter.Uniform(0, 1) if dp_threshold == 6.0: dp_threshold = parameter.Uniform(0,1)('k_threshold') pl = dropout.dropout_powerlaw(log10_A=log10_A, gamma=gamma, k_drop=k_drop, k_threshold=dp_threshold) rn = gp_signals.FourierBasisGP(pl, components=components, Tspan=Tspan, name='red_noise') model += rn elif red_noise: # red noise model += models.red_noise_block(prior=amp_prior, Tspan=Tspan, components=components) # ephemeris model if bayesephem: model += deterministic_signals.PhysicalEphemerisSignal(use_epoch_toas=True) # set up PTA pta = signal_base.PTA([model(p) for p in psrs]) return pta
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) elif self.params.gwb_lgA_prior == "normal": gwb_log10_A = parameter.Normal(mu=self.params.gwb_lgA[0], sigma=self.params.gwb_lgA[1])(amp_name) gam_name = '{}_gamma'.format(name) if "vary_gamma" in option: if self.params.gwb_gamma_prior == "uniform": gwb_gamma = parameter.Uniform(self.params.gwb_gamma[0], self.params.gwb_gamma[1])(gam_name) if self.params.gwb_gamma_prior == "normal": gwb_gamma = parameter.Normal(sigma=self.params.gwb_gamma[1], mu=self.params.gwb_gamma[0])(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: import time print('AZ about to do hd orf', time.perf_counter()) orf = utils.hd_orf() print('AZ called utils.hd_orf', time.perf_counter()) if len(optsp) > 1 or 'namehd' in option: gwname = 'gwb_hd' else: gwname = 'gwb' #print('evaluating gwb fourierbasiscommongp', time.perf_counter()) gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name=gwname, Tspan=self.params.Tspan) #print('evaluating gwb fourierbasiscommongp', time.perf_counter()) elif "mono" in option: print('Adding monopole ORF') orf = utils.monopole_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name='gwb', 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='gwb', Tspan=self.params.Tspan) elif "halfdip" in option: print('Adding dipole/2 ORF') orf = halfdip_orf() gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name='gwb', Tspan=self.params.Tspan) elif "varorf" in option: if len(optsp) > 1 or 'nameorf' in option: gwname = 'gwb_orf' else: gwname = 'gwb' corr_coeff = parameter.Uniform(-1., 1., size=7)('corr_coeff') if "noauto" in option: orf = infer_orf_noauto(corr_coeff=corr_coeff) else: orf = infer_orf(corr_coeff=corr_coeff) gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name=gwname, Tspan=self.params.Tspan) elif "interporf" in option: print("Adding numpy-interpolated free ORF") if len(optsp) > 1 or 'nameorf' in option: gwname = 'gwb_orf' else: gwname = 'gwb' corr_coeff = parameter.Uniform(-1., 1., size=7)('corr_coeff') if "noauto" in option: orf = infer_orf_npinterp_noauto(corr_coeff=corr_coeff) else: orf = infer_orf_npinterp(corr_coeff=corr_coeff) if "skyscr" in option: gwb = FourierBasisSkyscrambledGP(gwb_pl, orf, components=nfreqs, name=gwname+'_skyscr', Tspan=self.params.Tspan) else: gwb = gp_signals.FourierBasisCommonGP(gwb_pl, orf, components=nfreqs, name=gwname, Tspan=self.params.Tspan) else: gwb = gp_signals.FourierBasisGP(gwb_pl, components=nfreqs, name='gwb', Tspan=self.params.Tspan) if 'gwb_total' in locals(): gwb_total += gwb else: gwb_total = gwb return gwb_total
bkend_NG = selections.Selection(selections.nanograv_backends) # fix white noise parameters efac = parameter.Constant() equad = parameter.Constant() ecorr = parameter.Constant() # DMGP parameters and powerlaw dm_log10_A = parameter.Uniform(-20, -11) dm_gamma = parameter.Uniform(0, 7) dm_pl = utils.powerlaw(log10_A=dm_log10_A, gamma=dm_gamma) dm_basis = utils.createfourierdesignmatrix_dm(nmodes=30, Tspan=Tspan) # red noise parameters and powerlaw if args.ul: rn_log10_A = parameter.LinearExp(-20, -11) else: rn_log10_A = parameter.Uniform(-20, -11) rn_gamma = parameter.Uniform(0, 7) rn_pl = utils.powerlaw(log10_A=rn_log10_A, gamma=rn_gamma) # GWB parameters and powerlaw orf = utils.hd_orf() if args.ul: gwb_log10_A = parameter.LinearExp(-18, -12)('gwb_log10_A') else: gwb_log10_A = parameter.Uniform(-18, -12)('gwb_log10_A') gwb_gamma = parameter.Constant(13 / 3)('gwb_gamma') gwb_pl = utils.powerlaw(log10_A=gwb_log10_A, gamma=gwb_gamma) # signals
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
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) #Linear exp is upper limit run! Uniform is detection log10_A_gw = parameter.LinearExp(-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)
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 common_red_noise_block(psd='powerlaw', prior='log-uniform', Tspan=None, components=30, gamma_val=None, orf=None, 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'] :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 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 = { 'hd': utils.hd_orf(), 'dipole': utils.dipole_orf(), 'monopole': utils.monopole_orf() } # common red noise parameters if psd in ['powerlaw', 'turnover', 'turnover_knee']: 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) 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(): 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
import bilby from enterprise_warp import bilby_warp parfiles = sorted(glob.glob('data/*.par')) timfiles = sorted(glob.glob('data/*.tim')) psrs = [] for p, t in zip(parfiles, timfiles): psr = Pulsar(p, t) psrs.append(psr) ##### 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)
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