CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
RootMinuitCommands.h
Go to the documentation of this file.
1 #ifndef PhysicsTools_Utilities_RootMinuitCommands_h
2 #define PhysicsTools_Utilities_RootMinuitCommands_h
7 #include <map>
8 #include <string>
9 #include <cstdlib>
10 #include <fstream>
11 #include <sstream>
12 #include <iostream>
13 #include <boost/tokenizer.hpp>
14 #include <boost/algorithm/string/join.hpp>
15 
16 const char* kParameter = "par";
17 const char* kFix = "fix";
18 const char* kRelease = "release";
19 const char* kSet = "set";
20 const char* kMinimize = "minimize";
21 const char* kMigrad = "migrad";
22 const char* kPrintAll = "print_all";
23 
24 namespace fit {
25 
28  std::vector<std::string> stringArgs;
29  std::vector<double> doubleArgs;
30  void print(std::ostream& cout) const {
31  cout << name;
32  if (!stringArgs.empty()) {
33  for (size_t i = 0; i != stringArgs.size(); ++i) {
34  if (i != 0)
35  cout << ",";
36  cout << " \"" << stringArgs[i] << "\"";
37  }
38  }
39  if (!doubleArgs.empty()) {
40  for (size_t i = 0; i != doubleArgs.size(); ++i) {
41  if (i != 0)
42  cout << ",";
43  cout << " " << doubleArgs[i];
44  }
45  }
46  }
47  };
48 
49  template <class Function>
51  public:
55  RootMinuitCommands(const char* fileName, bool verbose = true) : verbose_(verbose) { init(fileName); }
56  void init(const char* fileName);
57  double par(const std::string& name) { return parameter(name).val; }
58  double err(const std::string& name) { return parameter(name).err; }
59  double min(const std::string& name) { return parameter(name).min; }
60  double max(const std::string& name) { return parameter(name).max; }
61  bool fixed(const std::string& name) { return parameter(name).fixed; }
63  const std::string& name = p.name();
64  const parameter_t& par = parameter(name);
65  minuit.addParameter(p, par.err, par.min, par.max);
66  if (par.fixed)
67  minuit.fixParameter(name);
68  }
69  void run(RootMinuit<Function>& minuit) const;
70 
71  private:
72  typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
73  bool verbose_;
74  unsigned int lineNumber_;
76  std::map<std::string, size_t> parIndices_;
77  std::vector<command> commands_;
78  double string2double(const std::string& str) const {
79  const char* begin = str.c_str();
80  char* end;
81  double val = strtod(begin, &end);
82  size_t s = end - begin;
83  if (s < str.size()) {
84  throw edm::Exception(edm::errors::Configuration) << "RootMinuitCommands: invalid double value: " << str << "\n";
85  }
86  return val;
87  }
88  const parameter_t& parameter(const std::string& name) const {
89  typename std::map<std::string, size_t>::const_iterator p = parIndices_.find(name);
90  if (p == parIndices_.end())
91  throw edm::Exception(edm::errors::Configuration) << "RootMinuit: can't find parameter " << name << "\n";
92  return pars_[p->second].second;
93  }
95  std::ostringstream out;
96  out << "RootMinuitCommands config. error, line " << lineNumber_ << ": ";
97  return out.str();
98  }
99  std::string nextToken(typename tokenizer::iterator& i, const typename tokenizer::iterator& end) const {
100  ++i;
101  if (i == end)
102  throw edm::Exception(edm::errors::Configuration) << errorHeader() << "missing parameter\n";
103  return *i;
104  }
105  };
106 
107  template <typename Function>
109  using namespace std;
110  string cmssw_release_base = std::getenv("CMSSW_RELEASE_BASE");
111  string cmssw_base = std::getenv("CMSSW_BASE");
112  vector<string> directories;
113  directories.reserve(3);
114  directories.emplace_back(".");
115  if (!cmssw_release_base.empty()) {
116  directories.emplace_back(cmssw_release_base + "/src");
117  }
118  if (!cmssw_base.empty()) {
119  directories.emplace_back(cmssw_base + "/src");
120  }
121  ifstream file;
122  for (auto const& d : directories) {
123  std::ifstream f{d + "/" + fileName};
124  if (f.good()) {
125  file = std::move(f);
126  break;
127  }
128  }
129  if (!file.is_open()) {
131  << "RootMinuitCommands: can't open file: " << fileName
132  << " in path: " << boost::algorithm::join(directories, ":") << "\n";
133  }
134  if (verbose_)
135  cout << ">>> configuration file: " << fileName << endl;
136  string line;
137  lineNumber_ = 0;
138  bool commands = false;
139  while (getline(file, line)) {
140  ++lineNumber_;
141  if (line.empty())
142  continue;
143  char last = *line.rbegin();
144  if (!(last >= '0' && last <= 'z'))
145  line.erase(line.end() - 1);
146  boost::char_separator<char> sep(" ");
147  tokenizer tokens(line, sep);
148  tokenizer::iterator i = tokens.begin(), e = tokens.end();
149  if (tokens.begin() == tokens.end())
150  continue;
151  if (*(i->begin()) != '#') {
152  if (*i == kParameter) {
153  if (commands)
155  << errorHeader() << "please, declare all parameter before all other minuit commands.\n";
156  string name = nextToken(i, e);
157  parameter_t par;
158  par.val = string2double(nextToken(i, e));
159  par.err = string2double(nextToken(i, e));
160  par.min = string2double(nextToken(i, e));
161  par.max = string2double(nextToken(i, e));
162  tokenizer::iterator j = i;
163  ++j;
164  if (j != e) {
165  string fixed = nextToken(i, e);
166  if (fixed == "fixed")
167  par.fixed = true;
168  else if (fixed == "free")
169  par.fixed = false;
170  else
172  << errorHeader() << "fix parameter option unknown: " << *i << "\n"
173  << "valid options are: fixed, free.\n";
174  } else {
175  par.fixed = false;
176  }
177  pars_.push_back(std::make_pair(name, par));
178  size_t s = parIndices_.size();
179  parIndices_[name] = s;
180  if (verbose_)
181  cout << ">>> " << kParameter << " " << name << " " << par.val << " [" << par.min << ", " << par.max << "],"
182  << " err: " << par.err << endl;
183  } else if (*i == kFix || *i == kRelease) {
184  commands = true;
185  command com;
186  com.name = *i;
187  string arg = nextToken(i, e);
188  com.stringArgs.push_back(arg);
189  commands_.push_back(com);
190  if (verbose_) {
191  cout << ">>> ";
192  com.print(cout);
193  cout << endl;
194  }
195  } else if (*i == kSet) {
196  commands = true;
197  command com;
198  com.name = *i;
199  string arg = nextToken(i, e);
200  com.stringArgs.push_back(arg);
201  com.doubleArgs.push_back(string2double(nextToken(i, e)));
202  commands_.push_back(com);
203  if (verbose_) {
204  cout << ">>> ";
205  com.print(cout);
206  cout << endl;
207  }
208  } else if (*i == kMinimize || *i == kMigrad || *i == kPrintAll) {
209  commands = true;
210  command com;
211  com.name = *i;
212  commands_.push_back(com);
213  if (verbose_) {
214  cout << ">>> ";
215  com.print(cout);
216  cout << endl;
217  }
218  } else {
219  throw edm::Exception(edm::errors::Configuration) << errorHeader() << "unkonwn command:: " << *i << "\n";
220  }
221  }
222  }
223  if (verbose_)
224  cout << ">>> end configuration" << endl;
225  }
226 
227  template <typename Function>
229  using namespace std;
230  typename vector<command>::const_iterator c = commands_.begin(), end = commands_.end();
231  for (; c != end; ++c) {
232  if (verbose_) {
233  cout << ">>> minuit command: ";
234  c->print(cout);
235  cout << endl;
236  }
237  if (c->name == kMinimize)
238  minuit.minimize();
239  else if (c->name == kMigrad)
240  minuit.migrad();
241  else if (c->name == kPrintAll)
242  minuit.printFitResults();
243  else if (c->name == kFix)
244  minuit.fixParameter(c->stringArgs[0]);
245  else if (c->name == kRelease)
246  minuit.releaseParameter(c->stringArgs[0]);
247  else if (c->name == kSet)
248  minuit.setParameter(c->stringArgs[0], c->doubleArgs[0]);
249  }
250  }
251 
252 } // namespace fit
253 
254 #endif
double min(const std::string &name)
void init(const char *fileName)
std::string errorHeader() const
const edm::EventSetup & c
const std::string & name() const
Definition: Parameter.h:12
boost::tokenizer< boost::char_separator< char > > tokenizer
std::vector< std::string > stringArgs
void printFitResults(std::ostream &cout=std::cout)
Definition: RootMinuit.h:177
bool verbose
void setParameter(const std::string &name, double val)
Definition: RootMinuit.h:99
double migrad()
Definition: RootMinuit.h:146
void fixParameter(const std::string &name)
Definition: RootMinuit.h:85
double par(const std::string &name)
void run(RootMinuit< Function > &minuit) const
std::vector< command > commands_
std::vector< double > doubleArgs
A arg
Definition: Factorize.h:31
std::string nextToken(typename tokenizer::iterator &i, const typename tokenizer::iterator &end) const
bool fixed(const std::string &name)
const char * kSet
tuple d
Definition: ztail.py:151
const char * kParameter
std::vector< std::pair< std::string, parameter_t > > parameterVector_t
Definition: ParameterMap.h:14
const char * kFix
double minimize()
Definition: RootMinuit.h:129
auto const & fit
def move
Definition: eostools.py:511
void print(std::ostream &cout) const
const char * kPrintAll
double string2double(const std::string &str) const
std::map< std::string, size_t > parIndices_
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
double max(const std::string &name)
void add(RootMinuit< Function > &minuit, funct::Parameter &p) const
const parameter_t & parameter(const std::string &name) const
double err(const std::string &name)
const char * kMigrad
const char * kRelease
RootMinuitCommand command
string end
Definition: dataset.py:937
tuple cout
Definition: gather_cfg.py:144
tuple cmssw_base
RootMinuit< Function > minuit
const char * kMinimize
tuple last
Definition: dqmdumpme.py:56
void releaseParameter(const std::string &name)
Definition: RootMinuit.h:92
#define str(s)
RootMinuitCommands(const char *fileName, bool verbose=true)
RootMinuitCommands(bool verbose=true)
void addParameter(const std::string &name, std::shared_ptr< double > val, double err, double min, double max)
Definition: RootMinuit.h:26