예제 #1
0
def quick_analytic_cov(l, Clth_dict, window, binning_file, lmax):

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    nbins = len(bin_size)
    fsky = steve_effective_fsky(window)
    prefac = 1 / ((2 * bin_c + 1) * fsky * bin_size)

    cov = {}
    cov["TT"] = Clth_dict["TaTc"] * Clth_dict["TbTd"] + Clth_dict[
        "TaTd"] * Clth_dict["TbTc"]
    cov["TE"] = Clth_dict["TaTc"] * Clth_dict["EbEd"] + Clth_dict[
        "TaEd"] * Clth_dict["EbTc"]
    cov["ET"] = Clth_dict["EaEc"] * Clth_dict["TbTd"] + Clth_dict[
        "EaTd"] * Clth_dict["TbEc"]
    cov["EE"] = Clth_dict["EaEc"] * Clth_dict["EbEd"] + Clth_dict[
        "EaEd"] * Clth_dict["EbEc"]

    mat_diag = np.zeros((4 * nbins, 4 * nbins))

    for count, spec in enumerate(["TT", "TE", "ET", "EE"]):
        lb, cov[spec] = pspy_utils.naive_binning(l, cov[spec], binning_file,
                                                 lmax)
        cov[spec] *= prefac
        for i in range(nbins):
            mat_diag[i + count * nbins, i + count * nbins] = cov[spec][i]

    return fsky, mat_diag
예제 #2
0
def process_planck_spectra(l,
                           cl,
                           binning_file,
                           lmax,
                           type,
                           spectra=None,
                           mcm_inv=None):
    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    n_bins = len(bin_hi)
    fac = (l * (l + 1) / (2 * np.pi))
    unbin_vec = []
    mcm_inv = so_mcm.coupling_dict_to_array(mcm_inv)
    for f in spectra:
        unbin_vec = np.append(unbin_vec, cl[f][2:lmax])
    cl = so_spectra.vec2spec_dict(lmax - 2, np.dot(mcm_inv, unbin_vec),
                                  spectra)
    l = np.arange(2, lmax)
    print(l.shape, cl['TT'].shape)
    vec = []
    for f in spectra:
        binnedPower = np.zeros(len(bin_c))
        for ibin in range(n_bins):
            loc = np.where((l >= bin_lo[ibin]) & (l <= bin_hi[ibin]))
            binnedPower[ibin] = (cl[f][loc] *
                                 fac[loc]).mean() / (fac[loc].mean())
        vec = np.append(vec, binnedPower)
    return l, cl, bin_c, so_spectra.vec2spec_dict(n_bins, vec, spectra)
예제 #3
0
def binning(l, cl, lmax, binning_file=None, size=None):
    
    if binning_file is not None:
        bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(binning_file, lmax)
    else:
        bin_lo = np.arange(2, lmax, size)
        bin_hi = bin_lo + size - 1
        bin_c = (bin_lo + bin_hi) / 2
    
    fac = (l * (l + 1) / (2 * np.pi))
    n_bins = len(bin_hi)
    binnedPower = np.zeros(len(bin_c))
    for ibin in range(n_bins):
        loc = np.where((l >= bin_lo[ibin]) & (l <= bin_hi[ibin]))
        binnedPower[ibin] = (cl[loc]*fac[loc]).mean()/(fac[loc].mean())
    return bin_c, binnedPower
예제 #4
0
            split.data *= cal
            if d["remove_mean"] == True:
                split = data_analysis_utils.remove_mean(split, window_tuple, ncomp)
                
            #split.plot(file_name="%s/split_%d_%s_%s" % (plot_dir, k, sv, ar), color_range=[250, 100, 100])

            master_alms[sv, ar, k] = sph_tools.get_alms(split, window_tuple, niter, lmax)
            if d["use_kspace_filter"]:
                # there is an extra normalisation for the FFT/IFFT bit
                # note that we apply it here rather than at the FFT level because correcting the alm is faster than correcting the maps
                master_alms[sv, ar, k] /= (split.data.shape[1]*split.data.shape[2])
                
        print(time.time()- t)

ps_dict = {}
_, _, lb, _ = pspy_utils.read_binning_file(binning_file, lmax)

for id_sv1, sv1 in enumerate(surveys):
    arrays_1 = d["arrays_%s" % sv1]
    nsplits_1 = nsplit[sv1]
    
    if d["tf_%s" % sv1] is not None:
        print("will deconvolve tf of %s" %sv1)
        _, _, tf1, _ = np.loadtxt(d["tf_%s" % sv1], unpack=True)
    else:
        tf1 = np.ones(len(lb))

    for id_ar1, ar1 in enumerate(arrays_1):
    
        for id_sv2, sv2 in enumerate(surveys):
            arrays_2 = d["arrays_%s" % sv2]
예제 #5
0
        for j in range(nbins):
            if np.abs(lb[i]-lb[j]) < delta_l:
                cut_mat[i,j] = mat[i,j]
    return cut_mat

d = so_dict.so_dict()
d.read_from_file(sys.argv[1])

cov_dir = "covariances"
mc_dir = "montecarlo"
exp = "Planck"
lmax = d["lmax"]
binning_file = d["binning_file"]
freqs = d["freqs"]

bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(binning_file, lmax)
nbins = len(bin_hi)

spec_name = []

for c1,freq1 in enumerate(freqs):
    for c2,freq2 in enumerate(freqs):
        if c1>c2: continue
        spec_name += ["%s_%sx%s_%s" % (exp, freq1, exp, freq2)]

# pspy produced TT-TE-ET-EE block covariance matrix, in this step of the code we read them and plug them in
# a multifrequency covariance matrix of size  4 (TT-TE-ET-EE) * nbins * nspec (100x100, 100x143, ..., 217x217)
# we also create a projection matrix that will be used for combining TE and ET in the futur

analytic_dict= {}
spectra = ["TT", "TE", "ET", "EE"]
예제 #6
0
def covariance_element(coupling, id_element, ns, ps_all, nl_all, binning_file, mbb_inv_ab, mbb_inv_cd):
    
    na, nb, nc, nd = id_element
    
    lmax = coupling["TaTcTbTd"].shape[0]
    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(binning_file, lmax)
    nbins = len(bin_hi)
    analytic_cov = np.zeros((4*nbins, 4*nbins))

    # TaTbTcTd
    M_00 = coupling["TaTcTbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TTTT")
    M_00 += coupling["TaTdTbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TTTT")
    analytic_cov[0*nbins:1*nbins, 0*nbins:1*nbins] = so_cov.bin_mat(M_00, binning_file, lmax)

    # TaEbTcEd
    M_11 = coupling["TaTcPbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TTEE")
    M_11 += coupling["TaPdPbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TEET")
    analytic_cov[1*nbins:2*nbins, 1*nbins:2*nbins] = so_cov.bin_mat(M_11, binning_file, lmax)

    # EaTbEcTd
    M_22 = coupling["PaPcTbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "EETT")
    M_22 += coupling["PaTdTbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "ETTE")
    analytic_cov[2*nbins:3*nbins, 2*nbins:3*nbins] = so_cov.bin_mat(M_22, binning_file, lmax)

    # EaEbEcEd
    M_33 = coupling["PaPcPbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "EEEE")
    M_33 += coupling["PaPdPbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "EEEE")
    analytic_cov[3*nbins:4*nbins, 3*nbins:4*nbins] = so_cov.bin_mat(M_33, binning_file, lmax)

    # TaTbTcEd
    M_01 = coupling["TaTcTbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TTTE")
    M_01 += coupling["TaPdTbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TETT")
    analytic_cov[0*nbins:1*nbins, 1*nbins:2*nbins] = so_cov.bin_mat(M_01, binning_file, lmax)

    # TaTbEcTd
    M_02 = coupling["TaPcTbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TETT")
    M_02 += coupling["TaTdTbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TTTE")
    analytic_cov[0*nbins:1*nbins, 2*nbins:3*nbins] = so_cov.bin_mat(M_02, binning_file, lmax)

    # TaTbEcEd
    M_03 = coupling["TaPcTbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TETE")
    M_03 += coupling["TaPdTbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TETE")
    analytic_cov[0*nbins:1*nbins, 3*nbins:4*nbins] = so_cov.bin_mat(M_03, binning_file, lmax)

    # TaEbEcTd
    M_12 = coupling["TaPcPbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TEET")
    M_12 += coupling["TaTdPbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TTEE")
    analytic_cov[1*nbins:2*nbins, 2*nbins:3*nbins] = so_cov.bin_mat(M_12, binning_file, lmax)

    # TaEbEcEd
    M_13 = coupling["TaPcPbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TEEE")
    M_13 += coupling["TaPdPbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TEEE")
    analytic_cov[1*nbins:2*nbins, 3*nbins:4*nbins] = so_cov.bin_mat(M_13, binning_file, lmax)

    # EaTbEcEd
    M_23 = coupling["PaPcTbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "EETE")
    M_23 += coupling["PaPdTbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "EETE")
    analytic_cov[2*nbins:3*nbins, 3*nbins:4*nbins] = so_cov.bin_mat(M_23, binning_file, lmax)

    # TaEbTcTd
    M_10 = coupling["TaTcPbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "TTET")
    M_10 += coupling["TaTdPbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "TTET")
    analytic_cov[1*nbins:2*nbins, 0*nbins:1*nbins] = so_cov.bin_mat(M_10, binning_file, lmax)

    # EaTbTcTd
    M_20 = coupling["PaTcTbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "ETTT")
    M_20 += coupling["PaTdTbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "ETTT")
    analytic_cov[2*nbins:3*nbins, 0*nbins:1*nbins] = so_cov.bin_mat(M_20, binning_file, lmax)

    # EaEbTcTd
    M_30 = coupling["PaTcPbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "ETET")
    M_30 += coupling["PaTdPbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "ETET")
    analytic_cov[3*nbins:4*nbins, 0*nbins:1*nbins] = so_cov.bin_mat(M_30, binning_file, lmax)

    # EaTbTcEd
    M_21 = coupling["PaTcTbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "ETTE")
    M_21 += coupling["PaPdTbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "EETT")
    analytic_cov[2*nbins:3*nbins, 1*nbins:2*nbins] = so_cov.bin_mat(M_21, binning_file, lmax)

    # EaEbTcEd
    M_31 = coupling["PaTcPbPd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "ETEE")
    M_31 += coupling["PaPdPbTc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "EEET")
    analytic_cov[3*nbins:4*nbins, 1*nbins:2*nbins] = so_cov.bin_mat(M_31, binning_file, lmax)

    # EaEbEcTd
    M_32 = coupling["PaPcPbTd"] * chi(na, nc, nb, nd, ns, ps_all, nl_all, "EEET")
    M_32 += coupling["PaTdPbPc"] * chi(na, nd, nb, nc, ns, ps_all, nl_all, "ETEE")
    analytic_cov[3*nbins:4*nbins, 2*nbins:3*nbins] = so_cov.bin_mat(M_32, binning_file, lmax)

    mbb_inv_ab = so_cov.extract_TTTEEE_mbb(mbb_inv_ab)
    mbb_inv_cd = so_cov.extract_TTTEEE_mbb(mbb_inv_cd)

    analytic_cov = np.dot(np.dot(mbb_inv_ab, analytic_cov), mbb_inv_cd.T)
    
    return analytic_cov
예제 #7
0
def get_covariance(window,
                   lmax,
                   spec_name_list,
                   ps_dict,
                   binning_file,
                   error_method="master",
                   spectra=None,
                   l_thres=None,
                   l_toep=None,
                   mbb_inv=None,
                   compute_T_only=False):
    """Compute the covariance matrix of the power spectrum in the patch

    Parameters
    ----------

    window: so_map
      the window function of the patch
    lmax: integer
      the maximum multipole to consider for the spectra computation
    spec_name_list:  list
      the list of  power spectra
      For example : [split0xsplit0,split0xsplit1,split1xsplit1]
      note that for computing the error on PS(split0xsplit1) we need PS(split0xsplit0), PS(split0xsplit1), PS(split1xsplit1)
    ps_dict: dict
      a dict containing all power spectra
    binning_file: text file
      a binning file with three columns bin low, bin high, bin mean
      note that either binning_file or bin_size should be provided
    error_method: string
      the method for the computation of error
      can be "master" or "knox" for now
   approx_coupling: dict
   mbb_inv: 2d array
     the inverse mode coupling matrix, not in use for 2dflat
   compute_T_only: boolean
     True to compute only T spectra

    """

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    n_bins = len(bin_hi)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4. / np.pi
    fsky *= np.mean(window.data)

    cov_dict = {}

    if error_method == "Knox":
        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                prefac = 1 / ((2 * bin_c + 1) * fsky * bin_size)
                cov_dict[name][X + Y] = np.diag(
                    prefac *
                    (ps_dict["%sx%s" %
                             (m1, m1)][X + X] * ps_dict["%sx%s" %
                                                        (m2, m2)][Y + Y] +
                     ps_dict["%sx%s" % (m1, m2)][X + Y]**2))

    elif error_method == "master":
        print("compute master error")
        if mbb_inv is None:
            raise ValueError("Missing 'mbb_inv' argument")
        if not compute_T_only:
            mbb_inv = mbb_inv["spin0xspin0"]
        coupling_dict = so_cov.cov_coupling_spin0(window,
                                                  lmax,
                                                  niter=0,
                                                  l_thres=l_thres,
                                                  l_toep=l_toep)
        coupling = so_cov.bin_mat(coupling_dict["TaTcTbTd"], binning_file,
                                  lmax)

        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                cov_dict[name][X + Y] = so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m1)][X + X]) * so_cov.symmetrize(
                        ps_dict["%sx%s" % (m2, m2)][Y + Y])
                cov_dict[name][X + Y] += so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m2)][X + Y]**2)
                cov_dict[name][X + Y] *= coupling
                cov_dict[name][X + Y] = np.dot(
                    np.dot(mbb_inv, cov_dict[name][X + Y]), mbb_inv.T)

    else:
        cov_dict = None

    return cov_dict
예제 #8
0
def compute_mode_coupling(window,
                          type,
                          lmax,
                          binning_file,
                          ps_method="master",
                          beam=None,
                          lmax_pad=None,
                          l_thres=None,
                          l_toep=None,
                          compute_T_only=False):
    """Compute the mode coupling corresponding the the window function

    Parameters
    ----------

    window: so_map
        the window function of the patch
    type: string
        the type of binning, either bin Cl or bin Dl
    lmax : integer
        the maximum multipole to consider for the spectra computation
    binning_file: text file
      a binning file with three columns bin low, bin high, bin mean
      note that either binning_file or bin_size should be provided
    ps_method: string
        the method for the computation of the power spectrum
        can be "master", "pseudo", or "2dflat" for now
    beam: text file
        file describing the beam of the map, expect bl to be the second column and start at l=0 (standard is : l,bl, ...)
    lmax_pad: integer
        the maximum multipole to consider for the mcm computation (optional)
        lmax_pad should always be greater than lmax
    compute_T_only: boolean
        True to compute only T spectra
    """

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    n_bins = len(bin_hi)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4. / np.pi
    fsky *= np.mean(window.data)

    if beam is not None:
        beam_data = np.loadtxt(beam)
        if compute_T_only:
            beam = beam_data[:, 1]
        else:
            beam = (beam_data[:, 1], beam_data[:, 1])

    if compute_T_only:
        if ps_method == "master":
            mbb_inv, Bbl = so_mcm.mcm_and_bbl_spin0(window,
                                                    binning_file,
                                                    bl1=beam,
                                                    lmax=lmax,
                                                    type=type,
                                                    niter=0,
                                                    lmax_pad=lmax_pad,
                                                    l_thres=l_thres,
                                                    l_toep=l_toep)

        elif ps_method == "pseudo":
            mbb_inv = np.identity(n_bins)
            mbb_inv *= 1 / fsky
    else:
        window = (window, window)
        if ps_method == "master":
            print("compute master MCM")
            mbb_inv, Bbl = so_mcm.mcm_and_bbl_spin0and2(window,
                                                        binning_file,
                                                        bl1=beam,
                                                        lmax=lmax,
                                                        type=type,
                                                        niter=0,
                                                        lmax_pad=lmax_pad,
                                                        l_thres=l_thres,
                                                        l_toep=l_toep)

        elif ps_method == "pseudo":
            mbb_inv = {}
            spin_list = ["spin0xspin0", "spin0xspin2", "spin2xspin0"]
            for spin in spin_list:
                mbb_inv[spin] = np.identity(n_bins)
                mbb_inv[spin] *= 1 / fsky
            mbb_inv["spin2xspin2"] = np.identity(4 * n_bins)
            mbb_inv["spin2xspin2"] *= 1 / fsky

    if ps_method == "2dflat":
        mbb_inv = None

    return mbb_inv
예제 #9
0
run_name = d["run_name"]

spectra_dir = "spectra_%s" % run_name
plot_dir = "plot_%s" % run_name

pspy_utils.create_directory(spectra_dir)
pspy_utils.create_directory(plot_dir)

lmax = d["lmax"]
type = d["type"]
clfile = d["clfile"]
l_exact_array = d["l_exact_array"]
l_band_array = d["l_band_array"]
l_toep_array = d["l_toep_array"]
compute_T_only = d["compute_T_only"]
l_lo, l_hi, lb, delta_l = pspy_utils.read_binning_file("data/binning.dat",
                                                       lmax)

id_sim = d["id_sim"]
result_ps = {}
result_cov = {}

test_names = []
for l_exact, l_band, l_toep in zip(l_exact_array, l_band_array, l_toep_array):

    if (l_exact == None) & (l_toep == None) & (l_band == None):
        test = "exact"
    else:
        test = "%d_%d_%d" % (l_exact, l_band, l_toep)

    print(test)
    t = time.time()
예제 #10
0
def covariance_element(coupling, id_element, ns, ps_all, nl_all, binning_file,
                       mbb_inv_ab, mbb_inv_cd):
    """
    This routine deserves some explanation
    We want to compute the covariance between two power spectra
    C1 = Wa * Xb, C2 =  Yc * Zd
    Here W, X, Y, Z can be either T or E and a,b,c,d will be an index
    corresponding to the survey and array we consider so for example a = s17_pa5_150 or a = dr6_pa4_090
    The formula for the analytic covariance of C1, C2 is given by
    Cov( Wa * Xb,  Yc * Zd) = < Wa Yc> <Xb Zd>  + < Wa Zd> <Xb Yc> (this is just from the wick theorem)
    In practice we need to include the effect of the mask (so we have to introduce the coupling dict D)
    and we need to take into account that we use only the cross power spectra, that is why we use the chi function
    Cov( Wa * Xb,  Yc * Zd) = D(Wa*Yc,Xb Zd) chi(Wa,Yc,Xb Zd) +  D(Wa*Zd,Xb*Yc) chi(Wa,Zd,Xb,Yc)
    
    Parameters
    ----------
    coupling : dictionnary
      a dictionnary that countains the coupling terms arising from the window functions
    id_element : list
      a list of the form [a,b,c,d] where a = dr6_pa4_090, etc, this identify which pair of power spectrum we want the covariance of
    ns: dict
      this dictionnary contains the number of split we consider for each of the survey
    ps_all: dict
      this dict contains the theoretical best power spectra, convolve with the beam for example
      ps["dr6&pa5_150", "dr6&pa4_150", "TT"] = bl_dr6_pa5_150 * bl_dr6_pa4_150 * (Dl^{CMB}_TT + fg_TT)
    nl_all: dict
      this dict contains the estimated noise power spectra, note that it correspond to the noise power spectrum per split
      e.g nl["dr6&pa5_150", "dr6&pa4_150", "TT"]
    binning_file:
      a binning file with three columns bin low, bin high, bin mean
    mbb_inv_ab and mbb_inv_cd:
      the inverse mode coupling matrices corresponding to the C1 = Wa * Xb and C2 =  Yc * Zd power spectra
    """

    na, nb, nc, nd = id_element

    lmax = coupling["TaTcTbTd"].shape[0]
    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)
    nbins = len(bin_hi)

    speclist = ["TT", "TE", "ET", "EE"]
    nspec = len(speclist)
    analytic_cov = np.zeros((nspec * nbins, nspec * nbins))
    for i, (W, X) in enumerate(speclist):
        for j, (Y, Z) in enumerate(speclist):

            id0 = W + "a" + Y + "c"
            id1 = X + "b" + Z + "d"
            id2 = W + "a" + Z + "d"
            id3 = X + "b" + Y + "c"

            M = coupling[id0.replace("E", "P") + id1.replace("E", "P")] * chi(
                na, nc, nb, nd, ns, ps_all, nl_all, W + Y + X + Z)
            M += coupling[id2.replace("E", "P") + id3.replace("E", "P")] * chi(
                na, nd, nb, nc, ns, ps_all, nl_all, W + Z + X + Y)
            analytic_cov[i * nbins:(i + 1) * nbins,
                         j * nbins:(j + 1) * nbins] = so_cov.bin_mat(
                             M, binning_file, lmax)

    mbb_inv_ab = so_cov.extract_TTTEEE_mbb(mbb_inv_ab)
    mbb_inv_cd = so_cov.extract_TTTEEE_mbb(mbb_inv_cd)

    analytic_cov = np.dot(np.dot(mbb_inv_ab, analytic_cov), mbb_inv_cd.T)

    return analytic_cov
예제 #11
0
파일: pstools.py 프로젝트: simonsobs/psplay
def get_covariance(
    window,
    lmax,
    spec_name_list,
    ps_dict,
    binning_file,
    error_method="master",
    spectra=None,
    l_exact=None,
    l_band=None,
    l_toep=None,
    mbb_inv=None,
    compute_T_only=False,
    transfer_function=None,
):
    """Compute the covariance matrix of the power spectrum in the patch

     Parameters
     ----------

     window: so_map
       the window function of the patch
     lmax: integer
       the maximum multipole to consider for the spectra computation
     spec_name_list:  list
       the list of  power spectra
       For example : [split0xsplit0,split0xsplit1,split1xsplit1]
       note that for computing the error on PS(split0xsplit1) we need PS(split0xsplit0), PS(split0xsplit1), PS(split1xsplit1)
     ps_dict: dict
       a dict containing all power spectra
     binning_file: text file
       a binning file with three columns bin low, bin high, bin mean
       note that either binning_file or bin_size should be provided
     error_method: string
       the method for the computation of error
       can be "master" or "knox" for now
    approx_coupling: dict
    mbb_inv: 2d array
      the inverse mode coupling matrix, not in use for 2dflat
    compute_T_only: boolean
      True to compute only T spectra
    transfer_function: str
      the path to the transfer function
    """
    timer.start("Compute {} error...".format(error_method))

    bin_lo, bin_hi, bin_c, bin_size = pspy_utils.read_binning_file(
        binning_file, lmax)

    fsky = enmap.area(window.data.shape, window.data.wcs) / 4.0 / np.pi
    fsky *= np.mean(window.data)

    cov_dict = {}

    if error_method == "knox":
        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                prefac = 1 / ((2 * bin_c + 1) * fsky * bin_size)
                # fmt: off
                cov_dict[name][X + Y] = np.diag(
                    prefac *
                    (ps_dict["%sx%s" %
                             (m1, m1)][X + X] * ps_dict["%sx%s" %
                                                        (m2, m2)][Y + Y] +
                     ps_dict["%sx%s" % (m1, m2)][X + Y]**2))
                # fmt: on

    elif error_method == "master":

        if not compute_T_only:
            mbb_inv = mbb_inv["spin0xspin0"]

        coupling_dict = so_cov.cov_coupling_spin0(window,
                                                  lmax,
                                                  niter=0,
                                                  l_band=l_band,
                                                  l_toep=l_toep,
                                                  l_exact=l_exact)
        coupling = so_cov.bin_mat(coupling_dict["TaTcTbTd"], binning_file,
                                  lmax)

        for name in spec_name_list:
            m1, m2 = name.split("x")
            cov_dict[name] = {}
            for spec in spectra:
                X, Y = spec
                cov_dict[name][X + Y] = so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m1)][X + X]) * so_cov.symmetrize(
                        ps_dict["%sx%s" % (m2, m2)][Y + Y])
                cov_dict[name][X + Y] += so_cov.symmetrize(
                    ps_dict["%sx%s" % (m1, m2)][X + Y]**2)
                cov_dict[name][X + Y] *= coupling
                cov_dict[name][X + Y] = np.dot(
                    np.dot(mbb_inv, cov_dict[name][X + Y]), mbb_inv.T)
                if transfer_function is not None:
                    _, _, tf, _ = np.loadtxt(transfer_function, unpack=True)
                    tf = tf[:len(bin_c)]
                    cov_dict[name][X + Y] /= np.outer(np.sqrt(tf), np.sqrt(tf))

    else:
        cov_dict = None

    timer.stop()
    return cov_dict