diff --git a/README.md b/README.md index 4e5454da..e08e3537 100644 --- a/README.md +++ b/README.md @@ -29,12 +29,12 @@ Basic objects are:
- Hit (position and signal)
- Module (id and signal)
Four mentioned objects are so-called channelized: -they contain set of channels (namely tracks, prticles, hits or modules) in each event
+they contain set of channels (namely tracks, particles, hits or modules) in each event
- EventHeader (vertex position) - contains information related to specific event
- DataHeader - contains common information for all events
- Matching - establishes a correspondence between channels in channelized objects (e.g. between simulated particle and reconstructed track). -Additionaly to mandatory information specified in round brackets (a.k.a. "default fileds"), each object can contain any number of integer, floating or boolean fields (a.k.a. "user-defined fields"). +Additionally to mandatory information specified in round brackets (a.k.a. "default fields"), each object can contain any number of integer, floating or boolean fields (a.k.a. "user-defined fields"). Information about all fields in all branches is stored in Configuration object. ## Installation diff --git a/core/BranchConfig.hpp b/core/BranchConfig.hpp index e11ecdc3..2ca97c29 100644 --- a/core/BranchConfig.hpp +++ b/core/BranchConfig.hpp @@ -113,7 +113,7 @@ class BranchConfig : public VectorConfig, public VectorConfig, publi } template void AddFields(const std::vector& names, const std::string& title = "") { - for (auto& n : names) { + for (const auto& n : names) { GuaranteeFieldNameVacancy(n); } VectorConfig::AddFields(names, title); @@ -127,7 +127,7 @@ class BranchConfig : public VectorConfig, public VectorConfig, publi void RemoveField(const std::string& name); void RemoveFields(const std::vector& names) { - for (auto& n : names) { + for (const auto& n : names) { RemoveField(n); } } diff --git a/core/Configuration.cpp b/core/Configuration.cpp index 36eba277..e8fc0ffc 100644 --- a/core/Configuration.cpp +++ b/core/Configuration.cpp @@ -65,7 +65,7 @@ BranchConfig& Configuration::GetBranchConfig(const std::string& name) { } const BranchConfig& Configuration::GetBranchConfig(const std::string& name) const { - for (auto& branch : branches_) { + for (const auto& branch : branches_) { if (branch.second.GetName() == name) return branch.second; } @@ -187,7 +187,7 @@ void Configuration::RemoveBranchConfig(const std::string& branchname) { std::vector Configuration::GetMatchesOfBranch(const std::string& branchname) const { std::vector matches{}; - for (auto& ma : matches_) { + for (const auto& ma : matches_) { if (ma.GetFirstBranchName() == branchname || ma.GetSecondBranchName() == branchname) matches.emplace_back(ma.GetDataBranchName()); } diff --git a/core/Configuration.hpp b/core/Configuration.hpp index 4cc2d7e4..1f180d99 100644 --- a/core/Configuration.hpp +++ b/core/Configuration.hpp @@ -102,7 +102,7 @@ class Configuration : public TObject { static MatchingIndex MakeMatchingIndex(const std::vector& matches) { MatchingIndex result; - for (auto& match : matches) { + for (const auto& match : matches) { std::array map_key{match.GetFirstBranchName(), match.GetSecondBranchName()}; auto emplace_result = result.emplace(map_key, match.GetDataBranchName()); if (!emplace_result.second) { @@ -114,7 +114,7 @@ class Configuration : public TObject { static std::vector MakeMatchConfigsFromIndex(const MatchingIndex& matching_index) { std::vector result; - for (auto& matching_index_element : matching_index) { + for (const auto& matching_index_element : matching_index) { result.emplace_back(matching_index_element.first[0], matching_index_element.first[1], matching_index_element.second); @@ -130,10 +130,10 @@ class Configuration : public TObject { * @param other */ void Merge(const Configuration& other) { - for (auto& other_branch : other.branches_) { + for (const auto& other_branch : other.branches_) { const auto other_id = other_branch.second.GetId(); const auto other_name = other_branch.second.GetName(); - for (auto& local_branch : branches_) { + for (const auto& local_branch : branches_) { if (other_id == local_branch.second.GetId()) { throw std::runtime_error("Configurations contain branches with the same id-s"); } diff --git a/infra/AnalysisEntry.cpp b/infra/AnalysisEntry.cpp index 69808c1d..e784132a 100644 --- a/infra/AnalysisEntry.cpp +++ b/infra/AnalysisEntry.cpp @@ -9,7 +9,7 @@ namespace AnalysisTree { AnalysisEntry::~AnalysisEntry() { - for (auto& br : branches_) { + for (const auto& br : branches_) { delete br.first; } } @@ -45,7 +45,7 @@ bool AnalysisEntry::ApplyCutOnBranches(std::vector& br, std::vect id_vec.emplace_back(br.at(i)->GetId()); } bool result = ok && (!cuts_ || cuts_->Apply(bch_vec, id_vec)); - for (auto& bv : bch_vec) { + for (const auto& bv : bch_vec) { delete bv; } return result; @@ -77,7 +77,7 @@ double AnalysisEntry::FillVariable(const Variable& var, std::vectorGetId()); } double result = var.GetValue(bch_vec, id_vec); - for (auto& bv : bch_vec) { + for (const auto& bv : bch_vec) { delete bv; } return result; @@ -116,7 +116,7 @@ void AnalysisEntry::FillFromEveHeaders() { br_vec.reserve(branches_.size()); cuts_vec.reserve(branches_.size()); id_vec.reserve(branches_.size()); - for (auto& br : branches_) { + for (const auto& br : branches_) { br_vec.emplace_back(br.first); cuts_vec.emplace_back(br.second); id_vec.emplace_back(0); @@ -154,7 +154,7 @@ void AnalysisEntry::FillFromOneChannalizedBranch() { br_vec.emplace_back(br.first); cuts_vec.emplace_back(br.second); } - for (auto& ehi : eve_header_indices_) { + for (const auto& ehi : eve_header_indices_) { id_vec.at(ehi) = 0; } @@ -195,7 +195,7 @@ void AnalysisEntry::FillFromTwoChannalizedBranches() { br_vec.emplace_back(br.first); cuts_vec.emplace_back(br.second); } - for (auto& ehi : eve_header_indices_) { + for (const auto& ehi : eve_header_indices_) { id_vec.at(ehi) = 0; } @@ -216,7 +216,7 @@ void AnalysisEntry::FillFromTwoChannalizedBranches() { } void AnalysisEntry::FillBranchNames() { - for (auto& var : vars_) { + for (const auto& var : vars_) { const auto& br = var.GetBranches(); branch_names_.insert(br.begin(), br.end()); } @@ -236,7 +236,7 @@ void AnalysisEntry::Init(const Configuration& conf, const std::map& map, AnalysisTree::Types type) { - for (auto& element : map) { + for (const auto& element : map) { auto field_name = element.first; if (config_.HasField(field_name)) { std::cout << "Field '" << field_name << "' already exists" << std::endl; @@ -190,7 +190,7 @@ void Branch::CreateMapping(const Branch* other, std::string branch_name_prefix) std::cout << "New cached mapping " << other->config_.GetName() << " --> " << config_.GetName() << std::endl; FieldsMapping fields_mapping; - for (auto& field_name_other : other->GetFieldNames()) { + for (const auto& field_name_other : other->GetFieldNames()) { std::string field_name_target = branch_name_prefix + field_name_other; if (!config_.HasField(field_name_target)) { continue; } fields_mapping.field_pairs.emplace_back(other->GetField(field_name_other), GetField(field_name_target)); @@ -208,7 +208,7 @@ void Branch::UpdateConfigHash() { std::vector Branch::GetFieldNames() const { std::vector result; auto fill_vector_from_map = [&result](const std::map& fields_map) -> void { - for (auto& element : fields_map) { + for (const auto& element : fields_map) { result.push_back(element.first); } }; diff --git a/infra/BranchChannel.cpp b/infra/BranchChannel.cpp index 01856cde..a1701f44 100644 --- a/infra/BranchChannel.cpp +++ b/infra/BranchChannel.cpp @@ -35,7 +35,7 @@ void BranchChannel::CopyContent(const BranchChannel& other, std::string branch_n /* Eval mapping */ const auto& field_pairs = mapping_it->second.field_pairs; - for (auto& field_pair /* src : dst */ : field_pairs) { + for (const auto& field_pair /* src : dst */ : field_pairs) { this->SetValue(field_pair.second, other.Value(field_pair.first)); } } diff --git a/infra/BranchHashHelper.hpp b/infra/BranchHashHelper.hpp index 1e9c5b61..7a13012f 100644 --- a/infra/BranchHashHelper.hpp +++ b/infra/BranchHashHelper.hpp @@ -19,7 +19,7 @@ inline std::size_t BranchConfigHasher(const AnalysisTree::BranchConfig& config) hash_combine(hash, static_cast(config.GetType())); auto hash_fields = [&hash](const std::map& fields_map, Type field_type) { - for (auto& field : fields_map) { + for (const auto& field : fields_map) { hash_combine(hash, field.first, field.second.id_, static_cast(field_type)); } }; diff --git a/infra/Chain.cpp b/infra/Chain.cpp index d31dfd16..5ab1dea0 100644 --- a/infra/Chain.cpp +++ b/infra/Chain.cpp @@ -113,7 +113,7 @@ void Chain::InitPointersToBranches(std::set names) { if (CheckBranchExistence(branch.first) == 1) ANALYSISTREE_UTILS_VISIT(set_branch_address_struct(this, branch.first), branch.second); else if (CheckBranchExistence(branch.first) == 2) - ANALYSISTREE_UTILS_VISIT(set_branch_address_struct(this, (branch.first + ".").c_str()), branch.second); + ANALYSISTREE_UTILS_VISIT(set_branch_address_struct(this, branch.first + "."), branch.second); else throw std::runtime_error("AnalysisTree::InitPointersToBranches - Branch " + branch.first + " does not exist"); } @@ -225,7 +225,7 @@ std::vector Chain::GetTChains() { int Chain::CheckBranchExistence(const std::string& branchname) { auto v_chains = this->GetTChains(); - for (auto& ch : v_chains) { + for (const auto& ch : v_chains) { auto* lob = ch->GetListOfBranches(); const int Nbranches = lob->GetEntries(); for (int i = 0; i < Nbranches; i++) { diff --git a/infra/Cuts.cpp b/infra/Cuts.cpp index 1a209336..9692024a 100644 --- a/infra/Cuts.cpp +++ b/infra/Cuts.cpp @@ -83,7 +83,7 @@ void Cuts::AddCut(const SimpleCut& cut) { } void Cuts::AddCuts(const std::vector& cuts) { - for (auto& cut : cuts) { + for (const auto& cut : cuts) { AddCut(cut); } } diff --git a/infra/HelperFunctions.hpp b/infra/HelperFunctions.hpp index 996a0d13..800c5b71 100644 --- a/infra/HelperFunctions.hpp +++ b/infra/HelperFunctions.hpp @@ -3,6 +3,8 @@ #include "SimpleCut.hpp" +#include + #include #include #include @@ -101,5 +103,14 @@ inline std::vector MergeVectors(const std::vector& vec1, const std::vector return MergeVectors(vec1, MergeVectors(vec2, args...)); } +template +inline T* GetObjectWithNullptrCheck(TFile* fileIn, const std::string& objectName) { + T* ptr = fileIn->Get(objectName.c_str()); + if (ptr == nullptr) { + throw std::runtime_error("HelperFunctions::GetObjectWithNullptrCheck() - object " + objectName + " in file " + fileIn->GetName() + " is missing"); + } + return ptr; +} + }// namespace HelperFunctions #endif// ANALYSISTREE_INFRA_HELPER_FUNCTIONS_HPP diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index 10c4e1dd..f87f37d0 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -19,7 +19,7 @@ void PlainTreeFiller::SetFieldsToIgnore(const std::vector& fields_t if (branch_name_.empty()) { throw std::runtime_error("PlainTreeFiller::SetFieldsToIgnore() must be called after PlainTreeFiller::AddBranch()\n"); } - for (auto& fti : fields_to_ignore) { + for (const auto& fti : fields_to_ignore) { fields_to_ignore_.emplace_back((branch_name_ + "." + fti).c_str()); } } @@ -28,19 +28,48 @@ void PlainTreeFiller::SetFieldsToPreserve(const std::vector& fields if (branch_name_.empty()) { throw std::runtime_error("PlainTreeFiller::SetFieldsToPreserve() must be called after PlainTreeFiller::AddBranch()\n"); } - for (auto& fti : fields_to_preserve) { + for (const auto& fti : fields_to_preserve) { fields_to_preserve_.emplace_back((branch_name_ + "." + fti).c_str()); } } +void PlainTreeFiller::SetFieldsToRename(const std::vector>& fields_to_rename) { + if (branch_name_.empty()) { + throw std::runtime_error("PlainTreeFiller::SetFieldsToRename() must be called after PlainTreeFiller::AddBranch()\n"); + } + for (const auto& ftr : fields_to_rename) { + fields_to_rename_.emplace((branch_name_ + "." + ftr.first).c_str(), (branch_name_ + "." + ftr.second).c_str()); + } +} + +void PlainTreeFiller::CheckIgnorePreserveRenameFields(const std::vector& leafNames) const { + for (const auto& fti : fields_to_ignore_) { + if (std::find(leafNames.begin(), leafNames.end(), fti) == leafNames.end()) { + std::cout << "WARNING PlainTreeFiller::CheckIgnorePreserveRenameFields(): field " << fti << " is set to be ignored, but it is absent among input fields\n"; + } + } + + for (const auto& ftp : fields_to_preserve_) { + if (std::find(leafNames.begin(), leafNames.end(), ftp) == leafNames.end()) { + std::cout << "WARNING PlainTreeFiller::CheckIgnorePreserveRenameFields(): field " << ftp << " is set to be preserved, but it is absent among input fields\n"; + } + } + + for (const auto& ftr : fields_to_rename_) { + if (std::find(leafNames.begin(), leafNames.end(), ftr.first) == leafNames.end()) { + std::cout << "WARNING PlainTreeFiller::CheckIgnorePreserveRenameFields(): field " << ftr.first << " is set to be renamed, but it is absent among input fields\n"; + } + } +} + void PlainTreeFiller::Init() { if (is_ignore_defual_fields_) { std::vector defaultFieldsNames; auto mapF = config_->GetBranchConfig(branch_name_).GetMap(); auto mapI = config_->GetBranchConfig(branch_name_).GetMap(); auto mapB = config_->GetBranchConfig(branch_name_).GetMap(); - for (auto& m : {mapF, mapI, mapB}) { - for (auto& me : m) { + for (const auto& m : {mapF, mapI, mapB}) { + for (const auto& me : m) { if (me.second.id_ < 0) defaultFieldsNames.emplace_back(me.first); } } @@ -79,23 +108,32 @@ void PlainTreeFiller::Init() { if (vars_.size() != vars.size()) throw std::runtime_error("PlainTreeFiller::Init(): vars_.size() != vars.size()"); + std::vector leafNames; + for (int iVar = 0, nVars = vars.size(); iVar < nVars; ++iVar) { + leafNames.emplace_back(vars[iVar].GetName()); + } + CheckIgnorePreserveRenameFields(leafNames); + file_ = TFile::Open(file_name_.c_str(), "recreate"); plain_tree_ = new TTree(tree_name_.c_str(), "Plain Tree"); plain_tree_->SetAutoSave(0); - for (size_t i = 0; i < vars.size(); ++i) { - std::string leaf_name = vars[i].GetName(); + for (int iLeaf = 0, nLeafs = leafNames.size(); iLeaf < nLeafs; ++iLeaf) { + std::string leaf_name = leafNames.at(iLeaf); if (!fields_to_ignore_.empty() && std::find(fields_to_ignore_.begin(), fields_to_ignore_.end(), leaf_name) != fields_to_ignore_.end()) continue; if (!fields_to_preserve_.empty() && std::find(fields_to_preserve_.begin(), fields_to_preserve_.end(), leaf_name) == fields_to_preserve_.end()) continue; + if (!fields_to_rename_.empty() && fields_to_rename_.find(leaf_name) != fields_to_rename_.end()) { + leaf_name = fields_to_rename_.at(leaf_name); + } 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())); - 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())); + if (vars_.at(iLeaf).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(iLeaf).float_, Form("%s/F", leaf_name.c_str())); + else if (vars_.at(iLeaf).type_ == Types::kInteger) + plain_tree_->Branch(leaf_name.c_str(), &vars_.at(iLeaf).int_, Form("%s/I", leaf_name.c_str())); + else if (vars_.at(iLeaf).type_ == Types::kBool) + plain_tree_->Branch(leaf_name.c_str(), &vars_.at(iLeaf).bool_, Form("%s/O", leaf_name.c_str())); } - for (auto& cm : cuts_map_) { + for (const auto& cm : cuts_map_) { if (cm.second != nullptr) { cm.second->Init(*(TaskManager::GetInstance()->GetChain()->GetConfiguration())); } diff --git a/infra/PlainTreeFiller.hpp b/infra/PlainTreeFiller.hpp index fb96afd4..c2e0b7d7 100644 --- a/infra/PlainTreeFiller.hpp +++ b/infra/PlainTreeFiller.hpp @@ -36,11 +36,14 @@ class PlainTreeFiller : public AnalysisTask { void SetFieldsToIgnore(const std::vector& fields_to_ignore); void SetFieldsToPreserve(const std::vector& fields_to_preserve); + void SetFieldsToRename(const std::vector>& fields_to_rename); void SetIsIgnoreDefaultFields(bool is = true) { is_ignore_defual_fields_ = is; } void SetIsPrependLeavesWithBranchName(bool is = true) { is_prepend_leaves_with_branchname_ = is; } protected: + void CheckIgnorePreserveRenameFields(const std::vector& leafNames) const; + TFile* file_{nullptr}; TTree* plain_tree_{nullptr}; @@ -51,6 +54,7 @@ class PlainTreeFiller : public AnalysisTask { std::vector vars_; std::vector fields_to_ignore_{}; std::vector fields_to_preserve_{}; + std::map fields_to_rename_{}; bool is_ignore_defual_fields_{false}; bool is_prepend_leaves_with_branchname_{true}; diff --git a/infra/SimpleCut.hpp b/infra/SimpleCut.hpp index 5adbdd25..9b00481b 100644 --- a/infra/SimpleCut.hpp +++ b/infra/SimpleCut.hpp @@ -46,7 +46,7 @@ class SimpleCut { SimpleCut(const std::vector& vars, std::function&)> lambda, std::string title = "") : title_(std::move(title)), lambda_(std::move(lambda)) { - for (auto& var : vars) { + for (const auto& var : vars) { vars_.emplace_back(var); } FillBranchNames(); diff --git a/infra/TaskManager.cpp b/infra/TaskManager.cpp index 511158ec..76f46217 100644 --- a/infra/TaskManager.cpp +++ b/infra/TaskManager.cpp @@ -74,12 +74,12 @@ void TaskManager::InitOutChain() { assert(configuration_ && data_header_ && chain_);// input should exist configuration_ = chain_->CloneConfiguration(); *(data_header_) = *(chain_->GetDataHeader()); - for (auto& brex : branches_exclude_) { + for (const auto& brex : branches_exclude_) { if (chain_->CheckBranchExistence(brex) == 1) { throw std::runtime_error("AnalysisTree::TaskManager::InitOutChain - Tree in the input file does not support selective cloning"); } chain_->SetBranchStatus((brex + ".*").c_str(), false); - for (auto& maex : configuration_->GetMatchesOfBranch(brex)) { + for (const auto& maex : configuration_->GetMatchesOfBranch(brex)) { chain_->SetBranchStatus((maex + ".*").c_str(), false); } configuration_->RemoveBranchConfig(brex); @@ -93,12 +93,18 @@ void TaskManager::InitOutChain() { } void TaskManager::Run(long long nEvents) { + if (chain_->GetEntries() > 0) { + nEvents = nEvents < 0 || nEvents > chain_->GetEntries() ? chain_->GetEntries() : nEvents; + } + Run(0, nEvents); +} +void TaskManager::Run(long long nEventFrom, long long nEvents) { std::cout << "AnalysisTree::Manager::Run" << std::endl; auto start = std::chrono::system_clock::now(); - if (chain_->GetEntries() > 0) { - nEvents = nEvents < 0 || nEvents > chain_->GetEntries() ? chain_->GetEntries() : nEvents; + if (nEventFrom + nEvents > chain_->GetEntries() && chain_->GetEntries() > 0) { + throw std::runtime_error("TaskManager::Run() - nEventFrom + nEvents > chain_->GetEntries()"); } if (verbosity_frequency_ > 0) { @@ -107,7 +113,7 @@ void TaskManager::Run(long long nEvents) { verbosity_period_ = static_cast(std::pow(10, vPlog)); } - for (long long iEvent = 0; iEvent < nEvents; ++iEvent) { + for (long long iEvent = nEventFrom; iEvent < nEventFrom + nEvents; ++iEvent) { if (verbosity_period_ > 0 && iEvent % verbosity_period_ == 0) { std::cout << "Event no " << iEvent << "\n"; } diff --git a/infra/TaskManager.hpp b/infra/TaskManager.hpp index 59479353..83432e8b 100644 --- a/infra/TaskManager.hpp +++ b/infra/TaskManager.hpp @@ -55,7 +55,8 @@ class TaskManager { * Initialization in case of only creating AnalysisTree */ virtual void Init(); - virtual void Run(long long nEvents = -1); + void Run(long long nEventFrom, long long nEvents); + void Run(long long nEvents = -1); virtual void Finish(); void AddTask(Task* task) { tasks_.emplace_back(task); }