Warning, file /acts/Plugins/DD4hep/src/DDG4/ActsMaterialTrackWriter.cpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/Root/RootMaterialTrackIo.hpp"
0010
0011 #include <algorithm>
0012 #include <cstddef>
0013 #include <memory>
0014 #include <mutex>
0015 #include <string>
0016
0017 #include <DDG4/Factories.h>
0018 #include <DDG4/Geant4Context.h>
0019 #include <DDG4/Geant4EventAction.h>
0020 #include <DDG4/Geant4Kernel.h>
0021 #include <DDG4/Geant4RunAction.h>
0022 #include <G4Event.hh>
0023 #include <G4Run.hh>
0024 #include <TFile.h>
0025 #include <TTree.h>
0026
0027 #include "detail/RecordedMaterialTracks.hpp"
0028
0029 namespace ActsPlugins {
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 class ActsMaterialTrackWriter final : public dd4hep::sim::Geant4EventAction {
0047 public:
0048
0049
0050
0051 ActsMaterialTrackWriter(dd4hep::sim::Geant4Context* context,
0052 const std::string& name);
0053
0054
0055 ~ActsMaterialTrackWriter() override;
0056
0057
0058
0059 void configureFiber(dd4hep::sim::Geant4Context* threadContext) override;
0060
0061
0062
0063 void end(const G4Event* event) override;
0064
0065 private:
0066 void beginRun(const G4Run* run);
0067 void endRun(const G4Run* run);
0068
0069 void closeFile();
0070
0071
0072 std::string m_outputFile = "material_tracks.root";
0073
0074 std::string m_treeName = "material_tracks";
0075
0076 std::unique_ptr<TFile> m_file;
0077 TTree* m_tree = nullptr;
0078 std::unique_ptr<ActsPlugins::RootMaterialTrackIo> m_trackIo;
0079
0080
0081 std::mutex m_fileMutex;
0082
0083 int m_endedRuns = 0;
0084 bool m_written = false;
0085 std::size_t m_nTracks = 0;
0086 };
0087
0088 ActsMaterialTrackWriter::ActsMaterialTrackWriter(
0089 dd4hep::sim::Geant4Context* context, const std::string& name)
0090 : dd4hep::sim::Geant4EventAction(context, name) {
0091 declareProperty("OutputFile", m_outputFile);
0092 declareProperty("TreeName", m_treeName);
0093
0094 context->runAction();
0095 }
0096
0097 void ActsMaterialTrackWriter::configureFiber(
0098 dd4hep::sim::Geant4Context* threadContext) {
0099 dd4hep::sim::Geant4EventAction::configureFiber(threadContext);
0100 threadContext->runAction().callAtBegin(this,
0101 &ActsMaterialTrackWriter::beginRun);
0102 threadContext->runAction().callAtEnd(this, &ActsMaterialTrackWriter::endRun);
0103 }
0104
0105 ActsMaterialTrackWriter::~ActsMaterialTrackWriter() {
0106 std::scoped_lock lock(m_fileMutex);
0107 if (m_file != nullptr) {
0108 warning("Not all threads ended their run, closing '%s' anyway.",
0109 m_outputFile.c_str());
0110 closeFile();
0111 }
0112 }
0113
0114 void ActsMaterialTrackWriter::beginRun(const G4Run* ) {
0115 std::scoped_lock lock(m_fileMutex);
0116 if (m_file != nullptr) {
0117
0118 return;
0119 }
0120 if (m_written) {
0121 except("Only a single run is supported, '%s' has already been written.",
0122 m_outputFile.c_str());
0123 }
0124
0125 m_file.reset(TFile::Open(m_outputFile.c_str(), "RECREATE"));
0126 if (m_file == nullptr || m_file->IsZombie()) {
0127 except("Could not open output file '%s'.", m_outputFile.c_str());
0128 }
0129
0130 m_tree = new TTree(m_treeName.c_str(), "Recorded material tracks");
0131 m_tree->SetDirectory(m_file.get());
0132
0133 ActsPlugins::RootMaterialTrackIo::Config ioCfg;
0134 ioCfg.prePostStepInfo = true;
0135 ioCfg.recalculateTotals = true;
0136 m_trackIo = std::make_unique<ActsPlugins::RootMaterialTrackIo>(ioCfg);
0137 m_trackIo->connectForWrite(*m_tree);
0138
0139 info("Writing material tracks to tree '%s' in '%s'.", m_treeName.c_str(),
0140 m_outputFile.c_str());
0141 }
0142
0143 void ActsMaterialTrackWriter::endRun(const G4Run* ) {
0144 std::scoped_lock lock(m_fileMutex);
0145
0146
0147 ++m_endedRuns;
0148 if (const int nThreads = std::max(
0149 context()->kernel().master().property("NumberOfThreads").value<int>(),
0150 1);
0151 m_endedRuns < nThreads || m_file == nullptr) {
0152 return;
0153 }
0154 closeFile();
0155 }
0156
0157 void ActsMaterialTrackWriter::closeFile() {
0158 m_file->cd();
0159 m_tree->Write();
0160 m_file->Close();
0161 m_tree = nullptr;
0162 m_trackIo.reset();
0163 m_file.reset();
0164 m_written = true;
0165 info("Wrote %zu material tracks to '%s'.", m_nTracks, m_outputFile.c_str());
0166 }
0167
0168 void ActsMaterialTrackWriter::end(const G4Event* event) {
0169
0170 const auto* recorded =
0171 context()->event().extension<detail::RecordedMaterialTracks>(false);
0172 if (recorded == nullptr) {
0173 warning(
0174 "No recorded material tracks in event %d, is the "
0175 "ActsMaterialRecorder stepping action configured?",
0176 event->GetEventID());
0177 return;
0178 }
0179
0180 for (const auto& [trackId, track] : recorded->tracks) {
0181 m_trackIo->write(event->GetEventID(), track);
0182 m_tree->Fill();
0183 }
0184 m_nTracks += recorded->tracks.size();
0185 }
0186
0187 }
0188
0189 DECLARE_GEANT4ACTION_NS(ActsPlugins, ActsMaterialTrackWriter)