def synfast_flat(nx, ny, lx, ly, cls, spin_arr, beam=None, seed=-1): """ Generates a flat-sky Gaussian random field according to a given power \ spectrum. This function is the flat-sky equivalent of healpy's synfast. :param int nx: number of pixels in the x-axis :param int ny: number of pixels in the y-axis :param float lx: patch size in the x-axis (in radians) :param float ly: patch size in the y-axis (in radians) :param array-like cls: array containing power spectra. Shape should be \ [n_cls][n_ell], where n_cls is the number of power spectra needed \ to define all the fields. This should be \ n_cls = n_maps * (n_maps + 1) / 2, where n_maps is the total number \ of maps required (1 for each spin-0 field, 2 for each spin>0 field). \ Power spectra must be provided only for the upper-triangular part in \ row-major order (e.g. if n_maps is 3, there will be 6 power spectra \ ordered as [1-1,1-2,1-3,2-2,2-3,3-3]. :param array-like spin_arr: array containing the spins of all the fields \ to generate. :param beam array-like: 2D array containing the instrumental beam of each \ field to simulate (the output map(s) will be convolved with it) :param int seed: RNG seed. If negative, will use a random seed. :return: a number of arrays (1 for each spin-0 field, 2 for each \ spin-2 field) of size (ny,nx) containing the simulated maps. """ if seed < 0: seed = np.random.randint(50000000) spin_arr = np.array(spin_arr).astype(np.int32) nfields = len(spin_arr) if np.any(spin_arr < 0): raise ValueError("Spins must be positive") nmaps = int(1 * np.sum(spin_arr == 0) + 2 * np.sum(spin_arr != 0)) ncls = (nmaps * (nmaps + 1)) // 2 if ncls != len(cls): raise ValueError("Must provide all Cls necessary to simulate all " "fields (%d)." % ncls) lmax = len(cls[0]) - 1 if beam is None: beam = np.ones([nfields, lmax + 1]) else: if len(beam) != nfields: raise ValueError("Must provide one beam per field") if len(beam[0]) != lmax + 1: raise ValueError( "The beam should have as many multipoles as the power spectrum" ) data = lib.synfast_new_flat(nx, ny, lx, ly, spin_arr, seed, cls, beam, nmaps * nx * ny) maps = data.reshape([nmaps, ny, nx]) return maps
def synfast_flat(nx,ny,lx,ly,cls,pol=False,beam=None,seed=-1) : """ Generates a flat-sky Gaussian random field according to a given power spectrum. This function is the flat-sky equivalent of healpy's synfast. :param int nx: number of pixels in the x-axis :param int ny: number of pixels in the y-axis :param float lx: patch size in the x-axis (in radians) :param float ly: patch size in the y-axis (in radians) :param array-like cls: array containing power spectra. If pol=False, cls should be a 1D array. If pol=True it should be a 2D array with 4 (TT,EE,BB,TE) or 6 (TT,EE,BB,TE,EB,TB) power spectra. :param boolean pol: Set to True if you want to generate T, Q and U :param beam array-like: 1D array containing the instrumental beam (the output map(s) will be convolved with it) :param int seed: RNG seed. If negative, will use a random seed. :return: 1 or 3 2D arrays of size (ny,nx) containing the simulated maps """ if seed<0 : seed=np.random.randint(50000000) if pol : use_pol=1 nmaps=3 if(len(np.shape(cls))!=2) : raise ValueError("You should supply more than one power spectrum if you want polarization") ncl=len(cls) if ((ncl!=4) and (ncl!=6)) : raise ValueError("You should provide 4 or 6 power spectra if you want polarization") lmax=len(cls[0])-1 cls_use=np.zeros([6,lmax+1]) cls_use[0,:]=cls[0] #TT cls_use[1,:]=cls[3] #TE cls_use[3,:]=cls[1] #EE cls_use[5,:]=cls[2] #BB if ncl==6 : cls_use[2,:]=cls[4] #TB cls_use[4,:]=cls[5] #EB else : use_pol=0 nmaps=1 if(len(np.shape(cls))!=1) : raise ValueError("You should supply only one power spectrum if you don't want polarization") lmax=len(cls)-1 cls_use=np.array([cls]) if beam is None : beam_use=np.ones(lmax+1) else : if len(beam)!=lmax+1 : raise ValueError("The beam should have as many multipoles as the power spectrum") beam_use=beam data=lib.synfast_new_flat(nx,ny,lx,ly,use_pol,seed,cls_use,beam_use,nmaps*ny*nx) maps=data.reshape([nmaps,ny,nx]) return maps