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 __init__(self, psr): super(CWSignal, self).__init__(psr) self._wf[''].add_kwarg(inc_psr_term=inc_psr_term) if inc_psr_term: pdist = parameter.Normal(psr.pdist[0], psr.pdist[1])('_'.join( [psr.name, 'cgw', 'pdist'])) pphase = parameter.Uniform(0, 2 * np.pi)('_'.join( [psr.name, 'cgw', 'pphase'])) self._params['p_dist'] = pdist self._params['p_phase'] = pphase self._wf['']._params['p_dist'] = pdist self._wf['']._params['p_phase'] = pphase
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 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 dmx_signal(dmx_data, name='dmx_signal'): """ Returns DMX signal: :param dmx_data: dictionary of DMX data for each pulsar from parfile. :param name: Name of signal. :return dmx_sig: dmx signal waveform. """ dmx = {} for dmx_id in sorted(dmx_data): dmx_data_tmp = dmx_data[dmx_id] dmx.update({ dmx_id: parameter.Normal(mu=dmx_data_tmp['DMX_VAL'], sigma=dmx_data_tmp['DMX_ERR']) }) wf = dmx_delay(dmx_ids=dmx_data, **dmx) dmx_sig = deterministic_signals.Deterministic(wf, name=name) return dmx_sig
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 Dropout_PhysicalEphemerisSignal( frame_drift_rate=parameter.Uniform(-1e-9, 1e-9)('frame_drift_rate'), d_jupiter_mass=parameter.Normal(0, 1.54976690e-11)('d_jupiter_mass'), d_saturn_mass=parameter.Normal(0, 8.17306184e-12)('d_saturn_mass'), d_uranus_mass=parameter.Normal(0, 5.71923361e-11)('d_uranus_mass'), d_neptune_mass=parameter.Normal(0, 7.96103855e-11)('d_neptune_mass'), jup_orb_elements=parameter.Uniform(-0.05, 0.05, size=6)('jup_orb_elements'), sat_orb_elements=parameter.Uniform(-0.5, 0.5, size=6)('sat_orb_elements'), inc_jupiter_orb=True, inc_saturn_orb=False, use_epoch_toas=True, k_drop=parameter.Uniform(0.0, 1.0), k_threshold=0.5, name=''): """ Class factory for dropout physical ephemeris model signal.""" # turn off saturn orbital element parameters if not including in signal if not inc_saturn_orb: sat_orb_elements = np.zeros(6) # define waveform jup_mjd, jup_orbelxyz, sat_mjd, sat_orbelxyz = ( utils.get_planet_orbital_elements()) wf = dropout_physical_ephem_delay(frame_drift_rate=frame_drift_rate, d_jupiter_mass=d_jupiter_mass, d_saturn_mass=d_saturn_mass, d_uranus_mass=d_uranus_mass, d_neptune_mass=d_neptune_mass, jup_orb_elements=jup_orb_elements, sat_orb_elements=sat_orb_elements, inc_jupiter_orb=inc_jupiter_orb, jup_orbelxyz=jup_orbelxyz, jup_mjd=jup_mjd, inc_saturn_orb=inc_saturn_orb, sat_orbelxyz=sat_orbelxyz, sat_mjd=sat_mjd, k_drop=k_drop, k_threshold=k_threshold) BaseClass = deterministic_signals.Deterministic(wf, name=name) class Dropout_PhysicalEphemerisSignal(BaseClass): signal_name = 'phys_ephem' signal_id = 'phys_ephem_' + name if name else 'phys_ephem' def __init__(self, psr): # not available for PINT yet if isinstance(psr, enterprise.pulsar.PintPulsar): msg = 'Physical Ephemeris model is not compatible with PINT ' msg += 'at this time.' raise NotImplementedError(msg) super(Dropout_PhysicalEphemerisSignal, self).__init__(psr) if use_epoch_toas: # get quantization matrix and calculate daily average TOAs U, _ = utils.create_quantization_matrix(psr.toas, nmin=1) self.uinds = utils.quant2ind(U) avetoas = np.array([psr.toas[sc].mean() for sc in self.uinds]) self._wf[''].add_kwarg(toas=avetoas) # interpolate ssb planet position vectors to avetoas planetssb = np.zeros((len(avetoas), 9, 3)) for jj in range(9): planetssb[:, jj, :] = np.array([ np.interp(avetoas, psr.toas, psr.planetssb[:, jj, aa]) for aa in range(3) ]).T self._wf[''].add_kwarg(planetssb=planetssb) # Inteprolating the pulsar position vectors onto epoch TOAs pos_t = np.array([ np.interp(avetoas, psr.toas, psr.pos_t[:, aa]) for aa in range(3) ]).T self._wf[''].add_kwarg(pos_t=pos_t) # initialize delay self._delay = np.zeros(len(psr.toas)) @signal_base.cache_call('delay_params') def get_delay(self, params): delay = self._wf[''](params=params) if use_epoch_toas: for slc, val in zip(self.uinds, delay): self._delay[slc] = val return self._delay else: return delay return Dropout_PhysicalEphemerisSignal
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
def PhysicalEphemerisSignal(frame_drift_rate=parameter.Uniform(-1e-9, 1e-9) ('frame_drift_rate'), d_mercury_mass=parameter.Normal( 0, 1.66 - 10)('d_mercury_mass'), d_venus_mass=parameter.Normal( 0, 2.45e-9)('d_venus_mass'), d_mars_mass=parameter.Normal( 0, 3.23e-10)('d_mars_mass'), d_jupiter_mass=parameter.Normal( 0, 1.54976690e-11)('d_jupiter_mass'), d_saturn_mass=parameter.Normal( 0, 8.17306184e-12)('d_saturn_mass'), d_uranus_mass=parameter.Normal( 0, 5.71923361e-11)('d_uranus_mass'), d_neptune_mass=parameter.Normal( 0, 7.96103855e-11)('d_neptune_mass'), jup_orb_elements=parameter.Uniform( -0.05, 0.05, size=6)('jup_orb_elements'), sat_orb_elements=parameter.Uniform( -0.5, 0.5, size=6)('sat_orb_elements'), model="setIII", use_epoch_toas=True, name=""): # noqa: E125,E501 """ Class factory for physical ephemeris model signal. This function implements a physically motivated ephemeris delay model. It is parameterized by an overall ecliptic-z frame drift rate, by the masses of gas giants, by the six orbital elements of Jupiter, and by the six orbital elements of Saturn. All these contributions can be disabled individually (Saturn orbit corrections are disabled by default). .. note:: This signal is only compatible with a tempo2 Pulsar object. The user can implement their own priors (e.g., by setting frame_drift_rate = parameter.Uniform(-1e-10,1e-10)('frame_drift_rate') but we have set reasonable defaults (see below). :param frame_drift_rate: ecliptic z-drift rate in units of rad/year referred to offset 1/1/2010. Default prior is Uniform(-1e-9, 1e-9). :param d_jupiter_mass: Mass deviation of Jupiter in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 1.54976690e-11) :param d_saturn_mass: Mass deviation of Saturn in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 8.17306184e-12) :param d_uranus_mass: Mass deviation of Uranus in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 5.71923361e-11) :param d_neptune_mass: Mass deviation of Neptune in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 7.96103855e-11) :param jup_orb_elements: Jupiter orbital-element perturbation coefficients. Default prior is Uniform(-0.05, 0.05) for each element, appropriate for standard SVD basis. :param sat_orb_elements: Saturn orbital-element perturbations coefficient. Default prior is Uniform(-0.5, 0.5) for each element, appropriate for standard SVD basis. :param model: Sets the vector basis used by Jupiter and Saturn orbital-element perturbations. Currently can be set to 'orbel', 'orbel-v2', 'setIII'. Default: 'setIII' :param use_epoch_toas: Use interpolation from epoch to full TOAs. This option reduces computational cost for large multi-channel TOA data sets. Default: True """ times, jup_orbit, sat_orbit = utils.get_planet_orbital_elements(model) wf = utils.physical_ephem_delay( frame_drift_rate=frame_drift_rate, d_mercury_mass=d_mercury_mass, d_venus_mass=d_venus_mass, d_mars_mass=d_mars_mass, d_jupiter_mass=d_jupiter_mass, d_saturn_mass=d_saturn_mass, d_uranus_mass=d_uranus_mass, d_neptune_mass=d_neptune_mass, jup_orb_elements=jup_orb_elements, sat_orb_elements=sat_orb_elements, times=times, jup_orbit=jup_orbit, sat_orbit=sat_orbit, ) BaseClass = Deterministic(wf, name=name) class PhysicalEphemerisSignal(BaseClass): signal_name = "phys_ephem" signal_id = "phys_ephem_" + name if name else "phys_ephem" def __init__(self, psr): # not available for PINT yet if isinstance(psr, pulsar.PintPulsar): msg = "Physical Ephemeris model is not compatible with PINT " msg += "at this time." raise NotImplementedError(msg) super(PhysicalEphemerisSignal, self).__init__(psr) if use_epoch_toas: # get quantization matrix and calculate daily average TOAs U, _ = utils.create_quantization_matrix(psr.toas, nmin=1) self._uinds = utils.quant2ind(U) avetoas = np.array([psr.toas[sc].mean() for sc in self._uinds]) self._avetoas = avetoas # interpolate ssb planet position vectors to avetoas planetssb = np.zeros((len(avetoas), 9, 3)) for jj in range(9): planetssb[:, jj, :] = np.array([ np.interp(avetoas, psr.toas, psr.planetssb[:, jj, aa]) for aa in range(3) ]).T self._planetssb = planetssb # Interpolating the pulsar position vectors onto epoch TOAs pos_t = np.array([ np.interp(avetoas, psr.toas, psr.pos_t[:, aa]) for aa in range(3) ]).T self._pos_t = pos_t # initialize delay self._delay = np.zeros(len(psr.toas)) # this defaults to all parameters @signal_base.cache_call("delay_params") def get_delay(self, params): if use_epoch_toas: delay = self._wf[""](toas=self._avetoas, planetssb=self._planetssb, pos_t=self._pos_t, params=params) for slc, val in zip(self._uinds, delay): self._delay[slc] = val return self._delay else: delay = self._wf[""](params=params) return delay return PhysicalEphemerisSignal
def PhysicalEphemerisSignal( frame_drift_rate=parameter.Uniform(-1e-9, 1e-9)('frame_drift_rate'), d_jupiter_mass=parameter.Normal(0, 1.54976690e-11)('d_jupiter_mass'), d_saturn_mass=parameter.Normal(0, 8.17306184e-12)('d_saturn_mass'), d_uranus_mass=parameter.Normal(0, 5.71923361e-11)('d_uranus_mass'), d_neptune_mass=parameter.Normal(0, 7.96103855e-11)('d_neptune_mass'), jup_orb_elements=parameter.Uniform(-0.05, 0.05, size=6)('jup_orb_elements'), sat_orb_elements=parameter.Uniform(-0.5, 0.5, size=6)('sat_orb_elements'), inc_jupiter_orb=True, inc_saturn_orb=False, use_epoch_toas=True, name=''): # noqa: E125,E501 """ Class factory for physical ephemeris model signal. This function implements a physically motivated ephemeris delay model. It is parameterized by an overall frame drift rate, masses of gas giants, 6 orbital elements of Jupiter (uses a PCA basis), and 6 orbital elements of Saturn (uses PCA basis). .. note:: This signal is only compatible with a tempo2 Pulsar object. The user can implement their own priors but we have set reasonable defaults. :param frame_drift_rate: ecliptic z-drift rate in units of rad/year referred to offset 1/1/2010. Default prior is Uniform(-1e-9, 1e-9). :param d_jupiter_mass: Mass deviation of jupiter in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 1.54976690e-11) :param d_saturn_mass: Mass deviation of saturn in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 8.17306184e-12) :param d_uranus_mass: Mass deviation of uranus in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 5.71923361e-11) :param d_neptune_mass: Mass deviation of neptune in solar masses. Default prior taken from IAU mass measurement uncertainty - Normal(0, 7.96103855e-11) :param jup_orb_elements: Amplitudes of PCA basis of jupiter orbital elements including (1) semi-major axis (2) eccentricity (3) inclination (4) longitude of the ascending node (5) longitude of perihelion (6) mean longitude Default prior is Uniform(-0.05, 0.05) for each element. :param sat_orb_elements: Amplitudes of PCA basis of saturn orbital elements including (1) semi-major axis (2) eccentricity (3) inclination (4) longitude of the ascending node (5) longitude of perihelion (6) mean longitude Default prior is Uniform(-0.5, 0.5) for each element. :param inc_jupiter_orb: Boolean indicating whether or not to include jupiter's orbital elements as free parameters in model. Default: True :param inc_saturn_orb: Boolean indicating whether or not to include saturn's orbital elements as free parameters in model. Default: False :param use_epoch_toas: Use interpolation from epoch to full TOAs. This option reduces computational cost for large multi-channel TOA data sets. Default: True """ # turn off saturn orbital element parameters if not including in signal if not inc_saturn_orb: sat_orb_elements = np.zeros(6) # define waveform jup_mjd, jup_orbelxyz, sat_mjd, sat_orbelxyz = ( utils.get_planet_orbital_elements()) wf = utils.physical_ephem_delay(frame_drift_rate=frame_drift_rate, d_jupiter_mass=d_jupiter_mass, d_saturn_mass=d_saturn_mass, d_uranus_mass=d_uranus_mass, d_neptune_mass=d_neptune_mass, jup_orb_elements=jup_orb_elements, sat_orb_elements=sat_orb_elements, inc_jupiter_orb=inc_jupiter_orb, jup_orbelxyz=jup_orbelxyz, jup_mjd=jup_mjd, inc_saturn_orb=inc_saturn_orb, sat_orbelxyz=sat_orbelxyz, sat_mjd=sat_mjd) BaseClass = Deterministic(wf, name=name) class PhysicalEphemerisSignal(BaseClass): signal_name = 'phys_ephem' signal_id = 'phys_ephem_' + name if name else 'phys_ephem' def __init__(self, psr): # not available for PINT yet if isinstance(psr, pulsar.PintPulsar): msg = 'Physical Ephemeris model is not compatible with PINT ' msg += 'at this time.' raise NotImplementedError(msg) super(PhysicalEphemerisSignal, self).__init__(psr) if use_epoch_toas: # get quantization matrix and calculate daily average TOAs U, _ = utils.create_quantization_matrix(psr.toas, nmin=1) self._uinds = utils.quant2ind(U) avetoas = np.array([psr.toas[sc].mean() for sc in self._uinds]) self._avetoas = avetoas # interpolate ssb planet position vectors to avetoas planetssb = np.zeros((len(avetoas), 9, 3)) for jj in range(9): planetssb[:, jj, :] = np.array([ np.interp(avetoas, psr.toas, psr.planetssb[:, jj, aa]) for aa in range(3) ]).T self._planetssb = planetssb # Interpolating the pulsar position vectors onto epoch TOAs pos_t = np.array([ np.interp(avetoas, psr.toas, psr.pos_t[:, aa]) for aa in range(3) ]).T self._pos_t = pos_t # initialize delay self._delay = np.zeros(len(psr.toas)) @signal_base.cache_call('delay_params') def get_delay(self, params): if use_epoch_toas: delay = self._wf[''](toas=self._avetoas, planetssb=self._planetssb, pos_t=self._pos_t, params=params) for slc, val in zip(self._uinds, delay): self._delay[slc] = val return self._delay else: delay = self._wf[''](params=params) return delay return PhysicalEphemerisSignal
nmodes=nmodes, Tspan=Tspan, logf=logf, fmin=fmin, fmax=fmax, modes=modes) n_Earth = np.einsum('ij,j', F, n_earth_rho) #np.repeat(10**n_earth_rho,2)) theta, R_earth, _, _ = SW.theta_impact(planetssb, sunssb, pos_t) dm_sol_wind = SW.dm_solar(1.0, theta, R_earth) dt_sw = n_Earth * dm_sol_wind * 4.148808e3 / freqs**2 return dt_sw n_earth_rho = parameter.Normal(0, 0.5, size=60)('n_earth_rho') sw_pert = solar_wind_perturb(n_earth_rho=n_earth_rho, Tspan=Tspan, nmodes=30) sw_perturb = deterministic_signals.Deterministic(sw_pert, name='sw_perturb') model += sw_perturb norm_model = model + dm_block if args.dm_dip: psr_models = [] for p in psrs: if p.name == 'J1713+0747': dmdip = chr.dm_exponential_dip(tmin=54700, tmax=54900) model_j1713 = norm_model + dmdip psr_models.append(model_j1713(p))
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
def bayes_ephem(self,option="default"): """ Deterministic signal from errors in Solar System ephemerides. """ ekw = {} ekw['model'] = "setIII" if isinstance(option, dict): # Converting parameters to bool masks for bekey, beval in option.items(): if isinstance(beval, list): option[bekey] = np.array(beval, dtype=bool) else: option[bekey] = bool(beval) options = '_'.join(option.keys()) else: options = option print(options) print(option) #adding keyword arguments to PhysicalEphemerisSignal based on input options #where PhysicalEphemerisSignal kwargs default to True, here we set to False if "framedr" in option: ekw['frame_drift_rate'] = parameter.Uniform(-1e-10, 1e-10)\ ('frame_drift_rate') else: ekw['frame_drift_rate'] = False if "mer_m" in option or "inner" in option: ekw['d_mercury_mass'] = parameter.Normal(0, 1.66e-10)('d_mer_mass') if "mer_el" in option: if isinstance(option, dict): ekw['mer_orb_elements'] = UniformMask(-0.5, 0.5, option['mer_el'])\ ('mer_oe') else: ekw['mer_orb_elements'] = parameter.Uniform(-0.5, 0.5, size=6)('mer_oe') if "ven_m" in options or "inner" in options: ekw['d_venus_mass'] = parameter.Normal(0, 2.45e-9)('d_ven_mass') if "ven_el" in options: if isinstance(option, dict): ekw['ven_orb_elements'] = UniformMask(-1., 1., option['ven_el'])('ven_oe') else: ekw['ven_orb_elements'] = parameter.Uniform(-1., 1., size=6)('ven_oe') if "mar_m" in option or "inner" in option: ekw['d_mars_mass'] = parameter.Normal(0, 3.23e-10)('d_mar_mass') if "mar_el" in option: if isinstance(option, dict): ekw['mar_orb_elements'] = UniformMask(-5., 5., option['mar_el'])('mar_oe') else: ekw['mar_orb_elements'] = parameter.Uniform(-5., 5., size=6)('mar_oe') if "jup_m" in option or "d_jupiter_mass" in option or "outer" in option or "default" in option: ekw['d_jupiter_mass'] = parameter.Normal(0, 1e-10)('d_jup_mass') #parameter.Normal(0, 1.54976690e-11)('d_jup_mass') else: ekw['d_jupiter_mass'] = False if "jup_el" in option or "outer" in option or "default" in option: if isinstance(option, dict) and (type(option['jup_el']) is list or \ type(option['jup_el']) is np.ndarray): ekw['jup_orb_elements'] = UniformMask(-0.5, 0.5, option['jup_el'])\ ('jup_oe') else: ekw['jup_orb_elements'] = parameter.Uniform(-0.5, 0.5, size=6)\ ('jup_oe') else: ekw['jup_orb_elements'] = False if "sat_m" in option or "outer" in option or "default" in option: ekw['d_saturn_mass'] = parameter.Normal(0, 8.17306184e-12)('d_sat_mass') else: ekw['d_saturn_mass'] = False if "sat_el" in option or "outer" in option: if isinstance(option, dict): ekw['sat_orb_elements'] = UniformMask(-5., 5., option['sat_el'])('sat_oe') else: ekw['sat_orb_elements'] = parameter.Uniform(-5., 5., size=6)('sat_oe') else: ekw['sat_orb_elements'] = False if "ura_m" in option or "outer" in option or "default" in option: ekw['d_uranus_mass'] = parameter.Normal(0, 5.71923361e-11)('d_ura_mass') else: ekw['d_uranus_mass'] = False if "ura_el" in option: if isinstance(option, dict): ekw['ura_orb_elements'] = UniformMask(-.5, .5, option['ura_el'])('ura_oe') else: ekw['ura_orb_elements'] = parameter.Uniform(-0.5, 0.5, size=6)('ura_oe') #else: # ekw['ura_orb_elements'] = False if "nep_m" in option or "outer" in option or "default" in option: ekw['d_neptune_mass'] = parameter.Normal(0, 7.96103855e-11)\ ('d_nep_mass') else: ekw['d_neptune_mass'] = False if "nep_el" in option: if isinstance(option, dict): ekw['nep_orb_elements'] = UniformMask(-.5, .5, option['nep_el'])('nep_oe') else: ekw['nep_orb_elements'] = parameter.Uniform(-0.5, 0.5, size=6)('nep_oe') #else: # ekw['nep_orb_elements'] = False #print(ekw) eph = deterministic_signals.PhysicalEphemerisSignal(**ekw) return eph
if args.sw_gp_mono_gp: @function def sw_free_spectrum(f, n_earth_rho=None): """ Free spectral model. PSD amplitude at each frequency is a free parameter. Model is parameterized by S(f_i) = \rho_i^2 * T, where \rho_i is the free parameter and T is the observation length. """ return np.repeat(n_earth_rho, 2) sw_desmatrix = SW.createfourierdesignmatrix_solar_dm(nmodes=40, Tspan=Tspan) n_earth_rho = parameter.Normal(0, 0.5, size=40)('n_earth_rho') fs = sw_free_spectrum(n_earth_rho=n_earth_rho) mono = utils.monopole_orf() sw_perturb = gp_signals.BasisCommonGP(fs, sw_desmatrix, mono, name='sw_perturb_mono') model += sw_perturb elif args.sw_pta_gp: @signal_base.function def solar_wind_perturb(toas, freqs, planetssb, sunssb,
# cw params cos_gwtheta = parameter.Uniform(-1, 1)('cos_gwtheta') gwphi = parameter.Uniform(0, 2 * np.pi)('gwphi') #log10_mc = parameter.LinearExp(7,10)('log10_mc') log10_mc = parameter.Uniform(7, 10)('log10_mc') #log10_fgw = BoundedNormal(log_f, log_f_err, -9, np.log10(3*10**(-7)))('log10_fgw') log10_fgw = parameter.Uniform(-9, np.log10(3 * 10**(-7)))('log10_fgw') phase0 = parameter.Uniform(0, 2 * np.pi)('phase0') psi = parameter.Uniform(0, np.pi)('psi') cos_inc = parameter.Uniform(-1, 1)('cos_inc') ##sarah's change p_phase = parameter.Uniform(0, 2 * np.pi) p_dist = parameter.Normal(0, 1) #log10_h = parameter.LinearExp(-18, -11)('log10_h') log10_h = parameter.Uniform(-18, -11)('log10_h') #log10_dL = parameter.Constant(np.log10(85.8))('log10_dL') cw_wf = fns.cw_delay(cos_gwtheta=cos_gwtheta, gwphi=gwphi, log10_mc=log10_mc, log10_h=log10_h, log10_fgw=log10_fgw, phase0=phase0, psi=psi, cos_inc=cos_inc, p_dist=p_dist, p_phase=p_phase,
def test_wideband(self): ms = white_signals.MeasurementNoise(selection=Selection(selections.by_backend)) dm = gp_signals.WidebandTimingModel( dmefac=parameter.Uniform(0.9, 1.1), dmefac_selection=Selection(selections.by_backend), dmjump=parameter.Normal(0, 1), dmjump_selection=Selection(selections.by_frontend), ) model = ms + dm pta = signal_base.PTA([model(self.psr)]) ps = parameter.sample(pta.params) pta.get_lnlikelihood(ps) dmtiming = pta.pulsarmodels[0].signals[1] msg = "DMEFAC masks do not cover the data." assert np.all(sum(dmtiming._dmefac_masks) == 1), msg msg = "DMJUMP masks do not cover the data." assert np.all(sum(dmtiming._dmjump_masks) == 1), msg # start with zero DMEFAC and DMJUMP p0 = {par.name: (1 if "dmefac" in par.name else 0) for par in dmtiming.params} pta.get_lnlikelihood(params=p0) phi0 = dmtiming.get_phi(params=p0) dl0 = dmtiming.get_delay(params=p0) dm_flags, dme_flags = np.array(self.psr.flags["pp_dm"], "d"), np.array(self.psr.flags["pp_dme"], "d") delays = np.zeros_like(self.psr.toas) check = 0 for index, par in enumerate(self.psr.fitpars): if "DMX" not in par: msg = "Problem with unbound timing parameters" assert phi0[index] == 1e40, msg else: dmx = self.psr.dmx[par] which = (dmx["DMXR1"] <= (self.psr.stoas / 86400)) & ((self.psr.stoas / 86400) < dmx["DMXR2"]) check += which avgdm = np.sum(dm_flags[which] / dme_flags[which] ** 2) / np.sum(1.0 / dme_flags[which] ** 2) vardm = 1.0 / np.sum(1.0 / dme_flags[which] ** 2) msg = "Priors do not match" assert np.allclose(vardm, phi0[index]), msg delays[which] = (avgdm - self.psr.dm - dmx["DMX"]) / (2.41e-4 * self.psr.freqs[which] ** 2) msg = "Not all TOAs are covered by DMX" assert np.all(check == 1) msg = "Delays do not match" assert np.allclose(dl0, delays), msg # sample DMEFACs randomly p1 = {par.name: (parameter.sample(par)[par.name] if "dmefac" in par.name else 0) for par in dmtiming.params} pta.get_lnlikelihood(params=p1) phi1 = dmtiming.get_phi(params=p1) dl1 = dmtiming.get_delay(params=p1) sel = Selection(selections.by_backend)(self.psr) msg = "Problem making selection" assert np.all(sum(m for m in sel.masks.values()) == 1), msg dme_flags_var = dme_flags.copy() for key, mask in sel.masks.items(): dmefac = p1["J1832-0836_" + key + "_dmefac"] dme_flags_var[mask] *= dmefac for index, par in enumerate(self.psr.fitpars): if "DMX" not in par: msg = "Problem with unbound timing parameters" assert phi1[index] == 1e40, msg else: dmx = self.psr.dmx[par] which = (dmx["DMXR1"] <= (self.psr.stoas / 86400)) & ((self.psr.stoas / 86400) < dmx["DMXR2"]) avgdm = np.sum(dm_flags[which] / dme_flags_var[which] ** 2) / np.sum(1.0 / dme_flags_var[which] ** 2) vardm = 1.0 / np.sum(1.0 / dme_flags_var[which] ** 2) msg = "Priors do not match" assert np.allclose(vardm, phi1[index]), msg delays[which] = (avgdm - self.psr.dm - dmx["DMX"]) / (2.41e-4 * self.psr.freqs[which] ** 2) msg = "Delays do not match" assert np.allclose(dl1, delays), msg