From d79e2ae2214f495efbadb011b2b08e681b0486d8 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Fri, 4 Apr 2025 18:25:55 +0200 Subject: [PATCH 1/9] bugfix in HelperFunctions sliceCuts name --- infra/HelperFunctions.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/HelperFunctions.hpp b/infra/HelperFunctions.hpp index 50a300c7..6efd5fa2 100644 --- a/infra/HelperFunctions.hpp +++ b/infra/HelperFunctions.hpp @@ -33,7 +33,7 @@ inline std::string ToStringWithSignificantFigures(const T a_value, const int n) inline std::vector CreateRangeCuts(const std::vector& ranges, const std::string& cutNamePrefix, const std::string& branchFieldName, int precision = 2) { std::vector sliceCuts; for (int iRange = 0; iRange < ranges.size() - 1; iRange++) { - const std::string cutName = cutNamePrefix + ToStringWithPrecision(ranges.at(iRange), 2) + "_" + ToStringWithPrecision(ranges.at(iRange + 1), precision); + const std::string cutName = cutNamePrefix + ToStringWithPrecision(ranges.at(iRange), precision) + "_" + ToStringWithPrecision(ranges.at(iRange + 1), precision); sliceCuts.emplace_back(AnalysisTree::RangeCut(branchFieldName, ranges.at(iRange), ranges.at(iRange + 1), cutName)); } From 9dc80608ea5b8b50b18ea1c3e14ef789b06691a6 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Tue, 8 Apr 2025 12:31:34 +0200 Subject: [PATCH 2/9] enable generic (plain) container, w/o default fields --- core/AnalysisTreeCoreLinkDef.h | 1 + core/Constants.hpp | 3 ++- infra/Branch.cpp | 4 ++++ infra/Chain.cpp | 4 ++++ infra/TaskManager.hpp | 7 ++++--- infra/Utils.hpp | 5 +++-- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/core/AnalysisTreeCoreLinkDef.h b/core/AnalysisTreeCoreLinkDef.h index 87d4f4c7..e658095d 100644 --- a/core/AnalysisTreeCoreLinkDef.h +++ b/core/AnalysisTreeCoreLinkDef.h @@ -40,6 +40,7 @@ #pragma link C++ typedef AnalysisTree::ModuleDetector; #pragma link C++ typedef AnalysisTree::HitDetector; #pragma link C++ typedef AnalysisTree::ModulePositions; +#pragma link C++ typedef AnalysisTree::GenericDetector; #pragma link C++ defined_in "Constants.h"; diff --git a/core/Constants.hpp b/core/Constants.hpp index 916e4275..6af3fa4b 100644 --- a/core/Constants.hpp +++ b/core/Constants.hpp @@ -49,7 +49,8 @@ enum class DetType : ShortInt_t { kModule, kTrack, kEventHeader, - kParticle + kParticle, + kGeneric }; enum class Types : ShortInt_t { diff --git a/infra/Branch.cpp b/infra/Branch.cpp index 46c5512d..cc2fc8fa 100644 --- a/infra/Branch.cpp +++ b/infra/Branch.cpp @@ -41,6 +41,10 @@ void Branch::InitDataPtr() { data_ = temp; break; } + case DetType::kGeneric: { + data_ = new GenericDetector(config_.GetId()); + break; + } default: throw std::runtime_error("Branch type is not known!"); } } diff --git a/infra/Chain.cpp b/infra/Chain.cpp index cac31914..d31dfd16 100644 --- a/infra/Chain.cpp +++ b/infra/Chain.cpp @@ -88,6 +88,10 @@ void Chain::InitPointersToBranches(std::set names) { branch_ptr = new ModuleDetector; break; } + case DetType::kGeneric: { + branch_ptr = new GenericDetector; + break; + } } branches_.emplace(branch, branch_ptr); } diff --git a/infra/TaskManager.hpp b/infra/TaskManager.hpp index 80bbfc0b..1e61a07d 100644 --- a/infra/TaskManager.hpp +++ b/infra/TaskManager.hpp @@ -107,6 +107,10 @@ class TaskManager { AddBranch(branch->GetDataRaw(), branch->GetConfig()); break; } + case DetType::kGeneric: { + AddBranch(branch->GetDataRaw(), branch->GetConfig()); + break; + } } } @@ -126,9 +130,6 @@ class TaskManager { configuration_->GetBranchConfig(br2).GetId()); configuration_->AddMatch(match); - // if (write_mode_ == eBranchWriteMode::kCreateNewTree) { - // chain_->GetConfiguration()->AddMatch(match); - // } out_tree_->Branch((configuration_->GetMatchName(br1, br2) + ".").c_str(), &match); } diff --git a/infra/Utils.hpp b/infra/Utils.hpp index 046a4414..e0e8e67b 100644 --- a/infra/Utils.hpp +++ b/infra/Utils.hpp @@ -32,9 +32,10 @@ class Particle; class Module; class Hit; class EventHeader; +class Container; -using BranchPointer = ANALYSISTREE_UTILS_VARIANT; -using ChannelPointer = ANALYSISTREE_UTILS_VARIANT; +using BranchPointer = ANALYSISTREE_UTILS_VARIANT; +using ChannelPointer = ANALYSISTREE_UTILS_VARIANT; namespace Utils { From ca0ddab7e9a982906d46298771ff497a24f835b9 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Tue, 8 Apr 2025 14:36:44 +0200 Subject: [PATCH 3/9] avoid deprecated function --- examples/example.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example.cpp b/examples/example.cpp index b690bdf3..db6b92b2 100644 --- a/examples/example.cpp +++ b/examples/example.cpp @@ -33,7 +33,7 @@ void example(const std::string& filename, const std::string& treename){ data_header->Print(); config->Print(); - auto rec_particles = chain->GetBranch("VtxTracks"); + auto rec_particles = chain->GetBranchObject("VtxTracks"); auto rec2sim_particles = chain->GetMatching("VtxTracks", "SimParticles"); auto rec_pT = rec_particles.GetField("pT"); From 041282d32e9c7b31a34394544c2b446894854d23 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Wed, 9 Apr 2025 22:24:55 +0200 Subject: [PATCH 4/9] fix Warning: Unused class rule: UserTaskWrite --- examples/AnalysisTreeUserLinkDef.h | 4 ++-- examples/CMakeLists.txt | 2 +- examples/UserTaskRead.hpp | 2 +- examples/UserTaskWrite.hpp | 4 ++-- infra/CMakeLists.txt | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/AnalysisTreeUserLinkDef.h b/examples/AnalysisTreeUserLinkDef.h index fda60a60..759171bf 100644 --- a/examples/AnalysisTreeUserLinkDef.h +++ b/examples/AnalysisTreeUserLinkDef.h @@ -4,7 +4,7 @@ #pragma link off all functions; #pragma link C++ nestedclasses; -//#pragma link C++ class UserTaskRead++; -#pragma link C++ class UserTaskWrite++; +#pragma link C++ class UserTaskRead+; +#pragma link C++ class UserTaskWrite+; #endif diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 65e011a3..38b1692b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -13,8 +13,8 @@ message(STATUS "CMAKE_PROJECT_NAME ${CMAKE_PROJECT_NAME}") string(REPLACE ".cpp" ".hpp" HEADERS "${SOURCES}") -include_directories(${CMAKE_SOURCE_DIR}/core ${CMAKE_SOURCE_DIR}/infra ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) add_library(AnalysisTreeUser SHARED ${SOURCES} G__AnalysisTreeUser.cxx) +target_include_directories(AnalysisTreeUser PRIVATE ${CMAKE_SOURCE_DIR}/core ${CMAKE_SOURCE_DIR}/infra ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) target_compile_definitions(AnalysisTreeUser PUBLIC $<$:ANALYSISTREE_BOOST_FOUND>) diff --git a/examples/UserTaskRead.hpp b/examples/UserTaskRead.hpp index 653128ee..5d42c1d3 100644 --- a/examples/UserTaskRead.hpp +++ b/examples/UserTaskRead.hpp @@ -1,7 +1,7 @@ #ifndef ANALYSISTREE_EXAMPLES_USERTASKREAD_HPP_ #define ANALYSISTREE_EXAMPLES_USERTASKREAD_HPP_ -#include +#include class UserTaskRead : public AnalysisTree::Task { diff --git a/examples/UserTaskWrite.hpp b/examples/UserTaskWrite.hpp index 3163cb2d..16af7f08 100644 --- a/examples/UserTaskWrite.hpp +++ b/examples/UserTaskWrite.hpp @@ -1,9 +1,9 @@ #ifndef ANALYSISTREE_EXAMPLES_USERTASKWRITE_HPP_ #define ANALYSISTREE_EXAMPLES_USERTASKWRITE_HPP_ -#include #include -#include +#include +#include class UserTaskWrite : public AnalysisTree::Task { diff --git a/infra/CMakeLists.txt b/infra/CMakeLists.txt index 9b6f23c7..11ab37f8 100644 --- a/infra/CMakeLists.txt +++ b/infra/CMakeLists.txt @@ -21,8 +21,8 @@ message(STATUS "CMAKE_PROJECT_NAME ${CMAKE_PROJECT_NAME}") string(REPLACE ".cpp" ".hpp" HEADERS "${SOURCES}") list(APPEND HEADERS "VariantMagic.hpp" "ToyMC.hpp" "Utils.hpp" "BranchHashHelper.hpp" "HelperFunctions.hpp") -include_directories(${CMAKE_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) add_library(AnalysisTreeInfra SHARED ${SOURCES} G__AnalysisTreeInfra.cxx) +target_include_directories(AnalysisTreeInfra PRIVATE ${CMAKE_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) target_compile_definitions(AnalysisTreeInfra PUBLIC $<$:ANALYSISTREE_BOOST_FOUND>) From ca386c05784c948cb63e46aedf2a72f4a47f81f0 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Sat, 12 Apr 2025 20:05:43 +0200 Subject: [PATCH 5/9] init GenericContainerFiller --- infra/CMakeLists.txt | 1 + infra/GenericContainerFiller.cpp | 107 +++++++++++++++++++++++++++++++ infra/GenericContainerFiller.hpp | 73 +++++++++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 infra/GenericContainerFiller.cpp create mode 100644 infra/GenericContainerFiller.hpp diff --git a/infra/CMakeLists.txt b/infra/CMakeLists.txt index 11ab37f8..63a0ec24 100644 --- a/infra/CMakeLists.txt +++ b/infra/CMakeLists.txt @@ -13,6 +13,7 @@ set(SOURCES Branch.cpp BranchChannel.cpp AnalysisEntry.cpp + GenericContainerFiller.cpp ) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp new file mode 100644 index 00000000..f203c760 --- /dev/null +++ b/infra/GenericContainerFiller.cpp @@ -0,0 +1,107 @@ +// +// Created by oleksii on 09.04.25. +// + +#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::Run(size_t nEntries) const { + TFile* fileIn = TFile::Open(file_in_name_.c_str(), "read"); + if(fileIn == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): fileIn == nullptr"); + + TTree* treeIn = fileIn->Get(tree_in_name_.c_str()); + if(treeIn == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): treeIn == nullptr"); + + if(!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) throw std::runtime_error("GenericContainerFiller::Run(): !fields_to_ignore_.empty() && !fields_to_preserve_.empty()"); + + const size_t nTreeEntries = treeIn->GetEntries(); + const size_t nRunEntries = (nEntries<0 || nEntries>nTreeEntries) ? nTreeEntries : nEntries; + + BranchConfig branchConfig(branch_out_name_, DetType::kGeneric); + std::vector branchMap; + std::vector branchValues; + + auto lol = treeIn->GetListOfLeaves(); + const int nLeaves = lol->GetEntries(); + for(int iLeave=0; iLeaveAt(iLeave); + const std::string fieldName = leave->GetName(); + const std::string fieldType = leave->ClassName(); + if (!fields_to_ignore_.empty() && (std::find(fields_to_ignore_.begin(), fields_to_ignore_.end(), fieldName) != fields_to_ignore_.end())) continue; + if (!fields_to_preserve_.empty() && (std::find(fields_to_preserve_.begin(), fields_to_preserve_.end(), fieldName) == fields_to_preserve_.end())) continue; + if (fieldType == "TLeafF") { + branchConfig.AddField(fieldName); + } else if (fieldType == "TLeafI" || fieldType == "TLeafB" || fieldType == "TLeafS") { + branchConfig.AddField(fieldName); + } + branchMap.emplace_back((IndexMap){fieldName, fieldType, branchConfig.GetFieldId(fieldName)}); + } + branchValues.resize(branchMap.size()); + + Configuration config; + config.AddBranchConfig(branchConfig); + + for(int iV=0; iVGetBranch(branchMap.at(iV).name_.c_str()); + SetAddressFICS(branch, branchMap.at(iV), branchValues.at(iV)); + } + + GenericDetector* genericDetector = new GenericDetector(branchConfig.GetId()); + + const int entrySwitchTriggerId = entry_switch_trigger_var_name_.empty() ? -999 : DetermineFieldIdByName(branchMap, entry_switch_trigger_var_name_); + + TFile* fileOut = TFile::Open(file_out_name_.c_str(), "recreate"); + TTree* treeOut = new TTree(tree_out_name_.c_str(), "Analysis Tree"); + treeOut->SetAutoSave(0); + treeOut->Branch((branchConfig.GetName() + ".").c_str(), "AnalysisTree::GenericDetector", &genericDetector); + + int previousTriggerVar{-799}; + for(int iEntry=0; iEntryGetEntry(iEntry); + const int currentTriggerVar = entrySwitchTriggerId >= 0 ? branchValues.at(entrySwitchTriggerId).int_ : previousTriggerVar; + auto isNewATEntry = [&]() {return iEntry == 0 || + (currentTriggerVar != previousTriggerVar) || + (n_channels_per_entry_ >= 0 && iEntry % n_channels_per_entry_ == 0); }; + + if(isNewATEntry()) genericDetector->ClearChannels(); + auto& channel = genericDetector->AddChannel(config.GetBranchConfig(genericDetector->GetId())); + SetFieldsFICS(branchMap, channel, branchValues); + if(isNewATEntry()) treeOut->Fill(); + } // iEntry + + fileOut->cd(); + config.Write("Configuration"); + treeOut->Write(); + fileOut->Close(); + fileIn->Close(); +} + +int GenericContainerFiller::DetermineFieldIdByName(const std::vector& iMap, const std::string& name) { + auto distance = std::distance(iMap.begin(),std::find_if(iMap.begin(), iMap.end(), [&name](const IndexMap& p) { return p.name_ == name; })); + if(distance == iMap.size()) throw std::runtime_error("DetermineFieldIdByName(): name " + name + " is missing"); + return distance; +} + +void GenericContainerFiller::SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc) { + if (imap.field_type_ == "TLeafF") branch->SetAddress(&ficc.float_); + else if(imap.field_type_ == "TLeafI") branch->SetAddress(&ficc.int_); + else if(imap.field_type_ == "TLeafB") branch->SetAddress(&ficc.char_); + else if(imap.field_type_ == "TLeafS") branch->SetAddress(&ficc.short_); + else throw std::runtime_error("GenericContainerFiller::SetAddressFICS(): unsupported filed type " + imap.field_type_); +} + +void GenericContainerFiller::SetFieldsFICS(const std::vector& imap, Container& container, const std::vector& ficc) { + for(int iV=0; iV(ficc.at(iV).char_), imap.at(iV).index_); + else if(imap.at(iV).field_type_ == "TLeafS") container.SetField(static_cast(ficc.at(iV).short_), imap.at(iV).index_); + else throw std::runtime_error("GenericContainerFiller::SetFieldsFICS(): unsupported filed type " + imap.at(iV).field_type_); + } +} \ No newline at end of file diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp new file mode 100644 index 00000000..cc5b5423 --- /dev/null +++ b/infra/GenericContainerFiller.hpp @@ -0,0 +1,73 @@ +// +// Created by oleksii on 09.04.25. +// + +#ifndef ANALYSISTREE_GENERICCONTAINERFILLER_HPP +#define ANALYSISTREE_GENERICCONTAINERFILLER_HPP + +#include "AnalysisTask.hpp" + +#include +#include + +struct IndexMap { + std::string name_; + std::string field_type_; + short index_; +}; + +struct FICS { // FICS stands for float, int, char, short + float float_{-999.f}; + int int_{-999}; + char char_{static_cast(-999)}; + short short_{static_cast(-999)}; +}; + +namespace AnalysisTree { + +class GenericContainerFiller { + public: + GenericContainerFiller() = delete; + explicit GenericContainerFiller(std::string fileInName, std::string treeInName="pTree"); + virtual ~GenericContainerFiller() = default; + + void SetOutputFileName(const std::string& name) { file_out_name_ = name; } + void SetOutputTreeName(const std::string& name) { tree_out_name_ = name; } + void SetOutputBranchName(const std::string& name) { branch_out_name_ = name; } + + void SetFieldsToIgnore(const std::vector& fields) { fields_to_ignore_ = fields; } + void SetFieldsToPreserve(const std::vector& fields) { fields_to_preserve_ = fields; } + + void SetEntrySwitchTriggerVarName(const std::string& name) { entry_switch_trigger_var_name_ = name; } + + void SetNChannelsPerEntry(int n) { n_channels_per_entry_ = n; } + + void Run(size_t nEntries=-1) const; + + protected: + static int DetermineFieldIdByName(const std::vector& iMap, const std::string& name); + static void SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc); + static void SetFieldsFICS(const std::vector& imap, Container& container, const std::vector& ficc); + + std::string file_in_name_; + std::string tree_in_name_; + + std::string file_out_name_{"AnalysisTree.root"}; + std::string tree_out_name_{"aTree"}; + std::string branch_out_name_{"PlainBranch"}; + + // variable, change of value of which triggers switch to a new AT event + std::string entry_switch_trigger_var_name_{""}; + + // if entry_switch_trigger_var_name_ is not empty, this field does not matter + // if entry_switch_trigger_var_name_ is empty, sets how many AT channels + // will constitute a single AT entry (event) + int n_channels_per_entry_{-1}; + + std::vector fields_to_ignore_{}; + std::vector fields_to_preserve_{}; + + +}; +} +#endif//ANALYSISTREE_GENERICCONTAINERFILLER_HPP From 69ffc1e18bbeb34781df9aa6707d141ad1aab3b6 Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Sat, 12 Apr 2025 23:49:22 +0200 Subject: [PATCH 6/9] dev GenericContainerFiller --- infra/GenericContainerFiller.cpp | 94 ++++++++++++++++++-------------- infra/GenericContainerFiller.hpp | 43 ++++++++++++--- 2 files changed, 89 insertions(+), 48 deletions(-) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index f203c760..abb830c7 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -4,30 +4,23 @@ #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::Run(size_t nEntries) const { - TFile* fileIn = TFile::Open(file_in_name_.c_str(), "read"); - if(fileIn == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): fileIn == nullptr"); +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"); - TTree* treeIn = fileIn->Get(tree_in_name_.c_str()); - if(treeIn == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): treeIn == nullptr"); + tree_in_ = file_in_->Get(tree_in_name_.c_str()); + if(tree_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): tree_in_ == nullptr"); if(!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) throw std::runtime_error("GenericContainerFiller::Run(): !fields_to_ignore_.empty() && !fields_to_preserve_.empty()"); - const size_t nTreeEntries = treeIn->GetEntries(); - const size_t nRunEntries = (nEntries<0 || nEntries>nTreeEntries) ? nTreeEntries : nEntries; - BranchConfig branchConfig(branch_out_name_, DetType::kGeneric); - std::vector branchMap; - std::vector branchValues; - auto lol = treeIn->GetListOfLeaves(); + auto lol = tree_in_->GetListOfLeaves(); const int nLeaves = lol->GetEntries(); for(int iLeave=0; iLeaveAt(iLeave); @@ -40,46 +33,65 @@ void GenericContainerFiller::Run(size_t nEntries) const { } else if (fieldType == "TLeafI" || fieldType == "TLeafB" || fieldType == "TLeafS") { branchConfig.AddField(fieldName); } - branchMap.emplace_back((IndexMap){fieldName, fieldType, branchConfig.GetFieldId(fieldName)}); + branch_map_.emplace_back((IndexMap){fieldName, fieldType, branchConfig.GetFieldId(fieldName)}); } - branchValues.resize(branchMap.size()); + branch_values_.resize(branch_map_.size()); + + config_.AddBranchConfig(branchConfig); + + for(int iV=0; iVGetBranch(branch_map_.at(iV).name_.c_str()); + SetAddressFICS(branch, branch_map_.at(iV), branch_values_.at(iV)); + } + + generic_detector_ = new GenericDetector(branchConfig.GetId()); - Configuration config; - config.AddBranchConfig(branchConfig); + file_out_ = TFile::Open(file_out_name_.c_str(), "recreate"); + tree_out_ = new TTree(tree_out_name_.c_str(), "Analysis Tree"); + tree_out_->SetAutoSave(0); + tree_out_->Branch((branchConfig.GetName() + ".").c_str(), "AnalysisTree::GenericDetector", &generic_detector_); - for(int iV=0; iVGetBranch(branchMap.at(iV).name_.c_str()); - SetAddressFICS(branch, branchMap.at(iV), branchValues.at(iV)); + entry_switch_trigger_id_ = entry_switch_trigger_var_name_.empty() ? -999 : DetermineFieldIdByName(branch_map_, entry_switch_trigger_var_name_); +} + +int GenericContainerFiller::Exec(int iEntry, int previousTriggerVar) { + tree_in_->GetEntry(iEntry); + const int currentTriggerVar = entry_switch_trigger_id_ >= 0 ? branch_values_.at(entry_switch_trigger_id_).get() : previousTriggerVar; + auto isNewATEntry = [&]() {return iEntry == 0 || + (currentTriggerVar != previousTriggerVar) || + (n_channels_per_entry_ >= 0 && iEntry % n_channels_per_entry_ == 0); }; + + if(isNewATEntry()) { + if(iEntry != 0) tree_out_->Fill(); + generic_detector_->ClearChannels(); } + auto& channel = generic_detector_->AddChannel(config_.GetBranchConfig(generic_detector_->GetId())); + SetFieldsFICS(branch_map_, channel, branch_values_); - GenericDetector* genericDetector = new GenericDetector(branchConfig.GetId()); + return currentTriggerVar; +} - const int entrySwitchTriggerId = entry_switch_trigger_var_name_.empty() ? -999 : DetermineFieldIdByName(branchMap, entry_switch_trigger_var_name_); +void GenericContainerFiller::Finish() { + file_out_->cd(); + config_.Write("Configuration"); + tree_out_->Write(); + file_out_->Close(); + file_in_->Close(); +} + +void GenericContainerFiller::Run(int nEntries) { + Init(); - TFile* fileOut = TFile::Open(file_out_name_.c_str(), "recreate"); - TTree* treeOut = new TTree(tree_out_name_.c_str(), "Analysis Tree"); - treeOut->SetAutoSave(0); - treeOut->Branch((branchConfig.GetName() + ".").c_str(), "AnalysisTree::GenericDetector", &genericDetector); + const size_t nTreeEntries = tree_in_->GetEntries(); + const size_t nRunEntries = (nEntries<0 || nEntries>nTreeEntries) ? nTreeEntries : nEntries; int previousTriggerVar{-799}; for(int iEntry=0; iEntryGetEntry(iEntry); - const int currentTriggerVar = entrySwitchTriggerId >= 0 ? branchValues.at(entrySwitchTriggerId).int_ : previousTriggerVar; - auto isNewATEntry = [&]() {return iEntry == 0 || - (currentTriggerVar != previousTriggerVar) || - (n_channels_per_entry_ >= 0 && iEntry % n_channels_per_entry_ == 0); }; - - if(isNewATEntry()) genericDetector->ClearChannels(); - auto& channel = genericDetector->AddChannel(config.GetBranchConfig(genericDetector->GetId())); - SetFieldsFICS(branchMap, channel, branchValues); - if(isNewATEntry()) treeOut->Fill(); + previousTriggerVar = Exec(iEntry, previousTriggerVar); } // iEntry + tree_out_->Fill(); - fileOut->cd(); - config.Write("Configuration"); - treeOut->Write(); - fileOut->Close(); - fileIn->Close(); + Finish(); } int GenericContainerFiller::DetermineFieldIdByName(const std::vector& iMap, const std::string& name) { diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index cc5b5423..1783c161 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -5,7 +5,12 @@ #ifndef ANALYSISTREE_GENERICCONTAINERFILLER_HPP #define ANALYSISTREE_GENERICCONTAINERFILLER_HPP -#include "AnalysisTask.hpp" +#include "Configuration.hpp" +#include "Container.hpp" +#include "Detector.hpp" + +#include +#include #include #include @@ -17,10 +22,18 @@ struct IndexMap { }; struct FICS { // FICS stands for float, int, char, short - float float_{-999.f}; - int int_{-999}; - char char_{static_cast(-999)}; - short short_{static_cast(-999)}; + float float_{-199.f}; + int int_{-199}; + char char_{static_cast(-199)}; + short short_{static_cast(-199)}; + + float get() { + 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_); + if(short_ != static_cast(-199)) return static_cast(short_); + throw std::runtime_error("GenericContainerFiller, FICS::get(): none of values initialized"); + } }; namespace AnalysisTree { @@ -42,12 +55,16 @@ class GenericContainerFiller { void SetNChannelsPerEntry(int n) { n_channels_per_entry_ = n; } - void Run(size_t nEntries=-1) const; + void Run(int nEntries=-1); protected: + void Init(); + int Exec(int iEntry, int previousTriggerVar); + void Finish(); + static int DetermineFieldIdByName(const std::vector& iMap, const std::string& name); static void SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc); - static void SetFieldsFICS(const std::vector& imap, Container& container, const std::vector& ficc); + static void SetFieldsFICS(const std::vector& imap, AnalysisTree::Container& container, const std::vector& ficc); std::string file_in_name_; std::string tree_in_name_; @@ -56,9 +73,21 @@ class GenericContainerFiller { std::string tree_out_name_{"aTree"}; std::string branch_out_name_{"PlainBranch"}; + TFile* file_in_{nullptr}; + TTree* tree_in_{nullptr}; + TFile* file_out_{nullptr}; + TTree* tree_out_{nullptr}; + + AnalysisTree::Configuration config_; + AnalysisTree::GenericDetector* generic_detector_{nullptr}; + std::vector branch_map_; + std::vector branch_values_; + // variable, change of value of which triggers switch to a new AT event std::string entry_switch_trigger_var_name_{""}; + int entry_switch_trigger_id_{-1}; + // if entry_switch_trigger_var_name_ is not empty, this field does not matter // if entry_switch_trigger_var_name_ is empty, sets how many AT channels // will constitute a single AT entry (event) From 8d0561bb6043be56b2a7d6b0a836bccec57ea22c Mon Sep 17 00:00:00 2001 From: Oleksii Lubynets Date: Sat, 12 Apr 2025 23:50:02 +0200 Subject: [PATCH 7/9] add StringToBool to HelperFunctions --- infra/HelperFunctions.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/infra/HelperFunctions.hpp b/infra/HelperFunctions.hpp index 6efd5fa2..abfc12a4 100644 --- a/infra/HelperFunctions.hpp +++ b/infra/HelperFunctions.hpp @@ -50,5 +50,11 @@ inline std::vector CreateEqualCuts(const std::vector Date: Mon, 14 Apr 2025 11:19:10 +0200 Subject: [PATCH 8/9] apply clang-format --- infra/GenericContainerFiller.cpp | 62 +++++++++++++++++--------------- infra/GenericContainerFiller.hpp | 18 +++++----- infra/HelperFunctions.hpp | 8 +++-- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index abb830c7..e51881ca 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -6,23 +6,23 @@ using namespace AnalysisTree; -GenericContainerFiller::GenericContainerFiller(std::string fileInName, std::string treeInName) : file_in_name_(std::move(fileInName)), - tree_in_name_(std::move(treeInName)) {} +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"); + if (file_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): file_in_ == nullptr"); tree_in_ = file_in_->Get(tree_in_name_.c_str()); - if(tree_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): tree_in_ == nullptr"); + if (tree_in_ == nullptr) throw std::runtime_error("GenericContainerFiller::Run(): tree_in_ == nullptr"); - if(!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) throw std::runtime_error("GenericContainerFiller::Run(): !fields_to_ignore_.empty() && !fields_to_preserve_.empty()"); + if (!fields_to_ignore_.empty() && !fields_to_preserve_.empty()) throw std::runtime_error("GenericContainerFiller::Run(): !fields_to_ignore_.empty() && !fields_to_preserve_.empty()"); BranchConfig branchConfig(branch_out_name_, DetType::kGeneric); auto lol = tree_in_->GetListOfLeaves(); const int nLeaves = lol->GetEntries(); - for(int iLeave=0; iLeaveAt(iLeave); const std::string fieldName = leave->GetName(); const std::string fieldType = leave->ClassName(); @@ -39,7 +39,7 @@ void GenericContainerFiller::Init() { config_.AddBranchConfig(branchConfig); - for(int iV=0; iVGetBranch(branch_map_.at(iV).name_.c_str()); SetAddressFICS(branch, branch_map_.at(iV), branch_values_.at(iV)); } @@ -57,12 +57,10 @@ void GenericContainerFiller::Init() { int GenericContainerFiller::Exec(int iEntry, int previousTriggerVar) { tree_in_->GetEntry(iEntry); const int currentTriggerVar = entry_switch_trigger_id_ >= 0 ? branch_values_.at(entry_switch_trigger_id_).get() : previousTriggerVar; - auto isNewATEntry = [&]() {return iEntry == 0 || - (currentTriggerVar != previousTriggerVar) || - (n_channels_per_entry_ >= 0 && iEntry % n_channels_per_entry_ == 0); }; + auto isNewATEntry = [&]() { return iEntry == 0 || (currentTriggerVar != previousTriggerVar) || (n_channels_per_entry_ >= 0 && iEntry % n_channels_per_entry_ == 0); }; - if(isNewATEntry()) { - if(iEntry != 0) tree_out_->Fill(); + if (isNewATEntry()) { + if (iEntry != 0) tree_out_->Fill(); generic_detector_->ClearChannels(); } auto& channel = generic_detector_->AddChannel(config_.GetBranchConfig(generic_detector_->GetId())); @@ -83,37 +81,45 @@ void GenericContainerFiller::Run(int nEntries) { Init(); const size_t nTreeEntries = tree_in_->GetEntries(); - const size_t nRunEntries = (nEntries<0 || nEntries>nTreeEntries) ? nTreeEntries : nEntries; + const size_t nRunEntries = (nEntries < 0 || nEntries > nTreeEntries) ? nTreeEntries : nEntries; int previousTriggerVar{-799}; - for(int iEntry=0; iEntryFill(); Finish(); } int GenericContainerFiller::DetermineFieldIdByName(const std::vector& iMap, const std::string& name) { - auto distance = std::distance(iMap.begin(),std::find_if(iMap.begin(), iMap.end(), [&name](const IndexMap& p) { return p.name_ == name; })); - if(distance == iMap.size()) throw std::runtime_error("DetermineFieldIdByName(): name " + name + " is missing"); + auto distance = std::distance(iMap.begin(), std::find_if(iMap.begin(), iMap.end(), [&name](const IndexMap& p) { return p.name_ == name; })); + if (distance == iMap.size()) throw std::runtime_error("DetermineFieldIdByName(): name " + name + " is missing"); return distance; } void GenericContainerFiller::SetAddressFICS(TBranch* branch, const IndexMap& imap, FICS& ficc) { - if (imap.field_type_ == "TLeafF") branch->SetAddress(&ficc.float_); - else if(imap.field_type_ == "TLeafI") branch->SetAddress(&ficc.int_); - else if(imap.field_type_ == "TLeafB") branch->SetAddress(&ficc.char_); - else if(imap.field_type_ == "TLeafS") branch->SetAddress(&ficc.short_); - else throw std::runtime_error("GenericContainerFiller::SetAddressFICS(): unsupported filed type " + imap.field_type_); + if (imap.field_type_ == "TLeafF") branch->SetAddress(&ficc.float_); + else if (imap.field_type_ == "TLeafI") + branch->SetAddress(&ficc.int_); + else if (imap.field_type_ == "TLeafB") + branch->SetAddress(&ficc.char_); + else if (imap.field_type_ == "TLeafS") + branch->SetAddress(&ficc.short_); + else + throw std::runtime_error("GenericContainerFiller::SetAddressFICS(): unsupported filed type " + imap.field_type_); } void GenericContainerFiller::SetFieldsFICS(const std::vector& imap, Container& container, const std::vector& ficc) { - for(int iV=0; iV(ficc.at(iV).char_), imap.at(iV).index_); - else if(imap.at(iV).field_type_ == "TLeafS") container.SetField(static_cast(ficc.at(iV).short_), imap.at(iV).index_); - else throw std::runtime_error("GenericContainerFiller::SetFieldsFICS(): unsupported filed type " + imap.at(iV).field_type_); + for (int iV = 0; iV < ficc.size(); iV++) { + if (imap.at(iV).field_type_ == "TLeafF") container.SetField(ficc.at(iV).float_, imap.at(iV).index_); + else if (imap.at(iV).field_type_ == "TLeafI") + container.SetField(ficc.at(iV).int_, imap.at(iV).index_); + else if (imap.at(iV).field_type_ == "TLeafB") + container.SetField(static_cast(ficc.at(iV).char_), imap.at(iV).index_); + else if (imap.at(iV).field_type_ == "TLeafS") + container.SetField(static_cast(ficc.at(iV).short_), imap.at(iV).index_); + else + throw std::runtime_error("GenericContainerFiller::SetFieldsFICS(): unsupported filed type " + imap.at(iV).field_type_); } } \ No newline at end of file diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index 1783c161..b7a5bbda 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -21,17 +21,17 @@ struct IndexMap { short index_; }; -struct FICS { // FICS stands for float, int, char, short +struct FICS {// FICS stands for float, int, char, short float float_{-199.f}; int int_{-199}; char char_{static_cast(-199)}; short short_{static_cast(-199)}; float get() { - 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_); - if(short_ != static_cast(-199)) return static_cast(short_); + 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_); + if (short_ != static_cast(-199)) return static_cast(short_); throw std::runtime_error("GenericContainerFiller, FICS::get(): none of values initialized"); } }; @@ -41,7 +41,7 @@ namespace AnalysisTree { class GenericContainerFiller { public: GenericContainerFiller() = delete; - explicit GenericContainerFiller(std::string fileInName, std::string treeInName="pTree"); + explicit GenericContainerFiller(std::string fileInName, std::string treeInName = "pTree"); virtual ~GenericContainerFiller() = default; void SetOutputFileName(const std::string& name) { file_out_name_ = name; } @@ -55,7 +55,7 @@ class GenericContainerFiller { void SetNChannelsPerEntry(int n) { n_channels_per_entry_ = n; } - void Run(int nEntries=-1); + void Run(int nEntries = -1); protected: void Init(); @@ -95,8 +95,6 @@ class GenericContainerFiller { std::vector fields_to_ignore_{}; std::vector fields_to_preserve_{}; - - }; -} +}// namespace AnalysisTree #endif//ANALYSISTREE_GENERICCONTAINERFILLER_HPP diff --git a/infra/HelperFunctions.hpp b/infra/HelperFunctions.hpp index abfc12a4..6b6caaff 100644 --- a/infra/HelperFunctions.hpp +++ b/infra/HelperFunctions.hpp @@ -51,9 +51,11 @@ inline std::vector CreateEqualCuts(const std::vector Date: Tue, 22 Apr 2025 14:33:06 +0200 Subject: [PATCH 9/9] revert include_directories() due to back compatibility --- examples/CMakeLists.txt | 5 +++-- infra/CMakeLists.txt | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 38b1692b..d04d3744 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -13,8 +13,8 @@ message(STATUS "CMAKE_PROJECT_NAME ${CMAKE_PROJECT_NAME}") string(REPLACE ".cpp" ".hpp" HEADERS "${SOURCES}") -add_library(AnalysisTreeUser SHARED ${SOURCES} G__AnalysisTreeUser.cxx) -target_include_directories(AnalysisTreeUser PRIVATE ${CMAKE_SOURCE_DIR}/core ${CMAKE_SOURCE_DIR}/infra ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) +include_directories(${CMAKE_SOURCE_DIR}/core ${CMAKE_SOURCE_DIR}/infra ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) +add_library(AnalysisTreeUser SHARED ${SOURCES}) target_compile_definitions(AnalysisTreeUser PUBLIC $<$:ANALYSISTREE_BOOST_FOUND>) @@ -23,6 +23,7 @@ ROOT_GENERATE_DICTIONARY(G__AnalysisTreeUser ${HEADERS} OPTIONS -I${CMAKE_BINARY_DIR}/include $<$:-DANALYSISTREE_BOOST_FOUND> + MODULE AnalysisTreeUser ) target_link_libraries(AnalysisTreeUser PUBLIC diff --git a/infra/CMakeLists.txt b/infra/CMakeLists.txt index 63a0ec24..9d84a270 100644 --- a/infra/CMakeLists.txt +++ b/infra/CMakeLists.txt @@ -22,8 +22,8 @@ message(STATUS "CMAKE_PROJECT_NAME ${CMAKE_PROJECT_NAME}") string(REPLACE ".cpp" ".hpp" HEADERS "${SOURCES}") list(APPEND HEADERS "VariantMagic.hpp" "ToyMC.hpp" "Utils.hpp" "BranchHashHelper.hpp" "HelperFunctions.hpp") -add_library(AnalysisTreeInfra SHARED ${SOURCES} G__AnalysisTreeInfra.cxx) -target_include_directories(AnalysisTreeInfra PRIVATE ${CMAKE_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) +include_directories(${CMAKE_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR} $<$:${Boost_INCLUDE_DIRS}>) +add_library(AnalysisTreeInfra SHARED ${SOURCES}) target_compile_definitions(AnalysisTreeInfra PUBLIC $<$:ANALYSISTREE_BOOST_FOUND>) @@ -32,6 +32,7 @@ ROOT_GENERATE_DICTIONARY(G__AnalysisTreeInfra ${HEADERS} OPTIONS -I${CMAKE_BINARY_DIR}/include $<$:-DANALYSISTREE_BOOST_FOUND> + MODULE AnalysisTreeInfra ) target_link_libraries(AnalysisTreeInfra PUBLIC