16#include <unordered_map>
29#ifdef HAS_RNTUPLE_SUPPORT
30#include "ROOT/RNTuple.hxx"
31#include "ROOT/RNTupleModel.hxx"
32#include "ROOT/RField.hxx"
33#include "ROOT/RNTupleWriter.hxx"
42#define BRANCH_VECTOR_MAX_SIZE 25000
68 m_buffer.reserve(
sizeof(
double)*count);
84 template <
typename T = u
int8_t>
89 template <
typename T = u
int8_t>
97 return *
reinterpret_cast<T*
>(
m_buffer.data() + entry.offset);
100 template <
typename T>
103 return *
reinterpret_cast<const T*
>(
m_buffer.data() + entry.offset);
110 if (entry.type !=
'D') {
111 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store double value '" + entry.name +
"'");
118 if (entry.type !=
'F') {
119 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store float value '" + entry.name +
"'");
126 if (entry.type !=
'I') {
127 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store int value '" + entry.name +
"'");
134 if (entry.type !=
'L') {
135 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store long long value '" + entry.name +
"'");
142 if (entry.type !=
'S') {
143 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store short value '" + entry.name +
"'");
151 if (entry.type !=
's') {
152 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store short value '" + entry.name +
"'");
159 if (entry.type !=
'i') {
160 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store unsigned int value '" + entry.name +
"'");
167 if (entry.type !=
'l') {
168 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store long long value '" + entry.name +
"'");
177 template <
typename T>
180 throw std::out_of_range(
"QwRootTreeBranchVector::back() called on empty container");
182 const auto& last_entry =
m_entries.back();
183 return *
reinterpret_cast<T*
>(
m_buffer.data() + last_entry.offset);
186 template <
typename T>
189 throw std::out_of_range(
"QwRootTreeBranchVector::back() called on empty container");
191 const auto& last_entry =
m_entries.back();
192 return *
reinterpret_cast<const T*
>(
m_buffer.data() + last_entry.offset);
195 void push_back(
const std::string& name,
const char type =
'D') {
200 throw std::out_of_range(
"QwRootTreeBranchVector::push_back() requires buffer resize beyond reserved capacity");
206 Entry entry{name, offset, entry_size, type};
209 const std::size_t required = offset + entry_size;
210 if (required >
m_buffer.capacity()) {
211 throw std::out_of_range(
"QwRootTreeBranchVector::push_back() requires buffer resize beyond reserved capacity");
219 void push_back(
const TString& name,
const char type =
'D') {
220 push_back(std::string(name.Data()), type);
224 void push_back(
const char* name,
const char type =
'D') {
229 static const std::string separator =
":";
230 std::ostringstream stream;
237 stream << entry.name <<
"/" << entry.type;
244 std::ostringstream stream;
245 stream <<
"QwRootTreeBranchVector: " <<
m_entries.size() <<
" entries, "
247 size_t end_offset = (end_index == 0 || end_index >
m_entries.size()) ?
250 stream <<
"QwRootTreeBranchVector: buffer at 0x" << std::hex << (
void*) &
m_buffer[0] <<
'\n';
251 stream <<
"QwRootTreeBranchVector: entries at 0x" << std::hex << (
void*) &
m_entries[0] <<
'\n';
252 for (
size_t offset =
m_entries[start_index].offset; offset < end_offset; offset += 4) {
254 <<
" [" << offset <<
"] "
256 <<
" offset=0x" << offset
257 <<
" (0x" << std::setw(4) << std::setfill(
'0')
258 << offset -
m_entries[start_index].offset <<
")"
261 for (std::size_t
byte = 0;
byte < 4; ++byte) {
262 stream << std::hex << std::setw(2) << std::setfill(
'0')
263 <<
static_cast<unsigned int>(
m_buffer[offset + byte])
268 end_index = (end_index == 0 || end_index >
m_entries.size()) ?
271 for (
size_type index = start_index; index < end_index; ++index) {
274 <<
" [" << index <<
"] "
276 <<
" offset=0x" << entry.offset
277 <<
" (0x" << std::setw(4) << std::setfill(
'0')
278 << entry.offset -
m_entries[start_index].offset <<
")"
279 <<
" size=0x" << entry.size
282 for (std::size_t
byte =
GetTypeSize(entry.type);
byte > 0; --
byte) {
283 stream << std::hex << std::setw(2) << std::setfill(
'0')
284 <<
static_cast<unsigned int>((
m_buffer.data() + entry.offset)[
byte - 1]);
287 <<
" name=" << entry.name <<
"/" << entry.type
298 return sizeof(double);
300 return sizeof(float);
302 return sizeof(
long long);
304 return sizeof(
unsigned long long);
308 return sizeof(
unsigned int);
310 return sizeof(short);
312 return sizeof(
unsigned short);
314 throw std::invalid_argument(
"Unsupported branch type code: " + std::string(1, type));
319 const std::size_t alignment = 4u;
320 return (offset + (alignment - 1u)) & ~(alignment - 1u);
327 switch (entry.
type) {
349 template <
typename T>
351 std::ostringstream stream;
372 QwRootTree(
const std::string& name,
const std::string& desc,
const std::string& prefix =
"")
389 QwRootTree(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"")
431 fTree->SetDirectory(gDirectory);
439 std::string name =
"units";
445 std::string name =
"previous_entry_in_" + to->
fName;
455 TString prefix = Form(
"%s",
fPrefix.c_str());
456 object.ConstructBranchAndVector(
fTree, prefix,
fVector);
459 fType =
typeid(object).name();
463 QwError <<
"The branch vector is too large: " <<
fVector.size() <<
" leaves! "
476 if (
typeid(
object).name() ==
fType) {
478 object.FillTreeVector(
fVector);
480 QwError <<
"Attempting to fill tree vector for type " <<
fType <<
" with "
481 <<
"object of type " <<
typeid(object).name() <<
QwLog::endl;
487 return fTree->AutoSave(option);
502 Int_t retval =
fTree->Fill();
583 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
597 if (
fTree)
fTree->SetBasketSize(
"*",basketsize);
606#ifdef HAS_RNTUPLE_SUPPORT
620 QwRootNTuple(
const std::string& name,
const std::string& desc,
const std::string& prefix =
"")
621 : fName(name), fDesc(desc), fPrefix(prefix), fType(
"type undefined"),
622 fCurrentEvent(0), fNumEventsCycle(0), fNumEventsToSave(0), fNumEventsToSkip(0) {
624 fModel = ROOT::RNTupleModel::Create();
629 QwRootNTuple(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"")
630 : fName(name), fDesc(desc), fPrefix(prefix), fType(
"type undefined"),
631 fCurrentEvent(0), fNumEventsCycle(0), fNumEventsToSave(0), fNumEventsToSkip(0) {
633 fModel = ROOT::RNTupleModel::Create();
636 ConstructFieldsAndVector(
object);
640 virtual ~QwRootNTuple() {
657 void ConstructFieldsAndVector(T&
object) {
662 TString prefix = Form(
"%s", fPrefix.c_str());
663 object.ConstructNTupleAndVector(fModel, prefix, fVector, fFieldPtrs);
666 fType =
typeid(object).name();
670 QwError <<
"The field vector is too large: " << fVector.size() <<
" fields! "
677 fVector.shrink_to_fit();
683 void InitializeWriter(TFile* file) {
690 if (fVector.empty()) {
698 fWriter = ROOT::RNTupleWriter::Append(std::move(fModel), fName, *file);
702 }
catch (
const std::exception& e) {
703 QwError <<
"Failed to create RNTuple writer for '" << fName <<
"': " << e.what() <<
QwLog::endl;
709 void FillNTupleFields(
const T&
object) {
710 if (
typeid(
object).name() == fType) {
712 object.FillNTupleVector(fVector);
716 for (
size_t i = 0; i < fVector.size() && i < fFieldPtrs.size(); ++i) {
718 *(fFieldPtrs[i]) = fVector[i];
728 if (fNumEventsCycle > 0) {
729 fCurrentEvent %= fNumEventsCycle;
735 QwError <<
"Attempting to fill RNTuple vector for type " << fType <<
" with "
736 <<
"object of type " <<
typeid(object).name() <<
QwLog::endl;
748 const std::string& GetName()
const {
return fName; }
750 const std::string& GetDesc()
const {
return fDesc; }
752 const std::string& GetPrefix()
const {
return fPrefix; }
754 std::string GetType()
const {
return fType; }
757 void SetPrescaling(UInt_t num_to_save, UInt_t num_to_skip) {
758 fNumEventsToSave = num_to_save;
759 fNumEventsToSkip = num_to_skip;
760 fNumEventsCycle = fNumEventsToSave + fNumEventsToSkip;
765 QwMessage << GetName() <<
", " << GetType();
767 QwMessage <<
" (prefix " << GetPrefix() <<
")";
774 std::unique_ptr<ROOT::RNTupleModel> fModel;
775 std::unique_ptr<ROOT::RNTupleWriter> fWriter;
778 std::vector<Double_t> fVector;
779 std::vector<std::shared_ptr<Double_t>> fFieldPtrs;
782 const std::string fName;
783 const std::string fDesc;
784 const std::string fPrefix;
790 UInt_t fCurrentEvent;
791 UInt_t fNumEventsCycle;
792 UInt_t fNumEventsToSave;
793 UInt_t fNumEventsToSkip;
795 friend class QwRootFile;
857 void ConstructIndices(
const std::string& from,
const std::string& to,
bool reverse =
true);
861 void ConstructTreeBranches(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"");
869#ifdef HAS_RNTUPLE_SUPPORT
872 void ConstructNTupleFields(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"");
875 void FillNTupleFields(
const std::string& name,
const T&
object);
878 void FillNTupleFields(
const T&
object);
897 static Int_t update_count = 0;
902 std::string type =
typeid(object).name();
905 if (! hasDir)
return;
907 object.FillHistograms();
912 void NewTree(
const std::string& name,
const std::string& desc) {
924#ifdef HAS_RNTUPLE_SUPPORT
926 void NewNTuple(
const std::string& name,
const std::string& desc) {
928 QwRootNTuple *ntuple = 0;
929 if (! HasNTupleByName(name)) {
930 ntuple =
new QwRootNTuple(name, desc);
938 fNTupleByName[name].push_back(ntuple);
958 std::map< const std::string, std::vector<QwRootTree*> >::iterator iter;
960 retval += iter->second.front()->Fill();
965#ifdef HAS_RNTUPLE_SUPPORT
967 void FillNTuple(
const std::string& name) {
968 if (HasNTupleByName(name)) {
969 fNTupleByName[name].front()->Fill();
974#ifdef HAS_RNTUPLE_SUPPORT
978 std::map< const std::string, std::vector<QwRootNTuple*> >::iterator iter;
979 for (iter = fNTupleByName.begin(); iter != fNTupleByName.end(); iter++) {
980 iter->second.front()->Fill();
989 std::map< const std::string, std::vector<QwRootTree*> >::const_iterator iter;
991 QwMessage << iter->first <<
": " << iter->second.size()
994 std::vector<QwRootTree*>::const_iterator tree;
995 for (tree = iter->second.begin(); tree != iter->second.end(); tree++) {
1004 std::map< const std::string, TDirectory* >::const_iterator iter;
1012 template <
class T >
1013 Int_t
WriteObject(
const T* obj,
const char* name, Option_t* option =
"", Int_t bufsize = 0) {
1024 QwMessage <<
"TMapFile memory resident size: "
1026 4 /
sizeof(int32_t) / 1024 / 1024 <<
" MiB"
1033 nBytes += iter->second.front()->AutoSave(
"SaveSelf");
1036 << nBytes/1000000 <<
"MB (inaccurate number)"
1049#ifdef HAS_RNTUPLE_SUPPORT
1051 for (
auto& pair : fNTupleByName) {
1052 for (
auto& ntuple : pair.second) {
1053 if (ntuple) ntuple->Close();
1062 if (!iter->second.empty() && iter->second.front()) {
1063 TTree* tree = iter->second.front()->GetTree();
1064 if (tree && tree->GetEntries() > 0) {
1074 TString rootfilename =
fRootFile->GetName();
1086 Bool_t
cd(
const char* path = 0) {
1087 Bool_t status = kTRUE;
1094 TDirectory*
mkdir(
const char* name,
const char* title =
"") {
1101 Int_t
Write(
const char* name = 0, Int_t option = 0, Int_t bufsize = 0) {
1183 std::map< const std::type_index , std::vector<QwRootTree*> >
fTreeByType;
1186#ifdef HAS_RNTUPLE_SUPPORT
1188 std::map< const std::string, std::vector<QwRootNTuple*> > fNTupleByName;
1189 std::map< const void* , std::vector<QwRootNTuple*> > fNTupleByAddr;
1190 std::map< const std::type_index , std::vector<QwRootNTuple*> > fNTupleByType;
1193 Bool_t fEnableRNTuples;
1202 template <
class T >
1204 const std::type_index type =
typeid(object);
1209 template <
class T >
1211 const void* addr =
static_cast<const void*
>(&object);
1216#ifdef HAS_RNTUPLE_SUPPORT
1218 bool HasNTupleByName(
const std::string& name) {
1219 if (fNTupleByName.count(name) == 0)
return false;
1223 template <
class T >
1224 bool HasNTupleByType(
const T&
object) {
1225 const std::type_index type =
typeid(object);
1226 if (fNTupleByType.count(type) == 0)
return false;
1230 template <
class T >
1231 bool HasNTupleByAddr(
const T&
object) {
1232 const void* addr =
static_cast<const void*
>(&object);
1233 if (fNTupleByAddr.count(addr) == 0)
return false;
1248 template <
class T >
1250 std::string type =
typeid(object).name();
1304 const std::string& name,
1305 const std::string& desc,
1307 const std::string& prefix)
1323 tree =
new QwRootTree(name, desc,
object, prefix);
1328 else if (name ==
"mul")
1331 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
1348 const void* addr =
static_cast<const void*
>(&object);
1349 const std::type_index type =
typeid(object);
1363 const std::string& name,
1372 const void* addr =
static_cast<const void*
>(&object);
1375 for (
size_t tree = 0; tree <
fTreeByAddr[addr].size(); tree++) {
1376 if (
fTreeByAddr[addr].at(tree)->GetName() == name) {
1377 fTreeByAddr[addr].at(tree)->FillTreeBranches(
object);
1395 const void* addr =
static_cast<const void*
>(&object);
1398 for (
size_t tree = 0; tree <
fTreeByAddr[addr].size(); tree++) {
1399 fTreeByAddr[addr].at(tree)->FillTreeBranches(
object);
1404#ifdef HAS_RNTUPLE_SUPPORT
1413void QwRootFile::ConstructNTupleFields(
1414 const std::string& name,
1415 const std::string& desc,
1417 const std::string& prefix)
1420 if (!fEnableRNTuples)
return;
1423 QwRootNTuple* ntuple = 0;
1426 if (fNTupleByName.count(name) == 0) {
1429 ntuple =
new QwRootNTuple(name, desc,
object, prefix);
1437 else if (name ==
"mul")
1448 const void* addr =
static_cast<const void*
>(&object);
1449 const std::type_index type =
typeid(object);
1450 fNTupleByName[name].push_back(ntuple);
1451 fNTupleByAddr[addr].push_back(ntuple);
1452 fNTupleByType[type].push_back(ntuple);
1462void QwRootFile::FillNTupleFields(
1463 const std::string& name,
1467 if (! HasNTupleByName(name))
return;
1469 if (! HasNTupleByType(
object))
return;
1472 const void* addr =
static_cast<const void*
>(&object);
1475 for (
size_t ntuple = 0; ntuple < fNTupleByAddr[addr].size(); ntuple++) {
1476 if (fNTupleByAddr[addr].at(ntuple)->GetName() == name) {
1477 fNTupleByAddr[addr].at(ntuple)->FillNTupleFields(
object);
1488void QwRootFile::FillNTupleFields(
1492 if (! HasNTupleByAddr(
object))
return;
1495 const void* addr =
static_cast<const void*
>(&object);
1498 for (
size_t ntuple = 0; ntuple < fNTupleByAddr[addr].size(); ntuple++) {
1499 fNTupleByAddr[addr].at(ntuple)->FillNTupleFields(
object);
1515 std::string type =
typeid(object).name();
1517 fRootFile->GetDirectory((
"/" + name).c_str()) ?
1518 fRootFile->GetDirectory((
"/" + name).c_str()) :
1519 fRootFile->GetDirectory(
"/")->mkdir(name.c_str());
1526 QwMessage <<
"QwRootFile::ConstructObjects::detectors address "
1528 <<
" and its name " << name
1531 std::string type =
typeid(object).name();
1534 object.ConstructObjects();
1552 std::string type =
typeid(object).name();
1554 fRootFile->GetDirectory((
"/" + name).c_str()) ?
1555 fRootFile->GetDirectory((
"/" + name).c_str()) :
1556 fRootFile->GetDirectory(
"/")->mkdir(name.c_str());
1564 QwMessage <<
"QwRootFile::ConstructHistograms::detectors address "
1566 <<
" and its name " << name
1569 std::string type =
typeid(object).name();
1573 object.ConstructHistograms();
1583 TList *param_list = (TList*)
fRootFile->FindObjectAny(name);
1584 if (not param_list) {
1585 retval =
fRootFile->WriteObject(
object.GetParamFileNameList(name), name);
An options class which parses command line, config file and environment.
#define QwError
Predefined log drain for errors.
#define QwMessage
Predefined log drain for regular messages.
#define BRANCH_VECTOR_MAX_SIZE
unsigned long long ULong64_t
static std::ostream & endl(std::ostream &)
End of the line.
Command-line and configuration file options processor.
A helper class to manage a vector of branch entries for ROOT trees.
const void * data() const noexcept
void SetValue(size_type index, Long64_t val)
void push_back(const char *name, const char type='D')
void reserve(size_type count)
size_type size() const noexcept
void SetValue(size_type index, Int_t val)
T & value(size_type index)
static std::string FormatNumeric(T input)
std::vector< Entry > m_entries
std::string LeafList(size_type start_index=0) const
QwRootTreeBranchVector()=default
T & operator[](size_type index)
void SetValue(size_type index, Short_t val)
std::string FormatValue(const Entry &entry, size_type index) const
bool empty() const noexcept
void SetValue(size_type index, ULong64_t val)
void SetValue(size_type index, UInt_t val)
size_type data_size() const noexcept
std::vector< std::uint8_t > m_buffer
const T & operator[](size_type index) const
static std::size_t GetTypeSize(char type)
void push_back(const std::string &name, const char type='D')
std::string Dump(size_type start_index=0, size_type end_index=0) const
static std::size_t AlignOffset(std::size_t offset)
void SetValue(size_type index, Float_t val)
void SetValue(size_type index, UShort_t val)
void SetValue(size_type index, Double_t val)
const T & value(size_type index) const
void push_back(const TString &name, const char type='D')
Wrapper class for ROOT tree management with vector-based data storage.
QwRootTree(const std::string &name, const std::string &desc, T &object, const std::string &prefix="")
Constructor with name, description, and object.
Long64_t AutoSave(Option_t *option)
Int_t Fill()
Fill the tree.
void ConstructNewTree()
Construct the tree.
UInt_t fCurrentEvent
Tree prescaling parameters.
virtual ~QwRootTree()
Destructor.
const std::string fPrefix
void SetAutoFlush(Long64_t autoflush=30000000)
Set autoflush size.
void Print() const
Print the tree name and description.
Long64_t fMaxTreeSize
Maximum tree size, autoflush and autosave.
const std::string fName
Name, description.
std::string fType
Object type.
static const TString kUnitsName
void ConstructUnitsBranch()
void SetCircular(Long64_t buff=100000)
void SetMaxTreeSize(Long64_t maxsize=1900000000)
Set maximum tree size.
QwRootTree(const std::string &name, const std::string &desc, const std::string &prefix="")
Constructor with name, and description.
void SetAutoSave(Long64_t autosave=300000000)
Set autosave size.
const std::string & GetPrefix() const
Get the description of the tree.
QwRootTreeBranchVector fVector
Vector of leaves.
void ConstructBranchAndVector(T &object)
Construct the branches and vector for generic objects.
static Double_t kUnitsValue[]
TTree * GetTree() const
Get the tree pointer for low level operations.
void ConstructIndexTo(QwRootTree *to)
Construct index from this tree to another tree.
const std::string & GetDesc() const
Get the description of the tree.
TTree * fTree
Tree pointer.
void SetBasketSize(Int_t basketsize=16000)
Set basket size.
void FillTreeBranches(const T &object)
Fill the branches for generic objects.
QwRootTree(const QwRootTree *tree, T &object, const std::string &prefix="")
Constructor with existing tree, and object.
QwRootTree(const QwRootTree *tree, const std::string &prefix="")
Constructor with existing tree.
const std::string & GetName() const
Get the name of the tree.
void SetPrescaling(UInt_t num_to_save, UInt_t num_to_skip)
Set tree prescaling parameters.
std::string GetType() const
Get the object type.
Bool_t IsRootFile() const
Is the ROOT file active?
bool HasTreeByType(const T &object)
Is a tree registered for this type.
std::vector< TPRegexp > fDisabledTrees
List of excluded trees.
std::map< const std::string, std::vector< std::string > > fDirsByType
void NewTree(const std::string &name, const std::string &desc)
Create a new tree with name and description.
TString fRootFileStem
ROOT file stem.
Int_t FillTree(const std::string &name)
Fill the tree with name.
TFile * fRootFile
ROOT file.
Bool_t IsMapFile() const
Is the map file active?
bool HasDirByType(const T &object)
Is a directory registered for this type.
virtual ~QwRootFile()
Destructor.
TString fRootFileDir
ROOT files dir.
void DisableTree(const TString ®exp)
Add regexp to list of disabled trees names.
Int_t fCompressionAlgorithm
Bool_t cd(const char *path=0)
Bool_t HasAnyFilled(void)
Search for non-empty trees or histograms in the file.
Int_t Write(const char *name=0, Int_t option=0, Int_t bufsize=0)
void PrintDirs() const
Print registered histogram directories.
static std::string fDefaultRootFileDir
Default ROOT files dir.
void PrintTrees() const
Print registered trees.
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)
std::map< const std::string, TDirectory * > fDirsByName
Directories.
void ProcessOptions(QwOptions &options)
Process the configuration options.
QwRootFile(const TString &run_label)
Constructor with run label.
UInt_t fNumHelEventsToSkip
bool IsHistoDisabled(const std::string &name)
Does this histogram directory match a disabled histogram directory?
std::map< const std::string, std::vector< QwRootTree * > > fTreeByName
Tree names, addresses, and types.
TDirectory * mkdir(const char *name, const char *title="")
void DisableHisto(const TString ®exp)
Add regexp to list of disabled histogram directories.
static void SetDefaultRootFileStem(const std::string &stem)
Set default ROOT file stem.
static void SetDefaultRootFileDir(const std::string &dir)
Set default ROOT files dir.
void ConstructTreeBranches(const std::string &name, const std::string &desc, T &object, const std::string &prefix="")
Construct the tree branches of a generic object.
UInt_t fNumMpsEventsToSave
static std::string fDefaultRootFileStem
Default ROOT file stem.
void FillHistograms(T &object)
Fill histograms of the subsystem array.
bool IsTreeDisabled(const std::string &name)
Does this tree name match a disabled tree name?
Int_t FillTrees()
Fill all registered trees.
std::map< const std::type_index, std::vector< QwRootTree * > > fTreeByType
static void DefineOptions(QwOptions &options)
Define the configuration options.
UInt_t fNumHelEventsToSave
TTree * GetTree(const std::string &name)
Get the tree with name.
bool HasTreeByAddr(const T &object)
Is a tree registered for this object.
TMapFile * fMapFile
Map file.
bool HasDirByName(const std::string &name)
Is a tree registered for this name.
void FillTreeBranches(const std::string &name, const T &object)
Fill the tree branches of a generic object by tree name.
Int_t WriteParamFileList(const TString &name, T &object)
QwRootFile()
Private default constructor.
void ConstructHistograms(const std::string &name, T &object)
Construct the histograms of a generic object.
UInt_t fCircularBufferSize
std::map< const void *, std::vector< QwRootTree * > > fTreeByAddr
void ConstructObjects(const std::string &name, T &object)
Construct the histograms of a generic object.
static const Long64_t kMaxTreeSize
Maximum tree size.
std::vector< TPRegexp > fDisabledHistos
UInt_t fNumMpsEventsToSkip
Prescaling of events written to tree.
void ConstructIndices(const std::string &from, const std::string &to, bool reverse=true)
Construct indices from one tree to another tree.
bool HasTreeByName(const std::string &name)
Is a tree registered for this name.