def generate_noise_sim(covsqrt, ivars, seed=None, dtype=None): """ Supports only two cases 1) nfreqs>=1,npol=3 2) nfreqs=1,npol=1 """ if isinstance(seed, int): seed = (seed, ) assert np.all(np.isfinite(covsqrt)) shape, wcs = covsqrt.shape, covsqrt.wcs Ny, Nx = shape[-2:] ncomps = covsqrt.shape[0] assert ncomps == covsqrt.shape[1] assert ((ncomps % 3) == 0) or (ncomps == 1) nfreqs = 1 if ncomps == 1 else ncomps // 3 if ncomps == 1: npol = 1 else: npol = 3 wmaps = enmap.extract(ivars, shape[-2:], wcs) nsplits = wmaps.shape[1] if dtype is np.float32: ctype = np.complex64 elif dtype is np.float64: ctype = np.complex128 # Old way with loop kmap = [] for i in range(nsplits): if seed is None: np.random.seed(None) else: np.random.seed(seed + (i, )) rmap = enmap.rand_gauss_harm((ncomps, Ny, Nx), covsqrt.wcs).astype(ctype) kmap.append(enmap.map_mul(covsqrt, rmap)) del covsqrt, rmap kmap = enmap.enmap(np.stack(kmap), wcs) outmaps = enmap.ifft(kmap, normalize="phys").real del kmap # Need to test this more ; it's only marginally faster and has different seed behaviour # covsqrt = icovsqrt # np.random.seed(seed) # rmap = enmap.rand_gauss_harm((nsplits,ncomps,Ny, Nx),covsqrt.wcs) # kmap = enmap.samewcs(np.einsum("abyx,cbyx->cayx", covsqrt, rmap),rmap) # outmaps = enmap.ifft(kmap, normalize="phys").real # isivars = 1/np.sqrt(wmaps) with np.errstate(divide='ignore', invalid='ignore'): isivars = ((1. / wmaps) - (1. / wmaps.sum(axis=1)[:, None, ...]))**0.5 isivars[~np.isfinite(isivars)] = 0 assert np.all(np.isfinite(outmaps)) # Divide by hits for ifreq in range(nfreqs): outmaps[:, ifreq * npol:(ifreq + 1) * npol, ...] = outmaps[:, ifreq * npol:(ifreq + 1) * npol, ...] * isivars[ifreq, ...] * np.sqrt(nsplits) retmaps = outmaps.reshape((nsplits, nfreqs, npol, Ny, Nx)).swapaxes(0, 1) assert np.all(np.isfinite(retmaps)) return retmaps, wmaps
def getActpolNoiseSim(noiseSeed, psa, noisePsdDir, freqs, verbose=True, useCovSqrt=True, killFactor=30., fillValue=0., noiseDiagsOnly=False, splitWanted=None): #return array of T, Q, U #to-do: these are currently using numpy.FFT and are slow; switch to FFTW if installed. #Could also have an alternative version of this using enlib tools. if useCovSqrt: #in this case it was the CovSqrt's that were saved. This is based on Mat's code in orphics. if verbose: print( 'getActpolNoiseSim(): getting weight maps; assuming I for all') iqu = 'I' #FOR NOW # stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'totalWeightMap' \ # + iqu + '_' + psa + '_' + freq + '_fromenlib.fits') \ # for freq in freqs ] if splitWanted is None: stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'totalWeightMap'\ + iqu + '_' + psa + '_' + freq + '_fromenlib.fits') \ for freq in freqs ] else: stackOfMaskMaps = [enmap.read_map(noisePsdDir + 'weightMap_split' + str(splitWanted) \ + iqu + '_' + psa + '_' + freq + '_fromenlib.fits') \ for freq in freqs ] thisWcs = stackOfMaskMaps[0].wcs maskMaps = enmap.enmap(np.stack(stackOfMaskMaps), thisWcs) #first one is for IXI, QxQ, UXU only print("loading") if False: print('loading ' + noisePsdDir + '/bigMatrixNoisePsdsCovSqrtDiags_' + psa + '.fits HACKING') covsqrt = enmap.read_fits(noisePsdDir + '/bigMatrixNoisePsdsCovSqrtDiags_' + psa + '.fits') if False: print('loading ' + noisePsdDir + '/bigMatrixNoisePsdsCovSqrt_' + psa + '.fits') covsqrt = enmap.read_fits(noisePsdDir + '/bigMatrixNoisePsdsCovSqrt_' + psa + '.fits') if noiseDiagsOnly: print('loading ' + noisePsdDir + '/noisePsds_flattened_covSqrtDiags_' + psa + '.fits') covsqrt = enmap.read_fits(noisePsdDir + '/noisePsds_flattened_covSqrtDiags_' + psa + '.fits') elif True: print('loading ' + noisePsdDir + '/noisePsds_flattened_covSqrt_' + psa + '.fits') covsqrt = enmap.read_fits(noisePsdDir + '/noisePsds_flattened_covSqrt_' + psa + '.fits') print("loading done") if verbose: print('getActpolNoiseSim(): running map_mul to make random phases') #get the right normalization covsqrt *= np.sqrt( np.prod(covsqrt.shape[-2:]) / enmap.area(covsqrt.shape[-2:], thisWcs)) np.random.seed(noiseSeed) print("randmap") rmap = enmap.rand_gauss_harm( (covsqrt.shape[0], covsqrt.shape[-2:][0], covsqrt.shape[-2:][1]), thisWcs) print("randmap done") print("map_mul") kmap = enmap.map_mul(covsqrt, rmap) print("map_mul done") #old way: # kmapReshape = kmap.reshape((4, kmap.shape[-2:][0], kmap.shape[-2:][1])) # outMaps = enmap.ifft(kmapReshape).real # kmap /= sqrt(mask) if verbose: print('getActpolNoiseSim(): inverse transforming') print('you are transforming %d maps' % kmap.shape[0]) spin = np.repeat([0], kmap.shape[0]) print("fft") outMaps = enmap.harm2map(kmap, iau=False, spin=spin) print("fft done") #now reshape to have shape [nfreqs, 3, Ny, Nx] #The "order = 'F' (row vs. column ordering) is due to the ordering that is done #in makeNoisePsds.py for the dichroic arrays, #namely I90, Q90, U90, I150, Q150, U150. outMaps = outMaps.reshape(len(freqs), outMaps.shape[0] / len(freqs), outMaps.shape[-2], outMaps.shape[-1], order='F') for fi, freq in enumerate(freqs): #Note each frequency has its own maskmap, so this loop is important thisMaskMap = np.squeeze(maskMaps[fi]) outMaps[fi, :, :, :] /= np.sqrt(thisMaskMap) #Loop over T,Q,U. Couldn't think of clever way to vectorize this part.. for z in range(outMaps.shape[-3]): outMaps[fi, z][thisMaskMap < thisMaskMap[np.where(np.isfinite(thisMaskMap))].max() / killFactor] \ = fillValue if verbose: print('getActpolNoiseSim(): done ') return outMaps else: raise ValueError('older ways of getting the noise maps are deprecated')
for amask in ['old', 'new']: mask = masks[amask] shape, wcs = mask.shape, mask.wcs modlmap = enmap.modlmap(shape, wcs) Ny, Nx = shape[-2:] n2d = rednoise(modlmap, rms_noise=20., lknee=3000., alpha=-4.5) n2d[modlmap < 100] = 0 bin_edges = np.arange(100, 8000, 40) binner = stats.bin2D(modlmap, bin_edges) cents, n1d = binner.bin(n2d) covsqrt = get_covsqrt(n2d[None, None].copy()) rmap = enmap.rand_gauss_harm((1, Ny, Nx), covsqrt.wcs) kmap = enmap.map_mul(covsqrt, rmap) imap = enmap.ifft(kmap, normalize="phys").real kmap = enmap.fft(imap * mask, normalize="phys") p2d = np.real(kmap * np.conjugate(kmap)) / np.mean(mask**2.) cents, p1d = binner.bin(p2d) pl.add(cents, p1d / n1d, label=method + amask) pl.hline(y=1) pl.done() # pl = io.Plotter(xyscale='linlog') # pl.add(cents,p1d) # pl.add(cents,n1d)