def __init__(self, Smax0, Smin0=0, f0=1, spectral_index=0.8, **parameters): # Ensure units Smax0 = ensure_unit(Smax0, un.Jy) Smin0 = ensure_unit(Smin0, un.Jy) self.Smax0 = Smax0 self.Smin0 = Smin0 self.f0 = np.atleast_1d(f0) self.spectral_index = spectral_index self.params = parameters
def fourier_beam(self, u, v=None, f0=1): "The fourier transform of beam attenuation at u,v" u2 = self._r2(u, v, f0) u2 = ensure_unit(u2, 1. / un.rad**2) return (2 * np.pi * self.sigma(f0)**2 * np.exp(-2 * np.pi**2 * self.sigma(f0)**2 * u2.T)).T
def dnds(self, s): s = ensure_unit(np.atleast_1d(s), un.Jy) dn = np.zeros(len(s)) * self.alpha[0].unit for i, (sb, b) in enumerate(zip(self.sbreak[:-1], self.params['beta'])): mask = np.logical_and(s < sb, s >= self.sbreak[i + 1]) dn[mask] = self.alpha[i] * (s[mask] / un.Jy)**-b return dn
def __init__(self, *args, **kwargs): super(MultiPowerLawSourceCounts, self).__init__(*args, **kwargs) self.params['alpha'] = ensure_unit(self.params['alpha'], 1. / un.Jy / un.steradian) a = self._get_alpha() if np.any(np.array(self.params['Sbreak']) > self.Smax0.value): ind = np.where(self.params['Sbreak'] > self.Smax0.value)[0][0] self.params["Sbreak"] = np.array(self.params["Sbreak"][(ind + 1):]) self.params["alpha"] = a[ind + 1] self.params["beta"] = np.array(self.params["beta"][(ind + 1):]) if np.any(np.array(self.params['Sbreak']) < self.Smin0.value): raise ValueError("All values of Sbreak must be larger than Smin0")
def effective_volume(self, Aeff): """ The approximate effective volume of the model in sr.MHz Parameters ---------- Aeff : float The effective collecting area of the telescope, in m^2. Returns ------- vol : Effective volume of the model (given the beamwidth and frequency coverage), in sr.MHz. """ Aeff = ensure_unit(Aeff, un.m**2) hz_range = self.beam_model.nu0 * (self.f0.max() - self.f0.min()) numax = self.beam_model.nu0 * self.f0.max() return un.steradian * (cnst.c**2 / numax**2).to(un.m** 2) / Aeff * hz_range
def __init__(self, source_counts, beam_model, u=np.linspace(8, 500, 50), clustering_params={"func": lambda u: np.zeros_like(u)}): self.u = ensure_unit(u, 1 / un.rad) self.beam_model = beam_model self.source_counts = source_counts self.f0 = self.source_counts.f0 if not np.allclose(np.diff(self.f0), self.f0[1] - self.f0[0]): raise ValueError( "Frequencies must be specified in regular intervals in real space" ) self.clustering_params = clustering_params if not isinstance(self.beam_model, CircularGaussian): raise ValueError( "This class requires the beam model to be a circular gaussian." )
def radio_to_cosmo_equiv(nu, Aeff): f21 = 1420 * un.MHz z = f21 / nu - 1 Aeff = ensure_unit(Aeff, un.m**2) hz_mpc = un.Hz.to(un.Mpc / hub, equivalencies=cosmo_21cm_los_equiv(z)) sr_mpc = un.steradian.to(un.Mpc**2 / hub**2, equivalencies=cosmo_21cm_angle_equiv(z)) jy_Ksr = un.Jy.to(un.K * un.steradian, equivalencies=brightness_temp(Aeff)) return [(un.steradian * un.Hz, un.Mpc**3 / hub**3, lambda x: x * hz_mpc * sr_mpc, lambda x: x / (hz_mpc * sr_mpc)), (un.Jy * un.Hz, un.K * un.Mpc**3 / hub**3, lambda x: x * jy_Ksr * sr_mpc * hz_mpc, lambda x: x / (jy_Ksr * sr_mpc * hz_mpc)), (un.Jy**2 * un.Hz**2, un.K**2 * un.Mpc**6 / hub**6, lambda x: x * (jy_Ksr * sr_mpc * hz_mpc)**2, lambda x: x / (jy_Ksr * sr_mpc * hz_mpc)**2), (un.Jy**4 * un.Hz**4, un.K**4 * un.Mpc**12 / hub**12, lambda x: x * (jy_Ksr * sr_mpc * hz_mpc)**4, lambda x: x / (jy_Ksr * sr_mpc * hz_mpc)**4)]
def dnds(self, s): s = ensure_unit(s, un.Jy) return self.params['alpha'] * (s / un.Jy)**-self.params['beta']
def __init__(self, *args, **kwargs): super(PowerLawSourceCounts, self).__init__(*args, **kwargs) self.params['alpha'] = ensure_unit(self.params['alpha'], 1 / un.Jy / un.steradian)
def beam_1D(self, l, m=None, f0=1): "The beam attenuation at l,m" r2 = self._r2(l, m, f0, 1) r2 = ensure_unit(r2, un.rad**2) return np.exp(-r2.T / (2 * self.sigma(f0)**2)).T
def __init__(self, *args, **kwargs): super(CircularGaussian, self).__init__(*args, **kwargs) self.params['D'] = ensure_unit(self.params['D'], un.m)
def __init__(self, nu0, **params): self.nu0 = ensure_unit(nu0, un.MHz) super(Beam, self).__init__(**params)
def __init__(self, *args, **kwargs): super(CircularGaussianPowerLaw, self).__init__(*args, **kwargs) self.clustering_params['u0'] = ensure_unit( self.clustering_params['u0'], 1 / un.rad)
def _beam_squared(self, r): r = ensure_unit(r, un.rad) s = self.beam_model.sigma[0] return np.exp(-r**2 / s**2)
def _beam_term(self, r): """Returns the inverse fourier transform of the fourier transformed beam squared""" r = ensure_unit(r, un.rad) s = self.beam_model.sigma[0] return np.pi * s**2 * np.exp(-r**2 / (4 * s**2))