Set up the Jupyter Notebook Environment
Overview
Teaching: 5 min
Exercises: 5 minQuestions
How to access simulation campaign output with python?
Objectives
Set up interactive python platform with Jupyter-notebook.
Set up Jupyter-notebook
- on Google Colab (recommended):
- copy this notebook to your own google drive.
- run the first cell under “setup” to install
uproot
andxrootd
(takes ~10 minutes)
- on your local environment:
- if not yet, install
uproot
andxrootd
with your local package manager, or, in jupyter-notebook, run!pip install xrootd !pip install uproot !pip install fsspec-xrootd !pip install particle ## optional
- if not yet, install
Note: we will be using other standard python packages such as
numpy
andpandas
, which are pre-installed on Colab.
Key Points
install uproot and xrootd
Introduction to the DD4hep simulation
Overview
Teaching: 25 min
Exercises: 15 minQuestions
Understand the inputs and outputs of the DD4hep simulation
Objectives
Event generation
Detector description
MCParticles and detector hits
Simulation campaign files
DD4hep simulation
This Geant4-based simualtion package propagates particles through magnetic field and materials. Particles and detector hits for each event are saved in the output rootfiles.
Input 1: Event generation
The collision event at ePIC, including the beam particles, vertices, and outgoing particles, are typically generated with a dedicated event generator, e.g. PYTHIA8 for specific physics channels. The outputs are provided to the DD4hep simulation in HEPMC3 format.
One can also use the DD4hep’s particle gun to generate outgoing particles with given vertex and distribution, see the previous tutorial on ddsim
.
Input 2: Detector description
The ePIC detector description in DD4hep is maintained on github. On the bottom of each sub-detector compact file under epic/compact
, the readout
block specifies how the detector hits are saved in the output rootfile.
Below is an example from epic/compact/tracking/vertex_barrel.xml:
<readouts>
<readout name="VertexBarrelHits">
<segmentation type="CartesianGridXY" grid_size_x="0.020*mm" grid_size_y="0.020*mm" />
<id>system:8,layer:4,module:12,sensor:2,x:32:-16,y:-16</id>
</readout>
</readouts>
All hits from this silicon vertex barrel detector, including their position, energy deposit, time, will be stored under the branch VertexBarrelHits
in output.
Each detector hit also comes an assigned 64-bit cell ID, with the last 32 bits from right to left represents the hit localtion in a 0.020 x 0.020 mm mesh grid. This segmentation often represents the detector granularity (in this case, the silicon pixel sensor size) that will be used later for hit digitization.
Output
The event
tree in the simulation output contains
MCParticles
: records the truth info of primary and secondary particles- Individual branches for signals from various sub-detector systems e.g.
VertexBarrelHits
Exercise 1.1: access simulation campaign rootfiles The simulation campaign website documents the available datasets and version information.
-Browse the directory For stand-alone
xrdfs
command, see the previous tutorials. Here we will proceed with the python interface:from XRootD import client # Create XRootD client eic_server = 'root://dtn-eic.jlab.org/' fs = client.FileSystem(eic_server) # List directory contents fpath = '/work/eic2/EPIC/RECO/24.12.0/epic_craterlake/SINGLE/e-/10GeV/130to177deg/' status, files = fs.dirlist(fpath) # Print files if status.ok: print(files.size) for entry in files: print(entry.name) else: print(f"Error: {status.message}")
-Open a simulation campaign file
fname = eic_server+fpath+'e-_10GeV_130to177deg.0307.eicrecon.tree.edm4eic.root' tree_name = "events" # tree_name = "podio_metadata" tree = ur.open(fname)[tree_name] print(f"Read {fname}:{tree_name}. \n {tree.num_entries} events in total")
Exercise 1.2: inspect available branches in a rootfile
- use
tree.keys(filter_name="*",recursive=False)
to display all branches- extract a given branch to dataframe
bname = "MCParticles" df = tree[bname].array(library="ak") df = ak.to_dataframe(df) print(df)
Exercise 1.3: extract momentum distribution of primary electrons
# select electrons from particle import Particle part = Particle.from_name("e-") pdg_id = part.pdgid.abspid condition1 = df["MCParticles.PDG"]==pdg_id # select primary particles condition2 = df["MCParticles.generatorStatus"]==1 # extract momentum and plot # all electrons df_new = df[condition1] mom = np.sqrt(df_new["MCParticles.momentum.x"]**2+df_new["MCParticles.momentum.y"]**2+df_new["MCParticles.momentum.z"]**2) bins = np.arange(0,20) _ = plt.hist(mom,bins=bins,alpha=0.5) # primary electrons df_new = df[condition1&condition2] mom = np.sqrt(df_new["MCParticles.momentum.x"]**2+df_new["MCParticles.momentum.y"]**2+df_new["MCParticles.momentum.z"]**2) _ = plt.hist(mom,bins=bins,histtype="step", color='r')
Key Points
event generator –
dd4hep
–> simulated hits and particles
Reconstruction workflow
Overview
Teaching: 25 min
Exercises: 15 minQuestions
Understand the EICrecon workflow
Objectives
Hit digitization
data model
Reconstruction algorithms
Reconstruction workflow
The ePIC reconsutrction framework EICrecon
is maintained on github. It process simulated hits from various detectors to reconstruct trajectory, PID, etc, and eventually reconstruct the simulated particle and physics observables at the vertex. In this section, we will use track reconstruction as an example. Please refer to the Lehigh reconstruction workfest presentations for reconstruction workflow of other systems.
Each reconstruction step involves 3 components:
- the algorithm,
- the JOmniFactory where algorithm and data type are declared.
- the factory generator to excute the algorithm.
Digitization
All simualted detector hits are digitized to reflect certain detector specs e.g. spatial and time resolution, and energy threshold. For example, the VertexBarrelHits
from simulation are digitized through the SiliconTrackerDigi
factory in EICrecon/src/detectors/BVTX/BVTX.cc
:
// Digitization
app->Add(new JOmniFactoryGeneratorT<SiliconTrackerDigi_factory>(
"SiBarrelVertexRawHits", // factory name
{
"VertexBarrelHits" // input
},
{
"SiBarrelVertexRawHits", // outputs
"SiBarrelVertexRawHitAssociations"
},
{
.threshold = 0.54 * dd4hep::keV, // configurations
},
app
));
The actual algorithm locates at EICrecon/src/algorithms/digi/SiliconTrackerDigi.cc
, with its input and output specified in SiliconTrackerDigi_factory.h
:
class SiliconTrackerDigi_factory : public JOmniFactory<SiliconTrackerDigi_factory, SiliconTrackerDigiConfig> {
public:
using AlgoT = eicrecon::SiliconTrackerDigi;
private:
std::unique_ptr<AlgoT> m_algo;
PodioInput<edm4hep::SimTrackerHit> m_sim_hits_input {this};
PodioOutput<edm4eic::RawTrackerHit> m_raw_hits_output {this};
PodioOutput<edm4eic::MCRecoTrackerHitAssociation> m_assoc_output {this};
ParameterRef<double> m_threshold {this, "threshold", config().threshold};
ParameterRef<double> m_timeResolution {this, "timeResolution", config().timeResolution};
...
By comparing the two blocks of code above, we can see that the digitized hits, SiBarrelVertexRawHits
, are stored in the data type RawTrackerHit
that is defined in the edm4eic data model:
edm4eic::RawTrackerHit:
Description: "Raw (digitized) tracker hit"
Author: "W. Armstrong, S. Joosten"
Members:
- uint64_t cellID // The detector specific (geometrical) cell id from segmentation
- int32_t charge
- int32_t timeStamp
In addition, the one-to-one relation between the sim hit and its digitized hit is stored as an MCRecoTrackerHitAssociation
object:
edm4eic::MCRecoTrackerHitAssociation:
Description: "Association between a RawTrackerHit and a SimTrackerHit"
Author: "C. Dilks, W. Deconinck"
Members:
- float weight // weight of this association
OneToOneRelations:
- edm4eic::RawTrackerHit rawHit // reference to the digitized hit
- edm4hep::SimTrackerHit simHit // reference to the simulated hit
which is filled in SiliconTrackerDigi.cc
:
auto hitassoc = associations->create();
hitassoc.setWeight(1.0);
hitassoc.setRawHit(item.second);
hitassoc.setSimHit(sim_hit);
Exercise 2.1: please find other detector systems that use
SiliconTrackerDigi
for digitization
Track Reconstruction
By default, we use the Combinatorial Kalman Filter from the ACTS library to handle track finding and fitting. This happens in the CKFTracking
factory.
Exercise 2.2: please find the inputs and outputs of
CKFTracking
, and draw a flow chart fromCentralTrackerMeasurements
toCentralTrackVertices
.
Reconstruction output
- events tree:
MCParticles
and detector sim hits are copied from simulation output to recon output- outputs from each step of recon algorithms must be either
edm4hep
oredm4eic
object if you want to save them in recon output - the default list of saved objects in recon output is defined in
EICrecon/src/services/io/podio/JEventProcessorPODIO.cc
. It can be configured in command line.
- podio_metadata tree:
events___idTable
provides a lookup table between output collection name and IDs.
Exercise 2.3: The vector member or relation of a given data collection is saved in a separate branch starts with “_”.
- Please use
tree.keys(filter_name="_CentralCKFTrajectories*", recursive=False)
to list those members in
CentralCKFTrajectories
- for a given event, the vector member
_CentralCKFTrajectories_measurementChi2
provides a list of chi2 for each meaurement hit respectively. If multiple trajectories are found for one event, you can useCentralCKFTrajectories.measurementChi2_begin
to locate the start index of a given trajectory (subentry).
Exercise 2.4:
CentralTrackerMeasurements
saved all available space points for tracking as 2D meaurement attached to representing surfaces.
- Please use the relation
_CentralTrackerMeasurements_hits
to trace back to the original detector hit collection (hint: use the collection ID lookup table), and obtain the 3D coordinate of the hit
What’s next
- Generate your own simulation and reconstruction rootfiles tutorial
- Contribute to reconstruction algorithsm tutorial
- Develop analysis benchmarks tutorial
Key Points
simulated hits–
EICrecon
–> reconstructed quantities