Search Results
ParameterSet.h
/*
* MoMEMta: a modular implementation of the Matrix Element Method
* Copyright (C) 2016 Universite catholique de Louvain (UCL), Belgium
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <memory>
#include <string>
#include <momemta/any.h>
#include <momemta/InputTag.h>
#include <momemta/impl/traits.h>
#include <momemta/Logging.h>
#include <momemta/Utils.h>
struct InputTag;
class ConfigurationReader;
class Configuration;
class ParameterSet;
namespace momemta {
struct ArgDef;
void setInputTagsForInput(const ArgDef&, ParameterSet&, const std::vector<InputTag>&);
class ComputationGraph;
}
class ParameterSet {
public:
ParameterSet() = default;
template<typename T> const T& get(const std::string& name) const {
auto value = m_set.find(name);
if (value == m_set.end())
throw not_found_error("Parameter '" + name + "' not found.");
try {
return momemta::any_cast<const T&>(value->second.value);
} catch (const momemta::bad_any_cast& e) {
LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
<< demangle(typeid(T).name())
<< "' while parameter is a '"
<< demangle(value->second.value.type().name())
<< "'";
throw e;
}
}
template<typename T> T& get(const std::string& name) {
auto value = m_set.find(name);
if (value == m_set.end())
throw not_found_error("Parameter '" + name + "' not found.");
try {
return momemta::any_cast<T&>(value->second.value);
} catch (const momemta::bad_any_cast& e) {
LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
<< demangle(typeid(T).name())
<< "' while parameter is a '"
<< demangle(value->second.value.type().name())
<< "'";
throw e;
}
}
template<typename T> const T& get(const std::string& name, const T& defaultValue) const {
auto value = m_set.find(name);
if (value == m_set.end())
return defaultValue;
try {
return momemta::any_cast<const T&>(value->second.value);
} catch (const momemta::bad_any_cast &e) {
LOG(fatal) << "Exception while trying to get parameter '" << name << "'. Requested a '"
<< demangle(typeid(T).name())
<< "' while parameter is a '"
<< demangle(value->second.value.type().name())
<< "'";
throw e;
}
}
const momemta::any& rawGet(const std::string& name) const;
bool exists(const std::string& name) const;
template<typename T> bool existsAs(const std::string& name) const {
auto value = m_set.find(name);
return (value != m_set.end() && value->second.value.type() == typeid(T));
}
template<typename T>
typename std::enable_if<std::is_same<T, bool>::value ||
std::is_same<T, InputTag>::value>::type set(const std::string& name, const T& value) {
set_helper(name, value);
}
template<typename T>
void set(const std::string& name, const std::vector<T>& value) {
static_assert(
std::is_same<T, int64_t>::value ||
std::is_same<T, double>::value ||
std::is_same<T, bool>::value ||
std::is_same<T, std::string>::value ||
std::is_same<T, InputTag>::value,
"Type not supported"
);
set_helper(name, value);
}
template<typename T>
typename std::enable_if<is_string<T>::value>::type set(const std::string& name, const T& value) {
set_helper(name, std::string(value));
}
template<typename T>
typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, bool>::value>::type set(const std::string& name, const T& value) {
set_helper(name, static_cast<int64_t>(value));
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type set(const std::string& name, const T& value) {
set_helper(name, static_cast<double>(value));
}
std::string getModuleName() const {
return get<std::string>("@name", "");
}
std::string getModuleType() const {
return get<std::string>("@type", "");
}
const ParameterSet& globalParameters() const {
auto it = m_set.find("@global_parameters");
if (it == m_set.end())
return *this;
return momemta::any_cast<const ParameterSet&>(it->second.value);
}
virtual ParameterSet* clone() const;
std::vector<std::string> getNames() const;
protected:
friend class ConfigurationReader;
friend class Configuration;
friend class ParameterSetParser;
friend class momemta::ComputationGraph;
friend void momemta::setInputTagsForInput(const momemta::ArgDef&, ParameterSet&, const std::vector<InputTag>&);
struct Element {
momemta::any value;
bool lazy = false;
template <typename T>
Element(const T& v) {
value = v;
}
template <typename T>
Element(const T& v, bool l) {
value = v;
lazy = l;
}
};
ParameterSet(const std::string& module_type, const std::string& module_name);
virtual bool lazy() const;
virtual void create(const std::string& name, const momemta::any& value);
virtual void setInternal(const std::string& name, Element& element, const momemta::any& value);
virtual void freeze();
std::map<std::string, Element> m_set;
private:
class not_found_error: public std::runtime_error {
using std::runtime_error::runtime_error;
};
class frozen_error: public std::runtime_error {
using std::runtime_error::runtime_error;
};
void setGlobalParameters(const ParameterSet&);
template<typename T>
void set_helper(const std::string& name, const T& value) {
static_assert(
std::is_same<T, int64_t>::value ||
std::is_same<T, double>::value ||
std::is_same<T, bool>::value ||
std::is_same<T, std::string>::value ||
std::is_same<T, InputTag>::value ||
std::is_same<T, std::vector<int64_t>>::value ||
std::is_same<T, std::vector<double>>::value ||
std::is_same<T, std::vector<bool>>::value ||
std::is_same<T, std::vector<std::string>>::value ||
std::is_same<T, std::vector<InputTag>>::value,
"Type not supported"
);
if (frozen) {
LOG(fatal) << "You are not allowed to edit a set once frozen.";
throw frozen_error("This ParameterSet is frozen");
}
raw_set(name, value);
}
template <typename T>
void raw_set(const std::string& name, const T& value) {
auto it = m_set.find(name);
// If the element does not exist in the set, we create it
// Otherwise, we simply update the value
if (it == m_set.end()) {
create(name, value);
} else {
setInternal(name, it->second, value);
}
}
void remove(const std::string& name);
bool frozen = false;
};