def test_some_angles(): import mceq_config as config from MCEq.core import MCEqRun import crflux.models as pm import numpy as np config.debug_level = 5 config.kernel_config = 'numpy' config.cuda_gpu_id = 0 config.mkl_threads = 2 mceq = MCEqRun(interaction_model='SIBYLL23C', theta_deg=0., primary_model=(pm.HillasGaisser2012, 'H3a')) nmu = [] for theta in [0., 30., 60., 90]: mceq.set_theta_deg(theta) mceq.solve() nmu.append( np.sum( mceq.get_solution('mu+', 0, integrate=True) + mceq.get_solution('mu-', 0, integrate=True))) print(nmu) assert np.allclose(nmu, [ 59787.31805017808, 60908.05990627792, 66117.91267025097, 69664.26521920023 ])
def get_angle_flux(angle, mag=0): """ angle should be in degrees! returns a dicitionary with the energies and the fluxes for each neutrino type """ if not (isinstance(angle, float) or isinstance(angle, int)): raise TypeError("Arg 'angle' should be {}, got {}".format( float, type(angle))) if not (angle <= 180. and angle >= 0.): raise ValueError("Invalid zenith angle {} deg".format(angle)) flux = {} mceq = MCEqRun( interaction_model='SIBYLL23C', primary_model=(HawkBPL, 0.), # primary_model = (crf.HillasGaisser2012, 'H3a'), theta_deg=angle) mceq.solve() flux['e_grid'] = mceq.e_grid flux['nue_flux'] = mceq.get_solution('nue', mag) + mceq.get_solution( 'pr_nue', mag) flux['nue_bar_flux'] = mceq.get_solution( 'antinue', mag) + mceq.get_solution('pr_antinue', mag) flux['numu_flux'] = mceq.get_solution('numu', mag) + mceq.get_solution( 'pr_numu', mag) flux['numu_bar_flux'] = mceq.get_solution( 'antinumu', mag) + mceq.get_solution('pr_antinumu', mag) flux['nutau_flux'] = mceq.get_solution('nutau', mag) + mceq.get_solution( 'pr_nutau', mag) flux['nutau_bar_flux'] = mceq.get_solution( 'antinutau', mag) + mceq.get_solution('pr_antinutau', mag) obj = open("temp_mceq_flux.dat".format(angle), 'w') # obj.write("# E[Gev] Phi_nue[Gev/cm2/s/sr] Phi_numu[Gev/cm2/s/sr] Phi_nutau[Gev/cm2/s/sr] Phi_nue_bar Phi_numu_bar Phi_nutau_bar\n") for i in range(len(flux['e_grid'])): obj.write(str(flux['e_grid'][i])) obj.write(' ') obj.write(str(flux['nue_flux'][i])) obj.write(' ') obj.write(str(flux['numu_flux'][i])) obj.write(' ') obj.write(str(flux['nutau_flux'][i])) obj.write(' ') obj.write(str(flux['nue_bar_flux'][i])) obj.write(' ') obj.write(str(flux['numu_bar_flux'][i])) obj.write(' ') obj.write(str(flux['nutau_bar_flux'][i])) obj.write('\n') obj.close()
def weight(xmat, egrid, name, c): return (1 + c) * numpy.ones_like(xmat) mceq.set_mod_pprod(2212, 211, weight, ('a', 0.141)) # Coefficients taken mceq.set_mod_pprod(2212, -211, weight, ('a', 0.116)) # from table 2 of Yanez et mceq.set_mod_pprod(2212, 321, weight, ('a', 0.402)) # al. mceq.set_mod_pprod(2212, -321, weight, ('a', 0.583)) mceq.regenerate_matrices(skip_decay_matrix=True) mceq.solve(int_grid=X_grid) energy = mceq.e_grid flux = mceq.get_solution('mu-', grid_idx=0) flux += mceq.get_solution('mu+', grid_idx=0) # Plot the result plot.figure() plot.semilogx(energy, energy**3 * flux, 'k--') plot.errorbar(bess.energy, bess.energy**3 * bess.flux, yerr=bess.energy**3 * bess.dflux, fmt='bo', label='BESS-TeV') plot.xlabel('energy [GeV]') plot.ylabel( '$dN_\\mu/dE (E/\\mathrm{GeV})^3$ [GeV$^{-1}$ cm$^{-2}$ s$^{-1}$ sr$^{-1}$]' ) plot.axis((3, 3E+03, 0, 0.5))
def _compute_outputs(self, inputs=None): """Compute histograms for output channels.""" logging.debug('Entering mceq._compute_outputs') primary_model = split(self.params['primary_model'].value, ',') if len(primary_model) != 2: raise ValueError('primary_model is not of length 2, instead is of ' 'length {0}'.format(len(primary_model))) primary_model[0] = eval('pm.' + primary_model[0]) density_model = (self.params['density_model'].value, (self.params['location'].value, self.params['season'].value)) mceq_run = MCEqRun( interaction_model=str(self.params['interaction_model'].value), primary_model=primary_model, theta_deg=0.0, density_model=density_model, **mceq_config.mceq_config_without(['density_model'])) # Power of energy to scale the flux (the results will be returned as E**mag * flux) mag = 0 # Obtain energy grid (fixed) of the solution for the x-axis of the plots e_grid = mceq_run.e_grid # Dictionary for results flux = OrderedDict() for nu in self.output_names: flux[nu] = [] binning = self.output_binning cz_binning = binning.dims[binning.index('coszen', use_basenames=True)] en_binning = binning.dims[binning.index('energy', use_basenames=True)] cz_centers = cz_binning.weighted_centers.m angles = (np.arccos(cz_centers) * ureg.radian).m_as('degrees') for theta in angles: mceq_run.set_theta_deg(theta) mceq_run.solve() flux['nue'].append(mceq_run.get_solution('total_nue', mag)) flux['nuebar'].append(mceq_run.get_solution('total_antinue', mag)) flux['numu'].append(mceq_run.get_solution('total_numu', mag)) flux['numubar'].append(mceq_run.get_solution( 'total_antinumu', mag)) for nu in flux.iterkeys(): flux[nu] = np.array(flux[nu]) smoothing = self.params['smoothing'].value.m en_centers = en_binning.weighted_centers.m_as('GeV') spline_flux = self.bivariate_spline(flux, cz_centers, e_grid, smooth=smoothing) ev_flux = self.bivariate_evaluate(spline_flux, cz_centers, en_centers) for nu in ev_flux: ev_flux[nu] = ev_flux[nu] * ureg('cm**-2 s**-1 sr**-1 GeV**-1') mapset = [] for nu in ev_flux.iterkeys(): mapset.append(Map(name=nu, hist=ev_flux[nu], binning=binning)) return MapSet(mapset)
def generate_table(interaction_model=None, primary_model=None, density_model=None): interaction_model = interaction_model or 'SIBYLL23C' primary_model = primary_model or 'H3a' density_model = density_model or 'USStd' tag = '-'.join((interaction_model.lower(), primary_model.lower(), density_model.lower())) weights = None if interaction_model == 'YFM': # Use weights from Yanez et al., 2019 (https://arxiv.org/abs/1909.08365) interaction_model = 'SIBYLL23C' weights = {211: 0.141, -211: 0.116, 321: 0.402, -321: 0.583} if primary_model == 'GSF': primary_model = (crf.GlobalSplineFitBeta, None) elif primary_model == 'H3a': primary_model = (crf.HillasGaisser2012, 'H3a') elif primary_model == 'PolyGonato': primary_model = (crf.PolyGonato, None) else: raise ValueError(f'Invalid primary model: {primary_model}') if density_model == 'USStd': density_model = ('CORSIKA', ('USStd', None)) elif density_model.startswith('MSIS00'): density_model = ('MSIS00', density_model.split('-')[1:]) else: raise ValueError(f'Invalid density model: {density_model}') config.e_min = 1E-01 config.enable_default_tracking = False config.enable_muon_energy_loss = True mceq = MCEqRun(interaction_model=interaction_model, primary_model=primary_model, density_model=density_model, theta_deg=0) if weights: def weight(xmat, egrid, name, c): return (1 + c) * numpy.ones_like(xmat) for pid, w in weights.items(): mceq.set_mod_pprod(2212, pid, weight, ('a', w)) mceq.regenerate_matrices(skip_decay_matrix=True) energy = mceq.e_grid cos_theta = numpy.linspace(0, 1, 51) altitude = numpy.linspace(0, 9E+03, 10) data = numpy.zeros((altitude.size, cos_theta.size, energy.size, 2)) for ic, ci in enumerate(cos_theta): print(f'processing {ci:.2f}') theta = numpy.arccos(ci) * 180 / numpy.pi mceq.set_theta_deg(theta) X_grid = mceq.density_model.h2X(altitude[::-1] * 1E+02) mceq.solve(int_grid=X_grid) for index, _ in enumerate(altitude): mu_m = mceq.get_solution('mu-', grid_idx=index) * 1E+04 mu_p = mceq.get_solution('mu+', grid_idx=index) * 1E+04 K = (mu_m > 0) & (mu_p > 0) data[altitude.size - 1 - index, ic, K, 0] = mu_m[K] data[altitude.size - 1 - index, ic, K, 1] = mu_p[K] # Dump the data grid to a litle endian binary file data = data.astype('f4').flatten() with open(f'data/simulated/flux-mceq-{tag}.table', 'wb') as f: numpy.array((energy.size, cos_theta.size, altitude.size), dtype='i8').astype('<i8').tofile(f) numpy.array((energy[0], energy[-1], cos_theta[0], cos_theta[-1], altitude[0], altitude[-1]), dtype='f8').astype('<f8').tofile(f) data.astype('<f4').tofile(f)
flux_January = {} #_conv means conventional (mostly pions and kaons) #flux_January['numu_total'] = (mceq_run_January.get_solution('total_numu', mag) # + mceq_run_January.get_solution('total_antinumu', mag)) #flux_January['nue_total'] = (mceq_run_January.get_solution('total_nue', mag) # + mceq_run_January.get_solution('total_antinue', mag)) #to use .. #part one nu/anti nu ratio flux_January['numu_only'] = (mceq_run_January.get_solution('total_numu', mag)) flux_January['antinumu_only'] = (mceq_run_January.get_solution('total_antinumu', mag)) flux_January['nue_only'] = (mceq_run_January.get_solution('total_nue', mag)) flux_January['antinue_only'] = (mceq_run_January.get_solution('total_antinue', mag)) #part two k/pi ratio flux_January['numu_from_kaon'] = (mceq_run_January.get_solution('k_numu', mag)) flux_January['antinumu_from_kaon'] = (mceq_run_January.get_solution('k_antinumu', mag)) flux_January['numu_from_pion'] = (mceq_run_January.get_solution('pi_numu', mag)) flux_January['antinumu_from_pion'] = (mceq_run_January.get_solution('pi_antinumu', mag))
def get_initial_state(energies, zeniths, n_nu, kwargs): """ This either loads the initial state, or generates it. Loading it is waaaay quicker. Possible issue! If you run a bunch of jobs and don't already have this flux generated, bad stuff can happen. I'm imagining issues where a bunch of jobs waste time making this, and then all try to write to the same file Very bad. Big crash. Very Fail """ path = os.path.join(config["datapath"], config["mceq_flux"]) if os.path.exists(path): # print("Loading MCEq Flux") f = open(path, 'rb') inistate = pickle.load(f) f.close() else: # print("Generating MCEq Flux") inistate = np.zeros(shape=(angular_bins, energy_bins, 2, n_nu)) mceq = MCEqRun(interaction_model=config["interaction_model"], primary_model=(crf.HillasGaisser2012, 'H3a'), theta_deg=0.) r_e = 6.378e6 # meters ic_depth = 1.5e3 # meters mag = 0. # power energy is raised to and then used to scale the flux for angle_bin in range(angular_bins): # get the MCEq angle from the icecube zenith angle angle_deg = asin( sin(pi - acos(zeniths[angle_bin])) * (r_e - ic_depth) / r_e) angle_deg = angle_deg * 180. / pi if angle_deg > 180.: angle_deg = 180. print("Evaluating {} deg Flux".format(angle_deg)) # for what it's worth, if you try just making a new MCEqRun for each angle, you get a memory leak. # so you need to manually set the angle mceq.set_theta_deg(angle_deg) mceq.solve() flux = {} flux['e_grid'] = mceq.e_grid flux['nue_flux'] = mceq.get_solution( 'nue', mag) + mceq.get_solution('pr_nue', mag) flux['nue_bar_flux'] = mceq.get_solution( 'antinue', mag) + mceq.get_solution('pr_antinue', mag) flux['numu_flux'] = mceq.get_solution( 'numu', mag) + mceq.get_solution('pr_numu', mag) flux['numu_bar_flux'] = mceq.get_solution( 'antinumu', mag) + mceq.get_solution('pr_antinumu', mag) flux['nutau_flux'] = mceq.get_solution( 'nutau', mag) + mceq.get_solution('pr_nutau', mag) flux['nutau_bar_flux'] = mceq.get_solution( 'antinutau', mag) + mceq.get_solution('pr_antinutau', mag) for neut_type in range(2): for flavor in range(n_nu): flav_key = get_key(flavor, neut_type) if flav_key == "": continue for energy_bin in range(energy_bins): # (account for the difference in units between mceq and nusquids! ) inistate[angle_bin][energy_bin][neut_type][ flavor] = get_closest( energies[energy_bin] / un.GeV, flux['e_grid'], flux[flav_key]) if np.min(inistate) < 0: raise ValueError( "Found negative value in the input from MCEq {}".format( np.min(inistate))) # save it now f = open(path, 'wb') pickle.dump(inistate, f, -1) f.close() return (inistate)
def make_plots(): Emin = 1 * un.GeV Emax = 10 * un.PeV energies = nsq.logspace(Emin, Emax, 100) angles = nsq.linspace(-0.99, -0.98, 2) # just look at straight up/down # get MCEq flux there mag = 0. angle = 0. #degrees mceq = MCEqRun(interaction_model='SIBYLL23C', primary_model=(crf.HillasGaisser2012, 'H3a'), theta_deg=0.) mceq.solve() n_nu = 3 inistate = np.zeros(shape=(2, len(energies), 2, n_nu)) flux = {} flux['e_grid'] = mceq.e_grid flux['nue_flux'] = mceq.get_solution('nue', mag) + mceq.get_solution( 'pr_nue', mag) flux['nue_bar_flux'] = mceq.get_solution( 'antinue', mag) + mceq.get_solution('pr_antinue', mag) flux['numu_flux'] = mceq.get_solution('numu', mag) + mceq.get_solution( 'pr_numu', mag) flux['numu_bar_flux'] = mceq.get_solution( 'antinumu', mag) + mceq.get_solution('pr_antinumu', mag) flux['nutau_flux'] = mceq.get_solution('nutau', mag) + mceq.get_solution( 'pr_nutau', mag) flux['nutau_bar_flux'] = mceq.get_solution( 'antinutau', mag) + mceq.get_solution('pr_antinutau', mag) # propagate it with nusquids for neut_type in range(2): for flavor in range(n_nu): flav_key = get_key(flavor, neut_type) if flav_key == "": continue for energy_bin in range(len(energies)): inistate[0][energy_bin][neut_type][flavor] = get_closest( energies[energy_bin] / un.GeV, flux['e_grid'], flux[flav_key]) inistate[1][energy_bin][neut_type][flavor] = get_closest( energies[energy_bin] / un.GeV, flux['e_grid'], flux[flav_key]) nus_atm = nsq.nuSQUIDSAtm(angles, energies, n_nu, nsq.NeutrinoType.both, True) nus_atm.Set_MixingAngle(0, 1, 0.563942) nus_atm.Set_MixingAngle(0, 2, 0.154085) nus_atm.Set_MixingAngle(1, 2, 0.785398) nus_atm.Set_SquareMassDifference(1, 7.65e-05) nus_atm.Set_SquareMassDifference(2, 0.00247) nus_atm.SetNeutrinoCrossSections(xs) #settting some zenith angle stuff nus_atm.Set_rel_error(1.0e-6) nus_atm.Set_abs_error(1.0e-6) #nus_atm.Set_GSL_step(gsl_odeiv2_step_rk4) nus_atm.Set_GSL_step(nsq.GSL_STEP_FUNCTIONS.GSL_STEP_RK4) # we load in the initial state. Generating or Loading from a file nus_atm.Set_initial_state(inistate, nsq.Basis.flavor) print("Done setting initial state") # we turn off the progress bar for jobs run on the cobalts nus_atm.Set_ProgressBar(False) nus_atm.Set_IncludeOscillations(True) print("Evolving State") nus_atm.EvolveState() # Evaluate the flux at the energies, flavors, and shit we care about eval_flux = {} for flavor in range(3): for nute in range(2): key = get_key(flavor, nute) if key == "": continue eval_flux[key] = np.zeros(len(energies)) for energy in range(len(energies)): powed = energies[energy] eval_flux[key][energy] = nus_atm.EvalFlavor( flavor, -0.985, powed, nute) # multiply the fluxes with total cross sections at that energy conv_flux = {} for flavor in flavors.keys(): if flavor == "electron": i_flav = 0 elif flavor == "muon": i_flav = 1 else: i_flav = 2 for neut_type in neut_types.keys(): if neut_type == "neutrino": i_neut = 0 else: i_neut = 1 eval_key = get_key(i_flav, i_neut) for current in currents.keys(): conv_key = "_".join([flavor, neut_type, current]) conv_flux[conv_key] = np.zeros(len(energies)) for energy in range(len(energies)): powed = energies[energy] conv_flux[conv_key][ energy] = eval_flux[eval_key][energy] * get_total_flux( powed, flavors[flavor], neut_types[neut_type], currents[current]) # sum up the cascades and compare them with the cross sections casc_fluxes = np.zeros(len(energies)) track_fluxes = np.zeros(len(energies)) for key in conv_flux: if is_cascade(key): casc_fluxes += conv_flux[key] else: track_fluxes += conv_flux[key] plt.plot(energies / un.GeV, casc_fluxes, label="Cascades") plt.plot(energies / un.GeV, track_fluxes, label="Tracks") plt.xscale('log') plt.xlim([10**2, 10**7]) plt.yscale('log') plt.legend() plt.xlabel("Energy [GeV]", size=14) plt.ylabel(r"Flux$\cdot\sigma_{total}$ [s GeV sr]$^{-1}$", size=14) plt.show()
def Solve_mceqs(): ### This function solves matrix cascade equations using MCEq. Please ### note that MCEq can do a lot more than what is currently used ### in this script. For more information and options, visit: ### https://github.com/afedynitch/MCEq import crflux.models as crf from MCEq.core import config, MCEqRun def Convert_name(particle): # MCEq can't handle "bar"s in particle names. It wants "anti"s instead. if 'bar' in particle[0]: pname = (particle[0].replace('_', '_anti') if '_' in particle[0] else 'anti' + particle[0]) pname = pname.replace('bar', '') else: pname = particle[0] return pname # Cosmic ray flux at the top of the atmosphere: primary_model = (HawkBPL, 0.) # High-energy hadronic interaction model: interaction_model = 'SIBYLL23C' # Zenith angles: zenith_deg = np.append(np.arange(0., 90., 10), 89) mceq = MCEqRun(interaction_model = interaction_model, primary_model = primary_model, theta_deg = 0.) mceq.pman.track_leptons_from([(130,0)], 'K0L_') mceq.pman.track_leptons_from([(310,0)], 'K0S_') # mceq.pman.print_particle_tables(0) mceq._resize_vectors_and_restore() mceq.regenerate_matrices() config.excpt_on_missing_particle = True energy = mceq.e_grid ## Solve the equation systems for all zenith angles: solutions = [[] for particle in particles] for angle in zenith_deg: print( '\n=== Solving MCEq for BPL ' + interaction_model + ' ' + str(angle) + ' deg' ) mceq.set_theta_deg(angle) mceq.solve() # Obtain solution for all chosen particles: print('Obtaining solution for:') for p, particle in enumerate(particles): print(particle[0]) solutions[p].append(mceq.get_solution(Convert_name(particle), mag=0)) # mag is a multiplication factor in order to stress steaper # parts of the spectrum. Don't store magnified fluxes in nuflux # (keep mag=0)! # Save solutions to file particle-wise: for p, particle in enumerate(particles): savename = name + '_' + particle[0] headr = ( savename.replace('_', '\t') + '\n' 'energy [GeV]\t' + ' '.join([str(z) + ' deg\t' for z in zenith_deg]) ) solutions[p].insert(0, energy) solutions[p] = np.array(solutions[p]) np.savetxt( dirname + '/data/' + savename + '.dat', np.transpose(solutions[p]), fmt='%.8e', header=headr, delimiter='\t' )