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
 
TString fMapFileDir
 
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
 
UInt_t fHistoFillPrescale = 1
 
UInt_t fHistoFillCount = 0
 

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 859 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 // Verify the target directory exists and is writable before asking ROOT
44 // to mmap a file there. On platforms without /dev/shm (e.g. macOS) the
45 // default location is absent; give an actionable message instead of a
46 // cryptic TMapFile failure.
47 if (gSystem->AccessPathName(fMapFileDir, kWritePermission)) {
48 QwError << "Memory-mapped file directory '" << fMapFileDir
49 << "' does not exist or is not writable." << QwLog::endl;
50 QwError << "Set --mapfile-dir to a writable directory (ideally a RAM "
51 "disk). /dev/shm does not exist on macOS; a normal directory "
52 "or a hdiutil-mounted RAM disk works there." << QwLog::endl;
53 return;
54 }
55
56 TString mapfilename = fMapFileDir + "/QwMemMapFile.map";
57
58 fMapFile = TMapFile::Create(mapfilename,"UPDATE", kMaxMapFileSize, "RealTime Producer File");
59
60 if (not fMapFile) {
61 QwError << "Memory-mapped file " << mapfilename
62 << " could not be opened!" << QwLog::endl;
63 return;
64 }
65
66 QwMessage << "================== RealTime Producer Memory Map File =================" << QwLog::endl;
67 QwMessage << "Memory-mapped file: " << mapfilename << QwLog::endl;
68 fMapFile->Print();
69 QwMessage << "======================================================================" << QwLog::endl;
70 } else
71#endif
72 {
73
74 TString rootfilename = fRootFileDir;
75 TString hostname = gSystem -> HostName();
76
77 // Use a probably-unique temporary file name.
78 pid_t pid = getpid();
79
80 fPermanentName = rootfilename
81 + Form("/%s%s.root", fRootFileStem.Data(), run_label.Data());
83 rootfilename += Form("/%s%s.%s.%d.root",
84 fRootFileStem.Data(), run_label.Data(),
85 hostname.Data(), pid);
86 // Delete permanent file if it exists to prevent accumulation across segments
87 if (gSystem->AccessPathName(fPermanentName.Data()) == 0) {
88 QwVerbose << "Removing existing permanent file: " << fPermanentName << QwLog::endl;
89 gSystem->Unlink(fPermanentName.Data());
90 }
91 // CRITICAL: Also delete the temporary file if it exists!
92 // RECREATE mode doesn't properly clear files that contain RNTuples,
93 // so we must manually delete before opening
94 if (gSystem->AccessPathName(rootfilename.Data()) == 0) {
95 QwVerbose << "Removing existing temporary file before RECREATE: " << rootfilename << QwLog::endl;
96 gSystem->Unlink(rootfilename.Data());
97 }
98 } else {
99 rootfilename = fPermanentName;
100 // Delete permanent file if it exists to ensure RECREATE truly starts fresh
101 // This is especially important for RNTuple files where RECREATE doesn't properly clear
102 if (gSystem->AccessPathName(rootfilename.Data()) == 0) {
103 QwMessage << "File exists before RECREATE, deleting: " << rootfilename << QwLog::endl;
104 int unlink_result = gSystem->Unlink(rootfilename.Data());
105 if (unlink_result == 0) {
106 QwMessage << "Successfully deleted file" << QwLog::endl;
107 } else {
108 QwError << "Failed to delete file! Error code: " << unlink_result << QwLog::endl;
109 }
110 } else {
111 QwMessage << "File does not exist before RECREATE: " << rootfilename << QwLog::endl;
112 }
113 }
114 QwMessage << "Opening file with RECREATE mode: " << rootfilename << QwLog::endl;
115 QwMessage << "QwRootFile constructor called for: " << rootfilename << QwLog::endl;
116 // Use TFile::Open instead of `new TFile(...)` so the ROOT plug-in manager
117 // can dispatch remote URLs (e.g. root://host/path) to TNetXNGFile etc.
118 // The TFile(name, opt, title) constructor refuses remote paths and returns
119 // a half-built object, which then segfaults at first use.
120 fRootFile = TFile::Open(rootfilename.Data(), "RECREATE", "myfile1");
121 if (!fRootFile || fRootFile->IsZombie()) {
122 QwError << "ROOT file " << rootfilename
123 << " could not be opened!" << QwLog::endl;
124 delete fRootFile;
125 fRootFile = nullptr;
126 return;
127 } else {
128 QwMessage << "Opened "<< (fUseTemporaryFile?"temporary ":"")
129 <<"rootfile " << rootfilename << QwLog::endl;
130 }
131
132 TString run_condition_name = Form("condition_%s", run_label.Data());
133 TList *run_cond_list = (TList*) fRootFile -> FindObjectAny(run_condition_name);
134 if (not run_cond_list) {
135 QwRunCondition run_condition(
136 gQwOptions.GetArgc(),
137 gQwOptions.GetArgv(),
138 run_condition_name
139 );
140
142 run_condition.Get(),
143 run_condition.GetName()
144 );
145 }
146
147 fRootFile->SetCompressionAlgorithm(fCompressionAlgorithm);
148 fRootFile->SetCompressionLevel(fCompressionLevel);
149 }
150}
#define gQwOptions
Definition QwOptions.h:31
#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
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 fMapFileDir
TString fPermanentName
TMapFile * fMapFile
Map file.
Int_t fUpdateInterval
Bool_t fMakePermanent
Bool_t fEnableMapFile

References QwLog::endl(), fCompressionAlgorithm, fCompressionLevel, fEnableMapFile, fMakePermanent, fMapFile, fMapFileDir, 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 156 of file QwRootFile.cc.

157{
158 // Keep the file on disk if any trees or histograms have been filled.
159 // Also respect any other requests to keep the file around.
161
162 // Close the map file
163 if (fMapFile) {
164 fMapFile->Close();
165 // TMapFiles may not be deleted
166 fMapFile = 0;
167 }
168
169 // Close the ROOT file.
170 // Rename if permanence is requested, remove otherwise
171 if (fRootFile) {
172 TString rootfilename = fRootFile->GetName();
173
174 fRootFile->Close();
175 delete fRootFile;
176 fRootFile = 0;
177
178 int err;
179 const char* action;
181 if (fMakePermanent) {
182 // Delete existing permanent file first to avoid accumulation
183 if (gSystem->AccessPathName(fPermanentName.Data()) == 0) {
184 remove(fPermanentName.Data());
185 }
186 action = " rename ";
187 err = rename( rootfilename.Data(), fPermanentName.Data() );
188 } else {
189 action = " remove ";
190 err = remove( rootfilename.Data() );
191 }
192 // It'd be proper to "extern int errno" and strerror() here,
193 // but that doesn't seem very C++-ish.
194 if (err) {
195 QwWarning << "Couldn't" << action << rootfilename << QwLog::endl;
196 } else {
197 QwMessage << "Was able to" << action << rootfilename << QwLog::endl;
198 QwMessage << "Root file is " << fPermanentName << QwLog::endl;
199 }
200 }
201 }
202
203 // Delete Qweak ROOT trees
204 std::map< const std::string, std::vector<QwRootTree*> >::iterator map_iter;
205 std::vector<QwRootTree*>::iterator vec_iter;
206 for (map_iter = fTreeByName.begin(); map_iter != fTreeByName.end(); map_iter++) {
207 for (vec_iter = map_iter->second.begin(); vec_iter != map_iter->second.end(); vec_iter++) {
208 delete *vec_iter;
209 }
210 }
211}
#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 1176 of file QwRootFile.h.

1176 {
1177 Bool_t status = kTRUE;
1178 if (fMapFile) status &= fMapFile->cd(path);
1179 if (fRootFile) status &= fRootFile->cd(path);
1180 return status;
1181 }

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 1093 of file QwRootFile.h.

1093 {
1094 if (!dir) return;
1095
1096 // First, collect subdirectory names
1097 std::vector<TString> subdirs;
1098 TIter next(dir->GetListOfKeys());
1099 TKey* key;
1100 while ((key = (TKey*)next())) {
1101 if (TString(key->GetClassName()) == "TDirectoryFile") {
1102 subdirs.push_back(key->GetName());
1103 }
1104 }
1105
1106 // Recursively clear subdirectories
1107 for (const auto& name : subdirs) {
1108 TDirectory* sub = dynamic_cast<TDirectory*>(dir->Get(name));
1109 if (sub) ClearInMemoryObjects(sub);
1110 }
1111
1112 // Clear this directory's in-memory object list
1113 // "nodelete" option: remove from list but don't delete the TKey entries
1114 TList* list = dir->GetList();
1115 if (list) {
1116 list->Clear("nodelete");
1117 }
1118 }
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 1121 of file QwRootFile.h.

1121 {
1122
1123 if (fRootFile) {
1124 // Step 1: Write all trees explicitly
1125 for (auto iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
1126 if (!iter->second.empty() && iter->second.front()) {
1127 TTree* tree = iter->second.front()->GetTree();
1128 if (tree && tree->GetEntries() > 0) {
1129 tree->Write();
1130 }
1131 }
1132 }
1133
1134 // Step 2: Write all in-memory objects (histograms, etc.) to disk
1135 // Use kOverwrite to avoid creating duplicate cycles
1136 fRootFile->Write(0, TObject::kOverwrite);
1137
1138 // Check if we should make the file permanent AFTER writing
1139 // This ensures histograms are on disk and detectable by HasAnyFilled()
1141
1142 // Step 3: CRITICAL FIX for RNTuple histogram duplication
1143 // Clear all in-memory objects from the TFile's directory structure.
1144 // This prevents RNTupleWriter::Close() from re-writing histograms,
1145 // which would create duplicate cycles. The histograms are already
1146 // safely written to disk in Step 2.
1147#ifdef HAS_RNTUPLE_SUPPORT
1148 if (!fNTupleByName.empty()) {
1150 }
1151#endif // HAS_RNTUPLE_SUPPORT
1152 }
1153
1154#ifdef HAS_RNTUPLE_SUPPORT
1155 // Step 4: Close all RNTuples
1156 // Now that in-memory histograms are cleared, the RNTupleWriter destructor
1157 // won't create duplicate histogram cycles when it internally writes to TFile
1158 for (auto& pair : fNTupleByName) {
1159 for (auto& ntuple : pair.second) {
1160 if (ntuple) ntuple->Close();
1161 }
1162 }
1163#endif // HAS_RNTUPLE_SUPPORT
1164
1165 // Step 5: Close the file
1166 if (fRootFile) {
1167 fRootFile->Close();
1168 }
1169
1170 // TMapFile::Close() is NOT idempotent: re-closing in ~QwRootFile()
1171 // crashes on the already-detached mmap descriptor.
1172 if (fMapFile) { fMapFile->Close(); fMapFile = 0; }
1173 }

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 1657 of file QwRootFile.h.

1658{
1659 // Return if we do not want this histogram information
1660 if (IsHistoDisabled(name)) return;
1661
1662 // Create the histograms in a directory
1663 if (fRootFile) {
1664 std::string type = typeid(object).name();
1665 fDirsByName[name] =
1666 fRootFile->GetDirectory(("/" + name).c_str()) ?
1667 fRootFile->GetDirectory(("/" + name).c_str()) :
1668 fRootFile->GetDirectory("/")->mkdir(name.c_str());
1669 fDirsByType[type].push_back(name);
1670
1671 object.ConstructHistograms(fDirsByName[name]);
1672 }
1673
1674 // No support for directories in a map file
1675 if (fMapFile) {
1676 QwMessage << "QwRootFile::ConstructHistograms::detectors address "
1677 << &object
1678 << " and its name " << name
1679 << QwLog::endl;
1680
1681 // TMapFile does not support subdirectories: histograms created inside a
1682 // mkdir'd directory are NOT retrievable via TMapFile::Get (readers such as
1683 // panguin get NULL). We must cd() into the map's top-level directory so
1684 // that histograms created by object.ConstructHistograms() attach there and
1685 // are streamed into shared memory by TMapFile::Update(); otherwise only
1686 // empty name stubs (class=NULL, size=0) reach the map.
1687 std::string type = typeid(object).name();
1688 fMapFile->cd();
1689 fDirsByName[name] = fMapFile->GetDirectory();
1690 fDirsByType[type].push_back(name);
1691 // TMapFile has no subdirectories, so every group's histograms share the
1692 // map's single top-level directory. Without a namespace, identically
1693 // named histograms from different groups (evt_histo/mul_histo/burst_histo)
1694 // collide: TDirectoryFile::Append replaces (and orphans) the earlier one,
1695 // producing "Replacing existing TH1 (Potential memory leak)" warnings and
1696 // dropping histograms from the live display. Prefix each group's
1697 // histograms with its directory name so they all coexist in the flat map.
1698 TString prefix = TString(name.c_str()) + "_";
1699 object.ConstructHistograms((TDirectory*)NULL, prefix);
1700 }
1701}
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 1378 of file QwRootFile.h.

1379{
1380 // Return if we do not want this tree information
1381 if (IsTreeDisabled(from)) return;
1382 if (IsTreeDisabled(to)) return;
1383
1384 // If the trees are defined
1385 if (fTreeByName.count(from) > 0 && fTreeByName.count(to) > 0) {
1386
1387 // Construct index from the first tree to the second tree
1388 fTreeByName[from].front()->ConstructIndexTo(fTreeByName[to].front());
1389
1390 // Construct index from the second tree back to the first tree
1391 if (reverse)
1392 fTreeByName[to].front()->ConstructIndexTo(fTreeByName[from].front());
1393 }
1394}
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 1616 of file QwRootFile.h.

1617{
1618 // Create the objects in a directory
1619 if (fRootFile) {
1620 std::string type = typeid(object).name();
1621 fDirsByName[name] =
1622 fRootFile->GetDirectory(("/" + name).c_str()) ?
1623 fRootFile->GetDirectory(("/" + name).c_str()) :
1624 fRootFile->GetDirectory("/")->mkdir(name.c_str());
1625 fDirsByType[type].push_back(name);
1626 object.ConstructObjects(fDirsByName[name]);
1627 }
1628
1629 // No support for directories in a map file
1630 if (fMapFile) {
1631 QwMessage << "QwRootFile::ConstructObjects::detectors address "
1632 << &object
1633 << " and its name " << name
1634 << QwLog::endl;
1635
1636 // TMapFile does not support subdirectories: objects created inside a
1637 // mkdir'd directory are NOT retrievable via TMapFile::Get (readers get
1638 // NULL). We must cd() into the map's top-level directory so that objects
1639 // created by object.ConstructObjects() attach there and are streamed into
1640 // shared memory by TMapFile::Update(); otherwise only empty name stubs
1641 // reach the map.
1642 std::string type = typeid(object).name();
1643 fMapFile->cd();
1644 fDirsByName[name] = fMapFile->GetDirectory();
1645 fDirsByType[type].push_back(name);
1646 object.ConstructObjects();
1647 }
1648}

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 1404 of file QwRootFile.h.

1409{
1410 // Return if we do not want this tree information
1411 if (IsTreeDisabled(name)) return;
1412
1413 // Pointer to new tree
1414 QwRootTree* tree = 0;
1415
1416 // If the tree does not exist yet, create it
1417 if (fTreeByName.count(name) == 0) {
1418
1419 // Go to top level directory
1420
1421 this->cd();
1422
1423 // New tree with name, description, object, prefix
1424 tree = new QwRootTree(name, desc, object, prefix);
1425
1426 // Settings only relevant for new trees
1427 if (name == "evt")
1429 else if (name == "mul")
1431
1432 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
1433 tree->SetAutoFlush(fAutoFlush);
1434 #endif
1435 tree->SetAutoSave(fAutoSave);
1438
1439 if (fCircularBufferSize > 0)
1441
1442 } else {
1443
1444 // New tree based on existing tree
1445 tree = new QwRootTree(fTreeByName[name].front(), object, prefix);
1446 }
1447
1448 // Add the branches to the list of trees by name, object, type
1449 const void* addr = static_cast<const void*>(&object);
1450 const std::type_index type = typeid(object);
1451 fTreeByName[name].push_back(tree);
1452 fTreeByAddr[addr].push_back(tree);
1453 fTreeByType[type].push_back(tree);
1454}
void SetAutoFlush(Long64_t autoflush=30000000)
Set autoflush size.
Definition QwRootFile.h:593
void SetCircular(Long64_t buff=100000)
Definition QwRootFile.h:613
void SetMaxTreeSize(Long64_t maxsize=1900000000)
Set maximum tree size.
Definition QwRootFile.h:587
void SetAutoSave(Long64_t autosave=300000000)
Set autosave size.
Definition QwRootFile.h:601
void SetBasketSize(Int_t basketsize=16000)
Set basket size.
Definition QwRootFile.h:607
void SetPrescaling(UInt_t num_to_save, UInt_t num_to_skip)
Set tree prescaling parameters.
Definition QwRootFile.h:573
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 217 of file QwRootFile.cc.

218{
219 // Define the ROOT files directory
220 options.AddOptions("Default options")
221 ("rootfiles", po::value<std::string>()->default_value(fDefaultRootFileDir),
222 "directory of the output ROOT files");
223
224 // Define the ROOT filename stem
225 options.AddOptions("Default options")
226 ("rootfile-stem", po::value<std::string>()->default_value(fDefaultRootFileStem),
227 "stem of the output ROOT filename");
228
229 // Define the memory map option
230 options.AddOptions()
231 ("enable-mapfile", po::value<bool>()->default_bool_value(false),
232 "enable output to memory-mapped file\n(likely requires circular-buffer too)");
233 options.AddOptions()
234 ("mapfile-dir", po::value<std::string>()->default_value("/dev/shm"),
235 "directory that holds the memory-mapped file (QwMemMapFile.map). Defaults "
236 "to /dev/shm (Linux tmpfs). Set this on platforms without /dev/shm "
237 "(e.g. macOS) to a writable directory, ideally a RAM disk.");
238 options.AddOptions()
239 ("write-temporary-rootfiles", po::value<bool>()->default_bool_value(true),
240 "When writing ROOT files, use the PID to create a temporary filename");
241
242 // Define the histogram and tree options
243 options.AddOptions("ROOT output options")
244 ("disable-tree", po::value<std::vector<std::string>>()->composing(),
245 "disable output to tree regex");
246 options.AddOptions("ROOT output options")
247 ("disable-trees", po::value<bool>()->default_bool_value(false),
248 "disable output to all trees");
249 options.AddOptions("ROOT output options")
250 ("disable-histos", po::value<bool>()->default_bool_value(false),
251 "disable output to all histograms");
252
253 // Define the helicity window versus helicity pattern options
254 options.AddOptions("ROOT output options")
255 ("disable-mps-tree", po::value<bool>()->default_bool_value(false),
256 "disable helicity window output");
257 options.AddOptions("ROOT output options")
258 ("disable-pair-tree", po::value<bool>()->default_bool_value(false),
259 "disable helicity pairs output");
260 options.AddOptions("ROOT output options")
261 ("disable-hel-tree", po::value<bool>()->default_bool_value(false),
262 "disable helicity pattern output");
263 options.AddOptions("ROOT output options")
264 ("disable-burst-tree", po::value<bool>()->default_bool_value(false),
265 "disable burst tree");
266 options.AddOptions("ROOT output options")
267 ("disable-slow-tree", po::value<bool>()->default_bool_value(false),
268 "disable slow control tree");
269 options.AddOptions("ROOT output options")
270 ("disable-redundant-trees", po::value<bool>()->default_bool_value(false),
271 "disable the per-entry trees whose content is already captured by a "
272 "matching histogram directory (evt/mul/burst). Histograms, the "
273 "running-sum trees (evts/muls/bursts), the pair tree (pr) and the slow "
274 "control tree (slow) are kept.");
275
276#ifdef HAS_RNTUPLE_SUPPORT
277 // Define the RNTuple options
278 options.AddOptions("ROOT output options")
279 ("enable-rntuples", po::value<bool>()->default_bool_value(false),
280 "enable RNTuple output");
281#endif // HAS_RNTUPLE_SUPPORT
282
283 // Define the tree output prescaling options
284 options.AddOptions("ROOT output options")
285 ("num-mps-accepted-events", po::value<int>()->default_value(0),
286 "number of accepted consecutive MPS events");
287 options.AddOptions("ROOT output options")
288 ("num-mps-discarded-events", po::value<int>()->default_value(0),
289 "number of discarded consecutive MPS events");
290 options.AddOptions("ROOT output options")
291 ("num-hel-accepted-events", po::value<int>()->default_value(0),
292 "number of accepted consecutive pattern events");
293 options.AddOptions("ROOT output options")
294 ("num-hel-discarded-events", po::value<int>()->default_value(0),
295 "number of discarded consecutive pattern events");
296 options.AddOptions("ROOT output options")
297 ("mapfile-update-interval", po::value<int>()->default_value(-1),
298 "Events between a map file update");
299 options.AddOptions("ROOT output options")
300 ("fill-prescale", po::value<int>()->default_value(1),
301 "Fill trees and histograms only on every Nth processed event (physics is "
302 "still computed every event). Roughly multiplies live (mapfile) throughput "
303 "by N at the cost of fewer accumulated monitoring entries. Default 1 = "
304 "fill every event.");
305
306 // Define the autoflush and autosave option (default values by ROOT)
307 options.AddOptions("ROOT performance options")
308 ("autoflush", po::value<int>()->default_value(0),
309 "TTree autoflush");
310 options.AddOptions("ROOT performance options")
311 ("autosave", po::value<int>()->default_value(300000000),
312 "TTree autosave");
313 options.AddOptions("ROOT performance options")
314 ("basket-size", po::value<int>()->default_value(16000),
315 "TTree basket size");
316 options.AddOptions("ROOT performance options")
317 ("circular-buffer", po::value<int>()->default_value(0),
318 "TTree circular buffer");
319 options.AddOptions("ROOT performance options")
320 ("compression-algorithm", po::value<int>()->default_value(1),
321 "TFile compression algorithm (1=ZLIB, 2=LZMA, 4=LZ4, 5=ZSTD, default=1 ZLIB)");
322 options.AddOptions("ROOT performance options")
323 ("compression-level", po::value<int>()->default_value(1),
324 "TFile compression level (default = 1, no compression = 0)");
325 options.AddOptions("ROOT performance options")
326 ("rntuple-compression-algorithm", po::value<int>()->default_value(4),
327 "RNTuple compression algorithm (1=ZLIB, 2=LZMA, 4=LZ4, 5=ZSTD, default=4 LZ4)");
328 options.AddOptions("ROOT performance options")
329 ("rntuple-compression-level", po::value<int>()->default_value(0),
330 "RNTuple compression level (0-12, default=0 for maximum performance)");
331}
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 1262 of file QwRootFile.h.

1262 {
1263 fDisabledHistos.push_back(regexp);
1264 }
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 1252 of file QwRootFile.h.

1252 {
1253 fDisabledTrees.push_back(regexp);
1254 }
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 927 of file QwRootFile.h.

927 {
928 // Update regularly
929 static Int_t update_count = 0;
930 update_count++;
931 if ((fUpdateInterval > 0) && ( update_count % fUpdateInterval == 0)) Update();
932
933 // Histogram fill prescaling. Physics is processed every event, but the
934 // (relatively expensive) histogram fill is performed only on every Nth
935 // event. This thins the live monitoring output to gain throughput; the
936 // visual refresh rate is unaffected because the displayed histograms
937 // simply accumulate slightly fewer entries.
938 if (fHistoFillPrescale > 1) {
939 if (++fHistoFillCount % fHistoFillPrescale != 0) return;
940 }
941
942 // Debug directory registration
943 std::string type = typeid(object).name();
944 bool hasDir = HasDirByType(object);
945
946 if (! hasDir) return;
947 // Fill histograms
948 object.FillHistograms();
949 }
bool HasDirByType(const T &object)
Is a directory registered for this type.
UInt_t fHistoFillCount
void Update()
UInt_t fHistoFillPrescale

References fHistoFillCount, fHistoFillPrescale, 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 993 of file QwRootFile.h.

993 {
994 if (! HasTreeByName(name)) return 0;
995 else return fTreeByName[name].front()->Fill();
996 }
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 1463 of file QwRootFile.h.

1466{
1467 // If this name has no registered trees
1468 if (! HasTreeByName(name)) return;
1469 // If this type has no registered trees
1470 if (! HasTreeByType(object)) return;
1471
1472 // Get the address of the object
1473 const void* addr = static_cast<const void*>(&object);
1474
1475 // Fill the trees with the correct address
1476 for (size_t tree = 0; tree < fTreeByAddr[addr].size(); tree++) {
1477 if (fTreeByAddr[addr].at(tree)->GetName() == name) {
1478 fTreeByAddr[addr].at(tree)->FillTreeBranches(object);
1479 }
1480 }
1481}
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 1489 of file QwRootFile.h.

1491{
1492 // If this address has no registered trees
1493 if (! HasTreeByAddr(object)) return;
1494
1495 // Get the address of the object
1496 const void* addr = static_cast<const void*>(&object);
1497
1498 // Fill the trees with the correct address
1499 for (size_t tree = 0; tree < fTreeByAddr[addr].size(); tree++) {
1500 fTreeByAddr[addr].at(tree)->FillTreeBranches(object);
1501 }
1502}
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 999 of file QwRootFile.h.

999 {
1000 // Loop over all registered tree names
1001 Int_t retval = 0;
1002 std::map< const std::string, std::vector<QwRootTree*> >::iterator iter;
1003 for (iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
1004 retval += iter->second.front()->Fill();
1005 }
1006 return retval;
1007 }

References fTreeByName.

◆ GetTree()

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

Get the tree with name.

Definition at line 987 of file QwRootFile.h.

987 {
988 if (! HasTreeByName(name)) return 0;
989 else return fTreeByName[name].front()->GetTree();
990 }

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 522 of file QwRootFile.cc.

522 {
523 if (!d) {
524
525 return false;
526 }
527
528 // First check if any in-memory trees have been filled
529 for (auto& pair : fTreeByName) {
530 for (auto& tree : pair.second) {
531 if (tree && tree->GetTree()) {
532 Long64_t entries = tree->GetTree()->GetEntries();
533 if (entries > 0) {
534
535 return true;
536 }
537 }
538 }
539 }
540
541#ifdef HAS_RNTUPLE_SUPPORT
542 // Then check if any RNTuples have been filled
543 for (auto& pair : fNTupleByName) {
544 for (auto& ntuple : pair.second) {
545 if (ntuple && ntuple->fCurrentEvent > 0) {
546
547 return true;
548 }
549 }
550 }
551#endif // HAS_RNTUPLE_SUPPORT
552
553 TList* l = d->GetListOfKeys();
554
555
556 for( int i=0; i < l->GetEntries(); ++i) {
557 const char* name = l->At(i)->GetName();
558 TObject* obj = d->FindObjectAny(name);
559
560
561
562 // Objects which can't be found don't count.
563 if (!obj) {
564
565 continue;
566 }
567
568 // Lists of parameter files, map files, and job conditions don't count.
569 if ( TString(name).Contains("parameter_file") ) {
570
571 continue;
572 }
573 if ( TString(name).Contains("mapfile") ) {
574 continue;
575 }
576 if ( TString(name).Contains("_condition") ) {
577 continue;
578 }
579 // The EPICS tree doesn't count
580 if ( TString(name).Contains("slow") ) {
581 continue;
582 }
583
584 // Recursively check subdirectories.
585 if (obj->IsA()->InheritsFrom( "TDirectory" )) {
586 if (this->HasAnyFilled( (TDirectory*)obj )) return true;
587 }
588
589 if (obj->IsA()->InheritsFrom( "TTree" )) {
590 Long64_t entries = ((TTree*) obj)->GetEntries();
591 if ( entries ) return true;
592 }
593
594 if (obj->IsA()->InheritsFrom( "TH1" )) {
595 Double_t entries = ((TH1*) obj)->GetEntries();
596 if ( entries ) return true;
597 }
598 }
599 return false;
600}

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 519 of file QwRootFile.cc.

519 {
520 return this->HasAnyFilled(fRootFile);
521}

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 1338 of file QwRootFile.h.

1338 {
1339 if (fDirsByName.count(name) == 0) return false;
1340 else return true;
1341 }

References fDirsByName.

◆ HasDirByType()

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

Is a directory registered for this type.

Definition at line 1344 of file QwRootFile.h.

1344 {
1345 std::string type = typeid(object).name();
1346 if (fDirsByType.count(type) == 0) return false;
1347 else return true;
1348 }

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 1305 of file QwRootFile.h.

1305 {
1306 const void* addr = static_cast<const void*>(&object);
1307 if (fTreeByAddr.count(addr) == 0) return false;
1308 else return true;
1309 }

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 1292 of file QwRootFile.h.

1292 {
1293 if (fTreeByName.count(name) == 0) return false;
1294 else return true;
1295 }

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 1298 of file QwRootFile.h.

1298 {
1299 const std::type_index type = typeid(object);
1300 if (fTreeByType.count(type) == 0) return false;
1301 else return true;
1302 }

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 1266 of file QwRootFile.h.

1266 {
1267 for (size_t i = 0; i < fDisabledHistos.size(); i++)
1268 if (fDisabledHistos.at(i).Match(name)) return true;
1269 return false;
1270 }

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 886 of file QwRootFile.h.

886{ return (fMapFile); };

References fMapFile.

◆ IsRootFile()

Bool_t QwRootFile::IsRootFile ( ) const
inline

Is the ROOT file active?

Definition at line 884 of file QwRootFile.h.

884{ 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 1256 of file QwRootFile.h.

1256 {
1257 for (size_t i = 0; i < fDisabledTrees.size(); i++)
1258 if (fDisabledTrees.at(i).Match(name)) return true;
1259 return false;
1260 }

References fDisabledTrees.

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

+ Here is the caller graph for this function:

◆ ls()

void QwRootFile::ls ( )
inline

Definition at line 1085 of file QwRootFile.h.

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

References fMapFile, and fRootFile.

◆ Map()

void QwRootFile::Map ( )
inline

Definition at line 1086 of file QwRootFile.h.

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

References fRootFile.

◆ mkdir()

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

Definition at line 1184 of file QwRootFile.h.

1184 {
1185 // TMapFile has no support for mkdir
1186 if (fRootFile) return fRootFile->mkdir(name, title);
1187 else return 0;
1188 }

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 953 of file QwRootFile.h.

953 {
954 if (IsTreeDisabled(name)) return;
955 this->cd();
956 QwRootTree *tree = 0;
957 if (! HasTreeByName(name)) {
958 tree = new QwRootTree(name,desc);
959 } else {
960 tree = new QwRootTree(fTreeByName[name].front());
961 }
962 fTreeByName[name].push_back(tree);
963 }

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 1084 of file QwRootFile.h.

1084{ 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 1045 of file QwRootFile.h.

1045 {
1046 QwMessage << "Dirs: " << QwLog::endl;
1047 // Loop ove rall registered directories
1048 std::map< const std::string, TDirectory* >::const_iterator iter;
1049 for (iter = fDirsByName.begin(); iter != fDirsByName.end(); iter++) {
1050 QwMessage << iter->first << QwLog::endl;
1051 }
1052 }

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 1030 of file QwRootFile.h.

1030 {
1031 QwMessage << "Trees: " << QwLog::endl;
1032 // Loop over all registered tree names
1033 std::map< const std::string, std::vector<QwRootTree*> >::const_iterator iter;
1034 for (iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++) {
1035 QwMessage << iter->first << ": " << iter->second.size()
1036 << " objects registered" << QwLog::endl;
1037 // Loop over all registered objects for this tree
1038 std::vector<QwRootTree*>::const_iterator tree;
1039 for (tree = iter->second.begin(); tree != iter->second.end(); tree++) {
1040 (*tree)->Print();
1041 }
1042 }
1043 }

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 338 of file QwRootFile.cc.

339{
340 // Option 'rootfiles' to specify ROOT files dir
341 fRootFileDir = TString(options.GetValue<std::string>("rootfiles"));
342 fs::path tmppath(fRootFileDir.Data());
343 if( ! fs::exists(tmppath) || ! fs::is_directory(tmppath)) {
344 QwError << "ERROR: The rootfile directory path, " << fRootFileDir
345 << ", does not exist. Exiting."
346 << QwLog::endl;
347 exit(2);
348 }
349
350 // Option 'root-stem' to specify ROOT file stem
351 fRootFileStem = TString(options.GetValue<std::string>("rootfile-stem"));
352
353 // Option 'mapfile' to enable memory-mapped ROOT file
354 fEnableMapFile = options.GetValue<bool>("enable-mapfile");
355#ifndef QW_ENABLE_MAPFILE
356 if( fEnableMapFile ) {
358 QwWarning << "QwRootFile::ProcessOptions: "
359 << "The 'enable-mapfile' flag is not supported by the ROOT "
360 "version with which this app is built. Disabling it."
361 << QwLog::endl;
362 fEnableMapFile = false;
363 }
364#endif
365 fMapFileDir = TString(options.GetValue<std::string>("mapfile-dir"));
366 while (fMapFileDir.Length() > 1 && fMapFileDir.EndsWith("/"))
367 fMapFileDir.Remove(fMapFileDir.Length() - 1);
368 fUseTemporaryFile = options.GetValue<bool>("write-temporary-rootfiles");
369
370#ifdef HAS_RNTUPLE_SUPPORT
371 // Option 'enable-rntuples' to enable RNTuple output
372 fEnableRNTuples = options.GetValue<bool>("enable-rntuples");
373 // RNTuples require a TFile (RNTupleWriter::Append takes a TDirectory&);
374 // they cannot be hosted by a TMapFile. If both flags are requested,
375 // disable RNTuples and warn loudly so the run does not crash later in
376 // QwRootNTuple::InitializeWriter with a null TFile*.
377 if (fEnableMapFile && fEnableRNTuples) {
379 QwWarning << "QwRootFile::ProcessOptions: "
380 << "RNTuple output is not supported alongside --enable-mapfile "
381 "(TMapFile is not a TDirectory). Disabling RNTuples."
382 << QwLog::endl;
383 fEnableRNTuples = false;
384 }
385#endif // HAS_RNTUPLE_SUPPORT
386
387 // Options 'disable-trees' and 'disable-histos' for disabling
388 // tree and histogram output
389 auto v = options.GetValueVector<std::string>("disable-tree");
390 std::for_each(v.begin(), v.end(), [&](const std::string& s){ this->DisableTree(s); });
391 if (options.GetValue<bool>("disable-trees")) DisableTree(".*");
392 if (options.GetValue<bool>("disable-histos")) DisableHisto(".*");
393
394 // Read --circular-buffer up front so the mapfile-mode logic below can use
395 // it (the original ProcessOptions read it further down, but we now need
396 // it during the mapfile-tree decision).
397 fCircularBufferSize = options.GetValue<int>("circular-buffer");
398
399 // TMapFile-mode tree publishing.
400 //
401 // TTrees can be published into the mapfile: TDirectoryFile::Append
402 // auto-calls TMapFile::Add() when the directory's mother is a TMapFile,
403 // so a TTree created while gDirectory == fMapFile->GetDirectory()
404 // becomes a TMapRec on its own. TMapFile::Update() then re-streams the
405 // tree (header + baskets) into the 1 GiB mmap on every interval.
406 //
407 // The hazard is that an unbounded TTree's serialized size grows
408 // monotonically and CustomReAlloc2 aborts as soon as it overruns the
409 // mmap. TTree::SetCircular(N) caps the in-memory entry count, which
410 // caps the serialized size. Require a non-zero circular buffer in
411 // mapfile mode; if the user did not pass one, force a safe default
412 // and warn loudly rather than silently dropping all trees.
414 const UInt_t kMapFileCircularDefault = 100;
416 QwWarning << "QwRootFile::ProcessOptions: "
417 << "--enable-mapfile requires a bounded TTree to avoid "
418 "overrunning the " << (kMaxMapFileSize >> 20)
419 << " MiB mmap region. "
420 "Forcing --circular-buffer=" << kMapFileCircularDefault
421 << " (pass --circular-buffer=N to override; pass "
422 "--disable-trees to suppress tree output entirely)."
423 << QwLog::endl;
424 fCircularBufferSize = kMapFileCircularDefault;
425 }
426
427#ifdef HAS_RNTUPLE_SUPPORT
428 // TTree and RNTuple writers share per-channel state (fTreeArrayIndex,
429 // fTreeArrayNumEntries, fDataToSave, b* flags). When both are active,
430 // the second Construct*AndVector() call clobbers the first writer's
431 // layout, and subsequent Fill*Vector() then walks a vector whose entry
432 // types no longer match what was pushed (e.g. SetValue throws
433 // "entry type 'D' cannot store unsigned int value 'block2'").
434 // Until per-writer layout state is added, make the two writers
435 // mutually exclusive: keep RNTuples and silence TTrees.
436 if (fEnableRNTuples) {
438 QwMessage << "QwRootFile::ProcessOptions: "
439 << "--enable-rntuples is set; disabling tree output "
440 "(channels share layout state between TTree and RNTuple "
441 "writers, so the two cannot be produced in the same run)."
442 << QwLog::endl;
443 DisableTree(".*");
444 }
445#endif // HAS_RNTUPLE_SUPPORT
446
447 // Options 'disable-mps' and 'disable-hel' for disabling
448 // helicity window and helicity pattern output
449 if (options.GetValue<bool>("disable-mps-tree")) DisableTree("^evt$");
450 if (options.GetValue<bool>("disable-pair-tree")) DisableTree("^pr$");
451 if (options.GetValue<bool>("disable-hel-tree")) DisableTree("^mul$");
452 if (options.GetValue<bool>("disable-burst-tree")) DisableTree("^burst$");
453 if (options.GetValue<bool>("disable-slow-tree")) DisableTree("^slow$");
454
455 // Option 'disable-redundant-trees' disables the per-entry trees that are
456 // fully captured by their matching histogram directories
457 // (evt->evt_histo, mul->mul_histo, burst->burst_histo). The running-sum
458 // trees (evts/muls/bursts) hold the unbinned moments, and the pair (pr)
459 // and slow (EPICS) trees have no histogram equivalent, so they are left
460 // untouched.
461 if (options.GetValue<bool>("disable-redundant-trees")) {
462 DisableTree("^evt$");
463 DisableTree("^mul$");
464 DisableTree("^burst$");
465 }
466
467 // Options 'num-accepted-events' and 'num-discarded-events' for
468 // prescaling of the tree output
469 fNumMpsEventsToSave = options.GetValue<int>("num-mps-accepted-events");
470 fNumMpsEventsToSkip = options.GetValue<int>("num-mps-discarded-events");
471 fNumHelEventsToSave = options.GetValue<int>("num-mps-accepted-events");
472 fNumHelEventsToSkip = options.GetValue<int>("num-mps-discarded-events");
473
474 // Live-output fill prescale. Filling trees and histograms is a sizeable
475 // fraction of the per-event cost, so thinning it to 1-in-N raises throughput
476 // (e.g. for live mapfile monitoring) while physics is still processed every
477 // event. The histogram side is gated in FillHistograms() via
478 // fHistoFillPrescale; the tree side reuses the existing per-tree prescale.
479 // If the user explicitly set a tree prescale we leave it untouched.
480 int fillPrescale = options.GetValue<int>("fill-prescale");
481 if (fillPrescale < 1) fillPrescale = 1;
482 fHistoFillPrescale = fillPrescale;
483 if (fillPrescale > 1) {
484 if (fNumMpsEventsToSave == 0 && fNumMpsEventsToSkip == 0) {
486 fNumMpsEventsToSkip = fillPrescale - 1;
487 }
488 if (fNumHelEventsToSave == 0 && fNumHelEventsToSkip == 0) {
490 fNumHelEventsToSkip = fillPrescale - 1;
491 }
492 }
493
494 // Update interval for the map file
495 fUpdateInterval = options.GetValue<int>("mapfile-update-interval");
496 fCompressionAlgorithm = options.GetValue<int>("compression-algorithm");
497 fCompressionLevel = options.GetValue<int>("compression-level");
498 fRNTupleCompressionAlgorithm = options.GetValue<int>("rntuple-compression-algorithm");
499 fRNTupleCompressionLevel = options.GetValue<int>("rntuple-compression-level");
500 fBasketSize = options.GetValue<int>("basket-size");
501
502 // Autoflush and autosave
503 fAutoFlush = options.GetValue<int>("autoflush");
504 if ((ROOT_VERSION_CODE < ROOT_VERSION(5,26,00)) && fAutoFlush != -30000000){
506 QwWarning << "QwRootFile::ProcessOptions: "
507 << "The 'autoflush' flag is not supported by ROOT version "
508 << ROOT_RELEASE
509 << QwLog::endl;
510 }
511 fAutoSave = options.GetValue<int>("autosave");
512 return;
513}
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, fHistoFillPrescale, fMapFileDir, 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 874 of file QwRootFile.h.

874 {
876 }

References fDefaultRootFileDir.

◆ SetDefaultRootFileStem()

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

Set default ROOT file stem.

Definition at line 878 of file QwRootFile.h.

878 {
880 }

References fDefaultRootFileStem.

◆ Update()

void QwRootFile::Update ( )
inline

Definition at line 1066 of file QwRootFile.h.

1066 {
1067 if (fMapFile) {
1068 QwMessage << "TMapFile memory resident size: "
1069 << ((int*)fMapFile->GetBreakval() - (int*)fMapFile->GetBaseAddr()) *
1070 4 / sizeof(int32_t) / 1024 / 1024 << " MiB"
1071 << QwLog::endl;
1072 fMapFile->Update();
1073 }else{
1074 // this option will allow for reading the tree during write
1075 Long64_t nBytes(0);
1076 for (auto iter = fTreeByName.begin(); iter != fTreeByName.end(); iter++)
1077 nBytes += iter->second.front()->AutoSave("SaveSelf");
1078
1079 QwMessage << "TFile saved: "
1080 << nBytes/1000000 << "MB (inaccurate number)" //FIXME this calculation is inaccurate
1081 << QwLog::endl;
1082 }
1083 }

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 1191 of file QwRootFile.h.

1191 {
1192 Int_t retval = 0;
1193 // TMapFile has no support for Write
1194 if (fRootFile) retval = fRootFile->Write(name, option, bufsize);
1195 return retval;
1196 }

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 1057 of file QwRootFile.h.

1057 {
1058 Int_t retval = 0;
1059 // TMapFile has no support for WriteObject
1060 if (fRootFile) retval = fRootFile->WriteObject(obj,name,option,bufsize);
1061 return retval;
1062 }

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 1705 of file QwRootFile.h.

1706{
1707 Int_t retval = 0;
1708 if (fRootFile) {
1709 TList *param_list = (TList*) fRootFile->FindObjectAny(name);
1710 if (not param_list) {
1711 retval = fRootFile->WriteObject(object.GetParamFileNameList(name), name);
1712 }
1713 }
1714 return retval;
1715}

References fRootFile.

Referenced by main().

+ Here is the caller graph for this function:

Field Documentation

◆ fAutoFlush

Int_t QwRootFile::fAutoFlush
private

Definition at line 1240 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fAutoSave

Int_t QwRootFile::fAutoSave
private

Definition at line 1241 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fBasketSize

Int_t QwRootFile::fBasketSize
private

Definition at line 1239 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fCircularBufferSize

UInt_t QwRootFile::fCircularBufferSize
private

Definition at line 1358 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fCompressionAlgorithm

Int_t QwRootFile::fCompressionAlgorithm
private

Definition at line 1235 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fCompressionLevel

Int_t QwRootFile::fCompressionLevel
private

Definition at line 1236 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fCurrentEvent

UInt_t QwRootFile::fCurrentEvent
private

Definition at line 1359 of file QwRootFile.h.

◆ fDefaultRootFileDir

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

Default ROOT files dir.

Definition at line 1211 of file QwRootFile.h.

Referenced by DefineOptions(), and SetDefaultRootFileDir().

◆ fDefaultRootFileStem

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

Default ROOT file stem.

Definition at line 1216 of file QwRootFile.h.

Referenced by DefineOptions(), and SetDefaultRootFileStem().

◆ fDirsByName

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

Directories.

Definition at line 1334 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 1335 of file QwRootFile.h.

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

◆ fDisabledHistos

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

Definition at line 1249 of file QwRootFile.h.

Referenced by DisableHisto(), and IsHistoDisabled().

◆ fDisabledTrees

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

List of excluded trees.

Definition at line 1248 of file QwRootFile.h.

Referenced by DisableTree(), and IsTreeDisabled().

◆ fEnableMapFile

Bool_t QwRootFile::fEnableMapFile
private

Definition at line 1230 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fHistoFillCount

UInt_t QwRootFile::fHistoFillCount = 0
private

Definition at line 1365 of file QwRootFile.h.

Referenced by FillHistograms().

◆ fHistoFillPrescale

UInt_t QwRootFile::fHistoFillPrescale = 1
private

Live-output fill prescale: fill histograms (and, via the per-tree prescale, the trees) only on every Nth processed event. Default 1 fills on every event. Used to raise throughput in live mapfile mode.

Definition at line 1364 of file QwRootFile.h.

Referenced by FillHistograms(), and ProcessOptions().

◆ fMakePermanent

Bool_t QwRootFile::fMakePermanent
private

Definition at line 1221 of file QwRootFile.h.

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

◆ fMapFile

TMapFile* QwRootFile::fMapFile
private

◆ fMapFileDir

TString QwRootFile::fMapFileDir
private

Directory that holds the memory-mapped file (default "/dev/shm" on Linux; override with –mapfile-dir on platforms without /dev/shm, e.g. macOS).

Definition at line 1233 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fNumHelEventsToSave

UInt_t QwRootFile::fNumHelEventsToSave
private

Definition at line 1357 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumHelEventsToSkip

UInt_t QwRootFile::fNumHelEventsToSkip
private

Definition at line 1356 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumMpsEventsToSave

UInt_t QwRootFile::fNumMpsEventsToSave
private

Definition at line 1355 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and ProcessOptions().

◆ fNumMpsEventsToSkip

UInt_t QwRootFile::fNumMpsEventsToSkip
private

Prescaling of events written to tree.

Definition at line 1354 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 1220 of file QwRootFile.h.

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

◆ fRNTupleCompressionAlgorithm

Int_t QwRootFile::fRNTupleCompressionAlgorithm
private

Definition at line 1237 of file QwRootFile.h.

Referenced by ProcessOptions().

◆ fRNTupleCompressionLevel

Int_t QwRootFile::fRNTupleCompressionLevel
private

Definition at line 1238 of file QwRootFile.h.

Referenced by ProcessOptions().

◆ fRootFile

TFile* QwRootFile::fRootFile
private

◆ fRootFileDir

TString QwRootFile::fRootFileDir
private

ROOT files dir.

Definition at line 1209 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ fRootFileStem

TString QwRootFile::fRootFileStem
private

ROOT file stem.

Definition at line 1214 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 1278 of file QwRootFile.h.

Referenced by ConstructTreeBranches(), and HasTreeByType().

◆ fUpdateInterval

Int_t QwRootFile::fUpdateInterval
private

Definition at line 1234 of file QwRootFile.h.

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

◆ fUseTemporaryFile

Bool_t QwRootFile::fUseTemporaryFile
private

Definition at line 1222 of file QwRootFile.h.

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

◆ kMaxMapFileSize

const Int_t QwRootFile::kMaxMapFileSize = 0x3fffffff
staticprivate

Definition at line 1369 of file QwRootFile.h.

Referenced by ProcessOptions(), and QwRootFile().

◆ kMaxTreeSize

const Long64_t QwRootFile::kMaxTreeSize = 100000000000LL
staticprivate

Maximum tree size.

Definition at line 1368 of file QwRootFile.h.

Referenced by ConstructTreeBranches().


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