File indexing completed on 2025-01-18 09:11:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp"
0010
0011 #include "Acts/Utilities/VectorHelpers.hpp"
0012 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0013 #include "ActsExamples/Propagation/PropagationAlgorithm.hpp"
0014
0015 #include <ios>
0016 #include <ostream>
0017 #include <stdexcept>
0018
0019 #include <TFile.h>
0020 #include <TTree.h>
0021
0022 namespace ActsExamples {
0023
0024 RootPropagationSummaryWriter::RootPropagationSummaryWriter(
0025 const RootPropagationSummaryWriter::Config& cfg, Acts::Logging::Level level)
0026 : WriterT(cfg.inputSummaryCollection, "RootPropagationSummaryWriter",
0027 level),
0028 m_cfg(cfg),
0029 m_outputFile(cfg.rootFile) {
0030
0031 if (m_cfg.inputSummaryCollection.empty()) {
0032 throw std::invalid_argument("Missing input collection");
0033 }
0034 if (m_cfg.treeName.empty()) {
0035 throw std::invalid_argument("Missing tree name");
0036 }
0037
0038
0039 if (m_outputFile == nullptr) {
0040 m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
0041 if (m_outputFile == nullptr) {
0042 throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'");
0043 }
0044 }
0045 m_outputFile->cd();
0046
0047 m_outputTree = new TTree(m_cfg.treeName.c_str(),
0048 "TTree from RootPropagationSummaryWriter");
0049 if (m_outputTree == nullptr) {
0050 throw std::bad_alloc();
0051 }
0052
0053
0054 m_outputTree->Branch("event_nr", &m_eventNr);
0055 m_outputTree->Branch("track_nr", &m_trackNr);
0056
0057 m_outputTree->Branch("d0", &m_d0);
0058 m_outputTree->Branch("z0", &m_z0);
0059 m_outputTree->Branch("phi", &m_phi);
0060 m_outputTree->Branch("theta", &m_theta);
0061 m_outputTree->Branch("qOverP", &m_qOverP);
0062 m_outputTree->Branch("t", &m_t);
0063
0064 m_outputTree->Branch("eta", &m_eta);
0065 m_outputTree->Branch("pt", &m_pt);
0066 m_outputTree->Branch("p", &m_p);
0067
0068 m_outputTree->Branch("nSensitives", &m_nSensitives);
0069 m_outputTree->Branch("nMaterials", &m_nMaterials);
0070 m_outputTree->Branch("nPortals", &m_nPortals);
0071
0072 m_outputTree->Branch("nAttemptedSteps", &m_nAttemptedSteps);
0073 m_outputTree->Branch("nRejectedSteps", &m_nRejectedSteps);
0074 m_outputTree->Branch("nSuccessfulSteps", &m_nSuccessfulSteps);
0075 m_outputTree->Branch("nReverseSteps", &m_nReverseSteps);
0076 m_outputTree->Branch("pathLength", &m_pathLength);
0077 m_outputTree->Branch("absolutePathLength", &m_absolutePathLength);
0078
0079 m_outputTree->Branch("nRenavigations", &m_nRenavigations);
0080 m_outputTree->Branch("nVolumeSwitches", &m_nVolumeSwitches);
0081 }
0082
0083 RootPropagationSummaryWriter::~RootPropagationSummaryWriter() {
0084 if (m_outputFile != nullptr) {
0085 m_outputFile->Close();
0086 }
0087 }
0088
0089 ProcessCode RootPropagationSummaryWriter::finalize() {
0090
0091 m_outputFile->cd();
0092 m_outputTree->Write();
0093
0094 if (m_cfg.rootFile == nullptr) {
0095 m_outputFile->Close();
0096 }
0097
0098 ACTS_VERBOSE("Wrote particles to tree '" << m_cfg.treeName << "' in '"
0099 << m_cfg.filePath << "'");
0100
0101 return ProcessCode::SUCCESS;
0102 }
0103
0104 ProcessCode RootPropagationSummaryWriter::writeT(
0105 const AlgorithmContext& context, const PropagationSummaries& summaries) {
0106
0107 std::scoped_lock lock(m_writeMutex);
0108
0109
0110 m_eventNr = static_cast<int>(context.eventNumber);
0111
0112
0113 for (const auto& [trackNr, summary] : Acts::enumerate(summaries)) {
0114
0115 m_trackNr = static_cast<int>(trackNr);
0116
0117
0118 const auto& startParameters = summary.startParameters;
0119 m_d0 = static_cast<float>(startParameters.parameters()[Acts::eBoundLoc0]);
0120 m_z0 = static_cast<float>(startParameters.parameters()[Acts::eBoundLoc1]);
0121 m_phi = static_cast<float>(startParameters.parameters()[Acts::eBoundPhi]);
0122 m_theta =
0123 static_cast<float>(startParameters.parameters()[Acts::eBoundTheta]);
0124 m_qOverP =
0125 static_cast<float>(startParameters.parameters()[Acts::eBoundQOverP]);
0126 m_t = static_cast<float>(startParameters.parameters()[Acts::eBoundTime]);
0127
0128
0129 m_eta = static_cast<float>(
0130 Acts::VectorHelpers::eta(startParameters.direction()));
0131 m_pt = static_cast<float>(startParameters.transverseMomentum());
0132 m_p = static_cast<float>(startParameters.absoluteMomentum());
0133
0134 m_nMaterials = 0;
0135 m_nSensitives = 0;
0136 m_nPortals = 0;
0137
0138
0139 std::ranges::for_each(summary.steps, [&](const auto& step) {
0140
0141 if (step.geoID.sensitive() > 0) {
0142 m_nSensitives++;
0143 }
0144
0145 if (step.geoID.boundary() > 0) {
0146 m_nPortals++;
0147 }
0148
0149 if (step.surface != nullptr) {
0150
0151 if (step.surface->surfaceMaterial() != nullptr) {
0152 m_nMaterials++;
0153 }
0154 }
0155 });
0156
0157
0158 m_nAttemptedSteps = summary.statistics.stepping.nAttemptedSteps;
0159 m_nRejectedSteps = summary.statistics.stepping.nRejectedSteps;
0160 m_nSuccessfulSteps = summary.statistics.stepping.nSuccessfulSteps;
0161 m_nReverseSteps = summary.statistics.stepping.nReverseSteps;
0162 m_pathLength = summary.statistics.stepping.pathLength;
0163 m_absolutePathLength = summary.statistics.stepping.absolutePathLength;
0164
0165
0166 m_nRenavigations = summary.statistics.navigation.nRenavigations;
0167 m_nVolumeSwitches = summary.statistics.navigation.nVolumeSwitches;
0168
0169 m_outputTree->Fill();
0170 }
0171
0172 return ProcessCode::SUCCESS;
0173 }
0174
0175 }