4 #include <TDirectory.h>
6 #include "NBinningDef.h"
7 #include "NBinningPoint.h"
11 #include "NStorageTree.h"
40 if (opt.Contains(
"F")) {
64 NLogInfo(
" filename='%s'",
fFileName.c_str());
65 NLogInfo(
" tree name='%s' entries=%lld address=%p",
fTree ?
fTree->GetName() :
"n/a",
67 NLogInfo(
" tree entries=%lld",
fTree ?
fTree->GetEntries() : -1);
68 NLogInfo(
" prefix='%s'",
fPrefix.c_str());
69 NLogInfo(
" postfix='%s'",
fPostfix.c_str());
71 NLogInfo(
" branches: size=%d %s",
fBranchesMap.size(), branchNames.c_str());
73 if (opt.Contains(
"A")) {
88 if (!filename.empty()) {
89 fFileName = gSystem->ExpandPathName(filename.c_str());
98 NLogTrace(
"Initializing tree '%s' using filename '%s' ...", treename.c_str(),
fFileName.c_str());
104 NLogError(
"NStorageTree::InitTree: Cannot open file '%s' !!!",
fFileName.c_str());
111 NLogTrace(
"NStorageTree::InitTree: Creating tree '%s' ...", treename.c_str());
112 fTree =
new TTree(treename.c_str(),
"ngnt tree");
114 NLogError(
"Cannot create tree '%s' using file '%s' !!!", treename.c_str(),
fFileName.c_str());
126 NLogError(
"NStorageTree::SetFileTree: tree is nullptr !!!");
131 NLogTrace(
"NStorageTree::SetFileTree: Setting file tree from file '%s' ...",
fFile->GetName());
149 NLogTrace(
"Getting entry=%lld nbranches=%d ...", entry,
fBranchesMap.size());
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);
161 NLogError(
"NStorageTree::GetEntry: Cannot set point content from linear index %lld !!!", entry);
166 NLogWarning(
"NStorageTree::GetEntry: Binning point is nullptr, cannot set point content !!!");
169 Long64_t bytessum = 0;
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());
178 if (kv.second.GetBranchStatus() == 0) {
179 NLogTrace(
"NStorageTree::GetEntry: Branch '%s' is disabled !!! Skipping ...", kv.first.c_str());
182 bytessum += kv.second.GetEntry(
fTree, entry);
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());
197 std::vector<std::vector<int>> ranges,
bool useProjection)
202 NLogTrace(
"NStorageTree::Fill: Filling entry in NStorageTree ...");
204 if (
fTree ==
nullptr) {
205 NLogError(
"NStorageTree::Fill: Tree is not initialized !!! Run 'NStorageTree::InitTree(...)' first !!!");
210 NLogTrace(
"NStorageTree::Fill: Saving content from %s ...", kv.first.c_str());
213 if (ranges.size() > 0) {
216 kv.second.Branch(
fTree,
nullptr);
217 kv.second.SaveEntry(hnstIn->
GetBranch(kv.first), useProjection);
220 kv.second.SaveEntry(
GetBranch(kv.first),
false);
224 Long64_t bin = point->
Fill(ignoreFilledCheck);
225 if (bin < 0 && ignoreFilledCheck ==
false) {
228 NLogWarning(
"Point was already processed, skipping ...");
240 if (
fTree ==
nullptr) {
241 NLogError(
"NStorageTree::Fill: Tree is not initialized !!!");
245 Int_t nBytes =
fTree->Fill();
246 NLogTrace(
"NStorageTree::Fill: Filled entry %lld -> tree entries=%lld %d", bin,
fTree->GetEntries(), nBytes);
248 if (
fFile && nBytes <= 0) {
249 NLogError(
"NStorageTree::Fill: Failed to fill tree '%s' in file '%s' !!!",
fTree->GetName(),
fFile->GetName());
253 Long64_t entry =
fTree->GetEntries() - 1;
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");
279 TList * userInfo =
fTree->GetUserInfo();
284 NLogError(
"NStorageTree::Close: Binning is not present, cannot store binning in user info !!! "
285 "Skipping to store tree content also ...");
289 userInfo->Add(Clone());
295 fFile->mkdir(
"outputs");
296 fFile->cd(
"outputs");
297 for (
auto & kv : outputs) {
298 if (kv.second && !kv.second->IsEmpty()) {
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());
306 fTree->Write(
"", TObject::kOverwrite);
308 NLogTrace(
"NStorageTree::Close: NGnTree was written to file '%s' ...",
fFile->GetName());
318 fTree->GetUserInfo()->Remove(
this);
321 NLogTrace(
"File '%s' was closed without saving ...",
fFile->GetName());
337 std::vector<std::string> keys;
340 if (kv.second.GetBranchStatus() == 0 && onlyEnabled)
continue;
341 keys.push_back(kv.first);
349 NLogWarning(
"Branch '%s' already exists, returning existing branch ...", name.c_str());
353 if (
fTree ==
nullptr) {
354 NLogError(
"Tree is not initialized !!! Run 'NGnTree::InitTree(...)' first !!!");
367 NLogError(
"NStorageTree::GetBranch: Branch name is empty !!!");
387 return branch->GetObject();
397 NLogError(
"NStorageTree::SetBranchAddresses:Tree is nullptr !!!");
404 NLogTrace(
"NStorageTree::SetBranchAddresses: Setting branch addresses for %d branches ...",
fBranchesMap.size());
407 NLogTrace(
"NStorageTree::SetBranchAddresses: Setting branch address '%s' ...", kv.first.c_str());
408 kv.second.SetBranchAddress(
fTree);
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);
425 NLogTrace(
"%s branch '%s' ...", status == 1 ?
"Disabling" :
"Enabling", kv.first.c_str());
426 kv.second.SetBranchStatus(status == 1 ? 0 : 1);
438 NLogError(
"NStorageTree::Merge: List is nullptr !!!");
441 if (list->IsEmpty()) {
442 NLogError(
"NStorageTree::Merge: List is empty !!!");
446 if (
fTree ==
nullptr) {
447 NLogError(
"NStorageTree::Merge: Tree is not initialized !!! Run 'NStorageTree::InitTree(...)' first !!!");
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());
457 NLogTrace(
"NStorageTree::Merge: Clearing ids in binning definition '%s' ...", kv.first.c_str());
458 kv.second->GetIds().clear();
474 if (cSparse ==
nullptr) {
475 NLogError(
"NHnSparseTree::Merge: Content is nullptr !!! Cannot merge and exiting ...");
478 NLogTrace(
"NStorageTree::Merge: Number of entries in content: %lld", cSparse->GetNbins());
479 Int_t * cCoords =
new Int_t[cSparse->GetNdimensions()];
481 std::unique_ptr<ROOT::Internal::THnBaseBinIter> iter{cSparse->CreateIter(
true )};
482 while ((linBin = iter->Next()) >= 0) {
483 Double_t v = cSparse->GetBinContent(linBin, cCoords);
484 Long64_t idx = cSparse->GetBin(cCoords);
487 NLogTrace(
"NStorageTree::Merge: Bin %lld(idx=%lld): %s content=%f", linBin, idx, binCoordsStr.c_str(), v);
491 NLogTrace(
"NStorageTree::Merge: BEGIN linBin=%lld ===================================", linBin);
496 if (obj ==
this || !obj)
continue;
497 NLogTrace(
"NHnSparseTree::Merge: Scanning object '%s' with %lld entries ...", obj->
GetFileName().c_str(),
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);
506 NLogTrace(
"NStorageTree::Merge: binObj=%lld", binObj);
508 NLogTrace(
"NStorageTree::Merge: bcObj=%lld", binGlobal);
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);
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);
520 NLogTrace(
"NStorageTree::Merge: bin=%lld obj->GetTree()->GetEntries()=%lld", bin, obj->
GetTree()->GetEntries());
528 std::vector<NBinningDef *> matchedDefinitions;
529 NLogTrace(
"NHnSparseTree::Merge: Looping over all binning definitions to fill ids ...");
534 NLogTrace(
"NHnSparseTree::Merge: Checking bin %lld to binning definition '%s' entry %lld linBin=%d "
535 "binGlobal=%lld ...",
540 if (std::find(binningDefIn->GetIds().begin(), binningDefIn->GetIds().end(), binGlobal) ==
541 binningDefIn->GetIds().end()) {
543 NLogTrace(
"***** NHnSparseTree::Merge: Found and added %lld to definition '%s' Skipping", binGlobal,
548 NLogTrace(
"***** NHnSparseTree::Merge: ID %lld already exists in definition '%s', Found ...", binGlobal,
555 matchedDefinitions.push_back(def);
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);
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());
573 TObject * branchObj = kv.second.GetObject();
575 NLogWarning(
"NHnSparseTree::Merge: Branch '%s' object is nullptr !!! Skipping ...", kv.first.c_str());
581 AddBranch(kv.first, kv.second.GetObject(), branchObj->IsA()->GetName());
592 Fill(point, obj,
true, {},
false);
593 for (
auto * def : matchedDefinitions) {
596 NLogTrace(
"NHnSparseTree::Merge: Filling point %s linBin=%d idx=%d entry_number=%d...", binCoordsStr.c_str(),
600 NLogTrace(
"NHnSparseTree::Merge: END linBin=%lld ===================================", linBin);
605 NLogTrace(
"NStorageTree::Merge: Closing file '%s' ...", obj->
GetFileName().c_str());
610 NLogTrace(
"NHnSparseTree::Merge: IDs in definition '%s': %s", kv.first.c_str(),
Defines binning mapping and content for NDMSPC histograms.
THnSparse * GetContent() const
Get the template content histogram.
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.
Int_t * GetStorageCoords() const
Get pointer to storage coordinates array.
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.
NBinningDef * GetDefinition(const std::string &name="")
Get binning definition by name.
std::vector< std::string > GetDefinitionNames() const
Get all definition names.
NBinningPoint * GetPoint()
Get the current binning point.
std::map< std::string, NBinningDef * > GetDefinitions() const
Get all binning definitions.
THnSparse * GetContent() const
Get the content histogram.
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.
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.
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.
TTree * GetTree() const
Get pointer to TTree 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.
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.
NDMSPC tree branch object for managing ROOT TBranch and associated data.
void SetAddress(void *address, bool deleteExisting=false)
Set address for branch data.
TObject * GetObject() const
Get object pointer.
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.
static TFile * OpenFile(std::string filename, std::string mode="READ", bool createLocalDir=true)
Open a ROOT file.
static std::string GetCoordsString(const std::vector< int > &coords, int index=-1, int width=0)
Get string representation of coordinates.
static std::vector< int > ArrayToVector(Int_t *v1, int size)
Convert array to vector.