NAIA
 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  m_rti.chain->GetEntryWithIndex(m_event.header->UTCTime);
57  }
58 
59  return m_rtiInfo;
60 }
61 
63  static unsigned int lastRun = 0;
64 
65  if (m_event.header->Run != lastRun) {
66  lastRun = m_event.header->Run;
67  m_file.chain->GetEntryWithIndex(m_event.header->Run);
68  }
69 
70  return m_fileInfo;
71 }
72 
74  static unsigned int lastRun = 0;
75 
76  if (!IsMC())
77  throw(std::runtime_error("GetEventMCFileInfo called on a non-MC chain"));
78 
79  if (m_event.header->Run != lastRun) {
80  lastRun = m_event.header->Run;
81  m_file.chain->GetEntryWithIndex(m_event.header->Run);
82  }
83 
84  return m_fileInfoMC;
85 }
86 
88  static const std::string &fnName = "NAIAChain::GetRTITree";
89  auto logger = getLogger(fnName);
90 
91  switch (m_accessMode) {
92  case AccessMode::Read:
93  return m_rti.chain;
94  case AccessMode::Write:
95  logger->error("Not supported in Write mode");
96  return nullptr;
97  default:
98  throw std::runtime_error("NAIAChain::GetRTITree - Unrecognized access mode");
99  }
100 }
101 
103  static const std::string &fnName = "NAIAChain::GetFileInfoTree";
104  auto logger = getLogger(fnName);
105 
106  switch (m_accessMode) {
107  case AccessMode::Read:
108  return m_file.chain;
109  case AccessMode::Write:
110  logger->error("Not supported in Write mode");
111  return nullptr;
112  default:
113  throw std::runtime_error("NAIAChain::GetFileInfoTree - Unrecognized access mode");
114  }
115 }
116 
117 void NAIAChain::SetDirectory(TDirectory *directory) {
118  m_data.tree->SetDirectory(directory);
119  m_rti.tree->SetDirectory(directory);
120  m_file.tree->SetDirectory(directory);
121 }
122 
123 int NAIAChain::Add(const std::string &filePath) {
124  switch (m_accessMode) {
125  case AccessMode::Read:
126  if (!CheckVersion(filePath)) {
127  return -1;
128  }
129 
130  m_file.chain->Add(filePath.c_str());
131  m_rti.chain->Add(filePath.c_str());
132 
133  return m_data.chain->Add(filePath.c_str());
134  case AccessMode::Write:
135  return -1;
136  default:
137  throw std::runtime_error("NAIAChain::Add - Unrecognized access mode");
138  }
139 }
140 
142  switch (m_accessMode) {
143  case AccessMode::Read:
144  return -1;
145  case AccessMode::Write:
146  return m_data.tree->Fill();
147  default:
148  throw std::runtime_error("NAIAChain::Fill - Unrecognized access mode");
149  }
150 }
151 
153  switch (m_accessMode) {
154  case AccessMode::Read:
155  return -1;
156  case AccessMode::Write:
157  return m_rti.tree->Fill();
158  default:
159  throw std::runtime_error("NAIAChain::FillRTI - Unrecognized access mode");
160  }
161 }
162 
164  switch (m_accessMode) {
165  case AccessMode::Read:
166  return -1;
167  case AccessMode::Write:
168  return m_file.tree->Fill();
169  default:
170  throw std::runtime_error("NAIAChain::FillFileInfo - Unrecognized access mode");
171  }
172 }
173 
174 unsigned long int NAIAChain::GetEntries() {
175  switch (m_accessMode) {
176  case AccessMode::Read:
177  return m_data.chain->GetEntries();
178  case AccessMode::Write:
179  return m_data.tree->GetEntries();
180  default:
181  throw std::runtime_error("NAIAChain::GetEntries - Unrecognized access mode");
182  }
183 }
184 
186  switch (m_accessMode) {
187  case AccessMode::Read:
188  m_file.chain->Print();
189  m_rti.chain->Print();
190  return m_data.chain->Print();
191  case AccessMode::Write:
192  m_file.tree->Print();
193  m_rti.tree->Print();
194  return m_data.tree->Print();
195  default:
196  throw std::runtime_error("NAIAChain::Print - Unrecognized access mode");
197  }
198 }
199 
201  switch (m_accessMode) {
202  case AccessMode::Read:
203  m_file.chain->Write();
204  m_rti.chain->Write();
205  return m_data.chain->Write();
206  case AccessMode::Write:
207  m_file.tree->BuildIndex("FileInfo.Run");
208  m_file.tree->Write();
209 
210  m_rti.tree->BuildIndex("RTIInfo.UTCTime");
211  m_rti.tree->Write();
212 
213  m_data.tree->BuildIndex("HeaderData.Run", "HeaderData.EventNo");
214  return m_data.tree->Write();
215  default:
216  throw std::runtime_error("NAIAChain::Write - Unrecognized access mode");
217  }
218 }
219 
220 void NAIAChain::SetupBranches(bool create_MC_branches) {
221  switch (m_accessMode) {
222  case AccessMode::Read:
223  if (m_data.chain->GetBranch("MCTruthBaseData")) {
224  m_isMC = true;
225  m_event.SetMC(true);
226  }
227 
229  m_file.chain->SetBranchAddress("FileInfo", &m_fileInfoPtr);
230  if (m_file.chain->GetBranch("MCFileInfo"))
231  m_file.chain->SetBranchAddress("MCFileInfo", &m_fileInfoMCPtr);
232  m_rti.chain->SetBranchAddress("RTIInfo", &m_rtiInfoPtr);
233 
234  m_file.chain->BuildIndex("FileInfo.Run");
235  m_rti.chain->BuildIndex("RTIInfo.UTCTime");
236  break;
237  case AccessMode::Write:
238  m_event.BranchAll(this->m_data.tree);
239  m_file.tree->Branch("FileInfo", &m_fileInfo);
240  if (create_MC_branches)
241  m_file.tree->Branch("MCFileInfo", &m_fileInfoMC);
242  m_rti.tree->Branch("RTIInfo", &m_rtiInfo);
243  break;
244  default:
245  throw std::runtime_error("NAIAChain::SetupBranches - Unrecognized access mode");
246  }
247 }
248 
249 static const std::unordered_map<std::string, std::function<void(Event &)>> evDisablers = {
250  {"EventSummary", [](Event &event) { event.evSummary.DisableIO(); }},
251  {"DAQ", [](Event &event) { event.daq.DisableIO(); }},
252  {"TofBase", [](Event &event) { event.tofBase.DisableIO(); }},
253  {"TofPlus", [](Event &event) { event.tofPlus.DisableIO(); }},
254  {"TofBaseStandalone", [](Event &event) { event.tofBaseSt.DisableIO(); }},
255  {"TofPlusStandalone", [](Event &event) { event.tofPlusSt.DisableIO(); }},
256  {"EcalBase", [](Event &event) { event.ecalBase.DisableIO(); }},
257  {"EcalPlus", [](Event &event) { event.ecalPlus.DisableIO(); }},
258  {"TrTrackBase", [](Event &event) { event.trTrackBase.DisableIO(); }},
259  {"TrTrackPlus", [](Event &event) { event.trTrackPlus.DisableIO(); }},
260  {"SecondTrTrackBase", [](Event &event) { event.secondTrTrackBase.DisableIO(); }},
261  {"TrTrackBaseStandalone", [](Event &event) { event.trTrackBaseSt.DisableIO(); }},
262  {"TrdKBase", [](Event &event) { event.trdKBase.DisableIO(); }},
263  {"TrdKBaseStandalone", [](Event &event) { event.trdKBaseSt.DisableIO(); }},
264  {"RichBase", [](Event &event) { event.richBase.DisableIO(); }},
265  {"RichPlus", [](Event &event) { event.richPlus.DisableIO(); }},
266  {"UnbExtHitBase", [](Event &event) { event.extHitBase.DisableIO(); }},
267  {"MCTruthBase", [](Event &event) { event.mcTruthBase.DisableIO(); }},
268  {"MCTruthPlus", [](Event &event) { event.mcTruthPlus.DisableIO(); }},
269 };
270 
271 SkimTreeHandle<NAIAChain> NAIAChain::CreateSkimTree(const std::string &filename, const std::string &exclBranches) {
272  static const std::string &fnName = "NAIAChain::CreateSkimTree";
273  auto logger = getLogger(fnName);
274 
275  auto outFile = std::make_unique<TFile>(filename.c_str(), "recreate");
276  auto newChain = std::make_unique<NAIAChain>(NAIAChain::AccessMode::Write);
277 
278  if (!exclBranches.empty()) {
279  for (const std::string &container : TokenizeString(exclBranches, ';')) {
280  if (evDisablers.find(container) != std::end(evDisablers)) {
281  logger->info("Disabling container {}", container);
282  evDisablers.at(container)(newChain->m_event);
283  } else {
284  logger->error("Unknown container {}", container);
285  }
286  }
287  }
288 
289  // link existing branches to new tree branches
290  newChain->m_event.MirrorBranches(newChain->m_data.tree, m_event);
291  newChain->m_rti.tree->Branch("RTIInfo", &m_rtiInfo);
292  newChain->m_file.tree->Branch("FileInfo", &m_fileInfo);
293  if (m_file.tree->GetBranch("MCFileInfo"))
294  newChain->m_file.tree->Branch("MCFileInfo", &m_fileInfoMC);
295 
296  return {std::move(outFile), std::move(newChain), this};
297 }
298 
299 void NAIAChain::SetEntryList(TEntryList *entryList, Option_t *option) {
300  static const std::string &fnName = "NAIAChain::SetEntryList";
301  auto logger = getLogger(fnName);
302 
303  switch (m_accessMode) {
304  case AccessMode::Write:
305  logger->error("TEntryList not supported in Write mode");
306  break;
307  case AccessMode::Read:
308  m_data.chain->SetEntryList(entryList, option);
309  break;
310  default:
311  break;
312  }
313 }
314 
315 bool NAIAChain::CheckVersion(const std::string &filePath) {
316  static const std::string &fnName = "NAIAChain::CheckVersion";
317  auto logger = getLogger(fnName);
318 
319  NAIA::Version this_version{};
320 
321  auto file = std::make_unique<TFile>(filePath.c_str(), "read");
322  NAIA::Version *file_version = file->Get<NAIA::Version>("VersionHeader");
323  if (!file_version) {
324  logger->error("NAIA version header not found in file {}. This file will be skipped.", filePath);
325  return false;
326  }
327 
328  if (file_version->major != this_version.major) {
329  logger->error("Major version mismatch in file {} ({} on file vs {} in this library). This file will be skipped.",
330  filePath, file_version->major, this_version.major);
331  return false;
332  }
333 
334  if (file_version->minor != this_version.minor) {
335  logger->warn("Minor version mismatch in file {} ({} on file vs {} in this library). This should be fine, however "
336  "please report any issue to the NAIA development team.",
337  filePath, file_version->minor, this_version.minor);
338  }
339 
340  return true;
341 }
342 
343 } // 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:220
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:299
unsigned long int GetEntries()
Get the total number of events.
Definition: NAIAChain.cpp:174
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:117
Container class for versioning info.
Definition: NAIAVersion.h:21
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:87
int FillFileInfo()
Fill the FileInfo data.
Definition: NAIAChain.cpp:163
Event object.
Definition: Event.h:20
TChain * GetFileInfoTree()
Get the FileInfo TTree object.
Definition: NAIAChain.cpp:102
static const std::unordered_map< std::string, std::function< void(Event &)> > evDisablers
Definition: NAIAChain.cpp:249
const MCFileInfo & GetEventMCFileInfo()
Get the MCFileInfo object associated with this event.
Definition: NAIAChain.cpp:73
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:271
void Print()
Print all the chains.
Definition: NAIAChain.cpp:185
int Add(const std::string &filePath)
Add a file to the chain.
Definition: NAIAChain.cpp:123
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:141
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:152
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:62
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:315
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:200
Container class for RTI info.
Definition: RTIInfo.h:33
unsigned int UTCTime
UTC time (in seconds) of current event.
Definition: Header.h:66