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); }