JAPAn
Just Another Parity Analyzer
Loading...
Searching...
No Matches
QwRootFile.cc
Go to the documentation of this file.
1/*!
2 * \file QwRootFile.cc
3 * \brief Implementation for ROOT file and tree management wrapper classes
4 */
5
6#include "QwRootFile.h"
7#include "QwRunCondition.h"
8#include "TH1.h"
9
10#include <unistd.h>
11#include <cstdio>
12
13#include <filesystem>
14namespace fs = std::filesystem;
15
16std::string QwRootFile::fDefaultRootFileDir = ".";
17std::string QwRootFile::fDefaultRootFileStem = "Qweak_";
18
19const Long64_t QwRootFile::kMaxTreeSize = 100000000000LL;
20const Int_t QwRootFile::kMaxMapFileSize = 0x3fffffff; // 1 GiB
21
22const TString QwRootTree::kUnitsName = "ppm/D:ppb/D:um/D:mm/D:mV_uA/D:V_uA/D";
23Double_t QwRootTree::kUnitsValue[] = { 1e-6, 1e-9, 1e-3, 1 , 1e-3, 1};
24
25/**
26 * Constructor with relative filename
27 */
28QwRootFile::QwRootFile(const TString& run_label)
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}
139
140
141/**
142 * Destructor
143 */
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}
200
201/**
202 * Defines configuration options using QwOptions functionality.
203 * @param options Options object
204 */
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}
303
304
305/**
306 * Parse the configuration options and store in class fields
307 * @param options Options object
308 */
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}
450
451/**
452 * Determine whether the rootfile object has any non-empty trees or
453 * histograms.
454 */
456 return this->HasAnyFilled(fRootFile);
457}
458Bool_t QwRootFile::HasAnyFilled(TDirectory* d) {
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}
#define QwVerbose
Predefined log drain for verbose messages.
Definition QwLog.h:54
#define QwError
Predefined log drain for errors.
Definition QwLog.h:39
#define QwWarning
Predefined log drain for warnings.
Definition QwLog.h:44
#define QwMessage
Predefined log drain for regular messages.
Definition QwLog.h:49
ROOT file and tree management wrapper classes.
#define gQwOptions
Definition QwOptions.h:31
Run condition management and metadata.
static std::ostream & endl(std::ostream &)
End of the line.
Definition QwLog.cc:297
Command-line and configuration file options processor.
Definition QwOptions.h:141
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
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 const TString kUnitsName
Definition QwRootFile.h:422
static Double_t kUnitsValue[]
Definition QwRootFile.h:23
Int_t fBasketSize
TString fRootFileStem
ROOT file stem.
TFile * fRootFile
ROOT file.
virtual ~QwRootFile()
Destructor.
TString fRootFileDir
ROOT files dir.
void DisableTree(const TString &regexp)
Add regexp to list of disabled trees names.
Int_t fCompressionAlgorithm
Bool_t HasAnyFilled(void)
Search for non-empty trees or histograms in the file.
static std::string fDefaultRootFileDir
Default ROOT files dir.
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.
UInt_t fNumHelEventsToSkip
Int_t fAutoSave
std::map< const std::string, std::vector< QwRootTree * > > fTreeByName
Tree names, addresses, and types.
Int_t fCompressionLevel
void DisableHisto(const TString &regexp)
Add regexp to list of disabled histogram directories.
Bool_t fUseTemporaryFile
UInt_t fNumMpsEventsToSave
static std::string fDefaultRootFileStem
Default ROOT file stem.
TString fPermanentName
static void DefineOptions(QwOptions &options)
Define the configuration options.
UInt_t fNumHelEventsToSave
Int_t fAutoFlush
TMapFile * fMapFile
Map file.
Int_t fUpdateInterval
QwRootFile()
Private default constructor.
UInt_t fCircularBufferSize
static const Long64_t kMaxTreeSize
Maximum tree size.
Bool_t fMakePermanent
Int_t fRNTupleCompressionLevel
UInt_t fNumMpsEventsToSkip
Prescaling of events written to tree.
Bool_t fEnableMapFile
Int_t fRNTupleCompressionAlgorithm
Run condition and quality management.