Esempio n. 1
0
def test_alternative(s, nu, k, N, h):
    """Test alternative hankel definition."""
    ht1 = HankelTransform(nu=nu, N=N, h=h)
    ht2 = HankelTransform(nu=nu, N=N, h=h, alt=True)
    ft1 = ht1.transform(lambda r: r**s, k, False, False)
    ft2 = ht2.transform(lambda r: r**(s + 0.5), k, False, False) / k**0.5
    print("Numerical Results: ", ft1, " and ", ft2)
    assert np.isclose(ft1, ft2, rtol=1e-3)
Esempio n. 2
0
def Cl_to_wtheta(nz, table_l, table_Cl, theta, path, nu=0, N=500, h=0.005):
    assert isinstance(nz, int), 'Invalid nz: {}. Must be an integer'.format(nz)
    import os
    from hankel import HankelTransform as HT
    import numpy as np
    from scipy.interpolate import UnivariateSpline

    header = '{:<25s}'.format('# r (deg)')
    for i in range(nz):
        header += '{:<25s}'.format('w_{}'.format(i))

    ht = HT(nu=nu, N=N, h=h)

    w = np.empty((nz, theta.size))
    for i in range(nz):
        # Fit Cl's with Spline
        Cl = UnivariateSpline(table_l, table_Cl[i], s=0, k=1)

        # Do the Hankel Transform to get the correlation function
        for j, thetai in zip(range(theta.size), np.deg2rad(theta)):
            f = lambda x: (x * Cl(x / thetai)) / (2. * np.pi * np.power(
                thetai, 2))
            w[i, j] = ht.transform(f)[0]

    np.savetxt(path,
               np.vstack((theta, w)).T,
               fmt='%-25.18e',
               header=header,
               comments='')
    return w
Esempio n. 3
0
def test_k_zero(nu, alt):
    """Testing k=0."""
    threshold = -0.5 if alt else 0
    ht = HankelTransform(nu=nu, N=50, h=1e-3, alt=alt)
    ans = ht.transform(lambda r: np.exp(-(r**2) / 2), 0, False, False)
    print("Numerical Results: ", ans)
    if nu < threshold:
        assert np.isnan(ans)
    elif nu > threshold:
        assert np.isclose(ans, 0, rtol=1e-3)
    else:
        assert np.isclose(ans, 1, rtol=1e-3)
Esempio n. 4
0
def test_powerlaw(s, nu, k, N, h):
    """
    Test f(r) = 1/r, nu=0
    """

    ht = HankelTransform(nu=nu, N=N, h=h)
    ans = ht.transform(lambda x: x ** s, k, False, False)
    if nu - s <= 0 and (nu - s) % 2 == 0:
        raise Exception("Can't have a negative integer for gamma")

    anl = 2 ** (s + 1) * gamma(0.5 * (2 + nu + s)) / k ** (s + 2) / gamma(0.5 * (nu - s))

    print("Numerical Result: ", ans, " (required %s)" % anl)
    assert np.isclose(ans, anl, rtol=1e-3)
Esempio n. 5
0
class SeeingApertureMTF:
    """
    This is the class that generates the effective aperture for a given Fried parameter and can also populate it using the model assuming that the Earth's atmosphere can be modelled as a medium with smoothly varying turbulence.

    Parameters
    ----------
    wavel : float
        The wavelength of light in Angstroms.
    r0 : float
        The Fried parameter in m.
    pxScale : float
        The size of one detector pixel in arcseconds on the observed object.
    air : bool, optional
        Whether or not the provided wavelength is air wavelength. If not then the wavelength is converted from vacuum value. Default is False.
    """
    def __init__(self, wavel, r0, pxScale, air=False):
        if air:
            self.wavel = wavel * 1e-10
        else:
            self.wavel = vac_to_air(wavel << u.Angstrom).value * 1e-10

        self.r0 = r0
        self.pxScale = pxScale

        self.resolution = 0.98 * self.wavel / self.r0 * 206265  # resolution of the image after being imaged through seeing
        self.diameter = int(self.resolution /
                            self.pxScale)  # diameter of PSF in pixels
        self.psf = np.zeros(shape=(int(self.diameter), int(self.diameter)))
        self.pxm = np.linspace(
            1.75, 880,
            int(880 / 1.75) + 1
        )  # 1.75 is the size of one pixel in metres and 880 is the size of 840 pixels in metres and the int(880/1.75)+1 is the number of pixels in the field-of-view of 840 pixels, this is an average field-of-view size in pixels with higher field-of-views not adding much to the terms
        self.modtf = self.mtf(self.wavel, self.r0)
        self.ht = HankelTransform(nu=0, h=0.05, N=62)
        self.psf1d = self.ht.transform(self.modtf, self.pxm, ret_err=False)

        for j in range(self.psf.shape[0]):
            for i in range(self.psf.shape[1]):
                idx = int(
                    np.linalg.norm((j - self.psf.shape[0] // 2,
                                    i - self.psf.shape[1] // 2)))
                self.psf[j, i] = self.psf1d[idx]

        self.psf /= self.psf.sum()

    @staticmethod
    def mtf(wavel, r0):
        return lambda x: np.exp(-(6.88 / 2.0) * (wavel * x /
                                                 (2 * np.pi * r0))**(5 / 3))
Esempio n. 6
0
def test_powerlaw(s, nu, k, N, h):
    """
    Test f(r) = 1/r, nu=0
    """

    ht = HankelTransform(nu=nu, N=N, h=h)
    ans = ht.transform(lambda x: x**s, k, False, False)
    if nu - s <= 0 and (nu - s) % 2 == 0:
        raise Exception("Can't have a negative integer for gamma")

    anl = (2**(s + 1) * gamma(0.5 * (2 + nu + s)) / k**(s + 2) /
           gamma(0.5 * (nu - s)))

    print("Numerical Result: ", ans, " (required %s)" % anl)
    assert np.isclose(ans, anl, rtol=1e-3)
def H_3(x,n,mu,dia):
    y = np.pi * mu / 6.0
    lam1 = (1 + 2 * y) ** 2 / ((1.0 - y) ** 4)
    lam2 = - (1 + y / 2.0) ** 2 / ((1.0 - y) ** 4)
    x = x/dia
    C3 = lambda x: -(lam1 * y * x ** 3 / 2.0 + 6 * y * lam2 * x + lam1) if (1 >= x.any() >= 0) else 0
    C2 = []
    for x2 in x:
        C2.append(C3(x2))
    h = HankelTransform(nu=0, N=1000, h=0.005)
    Ck_3 = h.transform(C3, k, ret_err=False)
    Hk_3 = Ck_3 / (1 - n * Ck_3)
    #Hk_3 = spline(k, Hk_3)  # Define a spline to approximate transform
    #Hx_3 = h.transform(Hk_3, x, False, inverse=True)
    #Fk = ht.transform(C3, k, ret_err=False)
    #Ck_3 = fft(C2)
    return Hk_3
Esempio n. 8
0
    def FT3D(self,
             k,
             cf,
             R=None,
             Rmin=None,
             Rmax=None,
             epsabs=1e-12,
             epsrel=1e-12,
             limit=500,
             split_by_scale=False,
             method='clenshaw-curtis',
             use_pb=False,
             suppression=np.inf):
        """
        This is nearly identical to the inverse transform function above,
        I just got tired of having to remember to swap meanings of the
        k and R variables. Sometimes clarity is better than minimizing 
        redundancy.
        """
        assert type(k) == np.ndarray

        if (type(cf) == FunctionType) or isinstance(cf, interp1d) \
           or isinstance(cf, Akima1DInterpolator):
            R = cf.x
        elif type(cf) == np.ndarray:
            # Setup interpolant

            assert R is not None, "Must supply R vector as well!"

            #if interpolant == 'akima':
            #    ps = Akima1DInterpolator(k, ps)
            #elif interpolant == 'cubic':
            cf = interp1d(np.log(R),
                          cf,
                          kind='cubic',
                          assume_sorted=True,
                          bounds_error=False,
                          fill_value=0.0)

        else:
            raise ValueError('Do not understand type of `ps`.')

        if Rmin is None:
            Rmin = R.min()
        if Rmax is None:
            Rmax = R.max()

        norm = 1. / cf(np.log(Rmin))

        if method == 'ogata':
            assert have_hankel, "hankel package required for this!"

            integrand = lambda RR: four_pi * R**2 * norm * cf(np.log(RR))
            ht = HankelTransform(nu=0, N=k.size, h=0.1)

            #integrand = lambda kk: ps(np.log(kk)) * norm
            #ht = SymmetricFourierTransform(3, N=k.size, h=0.001)

            #print(ht.integrate(integrand))
            ps = ht.transform(integrand, k=k, ret_err=False,
                              inverse=False) / norm

            return ps

        ##
        # Optional progress bar
        ##
        pb = ProgressBar(R.size,
                         use=self.pf['progress_bar'] * use_pb,
                         name='cf(R)->ps(k)')

        # Loop over k and perform integral
        ps = np.zeros_like(k)
        for i, kk in enumerate(k):

            if not pb.has_pb:
                pb.start()

            pb.update(i)

            if method == 'clenshaw-curtis':

                # Leave sin(k*R) out -- that's the 'weight' for scipy.
                # Note the minus sign.
                integrand = lambda RR: norm * four_pi * RR**2 * cf(np.log(RR)) \
                    * np.exp(-kk * RR / suppression) / kk / RR

                if split_by_scale:
                    Rcri = np.exp(cf.x[np.argmin(
                        np.abs(np.exp(cf.x) - 1. / kk))])

                    # Integral over small k is easy
                    lowR = np.exp(cf.x) <= Rcri
                    Rlow = np.exp(cf.x[lowR == 1])
                    clow = cf.y[lowR == 1]
                    sinc = np.sin(kk * Rlow) / Rlow / kk
                    integ = norm * four_pi * Rlow**2 * clow * sinc \
                        * np.exp(-kk * Rlow / suppression)
                    ps[i] = np.trapz(integ * Rlow, x=np.log(Rlow)) / norm

                    Rstart = Rcri

                    #if lowR.sum() < 1000 and lowR.sum() % 100 == 0:
                    #    import matplotlib.pyplot as pl
                    #
                    #    pl.figure(2)
                    #
                    #    sinc = np.sin(kk * R) / kk / R
                    #    pl.loglog(R, integrand(R) * sinc, color='k')
                    #    pl.loglog([Rcri]*2, [1e-4, 1e4], color='y')
                    #    raw_input('<enter>')

                else:
                    Rstart = Rmin

                # Use 'chebmo' to save Chebyshev moments and pass to next integral?
                ps[i] += quad(integrand,
                              Rstart,
                              Rmax,
                              epsrel=epsrel,
                              epsabs=epsabs,
                              limit=limit,
                              weight='sin',
                              wvar=kk)[0] / norm

            else:
                raise NotImplemented('help')

        pb.finish()

        #
        return np.abs(ps)
Esempio n. 9
0
    def InverseFT3D(self,
                    R,
                    ps,
                    k=None,
                    kmin=None,
                    kmax=None,
                    epsabs=1e-12,
                    epsrel=1e-12,
                    limit=500,
                    split_by_scale=False,
                    method='clenshaw-curtis',
                    use_pb=False,
                    suppression=np.inf):
        """
        Take a power spectrum and perform the inverse (3-D) FT to recover
        a correlation function.
        """
        assert type(R) == np.ndarray

        if (type(ps) == FunctionType) or isinstance(ps, interp1d) \
           or isinstance(ps, Akima1DInterpolator):
            k = ps.x
        elif type(ps) == np.ndarray:
            # Setup interpolant

            assert k is not None, "Must supply k vector as well!"

            #if interpolant == 'akima':
            #    ps = Akima1DInterpolator(k, ps)
            #elif interpolant == 'cubic':

            ps = interp1d(np.log(k),
                          ps,
                          kind='cubic',
                          assume_sorted=True,
                          bounds_error=False,
                          fill_value=0.0)

            #_ps = interp1d(np.log(k), np.log(ps), kind='cubic', assume_sorted=True,
            #    bounds_error=False, fill_value=-np.inf)
            #
            #ps = lambda k: np.exp(_ps.__call__(np.log(k)))

        else:
            raise ValueError('Do not understand type of `ps`.')

        if kmin is None:
            kmin = k.min()
        if kmax is None:
            kmax = k.max()

        norm = 1. / ps(np.log(kmax))

        ##
        # Use Steven Murray's `hankel` package to do the transform
        ##
        if method == 'ogata':
            assert have_hankel, "hankel package required for this!"

            integrand = lambda kk: four_pi * kk**2 * norm * ps(np.log(kk)) \
                * np.exp(-kk * R / suppression)
            ht = HankelTransform(nu=0, N=k.size, h=0.001)

            #integrand = lambda kk: ps(np.log(kk)) * norm
            #ht = SymmetricFourierTransform(3, N=k.size, h=0.001)

            #print(ht.integrate(integrand))
            cf = ht.transform(integrand, k=R, ret_err=False,
                              inverse=True) / norm

            return cf / (2. * np.pi)**3
        else:
            pass
            # Otherwise, do it by-hand.

        ##
        # Optional progress bar
        ##
        pb = ProgressBar(R.size,
                         use=self.pf['progress_bar'] * use_pb,
                         name='ps(k)->cf(R)')

        # Loop over R and perform integral
        cf = np.zeros_like(R)
        for i, RR in enumerate(R):

            if not pb.has_pb:
                pb.start()

            pb.update(i)

            # Leave sin(k*R) out -- that's the 'weight' for scipy.
            integrand = lambda kk: norm * four_pi * kk**2 * ps(np.log(kk)) \
                * np.exp(-kk * RR / suppression) / kk / RR

            if method == 'clenshaw-curtis':

                if split_by_scale:
                    kcri = np.exp(ps.x[np.argmin(
                        np.abs(np.exp(ps.x) - 1. / RR))])

                    # Integral over small k is easy
                    lowk = np.exp(ps.x) <= kcri
                    klow = np.exp(ps.x[lowk == 1])
                    plow = ps.y[lowk == 1]
                    sinc = np.sin(RR * klow) / klow / RR
                    integ = norm * four_pi * klow**2 * plow * sinc \
                        * np.exp(-klow * RR / suppression)
                    cf[i] = np.trapz(integ * klow, x=np.log(klow)) / norm

                    kstart = kcri

                    #print(RR, 1. / RR, kcri, lowk.sum(), ps.x.size - lowk.sum())
                    #
                    #if lowk.sum() < 1000 and lowk.sum() % 100 == 0:
                    #    import matplotlib.pyplot as pl
                    #
                    #    pl.figure(2)
                    #
                    #    sinc = np.sin(RR * k) / k / RR
                    #    pl.loglog(k, integrand(k) * sinc, color='k')
                    #    pl.loglog([kcri]*2, [1e-4, 1e4], color='y')
                    #    raw_input('<enter>')

                else:
                    kstart = kmin

                # Add in the wiggly part
                cf[i] += quad(integrand,
                              kstart,
                              kmax,
                              epsrel=epsrel,
                              epsabs=epsabs,
                              limit=limit,
                              weight='sin',
                              wvar=RR)[0] / norm

            else:
                raise NotImplemented('help')

        pb.finish()

        # Our FT convention
        cf /= (2 * np.pi)**3

        return cf
Esempio n. 10
0
for i, snapshot in enumerate([85, 79, 73, 68]):
  print i, snapshot
  # Load the measured correlation function
  gi=np.loadtxt('/Users/hattifattener/Documents/ias/mbii/2pt/ns300_nd1000/v10/snapshot%d/fiducial/GIplus_proj_corr_00.txt'%snapshot).T
  ii=np.loadtxt('/Users/hattifattener/Documents/ias/mbii/2pt/ns300_nd1000/v10/snapshot%d/fiducial/IIplus_proj_corr_00.txt'%snapshot).T

  # Initialise the transform
  ht4 = HankelTransform(nu=2, N=12000, h=0.005)
  ht4 = HankelTransform(nu=4, N=12000, h=0.005)
  spline = Spline(gi[0], gi[1], k=1)
  K = lambda x : spline(x)
  splineii = Spline(ii[0], ii[1], k=1)
  Kii = lambda x : splineii(x)

  # Evaluate the integral repeatedly at each of a set of k values 
  pk = np.array([ht4.transform(K, k0)[0] for k0 in k ])
  pkII = np.array([ 0.5 * (ht4.transform(Kii, k0)[0] + ht4.transform(Kii, k0)[0]) for k0 in k ])

  # Store the power spectrum for this redshift
  PgI[snapshot] = -1 * pk
  PII[snapshot] = pkII

  plt.plot(k, pk, color=colours[i], label='$z=%3.2f$'%redshift[snapshot])
  plt.plot(k, pkII, color=colours[i], ls='--')
  np.savetxt('pgI-massive_black_ii-snapshot%d.txt'%snapshot, [k,pk])
  np.savetxt('pII-massive_black_ii-snapshot%d.txt'%snapshot, [k,pkII])

plt.xlabel('Wavenumber $k$ / $h^{-1}$', fontsize=16)
plt.ylabel(r'$P_\mathrm{\delta_g I}(k)$', fontsize=16)
plt.xscale('log')
plt.yscale('log')
Esempio n. 11
0
def test_equivalence_of_integrate_and_transform():
    ht = HankelTransform(N=50)
    intg = ht.integrate(lambda x: 1, False)
    tr = ht.transform(lambda x: 1.0 / x, ret_err=False)
    assert intg == tr
Esempio n. 12
0
def test_k_scalar():
    k = 1
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1.0 / x, k, False)
    assert np.isscalar(res)
Esempio n. 13
0
def test_k_array():
    k = np.logspace(-3, 3, 10)
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1.0 / x, k, False)
    assert len(res) == 10
Esempio n. 14
0
#!/usr/bin/env python
import sys, os
import numpy as np
import pylab as py
from hankel import HankelTransform
from scipy.special import jv as bessel
from scipy.integrate import quad, quadrature, fixed_quad

BT = np.linspace(0, 10, 100)
W = lambda bT: np.exp(-0.5 * bT**2)

qT = 2.0

integrand = lambda bT: bT * bessel(0, bT * qT) * W(bT)
tgral = quad(integrand, 1e-4, np.inf)[0]
print tgral

f = lambda x: x * W(x / qT)
#h = HankelTransform(nu=0,N=120,h=0.03)
h = HankelTransform(nu=0, N=120, h=0.003)
print h.transform(f, ret_err=False)[0] / qT**2

#f = lambda x: 1  #Define the input function f(x)
#h = HankelTransform(nu=0,N=120,h=0.03)  #Create the HankelTransform instance
#print h.transform(f)
# P2D = interp1d(ls, refs, kind='cubic')
spl = Spline(np.log(ths), np.log(refs), k=1)


def P2D(x):
    return np.exp(spl(np.log(x)))


# Xi+
htp = HankelTransform(
    nu=0,  # The order of the bessel function
    N=120000,  # Number of steps in the integration
    h=0.01  # Proxy for "size" of steps in integration
)

xip = htp.transform(P2D, ths, ret_err=False)

# Xi-
htm = HankelTransform(
    nu=4,  # The order of the bessel function
    N=120000,  # Number of steps in the integration
    h=0.01  # Proxy for "size" of steps in integration
)

xim = htm.transform(P2D, ths, ret_err=False)

plt.figure(1).set_size_inches((8, 8), forward=False)
plt.plot(thsarcmin,
         [abs(xip[i] * 2 * np.pi - refs1[i]) / refs1[i] for i in range(nth)])
plt.title("Variation of $\\xi_+$ changing modes number, lref={0}".format(ref))
plt.xlabel("$\\theta$ (arcmin)")
Esempio n. 16
0
def test_equivalence_of_integrate_and_transform():
    ht = HankelTransform(N=50)
    int = ht.integrate(lambda x: 1, False)
    tr = ht.transform(lambda x: 1. / x, ret_err=False)
    assert int == tr
Esempio n. 17
0
def test_k_scalar():
    k = 1
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1. / x, k, False)
    assert np.isscalar(res)
Esempio n. 18
0
def test_k_array():
    k = np.logspace(-3, 3, 10)
    ht = HankelTransform(N=50)
    res = ht.transform(lambda x: 1. / x, k, False)
    assert len(res) == 10