/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PhysicsTools/Utilities/interface/RootMinuitCommands.h
254 строки
9 KB
Andrea Bocci
Apply `clang-tidy` automated code changes
18 май 2020, 13:24
Не верифицирован
18 май 2020, 13:24
46bba42
Код
Авторство
О чём код?
#ifndef PhysicsTools_Utilities_RootMinuitCommands_h #define PhysicsTools_Utilities_RootMinuitCommands_h #include "PhysicsTools/Utilities/interface/RootMinuit.h" #include "PhysicsTools/Utilities/interface/ParameterMap.h" #include "FWCore/Utilities/interface/EDMException.h" #include "PhysicsTools/Utilities/interface/Parameter.h" #include <map> #include <string> #include <cstdlib> #include <fstream> #include <sstream> #include <iostream> #include <boost/tokenizer.hpp> #include <boost/algorithm/string/join.hpp> const char* kParameter = "par"; const char* kFix = "fix"; const char* kRelease = "release"; const char* kSet = "set"; const char* kMinimize = "minimize"; const char* kMigrad = "migrad"; const char* kPrintAll = "print_all"; namespace fit { struct RootMinuitCommand { std::string name; std::vector<std::string> stringArgs; std::vector<double> doubleArgs; void print(std::ostream& cout) const { cout << name; if (!stringArgs.empty()) { for (size_t i = 0; i != stringArgs.size(); ++i) { if (i != 0) cout << ","; cout << " \"" << stringArgs[i] << "\""; } } if (!doubleArgs.empty()) { for (size_t i = 0; i != doubleArgs.size(); ++i) { if (i != 0) cout << ","; cout << " " << doubleArgs[i]; } } } }; template <class Function> class RootMinuitCommands { public: typedef RootMinuit<Function> minuit; typedef RootMinuitCommand command; RootMinuitCommands(bool verbose = true) : verbose_(verbose) {} RootMinuitCommands(const char* fileName, bool verbose = true) : verbose_(verbose) { init(fileName); } void init(const char* fileName); double par(const std::string& name) { return parameter(name).val; } double err(const std::string& name) { return parameter(name).err; } double min(const std::string& name) { return parameter(name).min; } double max(const std::string& name) { return parameter(name).max; } bool fixed(const std::string& name) { return parameter(name).fixed; } void add(RootMinuit<Function>& minuit, funct::Parameter& p) const { const std::string& name = p.name(); const parameter_t& par = parameter(name); minuit.addParameter(p, par.err, par.min, par.max); if (par.fixed) minuit.fixParameter(name); } void run(RootMinuit<Function>& minuit) const; private: typedef boost::tokenizer<boost::char_separator<char> > tokenizer; bool verbose_; unsigned int lineNumber_; parameterVector_t pars_; std::map<std::string, size_t> parIndices_; std::vector<command> commands_; double string2double(const std::string& str) const { const char* begin = str.c_str(); char* end; double val = strtod(begin, &end); size_t s = end - begin; if (s < str.size()) { throw edm::Exception(edm::errors::Configuration) << "RootMinuitCommands: invalid double value: " << str << "\n"; } return val; } const parameter_t& parameter(const std::string& name) const { typename std::map<std::string, size_t>::const_iterator p = parIndices_.find(name); if (p == parIndices_.end()) throw edm::Exception(edm::errors::Configuration) << "RootMinuit: can't find parameter " << name << "\n"; return pars_[p->second].second; } std::string errorHeader() const { std::ostringstream out; out << "RootMinuitCommands config. error, line " << lineNumber_ << ": "; return out.str(); } std::string nextToken(typename tokenizer::iterator& i, const typename tokenizer::iterator& end) const { ++i; if (i == end) throw edm::Exception(edm::errors::Configuration) << errorHeader() << "missing parameter\n"; return *i; } }; template <typename Function> void RootMinuitCommands<Function>::init(const char* fileName) { using namespace std; string cmssw_release_base = std::getenv("CMSSW_RELEASE_BASE"); string cmssw_base = std::getenv("CMSSW_BASE"); vector<string> directories; directories.reserve(3); directories.emplace_back("."); if (!cmssw_release_base.empty()) { directories.emplace_back(cmssw_release_base + "/src"); } if (!cmssw_base.empty()) { directories.emplace_back(cmssw_base + "/src"); } ifstream file; for (auto const& d : directories) { std::ifstream f{d + "/" + fileName}; if (f.good()) { file = std::move(f); break; } } if (!file.is_open()) { throw edm::Exception(edm::errors::Configuration) << "RootMinuitCommands: can't open file: " << fileName << " in path: " << boost::algorithm::join(directories, ":") << "\n"; } if (verbose_) cout << ">>> configuration file: " << fileName << endl; string line; lineNumber_ = 0; bool commands = false; while (getline(file, line)) { ++lineNumber_; if (line.empty()) continue; char last = *line.rbegin(); if (!(last >= '0' && last <= 'z')) line.erase(line.end() - 1); boost::char_separator<char> sep(" "); tokenizer tokens(line, sep); tokenizer::iterator i = tokens.begin(), e = tokens.end(); if (tokens.begin() == tokens.end()) continue; if (*(i->begin()) != '#') { if (*i == kParameter) { if (commands) throw edm::Exception(edm::errors::Configuration) << errorHeader() << "please, declare all parameter before all other minuit commands.\n"; string name = nextToken(i, e); parameter_t par; par.val = string2double(nextToken(i, e)); par.err = string2double(nextToken(i, e)); par.min = string2double(nextToken(i, e)); par.max = string2double(nextToken(i, e)); tokenizer::iterator j = i; ++j; if (j != e) { string fixed = nextToken(i, e); if (fixed == "fixed") par.fixed = true; else if (fixed == "free") par.fixed = false; else throw edm::Exception(edm::errors::Configuration) << errorHeader() << "fix parameter option unknown: " << *i << "\n" << "valid options are: fixed, free.\n"; } else { par.fixed = false; } pars_.push_back(std::make_pair(name, par)); size_t s = parIndices_.size(); parIndices_[name] = s; if (verbose_) cout << ">>> " << kParameter << " " << name << " " << par.val << " [" << par.min << ", " << par.max << "]," << " err: " << par.err << endl; } else if (*i == kFix || *i == kRelease) { commands = true; command com; com.name = *i; string arg = nextToken(i, e); com.stringArgs.push_back(arg); commands_.push_back(com); if (verbose_) { cout << ">>> "; com.print(cout); cout << endl; } } else if (*i == kSet) { commands = true; command com; com.name = *i; string arg = nextToken(i, e); com.stringArgs.push_back(arg); com.doubleArgs.push_back(string2double(nextToken(i, e))); commands_.push_back(com); if (verbose_) { cout << ">>> "; com.print(cout); cout << endl; } } else if (*i == kMinimize || *i == kMigrad || *i == kPrintAll) { commands = true; command com; com.name = *i; commands_.push_back(com); if (verbose_) { cout << ">>> "; com.print(cout); cout << endl; } } else { throw edm::Exception(edm::errors::Configuration) << errorHeader() << "unkonwn command:: " << *i << "\n"; } } } if (verbose_) cout << ">>> end configuration" << endl; } template <typename Function> void RootMinuitCommands<Function>::run(RootMinuit<Function>& minuit) const { using namespace std; typename vector<command>::const_iterator c = commands_.begin(), end = commands_.end(); for (; c != end; ++c) { if (verbose_) { cout << ">>> minuit command: "; c->print(cout); cout << endl; } if (c->name == kMinimize) minuit.minimize(); else if (c->name == kMigrad) minuit.migrad(); else if (c->name == kPrintAll) minuit.printFitResults(); else if (c->name == kFix) minuit.fixParameter(c->stringArgs[0]); else if (c->name == kRelease) minuit.releaseParameter(c->stringArgs[0]); else if (c->name == kSet) minuit.setParameter(c->stringArgs[0], c->doubleArgs[0]); } } } // namespace fit #endif