def make_propagator(ID, body, xs_model='dipole', granularity=0.5): if (ID in [12, -12]): return None particle_def = getattr(pp.particle, ID_2_name[ID])() #define how many layers of constant density we need for the tau descs = segment_body(body, granularity) #make the sectors sec_defs = [ make_sector(d / units.gr * units.cm**3, s * body.radius / units.meter, e * body.radius / units.meter, xs_model) for s, e, d in descs ] with path('taurunner.resources.proposal_tables', 'tables.txt') as p: tables_path = str(p).split('tables.txt')[0] #define interpolator interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = tables_path interpolation_def.path_to_tables_readonly = tables_path interpolation_def.nodes_cross_section = 200 #define propagator -- takes a particle definition - sector - detector - interpolator prop = pp.Propagator(particle_def=particle_def, sector_defs=sec_defs, detector=pp.geometry.Sphere(pp.Vector3D(), body.radius / units.cm, 0), interpolation_def=interpolation_def) return prop
def test_proposal(): # ========================================================= # Propagate # ========================================================= # initialize propagator args = { "particle_def": pp.particle.MuMinusDef(), "target": pp.medium.Ice(), "interpolate": True, "cuts": pp.EnergyCutSettings(500, 0.05) } cross = pp.crosssection.make_std_crosssection(**args) collection = pp.PropagationUtilityCollection() collection.displacement = pp.make_displacement(cross, True) collection.interaction = pp.make_interaction(cross, True) collection.time = pp.make_time(cross, args["particle_def"], True) utility = pp.PropagationUtility(collection=collection) detector = pp.geometry.Sphere(pp.Cartesian3D(0, 0, 0), 1e20) density_distr = pp.density_distribution.density_homogeneous( args["target"].mass_density) prop = pp.Propagator(args["particle_def"], [(detector, utility, density_distr)]) # intialize initial state statistics = 100 init_state = pp.particle.ParticleState() init_state.energy = 1e8 # initial energy in MeV init_state.position = pp.Cartesian3D(0, 0, 0) init_state.direction = pp.Cartesian3D(0, 0, -1) init_state.time = 0 pp.RandomGenerator.get().set_seed(1234) for i in range(statistics): output = prop.propagate(init_state) energies = output.track_energies() times = output.track_times() E_old = init_state.energy t_old = init_state.time for E, t in zip(energies, times): energy_diff = E_old - E time_diff = t - t_old E_old = E t_old = t assert (energy_diff >= 0) assert (time_diff >= 0)
def create_table(dir_name): """TODO: Docstring for create_table. Returns: TODO """ statistics = 10 prop = pp.Propagator(pp.particle.MuMinusDef(), "examples/config_minimal.json") init_particle = pp.particle.ParticleState() init_particle.energy = 1e8 init_particle.propagated_distance = 0 init_particle.position = pp.Cartesian3D(0, 0, 0) init_particle.direction = pp.Cartesian3D(0, 0, -1) init_particle.time = 0 pp.RandomGenerator.get().set_seed(1234) with open(dir_name + "Propagator_propagation.txt", "w") as file: buf = [""] buf.append("name") buf.append("length") buf.append("energy") buf.append("x") buf.append("y") buf.append("z") buf.append("dx") buf.append("dy") buf.append("dz") buf.append("\n") buf.append(str(statistics)) buf.append(str(init_particle.energy)) buf.append("\n") file.write("\t".join(buf)) for i in range(statistics): daughters = prop.propagate(init_particle) buf = [""] for d in daughters.stochastic_losses(): buf.append(str(d.type)) buf.append(str(d.propagated_distance)) buf.append(str(d.energy)) buf.append(str(d.position.x)) buf.append(str(d.position.y)) buf.append(str(d.position.z)) buf.append(str(d.direction.x)) buf.append(str(d.direction.y)) buf.append(str(d.direction.z)) buf.append("\n") file.write("\t".join(buf))
def create_table(dir_name): """TODO: Docstring for create_table. Returns: TODO """ statistics = 10 prop = pp.Propagator(pp.particle.MuMinusDef(), "resources/config_ice.json") mu = pp.particle.DynamicData(pp.particle.Particle_Id.MuMinus) mu.energy = 1e8 mu.propagated_distance = 0 mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) pp.RandomGenerator.get().set_seed(1234) with open(dir_name + "Propagator_propagation.txt", "w") as file: buf = [""] buf.append("name") buf.append("lenght") buf.append("energy") buf.append("x") buf.append("y") buf.append("z") buf.append("dx") buf.append("dy") buf.append("dz") buf.append("\n") buf.append(str(statistics)) buf.append(str(mu.energy)) buf.append("\n") file.write("\t".join(buf)) for i in range(statistics): daughters = prop.propagate(mu) buf = [""] for d in daughters.particles: buf.append(str(d.name)) buf.append(str(d.propagated_distance)) buf.append(str(d.energy)) buf.append(str(d.position.x)) buf.append(str(d.position.y)) buf.append(str(d.position.z)) buf.append(str(d.direction.x)) buf.append(str(d.direction.y)) buf.append(str(d.direction.z)) buf.append("\n") file.write("\t".join(buf))
def muons(energy, statistics, vcut, do_continuous_randomization, dist): sec_def = pp.SectorDefinition() sec_def.medium = pp.medium.StandardRock(1.0) sec_def.geometry = pp.geometry.Sphere(pp.Vector3D(), 1e20, 0) sec_def.particle_location = pp.ParticleLocation.inside_detector sec_def.scattering_model = pp.scattering.ScatteringModel.Highland sec_def.do_continuous_randomization = do_continuous_randomization sec_def.cut_settings.ecut = 0 sec_def.cut_settings.vcut = vcut interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = "~/.local/share/PROPOSAL/tables" interpolation_def.path_to_tables_readonly = "~/.local/share/PROPOSAL/tables" mu_def = pp.particle.MuMinusDef() prop = pp.Propagator(particle_def=mu_def, sector_defs=[sec_def], detector=pp.geometry.Sphere(pp.Vector3D(), 1e20, 0), interpolation_def=interpolation_def) mu = pp.particle.DynamicData(mu_def.particle_type) mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) mu.energy = energy mu.propagated_distance = 0. mu.time = 0. mu_energies = [] pp.RandomGenerator.get().set_seed(1234) for i in tqdm(range(statistics)): secondaries = prop.propagate(mu, dist * 100) mu_energies.append(secondaries.energy[-1]) # del secondaries return mu_energies
def muons(energy, statistics, vcut, do_continuous_randomization, dist): sec_def = pp.SectorDefinition() sec_def.medium = pp.medium.StandardRock(1.0) sec_def.geometry = pp.geometry.Sphere(pp.Vector3D(), 1e20, 0) sec_def.particle_location = pp.ParticleLocation.inside_detector sec_def.scattering_model = pp.scattering.ScatteringModel.Moliere sec_def.do_continuous_randomization = do_continuous_randomization sec_def.cut_settings.ecut = 0 sec_def.cut_settings.vcut = vcut interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = "" prop = pp.Propagator(particle_def=pp.particle.MuMinusDef.get(), sector_defs=[sec_def], detector=pp.geometry.Sphere(pp.Vector3D(), 1e20, 0), interpolation_def=interpolation_def) mu = prop.particle mu_energies = [] for i in range(statistics): mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) mu.energy = energy mu.propagated_distance = 0 d = prop.propagate(dist * 100) mu_energies.append(mu.energy) return mu_energies
def test_proposal(): # ========================================================= # Propagate # ========================================================= energy = 1e8 # MeV statistics = 100 sec_def = pp.SectorDefinition() sec_def.medium = pp.medium.Ice(1.0) sec_def.geometry = pp.geometry.Sphere(pp.Vector3D(), 1e20, 0) sec_def.particle_location = pp.ParticleLocation.inside_detector sec_def.do_continuous_energy_loss_output = True sec_def.scattering_model = pp.scattering.ScatteringModel.HighlandIntegral sec_def.crosssection_defs.brems_def.lpm_effect = False sec_def.crosssection_defs.epair_def.lpm_effect = False sec_def.cut_settings.ecut = 500 sec_def.cut_settings.vcut = 0.05 interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = table_path interpolation_def.path_to_tables_readonly = table_path mu_def = pp.particle.MuMinusDef() prop = pp.Propagator(particle_def=mu_def, sector_defs=[sec_def], detector=pp.geometry.Sphere(pp.Vector3D(), 1e20, 0), interpolation_def=interpolation_def) mu = pp.particle.DynamicData(mu_def.particle_type) mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) mu.energy = energy mu.propagated_distance = 0 pp.RandomGenerator.get().set_seed(1234) for i in range(statistics): secondaries = prop.propagate(mu).particles for idx, sec in enumerate(secondaries[1:-1]): if sec.type == int(ContinuousEnergyLoss): if (secondaries[idx - 1].type == int(ContinuousEnergyLoss) or secondaries[idx + 1].type == int(ContinuousEnergyLoss)): print("2 Continuous Losses in a row") continue energy_diff = secondaries[idx - 1].energy - secondaries[ idx + 1].parent_particle_energy continuou_energy_lost = sec.parent_particle_energy - sec.energy assert energy_diff == approx(continuou_energy_lost, abs=1e-3), "Energy differs" time_diff = secondaries[idx + 1].time - secondaries[idx - 1].time assert time_diff == approx(sec.time, abs=1e-3), "Time differs"
def propagate(): """ Propagte muon in ice threw a cylindric detector Returns: (Particle) Particle representing the start position (Geometry) Geometry of the detector (list) List of secondarys particles represeint interactions """ medium = pp.medium.Ice(1.0) geo_detector = pp.geometry.Cylinder(pp.Vector3D(), 800, 0, 1600) geo_outside = pp.geometry.Box(pp.Vector3D(), 500000, 500000, 500000) # Infront sec_def_infront = pp.SectorDefinition() sec_def_infront.medium = medium sec_def_infront.geometry = geo_outside sec_def_infront.particle_location = pp.ParticleLocation.infront_detector sec_def_infront.scattering_model = pp.scattering.ScatteringModel.Moliere sec_def_infront.cut_settings.ecut = -1 sec_def_infront.cut_settings.vcut = 0.05 # Inside sec_def_inside = pp.SectorDefinition() sec_def_inside.medium = medium sec_def_inside.geometry = geo_outside sec_def_inside.particle_location = pp.ParticleLocation.inside_detector sec_def_inside.scattering_model = pp.scattering.ScatteringModel.Moliere sec_def_inside.cut_settings.ecut = 500 sec_def_inside.cut_settings.vcut = -1 # Behind sec_def_behind = pp.SectorDefinition() sec_def_behind.medium = medium sec_def_behind.geometry = geo_outside sec_def_behind.particle_location = pp.ParticleLocation.behind_detector sec_def_behind.scattering_model = pp.scattering.ScatteringModel.Moliere sec_def_behind.cut_settings.ecut = -1 sec_def_behind.cut_settings.vcut = 0.05 # Interpolation defintion interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = "~/.local/share/PROPOSAL/tables" interpolation_def.path_to_tables_readonly = "~/.local/share/PROPOSAL/tables" # Propagator mu_def = pp.particle.MuMinusDef() prop = pp.Propagator( particle_def=mu_def, sector_defs=[sec_def_infront, sec_def_inside, sec_def_behind], detector=geo_detector, interpolation_def=interpolation_def ) mu = pp.particle.DynamicData(mu_def.particle_type) # Set energy and position of the particle mu.energy = 9e6 mu.direction = pp.Vector3D(0, 0, 1) pos = mu.position pos.set_cartesian_coordinates(0, 0, -1e5) mu.position = pos # mu_start = pp.particle.Particle(mu) secondarys = prop.propagate(mu).particles return mu, geo_detector, secondarys
def propagate_deflected_muons(initial_energies, minimum_energies, inter_type, deflection_type='continuous+stochastic', e_cut=500, v_cut=0.05, cont_rand=False, scattering_method="highlandintegral", beta=1.0, rnd_seed=1337, initial_direction=[0, 0, 1]): '''Propagate muon tracks with deflection. Scaling of Bremsstrahlung opening angle can be done by beta. Parameters ---------- initial_energies: list of energies minimum_energs: list of energies, lower propagation limit inter_type: list of interaction types for propagation/deflection deflection_type: string, choose one: 1. 'contiuous+stochastic' 2. 'continuous' 3. 'stochastic' beta: scaling factor for Bremsstrahlung e_cut, v_cut, cont_rand: usual PROPOSAL energy cut settings initial_direction: list of initial direction (cartesian coordinates) ''' pp.RandomGenerator.get().set_seed(rnd_seed) args = { "particle_def": pp.particle.MuMinusDef(), "target": pp.medium.Ice(), "interpolate": True, "cuts": pp.EnergyCutSettings(e_cut, v_cut, cont_rand) } cross = pp.crosssection.make_std_crosssection(**args) multiple_scatter = pp.make_multiple_scattering(scattering_method, args["particle_def"], args["target"], cross, True) stochastic_deflect = pp.make_default_stochastic_deflection( inter_type, args["particle_def"], args["target"]) collection = pp.PropagationUtilityCollection() collection.displacement = pp.make_displacement(cross, True) collection.interaction = pp.make_interaction(cross, True) collection.time = pp.make_time(cross, args["particle_def"], True) collection.decay = pp.make_decay(cross, args["particle_def"], True) if deflection_type == 'stochastic': print('stochastic deflection') if pp.particle.Interaction_Type.brems in inter_type: collection.scattering = pp.scattering.ScatteringMultiplier( stochastic_deflect, [(pp.particle.Interaction_Type.brems, beta)]) else: collection.scattering = pp.scattering.ScatteringMultiplier( stochastic_deflect, [(inter_type[0], 1.0)]) elif deflection_type == 'continuous': print('continuous deflection') collection.scattering = pp.scattering.ScatteringMultiplier( multiple_scatter, 1.0) elif deflection_type == 'continuous+stochastic': print('continuous and stochastic deflection') if pp.particle.Interaction_Type.brems in inter_type: collection.scattering = pp.scattering.ScatteringMultiplier( multiple_scatter, stochastic_deflect, 1.0, [(pp.particle.Interaction_Type.brems, beta)]) else: collection.scattering = pp.scattering.ScatteringMultiplier( multiple_scatter, stochastic_deflect, 1.0, [(inter_type[0], 1.0)]) utility = pp.PropagationUtility(collection=collection) detector = pp.geometry.Sphere(pp.Vector3D(0, 0, 0), 1e20) density_distr = pp.density_distribution.density_homogeneous( args["target"].mass_density) prop = pp.Propagator(args["particle_def"], [(detector, utility, density_distr)]) init_state = pp.particle.ParticleState() init_state.position = pp.Vector3D(0, 0, 0) init_state.direction = pp.Vector3D(initial_direction[0], initial_direction[1], initial_direction[2]) tracks = [] for E_i, E_min in zip(tqdm(initial_energies), minimum_energies): init_state.energy = E_i # initial energy in MeV track = prop.propagate(init_state, max_distance=1e9, min_energy=E_min) tracks.append(track) return tracks
def main(): prop = pp.Propagator(particle_def=pp.particle.MuMinusDef(), config_file="resources/config.json") # print('losses inside: ', prop.sector_list[0].sector_def.only_loss_inside_detector) pp.RandomGenerator.get().set_seed(1234) fig = plt.figure(figsize=(8, 10)) gs = gridspec.GridSpec(3, 1) ax1 = fig.add_subplot(gs[:-1]) ax2 = fig.add_subplot(gs[-1], sharex=ax1) # ax1 = fig.add_subplot(111) ax1.plot( np.array([ -prop.detector.radius, prop.detector.radius, prop.detector.radius, -prop.detector.radius, -prop.detector.radius ]), np.array([ -prop.detector.height, -prop.detector.height, prop.detector.height, prop.detector.height, -prop.detector.height ]) / 2, color='k', label='detector') ax1.set_xlabel('x coord. / cm') ax1.set_ylabel('z coord. / cm') ax1.set_xlim([-1e5, 1e5]) ax1.set_ylim([-1e5, 1e5]) labels = ['EPair', 'Brems', 'Ioniz', 'NuclInt', r'$e_{\mathrm{decay}}$'] start_positions = np.array([ # [-1e5,0,1e4], [-1e5, 0, 2e4], # [-3e4,0,3e4], # [1e4,0,4e4], [74428.7, 29332., 69745.] ]) tmp_dir = pp.Vector3D() tmp_dir.set_spherical_coordinates(1, 0.181678, 1.94055) tmp_dir.cartesian_from_spherical() tmp_dir = -tmp_dir # print(tmp_dir) start_directions = [ # [1, 0, 0], [1, 0, 0], # [1, 0, 0], # [1, 0, 0], [tmp_dir.x, tmp_dir.y, tmp_dir.z] ] start_energies = [ # 1e9, 3e5, # 1e5, # 1e5, 158816 ] for jdx in range(len(start_energies)): secondary_obj = propagate_particle(prop, position=start_positions[jdx], direction=start_directions[jdx], energy=start_energies[jdx]) secondarys = secondary_obj.particles nsecs = len(secondarys) # to get rid of the decay neutrinos positions = np.empty((nsecs, 3)) secs_energy = np.empty(nsecs) mu_energies = np.empty(nsecs) secs_ids = np.empty(nsecs) for idx in range(nsecs): positions[idx] = np.array([ secondarys[idx].position.x, secondarys[idx].position.y, secondarys[idx].position.z ]) mu_energies[idx] = secondarys[idx].parent_particle_energy secs_energy[idx] = secondarys[ idx].parent_particle_energy - secondarys[idx].energy if secondarys[idx].type == int(pp.particle.Interaction_Type.Epair): secs_ids[idx] = 0 elif secondarys[idx].type == int( pp.particle.Interaction_Type.Brems): secs_ids[idx] = 1 elif secondarys[idx].type == int( pp.particle.Interaction_Type.DeltaE): secs_ids[idx] = 2 elif secondarys[idx].type == int( pp.particle.Interaction_Type.NuclInt): secs_ids[idx] = 3 elif secondarys[idx].type == int( pp.particle.Interaction_Type.ContinuousEnergyLoss): secs_ids[idx] = 6 # decay elif secondarys[idx].type == int(pp.particle.Particle_Type.EMinus): secs_ids[idx] = 4 elif secondarys[idx].type == int(pp.particle.Particle_Type.NuMu): secs_ids[idx] = 5 elif secondarys[idx].type == int(pp.particle.Particle_Type.NuEBar): secs_ids[idx] = 5 else: print('unknown secondary id {}'.format(secondarys[idx].type)) for idx in range(len(labels)): ax2.plot(positions[:, 0][secs_ids == idx], secs_energy[secs_ids == idx] / 1e3, ls='None', marker='.', label=labels[idx]) last_sec = secondarys[-1] end_position = np.array( [[last_sec.position.x, last_sec.position.y, last_sec.position.z]]) # now after ploting the losss, one can add the start position/energy of the muon to plot it positions = np.concatenate( ([start_positions[jdx]], positions, end_position), axis=0) mu_energies = np.concatenate( ([start_energies[jdx]], mu_energies, [prop.particle_def.mass])) entry_pos = secondary_obj.entry_point.position exit_pos = secondary_obj.exit_point.position closest_appr_pos = secondary_obj.closest_approach_point.position ax2.plot(positions[:, 0], mu_energies / 1e3, label=r'$E_{\mu}$') ax2.axhline(0.5, color='r', label='ecut') ax2.axvline(entry_pos.x, color='g', ls='-', label='entry/exit') ax2.axvline(exit_pos.x, color='g', ls='-') ax2.axvline(closest_appr_pos.x, color='b', ls='dotted', label='closest approach') ax2.set_yscale('log') ax2.set_ylabel('Energy / GeV') ax2.set_xlabel('x coord. / cm') # ax2.legend() plt.subplots_adjust(hspace=.0) plt.setp(ax1.get_xticklabels(), visible=False) ax1.plot(positions[:, 0], positions[:, 2], label='muon') # {}'.format(jdx)) ax1.plot([entry_pos.x, exit_pos.x], [entry_pos.z, exit_pos.z], ls='None', marker='x', label='entry/exit') # {}'.format(jdx)) ax1.plot(closest_appr_pos.x, closest_appr_pos.z, ls='None', marker='+', label='closet approach') # {}'.format(jdx)) # ax1.plot([entry_pos.x, closest_appr_pos.x, exit_pos.x], # [entry_pos.z, closest_appr_pos.z, exit_pos.z], # ls='dotted', label='approx line')# {}'.format(jdx)) ax1.legend() fig.savefig('entry_exit_points.png') plt.show()
def __get_propagator(self, particle_code=13): """ Returns a PROPOSAL propagator for muons or taus. If it does not exist yet it is being generated. Parameters ---------- particle_code: integer Particle code for the muon- (13), muon+ (-13), tau- (15), or tau+ (-15) config_file: string or path The user can specify the path to their own config file or choose among the three available options: -'SouthPole', a config file for the South Pole (spherical Earth). It consists of a 2.7 km deep layer of ice, bedrock below and air above. -'MooresBay', a config file for Moore's Bay (spherical Earth). It consists of a 576 m deep ice layer with a 2234 m deep water layer below, and bedrock below that. -'InfIce', a config file with a medium of infinite ice -'Greenland', a config file for Summit Station, Greenland (spherical Earth), same as SouthPole but with a 3 km deep ice layer. IMPORTANT: If these options are used, the code is more efficient if the user requests their own "path_to_tables" and "path_to_tables_readonly", pointing them to a writable directory Returns ------- propagator: PROPOSAL propagator Propagator that can be used to calculate the interactions of a muon or tau """ if (particle_code not in self.__propagators): self.__logger.info( f"initializing propagator for particle code {particle_code}") mu_def_builder = pp.particle.ParticleDefBuilder() if (particle_code == 13): mu_def_builder.SetParticleDef(pp.particle.MuMinusDef()) elif (particle_code == -13): mu_def_builder.SetParticleDef(pp.particle.MuPlusDef()) elif (particle_code == 15): mu_def_builder.SetParticleDef(pp.particle.TauMinusDef()) elif (particle_code == -15): mu_def_builder.SetParticleDef(pp.particle.TauPlusDef()) else: error_str = "The propagation of this particle via PROPOSAL is not currently supported.\n" error_str += "Please choose between -/+muon (13/-13) and -/+tau (15/-15)" raise NotImplementedError(error_str) mu_def = mu_def_builder.build() if (self.__config_file == 'SouthPole'): config_file_full_path = os.path.join(os.path.dirname(__file__), 'config_PROPOSAL.json') elif (self.__config_file == 'MooresBay'): config_file_full_path = os.path.join( os.path.dirname(__file__), 'config_PROPOSAL_mooresbay.json') elif (self.__config_file == 'InfIce'): config_file_full_path = os.path.join( os.path.dirname(__file__), 'config_PROPOSAL_infice.json') elif (self.__config_file == 'Greenland'): config_file_full_path = os.path.join( os.path.dirname(__file__), 'config_PROPOSAL_greenland.json') elif (os.path.exists(self.__config_file)): config_file_full_path = self.__config_file else: raise ValueError( "Proposal config file is not valid. Please provide a valid option." ) if not os.path.exists(config_file_full_path): error_message = "Proposal config file does not exist.\n" error_message += "Please provide valid paths for the interpolation tables " error_message += "in file {}.sample ".format( config_file_full_path) error_message += "and copy the file to {}.".format( os.path.basename(config_file_full_path)) raise ValueError(error_message) check_path_to_tables(config_file_full_path) self.__propagators[particle_code] = pp.Propagator( particle_def=mu_def, config_file=config_file_full_path) return self.__propagators[particle_code]
statistics = 100 config_file = "resources/config_ice.json" if len(sys.argv) == 2: statistics = int(sys.argv[1]) elif len(sys.argv) == 3: statistics = int(sys.argv[1]) config_file = sys.argv[2] # ========================================================= # POPOSAL # ========================================================= mu_def = pp.particle.MuMinusDef() prop = pp.Propagator(particle_def=mu_def, config_file=config_file) E_max_log = 14 mu = pp.particle.DynamicData(mu_def.particle_type) mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) mu.energy = math.pow(10, E_max_log) mu.propagated_distance = 0 mu.time = 0 epair_primary_energy = [] epair_secondary_energy = [] brems_primary_energy = []
def propagate_muons(): mu_def = pp.particle.MuMinusDef() geometry = pp.geometry.Sphere(pp.Vector3D(), 1.e20, 0.0) ecut = 500 vcut = 5e-2 sector_def = pp.SectorDefinition() sector_def.cut_settings = pp.EnergyCutSettings(ecut, vcut) sector_def.medium = pp.medium.StandardRock(1.0) sector_def.geometry = geometry sector_def.scattering_model = pp.scattering.ScatteringModel.NoScattering sector_def.crosssection_defs.brems_def.lpm_effect = False sector_def.crosssection_defs.epair_def.lpm_effect = False # sector_def.crosssection_defs.photo_def.parametrization = pp.parametrization.photonuclear.PhotoParametrization.BezrukovBugaev # sector_def.do_stochastic_loss_weighting = True # sector_def.stochastic_loss_weighting = -0.1 detector = geometry interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = "~/.local/share/PROPOSAL/tables" interpolation_def.path_to_tables_readonly = "~/.local/share/PROPOSAL/tables" prop = pp.Propagator(mu_def, [sector_def], detector, interpolation_def) statistics_log = 4 statistics = int(10**statistics_log) propagation_length = 1e4 # cm E_min_log = 10.0 E_max_log = 10.0 spectral_index = 1.0 pp.RandomGenerator.get().set_seed(1234) # muon_energies = np.logspace(E_min_log, E_max_log, statistics) # muon_energies = power_law_sampler(spectral_index, 10**E_min_log, 10**E_max_log, statistics) muon_energies = np.ones(statistics)*10**10 epair_secondary_energy = [] brems_secondary_energy = [] ioniz_secondary_energy = [] photo_secondary_energy = [] mu_prop = pp.particle.DynamicData(mu_def.particle_type) mu_prop.position = pp.Vector3D(0, 0, 0) mu_prop.direction = pp.Vector3D(0, 0, -1) mu_prop.propagated_distance = 0 for mu_energy in tqdm(muon_energies): mu_prop.energy = mu_energy secondarys = prop.propagate(mu_prop, propagation_length) for sec in secondarys.particles: log_sec_energy = np.log10(sec.parent_particle_energy - sec.energy) if sec.type == int(pp.particle.Interaction_Type.Epair): epair_secondary_energy.append(log_sec_energy) if sec.type == int(pp.particle.Interaction_Type.Brems): brems_secondary_energy.append(log_sec_energy) if sec.type == int(pp.particle.Interaction_Type.DeltaE): ioniz_secondary_energy.append(log_sec_energy) if sec.type == int(pp.particle.Interaction_Type.NuclInt): photo_secondary_energy.append(log_sec_energy) # ========================================================= # Write # ========================================================= np.savez( 'data_sec_dist_{}_{}_Emin_{}_Emax_{}'.format( mu_def.name, sector_def.medium.name.lower(), E_min_log, E_max_log, ecut, vcut), brems=brems_secondary_energy, epair=epair_secondary_energy, photo=photo_secondary_energy, ioniz=ioniz_secondary_energy, statistics=[statistics], E_min=[E_min_log], E_max=[E_max_log], spectral_index=[spectral_index], distance=[propagation_length / 100], medium_name=[sector_def.medium.name.lower()], particle_name=[mu_def.name], ecut=[ecut], vcut=[vcut] )
sec_def.geometry = pp.geometry.Sphere(pp.Vector3D(), 1e20, 0) sec_def.particle_location = pp.ParticleLocation.inside_detector sec_def.scattering_model = pp.scattering.ScatteringModel.Moliere sec_def.crosssection_defs.brems_def.lpm_effect = False sec_def.crosssection_defs.epair_def.lpm_effect = False sec_def.cut_settings.ecut = 500 sec_def.cut_settings.vcut = 0.05 interpolation_def = pp.InterpolationDef() interpolation_def.path_to_tables = "~/.local/share/PROPOSAL/tables" interpolation_def.path_to_tables_readonly = "~/.local/share/PROPOSAL/tables" prop = pp.Propagator(particle_def=pp.particle.MuMinusDef(), sector_defs=[sec_def], detector=pp.geometry.Sphere(pp.Vector3D(), 1e20, 0), interpolation_def=interpolation_def) mu = pp.particle.DynamicData(pp.particle.MuMinusDef().particle_type) mu.position = pp.Vector3D(0, 0, 0) mu.direction = pp.Vector3D(0, 0, -1) mu.energy = energy mu.propagated_distance = 0 mu_length = [] n_secondarys = [] for i in tqdm(range(statistics)): d = prop.propagate(mu).particles
profiles = {} axis = pp.density_distribution.radial_axis(pp.Cartesian3D(0, 0, 0)) sigma = -5.5 * 1e5 # km -> cm profiles["air"] = pp.density_distribution.density_homogeneous( 1e-1 * targets["air"].mass_density) profiles["standardrock"] = pp.density_distribution.density_homogeneous( 1e-4 * targets["standardrock"].mass_density) env = [] for utility, geometry, prof in zip(utilities.values(), geometries.values(), profiles.values()): env.append((geometry, utility, prof)) prop = pp.Propagator(pp.particle.MuMinusDef(), env) def get_injection_point(): phi = 0 theta = 2 * np.pi * np.random.random() pos = pp.Spherical3D(earth_radius + atmosphere_depth, phi, theta) return pp.Cartesian3D(pos) def get_direction(pos): pos = pp.Spherical3D(-pos) pos.radius = 1 rnd1 = np.random.normal(0, np.pi / 20) rnd2 = np.random.normal(0, np.pi / 20)