NAIA  1.0.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups
NAIAChain.cpp
Go to the documentation of this file.
1 #include "Chain/NAIAChain.h"
3 
4 #include "TTreeIndex.h"
5 
6 #include <functional>
7 #include <unordered_map>
8 
9 namespace NAIA {
10 
11 NAIAChain::NAIAChain(AccessMode mode) : m_accessMode{mode} {
12  switch (m_accessMode) {
13  case AccessMode::Read:
14  m_data.chain = new TChain("NAIAChain");
15  m_rti.chain = new TChain("RTI");
16  m_file.chain = new TChain("FileInfo");
17  break;
18  case AccessMode::Write:
19  m_data.tree = new TTree("NAIAChain", "AMS-Italy ntuple tree");
20  m_rti.tree = new TTree("RTI", "RTIInfo tree");
21  m_file.tree = new TTree("FileInfo", "FileInfo tree");
22  break;
23  default:
24  throw std::runtime_error("NAIAChain::GetEntries - Unrecognized access mode");
25  }
26 }
27 
28 Event &NAIAChain::GetEvent(unsigned long long iEv) {
29  static int currentTree = -1;
30 
31  // when the tree changes we need to reload the branches...
32  auto treeReadEntry = m_data.chain->LoadTree(iEv);
33  if (m_data.chain->GetTreeNumber() != currentTree) {
34  spdlog::trace("Event {} -> CHANGING TREE", iEv);
36  currentTree = m_data.chain->GetTreeNumber();
37  }
38 
39  // do stuff to propagate iEv to the Event object (containers need to know which event to load)
40  m_event.SetEventNumber(treeReadEntry);
41  return m_event;
42 }
43 
44 Event &NAIAChain::GetEventWithIndex(unsigned int run, unsigned int eventno) {
45  return GetEvent(m_data.chain->GetEntryNumberWithIndex(run, eventno));
46 }
47 
49  static unsigned int lastSec = 0;
50 
51  if (IsMC())
52  throw(std::runtime_error("GetEventRTIInfo called on a MC chain"));
53 
54  if (m_event.header->UTCTime != lastSec) {
55  lastSec = m_event.header->UTCTime;
56  auto rc = m_rti.chain->GetEntryWithIndex(m_event.header->UTCTime);
57  if (rc < 0) {
58  throw std::runtime_error(
59  fmt::format("Failed to read entry for UTC second {} from RTI tree. (ec: {})", m_event.header->UTCTime, rc));
60  }
61  }
62 
63  return m_rtiInfo;
64 }
65 
67  static unsigned int lastRun = 0;
68 
69  if (m_event.header->Run != lastRun) {
70  lastRun = m_event.header->Run;
71  m_file.chain->GetEntryWithIndex(m_event.header->Run);
72  }
73 
74  return m_fileInfo;
75 }
76 
78  static unsigned int lastRun = 0;
79 
80  if (!IsMC())
81  throw(std::runtime_error("GetEventMCFileInfo called on a non-MC chain"));
82 
83  if (m_event.header->Run != lastRun) {
84  lastRun = m_event.header->Run;
85  m_file.chain->GetEntryWithIndex(m_event.header->Run);
86  }
87 
88  return m_fileInfoMC;
89 }
90 
92  static const std::string &fnName = "NAIAChain::GetRTITree";
93  auto logger = getLogger(fnName);
94 
95  switch (m_accessMode) {
96  case AccessMode::Read:
97  return m_rti.chain;
98  case AccessMode::Write:
99  logger->error("Not supported in Write mode");
100  return nullptr;
101  default:
102  throw std::runtime_error("NAIAChain::GetRTITree - Unrecognized access mode");
103  }
104 }
105 
107  static const std::string &fnName = "NAIAChain::GetFileInfoTree";
108  auto logger = getLogger(fnName);
109 
110  switch (m_accessMode) {
111  case AccessMode::Read:
112  return m_file.chain;
113  case AccessMode::Write:
114  logger->error("Not supported in Write mode");
115  return nullptr;
116  default:
117  throw std::runtime_error("NAIAChain::GetFileInfoTree - Unrecognized access mode");
118  }
119 }
120 
121 void NAIAChain::SetDirectory(TDirectory *directory) {
122  m_data.tree->SetDirectory(directory);
123  m_rti.tree->SetDirectory(directory);
124  m_file.tree->SetDirectory(directory);
125 }
126 
127 int NAIAChain::Add(const std::string &filePath) {
128  switch (m_accessMode) {
129  case AccessMode::Read:
130  if (!CheckVersion(filePath)) {
131  return -1;
132  }
133 
134  m_file.chain->Add(filePath.c_str());
135  m_rti.chain->Add(filePath.c_str());
136 
137  return m_data.chain->Add(filePath.c_str());
138  case AccessMode::Write:
139  return -1;
140  default:
141  throw std::runtime_error("NAIAChain::Add - Unrecognized access mode");
142  }
143 }
144 
146  switch (m_accessMode) {
147  case AccessMode::Read:
148  return -1;
149  case AccessMode::Write:
150  return m_data.tree->Fill();
151  default:
152  throw std::runtime_error("NAIAChain::Fill - Unrecognized access mode");
153  }
154 }
155 
157  switch (m_accessMode) {
158  case AccessMode::Read:
159  return -1;
160  case AccessMode::Write:
161  return m_rti.tree->Fill();
162  default:
163  throw std::runtime_error("NAIAChain::FillRTI - Unrecognized access mode");
164  }
165 }
166 
168  switch (m_accessMode) {
169  case AccessMode::Read:
170  return -1;
171  case AccessMode::Write:
172  return m_file.tree->Fill();
173  default:
174  throw std::runtime_error("NAIAChain::FillFileInfo - Unrecognized access mode");
175  }
176 }
177 
178 unsigned long int NAIAChain::GetEntries() {
179  switch (m_accessMode) {
180  case AccessMode::Read:
181  return m_data.chain->GetEntries();
182  case AccessMode::Write:
183  return m_data.tree->GetEntries();
184  default:
185  throw std::runtime_error("NAIAChain::GetEntries - Unrecognized access mode");
186  }
187 }
188 
190  switch (m_accessMode) {
191  case AccessMode::Read:
192  m_file.chain->Print();
193  m_rti.chain->Print();
194  return m_data.chain->Print();
195  case AccessMode::Write:
196  m_file.tree->Print();
197  m_rti.tree->Print();
198  return m_data.tree->Print();
199  default:
200  throw std::runtime_error("NAIAChain::Print - Unrecognized access mode");
201  }
202 }
203 
205  switch (m_accessMode) {
206  case AccessMode::Read:
207  m_file.chain->Write();
208  m_rti.chain->Write();
209  return m_data.chain->Write();
210  case AccessMode::Write:
211  m_file.tree->BuildIndex("FileInfo.Run");
212  m_file.tree->Write();
213 
214  if (!m_isMC) {
215  spdlog::debug("Building RTIInfo index");
216  m_rti.tree->BuildIndex("RTIInfo.UTCTime");
217  }
218  m_rti.tree->Write();
219 
220  m_data.tree->BuildIndex("HeaderData.Run", "HeaderData.EventNo");
221  return m_data.tree->Write();
222  default:
223  throw std::runtime_error("NAIAChain::Write - Unrecognized access mode");
224  }
225 }
226 
227 void NAIAChain::SetupBranches(bool create_MC_branches) {
228  switch (m_accessMode) {
229  case AccessMode::Read:
230  if (m_data.chain->GetBranch("MCTruthBaseData")) {
231  m_isMC = true;
232  m_event.SetMC(true);
233  }
234 
236  m_file.chain->SetBranchAddress("FileInfo", &m_fileInfoPtr);
237  if (m_file.chain->GetBranch("MCFileInfo"))
238  m_file.chain->SetBranchAddress("MCFileInfo", &m_fileInfoMCPtr);
239  m_rti.chain->SetBranchAddress("RTIInfo", &m_rtiInfoPtr);
240 
241  m_file.chain->BuildIndex("FileInfo.Run");
242  m_rti.chain->BuildIndex("RTIInfo.UTCTime");
243  break;
244  case AccessMode::Write:
245  m_event.BranchAll(this->m_data.tree);
246  m_file.tree->Branch("FileInfo", &m_fileInfo);
247  if (create_MC_branches)
248  m_file.tree->Branch("MCFileInfo", &m_fileInfoMC);
249  m_rti.tree->Branch("RTIInfo", &m_rtiInfo);
250  break;
251  default:
252  throw std::runtime_error("NAIAChain::SetupBranches - Unrecognized access mode");
253  }
254 }
255 
256 static const std::unordered_map<std::string, std::function<void(Event &)>> evDisablers = {
257  {"EventSummary", [](Event &event) { event.evSummary.DisableIO(); }},
258  {"DAQ", [](Event &event) { event.daq.DisableIO(); }},
259  {"TofBase", [](Event &event) { event.tofBase.DisableIO(); }},
260  {"TofPlus", [](Event &event) { event.tofPlus.DisableIO(); }},
261  {"TofBaseStandalone", [](Event &event) { event.tofBaseSt.DisableIO(); }},
262  {"TofPlusStandalone", [](Event &event) { event.tofPlusSt.DisableIO(); }},
263  {"EcalBase", [](Event &event) { event.ecalBase.DisableIO(); }},
264  {"EcalPlus", [](Event &event) { event.ecalPlus.DisableIO(); }},
265  {"TrTrackBase", [](Event &event) { event.trTrackBase.DisableIO(); }},
266  {"TrTrackPlus", [](Event &event) { event.trTrackPlus.DisableIO(); }},
267  {"SecondTrTrackBase", [](Event &event) { event.secondTrTrackBase.DisableIO(); }},
268  {"TrTrackBaseStandalone", [](Event &event) { event.trTrackBaseSt.DisableIO(); }},
269  {"TrdKBase", [](Event &event) { event.trdKBase.DisableIO(); }},
270  {"TrdKBaseStandalone", [](Event &event) { event.trdKBaseSt.DisableIO(); }},
271  {"RichBase", [](Event &event) { event.richBase.DisableIO(); }},
272  {"RichPlus", [](Event &event) { event.richPlus.DisableIO(); }},
273  {"UnbExtHitBase", [](Event &event) { event.extHitBase.DisableIO(); }},
274  {"MCTruthBase", [](Event &event) { event.mcTruthBase.DisableIO(); }},
275  {"MCTruthPlus", [](Event &event) { event.mcTruthPlus.DisableIO(); }},
276 };
277 
278 SkimTreeHandle<NAIAChain> NAIAChain::CreateSkimTree(const std::string &filename, const std::string &exclBranches) {
279  static const std::string &fnName = "NAIAChain::CreateSkimTree";
280  auto logger = getLogger(fnName);
281 
282  auto outFile = std::make_unique<TFile>(filename.c_str(), "recreate");
283  auto newChain = std::make_unique<NAIAChain>(NAIAChain::AccessMode::Write);
284  newChain->m_isMC = m_isMC;
285 
286  if (!exclBranches.empty()) {
287  for (const std::string &container : TokenizeString(exclBranches, ';')) {
288  if (evDisablers.find(container) != std::end(evDisablers)) {
289  logger->info("Disabling container {}", container);
290  evDisablers.at(container)(newChain->m_event);
291  } else {
292  logger->error("Unknown container {}", container);
293  }
294  }
295  }
296 
297  // link existing branches to new tree branches
298  newChain->m_event.MirrorBranches(newChain->m_data.tree, m_event);
299 
300  return {std::move(outFile), std::move(newChain), this};
301 }
302 
303 void NAIAChain::SetEntryList(TEntryList *entryList, Option_t *option) {
304  static const std::string &fnName = "NAIAChain::SetEntryList";
305  auto logger = getLogger(fnName);
306 
307  switch (m_accessMode) {
308  case AccessMode::Write:
309  logger->error("TEntryList not supported in Write mode");
310  break;
311  case AccessMode::Read:
312  m_data.chain->SetEntryList(entryList, option);
313  break;
314  default:
315  break;
316  }
317 }
318 
319 bool NAIAChain::CheckVersion(const std::string &filePath) {
320  static const std::string &fnName = "NAIAChain::CheckVersion";
321  auto logger = getLogger(fnName);
322 
323  NAIA::Version this_version{};
324 
325  auto file = std::unique_ptr<TFile>(TFile::Open(filePath.c_str()));
326  NAIA::Version *file_version = file->Get<NAIA::Version>("VersionHeader");
327  if (!file_version) {
328  logger->error("NAIA version header not found in file {}. This file will be skipped.", filePath);
329  return false;
330  }
331 
332  if (file_version->major != this_version.major) {
333  logger->error("Major version mismatch in file {} ({} on file vs {} in this library). This file will be skipped.",
334  filePath, file_version->major, this_version.major);
335  return false;
336  }
337 
338  if (file_version->minor != this_version.minor) {
339  logger->warn("Minor version mismatch in file {} ({} on file vs {} in this library). This should be fine, however "
340  "please report any issue to the NAIA development team.",
341  filePath, file_version->minor, this_version.minor);
342  }
343 
344  return true;
345 }
346 
347 } // namespace NAIA
void SetupBranches(bool create_MC_branches=false)
Set all branch addresses for reading operations, or create all branches for writing operation...
Definition: NAIAChain.cpp:227
Helper class to ease skimming operations.
const RTIInfo & GetEventRTIInfo()
Get the RTIInfo object associated with this event.
Definition: NAIAChain.cpp:48
unsigned int Run
The current run.
Definition: Header.h:63
AccessMode
Simple enum to express whether we are in read or write mode.
Definition: NAIAChain.h:40
FileInfo * m_fileInfoPtr
Definition: NAIAChain.h:276
NAIAChain class description.
void SetEntryList(TEntryList *entryList, Option_t *option)
Set an entry list for this tree.
Definition: NAIAChain.cpp:303
unsigned long int GetEntries()
Get the total number of events.
Definition: NAIAChain.cpp:178
Event & GetEventWithIndex(unsigned int run, unsigned int eventno)
Get the Event object using the underlying index.
Definition: NAIAChain.cpp:44
NAIAChain(AccessMode mode=AccessMode::Read)
Construct a new Single Tree Chain object.
Definition: NAIAChain.cpp:11
void SetDirectory(TDirectory *directory)
Set the TDirectory for the trees.
Definition: NAIAChain.cpp:121
void BranchAll(TTree *tree)
Forwards this tree to all containers so that each one can create its own branch.
Definition: Event.cpp:4
void SetAllBranchAddress(TTree *tree)
Forwards this tree to all containers so that each one can create its own branch address for reading o...
Definition: Event.cpp:39
RTIInfo m_rtiInfo
Definition: NAIAChain.h:273
AccessMode m_accessMode
Definition: NAIAChain.h:269
MCFileInfo * m_fileInfoMCPtr
needed for SetBranchAddress
Definition: NAIAChain.h:277
TChain * GetRTITree()
Get the RTIInfo TTree object.
Definition: NAIAChain.cpp:91
int FillFileInfo()
Fill the FileInfo data.
Definition: NAIAChain.cpp:167
Event object.
Definition: Event.h:20
TChain * GetFileInfoTree()
Get the FileInfo TTree object.
Definition: NAIAChain.cpp:106
static const std::unordered_map< std::string, std::function< void(Event &)> > evDisablers
Definition: NAIAChain.cpp:256
const MCFileInfo & GetEventMCFileInfo()
Get the MCFileInfo object associated with this event.
Definition: NAIAChain.cpp:77
RTIInfo * m_rtiInfoPtr
needed for SetBranchAddress
Definition: NAIAChain.h:278
SkimTreeHandle< NAIAChain > CreateSkimTree(const std::string &filename, const std::string &exclBranches)
Create a new SkimTree handle object and setup all internal branches.
Definition: NAIAChain.cpp:278
void Print()
Print all the chains.
Definition: NAIAChain.cpp:189
int Add(const std::string &filePath)
Add a file to the chain.
Definition: NAIAChain.cpp:127
void SetEventNumber(unsigned long long iEv)
Set the Event Number for all containers. The corresponding entry will be loaded upon the first read r...
Definition: Event.cpp:144
int Fill()
Fill the event data.
Definition: NAIAChain.cpp:145
Header header
Definition: Event.h:103
Container class for processed File information.
Definition: FileInfo.h:23
int FillRTI()
Fill the RTI data.
Definition: NAIAChain.cpp:156
Container class for additional MC File information.
Definition: FileInfo.h:54
const FileInfo & GetEventFileInfo()
Get the FileInfo object associated with this event.
Definition: NAIAChain.cpp:66
std::vector< std::string > TokenizeString(const std::string &input, const char separator)
Utility function that splits a string according to the provided separator.
Definition: Utils.h:30
Event & GetEvent(unsigned long long iEv)
Get the Event object.
Definition: NAIAChain.cpp:28
FileInfo m_fileInfo
Definition: NAIAChain.h:271
MCFileInfo m_fileInfoMC
Definition: NAIAChain.h:272
static bool CheckVersion(const std::string &filePath)
Definition: NAIAChain.cpp:319
bool IsMC() const
Check if this file is a MC file.
Definition: NAIAChain.h:190
NAIAChain::EventItr end(NAIAChain &chain)
Definition: NAIAChain.h:298
void SetMC(bool isMC)
Set wether this is a MC event or not.
Definition: Event.h:86
auto getLogger(const std::string &fnName)
Create a new logger with a given function name.
Definition: Logging.h:18
int Write()
Write the trees to disk.
Definition: NAIAChain.cpp:204
Container class for RTI info.
Definition: RTIInfo.h:33
unsigned int UTCTime
UTC time (in seconds) of current event.
Definition: Header.h:66