bins = nmt.NmtBin.from_edges(elledges[:-1], elledges[1:])

w = nmt.NmtWorkspace()

cls = {'ell_eff': bins.get_effective_ells()}

if conf['nside'] <= 2048:
    field_i = gclfield
    field_j = []
    print(f'\n Calculating shear fields ...', flush=True)
    for j in range(conf['nz_src']):
        print(f'z{j+1}', flush=True)
        cshcat_j = cshcat[j]
        cshmask_j = csh.mask_make(cshcat_j, conf['nside'])
        field_j.append(csh.field_make(cshcat_j, cshmask_j,
                                 save_maps=conf['save_maps'],
                                 maps_prefix=f'{odir}/zbin{j}'))
    print(f'\n Computing MCM and getting cls ...', flush=True)
    for i in range(conf['nz_lns']):
        for j in range(conf['nz_src']):
            print(f'MCM z{i+1}z{j+1}', flush=True)
            w.compute_coupling_matrix(field_i[i], field_j[j], bins)
            cls[f'bpwrwin_{i}{j}'] = w.get_bandpower_windows()
            print(f'getting coupled cls z{i+1}z{j+1}', flush=True)
            cls_coup = nmt.compute_coupled_cell(field_i[i], field_j[j])
            if conf['pixwin']:
                cls_coup /= np.array([hp.pixwin(conf['nside'])] * 2)**2
            print(f'decoupling cls z{i+1}z{j+1}', flush=True)
            cls[f'cl_{i}{j}'] = w.decouple_cell(cls_coup)
            print('\n')
if elledges[0] > 0:
    elledges = np.insert(elledges, 0, 0)
if elledges[-1] < 3 * conf['nside']:
    elledges = np.append(elledges, 3 * conf['nside'])
bins = nmt.NmtBin.from_edges(elledges[:-1], elledges[1:])

# Create dirs (if needed)
if not os.path.exists(odir):
    os.makedirs(odir)

cls = {'ell_eff': bins.get_effective_ells()}
for i in range(conf['nz_src']):
    cshcat_i = cshcat[i]
    cshmask_i = csh.mask_make(cshcat_i, conf['nside'])
    field_i = csh.field_make(cshcat_i, cshmask_i,
                             save_maps=conf['save_maps'],
                             maps_prefix=f'{odir}/zbin{i}')
    for j in range(i, conf['nz_src']):
        cshcat_j = cshcat[j]
        cshmask_j = csh.mask_make(cshcat_j, conf['nside'])
        field_j = csh.field_make(cshcat_j, cshmask_j)
        w = csh.mcm_make(field_i, field_j, bins)
        cls[f'bpwrwin_{i}{j}'] = w.get_bandpower_windows()
        cls_coup = nmt.compute_coupled_cell(field_i, field_j)
        if conf['pixwin']:
            cls_coup /= np.array([hp.pixwin(conf['nside'])] * 4)**2
        cls[f'cl_{i}{j}'] = w.decouple_cell(cls_coup)
        if i == j:
            nls_coup = csh.pclnoise_make(cshcat_i, cshmask_i)
            if conf['pixwin']:
                nls_coup /= np.array([hp.pixwin(conf['nside'])] * 4)**2
cls = {'ell_eff': bins.get_effective_ells()}

print('starting zbin loops')

for i in range(conf['nz_lens']):
    wc = hp.read_map(f"{conf['redmagic']}/wcountsmap_zbin{i}.fits")
    dmask = hp.read_map(f"{conf['redmagic']}/maskmap.fits")

    nbar = sum(wc[dmask > 0]) / sum(dmask[dmask > 0])
    print(nbar)

    dmap = np.full(len(dmask), 0.0)
    dmap[dmask > 0] = wc[dmask > 0] / (nbar * dmask[dmask > 0]) - 1

    field_i = nmt.NmtField(dmask, [dmap], purify_e=False, purify_b=False)
    for j in range(conf['nz_source']):
        print(i, j)
        cshcat_j = cshcat[j]
        cshmask_j = csh.mask_make(cshcat_j, conf['nside'])
        field_j = csh.field_make(cshcat_j, cshmask_j)
        w = csh.mcm_make(field_i, field_j, bins)
        cls[f'bpwrwin_{i}{j}'] = w.get_bandpower_windows()
        cls[f'cl_{i}{j}'] = w.decouple_cell(
            nmt.compute_coupled_cell(field_i, field_j))

if not os.path.exists(odir):
    os.makedirs(odir)

np.savez_compressed(ofn, **cls)