ndmspc  v1.2.0-0.1.rc3
NStorageTree.cxx
1 #include <TSystem.h>
2 #include <TROOT.h>
3 #include <TFolder.h>
4 #include <TDirectory.h>
5 #include "NBinning.h"
6 #include "NBinningDef.h"
7 #include "NBinningPoint.h"
8 #include "NLogger.h"
9 #include "NUtils.h"
10 
11 #include "NStorageTree.h"
12 
14 ClassImp(Ndmspc::NStorageTree);
16 
17 namespace Ndmspc {
18 NStorageTree::NStorageTree(NBinning * binning) : TObject(), fBinning(binning)
19 {
23  // InitTree("/tmp/ngnt.root", "ngnt");
24 }
26 {
30 }
31 
32 void NStorageTree::Clear(Option_t * option)
33 {
37  TString opt(option);
38  opt.ToUpper();
39 
40  if (opt.Contains("F")) {
41  if (fFile) {
42  fFile->Close();
43  delete fFile;
44  fFile = nullptr;
45  }
46  fTree = nullptr;
47  }
48  fBranchesMap.clear();
49  fFileName = "ngnt.root";
50  fPrefix.clear();
51  fPostfix.clear();
52 }
53 
54 void NStorageTree::Print(Option_t * option) const
55 {
59 
60  TString opt(option);
61  opt.ToUpper();
62 
63  NLogInfo("TTree:");
64  NLogInfo(" filename='%s'", fFileName.c_str());
65  NLogInfo(" tree name='%s' entries=%lld address=%p", fTree ? fTree->GetName() : "n/a",
66  fTree ? fTree->GetEntries() : -1, fTree);
67  NLogInfo(" tree entries=%lld", fTree ? fTree->GetEntries() : -1);
68  NLogInfo(" prefix='%s'", fPrefix.c_str());
69  NLogInfo(" postfix='%s'", fPostfix.c_str());
70  std::string branchNames = NUtils::GetCoordsString(GetBrancheNames());
71  NLogInfo(" branches: size=%d %s", fBranchesMap.size(), branchNames.c_str());
72 
73  if (opt.Contains("A")) {
74  for (auto & kv : fBranchesMap) {
75  kv.second.Print();
76  }
77  }
78  else {
79  }
80 }
81 bool NStorageTree::InitTree(const std::string & filename, const std::string & treename)
82 {
86 
87  // Set filename
88  if (!filename.empty()) {
89  fFileName = gSystem->ExpandPathName(filename.c_str());
90  }
91  else {
92  // NLogWarning("NStorageTree::InitTree: File was not defined, using RAM memory as storage ...",
93  // fFileName.c_str());
94  fFileName = "";
95  gROOT->cd();
96  }
97 
98  NLogTrace("Initializing tree '%s' using filename '%s' ...", treename.c_str(), fFileName.c_str());
99 
100  if (!fFileName.empty()) {
101  // Open file
102  fFile = NUtils::OpenFile(fFileName.c_str(), "RECREATE");
103  if (!fFile) {
104  NLogError("NStorageTree::InitTree: Cannot open file '%s' !!!", fFileName.c_str());
105  return false;
106  }
107  if (fPrefix.empty()) fPrefix = gSystem->GetDirName(fFileName.c_str());
108  if (fPostfix.empty()) fPostfix = gSystem->BaseName(fFileName.c_str());
109  }
110 
111  NLogTrace("NStorageTree::InitTree: Creating tree '%s' ...", treename.c_str());
112  fTree = new TTree(treename.c_str(), "ngnt tree");
113  if (!fTree) {
114  NLogError("Cannot create tree '%s' using file '%s' !!!", treename.c_str(), fFileName.c_str());
115  return false;
116  }
117 
118  return true;
119 }
120 bool NStorageTree::SetFileTree(TFile * file, TTree * tree)
121 {
125  if (!tree) {
126  NLogError("NStorageTree::SetFileTree: tree is nullptr !!!");
127  return false;
128  }
129  fFile = file;
130  if (fFile) {
131  NLogTrace("NStorageTree::SetFileTree: Setting file tree from file '%s' ...", fFile->GetName());
132  // if (fPrefix.empty() || force) fPrefix = gSystem->GetDirName(fFile->GetName());
133  // if (fPostfix.empty()) fPostfix = gSystem->BaseName(fFile->GetName());
134  fPrefix = gSystem->GetDirName(fFile->GetName());
135  fPostfix = gSystem->BaseName(fFile->GetName());
136  fFileName = fFile->GetName();
137  }
138  fTree = tree;
139  // print prefix and postfix
140  return true;
141 }
142 
143 Long64_t NStorageTree::GetEntry(Long64_t entry, NBinningPoint * point, bool checkBinningDef)
144 {
148 
149  NLogTrace("Getting entry=%lld nbranches=%d ...", entry, fBranchesMap.size());
150  // fTree->Print();
151  // Print warning if entry is out of bounds and return 0
152  if (entry < 0 || entry >= fTree->GetEntries()) {
153  NLogWarning("Entry %lld is out of bounds [0, %lld]. Reading 0 bytes and objects remain from last valid entry.",
154  entry, fTree->GetEntries() - 1);
155  fBinning->GetPoint()->Reset();
156  return 0;
157  }
158 
159  if (point) {
160  if (!point->SetPointContentFromLinearIndex(entry, checkBinningDef)) {
161  NLogError("NStorageTree::GetEntry: Cannot set point content from linear index %lld !!!", entry);
162  return 0;
163  }
164  }
165  else {
166  NLogWarning("NStorageTree::GetEntry: Binning point is nullptr, cannot set point content !!!");
167  return 0;
168  }
169  Long64_t bytessum = 0;
170 
171  for (auto & kv : fBranchesMap) {
172  NLogTrace("NStorageTree::GetEntry: Getting content from '%s' branch ...", kv.first.c_str());
173  if (kv.second.GetBranch() == nullptr) {
174  NLogError("NStorageTree::GetEntry: Branch '%s' is not initialized !!!", kv.first.c_str());
175  continue;
176  }
177  // check if branch is enabled
178  if (kv.second.GetBranchStatus() == 0) {
179  NLogTrace("NStorageTree::GetEntry: Branch '%s' is disabled !!! Skipping ...", kv.first.c_str());
180  continue;
181  }
182  bytessum += kv.second.GetEntry(fTree, entry);
183  }
184 
185  ProcInfo_t info;
186  gSystem->GetProcInfo(&info);
187  NLogDebug("NStorageTree::GetEntry: [entry=%lld] Bytes read : %.3f MB [RSS]: %ld kB file='%s'", entry,
188  (double)bytessum / (1024 * 1024), info.fMemResident, fFileName.empty() ? "memory" : fFileName.c_str());
189 
190  // NLogDebug("NStorageTree::GetEntry: [entry=%lld] Bytes read : %.3f MB file='%s'", entry,
191  // (double)bytessum / (1024 * 1024), fFileName.empty() ? "memory" : fFileName.c_str());
192 
193  return bytessum;
194 }
195 
196 Int_t NStorageTree::Fill(NBinningPoint * point, NStorageTree * hnstIn, bool ignoreFilledCheck,
197  std::vector<std::vector<int>> ranges, bool useProjection)
198 {
202  NLogTrace("NStorageTree::Fill: Filling entry in NStorageTree ...");
203 
204  if (fTree == nullptr) {
205  NLogError("NStorageTree::Fill: Tree is not initialized !!! Run 'NStorageTree::InitTree(...)' first !!!");
206  return -2;
207  }
208 
209  for (auto & kv : fBranchesMap) {
210  NLogTrace("NStorageTree::Fill: Saving content from %s ...", kv.first.c_str());
211  if (hnstIn) {
212  THnSparse * in = (THnSparse *)hnstIn->GetBranch(kv.first)->GetObject();
213  if (ranges.size() > 0) {
214  NUtils::SetAxisRanges(in, ranges);
215  }
216  kv.second.Branch(fTree, nullptr);
217  kv.second.SaveEntry(hnstIn->GetBranch(kv.first), useProjection);
218  }
219  else {
220  kv.second.SaveEntry(GetBranch(kv.first), false);
221  }
222  }
223 
224  Long64_t bin = point->Fill(ignoreFilledCheck);
225  if (bin < 0 && ignoreFilledCheck == false) {
226  fBinning->GetDefinition()->GetContent()->SetBinContent(point->GetStorageCoords(), point->GetEntryNumber());
227 
228  NLogWarning("Point was already processed, skipping ...");
229  // NLogWarning("NStorageTree::Fill: Point was already filled !!!");
230  return -2;
231  }
232 
233  // NLogInfo("NStorageTree::Fill: bin=%lld -> tree entries=%lld", bin, fTree->GetEntries());
234  // if (bin > fTree->GetEntries()) {
235  // NLogError("NStorageTree::Fill: Filled bin %lld is greater than tree entries %lld !!!", bin,
236  // fTree->GetEntries());
237  // return -2;
238  // }
239 
240  if (fTree == nullptr) {
241  NLogError("NStorageTree::Fill: Tree is not initialized !!!");
242  return -2;
243  }
244  // Filling entry to tree
245  Int_t nBytes = fTree->Fill();
246  NLogTrace("NStorageTree::Fill: Filled entry %lld -> tree entries=%lld %d", bin, fTree->GetEntries(), nBytes);
247 
248  if (fFile && nBytes <= 0) {
249  NLogError("NStorageTree::Fill: Failed to fill tree '%s' in file '%s' !!!", fTree->GetName(), fFile->GetName());
250  return -3;
251  }
252 
253  Long64_t entry = fTree->GetEntries() - 1;
254  fBinning->GetDefinition()->GetContent()->SetBinContent(point->GetStorageCoords(), point->GetEntryNumber());
255  point->SetEntryNumber(entry);
256 
257  ProcInfo_t info;
258  gSystem->GetProcInfo(&info);
259  NLogDebug("NStorageTree::Fill: [entry=%lld] Bytes written : %.3f MB [RSS]: %ld kB file='%s'", entry,
260  (Double_t)nBytes / (1024 * 1024), info.fMemResident,
261  fTree->GetCurrentFile() ? fTree->GetCurrentFile()->GetName() : "memory");
262 
263  return nBytes;
264 }
265 
266 bool NStorageTree::Close(bool write, std::map<std::string, TList *> outputs)
267 {
271 
272  if (write) {
273 
274  if (!fTree) {
275  // NLogError("NStorageTree::Close: Tree is not initialized !!!");
276  return false;
277  }
278 
279  TList * userInfo = fTree->GetUserInfo();
280  if (fBinning) {
281  userInfo->Add(fBinning->Clone());
282  }
283  else {
284  NLogError("NStorageTree::Close: Binning is not present, cannot store binning in user info !!! "
285  "Skipping to store tree content also ...");
286  if (fFile) fFile->Close();
287  return false;
288  }
289  userInfo->Add(Clone());
290 
291  if (fFile) {
292  fFile->cd();
293  // fFile->Print();
294 
295  fFile->mkdir("outputs");
296  fFile->cd("outputs");
297  for (auto & kv : outputs) {
298  if (kv.second && !kv.second->IsEmpty()) {
299 
300  kv.second->Write(kv.first.c_str(), TObject::kSingleKey);
301  NLogTrace("NStorageTree::Close: Output list '%s' with %d objects was written", kv.first.c_str(),
302  kv.second->GetEntries());
303  }
304  }
305  fFile->cd();
306  fTree->Write("", TObject::kOverwrite);
307  fFile->Close();
308  NLogTrace("NStorageTree::Close: NGnTree was written to file '%s' ...", fFile->GetName());
309  }
310  }
311  else {
312  if (fFile) {
313  // Remove 'this' from TTree's UserInfo before deleting the file.
314  // TTree is owned by TFile; when SafeDelete(fFile) triggers ~TFile -> ~TTree,
315  // TTree::GetUserInfo()->Delete() would free 'this' (self-deletion / UAF).
316  // macOS's allocator catches this immediately; Linux silently corrupts memory.
317  if (fTree && fTree->GetUserInfo()) {
318  fTree->GetUserInfo()->Remove(this);
319  }
320  fFile->Close();
321  NLogTrace("File '%s' was closed without saving ...", fFile->GetName());
322  }
323  }
324 
325  SafeDelete(fFile);
326  // gROOT->GetListOfFiles()->Remove(fFile); // Remove file from ROOT file list to prevent it from being closed
327  fFile = nullptr;
328  fTree = nullptr;
329  return true;
330 }
331 
332 std::vector<std::string> NStorageTree::GetBrancheNames(bool onlyEnabled) const
333 {
337  std::vector<std::string> keys;
338  for (auto & kv : fBranchesMap) {
339  // TODO:: Checking if enabled
340  if (kv.second.GetBranchStatus() == 0 && onlyEnabled) continue;
341  keys.push_back(kv.first);
342  }
343  return keys;
344 }
345 bool NStorageTree::AddBranch(const std::string & name, void * address, const std::string & className)
346 {
347 
348  if (fBranchesMap.find(name) != fBranchesMap.end()) {
349  NLogWarning("Branch '%s' already exists, returning existing branch ...", name.c_str());
350  return fBranchesMap[name].GetBranch();
351  }
352 
353  if (fTree == nullptr) {
354  NLogError("Tree is not initialized !!! Run 'NGnTree::InitTree(...)' first !!!");
355  return false;
356  }
357 
358  fBranchesMap[name] = NTreeBranch(fTree, name, address, className);
359  return true;
360 }
361 NTreeBranch * NStorageTree::GetBranch(const std::string & name)
362 {
366  if (name.empty()) {
367  NLogError("NStorageTree::GetBranch: Branch name is empty !!!");
368  return nullptr;
369  }
370 
371  if (fBranchesMap.find(name) == fBranchesMap.end()) {
372  // NLogError("NStorageTree::GetBranch: Branch '%s' not found !!!", name.c_str());
373  return nullptr;
374  }
375 
376  return &fBranchesMap[name];
377 }
378 TObject * NStorageTree::GetBranchObject(const std::string & name)
379 {
383  auto * branch = GetBranch(name);
384  if (!branch) {
385  return nullptr;
386  }
387  return branch->GetObject();
388 }
389 
391 {
395 
396  if (!fTree) {
397  NLogError("NStorageTree::SetBranchAddresses:Tree is nullptr !!!");
398  return;
399  }
400 
401  // NLogTrace("Setting branch addresses ...");
402 
403  // Print size of branches map
404  NLogTrace("NStorageTree::SetBranchAddresses: Setting branch addresses for %d branches ...", fBranchesMap.size());
405  // fTree->SetBranchStatus("*", 0);
406  for (auto & kv : fBranchesMap) {
407  NLogTrace("NStorageTree::SetBranchAddresses: Setting branch address '%s' ...", kv.first.c_str());
408  kv.second.SetBranchAddress(fTree);
409  }
410 }
411 
412 void NStorageTree::SetEnabledBranches(std::vector<std::string> branches, int status)
413 {
417 
418  // loop over all branches
419  for (auto & kv : fBranchesMap) {
420  if (branches.empty() || std::find(branches.begin(), branches.end(), kv.first) != branches.end()) {
421  NLogTrace("%s branch '%s' ...", status == 1 ? "Enabling" : "Disabling", kv.first.c_str());
422  kv.second.SetBranchStatus(status == 1 ? 1 : 0);
423  }
424  else {
425  NLogTrace("%s branch '%s' ...", status == 1 ? "Disabling" : "Enabling", kv.first.c_str());
426  kv.second.SetBranchStatus(status == 1 ? 0 : 1);
427  }
428  }
429 }
430 
431 Long64_t NStorageTree::Merge(TCollection * list)
432 {
436 
437  if (!list) {
438  NLogError("NStorageTree::Merge: List is nullptr !!!");
439  return -1;
440  }
441  if (list->IsEmpty()) {
442  NLogError("NStorageTree::Merge: List is empty !!!");
443  return -1;
444  }
445  // return 0;
446  if (fTree == nullptr) {
447  NLogError("NStorageTree::Merge: Tree is not initialized !!! Run 'NStorageTree::InitTree(...)' first !!!");
448  return -1;
449  }
450 
451  Long64_t nmerged = list->GetEntries();
452  NLogTrace("NStorageTree::Merge: Merging %d trees into tree '%s' ...", list->GetEntries(), fTree->GetName());
453  NLogTrace("NStorageTree::Merge: Merging %zu objects via NStorageTree::Merge ...", list->GetEntries());
454 
455  // Loop over all binning definitions in the list
456  for (auto & kv : fBinning->GetDefinitions()) {
457  NLogTrace("NStorageTree::Merge: Clearing ids in binning definition '%s' ...", kv.first.c_str());
458  kv.second->GetIds().clear();
459  }
460 
461  // clear all binning definition contents and ids before merging
462  // for (auto & kv : fBinning->GetDefinitions()) {
463  // auto binningDefIn = obj->GetBinning()->GetDefinition(kv.first);
464  // if (binningDefIn) {
465  // // binningDefIn->GetContent()->Reset();
466  // // binningDefIn->GetIds().clear();
467  // }
468  // }
469  NBinningPoint * point = fBinning->GetPoint();
470 
471  TIter next(list);
472  NStorageTree * obj = nullptr;
473  THnSparse * cSparse = fBinning->GetContent();
474  if (cSparse == nullptr) {
475  NLogError("NHnSparseTree::Merge: Content is nullptr !!! Cannot merge and exiting ...");
476  return 0;
477  }
478  NLogTrace("NStorageTree::Merge: Number of entries in content: %lld", cSparse->GetNbins());
479  Int_t * cCoords = new Int_t[cSparse->GetNdimensions()];
480  Long64_t linBin = 0;
481  std::unique_ptr<ROOT::Internal::THnBaseBinIter> iter{cSparse->CreateIter(true /*use axis range*/)};
482  while ((linBin = iter->Next()) >= 0) {
483  Double_t v = cSparse->GetBinContent(linBin, cCoords);
484  Long64_t idx = cSparse->GetBin(cCoords);
485  std::vector<int> cCoordsVector = NUtils::ArrayToVector(cCoords, cSparse->GetNdimensions());
486  std::string binCoordsStr = NUtils::GetCoordsString(cCoordsVector, -1);
487  NLogTrace("NStorageTree::Merge: Bin %lld(idx=%lld): %s content=%f", linBin, idx, binCoordsStr.c_str(), v);
488 
489  // if (linBin >= cSparse->GetNbins()) break;
490  // continue;
491  NLogTrace("NStorageTree::Merge: BEGIN linBin=%lld ===================================", linBin);
492  bool found = false;
493 
494  while ((obj = dynamic_cast<NStorageTree *>(next()))) {
495  if (found) break;
496  if (obj == this || !obj) continue;
497  NLogTrace("NHnSparseTree::Merge: Scanning object '%s' with %lld entries ...", obj->GetFileName().c_str(),
498  obj->GetTree()->GetEntries());
499  // continue;
500  Long64_t binObj = fBinning->GetContent()->GetBin(cCoords, false);
501  if (binObj < 0) {
502  NLogTrace("NStorageTree::Merge: Bin %lld(idx=%lld): %s -> file='%s' binObj=%lld, skipping ...", linBin, idx,
503  binCoordsStr.c_str(), obj->GetFileName().c_str(), binObj);
504  continue;
505  }
506  NLogTrace("NStorageTree::Merge: binObj=%lld", binObj);
507  Long64_t binGlobal = (Long64_t)fBinning->GetContent()->GetBinContent(binObj);
508  NLogTrace("NStorageTree::Merge: bcObj=%lld", binGlobal);
509  // Long64_t bin = fBinning->GetContent()->GetBin(cCoords, false);
510  Long64_t bin = obj->GetBinning()->GetContent()->GetBin(cCoords, false);
511 
512  NLogTrace("NStorageTree::Merge: Bin %lld(idx=%lld): %s -> file='%s' is bin=%lld binGlobal=%lld", linBin, idx,
513  binCoordsStr.c_str(), obj->GetFileName().c_str(), bin, binGlobal);
514  if (bin < 0) {
515  NLogTrace("NStorageTree::Merge: Bin %lld(idx=%lld): %s -> file='%s' bin=%lld, skipping ...", linBin, idx,
516  binCoordsStr.c_str(), obj->GetFileName().c_str(), bin);
517  continue;
518  }
519 
520  NLogTrace("NStorageTree::Merge: bin=%lld obj->GetTree()->GetEntries()=%lld", bin, obj->GetTree()->GetEntries());
521  if (bin < obj->GetTree()->GetEntries()) {
522  // obj->Print();
523  obj->GetEntry(bin, point);
524  // point->SetEntryNumber(bin); // Set the entry number to the linear bin index
525  // point->Print();
526  // // FIXME: check why ids are not filled correctly when merging
527  found = false;
528  std::vector<NBinningDef *> matchedDefinitions;
529  NLogTrace("NHnSparseTree::Merge: Looping over all binning definitions to fill ids ...");
530  for (auto & name : fBinning->GetDefinitionNames()) {
531  // check if id
532  auto binningDefIn = obj->GetBinning()->GetDefinition(name);
533  if (binningDefIn) {
534  NLogTrace("NHnSparseTree::Merge: Checking bin %lld to binning definition '%s' entry %lld linBin=%d "
535  "binGlobal=%lld ...",
536  idx, name.c_str(), point->GetEntryNumber(), linBin, binGlobal);
537 
538  // binningDefIn->Print();
539  // check if binGlobal is already in the binningDefIn->GetIds()
540  if (std::find(binningDefIn->GetIds().begin(), binningDefIn->GetIds().end(), binGlobal) ==
541  binningDefIn->GetIds().end()) {
542  // binningDefIn->GetIds().push_back(binGlobal);
543  NLogTrace("***** NHnSparseTree::Merge: Found and added %lld to definition '%s' Skipping", binGlobal,
544  name.c_str());
545  continue;
546  }
547  else {
548  NLogTrace("***** NHnSparseTree::Merge: ID %lld already exists in definition '%s', Found ...", binGlobal,
549  name.c_str());
550  found = true;
551  }
552 
553  NBinningDef * def = fBinning->GetDefinition(name);
554  if (def) {
555  matchedDefinitions.push_back(def);
556  }
557  }
558  }
559  if (found == false) {
560  NLogWarning("NHnSparseTree::Merge: Bin %lld(idx=%lld): %s -> bin in obj='%s' is bin=%lld binGlobal=%lld "
561  "but no definition found, skipping ...",
562  linBin, idx, binCoordsStr.c_str(), obj->GetFileName().c_str(), bin, binGlobal);
563  continue;
564  }
565  // Lopp over all branches in the object
566  for (auto & kv : obj->GetBranchesMap()) {
567  NLogTrace("NHnSparseTree::Merge: Merging branch '%s' ...", kv.first.c_str());
568  if (kv.second.GetBranchStatus() == 0) {
569  NLogTrace("NHnSparseTree::Merge: Branch '%s' is disabled !!! Skipping ...", kv.first.c_str());
570  continue;
571  }
572  // Get the branch object
573  TObject * branchObj = kv.second.GetObject();
574  if (!branchObj) {
575  NLogWarning("NHnSparseTree::Merge: Branch '%s' object is nullptr !!! Skipping ...", kv.first.c_str());
576  continue;
577  }
578 
579  NTreeBranch * b = GetBranch(kv.first);
580  if (b == nullptr) {
581  AddBranch(kv.first, kv.second.GetObject(), branchObj->IsA()->GetName());
582  b = GetBranch(kv.first);
583  }
584  // Pass deleteExisting=false: the source branch owns this object and
585  // already deletes it in GetEntry (de404cb). Deleting it here too
586  // would be a use-after-free on macOS's strict allocator.
587  b->SetAddress(branchObj, false); // Set the branch address
588  }
589  // SetPoint(obj->GetPoint()); // Set the point in the current NGnTree
590  // SaveEntry();
591  // fBinning->SetPoint(obj->GetBinning()->GetPoint());
592  Fill(point, obj, true, {}, false);
593  for (auto * def : matchedDefinitions) {
594  def->GetIds().push_back(point->GetEntryNumber());
595  }
596  NLogTrace("NHnSparseTree::Merge: Filling point %s linBin=%d idx=%d entry_number=%d...", binCoordsStr.c_str(),
597  linBin, idx, point->GetEntryNumber());
598  }
599  }
600  NLogTrace("NHnSparseTree::Merge: END linBin=%lld ===================================", linBin);
601  next.Reset(); // Reset the iterator to start from the beginning again
602  }
603  // closing all merged files
604  while ((obj = dynamic_cast<NStorageTree *>(next()))) {
605  NLogTrace("NStorageTree::Merge: Closing file '%s' ...", obj->GetFileName().c_str());
606  obj->Close(false);
607  }
608  // Print all definition ids after merging
609  for (auto & kv : fBinning->GetDefinitions()) {
610  NLogTrace("NHnSparseTree::Merge: IDs in definition '%s': %s", kv.first.c_str(),
611  NUtils::GetCoordsString(kv.second->GetIds(), -1).c_str());
612  }
613 
614  return nmerged;
615 }
616 
617 } // namespace Ndmspc
Defines binning mapping and content for NDMSPC histograms.
Definition: NBinningDef.h:26
THnSparse * GetContent() const
Get the template content histogram.
Definition: NBinningDef.h:118
Represents a single point in multi-dimensional binning.
Definition: NBinningPoint.h:21
Long64_t Fill(bool ignoreFilledCheck=false)
Fill the binning point content.
void SetEntryNumber(Long64_t entry)
Set entry number for the point.
Long64_t GetEntryNumber() const
Get entry number for the point.
Int_t * GetStorageCoords() const
Get pointer to storage coordinates array.
Definition: NBinningPoint.h:67
bool SetPointContentFromLinearIndex(Long64_t linBin, bool checkBinningDef=false)
Set point content from linear index.
virtual void Reset()
Reset the binning point to initial state.
NBinning object for managing multi-dimensional binning and axis definitions.
Definition: NBinning.h:45
NBinningDef * GetDefinition(const std::string &name="")
Get binning definition by name.
Definition: NBinning.cxx:1024
std::vector< std::string > GetDefinitionNames() const
Get all definition names.
Definition: NBinning.h:270
NBinningPoint * GetPoint()
Get the current binning point.
Definition: NBinning.cxx:1128
std::map< std::string, NBinningDef * > GetDefinitions() const
Get all binning definitions.
Definition: NBinning.h:264
THnSparse * GetContent() const
Get the content histogram.
Definition: NBinning.h:217
NDMSPC storage tree object for managing ROOT TTree-based data storage.
Definition: NStorageTree.h:22
std::map< std::string, NTreeBranch > fBranchesMap
Branches map.
Definition: NStorageTree.h:220
void SetBranchAddresses()
Set addresses for all branches.
TTree * fTree
! TTree container
Definition: NStorageTree.h:217
Long64_t GetEntries() const
Get number of entries in the tree.
Definition: NStorageTree.h:69
Long64_t Merge(TCollection *list)
Merge storage trees from a collection.
void SetEnabledBranches(std::vector< std::string > branches, int status=1)
Set enabled/disabled status for branches.
virtual void Clear(Option_t *option="")
Clear storage tree data.
bool SetFileTree(TFile *file, TTree *tree)
Tree handling.
std::string GetFileName() const
Get file name.
Definition: NStorageTree.h:194
bool AddBranch(const std::string &name, void *address, const std::string &className)
Add a branch to the tree.
Long64_t GetEntry(Long64_t entry, NBinningPoint *point=nullptr, bool checkBinningDef=false)
Get entry by index and fill NBinningPoint.
std::vector< std::string > GetBrancheNames(bool onlyEnabled=false) const
Branches handling.
std::string fFileName
Current filename.
Definition: NStorageTree.h:215
TObject * GetBranchObject(const std::string &name)
Get pointer to branch object by name.
NTreeBranch * GetBranch(const std::string &name)
Get pointer to NTreeBranch by name.
bool InitTree(const std::string &filename="", const std::string &treename="ngnt")
Initialize tree from file and tree name.
NBinning * GetBinning() const
Get pointer to binning object.
Definition: NStorageTree.h:176
virtual ~NStorageTree()
Destructor.
bool Close(bool write=false, std::map< std::string, TList * > outputs={})
Close the storage tree, optionally writing outputs.
TFile * fFile
! Current file
Definition: NStorageTree.h:216
NBinning * fBinning
Binning object.
Definition: NStorageTree.h:222
TTree * GetTree() const
Get pointer to TTree object.
Definition: NStorageTree.h:188
NStorageTree(NBinning *binning=nullptr)
Constructor.
virtual void Print(Option_t *option="") const
Print storage tree information.
std::string fPrefix
Prefix path.
Definition: NStorageTree.h:218
std::string fPostfix
Postfix path.
Definition: NStorageTree.h:219
Int_t Fill(NBinningPoint *point, NStorageTree *hnstIn=nullptr, bool ignoreFilledCheck=false, std::vector< std::vector< int >> ranges={}, bool useProjection=false)
Fill tree with NBinningPoint and optional input tree.
std::map< std::string, NTreeBranch > GetBranchesMap() const
Get map of branch names to NTreeBranch objects.
Definition: NStorageTree.h:129
NDMSPC tree branch object for managing ROOT TBranch and associated data.
Definition: NTreeBranch.h:18
void SetAddress(void *address, bool deleteExisting=false)
Set address for branch data.
Definition: NTreeBranch.cxx:59
TObject * GetObject() const
Get object pointer.
Definition: NTreeBranch.h:81
static bool SetAxisRanges(THnSparse *sparse, std::vector< std::vector< int >> ranges={}, bool withOverflow=false, bool modifyTitle=false, bool reset=true)
Set axis ranges for THnSparse using vector of ranges.
Definition: NUtils.cxx:1220
static TFile * OpenFile(std::string filename, std::string mode="READ", bool createLocalDir=true)
Open a ROOT file.
Definition: NUtils.cxx:719
static std::string GetCoordsString(const std::vector< int > &coords, int index=-1, int width=0)
Get string representation of coordinates.
Definition: NUtils.cxx:1588
static std::vector< int > ArrayToVector(Int_t *v1, int size)
Convert array to vector.
Definition: NUtils.cxx:1551