From 22b07fd94184eab794bf3b334e74101714f902f4 Mon Sep 17 00:00:00 2001
From: Chao Peng <cpeng@anl.gov>
Date: Tue, 25 May 2021 00:49:28 +0000
Subject: [PATCH] remove compact files from barrel emcal benchmarks

---
 .../compact/barrel_ecal_test.xml              | 129 ------------------
 benchmarks/sampling_ecal/run_emcal_barrel.sh  |   8 +-
 .../sampling_ecal/scripts/draw_cluster.py     |  67 +++++----
 .../scripts/draw_cluster_layers.py            |  43 ++++--
 benchmarks/sampling_ecal/scripts/utils.py     |  52 ++++++-
 5 files changed, 121 insertions(+), 178 deletions(-)
 delete mode 100644 benchmarks/sampling_ecal/compact/barrel_ecal_test.xml

diff --git a/benchmarks/sampling_ecal/compact/barrel_ecal_test.xml b/benchmarks/sampling_ecal/compact/barrel_ecal_test.xml
deleted file mode 100644
index c194cb19..00000000
--- a/benchmarks/sampling_ecal/compact/barrel_ecal_test.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<lccdd>
-  <info 
-    name="topside" 
-    title="Time-of-flight Optimized PID Silicon Detector for EIC (TOPSiDE)" 
-    author="Whitney R. Armstrong" 
-    url="" 
-    status="development" 
-    version="$Id: 1$">
-    <comment> </comment>
-  </info>
-
-  <define>
-    <include ref="topside/topside_defs.xml" />
-    <include ref="eic/eic_defs.xml" />
-  </define>
-
-  <properties>
-    <matrix name="RINDEX__Vacuum" coldim="2" values="
-      1.0*eV 1.0
-      5.1*eV 1.0
-      "/>
-    <matrix name="RINDEX__Air" coldim="2" values="
-      1.0*eV 1.00029
-      5.1*eV 1.00029
-      "/>
-    <matrix name="RINDEX__Quartz" coldim="2" values="
-      1.0*eV 1.46
-      5.1*eV 1.46
-      "/>
-    <matrix name="RINDEX__N2" coldim="2" values="
-      1.0*eV 1.00033
-      4.0*eV 1.00033
-      5.1*eV 1.00033
-      "/>
-    <matrix name="RINDEX__Pyrex" coldim="2" values="
-      1.0*eV 1.5
-      4.0*eV 1.5
-      5.1*eV 1.5
-      "/>
-    <matrix name= "REFLECTIVITY_mirror" coldim="2" values="
-      1.0*eV  0.9
-      4.0*eV  0.9
-      5.1*eV  0.9
-    "/>
-  </properties>
-
-  <includes>
-    <gdmlFile ref="topside/elements.xml"/>
-    <gdmlFile ref="topside/materials.xml"/>
-  </includes>
-
-  <materials>
-    <material name="AirOptical">
-      <D type="density" unit="g/cm3" value="0.0012"/>
-      <fraction n="0.754" ref="N"/>
-      <fraction n="0.234" ref="O"/>
-      <fraction n="0.012" ref="Ar"/>
-      <property name="RINDEX" ref="RINDEX__Vacuum"/>
-    </material>
-    <material name="N2cherenkov">
-      <D type="density" value="0.00125" unit="g/cm3"/>
-      <composite n="1" ref="N"/>
-      <property name="RINDEX"  ref="RINDEX__N2"/>
-    </material>
-    <material name="PyrexGlass">
-      <D type="density" value="2.23" unit="g/cm3"/>
-      <fraction n="0.806" ref="SiliconOxide"/>
-      <fraction n="0.130" ref="BoronOxide"/>
-      <fraction n="0.040" ref="SodiumOxide"/>
-      <fraction n="0.023" ref="AluminumOxide"/>
-      <property name="RINDEX" ref="RINDEX__Pyrex"/>
-    </material>
-  </materials>
-
-  <surfaces>
-    <comment> For the values of "finish", model and type, see TGeoOpticalSurface.h !
-    </comment>
-    <opticalsurface finish="polished" model="glisur" name="MirrorOpticalSurface" type="dielectric_metal" value="0">
-      <property name="REFLECTIVITY" ref="REFLECTIVITY_mirror"/>
-      <property name="RINDEX"       coldim="2" values="1.034*eV  1.5   4.136*eV  1.5"/>
-      <!--<property name="EFFICIENCY"   ref="EFFICIENCY0x8b77240"/>-->
-    </opticalsurface>
-    <opticalsurface name="mirror2" finish="polished" model="glisur" type="dielectric_dielectric">
-      <property name="REFLECTIVITY"            coldim="2" values="1.034*eV  0.8   4.136*eV  0.9"/>
-      <property name="EFFICIENCY"              coldim="2" values="2.034*eV  0.8   4.136*eV  1.0"/>
-      <property name="RINDEX"                  coldim="2" values="1.034*eV  1.5   4.136*eV  1.5"/>
-    </opticalsurface>
-
-  </surfaces>
-  <limits>
-    <limitset name="EICBeamlineLimits">
-      <limit name="step_length_max" particles="*" value="1.0" unit="mm" />
-      <limit name="track_length_max" particles="*" value="1.0" unit="mm" />
-      <limit name="time_max" particles="*" value="0.1" unit="ns" />
-      <limit name="ekin_min" particles="*" value="0.001" unit="MeV" />
-      <limit name="range_min" particles="*" value="0.1" unit="mm" />
-    </limitset>
-    <limitset name="cal_limits">
-      <limit name="step_length_max" particles="*" value="0.1" unit="mm"/>
-    </limitset>
-  </limits>
-
-  <display>
-  <include ref="topside/display.xml" />
-  </display>
-
-  <!--
-  <include ref="topside/vertex_tracker.xml"/>
-  -->
-  <include ref="topside/beampipe.xml"/>
-  <include ref="topside/silicon_tracker.xml"/>
-  <!--<include ref="topside/ecal.xml"/>-->        <comment> old version of em barrel - SiW sampling design </comment> 
-  <include ref="topside/ecal_wAstroPixSiW.xml"/>  <comment> new version of em barrel - SiW AstroPix sampling design </comment>
-  <!--
-  <include ref="topside/hcal.xml"/>
-  <include ref="topside/forward_rich.xml"/>
-  <include ref="topside/solenoid.xml"/>
-  <include ref="topside/roman_pots.xml"/>
-  <include ref="eic/forward_ion_beamline.xml"/>
-  -->
-
-  <detectors>
-  </detectors>
-  <readouts>
-  </readouts>
-
-
-</lccdd>
diff --git a/benchmarks/sampling_ecal/run_emcal_barrel.sh b/benchmarks/sampling_ecal/run_emcal_barrel.sh
index 2b076e02..aaf5ab56 100644
--- a/benchmarks/sampling_ecal/run_emcal_barrel.sh
+++ b/benchmarks/sampling_ecal/run_emcal_barrel.sh
@@ -8,13 +8,7 @@ do
     esac
 done
 
-if [[ ! -n  "${CB_EMCAL_TEST_DETECTOR}" ]] ; then
-  export CB_EMCAL_TEST_DETECTOR="barrel_ecal_test"
-fi
-# copy the compact file to detector path
-cp benchmarks/sampling_ecal/compact/${CB_EMCAL_TEST_DETECTOR}.xml ${DETECTOR_PATH}
-export CB_EMCAL_COMPACT_PATH=${DETECTOR_PATH}/${CB_EMCAL_TEST_DETECTOR}.xml
-
+export CB_EMCAL_COMPACT_PATH=${DETECTOR_PATH}/${JUGGLER_DETECTOR}.xml
 
 if [[ ! -n  "${CB_EMCAL_NUMEV}" ]] ; then
   export CB_EMCAL_NUMEV=1000
diff --git a/benchmarks/sampling_ecal/scripts/draw_cluster.py b/benchmarks/sampling_ecal/scripts/draw_cluster.py
index 31aafb78..5b6c93bd 100644
--- a/benchmarks/sampling_ecal/scripts/draw_cluster.py
+++ b/benchmarks/sampling_ecal/scripts/draw_cluster.py
@@ -107,6 +107,8 @@ if __name__ == '__main__':
                         help='bin size for projection plot (mrad)')
     parser.add_argument('--topo-range', type=float, default=50.0, dest='topo_range',
                         help='half range for projection plot (mrad)')
+    parser.add_argument('--zoom-factor', type=float, default=1.0, dest='zoom_factor',
+                        help='factor for zoom-in')
     args = parser.parse_args()
 
 
@@ -115,7 +117,7 @@ if __name__ == '__main__':
         'EcalBarrelAstroPix_RMin',
         'EcalBarrelAstroPix_ReadoutLayerThickness',
         'EcalBarrelAstroPix_ReadoutLayerNumber',
-        'EcalBarrelAstroPix_Length'
+        'EcalBarrelAstroPix_Length',
     ])
     if not len(desc):
         # or define Ecal shapes
@@ -130,22 +132,39 @@ if __name__ == '__main__':
     # read data
     load_root_macros(args.macros)
     df = get_hits_data(args.file, args.iev, branch=args.branch)
-    dfmcp = get_mcp_data(args.file, args.iev, 'mcparticles2')
-    vec = dfmcp.loc[dfmcp['status'] == 24578, ['px', 'py', 'pz']].iloc[0].values
-    vec = vec/np.linalg.norm(vec)
     df = df[df['cluster'] == args.icl]
     if not len(df):
         print("Error: do not find any hits for cluster {:d} in event {:d}".format(args.icl, args.iev))
         exit(-1)
+    # convert to polar coordinates (mrad), and stack all r values
+    df['r'] = np.sqrt(df['x'].values**2 + df['y'].values**2 + df['z'].values**2)
+    df['phi'] = np.arctan2(df['y'].values, df['x'].values)*1000.
+    df['theta'] = np.arccos(df['z'].values/df['r'].values)*1000.
+    df['eta'] = -np.log(np.tan(df['theta'].values/1000./2.))
+
+    # truth
+    dfmcp = get_mcp_simple(args.file, args.iev, 'mcparticles2').iloc[0]
+    pdgbase = ROOT.TDatabasePDG()
+    inpart = pdgbase.GetParticle(int(dfmcp['pid']))
+    print("Incoming particle = {}, pdgcode = {}, charge = {}, mass = {}"\
+          .format(inpart.GetName(), inpart.PdgCode(), inpart.Charge(), inpart.Mass()))
+    # neutral particle, no need to consider magnetic field
+    if np.isclose(inpart.Charge(), 0., rtol=1e-5):
+        vec = dfmcp[['px', 'py', 'pz']].values
+    # charge particle, use the cluster center
+    else:
+        flayer = df[df['layer'] == df['layer'].min()]
+        vec = flayer[['x', 'y', 'z']].mean().values
+    vec = vec/np.linalg.norm(vec)
+
     # particle line from (0, 0, 0) to the inner Ecal surface
     length = rmin/np.sqrt(vec[0]**2 + vec[1]**2)
     pline = np.transpose(vec*np.mgrid[0:length:2j][:, np.newaxis])
-
+    cmap = truncate_colormap(plt.get_cmap('jet'), 0.1, 0.9)
 
     os.makedirs(args.outdir, exist_ok=True)
     # cluster plot
-    cmap = truncate_colormap(plt.get_cmap('jet'), 0.1, 0.9)
-    fig = plt.figure(figsize=(20, 16), dpi=160)
+    fig = plt.figure(figsize=(15, 12), dpi=160)
     ax = fig.add_subplot(111, projection='3d')
     # draw particle line
     ax.plot(*pline[[2, 1]], '--', zs=pline[0], color='green')
@@ -161,17 +180,17 @@ if __name__ == '__main__':
 
 
     # zoomed-in cluster plot
-    fig = plt.figure(figsize=(20, 16), dpi=160)
+    fig = plt.figure(figsize=(15, 12), dpi=160)
     ax = fig.add_subplot(111, projection='3d')
     # draw particle line
     ax.plot(*pline[[2, 1]], '--', zs=pline[0], color='green')
     # draw hits
     draw_hits3d(ax, df[['x', 'y', 'z', 'edep']].values, cmap, s=20.0)
-    draw_track_fit(ax, df, stop_layer=args.stop,
-                   scat_kw=dict(color='k', s=50.0), line_kw=dict(linestyle=':', color='k', lw=3))
+    # draw_track_fit(ax, df, stop_layer=args.stop,
+    #                scat_kw=dict(color='k', s=50.0), line_kw=dict(linestyle=':', color='k', lw=3))
     # view range
     center = (length + thickness/2.)*vec
-    ranges = np.vstack([center - thickness/4., center + thickness/4.]).T
+    ranges = np.vstack([center - thickness/args.zoom_factor, center + thickness/args.zoom_factor]).T
     ax.set_zlim(*ranges[0])
     ax.set_ylim(*ranges[1])
     ax.set_xlim(*ranges[2])
@@ -181,31 +200,27 @@ if __name__ == '__main__':
 
 
     # projection plot
-    # convert to polar coordinates (mrad), and stack all r values
-    df['r'] = np.sqrt(df['x'].values**2 + df['y'].values**2 + df['z'].values**2)
-    df['phi'] = np.arctan2(df['y'].values, df['x'].values)*1000.
-    df['theta'] = np.arccos(df['z'].values/df['r'].values)*1000.
-
     # convert to mrad
     vecp = np.asarray([np.arccos(vec[2]), np.arctan2(vec[1], vec[0])])*1000.
     phi_rg = np.asarray([vecp[1] - args.topo_range, vecp[1] + args.topo_range])
     th_rg = np.asarray([vecp[0] - args.topo_range, vecp[0] + args.topo_range])
+    eta_rg = np.resize(-np.log(np.tan(vecp[0]/1000./2.)), 2) + np.asarray([-args.topo_range, args.topo_range])/1000.
 
-    fig, axs = plt.subplots(1, 2, figsize=(17, 16), dpi=160, gridspec_kw={'wspace':0., 'width_ratios': [16, 1]})
-    ax, sm = draw_heatmap(axs[0], df['theta'].values, df['phi'].values, weights=df['edep'].values,
-                          bins=(np.arange(*th_rg, step=args.topo_size), np.arange(*phi_rg, step=args.topo_size)),
+    fig, axs = plt.subplots(1, 2, figsize=(13, 12), dpi=160, gridspec_kw={'wspace':0., 'width_ratios': [12, 1]})
+    ax, sm = draw_heatmap(axs[0], df['eta'].values, df['phi'].values, weights=df['edep'].values,
+                          bins=(np.arange(*eta_rg, step=args.topo_size/1000.), np.arange(*phi_rg, step=args.topo_size)),
                           cmap=cmap, cmin=0., pc_kw=dict(alpha=0.8, edgecolor='k'))
 
-    ax.set_xlabel(r'$\theta$ (mrad)', fontsize=28)
-    ax.set_ylabel(r'$\phi$ (mrad)', fontsize=28)
-    ax.tick_params(labelsize=24)
+    ax.set_ylabel(r'$\phi$ (mrad)', fontsize=32)
+    ax.set_xlabel(r'$\eta$', fontsize=32)
+    ax.tick_params(labelsize=28)
     ax.xaxis.set_minor_locator(MultipleLocator(5))
     ax.yaxis.set_minor_locator(MultipleLocator(5))
     ax.grid(linestyle=':', which='both')
     ax.set_axisbelow(True)
-    cb = plt.colorbar(sm, cax=axs[1], shrink=0.85)
-    cb.ax.tick_params(labelsize=24)
-    cb.ax.get_yaxis().labelpad = 24
-    cb.ax.set_ylabel('Energy Deposit (MeV)', rotation=90, fontsize=28)
+    cb = plt.colorbar(sm, cax=axs[1], shrink=0.85, aspect=1.2*20)
+    cb.ax.tick_params(labelsize=28)
+    cb.ax.get_yaxis().labelpad = 10
+    cb.ax.set_ylabel('Energy Deposit (MeV)', rotation=90, fontsize=32)
     fig.savefig(os.path.join(args.outdir, 'e{}_topo.png'.format(args.iev)))
 
diff --git a/benchmarks/sampling_ecal/scripts/draw_cluster_layers.py b/benchmarks/sampling_ecal/scripts/draw_cluster_layers.py
index e3b9ed3d..18ce1c2a 100644
--- a/benchmarks/sampling_ecal/scripts/draw_cluster_layers.py
+++ b/benchmarks/sampling_ecal/scripts/draw_cluster_layers.py
@@ -71,9 +71,8 @@ if __name__ == '__main__':
         'EcalBarrelAstroPix_RMin',
         'EcalBarrelAstroPix_ReadoutLayerThickness',
         'EcalBarrelAstroPix_ReadoutLayerNumber',
-        'EcalBarrelAstroPix_Length'
+        'EcalBarrelAstroPix_Length',
     ])
-
     if not len(desc):
         # or define Ecal shapes
         rmin, thickness, length = 890, 20*(10. + 1.65), 860*2+500
@@ -87,27 +86,41 @@ if __name__ == '__main__':
     # read data
     load_root_macros(args.macros)
     df = get_hits_data(args.file, args.iev, args.branch)
-    dfmcp = get_mcp_data(args.file, args.iev, 'mcparticles2')
-    vec = dfmcp.loc[dfmcp['status'] == 24578, ['px', 'py', 'pz']].iloc[0].values
-    vec = vec/np.linalg.norm(vec)
     df = df[df['cluster'] == args.icl]
+    if not len(df):
+        print("Error: do not find any hits for cluster {:d} in event {:d}".format(args.icl, args.iev))
+        exit(-1)
     # convert to polar coordinates (mrad), and stack all r values
     df['r'] = np.sqrt(df['x'].values**2 + df['y'].values**2 + df['z'].values**2)
     df['phi'] = np.arctan2(df['y'].values, df['x'].values)*1000.
     df['theta'] = np.arccos(df['z'].values/df['r'].values)*1000.
-    if not len(df):
-        print("Error: do not find any hits for cluster {:d} in event {:d}".format(args.icl, args.iev))
-        exit(-1)
+    df['eta'] = -np.log(np.tan(df['theta'].values/1000./2.))
+
+    # truth
+    dfmcp = get_mcp_simple(args.file, args.iev, 'mcparticles2').iloc[0]
+    pdgbase = ROOT.TDatabasePDG()
+    inpart = pdgbase.GetParticle(int(dfmcp['pid']))
+    print("Incoming particle = {}, pdgcode = {}, charge = {}, mass = {}"\
+          .format(inpart.GetName(), inpart.PdgCode(), inpart.Charge(), inpart.Mass()))
+    # neutral particle, no need to consider magnetic field
+    if np.isclose(inpart.Charge(), 0., rtol=1e-5):
+        vec = dfmcp[['px', 'py', 'pz']].values
+    # charge particle, use the cluster center
+    else:
+        flayer = df[df['layer'] == df['layer'].min()]
+        vec = flayer[['x', 'y', 'z']].mean().values
+    vec = vec/np.linalg.norm(vec)
+
     # particle line from (0, 0, 0) to the inner Ecal surface
     length = rmin/np.sqrt(vec[0]**2 + vec[1]**2)
     pline = np.transpose(vec*np.mgrid[0:length:2j][:, np.newaxis])
     cmap = truncate_colormap(plt.get_cmap('jet'), 0.1, 0.9)
 
-
     # convert truth to mrad
     vecp = np.asarray([np.arccos(vec[2]), np.arctan2(vec[1], vec[0])])*1000.
     phi_rg = np.asarray([vecp[1] - args.topo_range, vecp[1] + args.topo_range])
     th_rg = np.asarray([vecp[0] - args.topo_range, vecp[0] + args.topo_range])
+    eta_rg = np.resize(-np.log(np.tan(vecp[0]/1000./2.)), 2) + np.asarray([-args.topo_range, args.topo_range])/1000.
 
     os.makedirs(args.outdir, exist_ok=True)
     # cluster plot by layers (rebinned)
@@ -117,11 +130,11 @@ if __name__ == '__main__':
     for i in np.arange(1, df['layer'].max() + 1, dtype=int):
         data = df[df['layer'] == i]
         fig, axs = plt.subplots(1, 2, figsize=(17, 16), dpi=160, gridspec_kw={'wspace':0., 'width_ratios': [16, 1]})
-        ax, sm = draw_heatmap(axs[0], data['theta'].values, data['phi'].values, weights=data['edep'].values,
-                              bins=(np.arange(*th_rg, step=args.topo_size), np.arange(*phi_rg, step=args.topo_size)),
+        ax, sm = draw_heatmap(axs[0], data['eta'].values, data['phi'].values, weights=data['edep'].values,
+                              bins=(np.arange(*eta_rg, step=args.topo_size/1000.), np.arange(*phi_rg, step=args.topo_size)),
                               cmap=cmap, vmin=0.0, vmax=1.0, pc_kw=dict(alpha=0.8, edgecolor='k'))
         ax.set_ylabel(r'$\phi$ (mrad)', fontsize=28)
-        ax.set_xlabel(r'$\theta$ (mrad)', fontsize=28)
+        ax.set_xlabel(r'$\eta$', fontsize=28)
         ax.tick_params(labelsize=24)
         ax.xaxis.set_minor_locator(MultipleLocator(5))
         ax.yaxis.set_minor_locator(MultipleLocator(5))
@@ -155,11 +168,11 @@ if __name__ == '__main__':
         fig, axs = plt.subplots(1, 2, figsize=(17, 16), dpi=160, gridspec_kw={'wspace':0., 'width_ratios': [16, 1]})
         ax = axs[0]
         colors = cmap(data['edep']/1.0)
-        ax.scatter(data['theta'].values, data['phi'].values, c=colors, marker='s', s=15.0)
-        ax.set_xlim(*th_rg)
+        ax.scatter(data['eta'].values, data['phi'].values, c=colors, marker='s', s=15.0)
+        ax.set_xlim(*eta_rg)
         ax.set_ylim(*phi_rg)
         ax.set_ylabel(r'$\phi$ (mrad)', fontsize=28)
-        ax.set_xlabel(r'$\theta$ (mrad)', fontsize=28)
+        ax.set_xlabel(r'$\eta$', fontsize=28)
         ax.tick_params(labelsize=24)
         ax.xaxis.set_minor_locator(MultipleLocator(5))
         ax.yaxis.set_minor_locator(MultipleLocator(5))
diff --git a/benchmarks/sampling_ecal/scripts/utils.py b/benchmarks/sampling_ecal/scripts/utils.py
index 2e81c508..a1e31a80 100644
--- a/benchmarks/sampling_ecal/scripts/utils.py
+++ b/benchmarks/sampling_ecal/scripts/utils.py
@@ -41,7 +41,7 @@ def get_mcp_data(path, evnums=None, branch='mcparticles2'):
     elif isinstance(evnums, int):
         evnums = [evnums]
 
-    dbuf = np.zeros(shape=(2000*len(evnums), 6))
+    dbuf = np.zeros(shape=(5000*len(evnums), 6))
     idb = 0
     for iev in evnums:
         if iev >= events.GetEntries():
@@ -122,3 +122,53 @@ def compact_constants(path, names):
     kernel.terminate()
     return vals
 
+
+# read clusters data from root file
+def get_clusters_data(path, evnums=None, branch='EcalBarrelClustersReco'):
+    f = ROOT.TFile(path)
+    events = f.events
+    if evnums is None:
+        evnums = np.arange(events.GetEntries())
+    elif isinstance(evnums, int):
+        evnums = [evnums]
+
+    dbuf = np.zeros(shape=(20*len(evnums), 6))
+    idb = 0
+    for iev in evnums:
+        if iev >= events.GetEntries():
+            print('Error: event {:d} is out of range (0 - {:d})'.format(iev, events.GetEntries() - 1))
+            continue
+
+        events.GetEntry(iev)
+        for k, cl in enumerate(getattr(events, branch)):
+            dbuf[idb] = (iev, k, cl.nhits, cl.edep, cl.cl_theta, cl.cl_phi)
+            idb += 1
+
+    return pd.DataFrame(data=dbuf[:idb], columns=['event', 'cluster', 'nhits', 'edep', 'cl_theta', 'cl_phi'])
+
+
+# read mc particles from root file
+def get_mcp_simple(path, evnums=None, branch='mcparticles2'):
+    f = ROOT.TFile(path)
+    events = f.events
+    if evnums is None:
+        evnums = np.arange(events.GetEntries())
+    elif isinstance(evnums, int):
+        evnums = [evnums]
+
+    dbuf = np.zeros(shape=(len(evnums), 6))
+    idb = 0
+    for iev in evnums:
+        if iev >= events.GetEntries():
+            print('Error: event {:d} is out of range (0 - {:d})'.format(iev, events.GetEntries() - 1))
+            continue
+
+        events.GetEntry(iev)
+        # extract full mc particle data
+        part = getattr(events, branch)[2]
+        dbuf[idb] = (iev, part.psx, part.psy, part.psz, part.pdgID, part.status)
+        idb += 1
+    return pd.DataFrame(data=dbuf[:idb], columns=['event', 'px', 'py', 'pz', 'pid', 'status'])
+
+
+
-- 
GitLab