diff --git a/Analysis/Tutorials/CMakeLists.txt b/Analysis/Tutorials/CMakeLists.txt index 76260b6ce453e..33fa1fe87785e 100644 --- a/Analysis/Tutorials/CMakeLists.txt +++ b/Analysis/Tutorials/CMakeLists.txt @@ -135,6 +135,19 @@ o2_add_dpl_workflow(histogram-registry PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisCore O2::AnalysisDataModel COMPONENT_NAME AnalysisTutorial) +o2_add_library(ConfigurableCut + SOURCES src/configurableCut.cxx + PUBLIC_LINK_LIBRARIES O2::AnalysisCore) + +o2_target_root_dictionary(ConfigurableCut + HEADERS include/Analysis/configurableCut.h + LINKDEF src/ConfigurableCutLinkDef.h) + +o2_add_dpl_workflow(configurable-objects + SOURCES src/configurableObjects.cxx + PUBLIC_LINK_LIBRARIES O2::Framework O2::ConfigurableCut + COMPONENT_NAME AnalysisTutorial) + o2_add_dpl_workflow(muon-iteration SOURCES src/muonIteration.cxx PUBLIC_LINK_LIBRARIES O2::Framework O2::AnalysisCore O2::AnalysisDataModel diff --git a/Analysis/Tutorials/include/Analysis/configurableCut.h b/Analysis/Tutorials/include/Analysis/configurableCut.h new file mode 100644 index 0000000000000..84737a67fb2dc --- /dev/null +++ b/Analysis/Tutorials/include/Analysis/configurableCut.h @@ -0,0 +1,42 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#ifndef CONFIGURABLECUT_H +#define CONFIGURABLECUT_H + +#include +#include + +class configurableCut +{ + public: + configurableCut(float cut_ = 2., int state_ = 1) + : cut{cut_}, state{state_} + { + } + + bool method(float arg) const; + + void setCut(float cut_); + float getCut() const; + + void setState(int state_); + int getState() const; + + private: + float cut; + int state; + + ClassDef(configurableCut, 2); +}; + +std::ostream& operator<<(std::ostream& os, configurableCut const& c); + +#endif // CONFIGURABLECUT_H diff --git a/Analysis/Tutorials/src/ConfigurableCutLinkDef.h b/Analysis/Tutorials/src/ConfigurableCutLinkDef.h new file mode 100644 index 0000000000000..0760e732fb45f --- /dev/null +++ b/Analysis/Tutorials/src/ConfigurableCutLinkDef.h @@ -0,0 +1,15 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class configurableCut + ; diff --git a/Analysis/Tutorials/src/configurableCut.cxx b/Analysis/Tutorials/src/configurableCut.cxx new file mode 100644 index 0000000000000..fabca8db4b8cf --- /dev/null +++ b/Analysis/Tutorials/src/configurableCut.cxx @@ -0,0 +1,43 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +#include "Analysis/configurableCut.h" +#include + +bool configurableCut::method(float arg) const +{ + return arg > cut; +} + +void configurableCut::setCut(float cut_) +{ + cut = cut_; +} + +float configurableCut::getCut() const +{ + return cut; +} + +std::ostream& operator<<(std::ostream& os, configurableCut const& c) +{ + os << "Cut value: " << c.getCut() << "; state: " << c.getState(); + return os; +} + +void configurableCut::setState(int state_) +{ + state = state_; +} + +int configurableCut::getState() const +{ + return state; +} diff --git a/Analysis/Tutorials/src/configurableCut.json b/Analysis/Tutorials/src/configurableCut.json new file mode 100644 index 0000000000000..33d4294b13286 --- /dev/null +++ b/Analysis/Tutorials/src/configurableCut.json @@ -0,0 +1,21 @@ +{ + "internal-dpl-clock": "", + "internal-dpl-aod-reader": { + "aod-file": "aod.root", + "time-limit": "0", + "start-value-enumeration": "0", + "end-value-enumeration": "-1", + "step-value-enumeration": "1" + }, + "internal-dpl-aod-spawner": "", + "configurable-demo": { + "cut": { + "cut": "0.1", + "state": "1" + }, + "mutable_cut": { + "cut": "0.2", + "state": "-1" + } + } +} diff --git a/Analysis/Tutorials/src/configurableObjects.cxx b/Analysis/Tutorials/src/configurableObjects.cxx new file mode 100644 index 0000000000000..5ae293436f981 --- /dev/null +++ b/Analysis/Tutorials/src/configurableObjects.cxx @@ -0,0 +1,58 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +#include "Framework/runDataProcessing.h" +#include "Framework/AnalysisTask.h" +#include "Framework/AnalysisDataModel.h" +#include "Analysis/configurableCut.h" + +using namespace o2; +using namespace o2::framework; +using namespace o2::framework::expressions; + +/// This task demonstrates how to use configurable to wrap classes +/// use it with supplied configuration: "configurableObject.json" + +struct ConfigurableObjectDemo { + Configurable cut{"cut", {0.5, 1}, "generic cut"}; + MutableConfigurable mutable_cut{"mutable_cut", {1., 2}, "generic cut"}; + void init(InitContext const&){}; + void process(aod::Collision const&, aod::Tracks const& tracks) + { + LOGF(INFO, "Cut1: %.3f; Cut2: %.3f", cut, mutable_cut); + for (auto& track : tracks) { + if (track.globalIndex() % 500 == 0) { + std::string decision1; + std::string decision2; + if (cut->method(std::abs(track.eta()))) { + decision1 = "true"; + } else { + decision1 = "false"; + } + if (mutable_cut->method(std::abs(track.eta()))) { + decision2 = "true"; + } else { + decision2 = "false"; + } + LOGF(INFO, "Cut1: %s; Cut2: %s", decision1, decision2); + if (decision2 == "false") { + mutable_cut->setState(-1); + } else { + mutable_cut->setState(1); + } + } + } + } +}; + +WorkflowSpec defineDataProcessing(ConfigContext const&) +{ + return WorkflowSpec{ + adaptAnalysisTask("configurable-demo")}; +} diff --git a/Framework/Core/include/Framework/Configurable.h b/Framework/Core/include/Framework/Configurable.h index 8e6917cc596dd..118e7afa99d93 100644 --- a/Framework/Core/include/Framework/Configurable.h +++ b/Framework/Core/include/Framework/Configurable.h @@ -12,29 +12,65 @@ #include namespace o2::framework { -/// This helper allows you to create a configurable option associated to a task. -/// Internally it will be bound to a ConfigParamSpec. template -struct Configurable { - Configurable(std::string const& name, T defaultValue, std::string const& help) - : name(name), value(defaultValue), help(help) +struct ConfigurableBase { + ConfigurableBase(std::string const& name, T&& defaultValue, std::string const& help) + : name(name), value{std::move(defaultValue)}, help(help) { } using type = T; std::string name; T value; std::string help; +}; + +template +struct ConfigurablePolicyConst : ConfigurableBase { + ConfigurablePolicyConst(std::string const& name, T&& defaultValue, std::string const& help) + : ConfigurableBase{name, std::forward(defaultValue), help} + { + } operator T() { - return value; + return this->value; } T const* operator->() const { - return &value; + return &this->value; + } +}; + +template +struct ConfigurablePolicyMutable : ConfigurableBase { + ConfigurablePolicyMutable(std::string const& name, T&& defaultValue, std::string const& help) + : ConfigurableBase{name, std::forward(defaultValue), help} + { + } + operator T() + { + return this->value; + } + T* operator->() + { + return &this->value; + } +}; + +/// This helper allows you to create a configurable option associated to a task. +/// Internally it will be bound to a ConfigParamSpec. +template > +struct Configurable : IP { + Configurable(std::string const& name, T&& defaultValue, std::string const& help) + : IP{name, std::forward(defaultValue), help} + { } }; + template -std::ostream& operator<<(std::ostream& os, Configurable const& c) +using MutableConfigurable = Configurable>; + +template +std::ostream& operator<<(std::ostream& os, Configurable const& c) { os << c.value; return os; diff --git a/Framework/Core/src/AnalysisManagers.h b/Framework/Core/src/AnalysisManagers.h index bba95b523034e..82aa5c52e7a18 100644 --- a/Framework/Core/src/AnalysisManagers.h +++ b/Framework/Core/src/AnalysisManagers.h @@ -355,9 +355,9 @@ struct OptionManager { } }; -template -struct OptionManager> { - static bool appendOption(std::vector& options, Configurable& what) +template +struct OptionManager> { + static bool appendOption(std::vector& options, Configurable& what) { if constexpr (variant_trait_v::type> != VariantType::Unknown) { options.emplace_back(ConfigParamSpec{what.name, variant_trait_v::type>, what.value, {what.help}}); @@ -368,7 +368,7 @@ struct OptionManager> { return true; } - static bool prepare(InitContext& context, Configurable& what) + static bool prepare(InitContext& context, Configurable& what) { if constexpr (variant_trait_v::type> != VariantType::Unknown) { what.value = context.options().get(what.name.c_str());