11 #include <BAT/BCParameter.h>
13 #include <BAT/BCAux.h>
14 #include <BAT/BCLog.h>
15 #include <BAT/BCSummaryTool.h>
28 const std::string& ModelConf_i,
29 const std::string& MonteCarloConf_i,
30 const std::string& OutFile_i,
31 const std::string& JobTag_i)
32 : myInputParser(ModelF, ThObsF), MCEngine(ModPars, Obs, Obs2D, CGO, CGP) {
36 if (OutFile_i.compare(
"") == 0)
OutFile =
"MCout" +
JobTag +
".root";
54 if (rank == 0)
throw std::runtime_error(
"ERROR: MonteCarlo::TestRun() cannot be called after calling MonteCarlo::Run().\n");
62 std::map<std::string, double> DP;
63 if (
Obs.size() == 0 &&
CGO.size() == 0)
throw std::runtime_error(
"\nMonteCarlo::TestRun(): No observables or correlated Gaussian observables defined in SomeModel.conf file\n");
65 for (std::vector<ModelParameter>::iterator it =
ModPars.begin(); it <
ModPars.end(); it++) {
66 if (it->IsCorrelated()) {
67 for (
unsigned int i = 0; i <
CGP.size(); i++) {
68 if (
CGP[i].getName().compare(it->getCgp_name()) == 0) {
69 std::string index = it->getname().substr(
CGP[i].getName().size());
70 long int lindex = strtol(index.c_str(), NULL, 10);
72 DP[
CGP[i].getPar(lindex - 1).getname()] = CGP[i].getPar(lindex - 1).getave();
74 std::stringstream out;
76 throw std::runtime_error(
"MonteCarlo::Run(): " + out.str() +
"seems to be part of a CorrelatedGaussianParameters object, but I couldn't find the corresponding object");
81 DP[it->getname()] = it->getave();
85 if (rank == 0)
throw std::runtime_error(
"ERROR: Parameter(s) missing in model initialization. \n");
89 if (
Obs.size() > 0) std::cout <<
"\nOservables: \n" << std::endl;
90 for (boost::ptr_vector<Observable>::iterator it =
Obs.begin(); it <
Obs.end(); it++) {
91 double th = it->computeTheoryValue();
92 std::cout << it->getName() <<
" = " << th << std::endl;
95 if (
CGO.size() > 0) std::cout <<
"\nCorrelated Gaussian Oservables: \n" << std::endl;
96 for (std::vector<CorrelatedGaussianObservables>::iterator it1 =
CGO.begin(); it1 <
CGO.end(); it1++) {
97 std::cout << it1->getName() <<
":" << std::endl;
98 std::vector<Observable> ObsInCGO = it1->getObs();
99 for (std::vector<Observable>::iterator it2 = ObsInCGO.begin(); it2 < ObsInCGO.end(); it2++) {
100 double th = it2->computeTheoryValue();
101 std::cout << it2->getName() <<
" = " << th << std::endl;
103 std::cout << std::endl;
110 if (rank == 0)
throw std::runtime_error(
"ERROR: MonteCarlo::Run() cannot be called after calling MonteCarlo::TestRun().\n");
121 std::map<std::string, double> DP;
122 for (std::vector<ModelParameter>::iterator it =
ModPars.begin(); it <
ModPars.end(); it++) {
123 if (it->geterrg() > 0. || it->geterrf() > 0.)
125 if (it->IsCorrelated()) {
126 for (
unsigned int i = 0; i <
CGP.size(); i++) {
127 if (
CGP[i].getName().compare(it->getCgp_name()) == 0) {
128 std::string index = it->getname().substr(
CGP[i].getName().size());
129 long int lindex = strtol(index.c_str(), NULL, 10);
131 DP[
CGP[i].getPar(lindex - 1).getname()] = CGP[i].getPar(lindex - 1).getave();
133 std::stringstream out;
134 out << it->getname();
135 throw std::runtime_error(
"MonteCarlo::Run(): " + out.str() +
"seems to be part of a CorrelatedGaussianParameters object, but I couldn't find the corresponding object");
140 DP[it->getname()] = it->getave();
143 if (rank == 0)
throw std::runtime_error(
"No parameters being varied. Aborting MCMC run.\n");
148 if (rank == 0)
throw std::runtime_error(
"\nERROR: Model cannot be initialization.\n");
152 if (rank == 0) std::cout << std::endl <<
"Running in MonteCarlo mode...\n" << std::endl;
157 if (gSystem->GetPathInfo(
ObsDirName.c_str(), info) != 0) {
158 if (gSystem->MakeDirectory(
ObsDirName.c_str()) == 0)
159 std::cout <<
ObsDirName <<
" directory has been created." << std::endl;
161 throw std::runtime_error(
"ERROR: " +
ObsDirName +
" directory cannot be created.\n");
169 double *recvbuff =
new double[buffsize];
174 double **sendbuff =
new double*[1];
175 sendbuff[0] =
new double[1];
177 std::vector<double> pars;
178 int obsbuffsize =
Obs.size() + 2 *
Obs2D.size();
179 for (std::vector<CorrelatedGaussianObservables>::iterator it1 =
CGO.begin(); it1 <
CGO.end(); it1++)
180 obsbuffsize += it1->getObs().size();
183 MPI::COMM_WORLD.Scatter(sendbuff[0], buffsize, MPI::DOUBLE,
184 recvbuff, buffsize, MPI::DOUBLE, 0);
186 if (recvbuff[0] == 0.) {
188 MPI::COMM_WORLD.Gather(&ll, 1, MPI::DOUBLE, sendbuff[0], 1, MPI::DOUBLE, 0);
189 }
else if (recvbuff[0] == 1.) {
190 pars.assign(recvbuff + 1, recvbuff + buffsize);
192 MPI::COMM_WORLD.Gather(&ll, 1, MPI::DOUBLE, sendbuff[0], 1, MPI::DOUBLE, 0);
193 }
else if (recvbuff[0] == 2.) {
194 double sbuff[obsbuffsize];
195 std::map<std::string, double> DPars;
196 pars.assign(recvbuff + 1, recvbuff + buffsize);
201 for (boost::ptr_vector<Observable>::iterator it =
Obs.begin(); it <
Obs.end(); it++) {
202 sbuff[k++] = it->computeTheoryValue();
204 for (std::vector<Observable2D>::iterator it =
Obs2D.begin(); it <
Obs2D.end(); it++) {
205 sbuff[k++] = it->computeTheoryValue();
206 sbuff[k++] = it->computeTheoryValue2();
209 for (std::vector<CorrelatedGaussianObservables>::iterator it1 =
CGO.begin(); it1 <
CGO.end(); it1++) {
210 std::vector<Observable> pino(it1->getObs());
211 for (std::vector<Observable>::iterator it = pino.begin(); it != pino.end(); ++it)
212 sbuff[k++] = it->computeTheoryValue();
214 MPI::COMM_WORLD.Gather(sbuff, obsbuffsize, MPI::DOUBLE, sendbuff[0], obsbuffsize, MPI::DOUBLE, 0);
215 }
else if (recvbuff[0] == 3.) {
216 double sbuff[obsbuffsize];
217 MPI::COMM_WORLD.Gather(sbuff, obsbuffsize, MPI::DOUBLE, sendbuff[0], obsbuffsize, MPI::DOUBLE, 0);
218 }
else if (recvbuff[0] == -1.)
221 std::cout <<
"recvbuff = " << recvbuff[0] <<
" rank " << rank << std::endl;
222 throw "MonteCarlo::Run(): error in MPI message!\n";
230 bool writechains =
false;
231 std::cout << std::endl;
232 std::cout << std::endl;
233 if (
ModPars.size() > 0) std::cout <<
ModPars.size() <<
" parameters defined." << std::endl;
234 if (
Obs.size() > 0) std::cout <<
Obs.size() <<
" observables defined." << std::endl;
235 if (
Obs2D.size() > 0) std::cout <<
Obs2D.size() <<
" 2D observables defined." << std::endl;
236 if (
CGO.size() > 0) std::cout <<
CGO.size() <<
" correlated gaussian observables defined";
238 std::cout <<
"." << std::endl;
240 std::cout <<
":" << std::endl;
241 for (std::vector<CorrelatedGaussianObservables>::iterator it1 =
CGO.begin();
242 it1 !=
CGO.end(); ++it1)
243 std::cout <<
" " << it1->getName() <<
" containing "
244 << it1->getObs().size() <<
" observables." << std::endl;
246 std::ifstream ifile(
MCMCConf.c_str());
247 if (!ifile.is_open())
248 throw std::runtime_error(
"\nERROR: " +
MCMCConf +
" does not exist. Make sure to specify a valid Monte Carlo configuration file.\n");
252 IsEOF = getline(ifile, line).eof();
253 if (*line.rbegin() ==
'\r') line.erase(line.length() - 1);
254 if (line.empty() || line.at(0) ==
'#')
256 boost::char_separator<char> sep(
" \t");
257 boost::tokenizer<boost::char_separator<char> > tok(line, sep);
258 boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin();
259 if (beg->compare(
"NChains") == 0) {
262 }
else if (beg->compare(
"PrerunMaxIter") == 0) {
264 MCEngine.MCMCSetNIterationsMax(atoi((*beg).c_str()));
265 }
else if (beg->compare(
"NIterationsUpdateMax") == 0) {
267 MCEngine.MCMCSetNIterationsUpdateMax(atoi((*beg).c_str()));
268 }
else if (beg->compare(
"Seed") == 0) {
270 int seed = atoi((*beg).c_str());
273 }
else if (beg->compare(
"Iterations") == 0) {
275 MCEngine.MCMCSetNIterationsRun(atoi((*beg).c_str()));
276 }
else if (beg->compare(
"MinimumEfficiency") == 0) {
278 MCEngine.MCMCSetMinimumEfficiency(atof((*beg).c_str()));
279 }
else if (beg->compare(
"WriteChain") == 0) {
281 if (beg->compare(
"true") == 0)
283 }
else if (beg->compare(
"FindModeWithMinuit") == 0) {
285 if (beg->compare(
"true") == 0) {
288 }
else if (beg->compare(
"CalculateNormalization") == 0) {
290 if (beg->compare(
"true") == 0) {
293 }
else if (beg->compare(
"PrintAllMarginalized") == 0) {
295 if (beg->compare(
"true") == 0) {
298 }
else if (beg->compare(
"PrintCorrelationMatrix") == 0) {
300 if (beg->compare(
"true") == 0) {
303 }
else if (beg->compare(
"PrintKnowledgeUpdatePlots") == 0) {
305 if (beg->compare(
"true") == 0) {
308 }
else if (beg->compare(
"PrintParameterPlot") == 0) {
310 if (beg->compare(
"true") == 0) {
313 }
else if (beg->compare(
"WritePreRunData") == 0) {
315 if (beg->compare(
"true") == 0) {
318 }
else if (beg->compare(
"ReadPreRunData") == 0) {
321 }
else if (beg->compare(
"OrderParameters") == 0) {
323 if (beg->compare(
"false") == 0) {
324 MCEngine.MCMCSetFlagOrderParameters(
false);
326 }
else if (beg->compare(
"StatOverFlow") == 0) {
330 else throw std::runtime_error(
"\nERROR: Wrong value in MonteCarlo config file for keyword StatOverFlow. It can be either true or false.\n");
332 throw std::runtime_error(
"\nERROR: Wrong keyword in MonteCarlo config file: " + *beg +
"\n Make sure to specify a valid Monte Carlo configuration file.\n");
337 out.WriteMarkovChain(
true);
345 BCLog::OpenLog((
"log" +
JobTag +
".txt").c_str());
346 BCLog::SetLogLevel(BCLog::debug);
350 MCEngine.SetMarginalizationMethod(BCIntegrate::kMargMetropolis);
351 std::time_t ti = std::time(NULL);
353 if (std::strftime(mbstr,
sizeof(mbstr),
"%H:%M:%S %d/%m/%y ", std::localtime(&ti)))
354 std::cout <<
"MCMC Run started at " << mbstr << std::endl;
356 std::time_t tf = std::time(NULL);
357 if (std::strftime(mbstr,
sizeof(mbstr),
"%H:%M:%S %d/%m/%y ", std::localtime(&tf)))
358 std::cout <<
"MCMC Run ended at " << mbstr << std::endl;
368 MCEngine.PrintAllMarginalized((
"MonteCarlo_plots" +
JobTag +
".pdf").c_str());
371 MCEngine.PrintResults((
"MonteCarlo_results" +
JobTag +
".txt").c_str());
376 BCSummaryTool myBCSummaryTool(&
MCEngine);
380 myBCSummaryTool.PrintCorrelationMatrix((
"ParamCorrelations" +
JobTag +
".pdf").c_str());
389 myBCSummaryTool.PrintKnowledgeUpdatePlots((
"ParamUpdate" +
JobTag +
".pdf").c_str());
393 myBCSummaryTool.PrintParameterPlot((
"ParamSummary" +
JobTag +
".pdf").c_str());
398 out.WriteMarginalizedDistributions();
399 out.FillAnalysisTree();
403 std::ofstream outHistoLog;
404 outHistoLog.open((
ObsDirName +
"/HistoLog" +
JobTag +
".txt").c_str(), std::ios::out);
409 std::ofstream outStatLog;
410 outStatLog.open((
ObsDirName +
"/Statistics" +
JobTag +
".txt").c_str(), std::ios::out);
417 std::ofstream outPreRun;
418 outPreRun.open((
"PreRun" +
JobTag +
".txt").c_str(), std::ios::out);
424 std::stringstream ss;
426 BCLog::OutSummary(ss.str().c_str());
429 BCLog::OutSummary(ss.str().c_str());
435 double ** sendbuff =
new double *[
MCEngine.procnum];
436 sendbuff[0] =
new double[
MCEngine.procnum * buffsize];
437 for (
int il = 1; il <
MCEngine.procnum; il++) {
438 sendbuff[il] = sendbuff[il - 1] + buffsize;
439 sendbuff[il][0] = -1.;
441 MPI::COMM_WORLD.Scatter(sendbuff[0], buffsize, MPI::DOUBLE,
442 recvbuff, buffsize, MPI::DOUBLE, 0);
450 }
catch (std::string message) {
451 std::cerr << message << std::endl;
458 std::ifstream ifile(file.c_str());
459 if (!ifile.is_open())
460 throw std::runtime_error(
"\nMonteCarlo::ReadPreRunData ERROR: " + file +
" does not exist.\n");
463 std::vector<double> mode;
464 std::vector<double> scale;
466 IsEOF = getline(ifile, line).eof();
469 boost::char_separator<char> sep(
" ");
470 boost::tokenizer<boost::char_separator<char> > tok(line, sep);
471 boost::tokenizer<boost::char_separator<char> >::iterator beg = tok.begin();
473 mode.push_back(atof((*beg).c_str()));
475 scale.push_back(atof((*beg).c_str()));
477 if (mode.size() !=
MCEngine.GetNParameters())
478 throw std::runtime_error(
"\nMonteCarlo::ReadPreRunData ERROR: wrong data size.\n");
479 std::vector<double> mode_all;
480 std::vector<double> scale_all;
481 for (
unsigned int i = 0; i <
MCEngine.MCMCGetNChains(); i++){
482 mode_all.insert(mode_all.end(), mode.begin(), mode.end());
483 scale_all.insert(scale_all.end(), scale.begin(), scale.end());
485 MCEngine.MCMCSetInitialPositions(mode_all);
486 MCEngine.MCMCSetTrialFunctionScaleFactor(scale_all);
bool checkrun
A check to make sure TestRun()and Run() are not called consecutively.
double normalization
A variable to store the evidence of a model.
virtual bool Update(const std::map< std::string, double > &DPars)
The update method for StandardModel.
std::string ObsDirName
String for the output directory name.
std::string computeStatistics()
A get method to compute the mean and rms of the computed observables.
void addCustomObservableType(const std::string name, boost::function< Observable *() > funct)
std::string getHistoLog() const
A get method to access the stream that stores the log messages coming from histogram printing and che...
int getNumOfDiscardedEvents() const
A get method to access the number of events discarded due to failure to update model. These events are not used for the MCMC run.
bool CalculateNormalization
< Flag for calculating the evidence.
void ReadPreRunData(std::string file)
bool PrintParameterPlot
Flag for printing the overview parameter plots.
MonteCarloEngine MCEngine
An object of the MonteCarloEngine class.
void PrintHistogram(BCModelOutput &out, Observable &it, const std::string OutputDir)
Overloaded from PrintHistogram(BCModelOutput&, const std::string) to print histogram for observables...
std::string OutFile
String for the name of the output root file without the .root extension.
double computeNormalization()
bool PrintAllMarginalized
Flag for printing all Marginalized distributions to be passed on to the BAT routines.
void Run(const int rank)
This member is responsible for setting the Monte Carlo run parameters and conducting the Monte Carlo ...
bool WritePreRunData
Flag for printing the overview parameter plots.
void AddChains()
A method to add the observable values and weights to the chain information.
std::vector< CorrelatedGaussianParameters > CGP
Vector for the Correlated Gaussian Parameters defined in SomeModel.conf.
virtual bool Init(const std::map< std::string, double > &DPars)
A method to initialize the model parameters.
std::vector< ModelParameter > ModPars
Vector for the model parameters defined in SomeModel.conf.
void setDParsFromParameters(const std::vector< double > ¶meters, std::map< std::string, double > &DPars_i)
bool PrintKnowledgeUpdatePlots
Flag for printing plots to compare prior vs. posterior knowledge of parameters.
void TestRun(int rank)
The default destructor.
bool PrintCorrelationMatrix
Flag for printing the correlation matrix.
std::string ModelName
The name of the model.
void setNChains(unsigned int i)
A set method to fix the number of chains.
std::string writePreRunData()
A method to write in a text file the best fit parameters and the prerun scale factors.
MonteCarlo(ModelFactory &ModelF, ThObsFactory &ThObsF, const std::string &ModelConf_i, const std::string &MonteCarloConf_i, const std::string &OutFile_i, const std::string &JobTag_i)
Constructor.
std::vector< Observable2D > Obs2D
Vector for the Observables2D defined in SomeModel.conf.
void setHistogramOverFlow(bool overflow)
boost::ptr_vector< Observable > Obs
Vector for the observables defined in SomeModel.conf.
void PrintCorrelationMatrix(const std::string filename)
This member generates the correlation matrix using BCH2D from the BAT libraries.
complex log(const complex &z)
std::vector< CorrelatedGaussianObservables > CGO
Vector for the Correlated Gaussian Observables defined in SomeModel.conf.
InputParser myInputParser
An object of the InputParser class.
bool FindModeWithMinuit
Flag for using Minuit libraries.
void Initialize(Model *Mod_i)
Initialization of the Monte Carlo Engine.
std::string MCMCConf
String for the name of the MonteCarlo.conf file.
int getNumOfUsedEvents() const
A get method to access the number of events used in the MCMC run.
std::string JobTag
String for the optional JobTag argument to be passes to the executable.
std::string ModelConf
String for the name of the SomeModel.conf file.