File indexing completed on 2025-12-16 09:24:02
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Root/RootTrackSummaryReader.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/TrackParametrization.hpp"
0013 #include "Acts/EventData/TrackParameters.hpp"
0014 #include "Acts/Surfaces/PerigeeSurface.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Utilities/Logger.hpp"
0017 #include "ActsExamples/EventData/SimParticle.hpp"
0018 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0019 #include "ActsExamples/Io/Root/RootUtility.hpp"
0020 #include "ActsFatras/EventData/Particle.hpp"
0021
0022 #include <iostream>
0023 #include <stdexcept>
0024
0025 #include <TChain.h>
0026
0027 namespace ActsExamples {
0028
0029 RootTrackSummaryReader::RootTrackSummaryReader(
0030 const RootTrackSummaryReader::Config& config, Acts::Logging::Level level)
0031 : IReader(),
0032 m_logger{Acts::getDefaultLogger(name(), level)},
0033 m_cfg(config) {
0034 m_inputChain = std::make_unique<TChain>(m_cfg.treeName.c_str());
0035
0036 if (m_cfg.filePath.empty()) {
0037 throw std::invalid_argument("Missing input filename");
0038 }
0039
0040 m_outputTrackParameters.initialize(m_cfg.outputTracks);
0041 m_outputParticles.initialize(m_cfg.outputParticles);
0042
0043
0044 m_inputChain->SetBranchAddress("event_nr", &m_eventNr);
0045 m_inputChain->SetBranchAddress("multiTraj_nr", &m_multiTrajNr.get());
0046 m_inputChain->SetBranchAddress("subTraj_nr", &m_subTrajNr.get());
0047
0048
0049 m_inputChain->SetBranchAddress("nStates", &m_nStates.get());
0050 m_inputChain->SetBranchAddress("nMeasurements", &m_nMeasurements.get());
0051 m_inputChain->SetBranchAddress("nOutliers", &m_nOutliers.get());
0052 m_inputChain->SetBranchAddress("nHoles", &m_nHoles.get());
0053 m_inputChain->SetBranchAddress("chi2Sum", &m_chi2Sum.get());
0054 m_inputChain->SetBranchAddress("NDF", &m_NDF.get());
0055 m_inputChain->SetBranchAddress("measurementChi2", &m_measurementChi2.get());
0056 m_inputChain->SetBranchAddress("outlierChi2", &m_outlierChi2.get());
0057 m_inputChain->SetBranchAddress("measurementVolume",
0058 &m_measurementVolume.get());
0059 m_inputChain->SetBranchAddress("measurementLayer", &m_measurementLayer.get());
0060 m_inputChain->SetBranchAddress("outlierVolume", &m_outlierVolume.get());
0061 m_inputChain->SetBranchAddress("outlierLayer", &m_outlierLayer.get());
0062
0063 if (m_inputChain->GetBranch("majorityParticleId") != nullptr) {
0064 m_hasCombinedMajorityParticleId = true;
0065 m_majorityParticleId.allocate();
0066 m_inputChain->SetBranchAddress("majorityParticleId",
0067 &m_majorityParticleId.get());
0068 } else {
0069 m_hasCombinedMajorityParticleId = false;
0070 m_majorityParticleVertexPrimary.allocate();
0071 m_majorityParticleVertexSecondary.allocate();
0072 m_majorityParticleParticle.allocate();
0073 m_majorityParticleGeneration.allocate();
0074 m_majorityParticleSubParticle.allocate();
0075 m_inputChain->SetBranchAddress("majorityParticleId_vertex_primary",
0076 &m_majorityParticleVertexPrimary.get());
0077 m_inputChain->SetBranchAddress("majorityParticleId_vertex_secondary",
0078 &m_majorityParticleVertexSecondary.get());
0079 m_inputChain->SetBranchAddress("majorityParticleId_particle",
0080 &m_majorityParticleParticle.get());
0081 m_inputChain->SetBranchAddress("majorityParticleId_generation",
0082 &m_majorityParticleGeneration.get());
0083 m_inputChain->SetBranchAddress("majorityParticleId_sub_particle",
0084 &m_majorityParticleSubParticle.get());
0085 }
0086 m_inputChain->SetBranchAddress("nMajorityHits", &m_nMajorityHits.get());
0087 m_inputChain->SetBranchAddress("t_charge", &m_t_charge.get());
0088 m_inputChain->SetBranchAddress("t_time", &m_t_time.get());
0089 m_inputChain->SetBranchAddress("t_vx", &m_t_vx.get());
0090 m_inputChain->SetBranchAddress("t_vy", &m_t_vy.get());
0091 m_inputChain->SetBranchAddress("t_vz", &m_t_vz.get());
0092 m_inputChain->SetBranchAddress("t_px", &m_t_px.get());
0093 m_inputChain->SetBranchAddress("t_py", &m_t_py.get());
0094 m_inputChain->SetBranchAddress("t_pz", &m_t_pz.get());
0095 m_inputChain->SetBranchAddress("t_theta", &m_t_theta.get());
0096 m_inputChain->SetBranchAddress("t_phi", &m_t_phi.get());
0097 m_inputChain->SetBranchAddress("t_eta", &m_t_eta.get());
0098 m_inputChain->SetBranchAddress("t_pT", &m_t_pT.get());
0099
0100 m_inputChain->SetBranchAddress("hasFittedParams", &m_hasFittedParams.get());
0101 m_inputChain->SetBranchAddress("eLOC0_fit", &m_eLOC0_fit.get());
0102 m_inputChain->SetBranchAddress("eLOC1_fit", &m_eLOC1_fit.get());
0103 m_inputChain->SetBranchAddress("ePHI_fit", &m_ePHI_fit.get());
0104 m_inputChain->SetBranchAddress("eTHETA_fit", &m_eTHETA_fit.get());
0105 m_inputChain->SetBranchAddress("eQOP_fit", &m_eQOP_fit.get());
0106 m_inputChain->SetBranchAddress("eT_fit", &m_eT_fit.get());
0107 m_inputChain->SetBranchAddress("err_eLOC0_fit", &m_err_eLOC0_fit.get());
0108 m_inputChain->SetBranchAddress("err_eLOC1_fit", &m_err_eLOC1_fit.get());
0109 m_inputChain->SetBranchAddress("err_ePHI_fit", &m_err_ePHI_fit.get());
0110 m_inputChain->SetBranchAddress("err_eTHETA_fit", &m_err_eTHETA_fit.get());
0111 m_inputChain->SetBranchAddress("err_eQOP_fit", &m_err_eQOP_fit.get());
0112 m_inputChain->SetBranchAddress("err_eT_fit", &m_err_eT_fit.get());
0113
0114 auto path = m_cfg.filePath;
0115
0116
0117 m_inputChain->Add(path.c_str());
0118 ACTS_DEBUG("Adding File " << path << " to tree '" << m_cfg.treeName << "'.");
0119
0120 m_events = m_inputChain->GetEntries();
0121 ACTS_DEBUG("The full chain has " << m_events << " entries.");
0122
0123
0124 {
0125
0126
0127 m_inputChain->SetEstimate(m_events + 1);
0128
0129 m_entryNumbers.resize(m_events);
0130 m_inputChain->Draw("event_nr", "", "goff");
0131 RootUtility::stableSort(m_inputChain->GetEntries(), m_inputChain->GetV1(),
0132 m_entryNumbers.data(), false);
0133 }
0134 }
0135
0136 std::pair<std::size_t, std::size_t> RootTrackSummaryReader::availableEvents()
0137 const {
0138 return {0u, m_events};
0139 }
0140
0141 ProcessCode RootTrackSummaryReader::read(const AlgorithmContext& context) {
0142 ACTS_DEBUG("Trying to read recorded tracks.");
0143
0144
0145 if (m_inputChain != nullptr && context.eventNumber < m_events) {
0146
0147 std::lock_guard<std::mutex> lock(m_read_mutex);
0148
0149
0150 std::shared_ptr<Acts::PerigeeSurface> perigeeSurface =
0151 Acts::Surface::makeShared<Acts::PerigeeSurface>(
0152 Acts::Vector3(0., 0., 0.));
0153
0154
0155 TrackParametersContainer trackParameterCollection;
0156 SimParticleContainer truthParticleCollection;
0157
0158
0159 auto entry = m_entryNumbers.at(context.eventNumber);
0160 m_inputChain->GetEntry(entry);
0161 ACTS_INFO("Reading event: " << context.eventNumber
0162 << " stored as entry: " << entry);
0163
0164 unsigned int nTracks = m_eLOC0_fit->size();
0165 for (unsigned int i = 0; i < nTracks; i++) {
0166 Acts::BoundVector paramVec;
0167 paramVec << (*m_eLOC0_fit)[i], (*m_eLOC1_fit)[i], (*m_ePHI_fit)[i],
0168 (*m_eTHETA_fit)[i], (*m_eQOP_fit)[i], (*m_eT_fit)[i];
0169
0170
0171 double resD0 = (*m_err_eLOC0_fit)[i];
0172 double resZ0 = (*m_err_eLOC1_fit)[i];
0173 double resPh = (*m_err_ePHI_fit)[i];
0174 double resTh = (*m_err_eTHETA_fit)[i];
0175 double resQp = (*m_err_eQOP_fit)[i];
0176 double resT = (*m_err_eT_fit)[i];
0177
0178
0179 Acts::BoundSquareMatrix covMat;
0180
0181 covMat << resD0 * resD0, 0., 0., 0., 0., 0., 0., resZ0 * resZ0, 0., 0.,
0182 0., 0., 0., 0., resPh * resPh, 0., 0., 0., 0., 0., 0., resTh * resTh,
0183 0., 0., 0., 0., 0., 0., resQp * resQp, 0., 0., 0., 0., 0., 0.,
0184 resT * resT;
0185
0186
0187 trackParameterCollection.push_back(Acts::BoundTrackParameters(
0188 perigeeSurface, paramVec, std::move(covMat),
0189 Acts::ParticleHypothesis::pion()));
0190 }
0191
0192 unsigned int nTruthParticles = m_t_vx->size();
0193 for (unsigned int i = 0; i < nTruthParticles; i++) {
0194 SimParticleState truthParticle;
0195
0196 truthParticle.setPosition4((*m_t_vx)[i], (*m_t_vy)[i], (*m_t_vz)[i],
0197 (*m_t_time)[i]);
0198 truthParticle.setDirection((*m_t_px)[i], (*m_t_py)[i], (*m_t_pz)[i]);
0199 auto makeBarcode = [](std::uint32_t vp, std::uint32_t vs,
0200 std::uint32_t particle, std::uint32_t generation,
0201 std::uint32_t subParticle) {
0202 SimBarcode barcode = SimBarcode::Invalid();
0203 return barcode
0204 .withVertexPrimary(static_cast<SimBarcode::PrimaryVertexId>(vp))
0205 .withVertexSecondary(static_cast<SimBarcode::SecondaryVertexId>(vs))
0206 .withParticle(static_cast<SimBarcode::ParticleId>(particle))
0207 .withGeneration(static_cast<SimBarcode::GenerationId>(generation))
0208 .withSubParticle(
0209 static_cast<SimBarcode::SubParticleId>(subParticle));
0210 };
0211
0212 SimBarcode barcode = SimBarcode::Invalid();
0213 if (m_hasCombinedMajorityParticleId && m_majorityParticleId.hasValue()) {
0214 const auto& components = (*m_majorityParticleId)[i];
0215 auto comp = [&](std::size_t idx) -> std::uint32_t {
0216 return (components.size() > idx) ? components[idx] : 0u;
0217 };
0218 barcode = makeBarcode(comp(0), comp(1), comp(2), comp(3), comp(4));
0219 } else {
0220 auto safeAt = [](const auto& branch, std::size_t idx) -> std::uint32_t {
0221 const auto* vec = branch.get();
0222 return (vec != nullptr && vec->size() > idx) ? vec->at(idx) : 0u;
0223 };
0224 barcode = makeBarcode(safeAt(m_majorityParticleVertexPrimary, i),
0225 safeAt(m_majorityParticleVertexSecondary, i),
0226 safeAt(m_majorityParticleParticle, i),
0227 safeAt(m_majorityParticleGeneration, i),
0228 safeAt(m_majorityParticleSubParticle, i));
0229 }
0230 truthParticle.setParticleId(barcode);
0231
0232 truthParticleCollection.insert(truthParticleCollection.end(),
0233 SimParticle(truthParticle, truthParticle));
0234 }
0235
0236 m_outputTrackParameters(context, std::move(trackParameterCollection));
0237 m_outputParticles(context, std::move(truthParticleCollection));
0238 } else {
0239 ACTS_WARNING("Could not read in event.");
0240 }
0241
0242 return ProcessCode::SUCCESS;
0243 }
0244
0245 }