def compute_Cls(par,hod_par=hod_params,z_cent=z_s_cents,N_gal_sample=N_gal_bin,k_arr=k_ar,z_arr=z_ar,a_arr=a_ar,ell=ells, compute_cov=False, compute_inv_cov=False,plot_for_sanity=False,powerspec='halofit',simple_bias=True): if powerspec == 'halofit': # Compute matter pk using halofit pk_mm_arr = np.array([ccl.nonlin_matter_power(cosmo_fid, k_arr, a) for a in a_arr]) elif powerspec == 'halomodel': # Alternatively use halo model pk_mm_arr = np.array([ccl.halomodel.halomodel_matter_power(cosmo_fid, k_arr, a) for a in a_arr]) if simple_bias == True: pk_gg_arr = pk_mm_arr.copy() # because we later include bias pk_gm_arr = pk_mm_arr.copy() # because we later include bias else: # Compute HOD hodpars = hod_funcs_evol_fit.HODParams(hod_par, islogm0=True, islogm1=True) hodprof = hod.HODProfile(cosmo_fid, hodpars.lmminf, hodpars.sigmf,\ hodpars.fcf, hodpars.m0f, hodpars.m1f, hodpars.alphaf) # Compute galaxy pk using halofit pk_gg_arr = np.array([hodprof.pk(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Compute galaxy-matter pk using halofit pk_gm_arr = np.array([hodprof.pk_gm(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Create pk2D objects for interpolation pk_mm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_mm_arr), is_logp=True) pk_gg = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gg_arr), is_logp=True) pk_gm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gm_arr), is_logp=True) # load the bias parameters # k # indicates which of N_tomo sampling bins b_z = np.array([par['b_%02d'%k]['val'] for k in range(N_zsamples)]) # load the dndz parameters dndz_z = np.zeros((N_tomo,N_zsamples)) for i_z in range(N_tomo): dndz_z[i_z,:] = np.array([par['dndz_%02d_%02d'%(i_z,k)]['val'] for k in range(N_zsamples)]) # per type gg gs ss tot_corr = N_ell*(N_tomo*(2*N_tomo+1)) # make Cl_all of size N_ell*N_tomo*(2N_tomo+1) CL_ALL = np.zeros(tot_corr) temp = np.arange(2*N_tomo) temp = np.vstack((temp,temp)).T combs = np.array(list(combinations(range(2*N_tomo),2))) all_combos = np.vstack((temp,combs)) for c, comb in enumerate(all_combos): i = comb[0]%N_tomo # first redshift bin j = comb[1]%N_tomo # second redshift bin t_i = comb[0]//N_tomo # tracer type 0 means g and 1 means s t_j = comb[1]//N_tomo # tracer type 0 means g and 1 means s # NOISE if (i == j): # number density of galaxies N_gal = N_gal_sample[i] n_gal = N_gal/area_COSMOS # in rad^-2 # Adding noise noise_gal = 1./n_gal noise_shape = sigma_e2[i]/n_gal else: noise_gal = 0. noise_shape = 0. # Now create corresponding Cls with pk2D objects matched to pk if t_i*2+t_j == 0: # this is gg tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[j,:]),mag_bias=None, \ has_rsd=False) cl_gg = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gg) cl_gg_no = cl_gg + noise_gal CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_gg_no elif t_i*2+t_j == 1: # this is gs tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j,:])) cl_gs = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gm) cl_gs_no = cl_gs CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_gs_no elif t_i*2+t_j == 3: # this is ss tracer_z1 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[i,:])) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j,:])) cl_ss = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_mm) cl_ss_no = cl_ss + noise_shape CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_ss_no if plot_for_sanity == True: if c == 0: # Plot for sanity plt.loglog(ells, cl_gg, label=r'$\mathrm{gg}$') plt.loglog(ells, cl_gg_no, label=r'$\mathrm{gg}+{\rm noise}$') plt.loglog(ells, cl_ss, label=r'$\mathrm{ss}$') plt.loglog(ells, cl_gs, label=r'$\mathrm{gs}$') plt.xlabel(r'$\ell$') plt.ylabel(r'$C_{\ell}$') plt.legend() plt.savefig('Cls.png') plt.close() if compute_inv_cov == False and compute_cov == False: print(len(CL_ALL)) return CL_ALL print(len(CL_ALL)) print(np.sum(CL_ALL>0)) COV_ALL = np.zeros((len(CL_ALL),len(CL_ALL))) # COMPUTE COVARIANCE MATRIX for c_A, comb_A in enumerate(all_combos): for c_B, comb_B in enumerate(all_combos): i = comb_A[0]%N_tomo # first redshift bin j = comb_A[1]%N_tomo # second redshift bin m = comb_B[0]%N_tomo # first redshift bin n = comb_B[1]%N_tomo # second redshift bin c_im = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_B[0]]))==all_combos,axis=1)) c_jn = np.argmax(np.product(np.sort(np.array([comb_A[1],comb_B[1]]))==all_combos,axis=1)) c_in = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_B[1]]))==all_combos,axis=1)) c_jm = np.argmax(np.product(np.sort(np.array([comb_A[1],comb_B[0]]))==all_combos,axis=1)) # PAIRS A,B ARE (ti,tj),(tm,tn) at same ell #cov(ij,mn) = im,jn + in,jm C_im = CL_ALL[(c_im*N_ell):(c_im*N_ell)+N_ell] C_jn = CL_ALL[(c_jn*N_ell):(c_jn*N_ell)+N_ell] C_in = CL_ALL[(c_in*N_ell):(c_in*N_ell)+N_ell] C_jm = CL_ALL[(c_jm*N_ell):(c_jm*N_ell)+N_ell] # Knox formula Cov_ijmn = (C_im*C_jn+C_in*C_jm)/((2*ell+1.)*delta_ell*f_sky) if plot_for_sanity == True: if (c_A == c_B): print(i,j,'=',m,n) print(c_A) Cl_err = np.sqrt(Cov_ijmn) t_i = comb_A[0]//N_tomo t_j = comb_A[1]//N_tomo print(N_tomo*i+j+1) plt.subplot(N_tomo, N_tomo, N_tomo*i+j+1) plt.title("z=%f x z=%f"%(z_bin_cents[i],z_bin_cents[j])) c_ij = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_A[1]]))==all_combos,axis=1)) C_ij = CL_ALL[(c_ij*N_ell):(c_ij*N_ell)+N_ell] # maybe add legend (_,caps,eb)=plt.errorbar(ell,C_ij,yerr=Cl_err,lw=2.,ls='-',capsize=5,label=str(t_i*2+t_j)) plt.legend() plt.xscale('log') plt.yscale('log') COV_ALL[(N_ell*c_A):(N_ell*c_A)+\ N_ell,(N_ell*c_B):(N_ell*c_B)+N_ell] = np.diag(Cov_ijmn) COV_ALL[(N_ell*c_B):(N_ell*c_B)+\ N_ell,(N_ell*c_A):(N_ell*c_A)+N_ell] = np.diag(Cov_ijmn) if compute_cov: return COV_ALL evals,evecs = la.eig(COV_ALL) if (is_pos_def(COV_ALL) != True): print("Covariance is not positive definite!"); exit(0) ICOV_ALL = la.inv(COV_ALL) return ICOV_ALL
def compute_Cls(cosmo_fid, dndz_z, b_z, z_cent, N_gal_sample, ell, a_arr, k_arr, sigma_e2, area_overlap, powerspec='halofit', simple_bias=True): N_ell = len(ell) N_zsamples_theo = len(z_cent) N_tomo = len(N_gal_sample) # choose a scheme for evaluating the matter power spectrum -- halofit is recommended if powerspec == 'halofit': # Compute matter pk using halofit pk_mm_arr = np.array( [ccl.nonlin_matter_power(cosmo_fid, k_arr, a) for a in a_arr]) elif powerspec == 'halomodel': # Alternatively use halo model pk_mm_arr = np.array([ ccl.halomodel.halomodel_matter_power(cosmo_fid, k_arr, a) for a in a_arr ]) # choose a scheme for evaluating the galaxy power spectrum between simple bias and HOD model if simple_bias == True: # Set the power spectra equal to the matter PS -- this changes later in the code pk_gg_arr = pk_mm_arr.copy() pk_gm_arr = pk_mm_arr.copy() else: # HOD parameter values hod_par = {'sigm_0': 0.4,'sigm_1': 0.,'alpha_0': 1.0,'alpha_1': 0.,'fc_0': 1.,'fc_1': 0.,\ 'lmmin_0': 3.71,'lmmin_1': 9.99,'m0_0': 1.28,'m0_1': 10.34,'m1_0': 7.08,'m1_1': 9.34} # Evolve HOD parameters and create an HOD profile hodpars = hod_funcs_evol_fit.HODParams(hod_par, islogm0=True, islogm1=True) hodprof = hod.HODProfile(cosmo_fid, hodpars.lmminf, hodpars.sigmf,\ hodpars.fcf, hodpars.m0f, hodpars.m1f, hodpars.alphaf) # Compute galaxy pk using halofit pk_gg_arr = np.array( [hodprof.pk(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Compute galaxy-matter pk using halofit pk_gm_arr = np.array( [hodprof.pk_gm(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Wipe b_z since HOD is adopted b_z[:, :] = 1. # Create pk2D objects for interpolation pk_mm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_mm_arr), is_logp=True) pk_gg = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gg_arr), is_logp=True) pk_gm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gm_arr), is_logp=True) # number of indep correlation functions per type gg gs ss N_tot_corr = N_ell * (N_tomo * (2 * N_tomo + 1)) # make C_ell of size N_ell*N_tomo*(2N_tomo+1) C_ell = np.zeros(N_tot_corr) # List all redshift bin combinations temp = np.arange(2 * N_tomo) temp = np.vstack((temp, temp)).T combs = np.array(list(combinations(range(2 * N_tomo), 2))) all_combos = np.vstack((temp, combs)) for c, comb in enumerate(all_combos): i = comb[0] % N_tomo # first redshift bin j = comb[1] % N_tomo # second redshift bin t_i = comb[0] // N_tomo # tracer type 0 means g and 1 means s t_j = comb[1] // N_tomo # tracer type 0 means g and 1 means s # Noise if (i == j): # number density of galaxies N_gal = N_gal_sample[i] n_gal = N_gal / area_overlap # in rad^-2 # Adding noise noise_gal = 1. / n_gal noise_shape = sigma_e2[i] / n_gal else: noise_gal = 0. noise_shape = 0. # Now create corresponding Cls with pk2D objects matched to pk # this is gg if t_i * 2 + t_j == 0: tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z[i,:]), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z[j,:]), \ dndz=(z_cent, dndz_z[j,:]),mag_bias=None, \ has_rsd=False) cl_gg = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gg) cl_gg_no = cl_gg + noise_gal C_ell[(N_ell * c):(N_ell * c) + N_ell] = cl_gg_no # this is gs elif t_i * 2 + t_j == 1: tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z[i,:]), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j, :])) cl_gs = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gm) cl_gs_no = cl_gs C_ell[(N_ell * c):(N_ell * c) + N_ell] = cl_gs_no # this is ss elif t_i * 2 + t_j == 3: tracer_z1 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[i, :])) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j, :])) cl_ss = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_mm) cl_ss_no = cl_ss + noise_shape C_ell[(N_ell * c):(N_ell * c) + N_ell] = cl_ss_no print(len(C_ell)) return C_ell
def compute_Cls(par,z_cent=z_s_cents,N_gal_sample=N_gal_bin,k_arr=k_ar,z_arr=z_ar,a_arr=a_ar,ell=ells,compute_inv_cov=False,plot_for_sanity=False,powerspec='halofit',simple_bias=False): # HOD parameters -- don't need to be called every time so can be taken out hod_par = { 'sigm_0': 0.4, 'sigm_1': 0., 'alpha_0': 1.0, 'alpha_1': 0., 'fc_0': 1., 'fc_1': 0., 'lmmin_0': par['lmmin_0']['val'], 'lmmin_1': par['lmmin_1']['val'], 'm0_0': par['m0_0']['val'], 'm0_1': par['m0_1']['val'], 'm1_0': par['m1_0']['val'], 'm1_1': par['m1_1']['val']} if powerspec == 'halofit': # Compute matter pk using halofit -- preferred pk_mm_arr = np.array([ccl.nonlin_matter_power(cosmo_fid, k_arr, a) for a in a_arr]) elif powerspec == 'halomodel': # Alternatively use halo model pk_mm_arr = np.array([ccl.halomodel.halomodel_matter_power(cosmo_fid, k_arr, a) for a in a_arr]) if simple_bias == True: # Using bias parameters # Pk_gg = b^2 Pmm and Pk_gm = b Pmm; however, this is taken into account when def tracers pk_gg_arr = pk_mm_arr.copy() pk_gm_arr = pk_mm_arr.copy() # load bias parameter b_z = np.array([par['b_%02d'%k]['val'] for k in range(N_zsamples)]) else: # Using the HOD model # load HOD and compute profile hodpars = hod_funcs_evol_fit.HODParams(hod_par, islogm0=True, islogm1=True) hodprof = hod.HODProfile(cosmo_fid, hodpars.lmminf, hodpars.sigmf,\ hodpars.fcf, hodpars.m0f, hodpars.m1f, hodpars.alphaf) # Compute galaxy power spectrum using halofit pk_gg_arr = np.array([hodprof.pk(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Compute galaxy-matter pk using halofit pk_gm_arr = np.array([hodprof.pk_gm(k_arr, a_arr[i]) for i in range(a_arr.shape[0])]) # Here we don't vary the bias parameters b_z = np.ones(N_zsamples) # Create pk2D objects for interpolation pk_mm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_mm_arr), is_logp=True) pk_gg = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gg_arr), is_logp=True) pk_gm = ccl.Pk2D(a_arr=a_arr, lk_arr=np.log(k_arr), pk_arr=np.log(pk_gm_arr), is_logp=True) # Assume a functional form of 0.95/D(a) for the bias parameters (notice how this plays in # the case of varying b(z)) it doesn't matter a lot in this case for we take finite diff #a_cent = 1./(1.+z_cent) #b_z *= 0.95/ccl.growth_factor(cosmo_fid,a_cent) # load the dndz parameters dndz_z = np.zeros((N_tomo,N_zsamples)) for i_z in range(N_tomo): dndz_z[i_z,:] = np.array([par['dndz_%02d_%02d'%(i_z,k)]['val'] for k in range(N_zsamples)]) # Number of total correlation elements for all of gg gs and ss variants tot_corr = N_ell*(N_tomo*(2*N_tomo+1)) # make CL_all of size N_ell*N_tomo*(2N_tomo+1) CL_ALL = np.zeros(tot_corr) # this lists all possible combinations of all gg gs and ss's for a given number of tomo bins # here is how it works: say we have 3 tomo bins, then we make an array of 2x3 = 6 numbers # from 0 through 5; where 0 through 2 correspond to galaxy tracer (g) and 3 through 5 to # shear tracer (s). # Our final list all_combos consists of every possible pair between # tracer 1 which can be any of 3 tomos and either g or s and tracer 2 which can also be # any of 3 tomos and either g or s. The way I do this is by first listing in temp # the 6 pairs making up all the tracer 1 and tracer 2 combs where they are either # both g or both s at the same tomographic redshift, i.e. temp is (0,0), (1,1) ... (5,5) # then I use the function combinations which finds all unique combinations between # two lists i.e. (0,1),(0,2)...(0,5),(1,2)...(1,5),(2,3)...(2,5),(3,4),(3,5),(4,5) # and call this list combs. Finally I combine the two in all_combos. # Note: combs does not have (1,0) for it contributes the same info as (0,1) # example pair (2,4) in this example corresponds to tracer 1 being galaxies in third tomographic # bin and tracer 2 being shear in second tomographic bin, in short (2,4)=(g2,s1) temp = np.arange(2*N_tomo) temp = np.vstack((temp,temp)).T combs = np.array(list(combinations(range(2*N_tomo),2))) all_combos = np.vstack((temp,combs)) for c, comb in enumerate(all_combos): # comb is the list pair, e.g. (2,5) while c is its order no. (b/n 0 and Ntomo(2Ntomo+1)-1) i = comb[0]%N_tomo # redshift bin of tracer 1 (b/n 0 and N_tomo-1 regardless of g or s) j = comb[1]%N_tomo # redshift bin of tracer 2 (b/n 0 and N_tomo-1 regardless of g or s) t_i = comb[0]//N_tomo # tracer type (0 or 1): 0 means g and 1 means s t_j = comb[1]//N_tomo # tracer type (0 or 1): 0 means g and 1 means s # Adding NOISE to only the diagonal elements if (i == j): # number density of galaxies - use area cosmos for these are the gals that overlap N_gal = N_gal_sample[i] n_gal = N_gal/area_COSMOS # in rad^-2 # Adding noise noise_gal = 1./n_gal noise_shape = sigma_e2[i]/n_gal else: noise_gal = 0. noise_shape = 0. # Now create corresponding Cls with pk2D objects matched to pk if t_i*2+t_j == 0: # this is gg (notice that this can only be 2*0+0 = 0) tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[j,:]),mag_bias=None, \ has_rsd=False) cl_gg = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gg) cl_gg_no = cl_gg + noise_gal CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_gg_no elif t_i*2+t_j == 1: # this is gs (notice that this can only be 2*0+1 = 1, never 2*1+0=2) tracer_z1 = ccl.NumberCountsTracer(cosmo_fid, bias=(z_cent, b_z), \ dndz=(z_cent, dndz_z[i,:]),mag_bias=None, \ has_rsd=False) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j,:])) cl_gs = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_gm) cl_gs_no = cl_gs CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_gs_no elif t_i*2+t_j == 3: # this is ss (notice that this can only be 2*1+1 = 3) tracer_z1 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[i,:])) tracer_z2 = ccl.WeakLensingTracer(cosmo_fid, dndz=(z_cent, dndz_z[j,:])) cl_ss = ccl.angular_cl(cosmo_fid, tracer_z1, tracer_z2, ell, p_of_k_a=pk_mm) cl_ss_no = cl_ss + noise_shape CL_ALL[(N_ell*c):(N_ell*c)+N_ell] = cl_ss_no # check whether things make sense if plot_for_sanity == True: if c == 0: # Plot for sanity plt.loglog(ells, cl_gg, label=r'$\mathrm{gg}$') plt.loglog(ells, cl_gg_no, label=r'$\mathrm{gg}+{\rm noise}$') plt.loglog(ells, cl_ss, label=r'$\mathrm{ss}$') plt.loglog(ells, cl_gs, label=r'$\mathrm{gs}$') plt.xlabel(r'$\ell$') plt.ylabel(r'$C_{\ell}$') plt.legend() plt.savefig('Cls.png') plt.close() # if we don't want the inverse covariance matrix if compute_inv_cov == False: print(len(CL_ALL)) return CL_ALL # print out numbers to make sure there is internet connection print(len(CL_ALL)) print(np.sum(CL_ALL>0)) # initiate covariance matrix into the trade COV_ALL = np.zeros((len(CL_ALL),len(CL_ALL))) # COMPUTE COVARIANCE MATRIX: Cov(A,B) for c_A, comb_A in enumerate(all_combos): # remove half the computations for c_B, comb_B in enumerate(all_combos): # pair A=(ti,tj), pair B=(tm,tn) at same ell, where t stands for either g or s i = comb_A[0]%N_tomo # redshift bin of tracer A_1 (i.e. along rows of Cov) j = comb_A[1]%N_tomo # redshift bin of tracer A_2 (i.e. along rows of Cov) m = comb_B[0]%N_tomo # redshift bin of tracer B_1 (i.e. along columns of Cov) n = comb_B[1]%N_tomo # redshift bin of tracer B_2 (i.e. along columns of Cov) # These are the pairs (their order number in all_combos) we need for Knox # cov(ij,mn) = im,jn + in,jm c_im = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_B[0]]))==all_combos,axis=1)) c_jn = np.argmax(np.product(np.sort(np.array([comb_A[1],comb_B[1]]))==all_combos,axis=1)) c_in = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_B[1]]))==all_combos,axis=1)) c_jm = np.argmax(np.product(np.sort(np.array([comb_A[1],comb_B[0]]))==all_combos,axis=1)) # retrieving their Cls C_im = CL_ALL[(c_im*N_ell):(c_im*N_ell)+N_ell] C_jn = CL_ALL[(c_jn*N_ell):(c_jn*N_ell)+N_ell] C_in = CL_ALL[(c_in*N_ell):(c_in*N_ell)+N_ell] C_jm = CL_ALL[(c_jm*N_ell):(c_jm*N_ell)+N_ell] # Knox formula Cov_ijmn = (C_im*C_jn+C_in*C_jm)/((2*ell+1.)*delta_ell*f_sky) if plot_for_sanity == True: if (c_A == c_B): print(i,j,'=',m,n) print(c_A) Cl_err = np.sqrt(Cov_ijmn) t_i = comb_A[0]//N_tomo t_j = comb_A[1]//N_tomo print(N_tomo*i+j+1) plt.subplot(N_tomo, N_tomo, N_tomo*i+j+1) plt.title("z=%f x z=%f"%(z_bin_cents[i],z_bin_cents[j])) c_ij = np.argmax(np.product(np.sort(np.array([comb_A[0],comb_A[1]]))==all_combos,axis=1)) C_ij = CL_ALL[(c_ij*N_ell):(c_ij*N_ell)+N_ell] # maybe add legend and make sure colors are the same for each type (_,caps,eb)=plt.errorbar(ell,C_ij,yerr=Cl_err,lw=2.,ls='-',capsize=5,label=str(t_i*2+t_j)) plt.legend() plt.xscale('log') plt.yscale('log') #plt.ylim([1.e-12,1.e-5]) # fill in the diagonals of the cov matrix and make use of its symmetry Cov(A,B)=Cov(B,A) COV_ALL[(N_ell*c_A):(N_ell*c_A)+\ N_ell,(N_ell*c_B):(N_ell*c_B)+N_ell] = np.diag(Cov_ijmn) COV_ALL[(N_ell*c_B):(N_ell*c_B)+\ N_ell,(N_ell*c_A):(N_ell*c_A)+N_ell] = np.diag(Cov_ijmn) # check matrix is positive definite if (is_pos_def(COV_ALL) != True): print("Covariance is not positive definite!"); exit(0) # compute and return inverse ICOV_ALL = la.inv(COV_ALL) return ICOV_ALL