|
16 | 16 |
|
17 | 17 | u = pint.get_application_registry() |
18 | 18 |
|
19 | | -g_world_size = 200 * u.cm |
| 19 | +g_world_size = 50 * u.cm |
20 | 20 | g_world_size_cm = g_world_size.to(u.cm).magnitude |
21 | 21 |
|
22 | 22 | macro = """ |
@@ -102,9 +102,14 @@ def simulate( |
102 | 102 | em_physics: str = "Livermore", |
103 | 103 | max_threads: int = 1, |
104 | 104 | ) -> str: |
105 | | - output = ( |
106 | | - f"output-energy_loss-{energy:.0f}-{material}-{had_physics}-{em_physics}.lh5" |
107 | | - ) |
| 105 | + if energy > 1: |
| 106 | + output = ( |
| 107 | + f"output-energy_loss-{energy:.0f}-{material}-{had_physics}-{em_physics}.lh5" |
| 108 | + ) |
| 109 | + else: |
| 110 | + output = ( |
| 111 | + f"output-energy_loss-{energy:.2f}-{material}-{had_physics}-{em_physics}.lh5" |
| 112 | + ) |
108 | 113 |
|
109 | 114 | events = 100000 * int(os.environ.get("RMG_STATS_FACTOR", "1")) |
110 | 115 |
|
@@ -136,7 +141,10 @@ def calculate_dEdx(remage_output: str): |
136 | 141 | mask = tracks["parent_trackid"] == 0 |
137 | 142 |
|
138 | 143 | # read in event data |
139 | | - stp = lh5.read("stp/", remage_output) |
| 144 | + try: |
| 145 | + stp = lh5.read("stp/", remage_output) |
| 146 | + except lh5.exceptions.LH5DecodeError: |
| 147 | + return np.array([0]) |
140 | 148 |
|
141 | 149 | c = sp.constants.physical_constants["speed of light in vacuum"][0] |
142 | 150 | m = sp.constants.physical_constants["muon mass energy equivalent in MeV"][0] |
@@ -363,7 +371,10 @@ def plot(energies, materials, had_physics, em_physics, outfiles): |
363 | 371 | for had_physic in had_physics: |
364 | 372 | for em_physic in em_physics: |
365 | 373 | remage_output = outfiles[(energy, material, had_physic, em_physic)] |
366 | | - dEdx_sims[(had_physic, em_physic)] = calculate_dEdx(remage_output) |
| 374 | + out = calculate_dEdx(remage_output) |
| 375 | + if isinstance(out, float): |
| 376 | + out = np.array([out]) |
| 377 | + dEdx_sims[(had_physic, em_physic)] = out |
367 | 378 |
|
368 | 379 | fig, ax = plt.subplots() |
369 | 380 |
|
@@ -438,6 +449,48 @@ def plot(energies, materials, had_physics, em_physics, outfiles): |
438 | 449 | ) |
439 | 450 |
|
440 | 451 |
|
| 452 | +def plot_energy_range(energies, materials, had_physics, em_physics, outfiles): |
| 453 | + |
| 454 | + for material in materials: |
| 455 | + dEdx_sims = {} |
| 456 | + for energy in energies: |
| 457 | + for had_physic in had_physics: |
| 458 | + for em_physic in em_physics: |
| 459 | + remage_output = outfiles[(energy, material, had_physic, em_physic)] |
| 460 | + dEdx_sims[energy] = calculate_dEdx(remage_output) |
| 461 | + |
| 462 | + x = np.array(energies) |
| 463 | + y = np.array([np.mean(dEdx_sim) for dEdx_sim in dEdx_sims.values()]) |
| 464 | + mask = y > 0 |
| 465 | + x = x[mask] |
| 466 | + y = y[mask] |
| 467 | + y_unc = np.array( |
| 468 | + [ |
| 469 | + np.std(dEdx_sim) / np.sqrt(len(dEdx_sim)) |
| 470 | + for dEdx_sim in dEdx_sims.values() |
| 471 | + ] |
| 472 | + ) |
| 473 | + |
| 474 | + x_exp = np.array(lookup_tables["energy_loss"]["total"][material])[:, 0] / 1e3 |
| 475 | + y_exp = ( |
| 476 | + np.array(lookup_tables["energy_loss"]["total"][material])[:, 1] |
| 477 | + * lookup_tables["densities"][material] |
| 478 | + ) |
| 479 | + |
| 480 | + fig, ax = plt.subplots() |
| 481 | + ax.errorbar(x, y, yerr=y_unc, fmt="o", label="simulation") |
| 482 | + ax.plot(x_exp, y_exp, label="expected") |
| 483 | + ax.set_xscale("log") |
| 484 | + ax.set_xlabel("muon energy [GeV]") |
| 485 | + ax.set_ylabel("mean energy loss dE/dx [MeV/cm]") |
| 486 | + ax.legend() |
| 487 | + ax.set_title( |
| 488 | + f"Energy loss of muons in {material}", |
| 489 | + size=8, |
| 490 | + ) |
| 491 | + fig.savefig(f"energy_loss_{material}_energy_range.output.png") |
| 492 | + |
| 493 | + |
441 | 494 | def _simulate_case( |
442 | 495 | case: tuple[float, str, str, str], max_threads: int = 1 |
443 | 496 | ) -> tuple[tuple[float, str, str, str], str]: |
@@ -521,3 +574,37 @@ def test_energy_loss(): |
521 | 574 | outfiles[key] = output |
522 | 575 |
|
523 | 576 | plot(energies, materials, had_physics_list, em_physics_list, outfiles) |
| 577 | + |
| 578 | + energies = np.array(lookup_tables["energy_loss"]["total"]["lar"])[:, 0][10::2] / 1e3 |
| 579 | + materials = ["lar", "water"] |
| 580 | + had_physics_list = ["Shielding"] |
| 581 | + em_physics_list = ["Livermore"] |
| 582 | + |
| 583 | + cases = [ |
| 584 | + (energy, material, had_physics, em_physics) |
| 585 | + for material in materials |
| 586 | + for had_physics in had_physics_list |
| 587 | + for em_physics in em_physics_list |
| 588 | + for energy in energies |
| 589 | + ] |
| 590 | + |
| 591 | + max_workers = min(len(cases), os.cpu_count() // 2) |
| 592 | + max_threads = os.cpu_count() // 2 // max_workers |
| 593 | + max_threads = max(1, max_threads) |
| 594 | + |
| 595 | + outfiles = {} |
| 596 | + if max_workers == 1: |
| 597 | + for case in cases: |
| 598 | + key, output = _simulate_case(case, max_threads=max_threads) |
| 599 | + outfiles[key] = output |
| 600 | + else: |
| 601 | + with ProcessPoolExecutor(max_workers=max_workers) as ex: |
| 602 | + futures = [ |
| 603 | + ex.submit(_simulate_case, case, max_threads=max_threads) |
| 604 | + for case in cases |
| 605 | + ] |
| 606 | + for fut in as_completed(futures): |
| 607 | + key, output = fut.result() |
| 608 | + outfiles[key] = output |
| 609 | + |
| 610 | + plot_energy_range(energies, materials, had_physics_list, em_physics_list, outfiles) |
0 commit comments