Example #1
0
def plot_dA(zmin=15, zmax=35, nz=100):
    das = np.zeros(nz)
    zs = np.linspace(zmin, zmax, nz)
    for i, z in enumerate(zs):
        das[i] = cf.val_dA(z) / Mpc_in_cm  # Mpc comoving

    #kmin = 2.*np.pi/(dA*sint/Mpc_in_cm) # 1/Mpc comoving
    #kmax = kmin * DeltaL_cm / lambda_z # 1/Mpc comoving
    plt.plot(zs, das, lw=3)
Example #2
0
def plot_dA(zmin=15,zmax=35,nz=100):
    das = np.zeros(nz)
    zs = np.linspace(zmin,zmax,nz)
    for i,z in enumerate(zs):
        das[i] = cf.val_dA( z )/Mpc_in_cm # Mpc comoving


    #kmin = 2.*np.pi/(dA*sint/Mpc_in_cm) # 1/Mpc comoving
    #kmax = kmin * DeltaL_cm / lambda_z # 1/Mpc comoving
    plt.plot(zs,das,lw=3)
Example #3
0
def nest_integrator(neval=100,
                    Nz=20,
                    DeltaL_km=2.,
                    kminmin=0.0001,
                    kmaxmax=10.,
                    zmax=35,
                    zmin=10,
                    Omega_survey=1.,
                    Omega_patch=1.,
                    thetan=np.pi / 2.,
                    phin=0.):
    """Alternative integrator for B0 and xi sensitivity; 
    NOTE: does not return the same units output as rand_integrator.
    """

    DeltaL_cm = DeltaL_km * 1e5
    zs = np.linspace(zmin, zmax, Nz)
    thetas = np.linspace(0., np.pi, neval)
    phis = np.linspace(0., 2. * np.pi, neval)
    ks = np.zeros(neval)

    samplesz = np.zeros(Nz)
    samplesp = np.zeros(neval)
    samplest = np.zeros(neval)
    samplesk = np.zeros(neval)
    for i, z in enumerate(zs):
        print(z)
        dA = cf.val_dA(z)
        lambda_z = lambda21 * (1. + z)
        for j, phik in enumerate(phis):
            for l, thetak in enumerate(thetas):
                thetak_n = np.arccos(
                    np.sin(thetak) * np.cos(phik) * np.sin(thetan) *
                    np.cos(phin) + np.sin(thetak) * np.sin(phik) *
                    np.sin(thetan) * np.sin(phin) +
                    np.cos(thetak) * np.cos(thetan))
                sint = np.sin(thetak_n)
                kmin = 2. * np.pi / (dA * sint / Mpc_in_cm)  # 1/Mpc comoving
                kmax = kmin * DeltaL_cm / lambda_z  # 1/Mpc comoving
                ks = np.linspace(kmin, kmax, neval)
                kVol = kmax - kmin
                samplesk = np.zeros(neval)
                for m, k in enumerate(ks):
                    x = np.array([z, k, thetak, phik])
                    samplesk[m] = integrand(x,
                                            DeltaL_km=DeltaL_km,
                                            Omega_patch=Omega_patch)
                samplest[l] = samplesk.mean() * kVol
            tVol = np.pi
            samplesp[j] = samplest.mean() * tVol
        pVol = 2. * np.pi
        samplesz[i] = samplesp.mean() * pVol

    zVol = zmax - zmin
    res = samplesz.mean() * zVol

    alpha_survey = (Omega_survey)**0.5
    result_all_survey = res / Omega_patch * np.pi * (
        alpha_survey + np.cos(alpha_survey) * np.sin(alpha_survey))

    result = 1. / result_all_survey**0.5

    return result
Example #4
0
def calc_SNR(zmin=15,
             zmax=25,
             t_yr=1.,
             DeltaL_km=1.,
             kminmin=0.01,
             kmaxmax=1.,
             neval=100,
             neval_PBi=5000,
             Omega_survey=1.,
             thetan=np.pi / 2.,
             phin=0.,
             debug=False,
             plotter_calling=False):
    """This is a master function for calculating SNR for detecting amplitude A0^2[Gauss^2] = 1/SNR at 1 sigma.

    This function only works for FFTT setup. It takes the stuff described below, returns sigma_A0 in Gauss.

    :param zmin:
      The minimum inegration redshift
    :type zmin: ``float``

    :param zmax:
      The maximum inegration redshift
    :type zmax: ``float``

    :param DeltaL_km:
      The size of the FFTT coverage on a side in kilometers.
    :type DeltaL_km: ``float``

    :param kminmin:
      The minimum wavenumber k considered, in 1/Mpc comoving;
      not the same as the integration limit kmin.
    :type kminmin: ``float``

    :param kmaxmax:
      The maximum wavenumber k considered, in 1/Mpc comoving;
      not the same as the integration limit kmax.
    :type kmaxmax: ``float``

    :param neval:
      The number of evaluations of the integrand, in z direction;
      neval = 100 is usually enough for convergence at a ~50% level.
    :type neval: ``int``

    :param neval_PBi:
      The number of evaluations of the integrand for the calculation of PBi, 
      in k, theta, phi directions;
      neval_PBi = 500 is usually enough for convergence at a ~10% level.
    :type neval_PBi: ``int``

    :param Omega_survey:
      The survey area (on the sky) in steradians.
    :type Omega_survey: ``float``

    :params thetan,phin:
      These define direction of the LOS in the frame where 
      mag. field vector B is along the z axis. 
      Do not change these unless you know exactly what you're getting into.
    :type thetan,phin: ``float``

    
    """

    if plotter_calling:
        zs = np.linspace(zmin, zmax, neval)
    else:
        zs = np.random.random(size=neval) * (zmax - zmin) + zmin
    samples = np.zeros(neval)
    for i, z in enumerate(zs):
        PBi = calc_PBi(z,
                       neval=neval_PBi,
                       t_yr=t_yr,
                       DeltaL_km=DeltaL_km,
                       Omega_survey=Omega_survey,
                       kminmin=kminmin,
                       kmaxmax=kmaxmax,
                       thetan=thetan,
                       phin=phin)
        dA = cf.val_dA(z)  # cm
        H_z = cf.H(z)
        dV = Vpatch_factor(z, dA=dA, H_z=H_z, Omega_patch=Omega_survey)
        lambda_z = lambda21 * (1. + z) * 1e-5  #converting lambda to km
        samples[i] = dV / PBi**2 * (1. - (lambda_z / DeltaL_km)**3) / (
            2. * np.pi / (dA / Mpc_in_cm))**3  #* (1 + z)**8
        if debug:
            print(z, samples[i], lambda_z, (1. - (DeltaL_km / lambda_z)**3))

    if plotter_calling:
        return zs, 1 / (1. / (10. * np.pi**2) * samples)**0.25 / np.pi

    res = 1. / (10. * np.pi**2) * samples.mean() * (zmax - zmin
                                                    )  #check coefficients?
    return 1. / res**0.25
Example #5
0
def integrand_PBi(x,
                  t_yr=1.,
                  Omega_survey=1.,
                  DeltaL_km=2.,
                  val_nk=FFTT_nk,
                  val_Ts=rf.Ts_21cmfast_interp,
                  val_Tk=rf.Tk_21cmfast_interp,
                  val_Jlya=rf.Jlya_21cmfast_interp,
                  val_x1s=rf.ones_x1s,
                  val_Tsys=Tsys_Mao2008,
                  val_Tg=rf.Tg_21cmfast_interp,
                  phin=0.,
                  thetan=np.pi / 2.,
                  debug=False):
    """Calculates value of the integrand for noise per component
     of a stochastic mag. field vector B (eq 51 of detectability notes).
     This is called by :func:`calc_SNR` that integrates it over k, theta, phi.

    :param x:
      Array of the following form: x = z, k_Mpc, thetak, phik
    :type x: ``array``

    :param t_yr:
      The total observation time in years.
      The time spent on a single field of view (=1sr for FFTT) is t_yr / Omega_survey. ???
    :type t_yr: ``float``

    :param DeltaL_km:
      The size of the FFTT coverage on a side in kilometers.
    :type DeltaL_km: ``float``

    :param Omega_survey:
      The survey area (on the sky) in steradians.
    :type Omega_survey: ``float``

    :params thetan,phin:
      These define direction of the LOS in the frame where 
      mag. field vector B is along the z axis. 
      Do not change these unless you know exactly what you're getting into.
    :type thetan,phin: ``float``

    :params val_*:
      Helper functions, like the calulators for various temperatures etc.
    :type val_*: ``function``


    """

    z = x[0]
    k_Mpc = x[1]
    thetak = x[2]
    phik = x[3]

    thetak_n = np.arccos(
        np.sin(thetak) * np.cos(phik) * np.sin(thetan) * np.cos(phin) +
        np.sin(thetak) * np.sin(phik) * np.sin(thetan) * np.sin(phin) +
        np.cos(thetak) * np.cos(thetan))
    sint = np.sin(thetak_n)
    if np.isclose(sint, 0.):
        if debug:
            return 0, 0, 0
        return 0.

    DeltaL_cm = DeltaL_km * 1e5  # cm
    lambda_z = lambda21 * (1. + z)  # cm
    dA = cf.val_dA(z)  # cm

    kmin = 2. * np.pi / (dA * sint / Mpc_in_cm)  # 1/Mpc comoving
    kmax = kmin * DeltaL_cm / lambda_z  # 1/Mpc comoving

    if k_Mpc > kmax or k_Mpc < kmin:
        if debug:
            return 0, 0, 0
        return 0.

    t_sec = 365. * 86400 * t_yr  # sec
    k_cm = k_Mpc / Mpc_in_cm  # cm
    N_ants = (DeltaL_cm / lambda_z)**2
    Ntot = N_ants * (N_ants + 1.) / 2.

    nk = val_nk(k_cm,
                Ntot=Ntot,
                lambda_z=lambda_z,
                dA=dA,
                sin_thetak_n=sint,
                Lmax=DeltaL_cm,
                Lmin=lambda_z,
                DeltaL=DeltaL_cm)

    t1 = t_sec
    if Omega_survey > 1.:
        t1 = t_sec / Omega_survey

    H_z = cf.H(z)
    Tsys = val_Tsys(z)
    Ts = val_Ts(z)
    Tg = val_Tg(z)
    Tk = val_Tk(z)
    Jlya = val_Jlya(z)
    Salpha = cf.val_Salpha(Ts, Tk, z, 1., 0)
    xalpha = rf.val_xalpha(Salpha=Salpha, Jlya=Jlya, Tg=Tg)
    xc = rf.val_xc(z, Tk=Tk, Tg=Tg)
    xBcoeff = ge * muB * Tstar / (2. * hbar * A * Tg)

    Pnoise = P21_N(dA=dA,
                   H_z=H_z,
                   z=z,
                   Tsys=Tsys,
                   t1=t1,
                   Ae=lambda_z**2,
                   Lmax=DeltaL_cm,
                   Lmin=lambda_z,
                   lambda_z=lambda_z,
                   nk=nk)
    if np.isnan(Pnoise):
        raise ValueError('Pnoise is nan.')

    Pdelta = cf.val_Pdelta(z, k_Mpc)

    G = pt.calc_G(thetak=thetak,
                  phik=phik,
                  thetan=thetan,
                  phin=phin,
                  Ts=Ts,
                  Tg=Tg,
                  z=z,
                  verbose=False,
                  xalpha=xalpha,
                  xc=xc,
                  xB=0.,
                  x1s=1.)

    dGdB = pt.calc_dGdB(thetak=thetak,
                        phik=phik,
                        thetan=thetan,
                        phin=phin,
                        Ts=Ts,
                        Tg=Tg,
                        z=z,
                        verbose=False,
                        xalpha=xalpha,
                        xc=xc,
                        xBcoeff=xBcoeff,
                        x1s=1.)

    Psignal = Pdelta * G**2
    Numerator = (2. * G * dGdB * (1. + z)**2 * Pdelta)**2
    Denominator = 2. * (2. * np.pi)**3 * (
        Psignal + Pnoise)**2  ###is 2pi factor right? check!

    res = k_Mpc**2 * np.sin(thetak) * Numerator / Denominator

    if debug:
        return res, Pnoise, nk, Numerator, G, dGdB
    return res
Example #6
0
def integrand(x,
              mode='B0',
              t_yr=1.,
              Omega_patch=1.,
              DeltaL_km=2.,
              val_nk=FFTT_nk,
              val_Ts=rf.Ts_21cmfast_interp,
              val_Tk=rf.Tk_21cmfast_interp,
              val_Jlya=rf.Jlya_21cmfast_interp,
              val_x1s=rf.ones_x1s,
              val_Tsys=Tsys_Mao2008,
              val_Tg=rf.Tg_21cmfast_interp,
              phin=0.,
              thetan=np.pi / 2.,
              print_klims=False,
              debug=False):
    """Calculates value of the integrand for sensitivity to uniform mag. field vector B (eqs 37,40 of detectability_notes).
     This is called by :func:`rand_integrator` that integrates it over z, k, theta, phi.

    :param x:
      Array of the following form: x = z, k_Mpc, thetak, phik
    :type x: ``array``

    :param t_yr:
      The total observation time in years.
      The time spent on a single field of view (=1sr for FFTT) is t_yr / Omega_survey. ???
    :type t_yr: ``float``

    :param mode:
      The mode of calculation; if mode == 'B0', returns sensitivity to measuring uniform mag. field B0
      if mode == 'xi', returns 1 sigma sensitivity to distinguishing saturated from unsaturated case, 
      where xi is unitless and between 0 and 1.
    :type mode: ``str``

    :param DeltaL_km:
      The size of the FFTT coverage on a side in kilometers.
    :type DeltaL_km: ``float``

    :param Omega_patch:
      The area of a small (approx. flat, < 1sr) patch the sky in steradians.
    :type Omega_patch: ``float``

    :params thetan,phin:
      These define direction of the LOS in the frame where 
      mag. field vector B is along the z axis. 
      Do not change these unless you know exactly what you're getting into.
    :type thetan,phin: ``float``

    :params val_*:
      Helper functions, like the calulators for various temperatures etc.
    :type val_*: ``function``

    """

    z = x[0]
    k_Mpc = x[1]
    thetak = x[2]
    phik = x[3]

    thetak_n = np.arccos(
        np.sin(thetak) * np.cos(phik) * np.sin(thetan) * np.cos(phin) +
        np.sin(thetak) * np.sin(phik) * np.sin(thetan) * np.sin(phin) +
        np.cos(thetak) * np.cos(thetan))
    sint = np.sin(thetak_n)
    if np.isclose(sint, 0.):
        if debug:
            return 0, 0, 0
        return 0.

    DeltaL_cm = DeltaL_km * 1e5  # cm
    lambda_z = lambda21 * (1. + z)  # cm
    dA = cf.val_dA(z)  # cm comov.

    kmin = 2. * np.pi / (dA * sint / Mpc_in_cm)  # 1/Mpc comoving
    kmax = kmin * DeltaL_cm / lambda_z  # 1/Mpc comoving

    if print_klims:
        print('kmax={}, kmin={}'.format(kmax, kmin))
    if k_Mpc > kmax or k_Mpc < kmin:
        if debug:
            return 0, 0, 0
        return 0.

    t_sec = 365. * 86400 * t_yr  # sec
    k_cm = k_Mpc / Mpc_in_cm  # cm
    N_ants = (DeltaL_cm / lambda_z)**2
    Ntot = N_ants * (N_ants + 1.) / 2.

    nk = val_nk(k_cm,
                Ntot=Ntot,
                lambda_z=lambda_z,
                dA=dA,
                sin_thetak_n=sint,
                Lmax=DeltaL_cm,
                Lmin=lambda_z,
                DeltaL=DeltaL_cm)

    t1 = t_sec
    if Omega_patch > 1.:
        t1 = t_sec / Omega_patch

    H_z = cf.H(z)
    Tsys = val_Tsys(z)
    Ts = val_Ts(z)
    Tg = val_Tg(z)
    Tk = val_Tk(z)
    Jlya = val_Jlya(z)
    Salpha = cf.val_Salpha(Ts, Tk, z, 1., 0)
    xalpha = rf.val_xalpha(Salpha=Salpha, Jlya=Jlya, Tg=Tg)
    xc = rf.val_xc(z, Tk=Tk, Tg=Tg)
    xBcoeff = ge * muB * Tstar / (2. * hbar * A * Tg)

    Vpatch = Vpatch_factor(z, dA=dA, H_z=H_z, Omega_patch=Omega_patch)
    Pnoise = P21_N(dA=dA,
                   H_z=H_z,
                   z=z,
                   Tsys=Tsys,
                   t1=t1,
                   Ae=lambda_z**2,
                   Lmax=DeltaL_cm,
                   Lmin=lambda_z,
                   lambda_z=lambda_z,
                   nk=nk)
    if np.isnan(Pnoise):
        raise ValueError('Pnoise is nan.')

    Pdelta = cf.val_Pdelta(z, k_Mpc)

    if mode == 'B0':
        G = pt.calc_G(thetak=thetak,
                      phik=phik,
                      thetan=thetan,
                      phin=phin,
                      Ts=Ts,
                      Tg=Tg,
                      z=z,
                      verbose=False,
                      xalpha=xalpha,
                      xc=xc,
                      xB=0.,
                      x1s=1.)

        dGdB = pt.calc_dGdB(thetak=thetak,
                            phik=phik,
                            thetan=thetan,
                            phin=phin,
                            Ts=Ts,
                            Tg=Tg,
                            z=z,
                            verbose=False,
                            xalpha=xalpha,
                            xc=xc,
                            xBcoeff=xBcoeff,
                            x1s=1.)

        Psignal = Pdelta * G**2
        Numerator = (2. * G * dGdB * (1 + z)**2 * Pdelta)**2
        Denominator = (Psignal + Pnoise)**2

        res = k_Mpc**2 * np.sin(thetak) * Vpatch * Numerator / Denominator / (
            2. * np.pi)**3

    if mode == 'xi':
        G_Bzero = pt.calc_G(thetak=thetak,
                            phik=phik,
                            thetan=thetan,
                            phin=phin,
                            Ts=Ts,
                            Tg=Tg,
                            z=z,
                            verbose=False,
                            xalpha=xalpha,
                            xc=xc,
                            x1s=1.,
                            xB=0.)
        G_Binfinity = pt.calc_G_Binfinity(thetak=thetak,
                                          phik=phik,
                                          thetan=thetan,
                                          phin=phin,
                                          Ts=Ts,
                                          Tg=Tg,
                                          z=z,
                                          verbose=False,
                                          xalpha=xalpha,
                                          xc=xc,
                                          x1s=1.)

        Psignal_Bzero = Pdelta * G_Bzero**2
        Psignal_Binfinity = Pdelta * G_Binfinity**2
        Numerator = (Psignal_Binfinity - Psignal_Bzero)**2
        Denominator = 2. * (Psignal_Bzero + Pnoise)**2

        res = k_Mpc**2 * np.sin(thetak) * Vpatch * Numerator / Denominator / (
            2. * np.pi)**3

    if mode == 'Bi':
        G = pt.calc_G(thetak=thetak,
                      phik=phik,
                      thetan=thetan,
                      phin=phin,
                      Ts=Ts,
                      Tg=Tg,
                      z=z,
                      verbose=False,
                      xalpha=xalpha,
                      xc=xc,
                      xB=0.,
                      x1s=1.)

        dGdB = pt.calc_dGdB(thetak=thetak,
                            phik=phik,
                            thetan=thetan,
                            phin=phin,
                            Ts=Ts,
                            Tg=Tg,
                            z=z,
                            verbose=False,
                            xalpha=xalpha,
                            xc=xc,
                            xBcoeff=xBcoeff,
                            x1s=1.)  #/ (1.+z)**2  #!!! VG: check

        Psignal = Pdelta * G**2
        Numerator = (2. * G * dGdB * (1 + z)**2 * Pdelta)**2
        Denominator = 2. * (Psignal + Pnoise)**2

        res = k_Mpc**2 * np.sin(thetak) * Numerator / Denominator

    if debug:
        dGdB, summ, xs = pt.calc_dGdB(thetak=thetak,
                                      phik=phik,
                                      thetan=thetan,
                                      phin=phin,
                                      Ts=Ts,
                                      Tg=Tg,
                                      z=z,
                                      verbose=False,
                                      xalpha=xalpha,
                                      xc=xc,
                                      xBcoeff=xBcoeff,
                                      x1s=1.,
                                      debug=True)
        return res, Numerator, Denominator, Psignal, Pnoise, G, dGdB, Pdelta, Ts, Tg, summ, xs
    return res