File indexing completed on 2025-01-18 09:14:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/InstanceCount.h>
0016 #include <DDDigi/DigiROOTInput.h>
0017
0018
0019 #include <TROOT.h>
0020 #include <TFile.h>
0021 #include <TTree.h>
0022
0023 using namespace dd4hep::digi;
0024
0025 class DigiROOTInput::inputsource_t
0026 : public DigiInputAction::input_source, public DigiInputAction::event_frame {
0027 public:
0028
0029 std::map<Key, container_t> branches { };
0030
0031 std::unique_ptr<TFile> file { nullptr };
0032
0033 TTree* tree { nullptr };
0034
0035 Long64_t entry { -1 };
0036
0037 public:
0038
0039 inputsource_t() = default;
0040
0041 ~inputsource_t() = default;
0042
0043 bool done() const {
0044 return (entry+1) >= tree->GetEntries();
0045 }
0046 inputsource_t& next() {
0047 tree->LoadTree( ++entry );
0048 return *this;
0049 }
0050 };
0051
0052
0053
0054
0055
0056
0057
0058
0059 class DigiROOTInput::internals_t {
0060 public:
0061 using source_t = std::unique_ptr<inputsource_t>;
0062
0063 DigiROOTInput* m_parent { nullptr };
0064
0065 source_t m_source { };
0066
0067 int m_curr_input { INPUT_START };
0068
0069 public:
0070
0071 internals_t (DigiROOTInput* p);
0072
0073 ~internals_t () = default;
0074
0075 inputsource_t& next();
0076
0077 std::unique_ptr<inputsource_t> open_source();
0078 };
0079
0080
0081 DigiROOTInput::internals_t::internals_t (DigiROOTInput* p)
0082 : m_parent(p)
0083 {
0084 }
0085
0086
0087 std::unique_ptr<DigiROOTInput::inputsource_t> DigiROOTInput::internals_t::open_source() {
0088 const auto& inputs = m_parent->inputs();
0089 const auto& tree_name = m_parent->input_section();
0090 int len = inputs.size();
0091
0092 if ( inputs.empty() ) m_curr_input = 0;
0093 while ( (m_curr_input+1) < len ) {
0094 const auto& fname = inputs[++m_curr_input];
0095 std::unique_ptr<TFile> file(TFile::Open(fname.c_str()));
0096 if ( file && file->IsZombie() ) {
0097 file.reset();
0098 m_parent->error("OpenInput ++ Failed to open input source %s", fname.c_str());
0099 }
0100 else if ( file ) {
0101 auto* tree = (TTree*)file->Get(tree_name.c_str());
0102 if ( !tree ) {
0103 m_parent->error("OpenInput ++ Failed to access tree: %s in input: %s",
0104 tree_name.c_str(), fname.c_str());
0105 continue;
0106 }
0107 Int_t total = tree->GetEntries();
0108 if ( total <= 0 ) {
0109 m_parent->error("OpenInput ++ TTree %s exists, but has no data. input: %s",
0110 tree_name.c_str(), fname.c_str());
0111 continue;
0112 }
0113 auto source = std::make_unique<inputsource_t>();
0114 source->file = std::move(file);
0115 source->tree = tree;
0116 auto* branches = tree->GetListOfBranches();
0117 int mask = m_parent->input_mask();
0118 TObjArrayIter it(branches);
0119 for(Int_t i=0; i < branches->GetEntriesFast(); ++i) {
0120 TBranch* b = (TBranch*)branches->At(i);
0121 if ( m_parent->object_loading_is_enabled(b->GetName()) ) {
0122 TClass* cls = gROOT->GetClass( b->GetClassName(), kTRUE );
0123 Key key(b->GetName(), mask);
0124 b->SetAutoDelete(kFALSE);
0125 source->branches.emplace(key, container_t(key, *b, *cls));
0126 }
0127 }
0128 if ( source->branches.empty() ) {
0129 m_parent->except("+++ No branches to be loaded. Configuration error!");
0130 }
0131 m_parent->onOpenFile(*source);
0132 return source;
0133 }
0134 }
0135 m_parent->except("+++ No open file present. Configuration error?");
0136 return {};
0137 }
0138
0139
0140 DigiROOTInput::inputsource_t& DigiROOTInput::internals_t::next() {
0141 if ( !m_source || m_source->done() || m_parent->fileLimitReached(*m_source) ) {
0142 m_source = open_source();
0143 }
0144 auto& src = m_source->next();
0145 m_parent->onProcessEvent(src, src);
0146 return src;
0147 }
0148
0149
0150 DigiROOTInput::DigiROOTInput(const DigiKernel& kernel, const std::string& nam)
0151 : DigiInputAction(kernel, nam)
0152 {
0153 imp = std::make_unique<internals_t>(this);
0154 InstanceCount::increment(this);
0155 }
0156
0157
0158 DigiROOTInput::~DigiROOTInput() {
0159 imp.reset();
0160 InstanceCount::decrement(this);
0161 }
0162
0163
0164 void DigiROOTInput::execute(DigiContext& context) const {
0165
0166
0167
0168 std::lock_guard<std::mutex> lock(context.global_io_lock());
0169 auto& event = context.event;
0170 auto& source = imp->next();
0171 std::size_t input_len = 0;
0172
0173
0174 DataSegment& segment = event->get_segment(m_input_segment);
0175 for( auto& b : source.branches ) {
0176 auto& ent = b.second;
0177 Long64_t bytes = ent.branch.GetEntry( source.entry );
0178 if ( bytes > 0 ) {
0179 work_t work { segment, ent };
0180 (*this)(context, work);
0181 input_len += bytes;
0182 }
0183 debug("%s+++ Loaded %8ld bytes from branch %s", event->id(), bytes, ent.branch.GetName());
0184 }
0185 info("%s+++ Read event %6ld [%ld bytes] from tree %s file: %s",
0186 event->id(), source.entry, input_len, source.tree->GetName(), source.file->GetName());
0187 }