diff --git a/core/AnalysisTreeCoreLinkDef.h b/core/AnalysisTreeCoreLinkDef.h index e658095d..4789faa7 100644 --- a/core/AnalysisTreeCoreLinkDef.h +++ b/core/AnalysisTreeCoreLinkDef.h @@ -18,6 +18,7 @@ #pragma link C++ class AnalysisTree::VectorConfig+; #pragma link C++ class AnalysisTree::VectorConfig+; +#pragma link C++ class AnalysisTree::VectorConfig+; #pragma link C++ class AnalysisTree::VectorConfig+; #pragma link C++ class AnalysisTree::ConfigElement+; #pragma link C++ class AnalysisTree::Configuration_v3+; diff --git a/core/BranchConfig.cpp b/core/BranchConfig.cpp index 85eca5de..4a2743da 100644 --- a/core/BranchConfig.cpp +++ b/core/BranchConfig.cpp @@ -68,6 +68,9 @@ Types BranchConfig::GetFieldType(const std::string& sField) const { id = VectorConfig::GetId(sField); if (id != UndefValueShort) return Types::kFloat; + id = VectorConfig::GetId(sField); + if (id != UndefValueShort) return Types::kDouble; + id = VectorConfig::GetId(sField); if (id != UndefValueShort) return Types::kBool; @@ -81,6 +84,9 @@ ShortInt_t BranchConfig::GetFieldId(const std::string& sField) const { id = VectorConfig::GetId(sField); if (id != UndefValueShort) return id; + id = VectorConfig::GetId(sField); + if (id != UndefValueShort) return id; + id = VectorConfig::GetId(sField); if (id != UndefValueShort) return id; @@ -89,14 +95,19 @@ ShortInt_t BranchConfig::GetFieldId(const std::string& sField) const { BranchConfig BranchConfig::Clone(const std::string& name, DetType type) const { BranchConfig result(name, type); + for (const auto& field : AnalysisTree::VectorConfig::map_) { + if (field.second.id_ >= 0) { + result.AddField(field.first, field.second.id_, field.second.title_); + } + } for (const auto& field : AnalysisTree::VectorConfig::map_) { if (field.second.id_ >= 0) { result.AddField(field.first, field.second.id_, field.second.title_); } } - for (const auto& field : AnalysisTree::VectorConfig::map_) { + for (const auto& field : AnalysisTree::VectorConfig::map_) { if (field.second.id_ >= 0) { - result.AddField(field.first, field.second.id_, field.second.title_); + result.AddField(field.first, field.second.id_, field.second.title_); } } for (const auto& field : AnalysisTree::VectorConfig::map_) { @@ -104,9 +115,10 @@ BranchConfig BranchConfig::Clone(const std::string& name, DetType type) const { result.AddField(field.first, field.second.id_, field.second.title_); } } - result.AnalysisTree::VectorConfig::size_ = AnalysisTree::VectorConfig::size_; result.AnalysisTree::VectorConfig::size_ = AnalysisTree::VectorConfig::size_; result.AnalysisTree::VectorConfig::size_ = AnalysisTree::VectorConfig::size_; + result.AnalysisTree::VectorConfig::size_ = AnalysisTree::VectorConfig::size_; + result.AnalysisTree::VectorConfig::size_ = AnalysisTree::VectorConfig::size_; return result; } @@ -118,11 +130,14 @@ BranchConfig BranchConfig::CloneAndMerge(const BranchConfig& attached) const { auto result = Clone(name1 + "_" + name2, type1); + for (const auto& field : attached.AnalysisTree::VectorConfig::map_) { + result.AddField(name2 + "_" + field.first, name2 + ": " + field.second.title_); + } for (const auto& field : attached.AnalysisTree::VectorConfig::map_) { result.AddField(name2 + "_" + field.first, name2 + ": " + field.second.title_); } - for (const auto& field : attached.AnalysisTree::VectorConfig::map_) { - result.AddField(name2 + "_" + field.first, name2 + ": " + field.second.title_); + for (const auto& field : attached.AnalysisTree::VectorConfig::map_) { + result.AddField(name2 + "_" + field.first, name2 + ": " + field.second.title_); } for (const auto& field : attached.AnalysisTree::VectorConfig::map_) { result.AddField(name2 + "_" + field.first, name2 + ": " + field.second.title_); @@ -190,6 +205,7 @@ void VectorConfig::RemoveField(const std::string& name, int id) { m.second.id_--; } } + size_--; } void BranchConfig::RemoveField(const std::string& name) { @@ -203,6 +219,7 @@ void BranchConfig::RemoveField(const std::string& name) { } if (field_type == Types::kInteger) VectorConfig::RemoveField(name, field_id); if (field_type == Types::kFloat) VectorConfig::RemoveField(name, field_id); + if (field_type == Types::kDouble) VectorConfig::RemoveField(name, field_id); if (field_type == Types::kBool) VectorConfig::RemoveField(name, field_id); } @@ -214,10 +231,13 @@ void BranchConfig::GuaranteeFieldNameVacancy(const std::string& name) const { void BranchConfig::Print() const { std::cout << "Branch " << name_ << " (" << title_ << ") consists of:" << std::endl; - std::cout << "\nFloating fields:" << std::endl; - VectorConfig::Print(); std::cout << "\nInteger fields:" << std::endl; VectorConfig::Print(); + std::cout << "\nFloating fields:" << std::endl; + VectorConfig::Print(); + const std::string double_fields_empty_message = VectorConfig::map_.empty() ? " no double fields in this branch" : ""; + std::cout << "\nDouble fields:" << double_fields_empty_message << std::endl; + VectorConfig::Print(); const std::string boolean_fields_empty_message = VectorConfig::map_.empty() ? " no boolean fields in this branch" : ""; std::cout << "\nBoolean fields:" << boolean_fields_empty_message << std::endl << std::endl; diff --git a/core/BranchConfig.hpp b/core/BranchConfig.hpp index 2ca97c29..7e33c1ac 100644 --- a/core/BranchConfig.hpp +++ b/core/BranchConfig.hpp @@ -86,7 +86,7 @@ class VectorConfig { /** * Maybe better design choise would be use composition over inheritance (?) */ -class BranchConfig : public VectorConfig, public VectorConfig, public VectorConfig { +class BranchConfig : public VectorConfig, public VectorConfig, public VectorConfig, public VectorConfig { public: BranchConfig() = default; @@ -174,7 +174,7 @@ class BranchConfig : public VectorConfig, public VectorConfig, publi size_t id_{0}; DetType type_{DetType(UndefValueShort)}; - ClassDefOverride(BranchConfig, 4); + ClassDefOverride(BranchConfig, 5); }; // BranchConfig Merge(const BranchConfig& primary, const BranchConfig& secondary); diff --git a/core/BranchConfig.test.cpp b/core/BranchConfig.test.cpp index 7593fd44..1388f6ca 100644 --- a/core/BranchConfig.test.cpp +++ b/core/BranchConfig.test.cpp @@ -41,6 +41,26 @@ TEST(BranchConfig, Basics) { EXPECT_EQ(branch_config.GetFieldId("pz"), TrackFields::kPz); } +TEST(BranchConfig, RemoveField) { + BranchConfig branch_config("RecTrack", DetType::kTrack); + branch_config.AddFields({"f0", "f1", "f2"}, "just a test field"); + EXPECT_EQ(branch_config.GetSize(), 3); + + branch_config.RemoveField("f1"); + EXPECT_FALSE(branch_config.HasField("f1")); + EXPECT_EQ(branch_config.GetSize(), 2); + EXPECT_EQ(branch_config.GetFieldId("f0"), 0); + EXPECT_EQ(branch_config.GetFieldId("f2"), 1); + + // a field added after removal must get the next free id, not collide with existing ones + branch_config.AddField("f3", "just a test field"); + EXPECT_EQ(branch_config.GetFieldId("f3"), 2); + EXPECT_EQ(branch_config.GetSize(), 3); + + EXPECT_THROW(branch_config.RemoveField("pT"), std::runtime_error); + EXPECT_EQ(branch_config.GetSize(), 3); +} + }// namespace #endif//ANALYSISTREE_CORE_BRANCHCONFIG_TEST_H_ diff --git a/core/Constants.hpp b/core/Constants.hpp index 6af3fa4b..9d1c5a1c 100644 --- a/core/Constants.hpp +++ b/core/Constants.hpp @@ -57,6 +57,7 @@ enum class Types : ShortInt_t { kFloat = 0, kInteger, kBool, + kDouble, kNumberOfTypes }; diff --git a/core/Container.cpp b/core/Container.cpp index d1d7c0fe..3a568bb0 100644 --- a/core/Container.cpp +++ b/core/Container.cpp @@ -12,6 +12,8 @@ std::vector& Container::Vector() { return ints_; } template<> std::vector& Container::Vector() { return floats_; } template<> +std::vector& Container::Vector() { return doubles_; } +template<> std::vector& Container::Vector() { return bools_; } template<> @@ -19,9 +21,12 @@ const std::vector& Container::GetVector() const { return ints_; } template<> const std::vector& Container::GetVector() const { return floats_; } template<> +const std::vector& Container::GetVector() const { return doubles_; } +template<> const std::vector& Container::GetVector() const { return bools_; } void Container::Init(const AnalysisTree::BranchConfig& branch) { + doubles_.resize(branch.GetSize()); floats_.resize(branch.GetSize()); ints_.resize(branch.GetSize()); bools_.resize(branch.GetSize()); @@ -42,6 +47,13 @@ void Container::Print() const noexcept { } std::cout << std::endl; } + if (!doubles_.empty()) { + std::cout << "Double fields: "; + for (auto d : doubles_) { + std::cout << d << " "; + } + std::cout << std::endl; + } if (!bools_.empty()) { std::cout << "Boolean fields: "; for (auto b : bools_) { diff --git a/core/Container.hpp b/core/Container.hpp index dea05c2a..6613ffa7 100644 --- a/core/Container.hpp +++ b/core/Container.hpp @@ -9,9 +9,9 @@ namespace AnalysisTree { -/// A class to store any number of integers, floats and bools. +/// A class to store any number of doubles, floats, integers and bools. /** - * Consists of IndexedObject and separate std::vector, for T={float, int, bool}. + * Consists of IndexedObject and separate std::vector, for T={double, float, int, bool}. * Intended to be used as a base class for all AnalysysTree objects. */ @@ -22,6 +22,7 @@ class Container : public IndexedObject { explicit Container(size_t id) : IndexedObject(id) {} Container(size_t id, const BranchConfig& branch) : IndexedObject(id), + doubles_(branch.GetSize()), floats_(branch.GetSize()), ints_(branch.GetSize()), bools_(branch.GetSize()) {} @@ -57,11 +58,12 @@ class Container : public IndexedObject { virtual void Print() const noexcept; protected: + std::vector doubles_{}; std::vector floats_{}; std::vector ints_{}; std::vector bools_{}; - ClassDefOverride(Container, 2); + ClassDefOverride(Container, 3); }; }// namespace AnalysisTree diff --git a/core/Container.test.cpp b/core/Container.test.cpp index d03813a2..ccacecf7 100644 --- a/core/Container.test.cpp +++ b/core/Container.test.cpp @@ -41,6 +41,35 @@ TEST(Container, Basics) { EXPECT_EQ(container.GetField(0), true); } +TEST(Container, Double) { + Container container; + EXPECT_EQ(container.GetSize(), 0); + + BranchConfig config("RecTrack", DetType::kTrack); + config.AddField("test_d", "just a test field"); + config.AddField("test_f", "just a test field"); + + EXPECT_EQ(config.GetFieldType("test_d"), Types::kDouble); + EXPECT_EQ(config.GetFieldId("test_d"), 0); + EXPECT_EQ(config.GetFieldId("test_f"), 0); + + container.Init(config); + EXPECT_EQ(container.GetSize(), 1); + + // value which cannot be represented exactly in float precision + const double value = 1. + 1e-12; + container.SetField(value, 0); + EXPECT_EQ(container.GetField(0), value); + EXPECT_NE(static_cast(value), value); + + auto clone = config.Clone("RecTrackClone", DetType::kTrack); + EXPECT_EQ(clone.GetFieldType("test_d"), Types::kDouble); + EXPECT_EQ(clone.GetSize(), 1); + + config.RemoveField("test_d"); + EXPECT_FALSE(config.HasField("test_d")); +} + }// namespace #endif//ANALYSISTREE_CORE_CONTAINER_TEST_HPP_ diff --git a/infra/Branch.cpp b/infra/Branch.cpp index ff920f4e..bd4f2469 100644 --- a/infra/Branch.cpp +++ b/infra/Branch.cpp @@ -69,6 +69,10 @@ Field Branch::NewVariable(const std::string& field_name, const std::string& titl using AnalysisTree::Types; switch (type) { + case Types::kDouble: { + config_.template AddField(field_name, title); + break; + } case Types::kFloat: { config_.template AddField(field_name, title); break; @@ -117,6 +121,7 @@ void Branch::CloneVariables(const AnalysisTree::BranchConfig& other) { }// map elements }; + import_fields_from_map(other.GetMap(), AnalysisTree::Types::kDouble); import_fields_from_map(other.GetMap(), AnalysisTree::Types::kFloat); import_fields_from_map(other.GetMap(), AnalysisTree::Types::kInteger); import_fields_from_map(other.GetMap(), AnalysisTree::Types::kBool); @@ -190,6 +195,7 @@ void Branch::CreateMapping(const Branch* other, std::string branch_name_prefix) other->CheckFrozen(); const std::map types_map = { + {AnalysisTree::Types::kDouble, "double"}, {AnalysisTree::Types::kFloat, "float"}, {AnalysisTree::Types::kInteger, "integer"}, {AnalysisTree::Types::kBool, "bool"}}; @@ -218,6 +224,7 @@ std::vector Branch::GetFieldNames() const { result.push_back(element.first); } }; + fill_vector_from_map(config_.GetMap()); fill_vector_from_map(config_.GetMap()); fill_vector_from_map(config_.GetMap()); fill_vector_from_map(config_.GetMap()); diff --git a/infra/BranchChannel.cpp b/infra/BranchChannel.cpp index bb9401ec..cbccb18a 100644 --- a/infra/BranchChannel.cpp +++ b/infra/BranchChannel.cpp @@ -75,6 +75,7 @@ double BranchChannel::Value(const Field& v) const { using AnalysisTree::Types; switch (v.GetFieldType()) { + case Types::kDouble: return ANALYSISTREE_UTILS_VISIT(get_field_struct(v.GetFieldId()), data_ptr_); case Types::kFloat: return ANALYSISTREE_UTILS_VISIT(get_field_struct(v.GetFieldId()), data_ptr_); case Types::kInteger: return ANALYSISTREE_UTILS_VISIT(get_field_struct(v.GetFieldId()), data_ptr_); case Types::kBool: return ANALYSISTREE_UTILS_VISIT(get_field_struct(v.GetFieldId()), data_ptr_); @@ -85,6 +86,7 @@ double BranchChannel::Value(const Field& v) const { void BranchChannel::SetValue(const Field& v, double value) { using AnalysisTree::Types; switch (v.GetFieldType()) { + case Types::kDouble: ANALYSISTREE_UTILS_VISIT(set_field_struct(value, v.GetFieldId()), data_ptr_); break; case Types::kFloat: ANALYSISTREE_UTILS_VISIT(set_field_struct(value, v.GetFieldId()), data_ptr_); break; case Types::kInteger: ANALYSISTREE_UTILS_VISIT(set_field_struct(value, v.GetFieldId()), data_ptr_); break; case Types::kBool: ANALYSISTREE_UTILS_VISIT(set_field_struct(value, v.GetFieldId()), data_ptr_); break; diff --git a/infra/BranchHashHelper.hpp b/infra/BranchHashHelper.hpp index 7a13012f..527150df 100644 --- a/infra/BranchHashHelper.hpp +++ b/infra/BranchHashHelper.hpp @@ -24,6 +24,7 @@ inline std::size_t BranchConfigHasher(const AnalysisTree::BranchConfig& config) } }; + hash_fields(config.GetMap(), Type::kDouble); hash_fields(config.GetMap(), Type::kFloat); hash_fields(config.GetMap(), Type::kInteger); hash_fields(config.GetMap(), Type::kBool); diff --git a/infra/ChainDrawHelper.cpp b/infra/ChainDrawHelper.cpp index 6fa91677..28ca8e65 100644 --- a/infra/ChainDrawHelper.cpp +++ b/infra/ChainDrawHelper.cpp @@ -17,6 +17,10 @@ void ChainDrawHelper::DrawFieldTransform(std::string& expr) { std::string type_str{}; switch (type) { + case (Types::kDouble): { + type_str = "double"; + break; + } case (Types::kFloat): { type_str = "float"; break; diff --git a/infra/Field.hpp b/infra/Field.hpp index a7ac2470..5271c016 100644 --- a/infra/Field.hpp +++ b/infra/Field.hpp @@ -65,6 +65,7 @@ class Field { throw std::runtime_error("Field::Fill - Field " + field_ + " is not initialized"); } switch (field_type_) { + case Types::kDouble: return object.template GetField(field_id_); case Types::kFloat: return object.template GetField(field_id_); case (Types::kInteger): return object.template GetField(field_id_); case Types::kBool: return object.template GetField(field_id_); diff --git a/infra/GenericContainerFiller.cpp b/infra/GenericContainerFiller.cpp index d2517a3a..bfc6da60 100644 --- a/infra/GenericContainerFiller.cpp +++ b/infra/GenericContainerFiller.cpp @@ -44,7 +44,9 @@ void GenericContainerFiller::Init() { 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") { + if (fieldType == "TLeafD") { + branchConfig.AddField(fieldName); + } else if (fieldType == "TLeafF") { branchConfig.AddField(fieldName); } else if (fieldType == "TLeafI" || fieldType == "TLeafB" || fieldType == "TLeafS") { branchConfig.AddField(fieldName); @@ -56,7 +58,7 @@ void GenericContainerFiller::Init() { config_.AddBranchConfig(branchConfig); for (int iV = 0; iV < static_cast(branch_values_.size()); iV++) { - SetAddressFICS(branch_map_.at(iV).name_, branch_map_.at(iV), branch_values_.at(iV)); + SetLeafAddress(branch_map_.at(iV).name_, branch_map_.at(iV), branch_values_.at(iV)); } generic_detector_ = new GenericDetector(branchConfig.GetId()); @@ -79,7 +81,7 @@ int GenericContainerFiller::Exec(int iEntry, int previousTriggerVar) { generic_detector_->ClearChannels(); } auto& channel = generic_detector_->AddChannel(config_.GetBranchConfig(generic_detector_->GetId())); - SetFieldsFICS(branch_map_, channel, branch_values_); + SetFieldsFromLeaves(branch_map_, channel, branch_values_); return currentTriggerVar; } @@ -113,28 +115,32 @@ int GenericContainerFiller::DetermineFieldIdByName(const std::vector& return distance; } -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_); +void GenericContainerFiller::SetLeafAddress(const std::string& branchName, const IndexMap& imap, LeafBuffer& buffer) { + if (imap.field_type_ == "TLeafD") tree_in_->SetBranchAddress(branchName.c_str(), &buffer.double_); + else if (imap.field_type_ == "TLeafF") + tree_in_->SetBranchAddress(branchName.c_str(), &buffer.float_); else if (imap.field_type_ == "TLeafI") - tree_in_->SetBranchAddress(branchName.c_str(), &ficc.int_); + tree_in_->SetBranchAddress(branchName.c_str(), &buffer.int_); else if (imap.field_type_ == "TLeafB") - tree_in_->SetBranchAddress(branchName.c_str(), &ficc.char_); + tree_in_->SetBranchAddress(branchName.c_str(), &buffer.char_); else if (imap.field_type_ == "TLeafS") - tree_in_->SetBranchAddress(branchName.c_str(), &ficc.short_); + tree_in_->SetBranchAddress(branchName.c_str(), &buffer.short_); else - throw std::runtime_error("GenericContainerFiller::SetAddressFICS(): unsupported filed type " + imap.field_type_); + throw std::runtime_error("GenericContainerFiller::SetLeafAddress(): unsupported filed type " + imap.field_type_); } -void GenericContainerFiller::SetFieldsFICS(const std::vector& imap, Container& container, const std::vector& ficc) { - for (int iV = 0; iV < static_cast(ficc.size()); iV++) { - if (imap.at(iV).field_type_ == "TLeafF") container.SetField(ficc.at(iV).float_, imap.at(iV).index_); +void GenericContainerFiller::SetFieldsFromLeaves(const std::vector& imap, Container& container, const std::vector& buffers) { + for (int iV = 0; iV < static_cast(buffers.size()); iV++) { + if (imap.at(iV).field_type_ == "TLeafD") container.SetField(buffers.at(iV).double_, imap.at(iV).index_); + else if (imap.at(iV).field_type_ == "TLeafF") + container.SetField(buffers.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_); + container.SetField(buffers.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_); + container.SetField(static_cast(buffers.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_); + container.SetField(static_cast(buffers.at(iV).short_), imap.at(iV).index_); else - throw std::runtime_error("GenericContainerFiller::SetFieldsFICS(): unsupported filed type " + imap.at(iV).field_type_); + throw std::runtime_error("GenericContainerFiller::SetFieldsFromLeaves(): unsupported filed type " + imap.at(iV).field_type_); } } diff --git a/infra/GenericContainerFiller.hpp b/infra/GenericContainerFiller.hpp index 49b29179..196ca8da 100644 --- a/infra/GenericContainerFiller.hpp +++ b/infra/GenericContainerFiller.hpp @@ -15,29 +15,34 @@ #include #include +namespace AnalysisTree { + struct IndexMap { std::string name_; std::string field_type_; short index_; }; -struct FICS {// FICS stands for float, int, char, short +/// Buffer for the value of one leaf of the input tree. +/// Only the member matching the leaf type is connected via SetBranchAddress, +/// the others keep their placeholder value -199. +struct LeafBuffer { + double double_{-199.}; float float_{-199.f}; int int_{-199}; char char_{static_cast(-199)}; short short_{static_cast(-199)}; - float get() const { + double get() const { + if (std::fabs(double_ + 199.) > 1e-4) return double_; 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"); + 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, LeafBuffer::get(): none of values initialized"); } }; -namespace AnalysisTree { - class GenericContainerFiller { public: GenericContainerFiller() = delete; @@ -63,8 +68,8 @@ class GenericContainerFiller { void Finish(); static int DetermineFieldIdByName(const std::vector& iMap, const std::string& name); - 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); + void SetLeafAddress(const std::string& branchName, const IndexMap& imap, LeafBuffer& buffer); + static void SetFieldsFromLeaves(const std::vector& imap, AnalysisTree::Container& container, const std::vector& buffers); std::string file_in_name_; std::string tree_in_name_; @@ -80,7 +85,7 @@ class GenericContainerFiller { AnalysisTree::Configuration config_; AnalysisTree::GenericDetector* generic_detector_{nullptr}; std::vector branch_map_; - std::vector branch_values_; + std::vector branch_values_; // variable, change of value of which triggers switch to a new AT event std::string entry_switch_trigger_var_name_; diff --git a/infra/PlainTreeFiller.cpp b/infra/PlainTreeFiller.cpp index f87f37d0..2f2ccac5 100644 --- a/infra/PlainTreeFiller.cpp +++ b/infra/PlainTreeFiller.cpp @@ -65,10 +65,11 @@ void PlainTreeFiller::CheckIgnorePreserveRenameFields(const std::vector defaultFieldsNames; + auto mapD = config_->GetBranchConfig(branch_name_).GetMap(); auto mapF = config_->GetBranchConfig(branch_name_).GetMap(); auto mapI = config_->GetBranchConfig(branch_name_).GetMap(); auto mapB = config_->GetBranchConfig(branch_name_).GetMap(); - for (const auto& m : {mapF, mapI, mapB}) { + for (const auto& m : {mapD, mapF, mapI, mapB}) { for (const auto& me : m) { if (me.second.id_ < 0) defaultFieldsNames.emplace_back(me.first); } @@ -82,6 +83,11 @@ void PlainTreeFiller::Init() { if (!branch_name_.empty()) { 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(); + vars_.back().type_ = Types::kDouble; + } for (const auto& field : branch_config.GetMap()) { AnalysisTask::AddEntry(AnalysisEntry({Variable(branch_name_, field.first)})); vars_.emplace_back(); @@ -126,7 +132,9 @@ 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(iLeaf).type_ == Types::kFloat) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(iLeaf).float_, Form("%s/F", leaf_name.c_str())); + if (vars_.at(iLeaf).type_ == Types::kDouble) plain_tree_->Branch(leaf_name.c_str(), &vars_.at(iLeaf).double_, Form("%s/D", leaf_name.c_str())); + else 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) @@ -146,7 +154,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::kDouble) vars_.at(i).double_ = channel.at(i); + else if (vars_.at(i).type_ == Types::kFloat) + vars_.at(i).float_ = 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) diff --git a/infra/PlainTreeFiller.hpp b/infra/PlainTreeFiller.hpp index c2e0b7d7..3dfd82a4 100644 --- a/infra/PlainTreeFiller.hpp +++ b/infra/PlainTreeFiller.hpp @@ -13,6 +13,7 @@ namespace AnalysisTree { struct FIB { + double double_{-299.}; float float_{-299.f}; int int_{-299}; bool bool_{false};