def test_cmb_map_bandpass(): nside = 32 # pretend for testing that the Dust is CMB model = pysm3.CMBMap(map_IQU="pysm_2/lensed_cmb.fits", nside=nside) freq = 100 * u.GHz expected_map = pysm3.read_map( "pysm_2/lensed_cmb.fits", field=0, nside=nside, unit=u.uK_CMB ).to(u.uK_RJ, equivalencies=u.cmb_equivalencies(freq)) print( "expected_scaling", (1 * u.K_CMB).to_value(u.K_RJ, equivalencies=u.cmb_equivalencies(freq)), ) freqs = np.array([98, 99, 100, 101, 102]) * u.GHz weights = np.ones(len(freqs)) # just checking that the result is reasonably close # to the delta frequency at the center frequency assert_quantity_allclose( expected_map, model.get_emission(freqs, weights)[0], rtol=1e-3 )
def test_cmb_map(): nside = 32 # pretend for testing that the Dust is CMB model = pysm3.CMBMap(map_IQU="pysm_2/lensed_cmb.fits", nside=nside) freq = 100 * u.GHz expected_map = pysm3.read_map( "pysm_2/lensed_cmb.fits", field=(0, 1), nside=nside, unit=u.uK_CMB ).to(u.uK_RJ, equivalencies=u.cmb_equivalencies(freq)) simulated_map = model.get_emission(freq) for pol in [0, 1]: assert_quantity_allclose(expected_map[pol], simulated_map[pol], rtol=1e-5)
def get_sky(self, coverage): setting = [] iscmb = False for k in self.skyconfig: if k == 'cmb': iscmb = True maps = self.get_cmb(coverage) rndstr = random_string(10) hp.write_map('/tmp/' + rndstr, maps) cmbmap = pysm3.CMBMap(self.nside, map_IQU='/tmp/' + rndstr) os.remove('/tmp/' + rndstr) #setting.append(skyconfig[k]) elif k == 'dust': pass else: setting.append(self.skyconfig[k]) sky = pysm3.Sky(nside=self.nside, preset_strings=setting) if iscmb: sky.add_component(cmbmap) return sky
def make_cmb_sims(params): """ Write cmb maps on disk Parameters ---------- params: module contating all the simulation parameters """ nmc_cmb = params.nmc_cmb nside = params.nside smooth = params.gaussian_smooth ch_name = [ 'SO_SAT_27', 'SO_SAT_39', 'SO_SAT_93', 'SO_SAT_145', 'SO_SAT_225', 'SO_SAT_280' ] freqs = sonc.Simons_Observatory_V3_SA_bands() beams = sonc.Simons_Observatory_V3_SA_beams() band_int = params.band_int parallel = params.parallel root_dir = params.out_dir out_dir = f'{root_dir}/cmb/' file_str = params.file_string seed_cmb = params.seed_cmb cmb_ps_file = params.cmb_ps_file rank = 0 size = 1 if params.parallel: from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() if not os.path.exists(out_dir) and rank == 0: os.makedirs(out_dir) if cmb_ps_file: print(cmb_ps_file) cl_cmb = hp.read_cl(cmb_ps_file) else: cmb_ps_scalar_file = os.path.join(os.path.dirname(__file__), 'datautils/Cls_Planck2018_r0.fits') cl_cmb_scalar = hp.read_cl(cmb_ps_scalar_file) cmb_ps_tensor_r1_file = os.path.join( os.path.dirname(__file__), 'datautils/Cls_Planck2018_tensor_r1.fits') cmb_r = params.cmb_r cl_cmb_tensor = hp.read_cl(cmb_ps_tensor_r1_file) * cmb_r cl_cmb = cl_cmb_scalar + cl_cmb_tensor nmc_cmb = math.ceil(nmc_cmb / size) * size if nmc_cmb != params.nmc_cmb: print_rnk0(f'WARNING: setting nmc_cmb = {nmc_cmb}', rank) perrank = nmc_cmb // size for nmc in range(rank * perrank, (rank + 1) * perrank): if seed_cmb: np.random.seed(seed_cmb + nmc) nmc_str = str(nmc).zfill(4) if not os.path.exists(out_dir + nmc_str): os.makedirs(out_dir + nmc_str) cmb_temp = hp.synfast(cl_cmb, nside, new=True, verbose=False) file_name = f'cmb_{nmc_str}_{file_str}.fits' file_tot_path = f'{out_dir}{nmc_str}/{file_name}' hp.write_map(file_tot_path, cmb_temp, overwrite=True, dtype=np.float32) os.environ["PYSM_LOCAL_DATA"] = f'{out_dir}' sky = pysm3.Sky(nside=nside, component_objects=[ pysm3.CMBMap(nside, map_IQU=f'{nmc_str}/{file_name}') ]) for nch, chnl in enumerate(ch_name): freq = freqs[nch] fwhm = beams[nch] cmb_map = sky.get_emission(freq * u.GHz) cmb_map = cmb_map.to(u.uK_CMB, equivalencies=u.cmb_equivalencies(freq * u.GHz)) if smooth: cmb_map_smt = hp.smoothing(cmb_map, fwhm=np.radians(fwhm / 60.), verbose=False) else: cmb_map_smt = cmb_map file_name = f'{chnl}_cmb_{nmc_str}_{file_str}.fits' file_tot_path = f'{out_dir}{nmc_str}/{file_name}' hp.write_map(file_tot_path, cmb_map_smt, overwrite=True, dtype=np.float32)
def __init__(self, skyconfig, d, instrument, out_dir, out_prefix, lmax=None): """ Parameters: skyconfig : a skyconfig dictionary to pass to (as expected by) `PySM` d : input dictionary, from which the following Parameters are read instrument : a `PySM` instrument describing the instrument out_dir : default path where the sky maps will be saved out_prefix : default word for the output files For more details about `PySM` see the `PySM` documentation at the floowing link: https://pysm-public.readthedocs.io/en/latest/index.html """ self.skyconfig = skyconfig self.nside = d['nside'] self.npix = 12 * self.nside ** 2 self.dictionary = d self.Nfin = int(self.dictionary['nf_sub']) self.Nfout = int(self.dictionary['nf_recon']) self.filter_nu = int(self.dictionary['filter_nu'] / 1e9) self.filter_relative_bandwidth = self.dictionary['filter_relative_bandwidth'] self.instrument = instrument self.output_directory = out_dir self.output_prefix = out_prefix self.input_cmb_maps = None self.input_cmb_spectra = None if lmax is None: self.lmax = 3 * d['nside'] else: self.lmax = lmax iscmb = False preset_strings = [] for k in skyconfig.keys(): if k == 'cmb': iscmb = True keyword = skyconfig[k] if isinstance(keyword, dict): # the CMB part is defined via a dictionary # This can be either a set of maps, a set of CAMB spectra, or whatever # In the second case it might also contain the seed (None means rerun it each time) # In the third case we recompute some CAMB spectra and generate the maps keys = keyword.keys() if 'IQUMaps' in keys: # this is the case where we have IQU maps mymaps = keyword['IQUMaps'] self.input_cmb_maps = mymaps self.input_cmb_spectra = None elif 'CAMBSpectra' in keys: # this is the case where we have CAMB Spectra # Note that they are in l(l+1) CL/2pi so we have to change that for synfast totDL = keyword['CAMBSpectra'] ell = keyword['ell'] mycls = qc.Dl2Cl_without_monopole(ell, totDL) # set the seed if needed if 'seed' in keys: np.random.seed(keyword['seed']) mymaps = hp.synfast(mycls.T, self.nside, verbose=False, new=True) self.input_cmb_maps = mymaps self.input_cmb_spectra = totDL else: raise ValueError( 'Bad Dictionary given for PySM in the CMB part - see QubicSkySim.py for details') else: # The CMB part is not defined via a dictionary but only by the seed for synfast # No map nor CAMB spectra was given, so we recompute them. # The assumed cosmology is the default one given in the get_CAMB_Dl() function # from camb_interface library. if keyword is not None: np.random.seed(keyword) ell, totDL, unlensedCL = qc.get_camb_Dl(lmax=self.lmax) mycls = qc.Dl2Cl_without_monopole(ell, totDL) mymaps = hp.synfast(mycls.T, self.nside, verbose=False, new=True) self.input_cmb_maps = mymaps self.input_cmb_spectra = totDL # Write a temporary file with the maps so the PySM can read them rndstr = random_string(10) hp.write_map('/tmp/' + rndstr, mymaps) cmbmap = pysm.CMBMap(self.nside, map_IQU='/tmp/' + rndstr) os.remove('/tmp/' + rndstr) else: # we add the other predefined components preset_strings.append(skyconfig[k]) self.sky = pysm.Sky(nside=self.nside, preset_strings=preset_strings) if iscmb: self.sky.add_component(cmbmap)
def generate_cmb(self): instr = self.instrument nmc_cmb = self.params.nmc_cmb nside = self.params.nside npix = hp.nside2npix(nside) smooth = self.params.gaussian_smooth parallel = self.params.parallel_mc root_dir = self.sim.base_path output_directory = root_dir / "cmb" file_str = self.params.output_string channels = instr.keys() n_channels = len(channels) seed_cmb = self.params.seed_cmb cmb_ps_file = self.params.cmb_ps_file col_units = [self.params.units, self.params.units, self.params.units] saved_maps = [] if parallel: comm = lbs.MPI_COMM_WORLD rank = comm.Get_rank() size = comm.Get_size() else: comm = None rank, size = 0, 1 if rank == 0: output_directory.mkdir(parents=True, exist_ok=True) if cmb_ps_file: cl_cmb = hp.read_cl(cmb_ps_file) else: datautils_dir = Path(__file__).parent.parent / "datautils" cl_cmb_scalar = hp.read_cl(datautils_dir / "Cls_Planck2018_for_PTEP_2020_r0.fits") cl_cmb_tensor = (hp.read_cl( datautils_dir / "Cls_Planck2018_for_PTEP_2020_tensor_r1.fits") * self.params.cmb_r) cl_cmb = cl_cmb_scalar + cl_cmb_tensor nmc_cmb = math.ceil(nmc_cmb / size) * size if nmc_cmb != self.params.nmc_cmb: log.info(f"setting nmc_cmb = {nmc_cmb}", rank) perrank = nmc_cmb // size if not self.params.save: cmb_map_matrix = np.zeros((n_channels, 3, npix)) else: cmb_map_matrix = None os.environ["PYSM_LOCAL_DATA"] = str(output_directory) for nmc in range(rank * perrank, (rank + 1) * perrank): if seed_cmb: np.random.seed(seed_cmb + nmc) nmc_str = f"{nmc:04d}" nmc_output_directory = output_directory / nmc_str if rank == 0: nmc_output_directory.mkdir(parents=True, exist_ok=True) cmb_temp = hp.synfast(cl_cmb, nside, new=True, verbose=False) file_name = f"cmb_{nmc_str}_{file_str}.fits" cur_map_path = nmc_output_directory / file_name lbs.write_healpix_map_to_file(cur_map_path, cmb_temp, column_units=col_units) saved_maps.append( MbsSavedMapInfo(path=cur_map_path, component="cmb", mc_num=nmc)) sky = pysm3.Sky( nside=nside, component_objects=[ pysm3.CMBMap(nside, map_IQU=Path(nmc_str) / file_name) ], ) for Nchnl, chnl in enumerate(channels): freq = instr[chnl].bandcenter_ghz if self.params.bandpass_int: band = instr[chnl].bandwidth_ghz fmin = freq - band / 2.0 fmax = freq + band / 2.0 fsteps = np.int(np.ceil(fmax - fmin) + 1) bandpass_frequencies = np.linspace(fmin, fmax, fsteps) * u.GHz weights = np.ones(len(bandpass_frequencies)) cmb_map = sky.get_emission(bandpass_frequencies, weights) cmb_map = cmb_map * pysm3.bandpass_unit_conversion( bandpass_frequencies, weights, self.pysm_units) else: cmb_map = sky.get_emission(freq * u.GHz) cmb_map = cmb_map.to(self.pysm_units, equivalencies=u.cmb_equivalencies( freq * u.GHz)) fwhm_arcmin = instr[chnl].fwhm_arcmin if smooth: cmb_map_smt = hp.smoothing(cmb_map, fwhm=np.radians(fwhm_arcmin / 60.0), verbose=False) else: cmb_map_smt = cmb_map if self.params.save: file_name = f"{chnl}_cmb_{nmc_str}_{file_str}.fits" cur_map_path = nmc_output_directory / file_name lbs.write_healpix_map_to_file(cur_map_path, cmb_map_smt, column_units=col_units) saved_maps.append( MbsSavedMapInfo(path=cur_map_path, component="cmb")) else: cmb_map_matrix[Nchnl] = cmb_map_smt return (cmb_map_matrix, saved_maps)