JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwRootFile Class Reference

A wrapper class for a ROOT file or memory mapped file. More...

#include <QwRootFile.h>

+ Collaboration diagram for QwRootFile:

Public Member Functions

 QwRootFile (const TString &run_label)
 Constructor with run label.
 
virtual ~QwRootFile ()
 Destructor.
 
void ProcessOptions (QwOptions &options)
 Process the configuration options.
 
Bool_t IsRootFile () const
 Is the ROOT file active?
 
Bool_t IsMapFile () const
 Is the map file active?
 
void ConstructIndices (const std::string &from, const std::string &to, bool reverse=true)
 Construct indices from one tree to another tree.
 
template<class T>
void ConstructTreeBranches (const std::string &name, const std::string &desc, T &object, const std::string &prefix="")
 Construct the tree branches of a generic object.
 
template<class T>
void FillTreeBranches (const std::string &name, const T &object)
 Fill the tree branches of a generic object by tree name.
 
template<class T>
void FillTreeBranches (const T &object)
 Fill the tree branches of a generic object by type only.
 
template<class T>
Int_t WriteParamFileList (const TString &name, T &object)
 
template<class T>
void ConstructObjects (const std::string &name, T &object)
 Construct the histograms of a generic object.
 
template<class T>
void ConstructHistograms (const std::string &name, T &object)
 Construct the histograms of a generic object.
 
template<class T>
void FillHistograms (T &object)
 Fill histograms of the subsystem array.
 
void NewTree (const std::string &name, const std::string &desc)
 Create a new tree with name and description.
 
TTree * GetTree (const std::string &name)
 Get the tree with name.
 
Int_t FillTree (const std::string &name)
 Fill the tree with name.
 
Int_t FillTrees ()
 Fill all registered trees.
 
void PrintTrees () const
 Print registered trees.
 
void PrintDirs () const
 Print registered histogram directories.
 
template<class T>
Int_t WriteObject (const T *obj, const char *name, Option_t *option="", Int_t bufsize=0)
 Write any object to the ROOT file (only valid for TFile)
 
void Update ()
 
void Print ()
 
void ls ()
 
void Map ()
 
void Close ()
 
Bool_t cd (const char *path=0)
 
TDirectory * mkdir (const char *name, const char *title="")
 
Int_t Write (const char *name=0, Int_t option=0, Int_t bufsize=0)
 

Static Public Member Functions

static void DefineOptions (QwOptions &options)
 Define the configuration options.
 
static void SetDefaultRootFileDir (const std::string &dir)
 Set default ROOT files dir.
 
static void SetDefaultRootFileStem (const std::string &stem)
 Set default ROOT file stem.
 

Private Member Functions

void ClearInMemoryObjects (TDirectory *dir)
 
 QwRootFile ()
 Private default constructor.
 
Bool_t HasAnyFilled (void)
 Search for non-empty trees or histograms in the file.
 
Bool_t HasAnyFilled (TDirectory *d)
 
void DisableTree (const TString &regexp)
 Add regexp to list of disabled trees names.
 
bool IsTreeDisabled (const std::string &name)
 Does this tree name match a disabled tree name?
 
void DisableHisto (const TString &regexp)
 Add regexp to list of disabled histogram directories.
 
bool IsHistoDisabled (const std::string &name)
 Does this histogram directory match a disabled histogram directory?
 
bool HasTreeByName (const std::string &name)
 Is a tree registered for this name.
 
template<class T>
bool HasTreeByType (const T &object)
 Is a tree registered for this type.
 
template<class T>
bool HasTreeByAddr (const T &object)
 Is a tree registered for this object.
 
bool HasDirByName (const std::string &name)
 Is a tree registered for this name.
 
template<class T>
bool HasDirByType (const T &object)
 Is a directory registered for this type.
 

Private Attributes

TFile * fRootFile
 ROOT file.
 
TString fRootFileDir
 ROOT files dir.
 
TString fRootFileStem
 ROOT file stem.
 
TString fPermanentName
 
Bool_t fMakePermanent
 
Bool_t fUseTemporaryFile
 
TMapFile * fMapFile
 Map file.
 
Bool_t fEnableMapFile
 
Int_t fUpdateInterval
 
Int_t fCompressionAlgorithm
 
Int_t fCompressionLevel
 
Int_t fRNTupleCompressionAlgorithm
 
Int_t fRNTupleCompressionLevel
 
Int_t fBasketSize
 
Int_t fAutoFlush
 
Int_t fAutoSave
 
std::vector< TPRegexp > fDisabledTrees
 List of excluded trees.
 
std::vector< TPRegexp > fDisabledHistos
 
std::map< const std::string, std::vector< QwRootTree * > > fTreeByName
 Tree names, addresses, and types.
 
std::map< const void *, std::vector< QwRootTree * > > fTreeByAddr
 
std::map< const std::type_index, std::vector< QwRootTree * > > fTreeByType
 
std::map< const std::string, TDirectory * > fDirsByName
 Directories.
 
std::map< const std::string, std::vector< std::string > > fDirsByType
 
UInt_t fNumMpsEventsToSkip
 Prescaling of events written to tree.
 
UInt_t fNumMpsEventsToSave
 
UInt_t fNumHelEventsToSkip
 
UInt_t fNumHelEventsToSave
 
UInt_t fCircularBufferSize
 
UInt_t fCurrentEvent
 

Static Private Attributes

static std::string fDefaultRootFileDir = "."
 Default ROOT files dir.
 
static std::string fDefaultRootFileStem = "Qweak_"
 Default ROOT file stem.
 
static const Long64_t kMaxTreeSize = 100000000000LL
 Maximum tree size.
 
static const Int_t kMaxMapFileSize = 0x3fffffff
 

Detailed Description

A wrapper class for a ROOT file or memory mapped file.

This class functions as a wrapper around a ROOT TFile or a TMapFile. The common inheritance of both is only TObject, so there is a lot that we have to wrap (rather than inherit). Theoretically you could have both a TFile and a TMapFile represented by an object of this class at the same time, but that is untested.

The functionality of writing to the file is done by templated functions. The objects that are passed to these functions have to provide the following functions:

  • ConstructHistograms, FillHistograms
  • ConstructBranchAndVector, FillTreeVector

The class keeps track of the registered tree names, and the types of objects that have branches constructed in those trees (via QwRootTree). In most cases it should be possible to just call FillTreeBranches with only the object, although in rare cases this could be ambiguous.

The proper way to register a tree is by either calling ConstructTreeBranches of NewTree first. Then FillTreeBranches will fill the vector, and FillTree will actually fill the tree. FillTree should be called only once.

Definition at line 849 of file QwRootFile.h.

Constructor & Destructor Documentation

◆ QwRootFile() [1/2]

QwRootFile::QwRootFile ( const TString & run_label)

Constructor with run label.

Constructor with relative filename

Definition at line 28 of file QwRootFile.cc.

30 fMapFile(0), fEnableMapFile(kFALSE),
32#ifdef HAS_RNTUPLE_SUPPORT
33 , fEnableRNTuples(kFALSE)
34#endif // HAS_RNTUPLE_SUPPORT
35{
36 // Process the configuration options
38
39#ifdef QW_ENABLE_MAPFILE
40 // Check for the memory-mapped file flag
41 if (fEnableMapFile) {
42
43 TString mapfilename = "/dev/shm/";
44
45 mapfilename += "/QwMemMapFile.map";
46
47 fMapFile = TMapFile::Create(mapfilename,"UPDATE", kMaxMapFileSize, "RealTime Producer File");
48
49 if (not fMapFile) {
50 QwError << "Memory-mapped file " << mapfilename
51 << " could not be opened!" << QwLog::endl;
52 return;
53 }
54
55 QwMessage << "================== RealTime Producer Memory Map File =================" << QwLog::endl;
56 fMapFile->Print();
57 QwMessage << "======================================================================" << QwLog::endl;
58 } else
59#endif
60 {
61
62 TString rootfilename = fRootFileDir;
63 TString hostname = gSystem -> HostName();
64
65 // Use a probably-unique temporary file name.
66 pid_t pid = getpid();
67
68 fPermanentName = rootfilename
69 + Form("/%s%s.root", fRootFileStem.Data(), run_label.Data());
71 rootfilename += Form("/%s%s.%s.%d.root",
72 fRootFileStem.Data(), run_label.Data(),
73 hostname.Data(), pid);
74 // Delete permanent file if it exists to prevent accumulation across segments
75 if (gSystem->AccessPathName(fPermanentName.Data()) == 0) {
76 QwVerbose << "Removing existing permanent file: " << fPermanentName << QwLog::endl;
77 gSystem->Unlink(fPermanentName.Data());
78 }
79 // CRITICAL: Also delete the temporary file if it exists!
80 // RECREATE mode doesn't properly clear files that contain RNTuples,
81 // so we must manually delete before opening
82 if (gSystem->AccessPathName(rootfilename.Data()) == 0) {
83 QwVerbose << "Removing existing temporary file before RECREATE: " << rootfilename << QwLog::endl;
84 gSystem->Unlink(rootfilename.Data());
85 }
86 } else {
87 rootfilename = fPermanentName;
88 // Delete permanent file if it exists to ensure RECREATE truly starts fresh
89 // This is especially important for RNTuple files where RECREATE doesn't properly clear
90 if (gSystem->AccessPathName(rootfilename.Data()) == 0) {
91 QwMessage << "File exists before RECREATE, deleting: " << rootfilename << QwLog::endl;
92 int unlink_result = gSystem->Unlink(rootfilename.Data());
93 if (unlink_result == 0) {
94 QwMessage << "Successfully deleted file" << QwLog::endl;
95 } else {
96 QwError << "Failed to delete file! Error code: " << unlink_result << QwLog::endl;
97 }
98 } else {
99 QwMessage << "File does not exist before RECREATE: " << rootfilename << QwLog::endl;
100 }
101 }
102 QwMessage << "Opening file with RECREATE mode: " << rootfilename << QwLog::endl;
103 QwMessage << "QwRootFile constructor called for: " << rootfilename << QwLog::endl;
104 // Use TFile::Open instead of `new TFile(...)` so the ROOT plug-in manager
105 // can dispatch remote URLs (e.g. root://host/path) to TNetXNGFile etc.
106 // The TFile(name, opt, title) constructor refuses remote paths and returns
107 // a half-built object, which then segfaults at first use.
108 fRootFile = TFile::Open(rootfilename.Data(), "RECREATE", "myfile1");
109 if (!fRootFile || fRootFile->IsZombie()) {
110 QwError << "ROOT file " << rootfilename
111 << " could not be opened!" << QwLog::endl;
112 delete fRootFile;
113 fRootFile = nullptr;
114 return;
115 } else {
116 QwMessage << "Opened "<< (fUseTemporaryFile?"temporary ":"")
117 <<"rootfile " << rootfilename << QwLog::endl;
118 }
119
120 TString run_condition_name = Form("condition_%s", run_label.Data());
121 TList *run_cond_list = (TList*) fRootFile -> FindObjectAny(run_condition_name);
122 if (not run_cond_list) {
123 QwRunCondition run_condition(
124 gQwOptions.GetArgc(),
125 gQwOptions.GetArgv(),
126 run_condition_name
127 );
128
130 run_condition.Get(),
131 run_condition.GetName()
132 );
133 }
134
135 fRootFile->SetCompressionAlgorithm(fCompressionAlgorithm);
136 fRootFile->SetCompressionLevel(fCompressionLevel);
137 }
138}
#define QwVerbose
Predefined log drain for verbose messages.
Definition QwLog.h:54
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
#define gQwOptions
Definition QwOptions.h:31
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
TString fRootFileStem
ROOT file stem.
TFile * fRootFile
ROOT file.
TString fRootFileDir
ROOT files dir.
Int_t fCompressionAlgorithm
static const Int_t kMaxMapFileSize
Int_t WriteObject(const T *obj, const char *name, Option_t *option="", Int_t bufsize=0)
Write any object to the ROOT file (only valid for TFile)
void ProcessOptions(QwOptions &options)
Process the configuration options.
Int_t fCompressionLevel
Bool_t fUseTemporaryFile
TString fPermanentName
TMapFile * fMapFile
Map file.
Int_t fUpdateInterval
Bool_t fMakePermanent
Bool_t fEnableMapFile

References QwLog::endl(), fCompressionAlgorithm, fCompressionLevel, fEnableMapFile, fMakePermanent, fMapFile, fPermanentName, fRootFile, fRootFileDir, fRootFileStem, fUpdateInterval, fUseTemporaryFile, QwRunCondition::Get(), QwRunCondition::GetName(), gQwOptions, kMaxMapFileSize, ProcessOptions(), QwError, QwMessage, QwVerbose, and WriteObject().

+ Here is the call graph for this function:

◆ ~QwRootFile()

QwRootFile::~QwRootFile ( )
virtual

Destructor.

Destructor

Definition at line 144 of file QwRootFile.cc.

145{
146 // Keep the file on disk if any trees or histograms have been filled.
147 // Also respect any other requests to keep the file around.
149
150 // Close the map file
151 if (fMapFile) {
152 fMapFile->Close();
153 // TMapFiles may not be deleted
154 fMapFile = 0;
155 }
156
157 // Close the ROOT file.
158 // Rename if permanence is requested, remove otherwise
159 if (fRootFile) {
160 TString rootfilename = fRootFile->GetName();
161
162 fRootFile->Close();
163 delete fRootFile;
164 fRootFile = 0;
165
166 int err;
167 const char* action;
169 if (fMakePermanent) {
170 // Delete existing permanent file first to avoid accumulation
171 if (gSystem->AccessPathName(fPermanentName.Data()) == 0) {
172 remove(fPermanentName.Data());
173 }
174 action = " rename ";
175 err = rename( rootfilename.Data(), fPermanentName.Data() );
176 } else {
177 action = " remove ";
178 err = remove( rootfilename.Data() );
179 }
180 // It'd be proper to "extern int errno" and strerror() here,
181 // but that doesn't seem very C++-ish.
182 if (err) {
183 QwWarning << "Couldn't" << action << rootfilename << QwLog::endl;
184 } else {
185 QwMessage << "Was able to" << action << rootfilename << QwLog::endl;
186 QwMessage << "Root file is " << fPermanentName << QwLog::endl;
187 }
188 }
189 }
190
191 // Delete Qweak ROOT trees
192 std::map< const std::string, std::vector<QwRootTree*> >::iterator map_iter;
193 std::vector<QwRootTree*>::iterator vec_iter;
194 for (map_iter = fTreeByName.begin(); map_iter != fTreeByName.end(); map_iter++) {
195 for (vec_iter = map_iter->second.begin(); vec_iter != map_iter->second.end(); vec_iter++) {
196 delete *vec_iter;
197 }
198 }
199}
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
Bool_t HasAnyFilled(void)
Search for non-empty trees or histograms in the file.
std::map< const std::string, std::vector< QwRootTree * > > fTreeByName
Tree names, addresses, and types.

References QwLog::endl(), fMakePermanent, fMapFile, fPermanentName, fRootFile, fTreeByName, fUseTemporaryFile, HasAnyFilled(), QwMessage, and QwWarning.

+ Here is the call graph for this function:

◆ QwRootFile() [2/2]

QwRootFile::QwRootFile ( )
private

Private default constructor.

Member Function Documentation

◆ cd()

Bool_t QwRootFile::cd ( const char * path = 0)
inline

Definition at line 1157 of file QwRootFile.h.

1157 {
1158 Bool_t status = kTRUE;
1159 if (fMapFile) status &= fMapFile->cd(path);
1160 if (fRootFile) status &= fRootFile->cd(path);
1161 return status;
1162 }

References fMapFile, and fRootFile.

Referenced by ConstructTreeBranches(), and NewTree().

+ Here is the caller graph for this function:

◆ ClearInMemoryObjects()

void QwRootFile::ClearInMemoryObjects ( TDirectory * dir)
inlineprivate

Recursively clear in-memory objects from a directory tree. This removes objects from the TDirectory's in-memory list without deleting their on-disk representation (keys). Used to prevent RNTupleWriter::Close() from creating duplicate histogram cycles when it internally calls TFile::Write().

Definition at line 1074 of file QwRootFile.h.

1074 {
1075 if (!dir) return;
1076
1077 // First, collect subdirectory names
1078 std::vector<TString> subdirs;
1079 TIter next(dir->GetListOfKeys());
1080 TKey* key;
1081 while ((key = (TKey*)next())) {
1082 if (TString(key->GetClassName()) == "TDirectoryFile") {
1083 subdirs.push_back(key->GetName());
1084 }
1085 }
1086
1087 // Recursively clear subdirectories
1088 for (const auto& name : subdirs) {
1089 TDirectory* sub = dynamic_cast<TDirectory*>(dir->Get(name));
1090 if (sub) ClearInMemoryObjects(sub);
1091 }
1092
1093 // Clear this directory's in-memory object list
1094 // "nodelete" option: remove from list but don't delete the TKey entries
1095 TList* list = dir->GetList();
1096 if (list) {
1097 list->Clear("nodelete");
1098 }
1099 }
void ClearInMemoryObjects(TDirectory *dir)

References ClearInMemoryObjects().

Referenced by ClearInMemoryObjects(), and Close().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Close()

void QwRootFile::Close ( )
inline

Definition at line 1102 of file QwRootFile.h.

1102 {
1103
1104 if (fRootFile) {
1105 // Step 1: Write all trees explicitly
1106 for (auto iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
1107 if (!iter->second.empty() && iter->second.front()) {
1108 TTree* tree = iter->second.front()->GetTree();
1109 if (tree && tree->GetEntries() > 0) {
1110 tree->Write();
1111 }
1112 }
1113 }
1114
1115 // Step 2: Write all in-memory objects (histograms, etc.) to disk
1116 // Use kOverwrite to avoid creating duplicate cycles
1117 fRootFile->Write(0, TObject::kOverwrite);
1118
1119 // Check if we should make the file permanent AFTER writing
1120 // This ensures histograms are on disk and detectable by HasAnyFilled()
1122
1123 // Step 3: CRITICAL FIX for RNTuple histogram duplication
1124 // Clear all in-memory objects from the TFile's directory structure.
1125 // This prevents RNTupleWriter::Close() from re-writing histograms,
1126 // which would create duplicate cycles. The histograms are already
1127 // safely written to disk in Step 2.
1128#ifdef HAS_RNTUPLE_SUPPORT
1129 if (!fNTupleByName.empty()) {
1131 }
1132#endif // HAS_RNTUPLE_SUPPORT
1133 }
1134
1135#ifdef HAS_RNTUPLE_SUPPORT
1136 // Step 4: Close all RNTuples
1137 // Now that in-memory histograms are cleared, the RNTupleWriter destructor
1138 // won't create duplicate histogram cycles when it internally writes to TFile
1139 for (auto& pair : fNTupleByName) {
1140 for (auto& ntuple : pair.second) {
1141 if (ntuple) ntuple->Close();
1142 }
1143 }
1144#endif // HAS_RNTUPLE_SUPPORT
1145
1146 // Step 5: Close the file
1147 if (fRootFile) {
1148 fRootFile->Close();
1149 }
1150
1151 // TMapFile::Close() is NOT idempotent: re-closing in ~QwRootFile()
1152 // crashes on the already-detached mmap descriptor.
1153 if (fMapFile) { fMapFile->Close(); fMapFile = 0; }
1154 }

References ClearInMemoryObjects(), fMakePermanent, fMapFile, fRootFile, fTreeByName, and HasAnyFilled().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ConstructHistograms()

template<class T>
void QwRootFile::ConstructHistograms ( const std::string & name,
T & object )

Construct the histograms of a generic object.

Construct the histogram of a generic object

Parameters
nameName for histogram directory
objectSubsystem array

Definition at line 1622 of file QwRootFile.h.

1623{
1624 // Return if we do not want this histogram information
1625 if (IsHistoDisabled(name)) return;
1626
1627 // Create the histograms in a directory
1628 if (fRootFile) {
1629 std::string type = typeid(object).name();
1630 fDirsByName[name] =
1631 fRootFile->GetDirectory(("/" + name).c_str()) ?
1632 fRootFile->GetDirectory(("/" + name).c_str()) :
1633 fRootFile->GetDirectory("/")->mkdir(name.c_str());
1634 fDirsByType[type].push_back(name);
1635
1636 object.ConstructHistograms(fDirsByName[name]);
1637 }
1638
1639 // No support for directories in a map file
1640 if (fMapFile) {
1641 QwMessage << "QwRootFile::ConstructHistograms::detectors address "
1642 << &object
1643 << " and its name " << name
1644 << QwLog::endl;
1645
1646 std::string type = typeid(object).name();
1647 fDirsByName[name] = fMapFile->GetDirectory()->mkdir(name.c_str());
1648 fDirsByType[type].push_back(name);
1649 //object.ConstructHistograms(fDirsByName[name]);
1650 object.ConstructHistograms();
1651 }
1652}
std::map< const std::string, std::vector< std::string > > fDirsByType
std::map< const std::string, TDirectory * > fDirsByName
Directories.
bool IsHistoDisabled(const std::string &name)
Does this histogram directory match a disabled histogram directory?

References QwLog::endl(), fDirsByName, fDirsByType, fMapFile, fRootFile, IsHistoDisabled(), and QwMessage.

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ConstructIndices()

void QwRootFile::ConstructIndices ( const std::string & from,
const std::string & to,
bool reverse = true )
inline

Construct indices from one tree to another tree.

Construct the indices from one tree to another tree, and optionally in reverse as well.

Parameters
fromName of tree where index will be created
toName of tree to which index will point
reverseFlag to create indices in both direction

Definition at line 1350 of file QwRootFile.h.

1351{
1352 // Return if we do not want this tree information
1353 if (IsTreeDisabled(from)) return;
1354 if (IsTreeDisabled(to)) return;
1355
1356 // If the trees are defined
1357 if (fTreeByName.count(from) > 0 && fTreeByName.count(to) > 0) {
1358
1359 // Construct index from the first tree to the second tree
1360 fTreeByName[from].front()->ConstructIndexTo(fTreeByName[to].front());
1361
1362 // Construct index from the second tree back to the first tree
1363 if (reverse)
1364 fTreeByName[to].front()->ConstructIndexTo(fTreeByName[from].front());
1365 }
1366}
bool IsTreeDisabled(const std::string &name)
Does this tree name match a disabled tree name?

References fTreeByName, and IsTreeDisabled().

+ Here is the call graph for this function:

◆ ConstructObjects()

template<class T>
void QwRootFile::ConstructObjects ( const std::string & name,
T & object )

Construct the histograms of a generic object.

Construct the objects directory of a generic object

Parameters
nameName for objects directory
objectSubsystem array

Definition at line 1588 of file QwRootFile.h.

1589{
1590 // Create the objects in a directory
1591 if (fRootFile) {
1592 std::string type = typeid(object).name();
1593 fDirsByName[name] =
1594 fRootFile->GetDirectory(("/" + name).c_str()) ?
1595 fRootFile->GetDirectory(("/" + name).c_str()) :
1596 fRootFile->GetDirectory("/")->mkdir(name.c_str());
1597 fDirsByType[type].push_back(name);
1598 object.ConstructObjects(fDirsByName[name]);
1599 }
1600
1601 // No support for directories in a map file
1602 if (fMapFile) {
1603 QwMessage << "QwRootFile::ConstructObjects::detectors address "
1604 << &object
1605 << " and its name " << name
1606 << QwLog::endl;
1607
1608 std::string type = typeid(object).name();
1609 fDirsByName[name] = fMapFile->GetDirectory()->mkdir(name.c_str());
1610 fDirsByType[type].push_back(name);
1611 object.ConstructObjects();
1612 }
1613}

References QwLog::endl(), fDirsByName, fDirsByType, fMapFile, fRootFile, and QwMessage.

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ConstructTreeBranches()

template<class T>
void QwRootFile::ConstructTreeBranches ( const std::string & name,
const std::string & desc,
T & object,
const std::string & prefix = "" )

Construct the tree branches of a generic object.

Construct the tree branches of a generic object

Parameters
nameName for tree
descDescription for tree
objectSubsystem array
prefixPrefix for the tree

Definition at line 1376 of file QwRootFile.h.

1381{
1382 // Return if we do not want this tree information
1383 if (IsTreeDisabled(name)) return;
1384
1385 // Pointer to new tree
1386 QwRootTree* tree = 0;
1387
1388 // If the tree does not exist yet, create it
1389 if (fTreeByName.count(name) == 0) {
1390
1391 // Go to top level directory
1392
1393 this->cd();
1394
1395 // New tree with name, description, object, prefix
1396 tree = new QwRootTree(name, desc, object, prefix);
1397
1398 // Settings only relevant for new trees
1399 if (name == "evt")
1401 else if (name == "mul")
1403
1404 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
1405 tree->SetAutoFlush(fAutoFlush);
1406 #endif
1407 tree->SetAutoSave(fAutoSave);
1410
1411 if (fCircularBufferSize > 0)
1413
1414 } else {
1415
1416 // New tree based on existing tree
1417 tree = new QwRootTree(fTreeByName[name].front(), object, prefix);
1418 }
1419
1420 // Add the branches to the list of trees by name, object, type
1421 const void* addr = static_cast<const void*>(&object);
1422 const std::type_index type = typeid(object);
1423 fTreeByName[name].push_back(tree);
1424 fTreeByAddr[addr].push_back(tree);
1425 fTreeByType[type].push_back(tree);
1426}
void SetAutoFlush(Long64_t autoflush=30000000)
Set autoflush size.
Definition QwRootFile.h:583
void SetCircular(Long64_t buff=100000)
Definition QwRootFile.h:603
void SetMaxTreeSize(Long64_t maxsize=1900000000)
Set maximum tree size.
Definition QwRootFile.h:577
void SetAutoSave(Long64_t autosave=300000000)
Set autosave size.
Definition QwRootFile.h:591
void SetBasketSize(Int_t basketsize=16000)
Set basket size.
Definition QwRootFile.h:597
void SetPrescaling(UInt_t num_to_save, UInt_t num_to_skip)
Set tree prescaling parameters.
Definition QwRootFile.h:563
Int_t fBasketSize
Bool_t cd(const char *path=0)
UInt_t fNumHelEventsToSkip
Int_t fAutoSave
UInt_t fNumMpsEventsToSave
std::map< const std::type_index, std::vector< QwRootTree * > > fTreeByType
UInt_t fNumHelEventsToSave
Int_t fAutoFlush
UInt_t fCircularBufferSize
std::map< const void *, std::vector< QwRootTree * > > fTreeByAddr
static const Long64_t kMaxTreeSize
Maximum tree size.
UInt_t fNumMpsEventsToSkip
Prescaling of events written to tree.

References cd(), fAutoFlush, fAutoSave, fBasketSize, fCircularBufferSize, fNumHelEventsToSave, fNumHelEventsToSkip, fNumMpsEventsToSave, fNumMpsEventsToSkip, fTreeByAddr, fTreeByName, fTreeByType, IsTreeDisabled(), kMaxTreeSize, QwRootTree::SetAutoFlush(), QwRootTree::SetAutoSave(), QwRootTree::SetBasketSize(), QwRootTree::SetCircular(), QwRootTree::SetMaxTreeSize(), and QwRootTree::SetPrescaling().

Referenced by QwExtractor::ConstructTreeBranches(), VQwDataHandler::ConstructTreeBranches(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DefineOptions()

void QwRootFile::DefineOptions ( QwOptions & options)
static

Define the configuration options.

Defines configuration options using QwOptions functionality.

Parameters
optionsOptions object

Definition at line 205 of file QwRootFile.cc.

206{
207 // Define the ROOT files directory
208 options.AddOptions("Default options")
209 ("rootfiles", po::value<std::string>()->default_value(fDefaultRootFileDir),
210 "directory of the output ROOT files");
211
212 // Define the ROOT filename stem
213 options.AddOptions("Default options")
214 ("rootfile-stem", po::value<std::string>()->default_value(fDefaultRootFileStem),
215 "stem of the output ROOT filename");
216
217 // Define the memory map option
218 options.AddOptions()
219 ("enable-mapfile", po::value<bool>()->default_bool_value(false),
220 "enable output to memory-mapped file\n(likely requires circular-buffer too)");
221 options.AddOptions()
222 ("write-temporary-rootfiles", po::value<bool>()->default_bool_value(true),
223 "When writing ROOT files, use the PID to create a temporary filename");
224
225 // Define the histogram and tree options
226 options.AddOptions("ROOT output options")
227 ("disable-tree", po::value<std::vector<std::string>>()->composing(),
228 "disable output to tree regex");
229 options.AddOptions("ROOT output options")
230 ("disable-trees", po::value<bool>()->default_bool_value(false),
231 "disable output to all trees");
232 options.AddOptions("ROOT output options")
233 ("disable-histos", po::value<bool>()->default_bool_value(false),
234 "disable output to all histograms");
235
236 // Define the helicity window versus helicity pattern options
237 options.AddOptions("ROOT output options")
238 ("disable-mps-tree", po::value<bool>()->default_bool_value(false),
239 "disable helicity window output");
240 options.AddOptions("ROOT output options")
241 ("disable-pair-tree", po::value<bool>()->default_bool_value(false),
242 "disable helicity pairs output");
243 options.AddOptions("ROOT output options")
244 ("disable-hel-tree", po::value<bool>()->default_bool_value(false),
245 "disable helicity pattern output");
246 options.AddOptions("ROOT output options")
247 ("disable-burst-tree", po::value<bool>()->default_bool_value(false),
248 "disable burst tree");
249 options.AddOptions("ROOT output options")
250 ("disable-slow-tree", po::value<bool>()->default_bool_value(false),
251 "disable slow control tree");
252
253#ifdef HAS_RNTUPLE_SUPPORT
254 // Define the RNTuple options
255 options.AddOptions("ROOT output options")
256 ("enable-rntuples", po::value<bool>()->default_bool_value(false),
257 "enable RNTuple output");
258#endif // HAS_RNTUPLE_SUPPORT
259
260 // Define the tree output prescaling options
261 options.AddOptions("ROOT output options")
262 ("num-mps-accepted-events", po::value<int>()->default_value(0),
263 "number of accepted consecutive MPS events");
264 options.AddOptions("ROOT output options")
265 ("num-mps-discarded-events", po::value<int>()->default_value(0),
266 "number of discarded consecutive MPS events");
267 options.AddOptions("ROOT output options")
268 ("num-hel-accepted-events", po::value<int>()->default_value(0),
269 "number of accepted consecutive pattern events");
270 options.AddOptions("ROOT output options")
271 ("num-hel-discarded-events", po::value<int>()->default_value(0),
272 "number of discarded consecutive pattern events");
273 options.AddOptions("ROOT output options")
274 ("mapfile-update-interval", po::value<int>()->default_value(-1),
275 "Events between a map file update");
276
277 // Define the autoflush and autosave option (default values by ROOT)
278 options.AddOptions("ROOT performance options")
279 ("autoflush", po::value<int>()->default_value(0),
280 "TTree autoflush");
281 options.AddOptions("ROOT performance options")
282 ("autosave", po::value<int>()->default_value(300000000),
283 "TTree autosave");
284 options.AddOptions("ROOT performance options")
285 ("basket-size", po::value<int>()->default_value(16000),
286 "TTree basket size");
287 options.AddOptions("ROOT performance options")
288 ("circular-buffer", po::value<int>()->default_value(0),
289 "TTree circular buffer");
290 options.AddOptions("ROOT performance options")
291 ("compression-algorithm", po::value<int>()->default_value(1),
292 "TFile compression algorithm (1=ZLIB, 2=LZMA, 4=LZ4, 5=ZSTD, default=1 ZLIB)");
293 options.AddOptions("ROOT performance options")
294 ("compression-level", po::value<int>()->default_value(1),
295 "TFile compression level (default = 1, no compression = 0)");
296 options.AddOptions("ROOT performance options")
297 ("rntuple-compression-algorithm", po::value<int>()->default_value(4),
298 "RNTuple compression algorithm (1=ZLIB, 2=LZMA, 4=LZ4, 5=ZSTD, default=4 LZ4)");
299 options.AddOptions("ROOT performance options")
300 ("rntuple-compression-level", po::value<int>()->default_value(0),
301 "RNTuple compression level (0-12, default=0 for maximum performance)");
302}
po::options_description_easy_init AddOptions(const std::string &blockname="Specialized options")
Add an option to a named block or create new block.
Definition QwOptions.h:170
static std::string fDefaultRootFileDir
Default ROOT files dir.
static std::string fDefaultRootFileStem
Default ROOT file stem.

References QwOptions::AddOptions(), fDefaultRootFileDir, and fDefaultRootFileStem.

Referenced by QwOptions::DefineOptions().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ DisableHisto()

void QwRootFile::DisableHisto ( const TString & regexp)
inlineprivate

Add regexp to list of disabled histogram directories.

Definition at line 1240 of file QwRootFile.h.

1240 {
1241 fDisabledHistos.push_back(regexp);
1242 }
std::vector< TPRegexp > fDisabledHistos

References fDisabledHistos.

Referenced by ProcessOptions().

+ Here is the caller graph for this function:

◆ DisableTree()

void QwRootFile::DisableTree ( const TString & regexp)
inlineprivate

Add regexp to list of disabled trees names.

Definition at line 1230 of file QwRootFile.h.

1230 {
1231 fDisabledTrees.push_back(regexp);
1232 }
std::vector< TPRegexp > fDisabledTrees
List of excluded trees.

References fDisabledTrees.

Referenced by ProcessOptions().

+ Here is the caller graph for this function:

◆ FillHistograms()

template<class T>
void QwRootFile::FillHistograms ( T & object)
inline

Fill histograms of the subsystem array.

Definition at line 917 of file QwRootFile.h.

917 {
918 // Update regularly
919 static Int_t update_count = 0;
920 update_count++;
921 if ((fUpdateInterval > 0) && ( update_count % fUpdateInterval == 0)) Update();
922
923 // Debug directory registration
924 std::string type = typeid(object).name();
925 bool hasDir = HasDirByType(object);
926
927 if (! hasDir) return;
928 // Fill histograms
929 object.FillHistograms();
930 }
bool HasDirByType(const T &object)
Is a directory registered for this type.
void Update()

References fUpdateInterval, HasDirByType(), and Update().

Referenced by main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FillTree()

Int_t QwRootFile::FillTree ( const std::string & name)
inline

Fill the tree with name.

Definition at line 974 of file QwRootFile.h.

974 {
975 if (! HasTreeByName(name)) return 0;
976 else return fTreeByName[name].front()->Fill();
977 }
bool HasTreeByName(const std::string &name)
Is a tree registered for this name.

References fTreeByName, and HasTreeByName().

Referenced by QwExtractor::FillTreeBranches(), VQwDataHandler::FillTreeBranches(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FillTreeBranches() [1/2]

template<class T>
void QwRootFile::FillTreeBranches ( const std::string & name,
const T & object )

Fill the tree branches of a generic object by tree name.

Fill the tree branches of a generic object by name

Parameters
nameName for tree
objectSubsystem array

Definition at line 1435 of file QwRootFile.h.

1438{
1439 // If this name has no registered trees
1440 if (! HasTreeByName(name)) return;
1441 // If this type has no registered trees
1442 if (! HasTreeByType(object)) return;
1443
1444 // Get the address of the object
1445 const void* addr = static_cast<const void*>(&object);
1446
1447 // Fill the trees with the correct address
1448 for (size_t tree = 0; tree < fTreeByAddr[addr].size(); tree++) {
1449 if (fTreeByAddr[addr].at(tree)->GetName() == name) {
1450 fTreeByAddr[addr].at(tree)->FillTreeBranches(object);
1451 }
1452 }
1453}
bool HasTreeByType(const T &object)
Is a tree registered for this type.

References fTreeByAddr, HasTreeByName(), and HasTreeByType().

Referenced by QwExtractor::FillTreeBranches(), VQwDataHandler::FillTreeBranches(), and main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ FillTreeBranches() [2/2]

template<class T>
void QwRootFile::FillTreeBranches ( const T & object)

Fill the tree branches of a generic object by type only.

Fill the tree branches of a generic object by type only

Parameters
objectSubsystem array

Definition at line 1461 of file QwRootFile.h.

1463{
1464 // If this address has no registered trees
1465 if (! HasTreeByAddr(object)) return;
1466
1467 // Get the address of the object
1468 const void* addr = static_cast<const void*>(&object);
1469
1470 // Fill the trees with the correct address
1471 for (size_t tree = 0; tree < fTreeByAddr[addr].size(); tree++) {
1472 fTreeByAddr[addr].at(tree)->FillTreeBranches(object);
1473 }
1474}
bool HasTreeByAddr(const T &object)
Is a tree registered for this object.

References fTreeByAddr, and HasTreeByAddr().

+ Here is the call graph for this function:

◆ FillTrees()

Int_t QwRootFile::FillTrees ( )
inline

Fill all registered trees.

Definition at line 980 of file QwRootFile.h.

980 {
981 // Loop over all registered tree names
982 Int_t retval = 0;
983 std::map< const std::string, std::vector<QwRootTree*> >::iterator iter;
984 for (iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
985 retval += iter->second.front()->Fill();
986 }
987 return retval;
988 }

References fTreeByName.

◆ GetTree()

TTree * QwRootFile::GetTree ( const std::string & name)
inline

Get the tree with name.

Definition at line 968 of file QwRootFile.h.

968 {
969 if (! HasTreeByName(name)) return 0;
970 else return fTreeByName[name].front()->GetTree();
971 }

References fTreeByName, and HasTreeByName().

Referenced by GrandCorrelator::ConstructTreeBranches(), QwCorrelator::ConstructTreeBranches(), and QwCorrelatorNew::ConstructTreeBranches().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasAnyFilled() [1/2]

Bool_t QwRootFile::HasAnyFilled ( TDirectory * d)
private

Definition at line 458 of file QwRootFile.cc.

458 {
459 if (!d) {
460
461 return false;
462 }
463
464 // First check if any in-memory trees have been filled
465 for (auto& pair : fTreeByName) {
466 for (auto& tree : pair.second) {
467 if (tree && tree->GetTree()) {
468 Long64_t entries = tree->GetTree()->GetEntries();
469 if (entries > 0) {
470
471 return true;
472 }
473 }
474 }
475 }
476
477#ifdef HAS_RNTUPLE_SUPPORT
478 // Then check if any RNTuples have been filled
479 for (auto& pair : fNTupleByName) {
480 for (auto& ntuple : pair.second) {
481 if (ntuple && ntuple->fCurrentEvent > 0) {
482
483 return true;
484 }
485 }
486 }
487#endif // HAS_RNTUPLE_SUPPORT
488
489 TList* l = d->GetListOfKeys();
490
491
492 for( int i=0; i < l->GetEntries(); ++i) {
493 const char* name = l->At(i)->GetName();
494 TObject* obj = d->FindObjectAny(name);
495
496
497
498 // Objects which can't be found don't count.
499 if (!obj) {
500
501 continue;
502 }
503
504 // Lists of parameter files, map files, and job conditions don't count.
505 if ( TString(name).Contains("parameter_file") ) {
506
507 continue;
508 }
509 if ( TString(name).Contains("mapfile") ) {
510 continue;
511 }
512 if ( TString(name).Contains("_condition") ) {
513 continue;
514 }
515 // The EPICS tree doesn't count
516 if ( TString(name).Contains("slow") ) {
517 continue;
518 }
519
520 // Recursively check subdirectories.
521 if (obj->IsA()->InheritsFrom( "TDirectory" )) {
522 if (this->HasAnyFilled( (TDirectory*)obj )) return true;
523 }
524
525 if (obj->IsA()->InheritsFrom( "TTree" )) {
526 Long64_t entries = ((TTree*) obj)->GetEntries();
527 if ( entries ) return true;
528 }
529
530 if (obj->IsA()->InheritsFrom( "TH1" )) {
531 Double_t entries = ((TH1*) obj)->GetEntries();
532 if ( entries ) return true;
533 }
534 }
535 return false;
536}

References fTreeByName, and HasAnyFilled().

+ Here is the call graph for this function:

◆ HasAnyFilled() [2/2]

Bool_t QwRootFile::HasAnyFilled ( void )
private

Search for non-empty trees or histograms in the file.

Determine whether the rootfile object has any non-empty trees or histograms.

Definition at line 455 of file QwRootFile.cc.

455 {
456 return this->HasAnyFilled(fRootFile);
457}

References fRootFile, and HasAnyFilled().

Referenced by Close(), HasAnyFilled(), HasAnyFilled(), and ~QwRootFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ HasDirByName()

bool QwRootFile::HasDirByName ( const std::string & name)
inlineprivate

Is a tree registered for this name.

Definition at line 1316 of file QwRootFile.h.

1316 {
1317 if (fDirsByName.count(name) == 0) return false;
1318 else return true;
1319 }

References fDirsByName.

◆ HasDirByType()

template<class T>
bool QwRootFile::HasDirByType ( const T & object)
inlineprivate

Is a directory registered for this type.

Definition at line 1322 of file QwRootFile.h.

1322 {
1323 std::string type = typeid(object).name();
1324 if (fDirsByType.count(type) == 0) return false;
1325 else return true;
1326 }

References fDirsByType.

Referenced by FillHistograms().

+ Here is the caller graph for this function:

◆ HasTreeByAddr()

template<class T>
bool QwRootFile::HasTreeByAddr ( const T & object)
inlineprivate

Is a tree registered for this object.

Definition at line 1283 of file QwRootFile.h.

1283 {
1284 const void* addr = static_cast<const void*>(&object);
1285 if (fTreeByAddr.count(addr) == 0) return false;
1286 else return true;
1287 }

References fTreeByAddr.

Referenced by FillTreeBranches().

+ Here is the caller graph for this function:

◆ HasTreeByName()

bool QwRootFile::HasTreeByName ( const std::string & name)
inlineprivate

Is a tree registered for this name.

Definition at line 1270 of file QwRootFile.h.

1270 {
1271 if (fTreeByName.count(name) == 0) return false;
1272 else return true;
1273 }

References fTreeByName.

Referenced by FillTree(), FillTreeBranches(), GetTree(), and NewTree().

+ Here is the caller graph for this function:

◆ HasTreeByType()

template<class T>
bool QwRootFile::HasTreeByType ( const T & object)
inlineprivate

Is a tree registered for this type.

Definition at line 1276 of file QwRootFile.h.

1276 {
1277 const std::type_index type = typeid(object);
1278 if (fTreeByType.count(type) == 0) return false;
1279 else return true;
1280 }

References fTreeByType.

Referenced by FillTreeBranches().

+ Here is the caller graph for this function:

◆ IsHistoDisabled()

bool QwRootFile::IsHistoDisabled ( const std::string & name)
inlineprivate

Does this histogram directory match a disabled histogram directory?

Definition at line 1244 of file QwRootFile.h.

1244 {
1245 for (size_t i = 0; i < fDisabledHistos.size(); i++)
1246 if (fDisabledHistos.at(i).Match(name)) return true;
1247 return false;
1248 }

References fDisabledHistos.

Referenced by ConstructHistograms().

+ Here is the caller graph for this function:

◆ IsMapFile()

Bool_t QwRootFile::IsMapFile ( ) const
inline

Is the map file active?

Definition at line 876 of file QwRootFile.h.

876{ return (fMapFile); };

References fMapFile.

◆ IsRootFile()

Bool_t QwRootFile::IsRootFile ( ) const
inline

Is the ROOT file active?

Definition at line 874 of file QwRootFile.h.

874{ return (fRootFile); };

References fRootFile.

◆ IsTreeDisabled()

bool QwRootFile::IsTreeDisabled ( const std::string & name)
inlineprivate

Does this tree name match a disabled tree name?

Definition at line 1234 of file QwRootFile.h.

1234 {
1235 for (size_t i = 0; i < fDisabledTrees.size(); i++)
1236 if (fDisabledTrees.at(i).Match(name)) return true;
1237 return false;
1238 }

References fDisabledTrees.

Referenced by ConstructIndices(), ConstructTreeBranches(), and NewTree().

+ Here is the caller graph for this function:

◆ ls()

void QwRootFile::ls ( )
inline

Definition at line 1066 of file QwRootFile.h.

1066{ if (fMapFile) fMapFile->ls(); if (fRootFile) fRootFile->ls(); }

References fMapFile, and fRootFile.

◆ Map()

void QwRootFile::Map ( )
inline

Definition at line 1067 of file QwRootFile.h.

1067{ if (fRootFile) fRootFile->Map(); }

References fRootFile.

◆ mkdir()

TDirectory * QwRootFile::mkdir ( const char * name,
const char * title = "" )
inline

Definition at line 1165 of file QwRootFile.h.

1165 {
1166 // TMapFile has no support for mkdir
1167 if (fRootFile) return fRootFile->mkdir(name, title);
1168 else return 0;
1169 }

References fRootFile.

◆ NewTree()

void QwRootFile::NewTree ( const std::string & name,
const std::string & desc )
inline

Create a new tree with name and description.

Definition at line 934 of file QwRootFile.h.

934 {
935 if (IsTreeDisabled(name)) return;
936 this->cd();
937 QwRootTree *tree = 0;
938 if (! HasTreeByName(name)) {
939 tree = new QwRootTree(name,desc);
940 } else {
941 tree = new QwRootTree(fTreeByName[name].front());
942 }
943 fTreeByName[name].push_back(tree);
944 }

References cd(), fTreeByName, HasTreeByName(), and IsTreeDisabled().

Referenced by GrandCorrelator::ConstructTreeBranches(), QwCorrelator::ConstructTreeBranches(), and QwCorrelatorNew::ConstructTreeBranches().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Print()

void QwRootFile::Print ( )
inline

Definition at line 1065 of file QwRootFile.h.

1065{ if (fMapFile) fMapFile->Print(); if (fRootFile) fRootFile->Print(); }

References fMapFile, and fRootFile.

◆ PrintDirs()

void QwRootFile::PrintDirs ( ) const
inline

Print registered histogram directories.

Definition at line 1026 of file QwRootFile.h.

1026 {
1027 QwMessage << "Dirs: " << QwLog::endl;
1028 // Loop ove rall registered directories
1029 std::map< const std::string, TDirectory* >::const_iterator iter;
1030 for (iter = fDirsByName.begin(); iter != fDirsByName.end(); iter++) {
1031 QwMessage << iter->first << QwLog::endl;
1032 }
1033 }

References QwLog::endl(), fDirsByName, and QwMessage.

+ Here is the call graph for this function:

◆ PrintTrees()

void QwRootFile::PrintTrees ( ) const
inline

Print registered trees.

Definition at line 1011 of file QwRootFile.h.

1011 {
1012 QwMessage << "Trees: " << QwLog::endl;
1013 // Loop over all registered tree names
1014 std::map< const std::string, std::vector<QwRootTree*> >::const_iterator iter;
1015 for (iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
1016 QwMessage << iter->first << ": " << iter->second.size()
1017 << " objects registered" << QwLog::endl;
1018 // Loop over all registered objects for this tree
1019 std::vector<QwRootTree*>::const_iterator tree;
1020 for (tree = iter->second.begin(); tree != iter->second.end(); tree++) {
1021 (*tree)->Print();
1022 }
1023 }
1024 }

References QwLog::endl(), fTreeByName, and QwMessage.

+ Here is the call graph for this function:

◆ ProcessOptions()

void QwRootFile::ProcessOptions ( QwOptions & options)

Process the configuration options.

Parse the configuration options and store in class fields

Parameters
optionsOptions object

Definition at line 309 of file QwRootFile.cc.

310{
311 // Option 'rootfiles' to specify ROOT files dir
312 fRootFileDir = TString(options.GetValue<std::string>("rootfiles"));
313 fs::path tmppath(fRootFileDir.Data());
314 if( ! fs::exists(tmppath) || ! fs::is_directory(tmppath)) {
315 QwError << "ERROR: The rootfile directory path, " << fRootFileDir
316 << ", does not exist. Exiting."
317 << QwLog::endl;
318 exit(2);
319 }
320
321 // Option 'root-stem' to specify ROOT file stem
322 fRootFileStem = TString(options.GetValue<std::string>("rootfile-stem"));
323
324 // Option 'mapfile' to enable memory-mapped ROOT file
325 fEnableMapFile = options.GetValue<bool>("enable-mapfile");
326#ifndef QW_ENABLE_MAPFILE
327 if( fEnableMapFile ) {
329 QwWarning << "QwRootFile::ProcessOptions: "
330 << "The 'enable-mapfile' flag is not supported by the ROOT "
331 "version with which this app is built. Disabling it."
332 << QwLog::endl;
333 fEnableMapFile = false;
334 }
335#endif
336 fUseTemporaryFile = options.GetValue<bool>("write-temporary-rootfiles");
337
338#ifdef HAS_RNTUPLE_SUPPORT
339 // Option 'enable-rntuples' to enable RNTuple output
340 fEnableRNTuples = options.GetValue<bool>("enable-rntuples");
341 // RNTuples require a TFile (RNTupleWriter::Append takes a TDirectory&);
342 // they cannot be hosted by a TMapFile. If both flags are requested,
343 // disable RNTuples and warn loudly so the run does not crash later in
344 // QwRootNTuple::InitializeWriter with a null TFile*.
345 if (fEnableMapFile && fEnableRNTuples) {
347 QwWarning << "QwRootFile::ProcessOptions: "
348 << "RNTuple output is not supported alongside --enable-mapfile "
349 "(TMapFile is not a TDirectory). Disabling RNTuples."
350 << QwLog::endl;
351 fEnableRNTuples = false;
352 }
353#endif // HAS_RNTUPLE_SUPPORT
354
355 // Options 'disable-trees' and 'disable-histos' for disabling
356 // tree and histogram output
357 auto v = options.GetValueVector<std::string>("disable-tree");
358 std::for_each(v.begin(), v.end(), [&](const std::string& s){ this->DisableTree(s); });
359 if (options.GetValue<bool>("disable-trees")) DisableTree(".*");
360 if (options.GetValue<bool>("disable-histos")) DisableHisto(".*");
361
362 // Read --circular-buffer up front so the mapfile-mode logic below can use
363 // it (the original ProcessOptions read it further down, but we now need
364 // it during the mapfile-tree decision).
365 fCircularBufferSize = options.GetValue<int>("circular-buffer");
366
367 // TMapFile-mode tree publishing.
368 //
369 // TTrees can be published into the mapfile: TDirectoryFile::Append
370 // auto-calls TMapFile::Add() when the directory's mother is a TMapFile,
371 // so a TTree created while gDirectory == fMapFile->GetDirectory()
372 // becomes a TMapRec on its own. TMapFile::Update() then re-streams the
373 // tree (header + baskets) into the 1 GiB mmap on every interval.
374 //
375 // The hazard is that an unbounded TTree's serialized size grows
376 // monotonically and CustomReAlloc2 aborts as soon as it overruns the
377 // mmap. TTree::SetCircular(N) caps the in-memory entry count, which
378 // caps the serialized size. Require a non-zero circular buffer in
379 // mapfile mode; if the user did not pass one, force a safe default
380 // and warn loudly rather than silently dropping all trees.
382 const UInt_t kMapFileCircularDefault = 100;
384 QwWarning << "QwRootFile::ProcessOptions: "
385 << "--enable-mapfile requires a bounded TTree to avoid "
386 "overrunning the " << (kMaxMapFileSize >> 20)
387 << " MiB mmap region. "
388 "Forcing --circular-buffer=" << kMapFileCircularDefault
389 << " (pass --circular-buffer=N to override; pass "
390 "--disable-trees to suppress tree output entirely)."
391 << QwLog::endl;
392 fCircularBufferSize = kMapFileCircularDefault;
393 }
394
395#ifdef HAS_RNTUPLE_SUPPORT
396 // TTree and RNTuple writers share per-channel state (fTreeArrayIndex,
397 // fTreeArrayNumEntries, fDataToSave, b* flags). When both are active,
398 // the second Construct*AndVector() call clobbers the first writer's
399 // layout, and subsequent Fill*Vector() then walks a vector whose entry
400 // types no longer match what was pushed (e.g. SetValue throws
401 // "entry type 'D' cannot store unsigned int value 'block2'").
402 // Until per-writer layout state is added, make the two writers
403 // mutually exclusive: keep RNTuples and silence TTrees.
404 if (fEnableRNTuples) {
406 QwMessage << "QwRootFile::ProcessOptions: "
407 << "--enable-rntuples is set; disabling tree output "
408 "(channels share layout state between TTree and RNTuple "
409 "writers, so the two cannot be produced in the same run)."
410 << QwLog::endl;
411 DisableTree(".*");
412 }
413#endif // HAS_RNTUPLE_SUPPORT
414
415 // Options 'disable-mps' and 'disable-hel' for disabling
416 // helicity window and helicity pattern output
417 if (options.GetValue<bool>("disable-mps-tree")) DisableTree("^evt$");
418 if (options.GetValue<bool>("disable-pair-tree")) DisableTree("^pr$");
419 if (options.GetValue<bool>("disable-hel-tree")) DisableTree("^mul$");
420 if (options.GetValue<bool>("disable-burst-tree")) DisableTree("^burst$");
421 if (options.GetValue<bool>("disable-slow-tree")) DisableTree("^slow$");
422
423 // Options 'num-accepted-events' and 'num-discarded-events' for
424 // prescaling of the tree output
425 fNumMpsEventsToSave = options.GetValue<int>("num-mps-accepted-events");
426 fNumMpsEventsToSkip = options.GetValue<int>("num-mps-discarded-events");
427 fNumHelEventsToSave = options.GetValue<int>("num-mps-accepted-events");
428 fNumHelEventsToSkip = options.GetValue<int>("num-mps-discarded-events");
429
430 // Update interval for the map file
431 fUpdateInterval = options.GetValue<int>("mapfile-update-interval");
432 fCompressionAlgorithm = options.GetValue<int>("compression-algorithm");
433 fCompressionLevel = options.GetValue<int>("compression-level");
434 fRNTupleCompressionAlgorithm = options.GetValue<int>("rntuple-compression-algorithm");
435 fRNTupleCompressionLevel = options.GetValue<int>("rntuple-compression-level");
436 fBasketSize = options.GetValue<int>("basket-size");
437
438 // Autoflush and autosave
439 fAutoFlush = options.GetValue<int>("autoflush");
440 if ((ROOT_VERSION_CODE < ROOT_VERSION(5,26,00)) && fAutoFlush != -30000000){
442 QwWarning << "QwRootFile::ProcessOptions: "
443 << "The 'autoflush' flag is not supported by ROOT version "
444 << ROOT_RELEASE
445 << QwLog::endl;
446 }
447 fAutoSave = options.GetValue<int>("autosave");
448 return;
449}
std::vector< T > GetValueVector(const std::string &key)
Get a list of templated values.
Definition QwOptions.h:249
T GetValue(const std::string &key)
Get a templated value.
Definition QwOptions.h:236
void DisableTree(const TString &regexp)
Add regexp to list of disabled trees names.
void DisableHisto(const TString &regexp)
Add regexp to list of disabled histogram directories.
Int_t fRNTupleCompressionLevel
Int_t fRNTupleCompressionAlgorithm

References DisableHisto(), DisableTree(), QwLog::endl(), fAutoFlush, fAutoSave, fBasketSize, fCircularBufferSize, fCompressionAlgorithm, fCompressionLevel, fEnableMapFile, fNumHelEventsToSave, fNumHelEventsToSkip, fNumMpsEventsToSave, fNumMpsEventsToSkip, fRNTupleCompressionAlgorithm, fRNTupleCompressionLevel, fRootFileDir, fRootFileStem, fUpdateInterval, fUseTemporaryFile, QwOptions::GetValue(), QwOptions::GetValueVector(), kMaxMapFileSize, QwError, QwMessage, and QwWarning.

Referenced by QwRootFile().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ SetDefaultRootFileDir()

static void QwRootFile::SetDefaultRootFileDir ( const std::string & dir)
inlinestatic

Set default ROOT files dir.

Definition at line 864 of file QwRootFile.h.

864 {
866 }

References fDefaultRootFileDir.

◆ SetDefaultRootFileStem()

static void QwRootFile::SetDefaultRootFileStem ( const std::string & stem)
inlinestatic

Set default ROOT file stem.

Definition at line 868 of file QwRootFile.h.

868 {
870 }

References fDefaultRootFileStem.

◆ Update()

void QwRootFile::Update ( )
inline

Definition at line 1047 of file QwRootFile.h.

1047 {
1048 if (fMapFile) {
1049 QwMessage << "TMapFile memory resident size: "
1050 << ((int*)fMapFile->GetBreakval() - (int*)fMapFile->GetBaseAddr()) *
1051 4 / sizeof(int32_t) / 1024 / 1024 << " MiB"
1052 << QwLog::endl;
1053 fMapFile->Update();
1054 }else{
1055 // this option will allow for reading the tree during write
1056 Long64_t nBytes(0);
1057 for (auto iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++)
1058 nBytes += iter->second.front()->AutoSave("SaveSelf");
1059
1060 QwMessage << "TFile saved: "
1061 << nBytes/1000000 << "MB (inaccurate number)" //FIXME this calculation is inaccurate
1062 << QwLog::endl;
1063 }
1064 }

References QwLog::endl(), fMapFile, fTreeByName, and QwMessage.

Referenced by FillHistograms().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Write()

Int_t QwRootFile::Write ( const char * name = 0,
Int_t option = 0,
Int_t bufsize = 0 )
inline

Definition at line 1172 of file QwRootFile.h.

1172 {
1173 Int_t retval = 0;
1174 // TMapFile has no support for Write
1175 if (fRootFile) retval = fRootFile->Write(name, option, bufsize);
1176 return retval;
1177 }

References fRootFile.

Referenced by main().

+ Here is the caller graph for this function:

◆ WriteObject()

template<class T>
Int_t QwRootFile::WriteObject ( const T * obj,
const char * name,
Option_t * option = "",
Int_t bufsize = 0 )
inline

Write any object to the ROOT file (only valid for TFile)

Definition at line 1038 of file QwRootFile.h.

1038 {
1039 Int_t retval = 0;
1040 // TMapFile has no support for WriteObject
1041 if (fRootFile) retval = fRootFile->WriteObject(obj,name,option,bufsize);
1042 return retval;
1043 }

References fRootFile.

Referenced by QwRootFile().

+ Here is the caller graph for this function:

◆ WriteParamFileList()

template<class T>
Int_t QwRootFile::WriteParamFileList ( const TString & name,
T & object )

Definition at line 1656 of file QwRootFile.h.

1657{
1658 Int_t retval = 0;
1659 if (fRootFile) {
1660 TList *param_list = (TList*) fRootFile->FindObjectAny(name);
1661 if (not param_list) {
1662 retval = fRootFile->WriteObject(object.GetParamFileNameList(name), name);
1663 }
1664 }
1665 return retval;
1666}

References fRootFile.

Referenced by main().

+ Here is the caller graph for this function:

Field Documentation

◆ fAutoFlush

Int_t QwRootFile::fAutoFlush
private

Definition at line 1218 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fAutoSave

Int_t QwRootFile::fAutoSave
private

Definition at line 1219 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fBasketSize

Int_t QwRootFile::fBasketSize
private

Definition at line 1217 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fCircularBufferSize

UInt_t QwRootFile::fCircularBufferSize
private

Definition at line 1336 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fCompressionAlgorithm

Int_t QwRootFile::fCompressionAlgorithm
private

Definition at line 1213 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fCompressionLevel

Int_t QwRootFile::fCompressionLevel
private

Definition at line 1214 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fCurrentEvent

UInt_t QwRootFile::fCurrentEvent
private

Definition at line 1337 of file QwRootFile.h.

◆ fDefaultRootFileDir

std::string QwRootFile::fDefaultRootFileDir = "."
staticprivate

Default ROOT files dir.

Definition at line 1192 of file QwRootFile.h.

Referenced by DefineOptions(), and SetDefaultRootFileDir().

◆ fDefaultRootFileStem

std::string QwRootFile::fDefaultRootFileStem = "Qweak_"
staticprivate

Default ROOT file stem.

Definition at line 1197 of file QwRootFile.h.

Referenced by DefineOptions(), and SetDefaultRootFileStem().

◆ fDirsByName

std::map< const std::string, TDirectory* > QwRootFile::fDirsByName
private

Directories.

Definition at line 1312 of file QwRootFile.h.

Referenced by ConstructHistograms(), ConstructObjects(), HasDirByName(), and PrintDirs().

◆ fDirsByType

std::map< const std::string, std::vector<std::string> > QwRootFile::fDirsByType
private

Definition at line 1313 of file QwRootFile.h.

Referenced by ConstructHistograms(), ConstructObjects(), and HasDirByType().

◆ fDisabledHistos

std::vector< TPRegexp > QwRootFile::fDisabledHistos
private

Definition at line 1227 of file QwRootFile.h.

Referenced by DisableHisto(), and IsHistoDisabled().

◆ fDisabledTrees

std::vector< TPRegexp > QwRootFile::fDisabledTrees
private

List of excluded trees.

Definition at line 1226 of file QwRootFile.h.

Referenced by DisableTree(), and IsTreeDisabled().

◆ fEnableMapFile

Bool_t QwRootFile::fEnableMapFile
private

Definition at line 1211 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fMakePermanent

Bool_t QwRootFile::fMakePermanent
private

Definition at line 1202 of file QwRootFile.h.

Referenced by Close(), QwRootFile(), and ~QwRootFile().

◆ fMapFile

TMapFile* QwRootFile::fMapFile
private

◆ fNumHelEventsToSave

UInt_t QwRootFile::fNumHelEventsToSave
private

Definition at line 1335 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumHelEventsToSkip

UInt_t QwRootFile::fNumHelEventsToSkip
private

Definition at line 1334 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumMpsEventsToSave

UInt_t QwRootFile::fNumMpsEventsToSave
private

Definition at line 1333 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumMpsEventsToSkip

UInt_t QwRootFile::fNumMpsEventsToSkip
private

Prescaling of events written to tree.

Definition at line 1332 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fPermanentName

TString QwRootFile::fPermanentName
private

While the file is open, give it a temporary filename. Perhaps change to a permanent name when closing the file.

Definition at line 1201 of file QwRootFile.h.

Referenced by QwRootFile(), and ~QwRootFile().

◆ fRNTupleCompressionAlgorithm

Int_t QwRootFile::fRNTupleCompressionAlgorithm
private

Definition at line 1215 of file QwRootFile.h.

Referenced by ProcessOptions().

◆ fRNTupleCompressionLevel

Int_t QwRootFile::fRNTupleCompressionLevel
private

Definition at line 1216 of file QwRootFile.h.

Referenced by ProcessOptions().

◆ fRootFile

TFile* QwRootFile::fRootFile
private

◆ fRootFileDir

TString QwRootFile::fRootFileDir
private

ROOT files dir.

Definition at line 1190 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fRootFileStem

TString QwRootFile::fRootFileStem
private

ROOT file stem.

Definition at line 1195 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fTreeByAddr

std::map< const void* , std::vector<QwRootTree*> > QwRootFile::fTreeByAddr
private

◆ fTreeByName

std::map< const std::string, std::vector<QwRootTree*> > QwRootFile::fTreeByName
private

◆ fTreeByType

std::map< const std::type_index , std::vector<QwRootTree*> > QwRootFile::fTreeByType
private

Definition at line 1256 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and HasTreeByType().

◆ fUpdateInterval

Int_t QwRootFile::fUpdateInterval
private

Definition at line 1212 of file QwRootFile.h.

Referenced by FillHistograms(), ProcessOptions(), and QwRootFile().

◆ fUseTemporaryFile

Bool_t QwRootFile::fUseTemporaryFile
private

Definition at line 1203 of file QwRootFile.h.

Referenced by ProcessOptions(), QwRootFile(), and ~QwRootFile().

◆ kMaxMapFileSize

const Int_t QwRootFile::kMaxMapFileSize = 0x3fffffff
staticprivate

Definition at line 1341 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ kMaxTreeSize

const Long64_t QwRootFile::kMaxTreeSize = 100000000000LL
staticprivate

Maximum tree size.

Definition at line 1340 of file QwRootFile.h.

Referenced by ConstructTreeBranches().


The documentation for this class was generated from the following files: