예제 #1
0
def findzfromDL(z, DL):
    return DL - de.luminosity_distance_de(z, **cosmo)
예제 #2
0
def horizon_dist_eval(orig_dist, snr, z0):
    guess_dist = orig_dist * snr / snr_th
    guess_redshift, res = leastsq(findzfromDL, z0, args=guess_dist)
    #return guess_redshift[0],guess_dist
    return guess_redshift[0], de.luminosity_distance_de(
        guess_redshift[0], **cosmo)
예제 #3
0
def find_horizon_range(m1, m2, network, asdfile, pwfile, approx=ls.IMRPhenomD):

    fmin = 10.
    fref = 10.
    df = 1.0

    ra, dec, psi, iota = genfromtxt('../data/horizon_coord_' + pwfile + '.txt',
                                    unpack=True)

    psdinterp_dict = {}
    minimum_freq = zeros(size(network))
    maximum_freq = zeros(size(network))
    for detector in range(0, size(network)):
        input_freq, strain = loadtxt(asdfile[detector],
                                     unpack=True,
                                     usecols=[0, 1])
        minimum_freq[detector] = maximum(min(input_freq), fmin)
        maximum_freq[detector] = minimum(max(input_freq), 5000.)
        psdinterp_dict[network[detector]] = interp1d(input_freq, strain**2)
    #initial guess of horizon redshift and luminosity distance
    z0 = 1.0
    input_dist = de.luminosity_distance_de(z0, **cosmo)
    hplus_tilda, hcross_tilda, freqs = get_htildas((1. + z0) * m1,
                                                   (1. + z0) * m2,
                                                   input_dist,
                                                   iota=iota,
                                                   fmin=fmin,
                                                   fref=fref,
                                                   df=df,
                                                   approx=approx)

    fsel = list()
    psd_interp = list()
    for detector in range(0, size(network)):
        fsel.append(
            logical_and(freqs > minimum_freq[detector],
                        freqs < maximum_freq[detector]))
        psd_interp.append(psdinterp_dict[network[detector]](
            freqs[fsel[detector]]))
    input_snr = compute_horizonSNR(hplus_tilda, hcross_tilda, network, ra, dec,
                                   psi, psd_interp, fsel, df)

    input_redshift = z0
    guess_snr = 0
    njump = 0
    #evaluate the horizon recursively
    while abs(
            guess_snr - snr_th
    ) > snr_th * 0.001 and njump < 10:  #require the error within 0.1%
        try:
            guess_redshift, guess_dist = horizon_dist_eval(
                input_dist, input_snr,
                input_redshift)  #horizon guess based on the old SNR
            hplus_tilda, hcross_tilda, freqs = get_htildas(
                (1. + guess_redshift) * m1, (1. + guess_redshift) * m2,
                guess_dist,
                iota=iota,
                fmin=fmin,
                fref=fref,
                df=df,
                approx=approx)
        except:
            njump = 10
            print("Will try interpolation.")
        fsel = list()
        psd_interp = list()
        for detector in range(0, size(network)):
            fsel.append(
                logical_and(freqs > minimum_freq[detector],
                            freqs < maximum_freq[detector]))
            psd_interp.append(psdinterp_dict[network[detector]](
                freqs[fsel[detector]]))
        guess_snr = compute_horizonSNR(hplus_tilda, hcross_tilda, network, ra,
                                       dec, psi, psd_interp, fsel,
                                       df)  #calculate the new SNR

        input_snr = guess_snr
        input_redshift = guess_redshift
        input_dist = guess_dist
        njump += 1
    horizon_redshift = guess_redshift

    #at high redshift the recursive jumps lead to too big a jump for each step, and the recursive loop converge slowly.
    #so I interpolate the z-SNR curve directly.
    if njump >= 10:
        print(
            "Recursive search for the horizon failed. Interpolation instead.")
        try:
            interp_z = linspace(0.001, 100, 200)
            interp_snr = zeros(size(interp_z))
            for i in range(0, size(interp_z)):
                hplus_tilda, hcross_tilda, freqs = get_htildas(
                    (1. + interp_z[i]) * m1, (1. + interp_z[i]) * m2,
                    de.luminosity_distance_de(interp_z[i], **cosmo),
                    iota=iota,
                    fmin=fmin,
                    fref=fref,
                    df=df,
                    approx=approx)
                fsel = list()
                psd_interp = list()
                for detector in range(0, size(network)):
                    fsel.append(
                        logical_and(freqs > minimum_freq[detector],
                                    freqs < maximum_freq[detector]))
                    psd_interp.append(psdinterp_dict[network[detector]](
                        freqs[fsel[detector]]))
                interp_snr[i] = compute_horizonSNR(hplus_tilda, hcross_tilda,
                                                   network, ra, dec, psi,
                                                   psd_interp, fsel, df)
            interpolate_snr = interp1d(interp_snr[::-1], interp_z[::-1])
            horizon_redshift = interpolate_snr(snr_th)
        except RuntimeError:  #If the sources lie outside the given interpolating redshift the sources can not be observe, so I cut down the interpolation range.
            print(
                "some of the SNR at the interpolated redshifts cannot be calculated."
            )
            interpolate_snr = interp1d(interp_snr[::-1], interp_z[::-1])
            horizon_redshift = interpolate_snr(snr_th)
        except ValueError:  #horizon outside the interpolated redshifts. Can potentially modify the interpolation range, but we basically can not observe the type of source or the source has to be catastrophically close.
            print(
                "Horizon further than z=100 or less than z=0.001. Need to modify the interpolated redshift range."
            )
            return

    #sampled universal antenna power pattern for code sped up
    w_sample, P_sample = genfromtxt('pw_' + pwfile + '.txt', unpack=True)
    P = interp1d(w_sample, P_sample, bounds_error=False, fill_value=0.0)
    n_zstep = 400
    print("horizon_redshift", horizon_redshift)
    z, dz = linspace(horizon_redshift,
                     0,
                     n_zstep,
                     endpoint=False,
                     retstep=True)
    dz = abs(dz)
    unit_volume = zeros(size(z))
    compensate_detect_frac = zeros(size(z))
    for i in range(0, size(z)):
        hplus_tilda, hcross_tilda, freqs = get_htildas(
            (1. + z[i]) * m1, (1. + z[i]) * m2,
            de.luminosity_distance_de(z[i], **cosmo),
            iota=iota,
            fmin=fmin,
            fref=fref,
            df=df,
            approx=approx)
        fsel = list()
        psd_interp = list()
        for detector in range(0, size(network)):
            fsel.append(
                logical_and(freqs > minimum_freq[detector],
                            freqs < maximum_freq[detector]))
            psd_interp.append(psdinterp_dict[network[detector]](
                freqs[fsel[detector]]))
        optsnr_z = compute_horizonSNR(hplus_tilda, hcross_tilda, network, ra,
                                      dec, psi, psd_interp, fsel, df)
        w = snr_th / optsnr_z
        compensate_detect_frac[i] = P(w)
        unit_volume[i] = (de.comoving_volume_de(z[i] + dz / 2., **cosmo) -
                          de.comoving_volume_de(z[i] - dz / 2., **cosmo)) / (
                              1. + z[i]) * P(w)

    #Find out the redshift at which we detect 50%/90% of the sources at the redshift
    z_response50 = max(z[where(compensate_detect_frac >= 0.5)])
    z_response90 = max(z[where(compensate_detect_frac >= 0.1)])

    vol_sum = sum(unit_volume)
    #Find out the redshifts that 50%/90% of the sources lie within assuming constant-comoving-rate density
    z50 = max(z[where(cumsum(unit_volume) >= 0.5 * vol_sum)])
    z90 = max(z[where(cumsum(unit_volume) >= 0.1 * vol_sum)])

    #Find out the redshifts that 50%/90% of the sources lie within assuming star formation rate
    sfr_vol_sum = sum(unit_volume * sfr(z) / sfr(0))
    sfr_z50 = max(
        z[where(cumsum(unit_volume * sfr(z) / sfr(0)) >= 0.5 * sfr_vol_sum)])
    sfr_z90 = max(
        z[where(cumsum(unit_volume * sfr(z) / sfr(0)) >= 0.1 * sfr_vol_sum)])

    #average redshift
    z_mean = sum(unit_volume * z) / vol_sum
    sfr_z_mean = sum(unit_volume * sfr(z) / sfr(0) * z) / sfr_vol_sum

    return (3. * vol_sum / 4. / pi)**(
        1. / 3.
    ), z_response50, z_response90, horizon_redshift, vol_sum / 1E9, z50, z90, sfr_z50, sfr_z90, z_mean, sfr_z_mean