Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RootParticleReader.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RootParticleReader.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017-2021 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
10 
16 
17 #include <algorithm>
18 #include <cstdint>
19 #include <iostream>
20 #include <stdexcept>
21 
22 #include <TChain.h>
23 #include <TMathBase.h>
24 
28  : ActsExamples::IReader(),
29  m_cfg(config),
30  m_logger(Acts::getDefaultLogger(name(), level)) {
31  m_inputChain = new TChain(m_cfg.treeName.c_str());
32 
33  if (m_cfg.filePath.empty()) {
34  throw std::invalid_argument("Missing input filename");
35  }
36  if (m_cfg.treeName.empty()) {
37  throw std::invalid_argument("Missing tree name");
38  }
39 
43 
44  // Set the branches
45  m_inputChain->SetBranchAddress("event_id", &m_eventId);
46  m_inputChain->SetBranchAddress("particle_id", &m_particleId);
47  m_inputChain->SetBranchAddress("particle_type", &m_particleType);
48  m_inputChain->SetBranchAddress("process", &m_process);
49  m_inputChain->SetBranchAddress("vx", &m_vx);
50  m_inputChain->SetBranchAddress("vy", &m_vy);
51  m_inputChain->SetBranchAddress("vz", &m_vz);
52  m_inputChain->SetBranchAddress("vt", &m_vt);
53  m_inputChain->SetBranchAddress("p", &m_p);
54  m_inputChain->SetBranchAddress("px", &m_px);
55  m_inputChain->SetBranchAddress("py", &m_py);
56  m_inputChain->SetBranchAddress("pz", &m_pz);
57  m_inputChain->SetBranchAddress("m", &m_m);
58  m_inputChain->SetBranchAddress("q", &m_q);
59  m_inputChain->SetBranchAddress("eta", &m_eta);
60  m_inputChain->SetBranchAddress("phi", &m_phi);
61  m_inputChain->SetBranchAddress("pt", &m_pt);
62  m_inputChain->SetBranchAddress("vertex_primary", &m_vertexPrimary);
63  m_inputChain->SetBranchAddress("vertex_secondary", &m_vertexSecondary);
64  m_inputChain->SetBranchAddress("particle", &m_particle);
65  m_inputChain->SetBranchAddress("generation", &m_generation);
66  m_inputChain->SetBranchAddress("sub_particle", &m_subParticle);
67 
68  auto path = m_cfg.filePath;
69 
70  // add file to the input chain
71  m_inputChain->Add(path.c_str());
72  ACTS_DEBUG("Adding File " << path << " to tree '" << m_cfg.treeName << "'.");
73 
74  m_events = m_inputChain->GetEntries();
75  ACTS_DEBUG("The full chain has " << m_events << " entries.");
76 
77  // If the events are not in order, get the entry numbers for ordered events
78  if (not m_cfg.orderedEvents) {
79  m_entryNumbers.resize(m_events);
80  m_inputChain->Draw("event_id", "", "goff");
81  // Sort to get the entry numbers of the ordered events
82  TMath::Sort(m_inputChain->GetEntries(), m_inputChain->GetV1(),
83  m_entryNumbers.data(), false);
84  }
85 }
86 
88  const {
89  return {0u, m_events};
90 }
91 
93  delete m_particleId;
94  delete m_particleType;
95  delete m_process;
96  delete m_vx;
97  delete m_vy;
98  delete m_vz;
99  delete m_vt;
100  delete m_p;
101  delete m_px;
102  delete m_py;
103  delete m_pz;
104  delete m_m;
105  delete m_q;
106  delete m_eta;
107  delete m_phi;
108  delete m_pt;
109  delete m_vertexPrimary;
110  delete m_vertexSecondary;
111  delete m_particle;
112  delete m_generation;
113  delete m_subParticle;
114 }
115 
117  const ActsExamples::AlgorithmContext& context) {
118  ACTS_DEBUG("Trying to read recorded particles.");
119 
120  // read in the particle
121  if (m_inputChain != nullptr && context.eventNumber < m_events) {
122  // lock the mutex
123  std::lock_guard<std::mutex> lock(m_read_mutex);
124  // now read
125 
126  // The particle collection to be written
127  SimParticleContainer particleContainer;
128 
129  // Primary vertex collection
130  std::vector<uint32_t> priVtxCollection;
131  // Secondary vertex collection
132  std::vector<uint32_t> secVtxCollection;
133 
134  // Read the correct entry
135  auto entry = context.eventNumber;
136  if (not m_cfg.orderedEvents and entry < m_entryNumbers.size()) {
137  entry = m_entryNumbers[entry];
138  }
139  m_inputChain->GetEntry(entry);
140  ACTS_INFO("Reading event: " << context.eventNumber
141  << " stored as entry: " << entry);
142 
143  unsigned int nParticles = m_particleId->size();
144 
145  for (unsigned int i = 0; i < nParticles; i++) {
146  SimParticle p;
147 
148  p.setProcess(static_cast<ActsFatras::ProcessType>((*m_process)[i]));
149  p.setPdg(static_cast<Acts::PdgParticle>((*m_particleType)[i]));
150  p.setCharge((*m_q)[i] * Acts::UnitConstants::e);
151  p.setMass((*m_m)[i] * Acts::UnitConstants::GeV);
152  p.setParticleId((*m_particleId)[i]);
153  p.setPosition4((*m_vx)[i] * Acts::UnitConstants::mm,
154  (*m_vy)[i] * Acts::UnitConstants::mm,
155  (*m_vz)[i] * Acts::UnitConstants::mm,
156  (*m_vt)[i] * Acts::UnitConstants::ns);
157  // NOTE: depends on the normalization done in setDirection
158  p.setDirection((*m_px)[i], (*m_py)[i], (*m_pz)[i]);
159  p.setAbsoluteMomentum((*m_p)[i] * Acts::UnitConstants::GeV);
160 
161  particleContainer.insert(particleContainer.end(), p);
162  priVtxCollection.push_back((*m_vertexPrimary)[i]);
163  secVtxCollection.push_back((*m_vertexSecondary)[i]);
164  }
165 
166  // Write the collections to the EventStore
167  m_outputParticles(context, std::move(particleContainer));
168 
169  if (not m_cfg.vertexPrimaryCollection.empty()) {
170  m_outputPrimaryVertices(context, std::move(priVtxCollection));
171  }
172 
173  if (not m_cfg.vertexSecondaryCollection.empty()) {
174  m_outputSecondaryVertices(context, std::move(secVtxCollection));
175  }
176  }
177  // Return success flag
179 }