EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RootParticleWriter.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file RootParticleWriter.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2017 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 
12 #include "Acts/Utilities/Units.hpp"
13 
14 #include <ios>
15 #include <stdexcept>
16 
17 #include <TFile.h>
18 #include <TTree.h>
19 
23  : WriterT(cfg.inputParticles, "RootParticleWriter", lvl), m_cfg(cfg) {
24  // inputParticles is already checked by base constructor
25  if (m_cfg.filePath.empty()) {
26  throw std::invalid_argument("Missing file path");
27  }
28  if (m_cfg.treeName.empty()) {
29  throw std::invalid_argument("Missing tree name");
30  }
31 
32  // open root file and create the tree
33  m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
34  if (m_outputFile == nullptr) {
35  throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'");
36  }
37  m_outputFile->cd();
38  m_outputTree = new TTree(m_cfg.treeName.c_str(), m_cfg.treeName.c_str());
39  if (m_outputTree == nullptr) {
40  throw std::bad_alloc();
41  }
42 
43  // setup the branches
44  m_outputTree->Branch("event_id", &m_eventId);
45  m_outputTree->Branch("particle_id", &m_particleId, "particle_id/l");
46  m_outputTree->Branch("particle_type", &m_particleType);
47  m_outputTree->Branch("process", &m_process);
48  m_outputTree->Branch("vx", &m_vx);
49  m_outputTree->Branch("vy", &m_vy);
50  m_outputTree->Branch("vz", &m_vz);
51  m_outputTree->Branch("vt", &m_vt);
52  m_outputTree->Branch("px", &m_px);
53  m_outputTree->Branch("py", &m_py);
54  m_outputTree->Branch("pz", &m_pz);
55  m_outputTree->Branch("m", &m_m);
56  m_outputTree->Branch("q", &m_q);
57  m_outputTree->Branch("eta", &m_eta);
58  m_outputTree->Branch("phi", &m_phi);
59  m_outputTree->Branch("pt", &m_pt);
60  m_outputTree->Branch("vertex_primary", &m_vertexPrimary);
61  m_outputTree->Branch("vertex_secondary", &m_vertexSecondary);
62  m_outputTree->Branch("particle", &m_particle);
63  m_outputTree->Branch("generation", &m_generation);
64  m_outputTree->Branch("sub_particle", &m_subParticle);
65 }
66 
68  if (m_outputFile) {
69  m_outputFile->Close();
70  }
71 }
72 
74  if (m_outputFile) {
75  m_outputFile->cd();
76  m_outputTree->Write();
77  ACTS_INFO("Wrote particles to tree '" << m_cfg.treeName << "' in '"
78  << m_cfg.filePath << "'");
79  }
80  return ProcessCode::SUCCESS;
81 }
82 
84  const AlgorithmContext& ctx, const SimParticleContainer& particles) {
85  if (not m_outputFile) {
86  ACTS_ERROR("Missing output file");
87  return ProcessCode::ABORT;
88  }
89 
90  // ensure exclusive access to tree/file while writing
91  std::lock_guard<std::mutex> lock(m_writeMutex);
92 
93  m_eventId = ctx.eventNumber;
94  for (const auto& particle : particles) {
95  m_particleId = particle.particleId().value();
96  m_particleType = particle.pdg();
97  m_process = static_cast<decltype(m_process)>(particle.process());
98  // position
99  m_vx = particle.position4().x() / Acts::UnitConstants::mm;
100  m_vy = particle.position4().y() / Acts::UnitConstants::mm;
101  m_vz = particle.position4().z() / Acts::UnitConstants::mm;
102  m_vt = particle.position4().w() / Acts::UnitConstants::ns;
103  // momentum
104  const auto p = particle.absMomentum() / Acts::UnitConstants::GeV;
105  m_px = p * particle.unitDirection().x();
106  m_py = p * particle.unitDirection().y();
107  m_pz = p * particle.unitDirection().z();
108  // particle constants
109  m_m = particle.mass() / Acts::UnitConstants::GeV;
110  m_q = particle.charge() / Acts::UnitConstants::e;
111  // derived kinematic quantities
112  m_eta = Acts::VectorHelpers::eta(particle.unitDirection());
113  m_phi = Acts::VectorHelpers::phi(particle.unitDirection());
114  m_pt = p * Acts::VectorHelpers::perp(particle.unitDirection());
115  // decoded barcode components
116  m_vertexPrimary = particle.particleId().vertexPrimary();
117  m_vertexSecondary = particle.particleId().vertexSecondary();
118  m_particle = particle.particleId().particle();
119  m_generation = particle.particleId().generation();
120  m_subParticle = particle.particleId().subParticle();
121  m_outputTree->Fill();
122  }
123 
124  return ProcessCode::SUCCESS;
125 }