File indexing completed on 2025-01-18 09:11:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Io/Root/RootPropagationStepsWriter.hpp"
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Geometry/GeometryIdentifier.hpp"
0013 #include "Acts/Propagator/ConstrainedStep.hpp"
0014 #include "Acts/Utilities/Helpers.hpp"
0015 #include "Acts/Utilities/VectorHelpers.hpp"
0016 #include "ActsExamples/EventData/PropagationSummary.hpp"
0017 #include "ActsExamples/Framework/AlgorithmContext.hpp"
0018
0019 #include <ios>
0020 #include <memory>
0021 #include <ostream>
0022 #include <stdexcept>
0023
0024 #include <TFile.h>
0025 #include <TTree.h>
0026
0027 ActsExamples::RootPropagationStepsWriter::RootPropagationStepsWriter(
0028 const ActsExamples::RootPropagationStepsWriter::Config& cfg,
0029 Acts::Logging::Level level)
0030 : WriterT(cfg.collection, "RootPropagationStepsWriter", level),
0031 m_cfg(cfg),
0032 m_outputFile(cfg.rootFile) {
0033
0034 if (m_cfg.collection.empty()) {
0035 throw std::invalid_argument("Missing input collection");
0036 } else if (m_cfg.treeName.empty()) {
0037 throw std::invalid_argument("Missing tree name");
0038 }
0039
0040
0041 if (m_outputFile == nullptr) {
0042 m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str());
0043 if (m_outputFile == nullptr) {
0044 throw std::ios_base::failure("Could not open '" + m_cfg.filePath + "'");
0045 }
0046 }
0047 m_outputFile->cd();
0048
0049 m_outputTree = new TTree(m_cfg.treeName.c_str(),
0050 "TTree from RootPropagationStepsWriter");
0051 if (m_outputTree == nullptr) {
0052 throw std::bad_alloc();
0053 }
0054
0055
0056 m_outputTree->Branch("event_nr", &m_eventNr);
0057 m_outputTree->Branch("track_nr", &m_trackNr);
0058 m_outputTree->Branch("d0", &m_d0);
0059 m_outputTree->Branch("z0", &m_z0);
0060 m_outputTree->Branch("phi", &m_phi);
0061 m_outputTree->Branch("theta", &m_theta);
0062 m_outputTree->Branch("qOverP", &m_qOverP);
0063 m_outputTree->Branch("t", &m_t);
0064 m_outputTree->Branch("eta", &m_eta);
0065 m_outputTree->Branch("pt", &m_pt);
0066 m_outputTree->Branch("p", &m_p);
0067 m_outputTree->Branch("volume_id", &m_volumeID);
0068 m_outputTree->Branch("boundary_id", &m_boundaryID);
0069 m_outputTree->Branch("layer_id", &m_layerID);
0070 m_outputTree->Branch("approach_id", &m_approachID);
0071 m_outputTree->Branch("sensitive_id", &m_sensitiveID);
0072 m_outputTree->Branch("extra_id", &m_extraID);
0073 m_outputTree->Branch("material", &m_material);
0074 m_outputTree->Branch("g_x", &m_x);
0075 m_outputTree->Branch("g_y", &m_y);
0076 m_outputTree->Branch("g_z", &m_z);
0077 m_outputTree->Branch("g_r", &m_r);
0078 m_outputTree->Branch("d_x", &m_dx);
0079 m_outputTree->Branch("d_y", &m_dy);
0080 m_outputTree->Branch("d_z", &m_dz);
0081 m_outputTree->Branch("type", &m_step_type);
0082 m_outputTree->Branch("step_acc", &m_step_acc);
0083 m_outputTree->Branch("step_act", &m_step_act);
0084 m_outputTree->Branch("step_abt", &m_step_abt);
0085 m_outputTree->Branch("step_usr", &m_step_usr);
0086 m_outputTree->Branch("nStepTrials", &m_nStepTrials);
0087 }
0088
0089 ActsExamples::RootPropagationStepsWriter::~RootPropagationStepsWriter() {
0090 if (m_outputFile != nullptr) {
0091 m_outputFile->Close();
0092 }
0093 }
0094
0095 ActsExamples::ProcessCode ActsExamples::RootPropagationStepsWriter::finalize() {
0096
0097 m_outputFile->cd();
0098 m_outputTree->Write();
0099
0100 if (m_cfg.rootFile == nullptr) {
0101 m_outputFile->Close();
0102 }
0103
0104 ACTS_VERBOSE("Wrote particles to tree '" << m_cfg.treeName << "' in '"
0105 << m_cfg.filePath << "'");
0106
0107 return ProcessCode::SUCCESS;
0108 }
0109
0110 ActsExamples::ProcessCode ActsExamples::RootPropagationStepsWriter::writeT(
0111 const AlgorithmContext& context, const PropagationSummaries& summaries) {
0112
0113 std::lock_guard<std::mutex> lock(m_writeMutex);
0114
0115
0116 m_eventNr = context.eventNumber;
0117
0118
0119
0120 std::size_t lastTotalTrials = 0;
0121
0122
0123 for (const auto& [trackNr, summary] : Acts::enumerate(summaries)) {
0124
0125 m_volumeID.clear();
0126 m_boundaryID.clear();
0127 m_layerID.clear();
0128 m_approachID.clear();
0129 m_sensitiveID.clear();
0130 m_extraID.clear();
0131 m_material.clear();
0132 m_x.clear();
0133 m_y.clear();
0134 m_z.clear();
0135 m_r.clear();
0136 m_dx.clear();
0137 m_dy.clear();
0138 m_dz.clear();
0139 m_step_type.clear();
0140 m_step_acc.clear();
0141 m_step_act.clear();
0142 m_step_abt.clear();
0143 m_step_usr.clear();
0144 m_nStepTrials.clear();
0145
0146
0147 m_trackNr = static_cast<int>(trackNr);
0148
0149
0150 const auto& startParameters = summary.startParameters;
0151 m_d0 = static_cast<float>(startParameters.parameters()[Acts::eBoundLoc0]);
0152 m_z0 = static_cast<float>(startParameters.parameters()[Acts::eBoundLoc1]);
0153 m_phi = static_cast<float>(startParameters.parameters()[Acts::eBoundPhi]);
0154 m_theta =
0155 static_cast<float>(startParameters.parameters()[Acts::eBoundTheta]);
0156 m_qOverP =
0157 static_cast<float>(startParameters.parameters()[Acts::eBoundQOverP]);
0158 m_t = static_cast<float>(startParameters.parameters()[Acts::eBoundTime]);
0159
0160
0161 m_eta = static_cast<float>(
0162 Acts::VectorHelpers::eta(startParameters.direction()));
0163 m_pt = static_cast<float>(startParameters.transverseMomentum());
0164 m_p = static_cast<float>(startParameters.absoluteMomentum());
0165
0166
0167 for (auto& step : summary.steps) {
0168 const auto& geoID = step.geoID;
0169 m_sensitiveID.push_back(geoID.sensitive());
0170 m_approachID.push_back(geoID.approach());
0171 m_layerID.push_back(geoID.layer());
0172 m_boundaryID.push_back(geoID.boundary());
0173 m_volumeID.push_back(geoID.volume());
0174 m_extraID.push_back(geoID.extra());
0175
0176 int material = 0;
0177 if (step.surface != nullptr &&
0178 step.surface->surfaceMaterial() != nullptr) {
0179 material = 1;
0180 }
0181 m_material.push_back(material);
0182
0183
0184 m_x.push_back(step.position.x());
0185 m_y.push_back(step.position.y());
0186 m_z.push_back(step.position.z());
0187 m_r.push_back(Acts::VectorHelpers::perp(step.position));
0188 auto direction = step.momentum.normalized();
0189 m_dx.push_back(direction.x());
0190 m_dy.push_back(direction.y());
0191 m_dz.push_back(direction.z());
0192
0193 double accuracy = step.stepSize.accuracy();
0194 double actor =
0195 step.stepSize.value(Acts::ConstrainedStep::Type::Navigator);
0196 double aborter = step.stepSize.value(Acts::ConstrainedStep::Type::Actor);
0197 double user = step.stepSize.value(Acts::ConstrainedStep::Type::User);
0198 double actAbs = std::abs(actor);
0199 double accAbs = std::abs(accuracy);
0200 double aboAbs = std::abs(aborter);
0201 double usrAbs = std::abs(user);
0202
0203 if (actAbs < accAbs && actAbs < aboAbs && actAbs < usrAbs) {
0204 m_step_type.push_back(0);
0205 } else if (accAbs < aboAbs && accAbs < usrAbs) {
0206 m_step_type.push_back(1);
0207 } else if (aboAbs < usrAbs) {
0208 m_step_type.push_back(2);
0209 } else {
0210 m_step_type.push_back(3);
0211 }
0212
0213
0214 m_step_acc.push_back(Acts::clampValue<float>(accuracy));
0215 m_step_act.push_back(Acts::clampValue<float>(actor));
0216 m_step_abt.push_back(Acts::clampValue<float>(aborter));
0217 m_step_usr.push_back(Acts::clampValue<float>(user));
0218
0219
0220 m_nStepTrials.push_back(step.nTotalTrials - lastTotalTrials);
0221 lastTotalTrials = step.nTotalTrials;
0222 }
0223 m_outputTree->Fill();
0224 }
0225
0226 return ActsExamples::ProcessCode::SUCCESS;
0227 }