Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
HistoToWorkspaceFactory.cxx
Go to the documentation of this file.
1 // @(#)root/roostats:$Id: cranmer $
2 // Author: Kyle Cranmer, Akira Shibata
3 /*************************************************************************
4  * Copyright (C) 1995-2008, Rene Brun and Fons Rademakers. *
5  * All rights reserved. *
6  * *
7  * For the licensing terms see $ROOTSYS/LICENSE. *
8  * For the list of contributors see $ROOTSYS/README/CREDITS. *
9  *************************************************************************/
10 
11 ////////////////////////////////////////////////////////////////////////////////
12 
13 /** \class RooStats::HistFactory::HistoToWorkspaceFactory
14  * \ingroup HistFactory
15  */
16 
17 
18 #ifndef __CINT__
19 #include "RooGlobalFunc.h"
20 #endif
21 
22 // Roofit/Roostat include
23 #include "RooDataSet.h"
24 #include "RooRealVar.h"
25 #include "RooConstVar.h"
26 #include "RooAddition.h"
27 #include "RooProduct.h"
28 #include "RooProdPdf.h"
29 #include "RooAddPdf.h"
30 #include "RooGaussian.h"
31 #include "RooExponential.h"
32 #include "RooRandom.h"
33 #include "RooCategory.h"
34 #include "RooSimultaneous.h"
35 #include "RooMultiVarGaussian.h"
36 #include "RooNumIntConfig.h"
37 #include "RooMinuit.h"
38 #include "RooNLLVar.h"
39 #include "RooProfileLL.h"
40 #include "RooFitResult.h"
41 #include "RooDataHist.h"
42 #include "RooHistPdf.h"
43 #include "RooProduct.h"
44 #include "RooWorkspace.h"
45 #include "RooCustomizer.h"
46 #include "RooPlot.h"
47 #include "RooMsgService.h"
48 #include "RooStats/RooStatsUtils.h"
49 #include "RooStats/ModelConfig.h"
50 
51 #include "TH2F.h"
52 #include "TH3F.h"
53 #include "TFile.h"
54 #include "TCanvas.h"
55 #include "TH1.h"
56 #include "TLine.h"
57 #include "TTree.h"
58 #include "TMarker.h"
59 #include "TStopwatch.h"
60 #include "TROOT.h"
61 #include "TStyle.h"
62 #include "TVectorD.h"
63 #include "TMatrixDSym.h"
64 
65 // specific to this package
66 //#include "RooStats/HistFactory/Helper.h"
69 #include "Helper.h"
70 
71 #define VERBOSE
72 
73 #define alpha_Low "-5"
74 #define alpha_High "5"
75 #define NoHistConst_Low "0"
76 #define NoHistConst_High "2000"
77 
78 // use this order for safety on library loading
79 using namespace RooFit ;
80 using namespace RooStats ;
81 using namespace std ;
82 //using namespace RooMsgService ;
83 
84 ClassImp(RooStats::HistFactory::HistoToWorkspaceFactory);
85 
86 namespace RooStats{
87 namespace HistFactory{
88 
89  HistoToWorkspaceFactory::HistoToWorkspaceFactory() :
90  fNomLumi(0),
91  fLumiError(0),
92  fLowBin(0),
93  fHighBin(0),
94  fOut_f(0),
95  pFile(0)
96  {
97  }
98 
99  HistoToWorkspaceFactory::~HistoToWorkspaceFactory(){
100  fclose(pFile);
101  }
102 
103  HistoToWorkspaceFactory::HistoToWorkspaceFactory(string filePrefix, string row, vector<string> syst, double nomL, double lumiE, int low, int high, TFile* f):
104  fFileNamePrefix(filePrefix),
105  fRowTitle(row),
106  fSystToFix(syst),
107  fNomLumi(nomL),
108  fLumiError(lumiE),
109  fLowBin(low),
110  fHighBin(high),
111  fOut_f(f) {
112 
113  // fResultsPrefixStr<<"results" << "_" << fNomLumi<< "_" << fLumiError<< "_" << fLowBin<< "_" << fHighBin;
114  fResultsPrefixStr<< "_" << fRowTitle;
115  while(fRowTitle.find("\\ ")!=string::npos){
116  int pos=fRowTitle.find("\\ ");
117  fRowTitle.replace(pos, 1, "");
118  }
119  pFile = fopen ((filePrefix+"_results.table").c_str(),"a");
120  //RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR) ;
121 
122  }
123 
124  string HistoToWorkspaceFactory::FilePrefixStr(string prefix){
125 
126  stringstream ss;
127  ss << prefix << "_" << fNomLumi<< "_" << fLumiError<< "_" << fLowBin<< "_" << fHighBin<< "_"<<fRowTitle;
128 
129  return ss.str();
130  }
131 
132  void HistoToWorkspaceFactory::ProcessExpectedHisto(TH1* hist,RooWorkspace* proto, string prefix, string productPrefix, string systTerm, double low, double high, int lowBin, int highBin){
133  if(hist)
134  cout << "processing hist " << hist->GetName() << endl;
135  else
136  cout << "hist is empty" << endl;
137  RooArgSet argset(prefix.c_str());
138  string highStr = "inf";
139  for(Int_t i=lowBin; i<highBin; ++i){
140  std::stringstream str;
141  std::stringstream range;
142  str<<"_"<<i;
143  if(hist)
144  range<<"["<<hist->GetBinContent(i+1) << "," << low << "," << highStr << "]";
145  else
146  range<<"["<< low << "," << high << "]";
147  cout << "for bin N"+str.str() << " var " << prefix+str.str()+" with range " << range.str() << endl;
148  RooRealVar* var = (RooRealVar*) proto->factory((prefix+str.str()+range.str()).c_str());
149 
150  // now create the product of the overall efficiency times the sigma(params) for this estimate
151  if(! (productPrefix.empty() || systTerm.empty()) )
152  proto->factory(("prod:"+productPrefix+str.str()+"("+prefix+str.str()+","+systTerm+")").c_str() );
153 
154  var->setConstant();
155  argset.add(* var );
156  }
157  proto->defineSet(prefix.c_str(),argset);
158  // proto->Print();
159  }
160 
161  void HistoToWorkspaceFactory::AddMultiVarGaussConstraint(RooWorkspace* proto, string prefix,int lowBin, int highBin, vector<string>& likelihoodTermNames){
162  // these are the nominal predictions: eg. the mean of some space of variations
163  // later fill these in a loop over histogram bins
164  TVectorD mean(highBin-lowBin);
165  cout << "a" << endl;
166  for(Int_t i=lowBin; i<highBin; ++i){
167  std::stringstream str;
168  str<<"_"<<i;
169  RooRealVar* temp = proto->var((prefix+str.str()).c_str());
170  mean(i) = temp->getVal();
171  }
172 
173  TMatrixDSym Cov(highBin-lowBin);
174  for(int i=lowBin; i<highBin; ++i){
175  for(int j=0; j<highBin-lowBin; ++j){
176  if(i==j)
177  Cov(i,j) = sqrt(mean(i));
178  else
179  Cov(i,j) = 0;
180  }
181  }
182  // can't make MultiVarGaussian with factory yet, do it by hand
183  RooArgList floating( *(proto->set(prefix.c_str() ) ) );
184  RooMultiVarGaussian constraint((prefix+"Constraint").c_str(),"",
185  floating, mean, Cov);
186 
187  proto->import(constraint);
188 
189  likelihoodTermNames.push_back(constraint.GetName());
190 
191  }
192 
193 
194  void HistoToWorkspaceFactory::LinInterpWithConstraint(RooWorkspace* proto, TH1* nominal, vector<TH1*> lowHist, vector<TH1*> highHist,
195  vector<string> sourceName, string prefix, string productPrefix, string systTerm,
196  int lowBin, int highBin, vector<string>& likelihoodTermNames){
197  // these are the nominal predictions: eg. the mean of some space of variations
198  // later fill these in a loop over histogram bins
199 
200  // make list of abstract parameters that interpolate in space of variations
201  RooArgList params( ("alpha_Hist") );
202  // range is set using defined macro (see top of the page)
203  string range=string("[")+alpha_Low+","+alpha_High+"]";
204  for(unsigned int j=0; j<lowHist.size(); ++j){
205  std::stringstream str;
206  str<<"_"<<j;
207 
208  RooRealVar* temp = (RooRealVar*) proto->var(("alpha_"+sourceName.at(j)).c_str());
209  if(!temp){
210  temp = (RooRealVar*) proto->factory(("alpha_"+sourceName.at(j)+range).c_str());
211 
212  // now add a constraint term for these parameters
213  string command=("Gaussian::alpha_"+sourceName.at(j)+"Constraint(alpha_"+sourceName.at(j)+",nom_"+sourceName.at(j)+"[0.,-10,10],1.)");
214  cout << command << endl;
215  likelihoodTermNames.push_back( proto->factory( command.c_str() )->GetName() );
216  proto->var(("nom_"+sourceName.at(j)).c_str())->setConstant();
217  const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*proto->var(("nom_"+sourceName.at(j)).c_str()));
218 
219  }
220 
221  params.add(* temp );
222 
223  }
224 
225  // now make function that linearly interpolates expectation between variations
226  for(Int_t i=lowBin; i<highBin; ++i){
227  std::stringstream str;
228  str<<"_"<<i;
229 
230  // get low/high variations to interpolate between
231  vector<double> low, high;
232  for(unsigned int j=0; j<lowHist.size(); ++j){
233  low.push_back( lowHist.at(j)->GetBinContent(i+1) );
234  high.push_back( highHist.at(j)->GetBinContent(i+1) );
235  cout << "for "+prefix+" bin "+str.str()+" creating linear interp of nominal " << nominal->GetBinContent(i+1)
236  << " in parameter " << sourceName.at(j)
237  << " between " << low.back() << " - " << high.back()
238  << " about " << 100.*fabs(low.back() - high.back() )/nominal->GetBinContent(i+1) << " % error"
239  << endl;
240  }
241 
242  // this is sigma(params), a piece-wise linear interpolation
243  LinInterpVar interp( (prefix+str.str()).c_str(), "", params, nominal->GetBinContent(i+1), low, high);
244 
245  // cout << "check: " << interp.getVal() << endl;
246  proto->import(interp); // individual params have already been imported in first loop of this function
247 
248  // now create the product of the overall efficiency times the sigma(params) for this estimate
249  proto->factory(("prod:"+productPrefix+str.str()+"("+prefix+str.str()+","+systTerm+")").c_str() );
250 
251  }
252 
253  }
254 
255  string HistoToWorkspaceFactory::AddNormFactor(RooWorkspace * proto, string & channel, string & sigmaEpsilon, EstimateSummary & es, bool doRatio){
256  string overallNorm_times_sigmaEpsilon ;
257  string prodNames;
258  vector<EstimateSummary::NormFactor> norm=es.normFactor;
259  if(norm.size()){
260  for(vector<EstimateSummary::NormFactor>::iterator itr=norm.begin(); itr!=norm.end(); ++itr){
261  cout << "making normFactor: " << itr->name << endl;
262  // remove "doRatio" and name can be changed when ws gets imported to the combined model.
263  std::stringstream range;
264  range<<"["<<itr->val<<","<<itr->low<<","<<itr->high<<"]";
265  //RooRealVar* var = 0;
266 
267  string varname;
268  if(!prodNames.empty()) prodNames+=",";
269  if(doRatio) {
270  varname=itr->name+"_"+channel;
271  }
272  else {
273  varname=itr->name;
274  }
275  proto->factory((varname+range.str()).c_str());
276  if(itr->constant){
277  // proto->var(varname.c_str())->setConstant();
278  // cout <<"setting " << varname << " constant"<<endl;
279  cout <<"WARNING: Const attribute to <NormFactor> tag is deprecated, will ignore."<<
280  " Instead, add \n\t<ParamSetting Const=\"True\">"<<varname<<"</ParamSetting>\n"<<
281  " to your top-level XML's <Measurment> entry"<< endl;
282  }
283  prodNames+=varname;
284  }
285  overallNorm_times_sigmaEpsilon = es.name+"_"+channel+"_overallNorm_x_sigma_epsilon";
286  proto->factory(("prod::"+overallNorm_times_sigmaEpsilon+"("+prodNames+","+sigmaEpsilon+")").c_str());
287  }
288 
289  if(!overallNorm_times_sigmaEpsilon.empty())
290  return overallNorm_times_sigmaEpsilon;
291  else
292  return sigmaEpsilon;
293  }
294 
295 
296  void HistoToWorkspaceFactory::AddEfficiencyTerms(RooWorkspace* proto, string prefix, string interpName,
297  map<string,pair<double,double> > systMap,
298  vector<string>& likelihoodTermNames, vector<string>& totSystTermNames){
299  // add variables for all the relative overall uncertainties we expect
300 
301  // range is set using defined macro (see top of the page)
302  string range=string("[0,")+alpha_Low+","+alpha_High+"]";
303  //string range="[0,-1,1]";
304  totSystTermNames.push_back(prefix);
305  //bool first=true;
306  RooArgSet params(prefix.c_str());
307  vector<double> lowVec, highVec;
308  for(map<string,pair<double,double> >::iterator it=systMap.begin(); it!=systMap.end(); ++it){
309  // add efficiency term
310  RooRealVar* temp = (RooRealVar*) proto->var((prefix+ it->first).c_str());
311  if(!temp){
312  temp = (RooRealVar*) proto->factory((prefix+ it->first +range).c_str());
313 
314  string command=("Gaussian::"+prefix+it->first+"Constraint("+prefix+it->first+",nom_"+prefix+it->first+"[0.,-10,10],1.)");
315  cout << command << endl;
316  likelihoodTermNames.push_back( proto->factory( command.c_str() )->GetName() );
317  proto->var(("nom_"+prefix+it->first).c_str())->setConstant();
318  const_cast<RooArgSet*>(proto->set("globalObservables"))->add(*proto->var(("nom_"+prefix+it->first).c_str()));
319 
320  }
321  params.add(*temp);
322 
323  // add constraint in terms of bifrucated gauss with low/high as sigmas
324  std::stringstream lowhigh;
325  double low = it->second.first;
326  double high = it->second.second;
327  lowVec.push_back(low);
328  highVec.push_back(high);
329 
330  }
331  if(systMap.size()>0){
332  // this is epsilon(alpha_j), a piece-wise linear interpolation
333  LinInterpVar interp( (interpName).c_str(), "", params, 1., lowVec, highVec);
334  proto->import(interp); // params have already been imported in first loop of this function
335  } else{
336  // some strange behavior if params,lowVec,highVec are empty.
337  //cout << "WARNING: No OverallSyst terms" << endl;
338  RooConstVar interp( (interpName).c_str(), "", 1.);
339  proto->import(interp); // params have already been imported in first loop of this function
340  }
341 
342  }
343 
344 
345  void HistoToWorkspaceFactory::MakeTotalExpected(RooWorkspace* proto, string totName, string /**/, string /**/,
346  int lowBin, int highBin, vector<string>& syst_x_expectedPrefixNames,
347  vector<string>& normByNames){
348 
349  // for ith bin calculate totN_i = lumi * sum_j expected_j * syst_j
350 
351  for(Int_t i=lowBin; i<highBin; ++i){
352  std::stringstream str;
353  str<<"_"<<i;
354  string command="sum::"+totName+str.str()+"(";
355  //vector<string>::iterator it=syst_x_expectedPrefixNames.begin();
356  string prepend="";
357  for(unsigned int j=0; j<syst_x_expectedPrefixNames.size();++j){
358  command+=prepend+normByNames.at(j)+"*"+syst_x_expectedPrefixNames.at(j)+str.str();
359  prepend=",";
360  }
361  command+=")";
362  cout << "function to calculate total: " << command << endl;
363  proto->factory(command.c_str());
364  }
365  }
366 
367  void HistoToWorkspaceFactory::AddPoissonTerms(RooWorkspace* proto, string prefix, string obsPrefix, string expPrefix, int lowBin, int highBin,
368  vector<string>& likelihoodTermNames){
369  /////////////////////////////////
370  // Relate observables to expected for each bin
371  // later modify variable named expPrefix_i to be product of terms
372  RooArgSet Pois(prefix.c_str());
373  for(Int_t i=lowBin; i<highBin; ++i){
374  std::stringstream str;
375  str<<"_"<<i;
376  //string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+")");
377  string command("Poisson::"+prefix+str.str()+"("+obsPrefix+str.str()+","+expPrefix+str.str()+",1)");//for no rounding
378  RooAbsArg* temp = (proto->factory( command.c_str() ) );
379 
380  // output
381  cout << "Poisson Term " << command << endl;
382  ((RooAbsPdf*) temp)->setEvalErrorLoggingMode(RooAbsReal::PrintErrors);
383  //cout << temp << endl;
384 
385  likelihoodTermNames.push_back( temp->GetName() );
386  Pois.add(* temp );
387  }
388  proto->defineSet(prefix.c_str(),Pois); // add argset to workspace
389  }
390 
391  void HistoToWorkspaceFactory::SetObsToExpected(RooWorkspace* proto, string obsPrefix, string expPrefix, int lowBin, int highBin){
392  /////////////////////////////////
393  // set observed to expected
394  TTree* tree = new TTree();
395  Double_t* obsForTree = new Double_t[highBin-lowBin];
396  RooArgList obsList("obsList");
397 
398  for(Int_t i=lowBin; i<highBin; ++i){
399  std::stringstream str;
400  str<<"_"<<i;
401  RooRealVar* obs = (RooRealVar*) proto->var((obsPrefix+str.str()).c_str());
402  cout << "expected number of events called: " << expPrefix << endl;
403  RooAbsReal* exp = proto->function((expPrefix+str.str()).c_str());
404  if(obs && exp){
405 
406  //proto->Print();
407  obs->setVal( exp->getVal() );
408  cout << "setting obs"+str.str()+" to expected = " << exp->getVal() << " check: " << obs->getVal() << endl;
409 
410  // add entry to array and attach to tree
411  obsForTree[i] = exp->getVal();
412  tree->Branch((obsPrefix+str.str()).c_str(), obsForTree+i ,(obsPrefix+str.str()+"/D").c_str());
413  obsList.add(*obs);
414  }else{
415  cout << "problem retrieving obs or exp " << obsPrefix+str.str() << obs << " " << expPrefix+str.str() << exp << endl;
416  }
417  }
418  tree->Fill();
419  RooDataSet* data = new RooDataSet("expData","", tree, obsList); // one experiment
420 
421  proto->import(*data);
422  delete[] obsForTree;
423  obsForTree = nullptr;
424  }
425 
426  void HistoToWorkspaceFactory::Customize(RooWorkspace* proto, const char* pdfNameChar, map<string,string> renameMap) {
427  cout << "in customizations" << endl;
428  string pdfName(pdfNameChar);
429  map<string,string>::iterator it;
430  string edit="EDIT::customized("+pdfName+",";
431  string precede="";
432  for(it=renameMap.begin(); it!=renameMap.end(); ++it) {
433  cout << it->first + "=" + it->second << endl;
434  edit+=precede + it->first + "=" + it->second;
435  precede=",";
436  }
437  edit+=")";
438  cout << edit<< endl;
439  proto->factory( edit.c_str() );
440  }
441 
442  //////////////////////////////////////////////////////////////////////////////
443  /// cout << "in edit, gammamap.size = " << gammaSyst.size() << ", unimap.size = " << uniformSyst.size() << endl;
444 
445  void HistoToWorkspaceFactory::EditSyst(RooWorkspace* proto, const char* pdfNameChar, map<string,double> gammaSyst, map<string,double> uniformSyst,map<string,double> logNormSyst) {
446  string pdfName(pdfNameChar);
447 
448  ModelConfig * combined_config = (ModelConfig *) proto->obj("ModelConfig");
449  // const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters();
450  // RooArgSet temp(*constrainedParams);
451  string edit="EDIT::newSimPdf("+pdfName+",";
452  string editList;
453  string lastPdf=pdfName;
454  string precede="";
455  unsigned int numReplacements = 0;
456  unsigned int nskipped = 0;
457  map<string,double>::iterator it;
458 
459  // add gamma terms and their constraints
460  for(it=gammaSyst.begin(); it!=gammaSyst.end(); ++it) {
461  //cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
462  if(! proto->var(("alpha_"+it->first).c_str())){
463  //cout << "systematic not there" << endl;
464  nskipped++;
465  continue;
466  }
467  numReplacements++;
468 
469  double relativeUncertainty = it->second;
470  double scale = 1/sqrt((1+1/pow(relativeUncertainty,2)));
471 
472  // this is the Gamma PDF and in a form that doesn't have roundoff problems like the Poisson does
473  proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
474  proto->factory(Form("y_%s[%f]",it->first.c_str(),1./pow(relativeUncertainty,2))) ;
475  proto->factory(Form("theta_%s[%f]",it->first.c_str(),pow(relativeUncertainty,2))) ;
476  proto->factory(Form("Gamma::beta_%sConstraint(beta_%s,sum::k_%s(y_%s,one[1]),theta_%s,zero[0])",
477  it->first.c_str(),
478  it->first.c_str(),
479  it->first.c_str(),
480  it->first.c_str(),
481  it->first.c_str())) ;
482 
483  /*
484  // this has some problems because N in poisson is rounded to nearest integer
485  proto->factory(Form("Poisson::beta_%sConstraint(y_%s[%f],prod::taub_%s(taus_%s[%f],beta_%s[1,0,5]))",
486  it->first.c_str(),
487  it->first.c_str(),
488  1./pow(relativeUncertainty,2),
489  it->first.c_str(),
490  it->first.c_str(),
491  1./pow(relativeUncertainty,2),
492  it->first.c_str()
493  ) ) ;
494  */
495  // combined->factory(Form("expr::alphaOfBeta('(beta-1)/%f',beta)",scale));
496  // combined->factory(Form("expr::alphaOfBeta_%s('(beta_%s-1)/%f',beta_%s)",it->first.c_str(),it->first.c_str(),scale,it->first.c_str()));
497  proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale));
498 
499  // set beta const status to be same as alpha
500  if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
501  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
502  else
503  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
504  // set alpha const status to true
505  // proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
506 
507  // replace alphas with alphaOfBeta and replace constraints
508  //cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
509  editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
510  precede=",";
511  // cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
512  editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
513 
514  /*
515  if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
516  cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
517  else
518  cout << "NOT THERE" << endl;
519  */
520 
521  // EDIT seems to die if the list of edits is too long. So chunck them up.
522  if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
523  edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
524  lastPdf+="_"; // append an underscore for the edit
525  editList=""; // reset edit list
526  precede="";
527  cout << "Going to issue this edit command\n" << edit<< endl;
528  proto->factory( edit.c_str() );
529  RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
530  if(!newOne)
531  cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
532 
533  }
534  }
535 
536  // add uniform terms and their constraints
537  for(it=uniformSyst.begin(); it!=uniformSyst.end(); ++it) {
538  cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
539  if(! proto->var(("alpha_"+it->first).c_str())){
540  cout << "systematic not there" << endl;
541  nskipped++;
542  continue;
543  }
544  numReplacements++;
545 
546  // this is the Uniform PDF
547  proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
548  proto->factory(Form("Uniform::beta_%sConstraint(beta_%s)",it->first.c_str(),it->first.c_str()));
549  proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{-1,1})",it->first.c_str(),it->first.c_str()));
550 
551  // set beta const status to be same as alpha
552  if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
553  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
554  else
555  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
556  // set alpha const status to true
557  // proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
558 
559  // replace alphas with alphaOfBeta and replace constraints
560  cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
561  editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
562  precede=",";
563  cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
564  editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
565 
566  if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
567  cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
568  else
569  cout << "NOT THERE" << endl;
570 
571  // EDIT seems to die if the list of edits is too long. So chunck them up.
572  if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
573  edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
574  lastPdf+="_"; // append an underscore for the edit
575  editList=""; // reset edit list
576  precede="";
577  cout << edit<< endl;
578  proto->factory( edit.c_str() );
579  RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
580  if(!newOne)
581  cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
582 
583  }
584  }
585 
586  /////////////////////////////////////////
587  ////////////////////////////////////
588 
589 
590  // add lognormal terms and their constraints
591  for(it=logNormSyst.begin(); it!=logNormSyst.end(); ++it) {
592  cout << "edit for " << it->first << "with rel uncert = " << it->second << endl;
593  if(! proto->var(("alpha_"+it->first).c_str())){
594  cout << "systematic not there" << endl;
595  nskipped++;
596  continue;
597  }
598  numReplacements++;
599 
600  double relativeUncertainty = it->second;
601  double kappa = 1+relativeUncertainty;
602  // when transforming beta -> alpha, need alpha=1 to be +1sigma value.
603  // the P(beta>kappa*\hat(beta)) = 16%
604  // and \hat(beta) is 1, thus
605  double scale = relativeUncertainty;
606  //double scale = kappa;
607 
608  // this is the LogNormal
609  proto->factory(Form("beta_%s[1,0,10]",it->first.c_str()));
610  proto->factory(Form("kappa_%s[%f]",it->first.c_str(),kappa));
611  proto->factory(Form("Lognormal::beta_%sConstraint(beta_%s,one[1],kappa_%s)",
612  it->first.c_str(),
613  it->first.c_str(),
614  it->first.c_str())) ;
615  proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1./scale,1./scale));
616  // proto->factory(Form("PolyVar::alphaOfBeta_%s(beta_%s,{%f,%f})",it->first.c_str(),it->first.c_str(),-1.,1./scale));
617 
618  // set beta const status to be same as alpha
619  if(proto->var(Form("alpha_%s",it->first.c_str()))->isConstant())
620  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(true);
621  else
622  proto->var(Form("beta_%s",it->first.c_str()))->setConstant(false);
623  // set alpha const status to true
624  // proto->var(Form("alpha_%s",it->first.c_str()))->setConstant(true);
625 
626  // replace alphas with alphaOfBeta and replace constraints
627  cout << "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint" << endl;
628  editList+=precede + "alpha_"+it->first+"Constraint=beta_" + it->first+ "Constraint";
629  precede=",";
630  cout << "alpha_"+it->first+"=alphaOfBeta_"+ it->first << endl;
631  editList+=precede + "alpha_"+it->first+"=alphaOfBeta_"+ it->first;
632 
633  if( proto->pdf(("alpha_"+it->first+"Constraint").c_str()) && proto->var(("alpha_"+it->first).c_str()) )
634  cout << " checked they are there" << proto->pdf(("alpha_"+it->first+"Constraint").c_str()) << " " << proto->var(("alpha_"+it->first).c_str()) << endl;
635  else
636  cout << "NOT THERE" << endl;
637 
638  // EDIT seems to die if the list of edits is too long. So chunck them up.
639  if(numReplacements%10 == 0 && numReplacements+nskipped!=gammaSyst.size()){
640  edit="EDIT::"+lastPdf+"_("+lastPdf+","+editList+")";
641  lastPdf+="_"; // append an underscore for the edit
642  editList=""; // reset edit list
643  precede="";
644  cout << edit<< endl;
645  proto->factory( edit.c_str() );
646  RooAbsPdf* newOne = proto->pdf(lastPdf.c_str());
647  if(!newOne)
648  cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
649 
650  }
651  }
652 
653  /////////////////////////////////////////
654  ////////////////////////////////////
655 
656  // commit last bunch of edits
657  edit="EDIT::newSimPdf("+lastPdf+","+editList+")";
658  cout << edit<< endl;
659  proto->factory( edit.c_str() );
660  // proto->writeToFile(("results/model_"+fRowTitle+"_edited.root").c_str());
661  RooAbsPdf* newOne = proto->pdf("newSimPdf");
662  if(newOne){
663  // newOne->graphVizTree(("results/"+pdfName+"_"+fRowTitle+"newSimPdf.dot").c_str());
664  combined_config->SetPdf(*newOne);
665  }
666  else{
667  cout << "\n\n ---------------------\n WARNING: failed to make EDIT\n\n" << endl;
668  }
669  }
670 
671  void HistoToWorkspaceFactory::PrintCovarianceMatrix(RooFitResult* result, RooArgSet* params, string filename){
672  // FILE * pFile;
673  pFile = fopen ((filename).c_str(),"w");
674 
675 
676  TIter iti = params->createIterator();
677  TIter itj = params->createIterator();
678  RooRealVar *myargi, *myargj;
679  fprintf(pFile," ") ;
680  while ((myargi = (RooRealVar *)iti.Next())) {
681  if(myargi->isConstant()) continue;
682  fprintf(pFile," & %s", myargi->GetName());
683  }
684  fprintf(pFile,"\\\\ \\hline \n" );
685  iti.Reset();
686  while ((myargi = (RooRealVar *)iti.Next())) {
687  if(myargi->isConstant()) continue;
688  fprintf(pFile,"%s", myargi->GetName());
689  itj.Reset();
690  while ((myargj = (RooRealVar *)itj.Next())) {
691  if(myargj->isConstant()) continue;
692  cout << myargi->GetName() << "," << myargj->GetName();
693  fprintf(pFile, " & %.2f", result->correlation(*myargi, *myargj));
694  }
695  cout << endl;
696  fprintf(pFile, " \\\\\n");
697  }
698  fclose(pFile);
699 
700  }
701 
702 
703  ///////////////////////////////////////////////
704  RooWorkspace* HistoToWorkspaceFactory::MakeSingleChannelModel(vector<EstimateSummary> summary, vector<string> systToFix, bool doRatio)
705  {
706 
707  if (summary.empty() ) {
708  Error("MakeSingleChannelModel","vector of EstimateSummry is empty - return a nullptr");
709  return 0;
710  }
711 
712  // to time the macro
713  TStopwatch t;
714  t.Start();
715  string channel=summary[0].channel;
716  cout << "\n\n-------------------\nStarting to process " << channel << " channel" << endl;
717 
718  //
719  // our main workspace that we are using to construct the model
720  //
721  RooWorkspace* proto = new RooWorkspace("proto","proto workspace");
722  ModelConfig * proto_config = new ModelConfig("ModelConfig", proto);
723  proto_config->SetWorkspace(*proto);
724 
725  RooArgSet likelihoodTerms("likelihoodTerms");
726  vector<string> likelihoodTermNames, totSystTermNames,syst_x_expectedPrefixNames, normalizationNames;
727 
728  string prefix, range;
729 
730  /////////////////////////////
731  // Make observables, set values to observed data if data is specified,
732  // otherwise use expected "Asimov" data
733  if (summary.at(0).name=="Data") {
734  ProcessExpectedHisto(summary.at(0).nominal,proto,"obsN","","",0,100000,fLowBin,fHighBin);
735  } else {
736  cout << "Will use expected (\"Asimov\") data set" << endl;
737  ProcessExpectedHisto(NULL,proto,"obsN","","",0,100000,fLowBin,fHighBin);
738  }
739 
740 
741 
742  /////////////////////////////
743  // shared parameters
744  // this is ratio of lumi to nominal lumi. We will include relative uncertainty in model
745  std::stringstream lumiStr;
746  // lumi range
747  lumiStr<<"["<<fNomLumi<<",0,"<<10.*fNomLumi<<"]";
748  proto->factory(("Lumi"+lumiStr.str()).c_str());
749  cout << "lumi str = " << lumiStr.str() << endl;
750 
751  std::stringstream lumiErrorStr;
752  // lumiErrorStr << "nominalLumi["<<fNomLumi << "]," << fLumiError ;
753  lumiErrorStr << "nominalLumi["<<fNomLumi << ",0,"<<fNomLumi+10*fLumiError<<"]," << fLumiError ;
754  proto->factory(("Gaussian::lumiConstraint(Lumi,"+lumiErrorStr.str()+")").c_str());
755  proto->var("nominalLumi")->setConstant();
756  proto->defineSet("globalObservables","nominalLumi");
757  likelihoodTermNames.push_back("lumiConstraint");
758  cout << "lumi Error str = " << lumiErrorStr.str() << endl;
759 
760  //proto->factory((string("SigXsecOverSM[1.,0.5,1..8]").c_str()));
761  ///////////////////////////////////
762  // loop through estimates, add expectation, floating bin predictions,
763  // and terms that constrain floating to expectation via uncertainties
764  vector<EstimateSummary>::iterator it = summary.begin();
765  for(; it!=summary.end(); ++it){
766  if(it->name=="Data") continue;
767 
768  string overallSystName = it->name+"_"+it->channel+"_epsilon";
769  string systSourcePrefix = "alpha_";
770  AddEfficiencyTerms(proto,systSourcePrefix, overallSystName,
771  it->overallSyst,
772  likelihoodTermNames, totSystTermNames);
773 
774  overallSystName=AddNormFactor(proto, channel, overallSystName, *it, doRatio);
775  // get histogram
776  TH1* nominal = it->nominal;
777  if(it->lowHists.size() == 0){
778  cout << it->name+"_"+it->channel+" has no variation histograms " <<endl;
779  string expPrefix=it->name+"_"+it->channel+"_expN";
780  string syst_x_expectedPrefix=it->name+"_"+it->channel+"_overallSyst_x_Exp";
781  ProcessExpectedHisto(nominal,proto,expPrefix,syst_x_expectedPrefix,overallSystName,atoi(NoHistConst_Low),atoi(NoHistConst_High),fLowBin,fHighBin);
782  syst_x_expectedPrefixNames.push_back(syst_x_expectedPrefix);
783  } else if(it->lowHists.size() != it->highHists.size()){
784  cout << "problem in "+it->name+"_"+it->channel
785  << " number of low & high variation histograms don't match" << endl;
786  return 0;
787  } else {
788  string constraintPrefix = it->name+"_"+it->channel+"_Hist_alpha"; // name of source for variation
789  string syst_x_expectedPrefix = it->name+"_"+it->channel+"_overallSyst_x_HistSyst";
790  LinInterpWithConstraint(proto, nominal, it->lowHists, it->highHists, it->systSourceForHist,
791  constraintPrefix, syst_x_expectedPrefix, overallSystName,
792  fLowBin, fHighBin, likelihoodTermNames);
793  syst_x_expectedPrefixNames.push_back(syst_x_expectedPrefix);
794  }
795 
796  // AddMultiVarGaussConstraint(proto, "exp"+it->first+"N", fLowBin, fHighBin, likelihoodTermNames);
797 
798  if(it->normName=="")
799  normalizationNames.push_back( "Lumi" );
800  else
801  normalizationNames.push_back( it->normName);
802  }
803  //proto->Print();
804 
805  ///////////////////////////////////
806  // for ith bin calculate totN_i = lumi * sum_j expected_j * syst_j
807  MakeTotalExpected(proto,channel+"_totN",channel+"_expN","Lumi",fLowBin,fHighBin,
808  syst_x_expectedPrefixNames, normalizationNames);
809 
810  /////////////////////////////////
811  // Relate observables to expected for each bin
812  AddPoissonTerms(proto, "Pois_"+channel, "obsN", channel+"_totN", fLowBin, fHighBin, likelihoodTermNames);
813 
814  /////////////////////////////////
815  // if no data histogram provided, make asimov data
816  if(summary.at(0).name!="Data"){
817  SetObsToExpected(proto, "obsN",channel+"_totN", fLowBin, fHighBin);
818  cout << " using asimov data" << endl;
819  } else{
820  SetObsToExpected(proto, "obsN","obsN", fLowBin, fHighBin);
821  cout << " using input data histogram" << endl;
822  }
823 
824  //////////////////////////////////////
825  // fix specified parameters
826  for(unsigned int i=0; i<systToFix.size(); ++i){
827  RooRealVar* temp = proto->var((systToFix.at(i)).c_str());
828  if(temp) temp->setConstant();
829  else cout << "could not find variable " << systToFix.at(i) << " could not set it to constant" << endl;
830  }
831 
832  //////////////////////////////////////
833  // final proto model
834  for(unsigned int i=0; i<likelihoodTermNames.size(); ++i){
835  // cout << likelihoodTermNames[i] << endl;
836  likelihoodTerms.add(* (proto->arg(likelihoodTermNames[i].c_str())) );
837  }
838  // likelihoodTerms.Print();
839 
840  proto->defineSet("likelihoodTerms",likelihoodTerms);
841  // proto->Print();
842 
843  cout <<"-----------------------------------------"<<endl;
844  cout <<"import model into workspace" << endl;
845  RooProdPdf* model = new RooProdPdf(("model_"+channel).c_str(),
846  "product of Poissons accross bins for a single channel",
847  likelihoodTerms);
848  proto->import(*model,RecycleConflictNodes());
849 
850  proto_config->SetPdf(*model);
851  proto_config->SetGlobalObservables(*proto->set("globalObservables"));
852 
853  proto->import(*proto_config,proto_config->GetName());
854  proto->importClassCode();
855  // proto->writeToFile(("results/model_"+channel+".root").c_str());
856 
857  return proto;
858  }
859 
860  RooWorkspace* HistoToWorkspaceFactory::MakeCombinedModel(vector<string> ch_names, vector<RooWorkspace*> chs)
861  {
862 
863  //
864  /// These things were used for debugging. Maybe useful in the future
865  //
866  // RooAbsReal::defaultIntegratorConfig()->setEpsAbs(1e-8) ;
867  // RooAbsReal::defaultIntegratorConfig()->setEpsRel(1e-8) ;
868  // RooMsgService::instance().setGlobalKillBelow(RooMsgService::WARNING);
869  // RooMsgService::instance().setGlobalKillBelow(RooMsgService::WARNING) ;
870  // cout << "MsgSvc: " << RooMsgService::instance().globalKillBelow() << " INFO "
871  // << RooMsgService::INFO << " WARNING " << RooMsgService::WARNING << endl;
872 
873  // RooArgSet* constrainedParams= new RooArgSet("constrainedParams");
874 
875  // check inputs (see JIRA-6890)
876  if (ch_names.empty() || chs.empty() ) {
877  Error("MakeCombinedModel","Input vectors are empty - return a nullptr");
878  return 0;
879  }
880  if (chs.size() < ch_names.size() ) {
881  Error("MakeCombinedModel","Input vector of workspace has an invalid size - return a nullptr");
882  return 0;
883  }
884 
885  map<string, RooAbsPdf*> pdfMap;
886  vector<RooAbsPdf*> models;
887  stringstream ss;
888 
889  RooArgSet globalObs;
890  for(unsigned int i = 0; i< ch_names.size(); ++i){
891  string channel_name=ch_names[i];
892 
893  if (ss.str().empty()) ss << channel_name ;
894  else ss << ',' << channel_name ;
895  RooWorkspace * ch=chs[i];
896 
897  RooAbsPdf* model = ch->pdf(("model_"+channel_name).c_str());
898  models.push_back(model);
899  globalObs.add(*ch->set("globalObservables"));
900 
901  // constrainedParams->add( * ch->set("constrainedParams") );
902  pdfMap[channel_name]=model;
903  }
904  //constrainedParams->Print();
905 
906  cout << "\n\n------------------\n Entering combination" << endl;
907  RooWorkspace* combined = new RooWorkspace("combined");
908 
909  RooCategory* channelCat = (RooCategory*) combined->factory(("channelCat["+ss.str()+"]").c_str());
910  RooSimultaneous * simPdf= new RooSimultaneous("simPdf","",pdfMap, *channelCat);
911  ModelConfig * combined_config = new ModelConfig("ModelConfig", combined);
912  combined_config->SetWorkspace(*combined);
913  // combined_config->SetNuisanceParameters(*constrainedParams);
914  combined->import(globalObs);
915  combined->defineSet("globalObservables",globalObs);
916  combined_config->SetGlobalObservables(*combined->set("globalObservables"));
917 
918  ////////////////////////////////////////////
919  // Make toy simultaneous dataset
920  cout <<"-----------------------------------------"<<endl;
921  cout << "create toy data for " << ss.str() << endl;
922 
923  const RooArgSet* obsN = chs[0]->set("obsN");
924 
925  RooDataSet * simData=new RooDataSet("simData","master dataset", *obsN,
926  Index(*channelCat), Import(ch_names[0].c_str(),*((RooDataSet*)chs[0]->data("expData"))));
927  for(unsigned int i = 1; i< ch_names.size(); ++i){
928  RooDataSet * simData_ch=new RooDataSet("simData","master dataset", *obsN,
929  Index(*channelCat), Import(ch_names[i].c_str(),*((RooDataSet*)chs[i]->data("expData"))));
930  simData->append(*simData_ch);
931  }
932  //for(int i=0; i<simData->numEntries(); ++i)
933  // simData->get(i)->Print("v");
934 
935  combined->import(*simData,RecycleConflictNodes());
936 
937  cout << "\n\n----------------\n Importing combined model" << endl;
938  combined->import(*simPdf,RecycleConflictNodes());
939  //combined->import(*simPdf, RenameVariable("SigXsecOverSM","SigXsecOverSM_comb"));
940  cout << "check pointer " << simPdf << endl;
941 
942  for(unsigned int i=0; i<fSystToFix.size(); ++i){
943  // make sure they are fixed
944  RooRealVar* temp = combined->var((fSystToFix.at(i)).c_str());
945  if(temp) {
946  temp->setConstant();
947  cout <<"setting " << fSystToFix.at(i) << " constant" << endl;
948  }
949  else cout << "could not find variable " << fSystToFix.at(i) << " could not set it to constant" << endl;
950  }
951 
952  ///
953  /// writing out the model in graphViz
954  ///
955  // RooAbsPdf* customized=combined->pdf("simPdf");
956  //combined_config->SetPdf(*customized);
957  combined_config->SetPdf(*simPdf);
958  // customized->graphVizTree(("results/"+fResultsPrefixStr.str()+"_simul.dot").c_str());
959  combined->import(*combined_config,combined_config->GetName());
960  combined->importClassCode();
961  // combined->writeToFile("results/model_combined.root");
962 
963  return combined;
964  }
965 
966  ///////////////////////////////////////////////
967  void HistoToWorkspaceFactory::FitModel(RooWorkspace * combined, string channel, string /*model_name*/, string data_name, bool /*doParamInspect*/)
968  {
969 
970  ModelConfig * combined_config = (ModelConfig *) combined->obj("ModelConfig");
971  RooDataSet * simData = (RooDataSet *) combined->obj(data_name.c_str());
972  // const RooArgSet * constrainedParams=combined_config->GetNuisanceParameters();
973  const RooArgSet * POIs=combined_config->GetParametersOfInterest();
974 
975  /*
976  RooRealVar* poi = (RooRealVar*) combined->var("SigXsecOverSM");
977  RooArgSet * params= new RooArgSet;
978  params->add(*poi);
979  combined_config->SetParameters(*params);
980 
981  RooAbsData* expData = combined->data("expData");
982  RooArgSet* temp = (RooArgSet*) combined->set("obsN")->Clone("temp");
983  temp->add(*poi);
984  RooAbsPdf* model=combined_config->GetPdf();
985  RooArgSet* constrainedParams = model->getParameters(temp);
986  combined->defineSet("constrainedParams", *constrainedParams);
987  */
988 
989  //RooAbsPdf* model=combined->pdf(model_name.c_str());
990  RooAbsPdf* model=combined_config->GetPdf();
991  // RooArgSet* allParams = model->getParameters(*simData);
992 
993  ///////////////////////////////////////
994  //Do combined fit
995  //RooMsgService::instance().setGlobalKillBelow(RooMsgService::INFO) ;
996  cout << "\n\n---------------" << endl;
997  cout << "---------------- Doing "<< channel << " Fit" << endl;
998  cout << "---------------\n\n" << endl;
999  // RooFitResult* result = model->fitTo(*simData, Minos(kTRUE), Save(kTRUE), PrintLevel(1));
1000  model->fitTo(*simData, Minos(kTRUE), PrintLevel(1));
1001  // PrintCovarianceMatrix(result, allParams, "results/"+FilePrefixStr(channel)+"_corrMatrix.table" );
1002 
1003  //
1004  // assuming there is only on poi
1005  //
1006  RooRealVar* poi = 0; // (RooRealVar*) POIs->first();
1007  // for results tables
1008  TIterator* params_itr=POIs->createIterator();
1009  TObject* params_obj=0;
1010  while((params_obj=params_itr->Next())){
1011  poi = (RooRealVar*) params_obj;
1012  cout << "printing results for " << poi->GetName() << " at " << poi->getVal()<< " high " << poi->getErrorLo() << " low " << poi->getErrorHi()<<endl;
1013  }
1014  fprintf(pFile, " %.4f / %.4f ", poi->getErrorLo(), poi->getErrorHi());
1015 
1016  RooAbsReal* nll = model->createNLL(*simData);
1017  RooAbsReal* profile = nll->createProfile(*poi);
1018  RooPlot* frame = poi->frame();
1019  FormatFrameForLikelihood(frame);
1020  TCanvas* c1 = new TCanvas( channel.c_str(), "",800,600);
1021  nll->plotOn(frame, ShiftToZero(), LineColor(kRed), LineStyle(kDashed));
1022  profile->plotOn(frame);
1023  frame->SetMinimum(0);
1024  frame->SetMaximum(2.);
1025  frame->Draw();
1026  // c1->SaveAs( ("results/"+FilePrefixStr(channel)+"_profileLR.eps").c_str() );
1027  c1->SaveAs( (fFileNamePrefix+"_"+channel+"_"+fRowTitle+"_profileLR.eps").c_str() );
1028 
1029  fOut_f->mkdir(channel.c_str())->mkdir("Summary")->cd();
1030 
1031  // an example of calculating profile for a nuisance parameter not poi
1032  /*
1033  RooRealVar* alpha_isrfsr = (RooRealVar*) combined->var("alpha_isrfsr");
1034  RooAbsReal* profile_isrfsr = nll->createProfile(*alpha_isrfsr);
1035  poi->setVal(0.55);
1036  poi->setConstant();
1037 
1038  RooPlot* frame_isrfsr = alpha_isrfsr->frame();
1039  profile_isrfsr->plotOn(frame_isrfsr, Precision(0.1));
1040  TCanvas c_isrfsr = new TCanvas( "combined", "",800,600);
1041  FormatFrameForLikelihood(frame_isrfsr, "alpha_{isrfsr}");
1042  frame_isrfsr->Draw();
1043  fOut_f->cd("Summary");
1044  c1->Write((FilePrefixStr(channel).str()+"_profileLR_alpha_isrfsr").c_str() );
1045  delete frame; delete c1;
1046  poi->setConstant(kFALSE);
1047  */
1048 
1049  RooCurve* curve=frame->getCurve();
1050  Int_t curve_N=curve->GetN();
1051  Double_t* curve_x=curve->GetX();
1052  delete frame; delete c1;
1053 
1054  //
1055  // Verbose output from MINUIT
1056  //
1057  /*
1058  RooMsgService::instance().setGlobalKillBelow(RooFit::DEBUG) ;
1059  profile->getVal();
1060  RooMinuit* minuit = ((RooProfileLL*) profile)->minuit();
1061  minuit->setPrintLevel(5) ; // Print MINUIT messages
1062  minuit->setVerbose(5) ; // Print RooMinuit messages with parameter
1063  // changes (corresponds to the Verbose() option of fitTo()
1064  */
1065 
1066  Double_t * x_arr = new Double_t[curve_N];
1067  Double_t * y_arr_nll = new Double_t[curve_N];
1068 // Double_t y_arr_prof_nll[curve_N];
1069 // Double_t y_arr_prof[curve_N];
1070 
1071  for(int i=0; i<curve_N; i++){
1072  double f=curve_x[i];
1073  poi->setVal(f);
1074  x_arr[i]=f;
1075  y_arr_nll[i]=nll->getVal();
1076  }
1077  TGraph * g = new TGraph(curve_N, x_arr, y_arr_nll);
1078  g->SetName((FilePrefixStr(channel)+"_nll").c_str());
1079  g->Write();
1080  delete g;
1081  delete [] x_arr;
1082  delete [] y_arr_nll;
1083 
1084  /** find out what's inside the workspace **/
1085  //combined->Print();
1086 
1087  }
1088 
1089 
1090 void HistoToWorkspaceFactory::FormatFrameForLikelihood(RooPlot* frame, string /*XTitle*/, string YTitle){
1091 
1092  gStyle->SetCanvasBorderMode(0);
1093  gStyle->SetPadBorderMode(0);
1094  gStyle->SetPadColor(0);
1095  gStyle->SetCanvasColor(255);
1096  gStyle->SetTitleFillColor(255);
1097  gStyle->SetFrameFillColor(0);
1098  gStyle->SetStatColor(255);
1099 
1100  RooAbsRealLValue* var = frame->getPlotVar();
1101  double xmin = var->getMin();
1102  double xmax = var->getMax();
1103 
1104  frame->SetTitle("");
1105  // frame->GetXaxis()->SetTitle(XTitle.c_str());
1106  frame->GetXaxis()->SetTitle(var->GetTitle());
1107  frame->GetYaxis()->SetTitle(YTitle.c_str());
1108  frame->SetMaximum(2.);
1109  frame->SetMinimum(0.);
1110  TLine * line = new TLine(xmin,.5,xmax,.5);
1111  line->SetLineColor(kGreen);
1112  TLine * line90 = new TLine(xmin,2.71/2.,xmax,2.71/2.);
1113  line90->SetLineColor(kGreen);
1114  TLine * line95 = new TLine(xmin,3.84/2.,xmax,3.84/2.);
1115  line95->SetLineColor(kGreen);
1116  frame->addObject(line);
1117  frame->addObject(line90);
1118  frame->addObject(line95);
1119  }
1120 
1121  TDirectory * HistoToWorkspaceFactory::Makedirs( TDirectory * file, vector<string> names ){
1122  if(! file) return file;
1123  string path="";
1124  TDirectory* ptr=0;
1125  for(vector<string>::iterator itr=names.begin(); itr != names.end(); ++itr){
1126  if( ! path.empty() ) path+="/";
1127  path+=(*itr);
1128  ptr=file->GetDirectory(path.c_str());
1129  if( ! ptr ) ptr=file->mkdir((*itr).c_str());
1130  file=file->GetDirectory(path.c_str());
1131  }
1132  return ptr;
1133  }
1134  TDirectory * HistoToWorkspaceFactory::Mkdir( TDirectory * file, string name ){
1135  if(! file) return file;
1136  TDirectory* ptr=0;
1137  ptr=file->GetDirectory(name.c_str());
1138  if( ! ptr ) ptr=file->mkdir(name.c_str());
1139  return ptr;
1140  }
1141 
1142 }
1143 }
1144