def do_model_setup(self, params): """ Method to calculate the power spectrum primordial and lensing templates for a given set of cosmological parameters. This computation requires that the lmax be set much higher that the lmax required in the final analys.s Parameters ---------- params: dict Dictionary of cosmological parameters to be sent to CLASS. Returns ------- tuple(array_like(float)) Tuple containing the BB primordial and lensing templates. """ try: params.pop('a_lens') except: pass params.update({ 'output': 'tCl pCl lCl', 'l_max_scalars': 5000, 'l_max_tensors': 2000, 'modes': 's, t', 'r': 1, 'lensing': 'yes', }) cosm = Class() cosm.set(params) cosm.compute() # get the lensed and raw power spectra up to the maximum # multipole used in the likelihood analysis. Multiply by # T_CMB ^ 2 to get from dimensionless to uK^2 units. lensed_cls = cosm.lensed_cl(3 * self.nside - 1)['bb'] * (2.7225e6)**2 raw_cls = cosm.raw_cl(3 * self.nside - 1)['bb'] * (2.7225e6)**2 # get ells, used in the calculation of the foreground model # over the same range. ells = cosm.raw_cl(3 * self.nside - 1)['ell'] # do the house keeping for the CLASS code. cosm.struct_cleanup() cosm.empty() # calculate the lensing-only template lens_template = self.apply_coupling(lensed_cls - raw_cls) raw_cls = self.apply_coupling(raw_cls) # now separately do the foreground template setup. if self.marg: fg_template = np.zeros(3 * self.nside) fg_template[1:] = (ells[1:] / 80.)**-2.4 fg_template = self.apply_coupling(fg_template) return (raw_cls, lens_template, fg_template) return (raw_cls, lens_template)
def class_spectrum(params): """ Function to generate the theoretical CMB power spectrum for a given set of parameters. Parameters ---------- params: dict dict containing the parameters expected by CLASS and their values. Returns ------- array_like(float) Array of shape (4, lmax + 1) containing the TT, EE, BB, TE power spectra. """ # This line is crucial to prevent pop from removing the lensing efficieny # from future runs in the same script. class_pars = {**params} try: # if lensing amplitude is set, remove it from dictionary that will # be passed to CLASS. a_lens = class_pars.pop('a_lens') except KeyError: # if not set in params dictionary just set to 1. a_lens = 1 # generate the CMB realizations. print("Running CLASS with lensing efficiency: ", a_lens) cos = Class() cos.set(class_pars) cos.compute() # returns CLASS format, 0 to lmax, dimensionless, Cls. # multiply by (2.7225e6) ** 2 to get in uK_CMB ^ 2 lensed_cls = cos.lensed_cl() raw_bb = cos.raw_cl()['bb'][:class_pars['l_max_scalars'] + 1] # calculate the lensing contribution to BB and rescale by # the lensing amplitude factor. lensing_bb = a_lens * (lensed_cls['bb'] - raw_bb) cos.struct_cleanup() cos.empty() synfast_cls = np.zeros((4, class_pars['l_max_scalars'] + 1)) synfast_cls[0, :] = lensed_cls['tt'] synfast_cls[1, :] = lensed_cls['ee'] synfast_cls[2, :] = lensing_bb + raw_bb synfast_cls[3, :] = lensed_cls['te'] return synfast_cls * (2.7225e6)**2
def calculate_spectra(self, cosmo_params, force_recalc=False): settings = cosmo_params.copy() settings.update({ "output": "tCl,mPk", "evolver": "1", "gauge": "newtonian", "P_k_max_1/Mpc": 10, }) database = Database(config.DATABASE_DIR, "spectra.dat") if settings in database and not force_recalc: data = database[settings] ell = data["ell"] tt = data["tt"] kh = data["kh"] Pkh = data["Pkh"] self.z_rec = data["z_rec"] else: cosmo = Class() cosmo.set(settings) cosmo.compute() # Cl's data = cosmo.raw_cl() ell = data["ell"] tt = data["tt"] # Matter spectrum k = np.logspace(-3, 1, config.MATTER_SPECTRUM_CLIENT_SAMPLES_PER_DECADE * 4) Pk = np.vectorize(cosmo.pk)(k, 0) kh = k * cosmo.h() Pkh = Pk / cosmo.h()**3 # Get redshift of decoupling z_rec = cosmo.get_current_derived_parameters(['z_rec'])['z_rec'] self.z_rec = z_rec # Store to database database[settings] = { "ell": data["ell"], "tt": data["tt"], "kh": k, "Pkh": Pk, "z_rec": z_rec, } return ClSpectrum(ell[2:], tt[2:]), PkSpectrum(kh, Pkh)
def _run_class(self, **kwargs): """Method to run class and return the lensed and unlensed spectra as dictionaries. Returns ------- cls_l : `dict` Dictionary containing the lensed spectra for a given run of CLASS. cls_u : `dict` Dictionary containing the unlensed spectra for the same run of CLASS. """ cosmo = Class() # Set some parameters we want that are not in the default CLASS setting. class_pars = { 'output': 'tCl pCl lCl', 'modes': 's, t', 'lensing': self.lensing, 'r': self.r, } # Update CLASS run with any kwargs that were passed. This is useful in # Pyranha.compute_cosmology in order to compute the r=1 case. class_pars.update(kwargs) cosmo.set(class_pars) cosmo.compute() # Get the lensed and unlensed spectra as dictionaries. cls_l = cosmo.lensed_cl(2500) cls_u = cosmo.raw_cl(2500) # Do the memory cleanup. cosmo.struct_cleanup() cosmo.empty() return cls_l, cls_u
def getDl( pii1=0.5e-10, pii2=1e-9, pri1=1e-13 ): # Define your cosmology (what is not specified will be set to CLASS default parameters) params = { 'output': 'tCl lCl pCl', 'modes': 's', # scalar perturbations 'lensing': 'yes', 'ic': 'ad&cdi', 'l_max_scalars':max_scalars, 'P_k_ini type': 'two_scales', 'k1': 0.002, 'k2': 0.1, 'P_{RR}^1': 2.34e-9, 'P_{RR}^2': 2.115e-9, 'P_{II}^1' : pii1, 'P_{II}^2' : pii2, 'P_{RI}^1' : pri1} cosmo = Class() cosmo.set(params) cosmo.compute() # print(dir(cosmo)) # use this command to see what is in the cosmo # It is a dictionary that contains the fields: tt, te, ee, bb, pp, tp cls = cosmo.raw_cl(max_l) # Access the cl until l=1000 yy = np.array( cls['ee'][1:] ) zz = np.array( cls['tt'][1:] ) yz = np.array( cls['te'][1:] ) ee = ((ell)*(ell+1) * yy / (2 * math.pi)) tt = ((ell)*(ell+1) * zz / (2 * math.pi)) te = ((ell)*(ell+1) * yz / (2 * math.pi)) cosmo.struct_cleanup() return tt, te, ee
def get_power(params, l_min, l_max): #CLASS gives results in natural units #convert to muK^2 to match data T_cmb = 2.7255e6 #temp in microkelvins #create an instance of CLASS wrapper w/correct params cosmo = Class() cosmo.set(params) #cosmo.set({'output':'tCl,pCl,lCl,mPk','lensing':'yes','P_k_max_1/Mpc':3.0}) cosmo.compute() #lensed cl until l=l_max output = cosmo.raw_cl(l_max) #lensed_cl(l_max) ls = output['ell'][l_min:] Cls = output['tt'][l_min:] Dls = ls * (ls + 1) * Cls * T_cmb**2 / (2 * np.pi) #clean ups cosmo.struct_cleanup() cosmo.empty() return ls, Cls, Dls
# # call CLASS : scalars only # ############### # M = Class() M.set(common_settings) M.set({ 'output': 'tCl,pCl', 'modes': 's', 'lensing': 'no', 'n_s': 0.9660499, 'l_max_scalars': l_max_scalars }) M.compute() cls = M.raw_cl(l_max_scalars) # In[ ]: ############### # # call CLASS : tensors only # ############### # M.empty( ) # reset input parameters to default, before passing a new parameter set M.set(common_settings) M.set({ 'output': 'tCl,pCl', 'modes': 't',
class Model(): def __init__(self, cosmo=None): """ Initialize the Model class. By default Model uses its own Class instance. cosmo = external Class instance. Default is None """ if cosmo: self.cosmo = cosmo else: self.cosmo = Class() self.computed = {} self.texnames = {} def __set_scale(self, axes, xscale, yscale): """ Set scales for axes in axes array. axes = axes array (e.g. f, ax = plt.subplots(2,2)) xscale = linear array of xscale. yscale = linear array of yscale. Scales are set once axes is flatten. Each plot is counted from left to right an from top to bottom. """ for i, ax in enumerate(axes.flat): ax.set_xscale(xscale[i]) ax.set_yscale(yscale[i]) def __set_label(self, axes, xlabel, ylabel): """ Set labels for axes in axes array. axes = axes array (e.g. f, ax = plt.subplots(2,2)) xlabel = linear array of xlabels. ylabel = linear array of ylabels. Labels are set once axes is flatten. Each plot is counted from left to right an from top to bottom. """ for i, ax in enumerate(axes.flat): ax.set_xlabel(xlabel[i]) ax.set_ylabel(ylabel[i]) def __store_cl(self, cl_dic): """ Store cl's as (l*(l+1)/2pi)*cl, which is much more useful. """ ell = cl_dic['ell'][2:] for cl, list_val in cl_dic.iteritems(): list_val = list_val[2:] if (list_val == ell).all(): cl_dic[cl] = list_val continue list_val = (ell * (ell + 1) / (2 * np.pi)) * list_val cl_dic[cl] = list_val # Remove first two null items (l=0,1) return cl_dic def add_derived(self, varied_name, keys, value): """ Add a derived parameter for varied_name dictionary. varied_name = varied variable's name. keys = list of keys in descending level. value = value to store for new dictionary key. """ dic = self.computed[varied_name] for key in keys: if key not in dic: dic[key] = {} dic = dic[key] dic.update(value) def compute_models(self, params, varied_name, index_variable, values, back=[], thermo=[], prim=[], pert=[], trans=[], pk=[0.0001, 0.1, 100], extra=[], update=True, cosmo_msg=False, texname=""): """ Fill dic with the hi_class output structures for the model with given params, modifying the varied_name value with values. params = parameters to be set in Class. They must be in agreement with what is asked for. varied_name = the name of the variable you are modifying. It will be used as key in dic assigned to its background structures. index_variable = variable's index in parameters_smg array. values = varied variable values you want to compute the cosmology for. back = list of variables to store from background. If 'all', store the whole dictionary. thermo = list of variables to store from thermodynamics. If 'all', store the whole dictionary. prim = list of variables to store from primordial. If 'all', store the whole dictionary. pert = list of variables to store from perturbations. If 'all', store the whole dictionary. trans = list of variables to store from transfer. If 'all', store the whole dictionary. get_transfer accept two optional arguments: z=0 and output_format='class' (avaible options are 'class' or 'camb'). If different values are desired, first item of trans must be {'z': value, 'output_format': value}. pk = list with the minimum and maximum k values to store the present matter power spectrum and the number of points [k_min, k_max, number_points]. Default [10^-4, 10^1, 100]. extra = list of any of the method or objects defined in cosmo, e.g. w0_smg(). It will store {'method': cosmo.w0_smg()} update = if True update old computed[key] dictionary elsewise create a new one. Default: True. cosmo_msg = if True, print cosmo.compute() messages. Default: False. """ key = varied_name if texname: self.set_texnames({varied_name: texname}) elif key not in self.texnames: # texname will not be set at this stage. No check required self.set_texnames({varied_name: varied_name}) if (not update) or (key not in self.computed.keys()): self.computed[key] = od() for val in values: # key = "{}={}".format(varied_name, val) params["parameters_smg"] = inip.vary_params(params["parameters_smg"], [[index_variable, val]]) # It might be after the try to not store empty dictionaries. # Nevertheless, I find more useful having them to keep track of # those failed and, perhaps, to implement a method to obtain them # with Omega_smg_debug. d = self.computed[key][val] = {} self.cosmo.empty() self.cosmo.set(params) try: self.cosmo.compute() except Exception, e: print "Error: skipping {}={}".format(key, val) if cosmo_msg: print e continue d['tunned'] = self.cosmo.get_current_derived_parameters(['tuning_parameter'])['tuning_parameter'] for lst in [[back, 'back', self.cosmo.get_background], [thermo, 'thermo', self.cosmo.get_thermodynamics], [prim, 'prim', self.cosmo.get_thermodynamics]]: if lst[0]: output = lst[2]() if lst[0][0] == 'all': d[lst[1]] = output else: d[lst[1]] = {} for item in back: if type(item) is list: d[lst[1]].update({item[0]: output[item[0]][item[1]]}) else: d[lst[1]].update({item: output[item]}) if pert: # Perturbation is tricky because it can accept two optional # argument for get_perturbations and this method returns a # dictionary {'kind_of_pert': [{variable: list_values}]}, where # each item in the list is for a k (chosen in params). if type(pert[0]) is dict: output = self.cosmo.get_perturbations(pert[0]['z'], pert[0]['output_format']) if pert[1] == 'all': d['pert'] = output else: output = self.cosmo.get_perturbations() if pert[0] == 'all': d['pert'] = output if (type(pert[0]) is not dict) and (pert[0] != 'all'): d['pert'] = {} for subkey, lst in output.iteritems(): d['pert'].update({subkey: []}) for n, kdic in enumerate(lst): # Each item is for a k d['pert'][subkey].append({}) for item in pert: if type(item) is list: d['pert'][subkey][n].update({item[0]: kdic[item[0]][item[1]]}) else: d['pert'][subkey][n].update({item: kdic[item]}) for i in extra: exec('d[i] = self.cosmo.{}'.format(i)) try: d['cl'] = self.__store_cl(self.cosmo.raw_cl()) except CosmoSevereError: pass try: d['lcl'] = self.__store_cl(self.cosmo.lensed_cl()) except CosmoSevereError: pass try: d['dcl'] = self.cosmo.density_cl() except CosmoSevereError: pass if ("output" in self.cosmo.pars) and ('mPk' in self.cosmo.pars['output']): k_array = np.linspace(*pk) pk_array = np.array([self.cosmo.pk(k, 0) for k in k_array]) d['pk'] = {'k': k_array, 'pk': pk_array} self.cosmo.struct_cleanup()
class TestClass(unittest.TestCase): """ Testing Class and its wrapper classy on different cosmologies To run it, do ~] nosetest test_class.py It will run many times Class, on different cosmological scenarios, and everytime testing for different output possibilities (none asked, only mPk, etc..) """ @classmethod def setUpClass(cls): cls.faulty_figs_path = os.path.join( os.path.sep.join( os.path.realpath(__file__).split(os.path.sep)[:-1]), 'faulty_figs') if os.path.isdir(cls.faulty_figs_path): shutil.rmtree(cls.faulty_figs_path) os.mkdir(cls.faulty_figs_path) @classmethod def tearDownClass(cls): pass def setUp(self): """ set up data used in the tests. setUp is called before each test function execution. """ self.cosmo = Class() self.cosmo_newt = Class() if CLASS_VERBOSE: self.verbose = { 'input_verbose': 1, 'background_verbose': 1, 'thermodynamics_verbose': 1, 'perturbations_verbose': 1, 'transfer_verbose': 1, 'primordial_verbose': 1, 'harmonic_verbose': 1, 'fourier_verbose': 1, 'lensing_verbose': 1, 'distortions_verbose': 1, 'output_verbose': 1, } else: self.verbose = {} self.scenario = {} def tearDown(self): self.cosmo.struct_cleanup() self.cosmo.empty() self.cosmo = 0 self.cosmo_newt.struct_cleanup() self.cosmo_newt.empty() self.cosmo_newt = 0 del self.scenario def poormansname(self, somedict): string = "_".join( [k + '=' + str(v) for k, v in list(somedict.items())]) string = string.replace('/', '%') string = string.replace(',', '') string = string.replace(' ', '') return string @parameterized.expand(TUPLE_ARRAY, doc_func=custom_name_func, custom_name_func=custom_name_func) @attr('dump_ini_files') def test_Valgrind(self, inputdict): """Dump files""" self.scenario.update(inputdict) self.name = self._testMethodName if self.has_incompatible_input(): return path = os.path.join(self.faulty_figs_path, self.name) self.store_ini_file(path) self.scenario.update({'gauge': 'Newtonian'}) self.store_ini_file(path + 'N') @parameterized.expand(TUPLE_ARRAY, doc_func=custom_name_func, custom_name_func=custom_name_func) @attr('test_scenario') def test_scenario(self, inputdict): """Test scenario""" self.scenario.update(inputdict) self.name = self._testMethodName self.cosmo.set( dict(itertools.chain(self.verbose.items(), self.scenario.items()))) cl_dict = { 'tCl': ['tt'], 'lCl': ['pp'], 'pCl': ['ee', 'bb'], 'nCl': ['dd'], 'sCl': ['ll'], } # 'lensing' is always set to yes. Therefore, trying to compute 'tCl' or # 'pCl' will fail except if we also ask for 'lCl'. if self.has_incompatible_input(): self.assertRaises(CosmoSevereError, self.cosmo.compute) return else: self.cosmo.compute() self.assertTrue(self.cosmo.state, "Class failed to go through all __init__ methods") # Depending if 'output' in self.scenario.keys(): # Positive tests of raw cls output = self.scenario['output'] for elem in output.split(): if elem in cl_dict.keys(): for cl_type in cl_dict[elem]: is_density_cl = (elem == 'nCl' or elem == 'sCl') if is_density_cl: cl = self.cosmo.density_cl(100) else: cl = self.cosmo.raw_cl(100) self.assertIsNotNone(cl, "raw_cl returned nothing") cl_length = np.shape( cl[cl_type][0])[0] if is_density_cl else np.shape( cl[cl_type])[0] self.assertEqual(cl_length, 101, "raw_cl returned wrong size") if elem == 'mPk': pk = self.cosmo.pk(0.1, 0) self.assertIsNotNone(pk, "pk returned nothing") # Negative tests of output functions if not any( [elem in list(cl_dict.keys()) for elem in output.split()]): # testing absence of any Cl self.assertRaises(CosmoSevereError, self.cosmo.raw_cl, 100) if 'mPk' not in output.split(): # testing absence of mPk self.assertRaises(CosmoSevereError, self.cosmo.pk, 0.1, 0) if COMPARE_OUTPUT_REF or COMPARE_OUTPUT_GAUGE: # Now compute same scenario in Newtonian gauge self.cosmo_newt.set( dict(list(self.verbose.items()) + list(self.scenario.items()))) self.cosmo_newt.set({'gauge': 'newtonian'}) self.cosmo_newt.compute() if COMPARE_OUTPUT_GAUGE: # Compare synchronous and Newtonian gauge self.assertTrue( self.cosmo_newt.state, "Class failed to go through all __init__ methods in Newtonian gauge" ) self.compare_output(self.cosmo, "Synchronous", self.cosmo_newt, 'Newtonian', COMPARE_CL_RELATIVE_ERROR_GAUGE, COMPARE_PK_RELATIVE_ERROR_GAUGE) if COMPARE_OUTPUT_REF: # Compute reference models in both gauges and compare cosmo_ref = classyref.Class() cosmo_ref.set(self.cosmo.pars) cosmo_ref.compute() status = self.compare_output(cosmo_ref, "Reference", self.cosmo, 'Synchronous', COMPARE_CL_RELATIVE_ERROR, COMPARE_PK_RELATIVE_ERROR) assert status, 'Reference comparison failed in Synchronous gauge!' cosmo_ref = classyref.Class() cosmo_ref.set(self.cosmo_newt.pars) cosmo_ref.compute() self.compare_output(cosmo_ref, "Reference", self.cosmo_newt, 'Newtonian', COMPARE_CL_RELATIVE_ERROR, COMPARE_PK_RELATIVE_ERROR) assert status, 'Reference comparison failed in Newtonian gauge!' def has_incompatible_input(self): should_fail = False # If we have tensor modes, we must have one tensor observable, # either tCl or pCl. if has_tensor(self.scenario): if 'output' not in list(self.scenario.keys()): should_fail = True else: output = self.scenario['output'].split() if 'tCl' not in output and 'pCl' not in output: should_fail = True # If we have specified lensing, we must have lCl in output, # otherwise lensing will not be read (which is an error). if 'lensing' in list(self.scenario.keys()): if 'output' not in list(self.scenario.keys()): should_fail = True else: output = self.scenario['output'].split() if 'lCl' not in output: should_fail = True elif 'tCl' not in output and 'pCl' not in output: should_fail = True # If we have specified a tensor method, we must have tensors. if 'tensor method' in list(self.scenario.keys()): if not has_tensor(self.scenario): should_fail = True # If we have specified non linear, we must have some form of # perturbations output. if 'non linear' in list(self.scenario.keys()): if 'output' not in list(self.scenario.keys()): should_fail = True # If we ask for Cl's of lensing potential, number counts or cosmic shear, we must have scalar modes. # The same applies to density and velocity transfer functions and the matter power spectrum: if 'output' in self.scenario and 'modes' in self.scenario and self.scenario[ 'modes'].find('s') == -1: requested_output_types = set(self.scenario['output'].split()) for scalar_output_type in [ 'lCl', 'nCl', 'dCl', 'sCl', 'mPk', 'dTk', 'mTk', 'vTk' ]: if scalar_output_type in requested_output_types: should_fail = True break # If we specify initial conditions (for scalar modes), we must have # perturbations and scalar modes. if 'ic' in list(self.scenario.keys()): if 'modes' in list(self.scenario.keys() ) and self.scenario['modes'].find('s') == -1: should_fail = True if 'output' not in list(self.scenario.keys()): should_fail = True # If we use inflation module, we must have scalar modes, # tensor modes, no vector modes and we should only have adiabatic IC: if 'P_k_ini type' in list(self.scenario.keys( )) and self.scenario['P_k_ini type'].find('inflation') != -1: if 'modes' not in list(self.scenario.keys()): should_fail = True else: if self.scenario['modes'].find('s') == -1: should_fail = True if self.scenario['modes'].find('v') != -1: should_fail = True if self.scenario['modes'].find('t') == -1: should_fail = True if 'ic' in list(self.scenario.keys() ) and self.scenario['ic'].find('i') != -1: should_fail = True return should_fail def compare_output(self, reference, reference_name, candidate, candidate_name, rtol_cl, rtol_pk): status_pass = True for elem in ['raw_cl', 'lensed_cl']: # Try to get the elem, but if they were not computed, a # CosmoComputeError should be raised. In this case, ignore the # whole block. try: to_test = getattr(candidate, elem)() except CosmoSevereError: continue ref = getattr(reference, elem)() for key, value in list(ref.items()): if key != 'ell': # For all self spectra, try to compare allclose if key[0] == key[1]: # If it is a 'dd' or 'll', it is a dictionary. if isinstance(value, dict): for subkey in list(value.keys()): try: np.testing.assert_allclose( value[subkey], to_test[key][subkey], rtol=rtol_cl, atol=COMPARE_CL_ABSOLUTE_ERROR) except AssertionError: self.cl_faulty_plot( elem + "_" + key, value[subkey][2:], reference_name, to_test[key][subkey][2:], candidate_name, rtol_cl) except TypeError: self.cl_faulty_plot( elem + "_" + key, value[subkey][2:], reference_name, to_test[key][subkey][2:], candidate_name, rtol_cl) else: try: np.testing.assert_allclose( value, to_test[key], rtol=rtol_cl, atol=COMPARE_CL_ABSOLUTE_ERROR) except (AssertionError, TypeError) as e: self.cl_faulty_plot(elem + "_" + key, value[2:], reference_name, to_test[key][2:], candidate_name, rtol_cl) status_pass = False # For cross-spectra, as there can be zero-crossing, we # instead compare the difference. else: # First, we multiply each array by the biggest value norm = max( np.abs(value).max(), np.abs(to_test[key]).max()) value *= norm to_test[key] *= norm try: np.testing.assert_array_almost_equal(value, to_test[key], decimal=3) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[2:], reference_name, to_test[key][2:], candidate_name, rtol_cl) status_pass = False if 'output' in list(self.scenario.keys()): if self.scenario['output'].find('mPk') != -1: # testing equality of Pk k = np.logspace(-2, log10(self.scenario['P_k_max_1/Mpc']), 50) reference_pk = np.array([reference.pk(elem, 0) for elem in k]) candidate_pk = np.array([candidate.pk(elem, 0) for elem in k]) try: np.testing.assert_allclose(reference_pk, candidate_pk, rtol=rtol_pk, atol=COMPARE_PK_ABSOLUTE_ERROR) except AssertionError: self.pk_faulty_plot(k, reference_pk, reference_name, candidate_pk, candidate_name, rtol_pk) status_pass = False return status_pass def store_ini_file(self, path): parameters = dict( list(self.verbose.items()) + list(self.scenario.items())) with open(path + '.ini', 'w') as param_file: param_file.write('# ' + str(parameters) + '\n') if len(parameters) == 0: # CLASS complains if the .ini file does not do anything. param_file.write('write warnings = yes\n') for key, value in list(parameters.items()): param_file.write(key + " = " + str(value) + '\n') def cl_faulty_plot(self, cl_type, reference, reference_name, candidate, candidate_name, rtol): path = os.path.join(self.faulty_figs_path, self.name) fig, axes = plt.subplots(2, 1, sharex=True) ell = np.arange(max(np.shape(candidate))) + 2 factor = ell * (ell + 1) / (2 * np.pi) if cl_type[-2:] != 'pp' else ell**5 axes[0].plot(ell, factor * reference, label=reference_name) axes[0].plot(ell, factor * candidate, label=candidate_name) axes[1].semilogy(ell, 100 * abs(candidate / reference - 1), label=cl_type) axes[1].axhline(y=100 * rtol, color='k', ls='--') axes[-1].set_xlabel(r'$\ell$') if cl_type[-2:] == 'pp': axes[0].set_ylabel(r'$\ell^5 C_\ell^\mathrm{{{_cl_type}}}$'.format( _cl_type=cl_type[-2:].upper())) else: axes[0].set_ylabel( r'$\ell(\ell + 1)/(2\pi)C_\ell^\mathrm{{{_cl_type}}}$'.format( _cl_type=cl_type[-2:].upper())) axes[1].set_ylabel('Relative error [%]') for ax in axes: ax.legend(loc='upper right') fig.tight_layout() fname = '{}_{}_{}_vs_{}.pdf'.format(path, cl_type, reference_name, candidate_name) fig.savefig(fname, bbox_inches='tight') plt.close(fig) # Store parameters (contained in self.scenario) to text file self.store_ini_file(path) def pk_faulty_plot(self, k, reference, reference_name, candidate, candidate_name, rtol): path = os.path.join(self.faulty_figs_path, self.name) fig, axes = plt.subplots(2, 1, sharex=True) axes[0].loglog(k, k**1.5 * reference, label=reference_name) axes[0].loglog(k, k**1.5 * candidate, label=candidate_name) axes[0].legend(loc='upper right') axes[1].loglog(k, 100 * np.abs(candidate / reference - 1)) axes[1].axhline(y=100 * rtol, color='k', ls='--') axes[-1].set_xlabel(r'$k\quad [\mathrm{Mpc}^{-1}]$') axes[0].set_ylabel(r'$k^\frac{3}{2}P(k)$') axes[1].set_ylabel(r'Relative error [%]') fig.tight_layout() fname = path + '_pk_{}_vs_{}.pdf'.format(reference_name, candidate_name) fig.savefig(fname, bbox_inches='tight') plt.close(fig) # Store parameters (contained in self.scenario) to text file self.store_ini_file(path)
class TestClass(unittest.TestCase): """ Testing Class and its wrapper classy on different cosmologies To run it, do ~] nosetest test_class.py It will run many times Class, on different cosmological scenarios, and everytime testing for different output possibilities (none asked, only mPk, etc..) """ @classmethod def setUpClass(self): self.faulty_figs_path = os.path.join( os.path.sep.join( os.path.realpath(__file__).split(os.path.sep)[:-1]), 'faulty_figs') if os.path.isdir(self.faulty_figs_path): shutil.rmtree(self.faulty_figs_path) os.mkdir(self.faulty_figs_path) @classmethod def tearDownClass(self): pass def setUp(self): """ set up data used in the tests. setUp is called before each test function execution. """ self.cosmo = Class() self.cosmo_newt = Class() self.verbose = { 'input_verbose': 1, 'background_verbose': 1, 'thermodynamics_verbose': 1, 'perturbations_verbose': 1, 'transfer_verbose': 1, 'primordial_verbose': 1, 'spectra_verbose': 1, 'nonlinear_verbose': 1, 'lensing_verbose': 1, 'output_verbose': 1 } self.scenario = {} def tearDown(self): self.cosmo.struct_cleanup() self.cosmo.empty() self.cosmo_newt.struct_cleanup() self.cosmo_newt.empty() del self.scenario def poormansname(self, somedict): string = "_".join( [k + '=' + str(v) for k, v in list(somedict.items())]) string = string.replace('/', '%') string = string.replace(',', '') string = string.replace(' ', '') return string @parameterized.expand(TUPLE_ARRAY) def test_0wrapper_implementation(self, inputdict): """Create a few instances based on different cosmologies""" self.scenario.update(inputdict) self.name = self.poormansname(inputdict) sys.stderr.write('\n\n---------------------------------\n') sys.stderr.write('| Test case %s |\n' % self.name) sys.stderr.write('---------------------------------\n') for key, value in list(self.scenario.items()): sys.stderr.write("%s = %s\n" % (key, value)) sys.stdout.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") setting = self.cosmo.set( dict(list(self.verbose.items()) + list(self.scenario.items()))) self.assertTrue(setting, "Class failed to initialize with input dict") cl_dict = {'tCl': ['tt'], 'lCl': ['pp'], 'pCl': ['ee', 'bb']} density_cl_list = ['nCl', 'sCl'] # 'lensing' is always set to yes. Therefore, trying to compute 'tCl' or # 'pCl' will fail except if we also ask for 'lCl'. The flag # 'should_fail' stores this status. sys.stderr.write('Should') should_fail = self.test_incompatible_input() if should_fail: sys.stderr.write(' fail...\n') else: sys.stderr.write(' not fail...\n') if not should_fail: self.cosmo.compute() else: self.assertRaises(CosmoSevereError, self.cosmo.compute) return self.assertTrue(self.cosmo.state, "Class failed to go through all __init__ methods") if self.cosmo.state: print('--> Class is ready') # Depending if 'output' in list(self.scenario.keys()): # Positive tests of raw cls output = self.scenario['output'] for elem in output.split(): if elem in list(cl_dict.keys()): for cl_type in cl_dict[elem]: sys.stderr.write('--> testing raw_cl for %s\n' % cl_type) cl = self.cosmo.raw_cl(100) self.assertIsNotNone(cl, "raw_cl returned nothing") self.assertEqual( np.shape(cl[cl_type])[0], 101, "raw_cl returned wrong size") # TODO do the same for lensed if 'lCl' is there, and for # density cl if elem == 'mPk': sys.stderr.write('--> testing pk function\n') pk = self.cosmo.pk(0.1, 0) self.assertIsNotNone(pk, "pk returned nothing") # Negative tests of output functions if not any( [elem in list(cl_dict.keys()) for elem in output.split()]): sys.stderr.write('--> testing absence of any Cl\n') self.assertRaises(CosmoSevereError, self.cosmo.raw_cl, 100) if 'mPk' not in output.split(): sys.stderr.write('--> testing absence of mPk\n') self.assertRaises(CosmoSevereError, self.cosmo.pk, 0.1, 0) if COMPARE_OUTPUT: # Now, compute with Newtonian gauge, and compare the results self.cosmo_newt.set( dict(list(self.verbose.items()) + list(self.scenario.items()))) self.cosmo_newt.set({'gauge': 'newtonian'}) self.cosmo_newt.compute() # Check that the computation worked self.assertTrue( self.cosmo_newt.state, "Class failed to go through all __init__ methods in Newtonian gauge" ) self.compare_output(self.cosmo, self.cosmo_newt) def test_incompatible_input(self): should_fail = False # If we have tensor modes, we must have one tensor observable, # either tCl or pCl. if has_tensor(self.scenario): if 'output' not in list(self.scenario.keys()): should_fail = True else: output = self.scenario['output'].split() if 'tCl' not in output and 'pCl' not in output: should_fail = True # If we have specified lensing, we must have lCl in output, # otherwise lensing will not be read (which is an error). if 'lensing' in list(self.scenario.keys()): if 'output' not in list(self.scenario.keys()): should_fail = True else: output = self.scenario['output'].split() if 'lCl' not in output: should_fail = True elif 'tCl' not in output and 'pCl' not in output: should_fail = True # If we have specified a tensor method, we must have tensors. if 'tensor method' in list(self.scenario.keys()): if not has_tensor(self.scenario): should_fail = True # If we have specified non linear, we must have some form of # perturbations output. if 'non linear' in list(self.scenario.keys()): if 'output' not in list(self.scenario.keys()): should_fail = True # If we ask for Cl's of lensing potential, we must have scalar modes. if 'output' in list(self.scenario.keys() ) and 'lCl' in self.scenario['output'].split(): if 'modes' in list(self.scenario.keys() ) and self.scenario['modes'].find('s') == -1: should_fail = True # If we specify initial conditions (for scalar modes), we must have # perturbations and scalar modes. if 'ic' in list(self.scenario.keys()): if 'modes' in list(self.scenario.keys() ) and self.scenario['modes'].find('s') == -1: should_fail = True if 'output' not in list(self.scenario.keys()): should_fail = True # If we use inflation module, we must have scalar modes, # tensor modes, no vector modes and we should only have adiabatic IC: if 'P_k_ini type' in list(self.scenario.keys( )) and self.scenario['P_k_ini type'].find('inflation') != -1: if 'modes' not in list(self.scenario.keys()): should_fail = True else: if self.scenario['modes'].find('s') == -1: should_fail = True if self.scenario['modes'].find('v') != -1: should_fail = True if self.scenario['modes'].find('t') == -1: should_fail = True if 'ic' in list(self.scenario.keys() ) and self.scenario['ic'].find('i') != -1: should_fail = True return should_fail def compare_output(self, reference, candidate): sys.stderr.write('\n\n---------------------------------\n') sys.stderr.write('| Comparing synch and Newt: |\n') sys.stderr.write('---------------------------------\n') for elem in ['raw_cl', 'lensed_cl', 'density_cl']: # Try to get the elem, but if they were not computed, a # CosmoComputeError should be raised. In this case, ignore the # whole block. try: to_test = getattr(candidate, elem)() except CosmoSevereError: continue ref = getattr(reference, elem)() for key, value in list(ref.items()): if key != 'ell': sys.stderr.write('--> testing equality of %s %s\n' % (elem, key)) # For all self spectra, try to compare allclose if key[0] == key[1]: # If it is a 'dd' or 'll', it is a dictionary. if isinstance(value, dict): for subkey in list(value.keys()): try: np.testing.assert_allclose( value[subkey], to_test[key][subkey], rtol=1e-03, atol=1e-20) except AssertionError: self.cl_faulty_plot( elem + "_" + key, value[subkey][2:], to_test[key][subkey][2:]) except TypeError: self.cl_faulty_plot( elem + "_" + key, value[subkey][2:], to_test[key][subkey][2:]) else: try: np.testing.assert_allclose(value, to_test[key], rtol=1e-03, atol=1e-20) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) except TypeError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) # For cross-spectra, as there can be zero-crossing, we # instead compare the difference. else: # First, we multiply each array by the biggest value norm = max( np.abs(value).max(), np.abs(to_test[key]).max()) value *= norm to_test[key] *= norm try: np.testing.assert_array_almost_equal(value, to_test[key], decimal=3) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) if 'output' in list(self.scenario.keys()): if self.scenario['output'].find('mPk') != -1: sys.stderr.write('--> testing equality of Pk') k = np.logspace(-2, log10(self.scenario['P_k_max_1/Mpc'])) reference_pk = np.array([reference.pk(elem, 0) for elem in k]) candidate_pk = np.array([candidate.pk(elem, 0) for elem in k]) try: np.testing.assert_allclose(reference_pk, candidate_pk, rtol=5e-03, atol=1e-20) except AssertionError: self.pk_faulty_plot(k, reference_pk, candidate_pk) def cl_faulty_plot(self, cl_type, reference, candidate): path = os.path.join(self.faulty_figs_path, self.name) fig = plt.figure() ax_lin = plt.subplot(211) ax_log = plt.subplot(212) ell = np.arange(max(np.shape(candidate))) + 2 ax_lin.plot(ell, 1 - candidate / reference) ax_log.loglog(ell, abs(1 - candidate / reference)) ax_lin.set_xlabel('l') ax_log.set_xlabel('l') ax_lin.set_ylabel('1-candidate/reference') ax_log.set_ylabel('abs(1-candidate/reference)') ax_lin.set_title(self.name) ax_log.set_title(self.name) ax_lin.legend([cl_type]) ax_log.legend([cl_type]) fig.savefig(path + '_' + cl_type + '.pdf') # Store parameters (contained in self.scenario) to text file parameters = dict( list(self.verbose.items()) + list(self.scenario.items())) with open(path + '.ini', 'w') as param_file: for key, value in list(parameters.items()): param_file.write(key + " = " + str(value) + '\n') def pk_faulty_plot(self, k, reference, candidate): path = os.path.join(self.faulty_figs_path, self.name) fig = plt.figure() ax_lin = plt.subplot(211) ax_log = plt.subplot(212) ax_lin.plot(k, 1 - candidate / reference) ax_log.loglog(k, abs(1 - candidate / reference)) ax_lin.set_xlabel('k') ax_log.set_xlabel('k') ax_lin.set_ylabel('1-candidate/reference') ax_log.set_ylabel('abs(1-candidate/reference)') ax_lin.set_title(self.name) ax_log.set_title(self.name) ax_lin.legend('$P_k$') ax_log.legend('$P_k$') fig.savefig(path + '_' + 'pk' + '.pdf') # Store parameters (contained in self.scenario) to text file parameters = dict( list(self.verbose.items()) + list(self.scenario.items())) with open(path + '.ini', 'w') as param_file: for key, value in list(parameters.items()): param_file.write(key + " = " + str(value) + '\n')
class TestClass(unittest.TestCase): """ Testing Class and its wrapper classy on different cosmologies To run it, do ~] nosetest test_class.py It will run many times Class, on different cosmological scenarios, and everytime testing for different output possibilities (none asked, only mPk, etc..) """ def setUp(self): """ set up data used in the tests. setUp is called before each test function execution. """ self.cosmo = Class() self.verbose = { "input_verbose": 1, "background_verbose": 1, "thermodynamics_verbose": 1, "perturbations_verbose": 1, "transfer_verbose": 1, "primordial_verbose": 1, "spectra_verbose": 1, "nonlinear_verbose": 1, "lensing_verbose": 1, "output_verbose": 1, } self.scenario = {"lensing": "yes"} def tearDown(self): self.cosmo.struct_cleanup() self.cosmo.empty() del self.scenario @parameterized.expand( itertools.product( ("LCDM", "Mnu", "Positive_Omega_k", "Negative_Omega_k", "Isocurvature_modes"), ( {"output": ""}, {"output": "mPk"}, {"output": "tCl"}, {"output": "tCl pCl lCl"}, {"output": "mPk tCl lCl", "P_k_max_h/Mpc": 10}, {"output": "nCl sCl"}, {"output": "tCl pCl lCl nCl sCl"}, ), ({"gauge": "newtonian"}, {"gauge": "sync"}), ({}, {"non linear": "halofit"}), ) ) def test_wrapper_implementation(self, name, scenario, gauge, nonlinear): """Create a few instances based on different cosmologies""" if name == "Mnu": self.scenario.update({"N_ncdm": 1, "m_ncdm": 0.06}) elif name == "Positive_Omega_k": self.scenario.update({"Omega_k": 0.01}) elif name == "Negative_Omega_k": self.scenario.update({"Omega_k": -0.01}) elif name == "Isocurvature_modes": self.scenario.update({"ic": "ad,nid,cdi", "c_ad_cdi": -0.5}) self.scenario.update(scenario) if scenario != {}: self.scenario.update(gauge) self.scenario.update(nonlinear) sys.stderr.write("\n\n---------------------------------\n") sys.stderr.write("| Test case %s |\n" % name) sys.stderr.write("---------------------------------\n") for key, value in self.scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") setting = self.cosmo.set(dict(self.verbose.items() + self.scenario.items())) self.assertTrue(setting, "Class failed to initialize with input dict") cl_list = ["tCl", "lCl", "pCl", "nCl", "sCl"] # Depending on the cases, the compute should fail or not should_fail = True output = self.scenario["output"].split() for elem in output: if elem in ["tCl", "pCl"]: for elem2 in output: if elem2 == "lCl": should_fail = False break if not should_fail: self.cosmo.compute() else: self.assertRaises(CosmoSevereError, self.cosmo.compute) return self.assertTrue(self.cosmo.state, "Class failed to go through all __init__ methods") if self.cosmo.state: print "--> Class is ready" # Depending if "output" in self.scenario.keys(): # Positive tests output = self.scenario["output"] for elem in output.split(): if elem in cl_list: print "--> testing raw_cl function" cl = self.cosmo.raw_cl(100) self.assertIsNotNone(cl, "raw_cl returned nothing") self.assertEqual(np.shape(cl["tt"])[0], 101, "raw_cl returned wrong size") if elem == "mPk": print "--> testing pk function" pk = self.cosmo.pk(0.1, 0) self.assertIsNotNone(pk, "pk returned nothing") # Negative tests of output functions if not any([elem in cl_list for elem in output.split()]): print "--> testing absence of any Cl" self.assertRaises(CosmoSevereError, self.cosmo.raw_cl, 100) if "mPk" not in self.scenario["output"].split(): print "--> testing absence of mPk" # args = (0.1, 0) self.assertRaises(CosmoSevereError, self.cosmo.pk, 0.1, 0) @parameterized.expand( itertools.product(("massless", "massive", "both"), ("photons", "massless", "exact"), ("t", "s, t")) ) def test_tensors(self, scenario, method, modes): """Test the new tensor mode implementation""" self.scenario = {} if scenario == "massless": self.scenario.update({"N_eff": 3.046, "N_ncdm": 0}) elif scenario == "massiv": self.scenario.update({"N_eff": 0, "N_ncdm": 2, "m_ncdm": "0.03, 0.04", "deg_ncdm": "2, 1"}) elif scenario == "both": self.scenario.update({"N_eff": 1.5, "N_ncdm": 2, "m_ncdm": "0.03, 0.04", "deg_ncdm": "1, 0.5"}) sys.stderr.write("\n\n---------------------------------\n") sys.stderr.write("| Test case: %s %s %s |\n" % (scenario, method, modes)) sys.stderr.write("---------------------------------\n") self.scenario.update({"tensor method": method, "modes": modes, "output": "tCl, pCl"}) for key, value in self.scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") self.cosmo.set(dict(self.verbose.items() + self.scenario.items())) self.cosmo.compute() @parameterized.expand(itertools.izip(powerset(["100*theta_s", "Omega_dcdmdr"]), powerset([1.04, 0.20]))) def test_shooting_method(self, variables, values): Omega_cdm = 0.25 scenario = {"Omega_b": 0.05} for variable, value in zip(variables, values): scenario.update({variable: value}) if "Omega_dcdmdr" in variables: scenario.update({"Gamma_dcdm": 100, "Omega_cdm": Omega_cdm - scenario["Omega_dcdmdr"]}) else: scenario.update({"Omega_cdm": Omega_cdm}) sys.stderr.write("\n\n---------------------------------\n") sys.stderr.write("| Test shooting: %s |\n" % (", ".join(variables))) sys.stderr.write("---------------------------------\n") for key, value in scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") scenario.update(self.verbose) self.assertTrue(self.cosmo.set(scenario), "Class failed to initialise with this input") self.assertRaises self.cosmo.compute() # Now, check that the values are properly extracted for variable, value in zip(variables, values): if variable == "100*theta_s": computed_value = self.cosmo.get_current_derived_parameters([variable])[variable] self.assertAlmostEqual(value, computed_value, places=5)
class TestClass(unittest.TestCase): """ Testing Class and its wrapper classy on different cosmologies To run it, do ~] nosetest test_class.py It will run many times Class, on different cosmological scenarios, and everytime testing for different output possibilities (none asked, only mPk, etc..) """ @classmethod def setUpClass(self): self.faulty_figs_path = os.path.join( os.path.sep.join(os.path.realpath(__file__).split(os.path.sep)[:-1]), "faulty_figs" ) if os.path.isdir(self.faulty_figs_path): shutil.rmtree(self.faulty_figs_path) os.mkdir(self.faulty_figs_path) @classmethod def tearDownClass(self): pass def setUp(self): """ set up data used in the tests. setUp is called before each test function execution. """ self.cosmo = Class() self.cosmo_newt = Class() self.verbose = { "input_verbose": 1, "background_verbose": 1, "thermodynamics_verbose": 1, "perturbations_verbose": 1, "transfer_verbose": 1, "primordial_verbose": 1, "spectra_verbose": 1, "nonlinear_verbose": 1, "lensing_verbose": 1, "output_verbose": 1, } self.scenario = {} def tearDown(self): self.cosmo.struct_cleanup() self.cosmo.empty() self.cosmo_newt.struct_cleanup() self.cosmo_newt.empty() del self.scenario def poormansname(self, somedict): string = "_".join([k + "=" + str(v) for k, v in somedict.iteritems()]) string = string.replace("/", "%") string = string.replace(",", "") string = string.replace(" ", "") return string @parameterized.expand(TUPLE_ARRAY) def test_0wrapper_implementation(self, inputdict): """Create a few instances based on different cosmologies""" self.scenario.update(inputdict) self.name = self.poormansname(inputdict) sys.stderr.write("\n\n---------------------------------\n") sys.stderr.write("| Test case %s |\n" % self.name) sys.stderr.write("---------------------------------\n") for key, value in self.scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stdout.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") setting = self.cosmo.set(dict(self.verbose.items() + self.scenario.items())) self.assertTrue(setting, "Class failed to initialize with input dict") cl_dict = {"tCl": ["tt"], "lCl": ["pp"], "pCl": ["ee", "bb"]} density_cl_list = ["nCl", "sCl"] # 'lensing' is always set to yes. Therefore, trying to compute 'tCl' or # 'pCl' will fail except if we also ask for 'lCl'. The flag # 'should_fail' stores this status. sys.stderr.write("Should") should_fail = self.test_incompatible_input() if should_fail: sys.stderr.write(" fail...\n") else: sys.stderr.write(" not fail...\n") if not should_fail: self.cosmo.compute() else: self.assertRaises(CosmoSevereError, self.cosmo.compute) return self.assertTrue(self.cosmo.state, "Class failed to go through all __init__ methods") if self.cosmo.state: print "--> Class is ready" # Depending if "output" in self.scenario.keys(): # Positive tests of raw cls output = self.scenario["output"] for elem in output.split(): if elem in cl_dict.keys(): for cl_type in cl_dict[elem]: sys.stderr.write("--> testing raw_cl for %s\n" % cl_type) cl = self.cosmo.raw_cl(100) self.assertIsNotNone(cl, "raw_cl returned nothing") self.assertEqual(np.shape(cl[cl_type])[0], 101, "raw_cl returned wrong size") # TODO do the same for lensed if 'lCl' is there, and for # density cl if elem == "mPk": sys.stderr.write("--> testing pk function\n") pk = self.cosmo.pk(0.1, 0) self.assertIsNotNone(pk, "pk returned nothing") # Negative tests of output functions if not any([elem in cl_dict.keys() for elem in output.split()]): sys.stderr.write("--> testing absence of any Cl\n") self.assertRaises(CosmoSevereError, self.cosmo.raw_cl, 100) if "mPk" not in output.split(): sys.stderr.write("--> testing absence of mPk\n") self.assertRaises(CosmoSevereError, self.cosmo.pk, 0.1, 0) if COMPARE_OUTPUT: # Now, compute with Newtonian gauge, and compare the results self.cosmo_newt.set(dict(self.verbose.items() + self.scenario.items())) self.cosmo_newt.set({"gauge": "newtonian"}) self.cosmo_newt.compute() # Check that the computation worked self.assertTrue(self.cosmo_newt.state, "Class failed to go through all __init__ methods in Newtonian gauge") self.compare_output(self.cosmo, self.cosmo_newt) def test_incompatible_input(self): should_fail = False # If we have tensor modes, we must have one tensor observable, # either tCl or pCl. if has_tensor(self.scenario): if "output" not in self.scenario.keys(): should_fail = True else: output = self.scenario["output"].split() if "tCl" not in output and "pCl" not in output: should_fail = True # If we have specified lensing, we must have lCl in output, # otherwise lensing will not be read (which is an error). if "lensing" in self.scenario.keys(): if "output" not in self.scenario.keys(): should_fail = True else: output = self.scenario["output"].split() if "lCl" not in output: should_fail = True elif "tCl" not in output and "pCl" not in output: should_fail = True # If we have specified a tensor method, we must have tensors. if "tensor method" in self.scenario.keys(): if not has_tensor(self.scenario): should_fail = True # If we have specified non linear, we must have some form of # perturbations output. if "non linear" in self.scenario.keys(): if "output" not in self.scenario.keys(): should_fail = True # If we ask for Cl's of lensing potential, we must have scalar modes. if "output" in self.scenario.keys() and "lCl" in self.scenario["output"].split(): if "modes" in self.scenario.keys() and self.scenario["modes"].find("s") == -1: should_fail = True # If we specify initial conditions (for scalar modes), we must have # perturbations and scalar modes. if "ic" in self.scenario.keys(): if "modes" in self.scenario.keys() and self.scenario["modes"].find("s") == -1: should_fail = True if "output" not in self.scenario.keys(): should_fail = True # If we use inflation module, we must have scalar modes, # tensor modes, no vector modes and we should only have adiabatic IC: if "P_k_ini type" in self.scenario.keys() and self.scenario["P_k_ini type"].find("inflation") != -1: if "modes" not in self.scenario.keys(): should_fail = True else: if self.scenario["modes"].find("s") == -1: should_fail = True if self.scenario["modes"].find("v") != -1: should_fail = True if self.scenario["modes"].find("t") == -1: should_fail = True if "ic" in self.scenario.keys() and self.scenario["ic"].find("i") != -1: should_fail = True return should_fail def compare_output(self, reference, candidate): sys.stderr.write("\n\n---------------------------------\n") sys.stderr.write("| Comparing synch and Newt: |\n") sys.stderr.write("---------------------------------\n") for elem in ["raw_cl", "lensed_cl", "density_cl"]: # Try to get the elem, but if they were not computed, a # CosmoComputeError should be raised. In this case, ignore the # whole block. try: to_test = getattr(candidate, elem)() except CosmoSevereError: continue ref = getattr(reference, elem)() for key, value in ref.iteritems(): if key != "ell": sys.stderr.write("--> testing equality of %s %s\n" % (elem, key)) # For all self spectra, try to compare allclose if key[0] == key[1]: # If it is a 'dd' or 'll', it is a dictionary. if isinstance(value, dict): for subkey in value.iterkeys(): try: np.testing.assert_allclose( value[subkey], to_test[key][subkey], rtol=1e-03, atol=1e-20 ) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[subkey][2:], to_test[key][subkey][2:]) except TypeError: self.cl_faulty_plot(elem + "_" + key, value[subkey][2:], to_test[key][subkey][2:]) else: try: np.testing.assert_allclose(value, to_test[key], rtol=1e-03, atol=1e-20) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) except TypeError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) # For cross-spectra, as there can be zero-crossing, we # instead compare the difference. else: # First, we multiply each array by the biggest value norm = max(np.abs(value).max(), np.abs(to_test[key]).max()) value *= norm to_test[key] *= norm try: np.testing.assert_array_almost_equal(value, to_test[key], decimal=3) except AssertionError: self.cl_faulty_plot(elem + "_" + key, value[2:], to_test[key][2:]) if "output" in self.scenario.keys(): if self.scenario["output"].find("mPk") != -1: sys.stderr.write("--> testing equality of Pk") k = np.logspace(-2, log10(self.scenario["P_k_max_1/Mpc"])) reference_pk = np.array([reference.pk(elem, 0) for elem in k]) candidate_pk = np.array([candidate.pk(elem, 0) for elem in k]) try: np.testing.assert_allclose(reference_pk, candidate_pk, rtol=5e-03, atol=1e-20) except AssertionError: self.pk_faulty_plot(k, reference_pk, candidate_pk) def cl_faulty_plot(self, cl_type, reference, candidate): path = os.path.join(self.faulty_figs_path, self.name) fig = plt.figure() ax_lin = plt.subplot(211) ax_log = plt.subplot(212) ell = np.arange(max(np.shape(candidate))) + 2 ax_lin.plot(ell, 1 - candidate / reference) ax_log.loglog(ell, abs(1 - candidate / reference)) ax_lin.set_xlabel("l") ax_log.set_xlabel("l") ax_lin.set_ylabel("1-candidate/reference") ax_log.set_ylabel("abs(1-candidate/reference)") ax_lin.set_title(self.name) ax_log.set_title(self.name) ax_lin.legend([cl_type]) ax_log.legend([cl_type]) fig.savefig(path + "_" + cl_type + ".pdf") # Store parameters (contained in self.scenario) to text file parameters = dict(self.verbose.items() + self.scenario.items()) with open(path + ".ini", "w") as param_file: for key, value in parameters.iteritems(): param_file.write(key + " = " + str(value) + "\n") def pk_faulty_plot(self, k, reference, candidate): path = os.path.join(self.faulty_figs_path, self.name) fig = plt.figure() ax_lin = plt.subplot(211) ax_log = plt.subplot(212) ax_lin.plot(k, 1 - candidate / reference) ax_log.loglog(k, abs(1 - candidate / reference)) ax_lin.set_xlabel("k") ax_log.set_xlabel("k") ax_lin.set_ylabel("1-candidate/reference") ax_log.set_ylabel("abs(1-candidate/reference)") ax_lin.set_title(self.name) ax_log.set_title(self.name) ax_lin.legend("$P_k$") ax_log.legend("$P_k$") fig.savefig(path + "_" + "pk" + ".pdf") # Store parameters (contained in self.scenario) to text file parameters = dict(self.verbose.items() + self.scenario.items()) with open(path + ".ini", "w") as param_file: for key, value in parameters.iteritems(): param_file.write(key + " = " + str(value) + "\n")
class classy(SlikPlugin): """ Compute the CMB power spectrum with CLASS. Based on work by: Brent Follin, Teresa Hamill """ #{cosmoslik name : class name} name_mapping = { 'As': 'A_s', 'lmax': 'l_max_scalars', 'mnu': 'm_ncdm', 'Neff': 'N_ncdm', 'ns': 'n_s', 'nt': 'n_t', 'ombh2': 'omega_b', 'omch2': 'omega_cdm', 'omk': 'Omega_k', 'pivot_scalar': 'k_pivot', 'r': 'r', 'tau': 'tau_reio', 'Tcmb': 'T_cmb', 'Yp': 'YHe', } def __init__(self, **defaults): super().__init__() from classy import Class self.model = Class() self.defaults = defaults def convert_params(self, **params): """ Convert from CosmoSlik params to CLASS """ params = {self.name_mapping.get(k, k): v for k, v in params.items()} if 'theta' in params: params['100*theta_s'] = 100 * params.pop('theta') params['lensing'] = 'yes' if params.pop('DoLensing', True) else 'no' return params def __call__(self, As=None, DoLensing=True, H0=None, lmax=None, mnu=None, Neff=None, nrun=None, ns=None, ombh2=None, omch2=None, omk=None, output='tCl, lCl, pCl', pivot_scalar=None, r=None, tau=None, Tcmb=2.7255, theta=None, w=None, Yp=None, nowarn=False, **kwargs): if not nowarn and kwargs: print('Warning: passing unknown parameters to CLASS: ' + str(kwargs) + ' (set nowarn=True to turn off this message.)') params = dict( self.defaults, **{ k: v for k, v in arguments(include_kwargs=False, exclude=["nowarn"]).items() if v is not None }) self.model.set(self.convert_params(**params)) self.model.compute() lmax = params['lmax'] ell = arange(lmax + 1) if params['DoLensing'] == True: self.cmb_result = { x: (self.model.lensed_cl(lmax)[x.lower()]) * Tcmb**2 * 1e12 * ell * (ell + 1) / 2 / pi for x in ['TT', 'TE', 'EE', 'BB', 'PP', 'TP'] } else: self.cmb_result = { x: (self.model.raw_cl(lmax)[x.lower()]) * Tcmb**2 * 1e12 * ell * (ell + 1) / 2 / pi for x in ['TT'] } self.model.struct_cleanup() self.model.empty() return self.cmb_result def get_bao_observables(self, z): return { 'H': self.model.Hubble(z), 'D_A': self.model.angular_distance(z), 'c': 1.0, 'r_d': (self.model.get_current_derived_parameters(['rs_rec']))['rs_rec'] }
# Create an instance of the CLASS wrapper cosmo = Class() # Set the parameters to the cosmological code cosmo.set(params) # Run the whole code. Depending on your output, it will call the # CLASS modules more or less fast. For instance, without any # output asked, CLASS will only compute background quantities, # thus running almost instantaneously. # This is equivalent to the beginning of the `main` routine of CLASS, # with all the struct_init() methods called. cosmo.compute() print dir(cosmo) # Access the lensed cl until l=2000 cls = cosmo.raw_cl(5000) # cls = cosmo.lensed_cl(5000) import healpy as hp import pylab as pl CMB = hp.synfast(cls['tt'], nside=128) print CMB print cls['tt'] hp.mollview(CMB) pl.show() exit() # Print on screen to see the output print cls # It is a dictionnary that contains the fields: tt, te, ee, bb, pp, tp
# In[ ]: ################ # # call CLASS again for the perturbations (will compute transfer functions at input value z_rec) # ################ M.empty() # reset input parameters to default, before passing a new parameter set M.set(common_settings) M.set({'z_pk':z_rec}) M.compute() # # save the total Cl's (we will plot them in the last step) # cl_tot = M.raw_cl(5000) # # # load transfer functions at recombination # one_time = M.get_transfer(z_rec) print (one_time.keys()) k = one_time['k (h/Mpc)'] Theta0 = 0.25*one_time['d_g'] phi = one_time['phi'] psi = one_time['psi'] theta_b = one_time['t_b'] # compute related quantitites R = 3./4.*M.Omega_b()/M.Omega_g()/(1+z_rec) # R = 3/4 * (rho_b/rho_gamma) at z_rec zero_point = -(1.+R)*psi # zero point of oscillations: -(1.+R)*psi Theta0_amp = max(Theta0.max(),-Theta0.min()) # Theta0 oscillation amplitude (for vertical scale of plot)
# ############### # # scalars only # M = Class() M.set(common_settings) M.set({ 'output': 'tCl,pCl', 'modes': 's', 'lensing': 'no', 'n_s': 0.9619, 'l_max_scalars': 3000 }) M.compute() cls = M.raw_cl(3000) M.struct_cleanup() M.empty() # # tensors only # M = Class() M.set(common_settings) l_max_tensors = 600 M.set({ 'output': 'tCl,pCl', 'modes': 't', 'lensing': 'no', 'r': 0.1, 'n_t': 0, 'l_max_tensors': l_max_tensors
(thetarad100**2) / (8 * np.log(2))) + ((thetaarcmin217 * sigmaP217)**(-2)) * np.exp(-l * (l + 1) * (thetarad217**2) / (8 * np.log(2))) + ((thetaarcmin353 * sigmaP353)**(-2)) * np.exp(-l * (l + 1) * (thetarad353**2) / (8 * np.log(2))))**(-1) # Theory Cls cosmo = Class() cosmo.set(params) cosmo.compute() fullcl = cosmo.raw_cl(lmax) #plt.loglog(fullcl['ell'][2:], dnoise(fullcl['ell'][2:]), label="Noise") #plt.loglog(fullcl['ell'][2:], dnoise_full(fullcl['ell'][2:]), label="Noise full") plt.loglog(fullcl['ell'][2:], factor * fullcl['tt'][2:], label="Temp") plt.legend() plt.show() #quit() TT = factor * fullcl['tt'][2:] + dnoise(fullcl['ell'][2:]) EE = factor * fullcl['ee'][2:] + dnoiseP(fullcl['ell'][2:]) TE = factor * fullcl['te'][2:] TT2 = TT**2 EE2 = EE**2 TE2 = TE**2 #### Fisher matrix ####
class TestClass(unittest.TestCase): """ Testing Class and its wrapper classy on different cosmologies To run it, do ~] nosetest test_class.py It will run many times Class, on different cosmological scenarios, and everytime testing for different output possibilities (none asked, only mPk, etc..) """ def setUp(self): """ set up data used in the tests. setUp is called before each test function execution. """ self.cosmo = Class() self.verbose = { 'background_verbose': 1, 'thermodynamics_verbose': 1, 'perturbations_verbose': 1, 'transfer_verbose': 1, 'primordial_verbose': 1, 'spectra_verbose': 1, 'nonlinear_verbose': 1, 'lensing_verbose': 1, 'output_verbose': 1} self.scenario = {'lensing':'yes'} def tearDown(self): self.cosmo.struct_cleanup() self.cosmo.empty() del self.scenario @parameterized.expand( itertools.product( ('LCDM', 'Mnu', 'Positive_Omega_k', 'Negative_Omega_k', 'Isocurvature_modes', ), ({'output': ''}, {'output': 'mPk'}, {'output': 'tCl'}, {'output': 'tCl pCl lCl'}, {'output': 'mPk tCl lCl', 'P_k_max_h/Mpc':10}, {'output': 'nCl sCl'}, {'output': 'tCl pCl lCl nCl sCl'}), ({'gauge': 'newtonian'}, {'gauge': 'sync'}), ({}, {'non linear': 'halofit'}))) def test_parameters(self, name, scenario, gauge, nonlinear): """Create a few instances based on different cosmologies""" if name == 'Mnu': self.scenario.update({'N_ncdm': 1, 'm_ncdm': 0.06}) elif name == 'Positive_Omega_k': self.scenario.update({'Omega_k': 0.01}) elif name == 'Negative_Omega_k': self.scenario.update({'Omega_k': -0.01}) elif name == 'Isocurvature_modes': self.scenario.update({'ic': 'ad,nid,cdi', 'c_ad_cdi': -0.5}) self.scenario.update(scenario) if scenario != {}: self.scenario.update(gauge) self.scenario.update(nonlinear) sys.stderr.write('\n\n---------------------------------\n') sys.stderr.write('| Test case %s |\n' % name) sys.stderr.write('---------------------------------\n') for key, value in self.scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") setting = self.cosmo.set( dict(self.verbose.items()+self.scenario.items())) self.assertTrue(setting, "Class failed to initialize with input dict") cl_list = ['tCl', 'lCl', 'pCl', 'nCl', 'sCl'] # Depending on the cases, the compute should fail or not should_fail = True output = self.scenario['output'].split() for elem in output: if elem in ['tCl', 'pCl']: for elem2 in output: if elem2 == 'lCl': should_fail = False break if not should_fail: self.cosmo.compute() else: self.assertRaises(CosmoSevereError, self.cosmo.compute) return self.assertTrue( self.cosmo.state, "Class failed to go through all __init__ methods") if self.cosmo.state: print '--> Class is ready' # Depending if 'output' in self.scenario.keys(): # Positive tests output = self.scenario['output'] for elem in output.split(): if elem in cl_list: print '--> testing raw_cl function' cl = self.cosmo.raw_cl(100) self.assertIsNotNone(cl, "raw_cl returned nothing") self.assertEqual( np.shape(cl['tt'])[0], 101, "raw_cl returned wrong size") if elem == 'mPk': print '--> testing pk function' pk = self.cosmo.pk(0.1, 0) self.assertIsNotNone(pk, "pk returned nothing") # Negative tests of output functions if not any([elem in cl_list for elem in output.split()]): print '--> testing absence of any Cl' self.assertRaises(CosmoSevereError, self.cosmo.raw_cl, 100) if 'mPk' not in self.scenario['output'].split(): print '--> testing absence of mPk' #args = (0.1, 0) self.assertRaises(CosmoSevereError, self.cosmo.pk, 0.1, 0) print '~~~~~~~~ passed ? ' @parameterized.expand( itertools.product( ('massless', 'massive', 'both'), ('photons', 'massless', 'exact'), ('t', 's, t'))) def test_tensors(self, scenario, method, modes): """Test the new tensor mode implementation""" self.scenario = {} if scenario == 'massless': self.scenario.update({'N_eff': 3.046, 'N_ncdm':0}) elif scenario == 'massiv': self.scenario.update( {'N_eff': 0, 'N_ncdm': 2, 'm_ncdm': '0.03, 0.04', 'deg_ncdm': '2, 1'}) elif scenario == 'both': self.scenario.update( {'N_eff': 1.5, 'N_ncdm': 2, 'm_ncdm': '0.03, 0.04', 'deg_ncdm': '1, 0.5'}) self.scenario.update({ 'tensor method': method, 'modes': modes, 'output': 'tCl, pCl'}) for key, value in self.scenario.iteritems(): sys.stderr.write("%s = %s\n" % (key, value)) sys.stderr.write("\n") self.cosmo.set( dict(self.verbose.items()+self.scenario.items())) self.cosmo.compute()
'omega_b': 0.022032, 'omega_cdm': 0.12038, 'h': 0.67556, 'A_s': 2.215e-9, 'tau_reio': 0.0925, 'ic': 'niv' }) LambdaCDM.set({ 'output': 'tCl,pCl,lCl,mPk', 'lensing': 'yes', 'P_k_max_1/Mpc': 3.0 }) # run class LambdaCDM.compute() # get all C_l output cls = LambdaCDM.raw_cl(2500) # To check the format of cls # ~cls.viewkeys() ll = cls['ell'][3:] clTT = cls['tt'][3:] clEE = cls['ee'][3:] clPP = cls['pp'][3:] # create instance of the class "Class" LambdaCDM1 = Class() # pass input parameters LambdaCDM1.set({ 'omega_b': 0.022032, 'omega_cdm': 0.12038, 'h': 0.67556,
'omega_cdm':0.12038, 'A_s':2.215e-9, 'n_s':0.9619, 'tau_reio':0.0925, # Take fixed value for primordial Helium (instead of automatic BBN adjustment) 'YHe':0.246, # other output and precision parameters 'l_max_scalars':5000} ############### # # call CLASS # M = Class() M.set(common_settings) M.compute() cl_tot = M.raw_cl(3000) cl_lensed = M.lensed_cl(3000) M.struct_cleanup() # clean output M.empty() # clean input # M.set(common_settings) # new input M.set({'temperature contributions':'tsw'}) M.compute() cl_tsw = M.raw_cl(3000) M.struct_cleanup() M.empty() # M.set(common_settings) M.set({'temperature contributions':'eisw'}) M.compute() cl_eisw = M.raw_cl(3000)
'tau_reio':0.079, 'output':'tCl', 'security_small_Omega_scf':1e-3, # 'output':'tCl,lCl,mPk', 'use_big_theta_scf': 'yes', 'scf_has_perturbations': 'yes', 'attractor_ic_scf': 'no', 'write thermodynamics':'yes', 'compute damping scale':'yes'} # ensuring memory isn't being eaten up # try to solve with a certain cosmology, no worries if it cannot try: cosmo.set(params) # Set the parameters to the cosmological code cosmo.compute() # solve physics clM = cosmo.raw_cl(2500) ll_1 = clM['ell'][2:] clTT_1 = clM['tt'][2:] except CosmoComputationError: # this happens when CLASS fails pass # eh, don't do anything cosmo.empty() cosmo.struct_cleanup() with open(write_in, 'w') as f: # creates a new file to write in / overwrites f.write('# rows correspond to ac values, columns correspond to Theta_initial \n') # info on format for j in range(N): ratio = [] # print i,j # going over a_c and Om_fld values
'A_s': 2.215e-9, 'n_s': 0.9619, 'tau_reio': 0.0925, # Take fixed value for primordial Helium (instead of automatic BBN adjustment) 'YHe': 0.246, # other output and precision parameters 'l_max_scalars': 5000 } ############### # # call CLASS # M = Class() M.set(common_settings) M.compute() cl_tot = M.raw_cl(3000) cl_lensed = M.lensed_cl(3000) M.struct_cleanup() # clean output M.empty() # clean input # M.set(common_settings) # new input M.set({'temperature contributions': 'tsw'}) M.compute() cl_tsw = M.raw_cl(3000) M.struct_cleanup() M.empty() # M.set(common_settings) M.set({'temperature contributions': 'eisw'}) M.compute() cl_eisw = M.raw_cl(3000)
ax_Cl.tick_params(axis='x', which='both', bottom='on', top='off', labelbottom='on', labeltop='off') ax_Cl.grid() # # the x-axis will show l/(tau_0-tau_rec), so we need (tau_0-tau_rec) in units of [Mpc/h] # tau_0_minus_tau_rec_hMpc = (derived['conformal_age'] - derived['tau_rec']) * M.h() # # save the total Cl's (we will plot them in the last step) # cl_tot = M.raw_cl(5000) # # call CLASS with TSW, then plot and save # M.struct_cleanup() # clean output M.empty() # clean input M.set(common_settings) # new input M.set({'temperature contributions': 'tsw'}) M.compute() cl = M.raw_cl(5000) # ax_Cl.semilogx(cl['ell'] / tau_0_minus_tau_rec_hMpc, 1.e10 * cl['ell'] * (cl['ell'] + 1.) * cl['tt'] / 2. / math.pi, 'c-', label=r'$\mathrm{T+SW}$') #
######################### # presentation settings ax_Cl.set_xlim([3.e-4,0.5]) ax_Cl.set_ylim([0.,8.]) ax_Cl.set_xlabel(r'$\ell/(\tau_0-\tau_{rec}) \,\,\, \mathrm{[h/Mpc]}$') ax_Cl.set_ylabel(r'$\ell (\ell+1) C_l^{TT} / 2 \pi \,\,\, [\times 10^{10}]$') ax_Cl.tick_params(axis='x',which='both',bottom='on',top='off',labelbottom='on',labeltop='off') ax_Cl.grid() # # the x-axis will show l/(tau_0-tau_rec), so we need (tau_0-tau_rec) in units of [Mpc/h] # tau_0_minus_tau_rec_hMpc = (derived['conformal_age']-derived['tau_rec'])*M.h() # # save the total Cl's (we will plot them in the last step) # cl_tot = M.raw_cl(5000) # # call CLASS with TSW, then plot and save # M.struct_cleanup() # clean output M.empty() # clean input M.set(common_settings) # new input M.set({'temperature contributions':'tsw'}) M.compute() cl = M.raw_cl(5000) # ax_Cl.semilogx(cl['ell']/tau_0_minus_tau_rec_hMpc,1.e10*cl['ell']*(cl['ell']+1.)*cl['tt']/2./math.pi,'c-',label=r'$\mathrm{T+SW}$') # ax_Cl.legend(loc='right',bbox_to_anchor=(1.4, 0.5)) fig.savefig('one_time_with_cl_1.pdf',bbox_inches='tight') #