From 937b05d26a0fa40dfbddf7b561fdcf00f66aa77f Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 18:52:50 +0200 Subject: [PATCH 1/7] enable run GenericContainerFiller with filelist --- infra/GenericContainerFiller.cpp | 26 +++++++++++++++++++++----- infra/GenericContainerFiller.hpp | 5 ++--- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index e51881ca..da5566a2 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -4,17 +4,33 @@ #include "GenericContainerFiller.hpp" +#include + using namespace AnalysisTree; GenericContainerFiller::GenericContainerFiller(std::string fileInName, std::string treeInName) : file_in_name_(std::move(fileInName)), tree_in_name_(std::move(treeInName)) {} void GenericContainerFiller::Init() { - file_in_ = TFile::Open(file_in_name_.c_str(), "read"); - if (file_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): file_in_ == nullptr"); + tree_in_ = new TChain(tree_in_name_.c_str()); + + auto ends_with = [](const std::string& str, const std::string& suffix) { + if (suffix.size() > str.size()) return false; + return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()); + }; + + if(ends_with(file_in_name_, ".root")) { + tree_in_->Add(file_in_name_.c_str()); + } else { + std::ifstream filelist(file_in_name_); + std::string line; - tree_in_ = file_in_->Get(tree_in_name_.c_str()); - if (tree_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): tree_in_ == nullptr"); + if (!filelist) throw std::runtime_error("GenericContainerFiller::Init(): filelist " + file_in_name_ + " is missing"); + + while (std::getline(filelist, line)) { + tree_in_->Add(line.c_str()); + } + } if (!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) throw std::runtime_error("GenericContainerFiller::Run(): !fields_to_ignore_.empty() && !fields_to_preserve_.empty()"); @@ -74,7 +90,7 @@ void GenericContainerFiller::Finish() { config_.Write("Configuration"); tree_out_->Write(); file_out_->Close(); - file_in_->Close(); + delete tree_in_; } void GenericContainerFiller::Run(int nEntries) { diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index b7a5bbda..b6806c1d 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -9,8 +9,8 @@ #include "Container.hpp" #include "Detector.hpp" +#include #include -#include #include #include @@ -73,8 +73,7 @@ class GenericContainerFiller { std::string tree_out_name_{"aTree"}; std::string branch_out_name_{"PlainBranch"}; - TFile* file_in_{nullptr}; - TTree* tree_in_{nullptr}; + TChain* tree_in_{nullptr}; TFile* file_out_{nullptr}; TTree* tree_out_{nullptr}; From 35357b0ea168e0cc87809cb9b720ddea285383ac Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 19:03:11 +0200 Subject: [PATCH 2/7] bugfix non-progressing trees in a chain when SetAddress() --- infra/GenericContainerFiller.cpp | 13 ++++++------- infra/GenericContainerFiller.hpp | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index da5566a2..83dcd66f 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -56,8 +56,7 @@ void GenericContainerFiller::Init() { config_.AddBranchConfig(branchConfig); for (int iV = 0; iV < branch_values_.size(); iV++) { - TBranch* branch = tree_in_->GetBranch(branch_map_.at(iV).name_.c_str()); - SetAddressFICS(branch, branch_map_.at(iV), branch_values_.at(iV)); + SetAddressFICS(branch_map_.at(iV).name_, branch_map_.at(iV), branch_values_.at(iV)); } generic_detector_ = new GenericDetector(branchConfig.GetId()); @@ -114,14 +113,14 @@ int GenericContainerFiller::DetermineFieldIdByName(const std::vector& return distance; } -void GenericContainerFiller::SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc) { - if (imap.field_type_ == "TLeafF") branch->SetAddress(&ficc.float_); +void GenericContainerFiller::SetAddressFICS(const std::string& branchName, const IndexMap& imap, FICS& ficc) { + if (imap.field_type_ == "TLeafF") tree_in_->SetBranchAddress(branchName.c_str(), &ficc.float_); else if (imap.field_type_ == "TLeafI") - branch->SetAddress(&ficc.int_); + tree_in_->SetBranchAddress(branchName.c_str(), &ficc.int_); else if (imap.field_type_ == "TLeafB") - branch->SetAddress(&ficc.char_); + tree_in_->SetBranchAddress(branchName.c_str(), &ficc.char_); else if (imap.field_type_ == "TLeafS") - branch->SetAddress(&ficc.short_); + tree_in_->SetBranchAddress(branchName.c_str(), &ficc.short_); else throw std::runtime_error("GenericContainerFiller::SetAddressFICS(): unsupported filed type " + imap.field_type_); } diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index b6806c1d..4125674a 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -63,7 +63,7 @@ class GenericContainerFiller { void Finish(); static int DetermineFieldIdByName(const std::vector& iMap, const std::string& name); - static void SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc); + void SetAddressFICS(const std::string& branchName, const IndexMap& imap, FICS& ficc); static void SetFieldsFICS(const std::vector& imap, AnalysisTree::Container& container, const std::vector& ficc); std::string file_in_name_; From b6f1ad365de63beaf9732ec14462790f605c7504 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 19:04:06 +0200 Subject: [PATCH 3/7] apply clang-format --- infra/GenericContainerFiller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index 83dcd66f..49818ce5 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -19,7 +19,7 @@ void GenericContainerFiller::Init() { return std::equal(suffix.rbegin(), suffix.rend(), str.rbegin()); }; - if(ends_with(file_in_name_, ".root")) { + if (ends_with(file_in_name_, ".root")) { tree_in_->Add(file_in_name_.c_str()); } else { std::ifstream filelist(file_in_name_); From 5d7e3142e3f94bca0ea483741f07f45beb20b925 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 23:05:57 +0200 Subject: [PATCH 4/7] distinguish float, int, bool in PlainTreeFiller --- infra/PlainTreeFiller.cpp | 18 ++++++++++++++---- infra/PlainTreeFiller.hpp | 9 ++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index 1300241e..8a4c94a1 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -55,12 +55,18 @@ void PlainTreeFiller::Init() { const auto& branch_config = config_->GetBranchConfig(branch_name_); for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); + vars_.emplace_back(FIB()); + vars_.back().type_ = Types::kFloat; } for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); + vars_.emplace_back(FIB()); + vars_.back().type_ = Types::kInteger; } for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); + vars_.emplace_back(FIB()); + vars_.back().type_ = Types::kBool; } } @@ -70,7 +76,8 @@ void PlainTreeFiller::Init() { throw std::runtime_error("Only 1 output branch"); } const auto& vars = entries_[0].GetVariables(); - vars_.resize(vars.size()); + + if(vars_.size() != vars.size()) throw std::runtime_error("PlainTreeFiller::Init(): vars_.size() != vars.size()"); file_ = TFile::Open(file_name_.c_str(), "recreate"); plain_tree_ = new TTree(tree_name_.c_str(), "Plain Tree"); @@ -81,7 +88,9 @@ void PlainTreeFiller::Init() { if (!fields_to_preserve_.empty() && std::find(fields_to_preserve_.begin(), fields_to_preserve_.end(), leaf_name) == fields_to_preserve_.end()) continue; if (!is_prepend_leaves_with_branchname_) leaf_name.erase(0, branch_name_.size() + 1); std::replace(leaf_name.begin(), leaf_name.end(), '.', '_'); - plain_tree_->Branch(leaf_name.c_str(), &(vars_.at(i)), Form("%s/F", leaf_name.c_str())); + if(vars_.at(i).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).float_, Form("%s/F", leaf_name.c_str())); + if(vars_.at(i).type_ == Types::kInteger) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).int_, Form("%s/I", leaf_name.c_str())); + if(vars_.at(i).type_ == Types::kBool) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).bool_, Form("%s/O", leaf_name.c_str())); } for (auto& cm : cuts_map_) { @@ -97,7 +106,9 @@ void PlainTreeFiller::Exec() { for (const auto& channel : values) { assert(channel.size() == vars_.size()); for (size_t i = 0; i < channel.size(); ++i) { - vars_.at(i) = channel.at(i); + if(vars_.at(i).type_ == Types::kFloat) vars_.at(i).float_ = static_cast(channel.at(i)); + if(vars_.at(i).type_ == Types::kInteger) vars_.at(i).int_ = static_cast(channel.at(i)); + if(vars_.at(i).type_ == Types::kBool) vars_.at(i).bool_ = static_cast(channel.at(i)); } plain_tree_->Fill(); } @@ -109,6 +120,5 @@ void PlainTreeFiller::Finish() { plain_tree_->Write(); file_->Close(); delete file_; - // delete plain_tree_; } }// namespace AnalysisTree diff --git a/infra/PlainTreeFiller.hpp b/infra/PlainTreeFiller.hpp index 1bf9c5d4..fb96afd4 100644 --- a/infra/PlainTreeFiller.hpp +++ b/infra/PlainTreeFiller.hpp @@ -12,6 +12,13 @@ namespace AnalysisTree { +struct FIB { + float float_{-299.f}; + int int_{-299}; + bool bool_{false}; + Types type_{Types::kNumberOfTypes}; +}; + class PlainTreeFiller : public AnalysisTask { public: PlainTreeFiller() = default; @@ -41,7 +48,7 @@ class PlainTreeFiller : public AnalysisTask { std::string tree_name_{"PlainTree"}; std::string branch_name_; - std::vector vars_{}; + std::vector vars_; std::vector fields_to_ignore_{}; std::vector fields_to_preserve_{}; From e56e2969900e3617e3b7aa1799e6c19345e3b0b9 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 23:12:23 +0200 Subject: [PATCH 5/7] follow clang-tidy suggestions --- infra/GenericContainerFiller.hpp | 4 ++-- infra/PlainTreeFiller.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index 4125674a..49b29179 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -27,7 +27,7 @@ struct FICS {// FICS stands for float, int, char, short char char_{static_cast(-199)}; short short_{static_cast(-199)}; - float get() { + float get() const { if (std::fabs(float_ + 199.f) > 1e-4) return float_; if (int_ != -199) return static_cast(int_); if (char_ != static_cast(-199)) return static_cast(char_); @@ -83,7 +83,7 @@ class GenericContainerFiller { std::vector branch_values_; // variable, change of value of which triggers switch to a new AT event - std::string entry_switch_trigger_var_name_{""}; + std::string entry_switch_trigger_var_name_; int entry_switch_trigger_id_{-1}; diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index 8a4c94a1..61871b41 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -16,7 +16,7 @@ void PlainTreeFiller::AddBranch(const std::string& branch_name) { } void PlainTreeFiller::SetFieldsToIgnore(const std::vector& fields_to_ignore) { - if (branch_name_ == "") { + if (branch_name_.empty()) { throw std::runtime_error("PlainTreeFiller::SetFieldsToIgnore() must be called after PlainTreeFiller::AddBranch()\n"); } for (auto& fti : fields_to_ignore) { @@ -25,7 +25,7 @@ void PlainTreeFiller::SetFieldsToIgnore(const std::vector& fields_t } void PlainTreeFiller::SetFieldsToPreserve(const std::vector& fields_to_preserve) { - if (branch_name_ == "") { + if (branch_name_.empty()) { throw std::runtime_error("PlainTreeFiller::SetFieldsToPreserve() must be called after PlainTreeFiller::AddBranch()\n"); } for (auto& fti : fields_to_preserve) { @@ -44,7 +44,7 @@ void PlainTreeFiller::Init() { if (me.second.id_ < 0) defaultFieldsNames.emplace_back(me.first); } } - SetFieldsToIgnore(std::move(defaultFieldsNames)); + SetFieldsToIgnore(defaultFieldsNames); } if (!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) { @@ -55,17 +55,17 @@ void PlainTreeFiller::Init() { const auto& branch_config = config_->GetBranchConfig(branch_name_); for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); - vars_.emplace_back(FIB()); + vars_.emplace_back(); vars_.back().type_ = Types::kFloat; } for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); - vars_.emplace_back(FIB()); + vars_.emplace_back(); vars_.back().type_ = Types::kInteger; } for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); - vars_.emplace_back(FIB()); + vars_.emplace_back(); vars_.back().type_ = Types::kBool; } } From e53b556e32e4e585d7f8245c5ab29c1d0125a46c Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 23:13:15 +0200 Subject: [PATCH 6/7] apply clang format --- infra/PlainTreeFiller.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index 61871b41..78cd5e2f 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -77,7 +77,7 @@ void PlainTreeFiller::Init() { } const auto& vars = entries_[0].GetVariables(); - if(vars_.size() != vars.size()) throw std::runtime_error("PlainTreeFiller::Init(): vars_.size() != vars.size()"); + if (vars_.size() != vars.size()) throw std::runtime_error("PlainTreeFiller::Init(): vars_.size() != vars.size()"); file_ = TFile::Open(file_name_.c_str(), "recreate"); plain_tree_ = new TTree(tree_name_.c_str(), "Plain Tree"); @@ -88,9 +88,9 @@ void PlainTreeFiller::Init() { if (!fields_to_preserve_.empty() && std::find(fields_to_preserve_.begin(), fields_to_preserve_.end(), leaf_name) == fields_to_preserve_.end()) continue; if (!is_prepend_leaves_with_branchname_) leaf_name.erase(0, branch_name_.size() + 1); std::replace(leaf_name.begin(), leaf_name.end(), '.', '_'); - if(vars_.at(i).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).float_, Form("%s/F", leaf_name.c_str())); - if(vars_.at(i).type_ == Types::kInteger) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).int_, Form("%s/I", leaf_name.c_str())); - if(vars_.at(i).type_ == Types::kBool) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).bool_, Form("%s/O", leaf_name.c_str())); + if (vars_.at(i).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).float_, Form("%s/F", leaf_name.c_str())); + if (vars_.at(i).type_ == Types::kInteger) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).int_, Form("%s/I", leaf_name.c_str())); + if (vars_.at(i).type_ == Types::kBool) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).bool_, Form("%s/O", leaf_name.c_str())); } for (auto& cm : cuts_map_) { @@ -106,9 +106,9 @@ void PlainTreeFiller::Exec() { for (const auto& channel : values) { assert(channel.size() == vars_.size()); for (size_t i = 0; i < channel.size(); ++i) { - if(vars_.at(i).type_ == Types::kFloat) vars_.at(i).float_ = static_cast(channel.at(i)); - if(vars_.at(i).type_ == Types::kInteger) vars_.at(i).int_ = static_cast(channel.at(i)); - if(vars_.at(i).type_ == Types::kBool) vars_.at(i).bool_ = static_cast(channel.at(i)); + if (vars_.at(i).type_ == Types::kFloat) vars_.at(i).float_ = static_cast(channel.at(i)); + if (vars_.at(i).type_ == Types::kInteger) vars_.at(i).int_ = static_cast(channel.at(i)); + if (vars_.at(i).type_ == Types::kBool) vars_.at(i).bool_ = static_cast(channel.at(i)); } plain_tree_->Fill(); } From 3b90ac006ea2ad42acb272abe0ee734215e16b4b Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 25 Apr 2025 23:30:56 +0200 Subject: [PATCH 7/7] more safe cast of double into int and bool --- infra/PlainTreeFiller.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index 78cd5e2f..10c4e1dd 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -89,8 +89,10 @@ void PlainTreeFiller::Init() { if (!is_prepend_leaves_with_branchname_) leaf_name.erase(0, branch_name_.size() + 1); std::replace(leaf_name.begin(), leaf_name.end(), '.', '_'); if (vars_.at(i).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).float_, Form("%s/F", leaf_name.c_str())); - if (vars_.at(i).type_ == Types::kInteger) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).int_, Form("%s/I", leaf_name.c_str())); - if (vars_.at(i).type_ == Types::kBool) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).bool_, Form("%s/O", leaf_name.c_str())); + else if (vars_.at(i).type_ == Types::kInteger) + plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).int_, Form("%s/I", leaf_name.c_str())); + else if (vars_.at(i).type_ == Types::kBool) + plain_tree_->Branch(leaf_name.c_str(), &vars_.at(i).bool_, Form("%s/O", leaf_name.c_str())); } for (auto& cm : cuts_map_) { @@ -107,8 +109,10 @@ void PlainTreeFiller::Exec() { assert(channel.size() == vars_.size()); for (size_t i = 0; i < channel.size(); ++i) { if (vars_.at(i).type_ == Types::kFloat) vars_.at(i).float_ = static_cast(channel.at(i)); - if (vars_.at(i).type_ == Types::kInteger) vars_.at(i).int_ = static_cast(channel.at(i)); - if (vars_.at(i).type_ == Types::kBool) vars_.at(i).bool_ = static_cast(channel.at(i)); + else if (vars_.at(i).type_ == Types::kInteger) + vars_.at(i).int_ = static_cast(std::round(channel.at(i))); + else if (vars_.at(i).type_ == Types::kBool) + vars_.at(i).bool_ = static_cast(std::round(channel.at(i))); } plain_tree_->Fill(); }