16#include <unordered_map>
30#ifdef HAS_RNTUPLE_SUPPORT
31#include "ROOT/RNTuple.hxx"
32#include "ROOT/RNTupleModel.hxx"
33#include "ROOT/RField.hxx"
34#include "ROOT/RNTupleWriter.hxx"
35#include "ROOT/RNTupleWriteOptions.hxx"
44#define BRANCH_VECTOR_MAX_SIZE 25000
70 m_buffer.reserve(
sizeof(
double)*count);
86 template <
typename T = u
int8_t>
91 template <
typename T = u
int8_t>
99 return *
reinterpret_cast<T*
>(
m_buffer.data() + entry.offset);
102 template <
typename T>
105 return *
reinterpret_cast<const T*
>(
m_buffer.data() + entry.offset);
112 if (entry.type !=
'D') {
113 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store double value '" + entry.name +
"'");
120 if (entry.type !=
'F') {
121 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store float value '" + entry.name +
"'");
128 if (entry.type !=
'I') {
129 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store int value '" + entry.name +
"'");
136 if (entry.type !=
'L') {
137 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store long long value '" + entry.name +
"'");
144 if (entry.type !=
'S') {
145 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store short value '" + entry.name +
"'");
153 if (entry.type !=
's') {
154 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store short value '" + entry.name +
"'");
161 if (entry.type !=
'i') {
162 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store unsigned int value '" + entry.name +
"'");
169 if (entry.type !=
'l') {
170 throw std::invalid_argument(
"Type mismatch: entry type '" + std::string(1, entry.type) +
"' cannot store long long value '" + entry.name +
"'");
179 template <
typename T>
182 throw std::out_of_range(
"QwRootTreeBranchVector::back() called on empty container");
184 const auto& last_entry =
m_entries.back();
185 return *
reinterpret_cast<T*
>(
m_buffer.data() + last_entry.offset);
188 template <
typename T>
191 throw std::out_of_range(
"QwRootTreeBranchVector::back() called on empty container");
193 const auto& last_entry =
m_entries.back();
194 return *
reinterpret_cast<const T*
>(
m_buffer.data() + last_entry.offset);
197 void push_back(
const std::string& name,
const char type =
'D') {
202 throw std::out_of_range(
"QwRootTreeBranchVector::push_back() requires buffer resize beyond reserved capacity");
208 Entry entry{name, offset, entry_size, type};
211 const std::size_t required = offset + entry_size;
212 if (required >
m_buffer.capacity()) {
213 throw std::out_of_range(
"QwRootTreeBranchVector::push_back() requires buffer resize beyond reserved capacity");
221 void push_back(
const TString& name,
const char type =
'D') {
222 push_back(std::string(name.Data()), type);
226 void push_back(
const char* name,
const char type =
'D') {
231 static const std::string separator =
":";
232 std::ostringstream stream;
239 stream << entry.name <<
"/" << entry.type;
246 std::ostringstream stream;
247 stream <<
"QwRootTreeBranchVector: " <<
m_entries.size() <<
" entries, "
249 size_t end_offset = (end_index == 0 || end_index >
m_entries.size()) ?
252 stream <<
"QwRootTreeBranchVector: buffer at 0x" << std::hex << (
void*) &
m_buffer[0] <<
'\n';
253 stream <<
"QwRootTreeBranchVector: entries at 0x" << std::hex << (
void*) &
m_entries[0] <<
'\n';
254 for (
size_t offset =
m_entries[start_index].offset; offset < end_offset; offset += 4) {
256 <<
" [" << offset <<
"] "
258 <<
" offset=0x" << offset
259 <<
" (0x" << std::setw(4) << std::setfill(
'0')
260 << offset -
m_entries[start_index].offset <<
")"
263 for (std::size_t
byte = 0;
byte < 4; ++byte) {
264 stream << std::hex << std::setw(2) << std::setfill(
'0')
265 <<
static_cast<unsigned int>(
m_buffer[offset + byte])
270 end_index = (end_index == 0 || end_index >
m_entries.size()) ?
273 for (
size_type index = start_index; index < end_index; ++index) {
276 <<
" [" << index <<
"] "
278 <<
" offset=0x" << entry.offset
279 <<
" (0x" << std::setw(4) << std::setfill(
'0')
280 << entry.offset -
m_entries[start_index].offset <<
")"
281 <<
" size=0x" << entry.size
284 for (std::size_t
byte =
GetTypeSize(entry.type);
byte > 0; --
byte) {
285 stream << std::hex << std::setw(2) << std::setfill(
'0')
286 <<
static_cast<unsigned int>((
m_buffer.data() + entry.offset)[
byte - 1]);
289 <<
" name=" << entry.name <<
"/" << entry.type
300 return sizeof(double);
302 return sizeof(float);
304 return sizeof(
long long);
306 return sizeof(
unsigned long long);
310 return sizeof(
unsigned int);
312 return sizeof(short);
314 return sizeof(
unsigned short);
316 throw std::invalid_argument(
"Unsupported branch type code: " + std::string(1, type));
321 const std::size_t alignment = 4u;
322 return (offset + (alignment - 1u)) & ~(alignment - 1u);
329 switch (entry.
type) {
351 template <
typename T>
353 std::ostringstream stream;
374 QwRootTree(
const std::string& name,
const std::string& desc,
const std::string& prefix =
"")
391 QwRootTree(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"")
433 fTree->SetDirectory(gDirectory);
441 std::string name =
"units";
447 std::string name =
"previous_entry_in_" + to->
fName;
457 TString prefix = Form(
"%s",
fPrefix.c_str());
458 object.ConstructBranchAndVector(
fTree, prefix,
fVector);
461 fType =
typeid(object).name();
465 QwError <<
"The branch vector is too large: " <<
fVector.size() <<
" leaves! "
488 if (
typeid(
object).name() ==
fType) {
490 object.FillTreeVector(
fVector);
492 QwError <<
"Attempting to fill tree vector for type " <<
fType <<
" with "
493 <<
"object of type " <<
typeid(object).name() <<
QwLog::endl;
499 return fTree->AutoSave(option);
514 Int_t retval =
fTree->Fill();
595 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
609 if (
fTree)
fTree->SetBasketSize(
"*",basketsize);
618#ifdef HAS_RNTUPLE_SUPPORT
632 QwRootNTuple(
const std::string& name,
const std::string& desc,
const std::string& prefix =
"")
633 : fName(name), fDesc(desc), fPrefix(prefix), fType(
"type undefined"),
634 fCurrentEvent(0), fNumEventsCycle(0), fNumEventsToSave(0), fNumEventsToSkip(0) {
636 fModel = ROOT::RNTupleModel::Create();
641 QwRootNTuple(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"")
642 : fName(name), fDesc(desc), fPrefix(prefix), fType(
"type undefined"),
643 fCurrentEvent(0), fNumEventsCycle(0), fNumEventsToSave(0), fNumEventsToSkip(0) {
645 fModel = ROOT::RNTupleModel::Create();
648 ConstructFieldsAndVector(
object);
652 virtual ~QwRootNTuple() {
669 void ConstructFieldsAndVector(T&
object) {
674 TString prefix = Form(
"%s", fPrefix.c_str());
675 object.ConstructNTupleAndVector(fModel, prefix, fVector, fFieldPtrs);
678 fType =
typeid(object).name();
682 QwError <<
"The field vector is too large: " << fVector.size() <<
" fields! "
689 fVector.shrink_to_fit();
695 void InitializeWriter(TFile* file) {
702 if (fVector.empty()) {
709 ROOT::RNTupleWriteOptions options;
710 options.SetCompression(
711 static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues
>(fRNTupleCompressionAlgorithm),
712 fRNTupleCompressionLevel
717 fWriter = ROOT::RNTupleWriter::Append(std::move(fModel), fName, *file, options);
719 const char* algo_name =
"UNKNOWN";
720 switch(fRNTupleCompressionAlgorithm) {
721 case 1: algo_name =
"ZLIB";
break;
722 case 2: algo_name =
"LZMA";
break;
723 case 4: algo_name =
"LZ4";
break;
724 case 5: algo_name =
"ZSTD";
break;
726 QwMessage <<
"Created RNTuple '" << fName <<
"' with " << algo_name
727 <<
" compression (level " << fRNTupleCompressionLevel <<
") in file "
730 }
catch (
const std::exception& e) {
731 QwError <<
"Failed to create RNTuple writer for '" << fName <<
"': " << e.what() <<
QwLog::endl;
737 void FillNTupleFields(
const T&
object) {
738 if (
typeid(
object).name() == fType) {
740 object.FillNTupleVector(fVector);
744 for (
size_t i = 0; i < fVector.size() && i < fFieldPtrs.size(); ++i) {
746 *(fFieldPtrs[i]) = fVector[i];
756 if (fNumEventsCycle > 0) {
757 fCurrentEvent %= fNumEventsCycle;
763 QwError <<
"Attempting to fill RNTuple vector for type " << fType <<
" with "
764 <<
"object of type " <<
typeid(object).name() <<
QwLog::endl;
776 const std::string& GetName()
const {
return fName; }
778 const std::string& GetDesc()
const {
return fDesc; }
780 const std::string& GetPrefix()
const {
return fPrefix; }
782 std::string GetType()
const {
return fType; }
785 void SetPrescaling(UInt_t num_to_save, UInt_t num_to_skip) {
786 fNumEventsToSave = num_to_save;
787 fNumEventsToSkip = num_to_skip;
788 fNumEventsCycle = fNumEventsToSave + fNumEventsToSkip;
793 QwMessage << GetName() <<
", " << GetType();
795 QwMessage <<
" (prefix " << GetPrefix() <<
")";
802 std::unique_ptr<ROOT::RNTupleModel> fModel;
803 std::unique_ptr<ROOT::RNTupleWriter> fWriter;
806 std::vector<Double_t> fVector;
807 std::vector<std::shared_ptr<Double_t>> fFieldPtrs;
810 const std::string fName;
811 const std::string fDesc;
812 const std::string fPrefix;
818 UInt_t fCurrentEvent;
819 UInt_t fNumEventsCycle;
820 UInt_t fNumEventsToSave;
821 UInt_t fNumEventsToSkip;
824 Int_t fRNTupleCompressionAlgorithm;
825 Int_t fRNTupleCompressionLevel;
827 friend class QwRootFile;
889 void ConstructIndices(
const std::string& from,
const std::string& to,
bool reverse =
true);
893 void ConstructTreeBranches(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"");
901#ifdef HAS_RNTUPLE_SUPPORT
904 void ConstructNTupleFields(
const std::string& name,
const std::string& desc, T&
object,
const std::string& prefix =
"");
907 void FillNTupleFields(
const std::string& name,
const T&
object);
910 void FillNTupleFields(
const T&
object);
929 static Int_t update_count = 0;
943 std::string type =
typeid(object).name();
946 if (! hasDir)
return;
948 object.FillHistograms();
953 void NewTree(
const std::string& name,
const std::string& desc) {
965#ifdef HAS_RNTUPLE_SUPPORT
967 void NewNTuple(
const std::string& name,
const std::string& desc) {
969 QwRootNTuple *ntuple = 0;
970 if (! HasNTupleByName(name)) {
971 ntuple =
new QwRootNTuple(name, desc);
982 fNTupleByName[name].push_back(ntuple);
1002 std::map< const std::string, std::vector<QwRootTree*> >::iterator iter;
1004 retval += iter->second.front()->Fill();
1009#ifdef HAS_RNTUPLE_SUPPORT
1011 void FillNTuple(
const std::string& name) {
1012 if (HasNTupleByName(name)) {
1013 fNTupleByName[name].front()->Fill();
1018#ifdef HAS_RNTUPLE_SUPPORT
1020 void FillNTuples() {
1022 std::map< const std::string, std::vector<QwRootNTuple*> >::iterator iter;
1023 for (iter = fNTupleByName.begin(); iter != fNTupleByName.end(); iter++) {
1024 iter->second.front()->Fill();
1033 std::map< const std::string, std::vector<QwRootTree*> >::const_iterator iter;
1035 QwMessage << iter->first <<
": " << iter->second.size()
1038 std::vector<QwRootTree*>::const_iterator tree;
1039 for (tree = iter->second.begin(); tree != iter->second.end(); tree++) {
1048 std::map< const std::string, TDirectory* >::const_iterator iter;
1056 template <
class T >
1057 Int_t
WriteObject(
const T* obj,
const char* name, Option_t* option =
"", Int_t bufsize = 0) {
1068 QwMessage <<
"TMapFile memory resident size: "
1070 4 /
sizeof(int32_t) / 1024 / 1024 <<
" MiB"
1077 nBytes += iter->second.front()->AutoSave(
"SaveSelf");
1080 << nBytes/1000000 <<
"MB (inaccurate number)"
1097 std::vector<TString> subdirs;
1098 TIter next(dir->GetListOfKeys());
1100 while ((key = (TKey*)next())) {
1101 if (TString(key->GetClassName()) ==
"TDirectoryFile") {
1102 subdirs.push_back(key->GetName());
1107 for (
const auto& name : subdirs) {
1108 TDirectory* sub =
dynamic_cast<TDirectory*
>(dir->Get(name));
1114 TList* list = dir->GetList();
1116 list->Clear(
"nodelete");
1126 if (!iter->second.empty() && iter->second.front()) {
1127 TTree* tree = iter->second.front()->GetTree();
1128 if (tree && tree->GetEntries() > 0) {
1136 fRootFile->Write(0, TObject::kOverwrite);
1147#ifdef HAS_RNTUPLE_SUPPORT
1148 if (!fNTupleByName.empty()) {
1154#ifdef HAS_RNTUPLE_SUPPORT
1158 for (
auto& pair : fNTupleByName) {
1159 for (
auto& ntuple : pair.second) {
1160 if (ntuple) ntuple->Close();
1176 Bool_t
cd(
const char* path = 0) {
1177 Bool_t status = kTRUE;
1184 TDirectory*
mkdir(
const char* name,
const char* title =
"") {
1191 Int_t
Write(
const char* name = 0, Int_t option = 0, Int_t bufsize = 0) {
1278 std::map< const std::type_index , std::vector<QwRootTree*> >
fTreeByType;
1281#ifdef HAS_RNTUPLE_SUPPORT
1283 std::map< const std::string, std::vector<QwRootNTuple*> > fNTupleByName;
1284 std::map< const void* , std::vector<QwRootNTuple*> > fNTupleByAddr;
1285 std::map< const std::type_index , std::vector<QwRootNTuple*> > fNTupleByType;
1288 Bool_t fEnableRNTuples;
1297 template <
class T >
1299 const std::type_index type =
typeid(object);
1304 template <
class T >
1306 const void* addr =
static_cast<const void*
>(&object);
1311#ifdef HAS_RNTUPLE_SUPPORT
1313 bool HasNTupleByName(
const std::string& name) {
1314 if (fNTupleByName.count(name) == 0)
return false;
1318 template <
class T >
1319 bool HasNTupleByType(
const T&
object) {
1320 const std::type_index type =
typeid(object);
1321 if (fNTupleByType.count(type) == 0)
return false;
1325 template <
class T >
1326 bool HasNTupleByAddr(
const T&
object) {
1327 const void* addr =
static_cast<const void*
>(&object);
1328 if (fNTupleByAddr.count(addr) == 0)
return false;
1343 template <
class T >
1345 std::string type =
typeid(object).name();
1405 const std::string& name,
1406 const std::string& desc,
1408 const std::string& prefix)
1424 tree =
new QwRootTree(name, desc,
object, prefix);
1429 else if (name ==
"mul")
1432 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,26,00)
1449 const void* addr =
static_cast<const void*
>(&object);
1450 const std::type_index type =
typeid(object);
1464 const std::string& name,
1473 const void* addr =
static_cast<const void*
>(&object);
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);
1496 const void* addr =
static_cast<const void*
>(&object);
1499 for (
size_t tree = 0; tree <
fTreeByAddr[addr].size(); tree++) {
1500 fTreeByAddr[addr].at(tree)->FillTreeBranches(
object);
1505#ifdef HAS_RNTUPLE_SUPPORT
1514void QwRootFile::ConstructNTupleFields(
1515 const std::string& name,
1516 const std::string& desc,
1518 const std::string& prefix)
1521 if (!fEnableRNTuples)
return;
1524 QwRootNTuple* ntuple = 0;
1527 if (fNTupleByName.count(name) == 0) {
1530 ntuple =
new QwRootNTuple(name, desc,
object, prefix);
1542 else if (name ==
"mul")
1553 const void* addr =
static_cast<const void*
>(&object);
1554 const std::type_index type =
typeid(object);
1555 fNTupleByName[name].push_back(ntuple);
1556 fNTupleByAddr[addr].push_back(ntuple);
1557 fNTupleByType[type].push_back(ntuple);
1567void QwRootFile::FillNTupleFields(
1568 const std::string& name,
1572 if (! HasNTupleByName(name))
return;
1574 if (! HasNTupleByType(
object))
return;
1577 const void* addr =
static_cast<const void*
>(&object);
1580 for (
size_t ntuple = 0; ntuple < fNTupleByAddr[addr].size(); ntuple++) {
1581 if (fNTupleByAddr[addr].at(ntuple)->GetName() == name) {
1582 fNTupleByAddr[addr].at(ntuple)->FillNTupleFields(
object);
1593void QwRootFile::FillNTupleFields(
1597 if (! HasNTupleByAddr(
object))
return;
1600 const void* addr =
static_cast<const void*
>(&object);
1603 for (
size_t ntuple = 0; ntuple < fNTupleByAddr[addr].size(); ntuple++) {
1604 fNTupleByAddr[addr].at(ntuple)->FillNTupleFields(
object);
1620 std::string type =
typeid(object).name();
1622 fRootFile->GetDirectory((
"/" + name).c_str()) ?
1623 fRootFile->GetDirectory((
"/" + name).c_str()) :
1624 fRootFile->GetDirectory(
"/")->mkdir(name.c_str());
1631 QwMessage <<
"QwRootFile::ConstructObjects::detectors address "
1633 <<
" and its name " << name
1642 std::string type =
typeid(object).name();
1646 object.ConstructObjects();
1664 std::string type =
typeid(object).name();
1666 fRootFile->GetDirectory((
"/" + name).c_str()) ?
1667 fRootFile->GetDirectory((
"/" + name).c_str()) :
1668 fRootFile->GetDirectory(
"/")->mkdir(name.c_str());
1676 QwMessage <<
"QwRootFile::ConstructHistograms::detectors address "
1678 <<
" and its name " << name
1687 std::string type =
typeid(object).name();
1698 TString prefix = TString(name.c_str()) +
"_";
1699 object.ConstructHistograms((TDirectory*)NULL, prefix);
1709 TList *param_list = (TList*)
fRootFile->FindObjectAny(name);
1710 if (not param_list) {
1711 retval =
fRootFile->WriteObject(
object.GetParamFileNameList(name), name);
An options class which parses command line, config file and environment.
#define BRANCH_VECTOR_MAX_SIZE
#define QwError
Predefined log drain for errors.
#define QwMessage
Predefined log drain for regular messages.
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.
UInt_t fHistoFillPrescale
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.
void ClearInMemoryObjects(TDirectory *dir)
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
Int_t fRNTupleCompressionLevel
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.
Int_t fRNTupleCompressionAlgorithm