ndmspc v1.2.0-0.1.rc7
Loading...
Searching...
No Matches
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
14ClassImp(Ndmspc::NStorageTree);
16
17namespace Ndmspc {
18NStorageTree::NStorageTree(NBinning * binning) : TObject(), fBinning(binning)
19{
23 // InitTree("/tmp/ngnt.root", "ngnt");
24}
31
32void 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
54void 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}
81bool 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}
120bool 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
143Long64_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
196Int_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
266bool 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
332std::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}
345bool 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}
361NTreeBranch * 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}
378TObject * 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
412void 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
431Long64_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
Represents a single point in multi-dimensional binning.
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.
bool SetPointContentFromLinearIndex(Long64_t linBin, bool checkBinningDef=false)
Set point content from linear index.
Int_t * GetStorageCoords() const
Get pointer to storage coordinates array.
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.
THnSparse * GetContent() const
Get the content histogram.
Definition NBinning.h:217
NDMSPC storage tree object for managing ROOT TTree-based data storage.
std::map< std::string, NTreeBranch > fBranchesMap
Branches map.
void SetBranchAddresses()
Set addresses for all branches.
TTree * fTree
! TTree container
Long64_t GetEntries() const
Get number of entries in the tree.
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.
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.
std::map< std::string, NTreeBranch > GetBranchesMap() const
Get map of branch names to NTreeBranch objects.
TObject * GetBranchObject(const std::string &name)
Get pointer to branch object by name.
NBinning * GetBinning() const
Get pointer to binning object.
NTreeBranch * GetBranch(const std::string &name)
Get pointer to NTreeBranch by name.
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.
bool InitTree(const std::string &filename="", const std::string &treename="ngnt")
Initialize tree from file and tree name.
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
NBinning * fBinning
Binning object.
NStorageTree(NBinning *binning=nullptr)
Constructor.
virtual void Print(Option_t *option="") const
Print storage tree information.
std::string fPrefix
Prefix path.
std::string fPostfix
Postfix path.
TTree * GetTree() const
Get pointer to TTree object.
NDMSPC tree branch object for managing ROOT TBranch and associated data.
Definition NTreeBranch.h:18
TObject * GetObject() const
Get object pointer.
Definition NTreeBranch.h:81
void SetAddress(void *address, bool deleteExisting=false)
Set address for branch data.
static TFile * OpenFile(std::string filename, std::string mode="READ", bool createLocalDir=true)
Open a ROOT file.
Definition NUtils.cxx:719
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:1224
static std::string GetCoordsString(const std::vector< int > &coords, int index=-1, int width=0)
Get string representation of coordinates.
Definition NUtils.cxx:1592
static std::vector< int > ArrayToVector(Int_t *v1, int size)
Convert array to vector.
Definition NUtils.cxx:1555
Global callback function for libwebsockets client events.