File indexing completed on 2025-01-18 09:11:58
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Root/RootSimHitReader.hpp"
0010
0011 #include "Acts/Definitions/PdgParticle.hpp"
0012 #include "Acts/Utilities/Logger.hpp"
0013 #include "ActsExamples/EventData/SimParticle.hpp"
0014 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0015 #include "ActsFatras/EventData/ProcessType.hpp"
0016
0017 #include <algorithm>
0018 #include <cstdint>
0019 #include <iostream>
0020 #include <stdexcept>
0021
0022 #include <TChain.h>
0023 #include <TMathBase.h>
0024
0025 namespace ActsExamples {
0026
0027 RootSimHitReader::RootSimHitReader(const RootSimHitReader::Config& config,
0028 Acts::Logging::Level level)
0029 : IReader(),
0030 m_cfg(config),
0031 m_logger(Acts::getDefaultLogger(name(), level)) {
0032 m_inputChain = std::make_unique<TChain>(m_cfg.treeName.c_str());
0033
0034 if (m_cfg.filePath.empty()) {
0035 throw std::invalid_argument("Missing input filename");
0036 }
0037 if (m_cfg.treeName.empty()) {
0038 throw std::invalid_argument("Missing tree name");
0039 }
0040
0041 m_outputSimHits.initialize(m_cfg.outputSimHits);
0042
0043
0044 int f = 0;
0045 auto setBranches = [&](const auto& keys, auto& columns) {
0046 for (auto key : keys) {
0047 columns.insert({key, f++});
0048 }
0049 for (auto key : keys) {
0050 m_inputChain->SetBranchAddress(key, &columns.at(key));
0051 }
0052 };
0053
0054 setBranches(m_floatKeys, m_floatColumns);
0055 setBranches(m_uint32Keys, m_uint32Columns);
0056 setBranches(m_uint64Keys, m_uint64Columns);
0057 setBranches(m_int32Keys, m_int32Columns);
0058
0059
0060 m_inputChain->Add(m_cfg.filePath.c_str());
0061 m_inputChain->LoadTree(0);
0062 ACTS_DEBUG("Adding File " << m_cfg.filePath << " to tree '" << m_cfg.treeName
0063 << "'.");
0064
0065
0066
0067
0068
0069
0070
0071 m_inputChain->SetBranchStatus("*", false);
0072 m_inputChain->SetBranchStatus("event_id", true);
0073
0074 auto nEntries = static_cast<std::size_t>(m_inputChain->GetEntriesFast());
0075 if (nEntries == 0) {
0076 throw std::runtime_error("Did not find any entries in input file");
0077 }
0078
0079
0080 m_inputChain->GetEntry(0);
0081 m_eventMap.push_back({m_uint32Columns.at("event_id"), 0ul, 0ul});
0082
0083
0084 for (auto i = 1ul; i < nEntries; ++i) {
0085 m_inputChain->GetEntry(i);
0086 const auto evtId = m_uint32Columns.at("event_id");
0087
0088 if (evtId != std::get<0>(m_eventMap.back())) {
0089 std::get<2>(m_eventMap.back()) = i;
0090 m_eventMap.push_back({evtId, i, i});
0091 }
0092 }
0093
0094 std::get<2>(m_eventMap.back()) = nEntries;
0095
0096
0097 std::ranges::sort(m_eventMap, {},
0098 [](const auto& m) { return std::get<0>(m); });
0099
0100
0101 m_inputChain->SetBranchStatus("*", true);
0102 ACTS_DEBUG("Event range: " << availableEvents().first << " - "
0103 << availableEvents().second);
0104 }
0105
0106 RootSimHitReader::~RootSimHitReader() = default;
0107
0108 std::pair<std::size_t, std::size_t> RootSimHitReader::availableEvents() const {
0109 return {std::get<0>(m_eventMap.front()), std::get<0>(m_eventMap.back()) + 1};
0110 }
0111
0112 ProcessCode RootSimHitReader::read(const AlgorithmContext& context) {
0113 auto it = std::ranges::find_if(m_eventMap, [&](const auto& a) {
0114 return std::get<0>(a) == context.eventNumber;
0115 });
0116
0117 if (it == m_eventMap.end()) {
0118
0119
0120 if ((context.eventNumber == availableEvents().first) &&
0121 (context.eventNumber == availableEvents().second - 1)) {
0122 ACTS_WARNING("Reading empty event: " << context.eventNumber);
0123 } else {
0124 ACTS_DEBUG("Reading empty event: " << context.eventNumber);
0125 }
0126
0127 m_outputSimHits(context, {});
0128
0129
0130 return ProcessCode::SUCCESS;
0131 }
0132
0133
0134 std::lock_guard<std::mutex> lock(m_read_mutex);
0135
0136 ACTS_DEBUG("Reading event: " << std::get<0>(*it)
0137 << " stored in entries: " << std::get<1>(*it)
0138 << " - " << std::get<2>(*it));
0139
0140 SimHitContainer hits;
0141 for (auto entry = std::get<1>(*it); entry < std::get<2>(*it); ++entry) {
0142 m_inputChain->GetEntry(entry);
0143
0144 auto eventId = m_uint32Columns.at("event_id");
0145 if (eventId != context.eventNumber) {
0146 break;
0147 }
0148
0149 const Acts::GeometryIdentifier geoid = m_uint64Columns.at("geometry_id");
0150 const SimBarcode pid = m_uint64Columns.at("particle_id");
0151 const auto index = m_int32Columns.at("index");
0152
0153 const Acts::Vector4 pos4 = {
0154 m_floatColumns.at("tx") * Acts::UnitConstants::mm,
0155 m_floatColumns.at("ty") * Acts::UnitConstants::mm,
0156 m_floatColumns.at("tz") * Acts::UnitConstants::mm,
0157 m_floatColumns.at("tt") * Acts::UnitConstants::mm,
0158 };
0159
0160 const Acts::Vector4 before4 = {
0161 m_floatColumns.at("tpx") * Acts::UnitConstants::GeV,
0162 m_floatColumns.at("tpy") * Acts::UnitConstants::GeV,
0163 m_floatColumns.at("tpz") * Acts::UnitConstants::GeV,
0164 m_floatColumns.at("te") * Acts::UnitConstants::GeV,
0165 };
0166
0167 const Acts::Vector4 delta = {
0168 m_floatColumns.at("deltapx") * Acts::UnitConstants::GeV,
0169 m_floatColumns.at("deltapy") * Acts::UnitConstants::GeV,
0170 m_floatColumns.at("deltapz") * Acts::UnitConstants::GeV,
0171 m_floatColumns.at("deltae") * Acts::UnitConstants::GeV,
0172 };
0173
0174 SimHit hit(geoid, pid, pos4, before4, before4 + delta, index);
0175
0176 hits.insert(hit);
0177 }
0178
0179 ACTS_DEBUG("Read " << hits.size() << " hits for event "
0180 << context.eventNumber);
0181
0182 m_outputSimHits(context, std::move(hits));
0183
0184
0185 return ProcessCode::SUCCESS;
0186 }
0187
0188 }