|
117 | 117 | bls = [] |
118 | 118 | for task in subtasks: |
119 | 119 | sv1, m1, sv2, m2 = sv1_list[task], m1_list[task], sv2_list[task], m2_list[task] |
| 120 | + mapnames = ((sv1, m1), (sv2, m2)) |
| 121 | + pols = ('T', 'pol') |
120 | 122 |
|
121 | | - # for now, save some i/o and map2alm for likely case that pol is T |
122 | | - win1_T = so_map.read_map(d[f"window_T_{sv1}_{m1}"]) |
123 | | - if d[f'window_pol_{sv1}_{m1}'] != d[f'window_T_{sv1}_{m1}']: |
124 | | - win1_pol = so_map.read_map(d[f'window_pol_{sv1}_{m1}']) |
125 | | - else: |
126 | | - win1_pol = win1_T |
127 | | - |
128 | | - win2_T = so_map.read_map(d[f"window_T_{sv2}_{m2}"]) |
129 | | - if d[f'window_pol_{sv2}_{m2}'] != d[f'window_T_{sv2}_{m2}']: |
130 | | - win2_pol = so_map.read_map(d[f'window_pol_{sv2}_{m2}']) |
131 | | - else: |
132 | | - win2_pol = win2_T |
133 | 123 | log.info(f"[Rank {so_mpi.rank}, {task:02d}]: Preparing data for {sv1}_{m1} x {sv2}_{m2}") |
134 | 124 |
|
| 125 | + # only calculate the stuff we need to avoid numerical differences |
| 126 | + m2win_fn = {} |
| 127 | + for (sv, m) in mapnames: |
| 128 | + for pol in pols: |
| 129 | + m2win_fn[sv, m, pol] = d[f"window_{pol}_{sv}_{m}"] # no repeated keys |
| 130 | + |
| 131 | + win_fn2win = {} |
| 132 | + for win_fn in m2win_fn.values(): |
| 133 | + if win_fn not in win_fn2win: |
| 134 | + win_fn2win[win_fn] = so_map.read_map(win_fn) # no repeated computation (or keys) |
| 135 | + |
135 | 136 | # TODO: make DRY code with so_mcm for preparing inputs |
136 | 137 | lmax_limit = np.inf |
137 | | - for win in (win1_T, win1_pol, win2_T, win2_pol): |
| 138 | + for win in win_fn2win.values(): |
138 | 139 | _lmax_limit = win.get_lmax_limit() * 2 # this is OK |
139 | 140 | if _lmax_limit < lmax_limit: |
140 | 141 | lmax_limit = _lmax_limit |
141 | 142 | if lmax > lmax_limit: |
142 | 143 | raise ValueError("the requested lmax is too high with respect to the map pixellisation") |
143 | 144 | maxl = np.minimum(2*lmax, lmax_limit).astype(int) |
144 | 145 |
|
145 | | - win1_alm_T = sph_tools.map2alm(win1_T, niter=niter, lmax=maxl, dtype=np.complex128) |
146 | | - if win1_pol is not win1_T: # tests object equivalence |
147 | | - win1_alm_P = sph_tools.map2alm(win1_pol, niter=niter, lmax=maxl, dtype=np.complex128) |
148 | | - else: |
149 | | - win1_alm_P = win1_alm_T |
150 | | - win1 = (win1_alm_T, win1_alm_P) |
| 146 | + win_fn2walm = {} |
| 147 | + for win_fn, win in win_fn2win.items(): |
| 148 | + if win_fn not in win_fn2walm: |
| 149 | + win_fn2walm[win_fn] = sph_tools.map2alm(win, niter=niter, lmax=maxl, dtype=np.complex128) # no repeated computation (or keys) |
151 | 150 |
|
152 | | - win2_alm_T = sph_tools.map2alm(win2_T, niter=niter, lmax=maxl, dtype=np.complex128) |
153 | | - if win2_pol is not win2_T: # tests object equivalence |
154 | | - win2_alm_P = sph_tools.map2alm(win2_pol, niter=niter, lmax=maxl, dtype=np.complex128) |
155 | | - else: |
156 | | - win2_alm_P = win2_alm_T |
157 | | - win2 = (win2_alm_T, win2_alm_P) |
| 151 | + can_win_fn_2pt2cl = {} |
| 152 | + for win_fn1, walm1 in win_fn2walm.items(): |
| 153 | + for win_fn2, walm2 in win_fn2walm.items(): |
| 154 | + can_win_fn_2pt = pspipe_list.canonize_connected_2pt(win_fn1, win_fn2) |
| 155 | + if can_win_fn_2pt not in can_win_fn_2pt2cl: |
| 156 | + can_win_fn_2pt2cl[can_win_fn_2pt] = curvedsky.alm2cl(walm1, walm2, dtype=np.float64) # no repeated computation (or keys) |
158 | 157 |
|
| 158 | + # beams have no numerical differences due to multithreading |
159 | 159 | _, bl1 = misc.read_beams(d[f"beam_T_{sv1}_{m1}"], d[f"beam_pol_{sv1}_{m1}"]) |
160 | 160 | _, bl2 = misc.read_beams(d[f"beam_T_{sv2}_{m2}"], d[f"beam_pol_{sv2}_{m2}"]) |
161 | 161 |
|
162 | 162 | bl1 = (bl1["T"], bl1["E"]) |
163 | 163 | bl2 = (bl2["T"], bl2["E"]) |
164 | 164 |
|
| 165 | + # tabulate inputs for ducc, avoid numerical differences in specs_for_ducc |
165 | 166 | spec_for_ducc = [] |
166 | 167 | bl = [] |
167 | 168 | for i in range(2): |
168 | 169 | for j in range(2): |
169 | | - spec_for_ducc.append(curvedsky.alm2cl(win1[i], win2[j])) |
| 170 | + (svi, mi), (svj, mj) = mapnames[i], mapnames[j] |
| 171 | + poli, polj = pols[i], pols[j] |
| 172 | + win_fni, win_fnj = m2win_fn[svi, mi, poli], m2win_fn[svj, mj, polj] |
| 173 | + can_win_fn_2pt_ij = pspipe_list.canonize_connected_2pt(win_fni, win_fnj) |
| 174 | + spec_for_ducc.append(can_win_fn_2pt2cl[can_win_fn_2pt]) |
170 | 175 | bl.append(bl1[i][2:lmax] * bl2[j][2:lmax]) # TODO: reconsider pspipe conventions |
171 | 176 | specs_for_ducc.append(spec_for_ducc) |
172 | 177 | bls.append(bl) |
|
177 | 182 | bls = np.repeat(bls, (1, 1, 1, 2), axis=1) # (nspec, 4, nl) -> (nspec, 5, nl) |
178 | 183 | bls = bls[..., None, :] # (nspec, 5, nl) -> (nspec, 5, 1, nl) |
179 | 184 |
|
180 | | - mcms = so_mcm.ducc_couplings(specs_for_ducc, lmax, len(subtasks)*[0, 1, 2, 4], |
| 185 | + mcms = so_mcm.ducc_couplings(specs_for_ducc, lmax, len(subtasks)*[0, 1, 1, 4], # 00, 02, 02, ++, -- |
181 | 186 | dtype=np.float64, coupling=False, |
182 | 187 | pspy_index_convention=True) |
183 | 188 | mcms = mcms.reshape(len(subtasks), 5, lmax-2, lmax-2) # (nspec*5, nl, nl) -> (nspec, 5, nl, nl) |
|
0 commit comments