Back to home page

EIC code displayed by LXR

 
 

    


Warning, /detector_benchmarks/benchmarks/ecal_gaps/ecal_gaps.org is written in an unsupported language. File is not indexed.

0001 #+PROPERTY: header-args:jupyter-python :session /jpy:localhost#8888:gap :async yes :results drawer :exports both
0002 
0003 #+TITLE: ePIC ECal gap study
0004 #+AUTHOR: Dmitry Kalinkin
0005 #+OPTIONS: d:t
0006 
0007 #+begin_src jupyter-python :results silent
0008 import os
0009 from pathlib import Path
0010 
0011 import awkward as ak
0012 import boost_histogram as bh
0013 import dask
0014 import dask_awkward as dak
0015 import dask_histogram as dh
0016 import numpy as np
0017 import uproot
0018 #+end_src   
0019 
0020 #+begin_src jupyter-python :results slient
0021 from dask.distributed import Client
0022 client = Client(os.environ.get("DASK_SCHEDULER", "localhost:8786"))
0023 #+end_src
0024 
0025 * Plotting setup
0026 
0027 #+begin_src jupyter-python :results silent
0028 import matplotlib as mpl
0029 import matplotlib.pyplot as plt
0030        
0031 def setup_presentation_style():
0032     mpl.rcParams.update(mpl.rcParamsDefault)
0033     plt.style.use('ggplot')
0034     plt.rcParams.update({
0035         'axes.labelsize': 8,
0036         'axes.titlesize': 9,
0037         'figure.titlesize': 9,
0038         'figure.figsize': (4, 3),
0039         'legend.fontsize': 7,
0040         'xtick.labelsize': 8,
0041         'ytick.labelsize': 8,
0042         'xaxis.labellocation': 'right',
0043         'yaxis.labellocation': 'top',
0044         'pgf.rcfonts': False,
0045     })
0046 
0047 setup_presentation_style()
0048 #+end_src       
0049 
0050 ** Settings
0051 
0052 #+begin_src jupyter-python :results silent
0053 DETECTOR_CONFIG=os.environ.get("DETECTOR_CONFIG")
0054 
0055 output_dir=Path(os.environ.get("OUTPUT_DIR", "./"))
0056 output_dir.mkdir(parents=True, exist_ok=True)
0057 #+end_src
0058 
0059 * Analysis
0060 
0061 #+begin_src jupyter-python :results silent
0062 def filter_name(name):
0063     return (
0064         "PARAMETERS" not in name
0065         and all(coll not in name for coll in ["_intMap", "_floatMap", "_stringMap", "_doubleMap"])
0066     )
0067 
0068 import functools
0069 
0070 axis_eta = bh.axis.Regular(200, -4, 4)
0071 axis_eta_coarse = bh.axis.Regular(100, -4, 4)
0072 
0073 @functools.cache
0074 def get_events(particle="e-", energy="20GeV", num_files=1):
0075     events = uproot.dask(
0076         {}
0077         | {f"sim_output/ecal_gaps/{DETECTOR_CONFIG}/{particle}/{energy}/3to50deg/{particle}_{energy}_3to50deg.{INDEX:04d}.eicrecon.tree.edm4eic.root": "events" for INDEX in range(num_files)}
0078         | {f"sim_output/ecal_gaps/{DETECTOR_CONFIG}/{particle}/{energy}/45to135deg/{particle}_{energy}_45to135deg.{INDEX:04d}.eicrecon.tree.edm4eic.root": "events" for INDEX in range(num_files)}
0079         | {f"sim_output/ecal_gaps/{DETECTOR_CONFIG}/{particle}/{energy}/130to177deg/{particle}_{energy}_130to177deg.{INDEX:04d}.eicrecon.tree.edm4eic.root": "events" for INDEX in range(num_files)}
0080         ,
0081         filter_name=filter_name, open_files=False, steps_per_file=1,
0082     )
0083 
0084     pt = np.hypot(events["MCParticles.momentum.x"][:,0], events["MCParticles.momentum.y"][:,0])
0085     theta = np.arctan2(pt, events["MCParticles.momentum.z"][:,0])
0086     eta = -np.log(np.tan(theta / 2))
0087     p = np.hypot(pt, events["MCParticles.momentum.z"][:,0])
0088 
0089     hist_norm = dh.factory(
0090         eta,
0091         axes=(
0092             axis_eta,
0093         ),
0094     ).compute()
0095     weight_lut = 1 / hist_norm.values(flow=True)
0096 
0097     def get_weight(array):
0098         if ak.backend(array) == "typetracer":
0099             ak.typetracer.touch_data(array)
0100             return array
0101         return ak.from_numpy(weight_lut[axis_eta.index(ak.to_numpy(array))])
0102 
0103     weights = eta.map_partitions(get_weight)
0104 
0105     events["p_thrown"] = p
0106     events["eta_thrown"] = eta
0107     events["weights"] = weights
0108 
0109     return events
0110 #+end_src
0111 
0112 #+begin_src jupyter-python
0113 particle = "e-"
0114 
0115 for energy in ["500MeV", "5GeV", "20GeV"]:
0116     events = get_events(particle=particle, energy=energy)
0117 
0118     for calo_name in ["EcalEndcapN", "EcalBarrelScFi", "EcalBarrelImaging", "EcalEndcapP"]:
0119         cond = ak.sum(events[f"{calo_name}RecHits.energy"], axis=1) > 10e-3 # GeV
0120 
0121         hist, profile = client.gather(client.compute([
0122             dh.factory(
0123                 events["eta_thrown"][cond],
0124                 (ak.sum(events[f"{calo_name}RecHits.energy"], axis=1) / events["p_thrown"])[cond],
0125                 axes=(
0126                     axis_eta,
0127                     bh.axis.Regular(100, 0.1, 1.1),
0128                 ),
0129                 weights=events["weights"][cond],
0130             ),
0131             dh.factory(
0132                 events["eta_thrown"][cond],
0133                 sample=(ak.sum(events[f"{calo_name}RecHits.energy"], axis=1) / events["p_thrown"])[cond],
0134                 storage=bh.storage.WeightedMean(),
0135                 axes=(
0136                     axis_eta_coarse,
0137                 ),
0138                 weights=events["weights"][cond],
0139             ),
0140         ]))
0141 
0142         cmap = plt.get_cmap(name="rainbow", lut=None).copy()
0143         cmap.set_under("none")
0144 
0145         plt.pcolormesh(
0146             hist.axes[0].edges,
0147             hist.axes[1].edges,
0148             hist.values().T,
0149             cmap=cmap,
0150             norm=mpl.colors.LogNorm(
0151                 vmin=np.min(hist.values()[hist.values() > 0]),
0152             ),
0153         )
0154         plt.colorbar()
0155         std = np.sqrt(profile.variances())
0156         cond = profile.values() > std
0157         plt.errorbar(profile.axes[0].centers[cond], profile.values()[cond], yerr=std[cond], marker=".", markersize=2, color="black", ls="none", lw=0.6, capsize=1.)
0158         plt.xlabel(r"$\eta_{thrown}$")
0159         plt.ylabel(r"$\sum E_{\mathrm{dep.}} / p_{\mathrm{thrown}}$")
0160         plt.title(f"{energy} {particle} in {calo_name}")
0161         plt.minorticks_on()
0162         plt.savefig(output_dir / f"ecal_gap_{particle}_{energy}_{calo_name}.png", bbox_inches="tight")
0163         plt.show()
0164         plt.clf()
0165 #+end_src
0166 
0167 #+begin_src jupyter-python
0168 particle = "e-"
0169 
0170 for energy in ["500MeV", "5GeV", "20GeV"]:
0171     events = get_events(particle=particle, energy=energy)
0172 
0173     calos = ["EcalEndcapN", "EcalBarrelScFi", "EcalEndcapP"]
0174     total_energy = sum([
0175         ak.sum(events[f"{calo_name}RecHits.energy"], axis=1)
0176         for calo_name in calos
0177     ])
0178 
0179     hist, profile = client.gather(client.compute([
0180         dh.factory(
0181             events["eta_thrown"],
0182             total_energy / events["p_thrown"],
0183             axes=(
0184                 axis_eta,
0185                 bh.axis.Regular(100, 0.1, 1.1),
0186             ),
0187             weights=events["weights"],
0188         ),
0189         dh.factory(
0190             events["eta_thrown"],
0191             sample=total_energy / events["p_thrown"],
0192             storage=bh.storage.WeightedMean(),
0193             axes=(
0194                 axis_eta_coarse,
0195             ),
0196             weights=events["weights"],
0197         ),
0198     ]))
0199 
0200     cmap = plt.get_cmap(name="rainbow", lut=None).copy()
0201     cmap.set_under("none")
0202 
0203     plt.pcolormesh(
0204         hist.axes[0].edges,
0205         hist.axes[1].edges,
0206         hist.values().T,
0207         cmap=cmap,
0208         norm=mpl.colors.LogNorm(
0209             vmin=np.min(hist.values()[hist.values() > 0]),
0210         ),
0211     )
0212     plt.colorbar()
0213     std = np.sqrt(profile.variances())
0214     cond = profile.values() > std
0215     plt.errorbar(profile.axes[0].centers[cond], profile.values()[cond], yerr=std[cond], marker=".", markersize=2, color="black", ls="none", lw=0.6, capsize=1.)
0216     plt.xlabel(r"$\eta_{thrown}$")
0217     plt.ylabel(r"$\sum E_{\mathrm{dep.}} / p_{\mathrm{thrown}}$")
0218     plt.title(f"{energy} {particle}\n" + "+".join(calos))
0219     plt.minorticks_on()
0220     plt.savefig(output_dir / f"ecal_gap_{particle}_{energy}_sum_all.png", bbox_inches="tight")
0221     plt.show()
0222     plt.clf()
0223 #+end_src