diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml new file mode 100644 index 0000000..14f169f --- /dev/null +++ b/.github/workflows/clang.yml @@ -0,0 +1,14 @@ +name: Clang Format Checker +on: + push: + pull_request: + branches: [ master ] +jobs: + clang-format-checking: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: RafikFarhad/clang-format-github-action@v2.0.0 + with: + sources: "src/*.*pp examples/*.*pp" + style: file diff --git a/cmake_modules/AnalysisTreeQAConfig.sh.in b/cmake_modules/AnalysisTreeQAConfig.sh.in index 463bb55..396c280 100644 --- a/cmake_modules/AnalysisTreeQAConfig.sh.in +++ b/cmake_modules/AnalysisTreeQAConfig.sh.in @@ -4,3 +4,4 @@ source ${AT_INSTALL_BIN}/AnalysisTreeConfig.sh export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${CMAKE_INSTALL_PREFIX}/lib export ROOT_INCLUDE_PATH=$ROOT_INCLUDE_PATH:${CMAKE_INSTALL_PREFIX}/include/AnalysisTreeQA +export PATH=$PATH:${CMAKE_INSTALL_PREFIX}/bin diff --git a/src/EntryConfig.cpp b/src/EntryConfig.cpp index a514c08..0e3cfd0 100644 --- a/src/EntryConfig.cpp +++ b/src/EntryConfig.cpp @@ -13,11 +13,17 @@ using TH1FD = TH1F; using TH2FD = TH2F; #endif -namespace AnalysisTree::QA { +namespace AnalysisTree { +namespace QA { struct fill2_struct : public Utils::Visitor { fill2_struct(double val1, double val2) : val1_(val1), val2_(val2) {} - void operator()(TH1* h1) const { h1->Fill(val1_, val2_); } + void operator()(TH1* h1) const { + if (FloatingEqualZero(val2_)) return; + if (FloatingEqualOne(val2_)) h1->Fill(val1_); + else + h1->Fill(val1_, val2_); + } void operator()(TH2* h2) const { h2->Fill(val1_, val2_); } void operator()(TProfile* p) const { p->Fill(val1_, val2_); } double val1_, val2_; @@ -26,17 +32,27 @@ struct fill2_struct : public Utils::Visitor { struct fill3_struct : public Utils::Visitor { fill3_struct(double val1, double val2, double val3) : val1_(val1), val2_(val2), val3_(val3) {} void operator()(TH1*) const { throw std::runtime_error("EntryConfig, fill3_struct: cannot fill TH1 with 3 arguments"); } - void operator()(TH2* h2) const { h2->Fill(val1_, val2_, val3_); } - void operator()(TProfile* p) const { p->Fill(val1_, val2_, val3_); } + void operator()(TH2* h2) const { + if (FloatingEqualZero(val3_)) return; + if (FloatingEqualOne(val3_)) h2->Fill(val1_, val2_); + else + h2->Fill(val1_, val2_, val3_); + } + void operator()(TProfile* p) const { + if (FloatingEqualZero(val3_)) return; + if (FloatingEqualOne(val3_)) p->Fill(val1_, val2_); + else + p->Fill(val1_, val2_, val3_); + } double val1_, val2_, val3_; }; -EntryConfig::EntryConfig(const Axis& axis, Variable& weight, const std::string& name, Cuts* cuts, bool is_integral) +EntryConfig::EntryConfig(const Axis& axis, const Variable& weight, const std::string& name, Cuts* cuts, bool is_integral) : name_(name == "" ? axis.GetName() : name), type_(is_integral ? PlotType::kIntegral1D : PlotType::kHisto1D), axes_({axis}), var4weight_(weight), - entry_cuts_(cuts) { + entry_cuts_name_(cuts != nullptr ? cuts->GetName() : "") { if (name == "") { if (cuts) name_ += "_" + cuts->GetName(); @@ -50,18 +66,22 @@ EntryConfig::EntryConfig(const Axis& axis, Variable& weight, const std::string& InitPlot(); } -EntryConfig::EntryConfig(const Axis& x, const Axis& y, Variable& weight, const std::string& name, Cuts* cuts, bool is_profile) : type_(is_profile ? PlotType::kProfile : PlotType::kHisto2D), - axes_({x, y}), - var4weight_(weight), - entry_cuts_(cuts) { +EntryConfig::EntryConfig(const Axis& x, const Axis& y, const Variable& weight, const std::string& name, Cuts* cuts, bool is_profile) : type_(is_profile ? PlotType::kProfile : PlotType::kHisto2D), + axes_({x, y}), + var4weight_(weight), + entry_cuts_name_(cuts != nullptr ? cuts->GetName() : "") { Set2DName(name); InitPlot(); } -EntryConfig::EntryConfig(const Axis& x, Cuts* cuts_x, const Axis& y, Cuts* cuts_y) : type_(PlotType::kIntegral2D), - axes_({x, y}), - entry_cuts_(cuts_x) { - Set2DName(); +EntryConfig::EntryConfig(const Axis& x, Cuts* cuts_x, const Axis& y, Cuts* cuts_y, const std::string& name) : type_(PlotType::kIntegral2D), + axes_({x, y}) { + const std::string cutNameX = cuts_x != nullptr ? cuts_x->GetName() : ""; + const std::string cutNameY = cuts_y != nullptr ? cuts_y->GetName() : ""; + const std::string cutNameSeparator = cuts_x != nullptr && cuts_y != nullptr ? "_" : ""; + entry_cuts_name_ = cutNameX + cutNameSeparator + cutNameY; + + Set2DName(name); InitPlot(); } @@ -172,8 +192,9 @@ void EntryConfig::InitPlot() { void EntryConfig::Set2DName(const std::string& name) { name_ = name.empty() ? Form("%s_%s", axes_[0].GetName(), axes_[1].GetName()) : name; if (name.empty()) { - if (entry_cuts_ != nullptr) - name_ += "_" + entry_cuts_->GetName(); + if (!entry_cuts_name_.empty()) { + name_ += "_" + entry_cuts_name_; + } if (!var4weight_.GetName().empty() && var4weight_.GetFields().at(0).GetName() != "ones") { name_ += "_weight_" + var4weight_.GetName(); @@ -206,8 +227,8 @@ std::string EntryConfig::GetDirectoryName() const { for (auto it = ++branches.begin(); it != branches.end(); ++it) { name += "_" + *it; } - if (entry_cuts_) { - name += "_" + entry_cuts_->GetName(); + if (!entry_cuts_name_.empty()) { + name += "_" + entry_cuts_name_; } if (!var4weight_.GetName().empty() && var4weight_.GetFields().at(0).GetName() != "ones") { name += "_weight_" + var4weight_.GetName(); @@ -215,4 +236,5 @@ std::string EntryConfig::GetDirectoryName() const { return name; } -}// namespace AnalysisTree::QA +}// namespace QA +}// namespace AnalysisTree diff --git a/src/EntryConfig.hpp b/src/EntryConfig.hpp index 46269ef..771c5eb 100644 --- a/src/EntryConfig.hpp +++ b/src/EntryConfig.hpp @@ -12,7 +12,8 @@ #include "AnalysisTree/Cuts.hpp" #include "AnalysisTree/Utils.hpp" -namespace AnalysisTree::QA { +namespace AnalysisTree { +namespace QA { class Axis : public Variable, public TAxis { public: @@ -44,9 +45,9 @@ class EntryConfig { }; EntryConfig() = default; - explicit EntryConfig(const Axis& axis, [[maybe_unused]] Variable& weight, const std::string& name, Cuts* cuts = nullptr, bool is_integral = false); - EntryConfig(const Axis& x, const Axis& y, Variable& weight, const std::string& name, Cuts* cuts = nullptr, bool is_profile = false); - EntryConfig(const Axis& x, Cuts* cuts_x, const Axis& y, Cuts* cuts_y); + explicit EntryConfig(const Axis& axis, [[maybe_unused]] const Variable& weight, const std::string& name, Cuts* cuts = nullptr, bool is_integral = false); + EntryConfig(const Axis& x, const Axis& y, const Variable& weight, const std::string& name, Cuts* cuts = nullptr, bool is_profile = false); + EntryConfig(const Axis& x, Cuts* cuts_x, const Axis& y, Cuts* cuts_y, const std::string& name); EntryConfig(const EntryConfig&) = default; EntryConfig(EntryConfig&&) = default; @@ -59,7 +60,7 @@ class EntryConfig { void Fill(double value1, double value2, double value3); ANALYSISTREE_ATTR_NODISCARD unsigned int GetNdimensions() const { return axes_.size(); } - ANALYSISTREE_ATTR_NODISCARD Cuts* GetEntryCuts() const { return entry_cuts_; } + ANALYSISTREE_ATTR_NODISCARD const std::string& GetEntryCutsName() const { return entry_cuts_name_; } ANALYSISTREE_ATTR_NODISCARD PlotType GetType() const { return type_; } ANALYSISTREE_ATTR_NODISCARD std::vector> GetVariablesId() const { return vars_id_; } @@ -97,11 +98,15 @@ class EntryConfig { std::vector axes_{}; Variable var4weight_{}; - Cuts* entry_cuts_{nullptr}; + std::string entry_cuts_name_{}; std::vector> vars_id_{}; ClassDef(EntryConfig, 1); }; -}// namespace AnalysisTree::QA +inline bool FloatingEqualZero(const double value, const double eps = 1e-6) { return std::fabs(value) < eps; } +inline bool FloatingEqualOne(const double value, const double eps = 1e-6) { return std::fabs(value - 1) < eps; } + +}// namespace QA +}// namespace AnalysisTree #endif//ANALYSISTREE_QA_ENTRYCONFIG_H diff --git a/src/Task.cpp b/src/Task.cpp index b7a43d4..e07501a 100644 --- a/src/Task.cpp +++ b/src/Task.cpp @@ -2,93 +2,95 @@ #include -namespace AnalysisTree::QA { +namespace AnalysisTree { +namespace QA { -size_t Task::AddH1(const std::string& name, const Axis& x, Cuts* cuts, Variable weight) { +size_t Task::AddH1(const std::string& name, const Axis& x, Cuts* cuts, const Variable& weight) { CreateOutputFileIfNotYet(); - weight.IfEmptyVariableConvertToOnes(x); entries_.emplace_back(x, weight, name, cuts, false); const std::string dirName = ConstructOutputDirectoryName(); - TDirectory* dir = MkMultiLevelDir(out_file_, dirName); + TDirectory* dir = MkDirIfNotYet(out_file_, dirName); ANALYSISTREE_UTILS_VISIT(setdirectory_struct(dir), entries_.back().GetPlot()); ANALYSISTREE_UTILS_VISIT(setname_struct(entries_.back().GetName()), entries_.back().GetPlot()); - auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), entries_.back().GetEntryCuts(), entries_.back().GetVariableForWeight())); + const auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), cuts, entries_.back().GetVariableForWeight())); entries_.back().SetVariablesId({{var_id.first, var_id.second.at(0)}}); return entries_.size() - 1; } -size_t Task::AddH1(const Axis& x, Cuts* cuts, Variable weight) { - return AddH1("", x, cuts, std::move(weight)); +size_t Task::AddH1(const Axis& x, Cuts* cuts, const Variable& weight) { + return AddH1("", x, cuts, weight); } -size_t Task::AddH2(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts, Variable weight) { +size_t Task::AddH2(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts, const Variable& weight) { CreateOutputFileIfNotYet(); - weight.IfEmptyVariableConvertToOnes(x); entries_.emplace_back(x, y, weight, name, cuts); const std::string dirName = ConstructOutputDirectoryName(); - TDirectory* dir = MkMultiLevelDir(out_file_, dirName); + TDirectory* dir = MkDirIfNotYet(out_file_, dirName); ANALYSISTREE_UTILS_VISIT(setdirectory_struct(dir), entries_.back().GetPlot()); ANALYSISTREE_UTILS_VISIT(setname_struct(entries_.back().GetName()), entries_.back().GetPlot()); - auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), entries_.back().GetEntryCuts(), entries_.back().GetVariableForWeight())); + const auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), cuts, entries_.back().GetVariableForWeight())); entries_.back().SetVariablesId({{var_id.first, var_id.second.at(0)}, {var_id.first, var_id.second.at(1)}}); return entries_.size() - 1; } -size_t Task::AddH2(const Axis& x, const Axis& y, Cuts* cuts, Variable weight) { - return AddH2("", x, y, cuts, std::move(weight)); +size_t Task::AddH2(const Axis& x, const Axis& y, Cuts* cuts, const Variable& weight) { + return AddH2("", x, y, cuts, weight); } -size_t Task::AddProfile(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts, Variable weight) { +size_t Task::AddProfile(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts, const Variable& weight) { CreateOutputFileIfNotYet(); - weight.IfEmptyVariableConvertToOnes(x); entries_.emplace_back(x, y, weight, name, cuts, true); const std::string dirName = ConstructOutputDirectoryName(); - TDirectory* dir = MkMultiLevelDir(out_file_, dirName); + TDirectory* dir = MkDirIfNotYet(out_file_, dirName); ANALYSISTREE_UTILS_VISIT(setdirectory_struct(dir), entries_.back().GetPlot()); ANALYSISTREE_UTILS_VISIT(setname_struct(entries_.back().GetName()), entries_.back().GetPlot()); - auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), entries_.back().GetEntryCuts(), entries_.back().GetVariableForWeight())); + const auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), cuts, entries_.back().GetVariableForWeight())); entries_.back().SetVariablesId({{var_id.first, var_id.second.at(0)}, {var_id.first, var_id.second.at(1)}}); return entries_.size() - 1; } -size_t Task::AddProfile(const Axis& x, const Axis& y, Cuts* cuts, Variable weight) { - return AddProfile("", x, y, cuts, std::move(weight)); +size_t Task::AddProfile(const Axis& x, const Axis& y, Cuts* cuts, const Variable& weight) { + return AddProfile("", x, y, cuts, weight); } -size_t Task::AddIntegral(const std::string& name, const Axis& x, Cuts* cuts, Variable weight) { +size_t Task::AddIntegral(const std::string& name, const Axis& x, Cuts* cuts) { CreateOutputFileIfNotYet(); - weight.IfEmptyVariableConvertToOnes(x); + const Variable weight{}; entries_.emplace_back(x, weight, name, cuts, true); const std::string dirName = ConstructOutputDirectoryName(); - TDirectory* dir = MkMultiLevelDir(out_file_, dirName); + TDirectory* dir = MkDirIfNotYet(out_file_, dirName); ANALYSISTREE_UTILS_VISIT(setdirectory_struct(dir), entries_.back().GetPlot()); ANALYSISTREE_UTILS_VISIT(setname_struct(entries_.back().GetName()), entries_.back().GetPlot()); - auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), entries_.back().GetEntryCuts(), entries_.back().GetVariableForWeight())); + const auto var_id = AddEntry(AnalysisEntry(entries_.back().GetVariables(), cuts, entries_.back().GetVariableForWeight())); entries_.back().SetVariablesId({{var_id.first, var_id.second.at(0)}}); return entries_.size() - 1; } -size_t Task::AddIntegral(const Axis& x, Cuts* cuts, Variable weight) { - return AddIntegral("", x, cuts, std::move(weight)); +size_t Task::AddIntegral(const Axis& x, Cuts* cuts) { + return AddIntegral("", x, cuts); } -size_t Task::AddIntegral(const Axis& x, const Axis& y, Cuts* cuts_x, Cuts* cuts_y) { +size_t Task::AddIntegral(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts_x, Cuts* cuts_y) { CreateOutputFileIfNotYet(); - entries_.emplace_back(x, cuts_x, y, cuts_y); + entries_.emplace_back(x, cuts_x, y, cuts_y, name); const std::string dirName = ConstructOutputDirectoryName(); - TDirectory* dir = MkMultiLevelDir(out_file_, dirName); + TDirectory* dir = MkDirIfNotYet(out_file_, dirName); ANALYSISTREE_UTILS_VISIT(setdirectory_struct(dir), entries_.back().GetPlot()); ANALYSISTREE_UTILS_VISIT(setname_struct(entries_.back().GetName()), entries_.back().GetPlot()); - auto var_id_x = AddEntry(AnalysisEntry({entries_.back().GetVariables()[0]}, cuts_x)); - auto var_id_y = AddEntry(AnalysisEntry({entries_.back().GetVariables()[1]}, cuts_y)); + const auto var_id_x = AddEntry(AnalysisEntry({entries_.back().GetVariables()[0]}, cuts_x)); + const auto var_id_y = AddEntry(AnalysisEntry({entries_.back().GetVariables()[1]}, cuts_y)); entries_.back().SetVariablesId({{var_id_x.first, var_id_x.second.at(0)}, {var_id_y.first, var_id_y.second.at(0)}}); return entries_.size() - 1; } -void Task::FillIntegral(EntryConfig& plot) { +size_t Task::AddIntegral(const Axis& x, const Axis& y, Cuts* cuts_x, Cuts* cuts_y) { + return AddIntegral("", x, y, cuts_x, cuts_y); +} + +void Task::FillIntegral(EntryConfig& plot) const { double integral_x{0.}; double integral_y{0.}; - auto var_ids = plot.GetVariablesId(); + const auto& var_ids = plot.GetVariablesId(); for (const auto& var : this->GetValues(var_ids.at(0).first)) { integral_x += var[var_ids.at(0).second]; @@ -109,31 +111,20 @@ void Task::Exec() { AnalysisTask::Exec(); for (auto& plot : entries_) { - if (plot.GetType() == EntryConfig::PlotType::kIntegral1D || plot.GetType() == EntryConfig::PlotType::kIntegral2D) { FillIntegral(plot); continue; } - auto var_ids = plot.GetVariablesId(); - auto weights = this->GetWeights(var_ids.at(0).first); + const auto& var_ids = plot.GetVariablesId(); + const auto& weights = this->GetWeights(var_ids.at(0).first); int ivw{-1}; - for (auto var : this->GetValues(var_ids.at(0).first)) { + for (const auto& var : this->GetValues(var_ids.at(0).first)) { ++ivw; - auto weight = weights.at(ivw); - if (std::fabs(weight) < 1e-6) continue; - switch (plot.GetNdimensions()) { - case 1: { - if (std::fabs(weight - 1) < 1e-4) plot.Fill(var[var_ids.at(0).second]); - else - plot.Fill(var[var_ids.at(0).second], weight); - break; - } - case 2: { - if (std::fabs(weight - 1) < 1e-4) plot.Fill(var[var_ids.at(0).second], var[var_ids.at(1).second]); - else - plot.Fill(var[var_ids.at(0).second], var[var_ids.at(1).second], weight); - break; - } + const auto& weight = weights.at(ivw); + if (plot.GetNdimensions() == 1) { + plot.Fill(var[var_ids.at(0).second], weight); + } else { + plot.Fill(var[var_ids.at(0).second], var[var_ids.at(1).second], weight); } } }// plots @@ -144,40 +135,31 @@ void Task::Finish() { out_file_->Close(); } -TDirectory* Task::MkMultiLevelDir(TFile* file, const std::string& name) const { - auto splitBySlash = [](const std::string& str) { - std::vector result; - std::stringstream ss(str); - std::string item; - - // Split the string by slashes - while (std::getline(ss, item, '/')) { - result.push_back(item); - } - - return result; - }; - - auto vDirs = splitBySlash(name); - TDirectory* result; - for (int iDir = 0; iDir < vDirs.size(); iDir++) { - if (iDir == 0) result = MkDirIfNotExists(file, vDirs.at(iDir)); - else - result = MkDirIfNotExists(result, vDirs.at(iDir)); - } - return result; -} - void Task::CreateOutputFileIfNotYet() { if (out_file_ == nullptr) out_file_ = new TFile(out_file_name_.c_str(), out_file_option_.c_str()); } -std::string Task::ConstructOutputDirectoryName() { - const std::string entryName = entries_.back().GetDirectoryName(); - std::string dirName = toplevel_dir_name_.empty() ? entryName : toplevel_dir_name_; - if (is_append_dir_name_with_entry_name_ && !toplevel_dir_name_.empty()) dirName.append("/" + entryName); +std::string Task::ConstructOutputDirectoryName() const { + const std::string& entryName = entries_.back().GetDirectoryName(); + std::string dirName = toplevel_dir_name_ == UndefTopLevelDirName ? entryName : toplevel_dir_name_; + if (is_append_dir_name_with_entry_name_ && toplevel_dir_name_ != UndefTopLevelDirName) { + dirName.append((toplevel_dir_name_.empty() ? "" : "/") + entryName); + }; return dirName; } -}// namespace AnalysisTree::QA +void Task::SetOutputFileName(std::string name, std::string option) { + out_file_name_ = std::move(name); + out_file_option_ = std::move(option); +} +void Task::SetTopLevelDirName(const std::string& name, bool is_append_dir_name_with_entry_name) { + toplevel_dir_name_ = name; + is_append_dir_name_with_entry_name_ = is_append_dir_name_with_entry_name; +} +void Task::ResetTopLevelDirName() { + SetTopLevelDirName(UndefTopLevelDirName, false); +} + +}// namespace QA +}// namespace AnalysisTree diff --git a/src/Task.hpp b/src/Task.hpp index bdcaa9e..232e2fa 100644 --- a/src/Task.hpp +++ b/src/Task.hpp @@ -12,6 +12,8 @@ namespace AnalysisTree { namespace QA { +const std::string UndefTopLevelDirName{"-999"}; + struct setdirectory_struct : Utils::Visitor { explicit setdirectory_struct(TDirectory* dir) : dir_(dir) {} template @@ -33,58 +35,52 @@ class Task : public AnalysisTask { void Exec() override; void Finish() override; - size_t AddH1(const std::string& name, const Axis& x, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddH1(const std::string& name, const Axis& x, Cuts* cuts = nullptr, const Variable& weight = {}); + + size_t AddH1(const Axis& x, Cuts* cuts = nullptr, const Variable& weight = {}); - size_t AddH1(const Axis& x, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddH2(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts = nullptr, const Variable& weight = {}); - size_t AddH2(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddH2(const Axis& x, const Axis& y, Cuts* cuts = nullptr, const Variable& weight = {}); - size_t AddH2(const Axis& x, const Axis& y, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddProfile(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts = nullptr, const Variable& weight = {}); - size_t AddProfile(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddProfile(const Axis& x, const Axis& y, Cuts* cuts = nullptr, const Variable& weight = {}); - size_t AddProfile(const Axis& x, const Axis& y, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddIntegral(const std::string& name, const Axis& x, Cuts* cuts = nullptr); - size_t AddIntegral(const std::string& name, const Axis& x, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddIntegral(const Axis& x, Cuts* cuts = nullptr); - size_t AddIntegral(const Axis& x, Cuts* cuts = nullptr, Variable weight = Variable{}); + size_t AddIntegral(const std::string& name, const Axis& x, const Axis& y, Cuts* cuts_x = nullptr, Cuts* cuts_y = nullptr); size_t AddIntegral(const Axis& x, const Axis& y, Cuts* cuts_x = nullptr, Cuts* cuts_y = nullptr); std::vector& Entries() { return entries_; } - void SetOutputFileName(std::string name, std::string option = "recreate") { - out_file_name_ = std::move(name); - out_file_option_ = std::move(option); - } - void SetTopLevelDirName(const std::string& name, bool is_append_dir_name_with_entry_name = false) { - toplevel_dir_name_ = name; - is_append_dir_name_with_entry_name_ = is_append_dir_name_with_entry_name; - } - void ResetTopLevelDirName() { - toplevel_dir_name_ = ""; - is_append_dir_name_with_entry_name_ = false; - } + + void SetOutputFileName(std::string name, std::string option = "recreate"); + void SetTopLevelDirName(const std::string& name, bool is_append_dir_name_with_entry_name = false); + void ResetTopLevelDirName(); private: - void FillIntegral(EntryConfig& plot); - TDirectory* MkMultiLevelDir(TFile* file, const std::string& name) const; + void FillIntegral(EntryConfig& plot) const; template - TDirectory* MkDirIfNotExists(T* fod, std::string name) const { - if (fod == nullptr) throw std::runtime_error("Task::MkDirIfNotExists(): file or directory ptr is null"); - TDirectory* result = fod->GetDirectory(name.c_str()); - if (result == nullptr) result = fod->mkdir(name.c_str()); + static TDirectory* MkDirIfNotYet(T* fileOrDirectory, const std::string& name) { + if (fileOrDirectory == nullptr) throw std::runtime_error("HelperFunctions::MkDirIfNotYet(): file or directory ptr is null"); + TDirectory* result = fileOrDirectory->GetDirectory(name.c_str()); + if (result == nullptr) fileOrDirectory->mkdir(name.c_str()); + result = fileOrDirectory->GetDirectory(name.c_str()); return result; } void CreateOutputFileIfNotYet(); - std::string ConstructOutputDirectoryName(); + std::string ConstructOutputDirectoryName() const; std::vector entries_{}; std::map dir_map_{}; std::string out_file_name_{"QA.root"}; std::string out_file_option_{"recreate"}; - std::string toplevel_dir_name_{""}; + std::string toplevel_dir_name_{UndefTopLevelDirName}; bool is_append_dir_name_with_entry_name_{false}; TFile* out_file_{nullptr};