CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TagProbeFitter.cc
Go to the documentation of this file.
2 #include <stdexcept>
3 //#include "TagProbeFitter.h"
4 
5 #include "TROOT.h"
6 #include "TFile.h"
7 #include "TPad.h"
8 #include "TText.h"
9 #include "TCanvas.h"
10 #include "TGraphAsymmErrors.h"
11 #include "TH2F.h"
12 #include "TStyle.h"
13 #include "Math/QuantFuncMathCore.h"
14 #include "Roo1DTable.h"
15 #include "RooAbsDataStore.h"
16 #include "RooAbsReal.h"
17 #include "RooAddPdf.h"
18 #include "RooBinning.h"
19 #include "RooBinningCategory.h"
20 #include "RooCategory.h"
21 #include "RooChebychev.h"
22 #include "RooDataHist.h"
23 #include "RooDataSet.h"
24 #include "RooEfficiency.h"
25 #include "RooExtendPdf.h"
26 #include "RooFitResult.h"
27 #include "RooFormulaVar.h"
28 #include "RooGaussian.h"
29 #include "RooGenericPdf.h"
30 #include "RooGlobalFunc.h"
31 #include "RooLinkedListIter.h"
32 #include "RooMappedCategory.h"
33 #include "RooMinimizer.h"
34 #include "RooMinuit.h"
35 #include "RooMsgService.h"
36 #include "RooMultiCategory.h"
37 #include "RooNLLVar.h"
38 #include "RooNumIntConfig.h"
39 #include "RooPlot.h"
40 #include "RooProdPdf.h"
41 #include "RooProfileLL.h"
42 #include "RooRealVar.h"
43 #include "RooSimultaneous.h"
44 #include "RooThresholdCategory.h"
45 #include "RooTrace.h"
46 #include "RooWorkspace.h"
47 
48 using namespace std;
49 using namespace RooFit;
50 
51 TagProbeFitter::TagProbeFitter(const std::vector<std::string>& inputFileNames, string inputDirectoryName, string inputTreeName, string outputFileName, int numCPU_, bool saveWorkspace_, bool floatShapeParameters_, const std::vector<std::string>& fixVars_){
52  inputTree = new TChain((inputDirectoryName+"/"+inputTreeName).c_str());
53  for(size_t i=0; i<inputFileNames.size(); i++){
54  inputTree->Add(inputFileNames[i].c_str());
55  }
56  outputFile = new TFile(outputFileName.c_str(),"recreate");
57  outputDirectory = outputFile->mkdir(inputDirectoryName.c_str());
58  numCPU = numCPU_;
59  saveWorkspace = saveWorkspace_;
60  massBins = 0; // automatic default
61  floatShapeParameters = floatShapeParameters_;
62  fixVars = fixVars_;
63  weightVar = "";
64  if(!floatShapeParameters && fixVars.empty()) std::cout << "TagProbeFitter: " << "You wnat to fix some variables but do not specify them!";
65 
66  gROOT->SetStyle("Plain");
67  gStyle->SetTitleFillColor(0);
68  gStyle->SetPalette(1);
69  gStyle->SetOptStat(0);
70  gStyle->SetPaintTextFormat(".2f");
71 
72  quiet = false;
73 
74  binnedFit = false;
75 
76  doSaveDistributionsPlot = true;
77 
78  // make integration very precise
79  RooAbsReal::defaultIntegratorConfig()->setEpsAbs(1e-13);
80  RooAbsReal::defaultIntegratorConfig()->setEpsRel(1e-13);
81 }
82 
84  if(inputTree)
85  delete inputTree;
86  if(outputFile)
87  outputFile->Close();
88 }
89 
90 void TagProbeFitter::setQuiet(bool quiet_) {
91  quiet = quiet_;
92  if (quiet) {
93  RooMsgService::instance().setGlobalKillBelow(RooFit::ERROR);
94  } else {
95  RooMsgService::instance().setGlobalKillBelow(RooFit::WARNING);
96  }
97 }
98 bool TagProbeFitter::addVariable(string name, string title, double low, double hi, string units){
99  RooRealVar temp(name.c_str(), title.c_str(), low, hi, units.c_str());
100  temp.setBins(5000,"cache");
101  variables.addClone(temp);
102  return true;
103 }
104 
105 bool TagProbeFitter::addCategory(string name, string title, string expression){
106  RooCategory* c = (RooCategory*) parameterParser.factory(expression.c_str());
107  if(!c)
108  return false;
109  //set the name of the category to the passed name instead of the one in the expression
110  c->SetName(name.c_str());
111  c->SetTitle(title.c_str());
112  variables.addClone(*c);
113  return true;
114 }
115 
116 bool TagProbeFitter::addExpression(string expressionName, string title, string expression, const std::vector<string>& arguments) {
117  expressionVars.push_back(make_pair(make_pair(expressionName,title), make_pair(expression,arguments)));
118  return true;
119 }
120 
121 
122 bool TagProbeFitter::addThresholdCategory(string categoryName, string title, string varName, double cutValue){
123  thresholdCategories.push_back(make_pair(make_pair(categoryName,title), make_pair(varName,cutValue)));
124  return true;
125 }
126 
127 
128 void TagProbeFitter::addPdf(string name, vector<string>& pdfCommands){
129  pdfs[name] = pdfCommands;
130 }
131 
133  massBins = bins;
134 }
135 
137  weightVar = var;
138 }
139 
140 string TagProbeFitter::calculateEfficiency(string dirName,const std::vector<string>& effCats,const std::vector<string>& effStates, vector<string>& unbinnedVariables, map<string, vector<double> >& binnedReals, map<string, std::vector<string> >& binnedCategories, vector<string>& binToPDFmap){
141  //go to home directory
142  outputDirectory->cd();
143  //make a directory corresponding to this efficiency binning
144  gDirectory->mkdir(dirName.c_str())->cd();
145 
146  RooArgSet dataVars;
147 
148  //collect unbinned variables
149  for(vector<string>::iterator v=unbinnedVariables.begin(); v!=unbinnedVariables.end(); v++){
150  dataVars.addClone(variables[v->c_str()], true);
151  if (binnedFit && (v == unbinnedVariables.begin())) {
152  ((RooRealVar&)dataVars[v->c_str()]).setBins(massBins);
153  }
154  }
155  //collect the binned variables and the corresponding bin categories
156  RooArgSet binnedVariables;
157  RooArgSet binCategories;
158  for(map<string, vector<double> >::iterator v=binnedReals.begin(); v!=binnedReals.end(); v++){
159  TString name = v->first;
160  if (variables.find(name) == 0) { cerr << "Binned variable '"<<name<<"' not found." << endl; return "Error"; }
161  binnedVariables.addClone(variables[name]);
162  ((RooRealVar&)binnedVariables[name]).setBinning( RooBinning(v->second.size()-1, &v->second[0]) );
163  binCategories.addClone( RooBinningCategory(name+"_bins", name+"_bins", (RooRealVar&)binnedVariables[name]) );
164  }
165  dataVars.addClone(binnedVariables, true);
166 
167  //collect the category variables and the corresponding mapped categories
168  RooArgSet categories;
169  RooArgSet mappedCategories;
170  for(map<string, vector<string> >::iterator v=binnedCategories.begin(); v!=binnedCategories.end(); v++){
171  TString name = v->first;
172  if (variables.find(name) == 0) { cerr << "Binned category '"<<name<<"' not found." << endl; return "Error"; }
173  categories.addClone(variables[name]);
174  mappedCategories.addClone(RooMappedCategory(name+"_bins", name+"_bins", (RooCategory&)categories[name]));
175  for(unsigned int i = 0; i<v->second.size(); i++){
176  ((RooMappedCategory&)mappedCategories[name+"_bins"]).map(v->second[i].c_str(), name+"_"+TString(v->second[i].c_str()).ReplaceAll(",","_"));
177  }
178  }
179  dataVars.addClone(categories, true);
180 
181  // add the efficiency category if it's not a dynamic one
182  for (vector<string>::const_iterator effCat = effCats.begin(); effCat != effCats.end(); ++effCat) {
183  if (variables.find(effCat->c_str()) != 0) {
184  dataVars.addClone(variables[effCat->c_str()], true);
185  }
186  }
187 
188  // add all variables used in expressions
189  for(vector<pair<pair<string,string>, pair<string, vector<string> > > >::const_iterator ev = expressionVars.begin(), eve = expressionVars.end(); ev != eve; ++ev){
190  for (vector<string>::const_iterator it = ev->second.second.begin(), ed = ev->second.second.end(); it != ed; ++it) {
191  // provided that they are real variables themselves
192  if (variables.find(it->c_str())) dataVars.addClone(variables[it->c_str()], true);
193  }
194  }
195  // add all real variables used in cuts
196  for(vector<pair<pair<string,string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(), tce = thresholdCategories.end(); tc != tce; ++tc){
197  if (variables.find(tc->second.first.c_str())) dataVars.addClone(variables[tc->second.first.c_str()], true);
198  }
199 
200 
201  //now add the necessary mass and passing variables to make the unbinned RooDataSet
202  RooDataSet data("data", "data", inputTree,
203  dataVars,
204  /*selExpr=*/"", /*wgtVarName=*/(weightVar.empty() ? 0 : weightVar.c_str()));
205 
206  // Now add all expressions that are computed dynamically
207  for(vector<pair<pair<string,string>, pair<string, vector<string> > > >::const_iterator ev = expressionVars.begin(), eve = expressionVars.end(); ev != eve; ++ev){
208  RooArgList args;
209  for (vector<string>::const_iterator it = ev->second.second.begin(), ed = ev->second.second.end(); it != ed; ++it) {
210  args.add(dataVars[it->c_str()]);
211  }
212  RooFormulaVar expr(ev->first.first.c_str(), ev->first.second.c_str(), ev->second.first.c_str(), args);
213  RooRealVar *col = (RooRealVar *) data.addColumn(expr);
214  dataVars.addClone(*col);
215  }
216 
217  // And add all dynamic categories from thresholds
218  for(vector<pair<pair<string,string>, pair<string, double> > >::const_iterator tc = thresholdCategories.begin(), tce = thresholdCategories.end(); tc != tce; ++tc){
219  RooThresholdCategory tmp(tc->first.first.c_str(), tc->first.second.c_str(), (RooAbsReal &)dataVars[tc->second.first.c_str()], "above", 1);
220  tmp.addThreshold(tc->second.second, "below",0);
221  RooCategory *cat = (RooCategory *) data.addColumn(tmp);
222  dataVars.addClone(*cat);
223  }
224 
225 
226  //merge the bin categories to a MultiCategory for convenience
227  RooMultiCategory allCats("allCats", "allCats", RooArgSet(binCategories, mappedCategories));
228  data.addColumn(allCats);
229  string effName;
230  //setup the efficiency category
231  if (effCats.size() == 1) {
232  effName = effCats.front() + "::" + effStates.front();
233  RooMappedCategory efficiencyCategory("_efficiencyCategory_", "_efficiencyCategory_", (RooCategory&)dataVars[effCats.front().c_str()], "Failed");
234  efficiencyCategory.map(effStates.front().c_str(), "Passed");
235  data.addColumn( efficiencyCategory );
236  } else {
237  RooArgSet rooEffCats;
238  string multiState = "{";
239  for (size_t i = 0; i < effCats.size(); ++i) {
240  if (i) { multiState += ";"; effName += " && "; }
241  rooEffCats.add((RooCategory &) dataVars[effCats[i].c_str()]);
242  multiState += effStates[i];
243  effName = effCats[i] + "::" + effStates[i];
244  }
245  multiState += "}";
246  RooMultiCategory efficiencyMultiCategory("_efficiencyMultiCategory_", "_efficiencyMultiCategory_", rooEffCats);
247  RooMappedCategory efficiencyCategory("_efficiencyCategory_", "_efficiencyCategory_", efficiencyMultiCategory, "Failed");
248  efficiencyCategory.map(multiState.c_str(), "Passed");
249  data.addColumn( efficiencyCategory );
250  }
251  //setup the pdf category
252  RooMappedCategory pdfCategory("_pdfCategory_", "_pdfCategory_", allCats, (binToPDFmap.size()>0)?binToPDFmap[0].c_str():"all");
253  for(unsigned int i = 1; i<binToPDFmap.size(); i+=2){
254  pdfCategory.map(binToPDFmap[i].c_str(), binToPDFmap[i+1].c_str());
255  }
256  data.addColumn( pdfCategory );
257 
258  //create the empty efficiency datasets from the binned variables
259  RooRealVar efficiency("efficiency", "Efficiency", 0, 1);
260 
261  RooDataSet fitEfficiency("fit_eff", "Efficiency from unbinned ML fit", RooArgSet(RooArgSet(binnedVariables, categories), efficiency), StoreAsymError(RooArgSet(binnedVariables, efficiency)));
262 // RooDataSet sbsEfficiency("sbs_eff", "Efficiency from side band substraction", RooArgSet(RooArgSet(binnedVariables, categories), efficiency), StoreAsymError(RooArgSet(binnedVariables, efficiency)));
263  RooDataSet cntEfficiency("cnt_eff", "Efficiency from counting", RooArgSet(RooArgSet(binnedVariables, categories), efficiency), StoreAsymError(RooArgSet(binnedVariables, efficiency)));
264 
265 
266  if(!floatShapeParameters){
267  //fitting whole dataset to get initial values for some parameters
268  RooWorkspace* w = new RooWorkspace();
269  w->import(data);
270  efficiency.setVal(0);//reset
271  efficiency.setAsymError(0,0);
272  std::cout << "ALL dataset: calling doFitEfficiency with pdf: " << pdfCategory.getLabel() << std::endl;
273  doFitEfficiency(w, pdfCategory.getLabel(), efficiency);
274  delete w;
275  }
276 
277  //loop over all bins with the help of allCats
278  TIterator* it = allCats.typeIterator();
279  for(RooCatType* t = (RooCatType*)it->Next(); t!=0; t = (RooCatType*)it->Next() ){
280  //name of the multicategory
281  TString catName = t->GetName();
282  //skip unmapped states
283  if(catName.Contains("NotMapped")) continue;
284  //create the dataset
285  RooAbsData* data_bin = (RooDataSet*) data.reduce(Cut(TString::Format("allCats==%d",t->getVal())));
286  //set the category variables by reading the first event
287  const RooArgSet* row = data_bin->get();
288 
289  //get PDF name
290  TString pdfName(((RooCategory*)row->find("_pdfCategory_"))->getLabel());
291 
292 
293  //make directory name
294  TString dirName = catName;
295  dirName.ReplaceAll("{","").ReplaceAll("}","").ReplaceAll(";","__");
296  if(pdfName.Length() > 0){
297  dirName.Append("__").Append(pdfName);
298  }
299 
300  cout<<"Fitting bin: "<<dirName<<endl;
301  //make a directory for each bin
302  gDirectory->mkdir(dirName)->cd();
303 
304 
305  //create a workspace
306  RooWorkspace* w = new RooWorkspace();
307  //import the data
308  w->import(*data_bin);
309  delete data_bin; // clean up earlier
310  data_bin = w->data("data"); // point to the data that's in the workspace now (saves memory)
311 
312  //save the distribution of variables
313  if (doSaveDistributionsPlot) saveDistributionsPlot(w);
314  //do the fitting only if there is sufficient number of events
315  if(data_bin->numEntries()>0){
316  //set the values of binnedVariables to the mean value in this data bin
317  RooArgSet meanOfVariables;
318  RooLinkedListIter vit = binnedVariables.iterator();
319  for(RooRealVar* v = (RooRealVar*)vit.Next(); v!=0; v = (RooRealVar*)vit.Next() ){
320  meanOfVariables.addClone(*v);
321  double mean = w->data("data")->mean(*v);
322  RooBinning binning((RooBinning&)v->getBinning());
323  int ind = binning.binNumber(mean);
324  RooRealVar& newVar = (RooRealVar&)meanOfVariables[v->GetName()];
325  newVar.setVal(mean);
326  newVar.setAsymError(binning.binLow(ind)-mean, binning.binHigh(ind)-mean);
327  }
328 
329  //put an entry in the efficiency dataset
330  //note that the category values are coming from data_bin->get(0)
331  meanOfVariables.addClone(*data_bin->get(0), true);
332 
333  efficiency.setVal(0);//reset
334  efficiency.setAsymError(0,0);
335  doFitEfficiency(w, pdfName.Data(), efficiency);
336  fitEfficiency.add( RooArgSet(meanOfVariables, efficiency) );
337 
338 /* efficiency.setVal(0);//reset
339  doSBSEfficiency(w, efficiency);
340  sbsEfficiency.add( RooArgSet(meanOfVariables, efficiency) );*/
341 
342  efficiency.setVal(0);//reset
343  doCntEfficiency(w, efficiency);
344  cntEfficiency.add( RooArgSet(meanOfVariables, efficiency) );
345  }
346  //save the workspace if requested
347  if(saveWorkspace){
348  w->Write("w");
349  }
350  //clean up
351  delete w;
352  //get back to the initial directory
353  gDirectory->cd("..");
354  }
355 
356  //save the efficiency data
357  fitEfficiency.Write();
358  gDirectory->mkdir("fit_eff_plots")->cd();
359  saveEfficiencyPlots(fitEfficiency, effName, binnedVariables, mappedCategories);
360  gDirectory->cd("..");
361 
362 /* sbsEfficiency.Write();
363  gDirectory->mkdir("sbs_eff_plots")->cd();
364  saveEfficiencyPlots(sbsEfficiency, effCat+"::"+effState, binnedVariables, mappedCategories);
365  gDirectory->cd("..");*/
366 
367  cntEfficiency.Write();
368  gDirectory->mkdir("cnt_eff_plots")->cd();
369  saveEfficiencyPlots(cntEfficiency, effName, binnedVariables, mappedCategories);
370  gDirectory->cd("..");
371  //empty string means no error
372  return "";
373 }
374 
375 void TagProbeFitter::doFitEfficiency(RooWorkspace* w, string pdfName, RooRealVar& efficiency){
376  //if pdfName is empty skip the fit
377  if(pdfName == "all"){
378  return;
379  }
380  //create the simultaneous pdf of name pdfName
381  createPdf(w, pdfs[pdfName]);
382  //set the initial values for the yields of signal and background
383  setInitialValues(w);
384  std::auto_ptr<RooFitResult> res(0);
385 
386  RooAbsData *data = w->data("data");
387  std::auto_ptr<RooDataHist> bdata;
388  if (binnedFit) {
389  // get variables from data, which contain also other binning or expression variables
390  const RooArgSet *dataObs = data->get(0);
391  // remove everything which is not a dependency of the pdf
392  RooArgSet *obs = w->pdf("simPdf")->getObservables(dataObs);
393  bdata.reset(new RooDataHist("data_binned", "data_binned", *obs, *data));
394  w->import(*bdata);
395  data = w->data("data_binned");
396  delete obs;
397  }
398 
399  double totPassing = data->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Passed");
400  double totFailing = data->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Failed");
401 
402  RooAbsReal* simNLL = w->pdf("simPdf")->createNLL(*data,Extended(true),NumCPU(numCPU));
403 
404  RooMinimizer minimizer(*simNLL); // we are going to use this for 'scan'
405  RooMinuit minuit(*simNLL);
406  minuit.setStrategy(1);
407  minuit.setProfile(true);
408  RooProfileLL profileLL("simPdfNLL","",*simNLL,*w->var("efficiency"));
409 
410 
411  //******* The block of code below is to make the fit converge faster.
412  // ****** This part is OPTIONAL, i.e., off be default. User can activate this
413  // ****** by setting the following parameters: "fixVars" and "floatShapeParameters"
414  // ****** Here is the full logic:
425 
426 
427  if(!fixVars.empty()){
428  // calculate initial values for parameters user want to fix
429  if(!floatShapeParameters && fixVarValues.empty()){
430  // we want to fix these parameters for each bin.
431  // the following sequence fixes them, fits, releases and fits again
432  // to get reasonable values.
433  // ----------------------------------------------------------------------
434  // This procedure works only once with a whole dataset (without binning)
435  // ----------------------------------------------------------------------
436 
437  // fix them
438  varFixer(w,true);
439  //do fit
440  minimizer.minimize("Minuit2","Scan");
441  minuit.migrad();
442  minuit.hesse();
443  //minuit.minos();
444  //w->pdf("simPdf")->fitTo(*data, Save(true), Extended(true), NumCPU(numCPU), Strategy(2),
445  //PrintLevel(quiet?-1:1), PrintEvalErrors(quiet?-1:1), Warnings(!quiet));
446  //release vars
447  varFixer(w,false);
448  //do fit
449  minimizer.minimize("Minuit2","Scan");
450  minuit.migrad();
451  minuit.hesse();
452  //minuit.minos();
453  //w->pdf("simPdf")->fitTo(*data, Save(true), Extended(true), NumCPU(numCPU), Strategy(2),
454  //PrintLevel(quiet?-1:1), PrintEvalErrors(quiet?-1:1), Warnings(!quiet));
455  //save vars
456  varSaver(w);
457  // now we have a starting point. Fit will converge faster.
458  }
459 
460  // here we can use initial values if we want (this works for each bin)
461  if(!floatShapeParameters) varRestorer(w); //restore vars
462 
463  //do fit
464  minimizer.minimize("Minuit2","Scan");
465  minuit.migrad();
466  minuit.hesse();
467  // initialize the profile likelihood
468  profileLL.getVal();
469  RooMinimizer* profMinuit = profileLL.minimizer();
470  profMinuit->setProfile(true);
471  profMinuit->setStrategy(2);
472  profMinuit->setPrintLevel(1);
473  profMinuit->minos(*w->var("efficiency"));
474  res.reset( profMinuit->save() );
475  //res = w->pdf("simPdf")->fitTo(*data, Save(true), Extended(true), NumCPU(numCPU), Strategy(2),
476  //Minos(*w->var("efficiency")), PrintLevel(quiet?-1:1),
477  //PrintEvalErrors(quiet?-1:1), Warnings(!quiet));
478  }//if(!fixVars.empty())
479 
480  // (default = true) if we don't want to fix any parameters or want to fit each bin with all parameters floating
481  if(floatShapeParameters){
482  //release vars
483  varFixer(w,false);
484 
485  //do fit
486  minimizer.minimize("Minuit2","Scan");
487  minuit.migrad();
488  minuit.hesse();
489  res.reset( w->pdf("simPdf")->fitTo(*data, Save(true), Extended(true), NumCPU(numCPU), Strategy(2),
490  Minos(*w->var("efficiency")), PrintLevel(quiet?-1:1),
491  PrintEvalErrors(quiet?-1:1), Warnings(!quiet)) );
492  }
493 
494 
495 
496  // save everything
497  res->Write("fitresults");
498  w->saveSnapshot("finalState",w->components());
499  saveFitPlot(w);
500  //extract the efficiency parameter from the results
501  RooRealVar* e = (RooRealVar*) res->floatParsFinal().find("efficiency");
502  //What's wrong with this? and why don't they copy the errors!
503  //efficiency = *e;
504  efficiency.setVal(e->getVal());
505  Double_t errLo = e->getErrorLo(), errHi = e->getErrorHi();
506  if (errLo == 0 && e->getVal() < 0.5) errLo = e->getMin()-e->getVal();
507  if (errHi == 0 && e->getVal() > 0.5) errHi = e->getMax()-e->getVal();
508  efficiency.setAsymError(errLo, errHi);
509 
510  if (totPassing * totFailing == 0) {
511  RooRealVar* nTot = (RooRealVar*) res->floatParsFinal().find("numTot");
512  RooRealVar* fSig = (RooRealVar*) res->floatParsFinal().find("fSigAll");
513  double cerr = ROOT::Math::beta_quantile( 1-(1.0-.68540158589942957)/2, 1, nTot->getVal() * fSig->getVal() );
514  /*
515  std::cout << "======================================================================================" << std::endl;
516  std::cout << "======= totPassing " << totPassing << ", totFailing " << totFailing << std::endl;
517  std::cout << "======= FIT: e " << e->getVal() << ", e Lo " << e->getErrorLo() << ", e Hi " << e->getErrorHi() << std::endl;
518  std::cout << "======= FIT:nS " << nS->getVal() << ", nS Lo " << nS->getErrorLo() << ", nS Hi " << nS->getErrorHi() << std::endl;
519  std::cout << "======= FIT:nB " << nB->getVal() << ", nB Lo " << nB->getErrorLo() << ", nB Hi " << nB->getErrorHi() << std::endl;
520  std::cout << "======= CNT: " << cerr << std::endl;
521  std::cout << "======================================================================================" << std::endl;
522  */
523  if (totPassing == 0) {
524  efficiency.setVal(0);
525  efficiency.setAsymError(0,cerr);
526  } else {
527  efficiency.setVal(1);
528  efficiency.setAsymError(-cerr,0);
529  }
530  }
531 
532  delete simNLL;
533 }
534 
535 void TagProbeFitter::createPdf(RooWorkspace* w, vector<string>& pdfCommands){
536  // create the signal and background pdfs defined by the user
537  for(unsigned int i=0; i<pdfCommands.size(); i++){
538  const std::string & command = pdfCommands[i];
539  if (command.find("#import ") == 0) {
540  TDirectory *here = gDirectory;
541  w->import(command.substr(8).c_str());
542  here->cd();
543  } else {
544  TDirectory *here = gDirectory;
545  w->factory(command.c_str());
546  here->cd();
547  }
548  }
549  // setup the simultaneous extended pdf
550 
551  w->factory("expr::nSignalPass('efficiency*fSigAll*numTot', efficiency, fSigAll[.9,0,1],numTot[1,0,1e10])");
552  w->factory("expr::nSignalFail('(1-efficiency)*fSigAll*numTot', efficiency, fSigAll,numTot)");
553  w->factory("expr::nBkgPass('effBkg*(1-fSigAll)*numTot', effBkg[.9,0,1],fSigAll,numTot)");
554  w->factory("expr::nBkgFail('(1-effBkg)*(1-fSigAll)*numTot', effBkg,fSigAll,numTot)");
555  TString sPass = "signal", sFail = "signal";
556  if (w->pdf("signalPass") != 0 && w->pdf("signalFail") != 0) {
557  if (w->pdf("signal") != 0) throw std::logic_error("You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail'), not both!");
558  sPass = "signalPass"; sFail = "signalFail";
559  } else if (w->pdf("signal") != 0) {
560  if (w->pdf("signalPass") != 0 || w->pdf("signalFail") != 0) {
561  throw std::logic_error("You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail'), not both!");
562  }
563  } else {
564  throw std::logic_error("You must either define one 'signal' PDF or two PDFs ('signalPass', 'signalFail')");
565  }
566  w->factory("SUM::pdfPass(nSignalPass*"+sPass+", nBkgPass*backgroundPass)"); //fBkgPass*
567  w->factory("SUM::pdfFail(nSignalFail*"+sFail+", nBkgFail*backgroundFail)"); //fBkgFail*
568 
569  w->factory("SIMUL::simPdf(_efficiencyCategory_, Passed=pdfPass, Failed=pdfFail)");
570  // signalFractionInPassing is not used in the fit just to set the initial values
571  if (w->pdf("simPdf") == 0) throw std::runtime_error("Could not create simultaneous fit pdf.");
572  if(w->var("signalFractionInPassing") == 0)
573  w->factory("signalFractionInPassing[0.9]");
574 }
575 
576 void TagProbeFitter::setInitialValues(RooWorkspace* w){
577  // calculate initial values
578  double signalEfficiency = w->var("efficiency")->getVal();
579  double signalFractionInPassing = w->var("signalFractionInPassing")->getVal();
580  double totPassing = w->data("data")->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Passed");
581  double totFailinging = w->data("data")->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Failed");
582  double numSignalAll = totPassing*signalFractionInPassing/signalEfficiency;
583 
584  //std::cout << "Number of probes: " << totPassing+totFailinging << std::endl;
585 
586  // check if this value is inconsistent on the failing side
587  if(numSignalAll*(1-signalEfficiency) > totFailinging)
588  numSignalAll = totFailinging;
589  // now set the values
590  w->var("numTot")->setVal(totPassing+totFailinging);
591  w->var("numTot")->setMax(2.0*(totPassing+totFailinging)+10); //wiggle room in case of 0 events in bin
592 
593  if (totPassing == 0) {
594  w->var("efficiency")->setVal(0.0);
595  w->var("efficiency")->setAsymError(0,1);
596  w->var("efficiency")->setConstant(false);
597  } else if (totFailinging == 0) {
598  w->var("efficiency")->setVal(1.0);
599  w->var("efficiency")->setAsymError(-1,0);
600  w->var("efficiency")->setConstant(false);
601  } else {
602  w->var("efficiency")->setConstant(false);
603  }
604 
605  // if signal fraction is 1 then set the number of background events to 0.
606  //RooRealVar* fBkgPass = w->var("numBackgroundPass");
607  //if(signalFractionInPassing==1.0) { fBkgPass->setVal(0.0); fBkgPass->setConstant(true); }
608 
609  // save initial state for reference
610  w->saveSnapshot("initialState",w->components());
611 }
612 
613 void TagProbeFitter::saveFitPlot(RooWorkspace* w){
614  // save refferences for convenience
615  RooCategory& efficiencyCategory = *w->cat("_efficiencyCategory_");
616  RooAbsData* dataAll = (binnedFit ? w->data("data_binned") : w->data("data") );
617  RooAbsData* dataPass = dataAll->reduce(Cut("_efficiencyCategory_==_efficiencyCategory_::Passed"));
618  RooAbsData* dataFail = dataAll->reduce(Cut("_efficiencyCategory_==_efficiencyCategory_::Failed"));
619  RooAbsPdf& pdf = *w->pdf("simPdf");
620  std::auto_ptr<RooArgSet> obs(pdf.getObservables(*dataAll));
621  RooRealVar* mass = 0;
622  RooLinkedListIter it = obs->iterator();
623  for(RooAbsArg* v = (RooAbsArg*)it.Next(); v!=0; v = (RooAbsArg*)it.Next() ){
624  if(!v->InheritsFrom("RooRealVar")) continue;
625  mass = (RooRealVar*)v;
626  break;
627  }
628  if(!mass) return;
629  // make a 2x2 canvas
630  TCanvas canvas("fit_canvas");
631  canvas.Divide(2,2);
632  vector<RooPlot*> frames;
633  // plot the Passing Probes
634  canvas.cd(1);
635  if (massBins == 0) {
636  frames.push_back(mass->frame(Name("Passing"), Title("Passing Probes")));
637  frames.push_back(mass->frame(Name("Failing"), Title("Failing Probes")));
638  frames.push_back(mass->frame(Name("All"), Title("All Probes")));
639  } else {
640  frames.push_back(mass->frame(Name("Passing"), Title("Passing Probes"), Bins(massBins)));
641  frames.push_back(mass->frame(Name("Failing"), Title("Failing Probes"), Bins(massBins)));
642  frames.push_back(mass->frame(Name("All"), Title("All Probes"), Bins(massBins)));
643  }
644  dataPass->plotOn(frames[0]);
645  pdf.plotOn(frames[0], Slice(efficiencyCategory, "Passed"), ProjWData(*dataPass), LineColor(kGreen));
646  pdf.plotOn(frames[0], Slice(efficiencyCategory, "Passed"), ProjWData(*dataPass), LineColor(kGreen), Components("backgroundPass"), LineStyle(kDashed));
647  frames[0]->Draw();
648  // plot the Failing Probes
649  canvas.cd(2);
650  dataFail->plotOn(frames[1]);
651  pdf.plotOn(frames[1], Slice(efficiencyCategory, "Failed"), ProjWData(*dataFail), LineColor(kRed));
652  pdf.plotOn(frames[1], Slice(efficiencyCategory, "Failed"), ProjWData(*dataFail), LineColor(kRed), Components("backgroundFail"), LineStyle(kDashed));
653  frames[1]->Draw();
654  // plot the All Probes
655  canvas.cd(3);
656  dataAll->plotOn(frames.back());
657  pdf.plotOn(frames.back(), ProjWData(*dataAll), LineColor(kBlue));
658  pdf.plotOn(frames.back(), ProjWData(*dataAll), LineColor(kBlue), Components("backgroundPass,backgroundFail"), LineStyle(kDashed));
659  frames.back()->Draw();
660  // plot the Fit Results
661  canvas.cd(4);
662  frames.push_back(mass->frame(Name("Fit Results"), Title("Fit Results")));
663  pdf.paramOn(frames.back(), dataAll, "", 0, "NELU", 0.1, 0.9, 0.9);
664  // draw only the parameter box not the whole frame
665  frames.back()->findObject(Form("%s_paramBox",pdf.GetName()))->Draw();
666  //save and clean up
667  canvas.Draw();
668  canvas.Write();
669  for (size_t i=0; i<frames.size(); i++) {
670  delete frames[i];
671  }
672  delete dataPass;
673  delete dataFail;
674 }
675 
677  // save pointers to datasets to manage memory
678  RooAbsData* dataAll = w->data("data");
679  RooAbsData* dataPass = dataAll->reduce(Cut("_efficiencyCategory_==_efficiencyCategory_::Passed"));
680  RooAbsData* dataFail = dataAll->reduce(Cut("_efficiencyCategory_==_efficiencyCategory_::Failed"));
681 
682  const RooArgSet* vars = dataAll->get();
683  vector<RooRealVar*> reals;
684  RooLinkedListIter it = vars->iterator();
685  for(RooAbsArg* v = (RooAbsArg*)it.Next(); v!=0; v = (RooAbsArg*)it.Next() ){
686  if(!v->InheritsFrom("RooRealVar")) continue;
687  reals.push_back((RooRealVar*)v);
688  }
689  TCanvas canvas("distributions_canvas");
690  canvas.Divide(3,reals.size());
691  vector<RooPlot*> frames;
692  for(unsigned int i=0; i<reals.size(); i++){
693  // plot the Passing Probes
694  canvas.cd(3*i+1);
695  frames.push_back(reals[i]->frame(Name("Passing"), Title("Passing Probes"), Bins(100)));
696  dataPass->plotOn(frames.back(), LineColor(kGreen));
697  dataPass->statOn(frames.back());
698  frames.back()->Draw();
699  // plot the Failing Probes
700  canvas.cd(3*i+2);
701  frames.push_back(reals[i]->frame(Name("Failing"), Title("Failing Probes"), Bins(100)));
702  dataFail->plotOn(frames.back(), LineColor(kRed));
703  dataFail->statOn(frames.back());
704  frames.back()->Draw();
705  // plot the All Probes
706  canvas.cd(3*i+3);
707  frames.push_back(reals[i]->frame(Name("All"), Title("All Probes"), Bins(100)));
708  dataAll->plotOn(frames.back(), LineColor(kBlue));
709  dataAll->statOn(frames.back());
710  frames.back()->Draw();
711  }
712  canvas.Draw();
713  canvas.Write();
714  for (size_t i=0; i<frames.size(); i++) {
715  delete frames[i];
716  }
717  delete dataPass;
718  delete dataFail;
719 }
720 
721 void TagProbeFitter::saveEfficiencyPlots(RooDataSet& eff, const TString& effName, RooArgSet& binnedVariables,RooArgSet& mappedCategories){
722  RooLinkedListIter v1it = binnedVariables.iterator();
723  bool isOnePoint = (eff.numEntries() == 1); // for datasets with > 1 entry, we don't make plots for variables with just one bin
724  for(RooRealVar* v1 = (RooRealVar*)v1it.Next(); v1!=0; v1 = (RooRealVar*)v1it.Next() ){
725  RooArgSet binCategories1D;
726  if (v1->numBins() == 1 && !isOnePoint) continue;
727  RooLinkedListIter v2it = binnedVariables.iterator();
728  for(RooRealVar* v2 = (RooRealVar*)v2it.Next(); v2!=0; v2 = (RooRealVar*)v2it.Next() ){
729  if(v2 == v1) continue;
730  if (v2->numBins() == 1 && !isOnePoint) continue;
731  binCategories1D.addClone( RooBinningCategory(TString(v2->GetName())+"_bins", TString(v2->GetName())+"_bins", *v2) );
732 
733  RooArgSet binCategories2D;
734  RooLinkedListIter v3it = binnedVariables.iterator();
735  for(RooRealVar* v3 = (RooRealVar*)v3it.Next(); v3!=0; v3 = (RooRealVar*)v3it.Next() ){
736  if(v3 == v1 || v3 == v2) continue;
737  binCategories2D.addClone( RooBinningCategory(TString(v3->GetName())+"_bins", TString(v3->GetName())+"_bins", *v3) );
738  }
739  RooMultiCategory allCats2D("allCats2D", "allCats2D", RooArgSet(binCategories2D, mappedCategories));
740  if(allCats2D.numTypes()==0){
741  makeEfficiencyPlot2D(eff, *v1, *v2, TString::Format("%s_%s_PLOT", v1->GetName(), v2->GetName()), "", effName);
742  }else{
743  RooDataSet myEff(eff);
744  myEff.addColumn(allCats2D);
745  std::auto_ptr<TIterator> catIt(allCats2D.typeIterator());
746  for(RooCatType* t = (RooCatType*)catIt->Next(); t!=0; t = (RooCatType*)catIt->Next() ){
747  TString catName = t->GetName();
748  if(catName.Contains("NotMapped")) continue;
749  catName.ReplaceAll("{","").ReplaceAll("}","").ReplaceAll(";","_&_");
750  makeEfficiencyPlot2D(myEff, *v1, *v2, TString::Format("%s_%s_PLOT_%s",v1->GetName(), v2->GetName(), catName.Data()), catName, effName, "allCats1D", t->getVal());
751  }
752  }
753  }
754  RooMultiCategory allCats1D("allCats1D", "allCats1D", RooArgSet(binCategories1D, mappedCategories));
755  if(allCats1D.numTypes()==0){
756  makeEfficiencyPlot1D(eff, *v1, TString::Format("%s_PLOT", v1->GetName()), "", effName);
757  }else{
758  RooDataSet myEff(eff);
759  myEff.addColumn(allCats1D);
760  std::auto_ptr<TIterator> catIt(allCats1D.typeIterator());
761  for(RooCatType* t = (RooCatType*)catIt->Next(); t!=0; t = (RooCatType*)catIt->Next() ){
762  TString catName = t->GetName();
763  if(catName.Contains("NotMapped")) continue;
764  catName.ReplaceAll("{","").ReplaceAll("}","").ReplaceAll(";","_&_");
765  makeEfficiencyPlot1D(myEff, *v1, TString::Format("%s_PLOT_%s", v1->GetName(), catName.Data()), catName, effName, "allCats1D", t->getVal());
766  }
767  }
768  }
769 }
770 
771 void TagProbeFitter::makeEfficiencyPlot1D(RooDataSet& eff, RooRealVar& v, const TString& plotName, const TString& plotTitle, const TString& effName, const char *catName, int catIndex){
772  TGraphAsymmErrors *p = new TGraphAsymmErrors();
773  const RooArgSet *entry = eff.get();
774  const RooRealVar &vi = dynamic_cast<const RooRealVar &>(*entry->find(v.GetName()));
775  const RooRealVar &ei = dynamic_cast<const RooRealVar &>(*entry->find("efficiency"));
776  for (unsigned int i = 0, n = eff.numEntries(); i < n; ++i) {
777  entry = eff.get(i);
778  if (catName != 0 && entry->getCatIndex(catName) != catIndex) continue;
779  int j = p->GetN(); p->Set(j+1);
780  p->SetPoint(j, vi.getVal(), ei.getVal() );
781  p->SetPointError(j, -vi.getAsymErrorLo(), vi.getAsymErrorHi(), -ei.getAsymErrorLo(), ei.getAsymErrorHi() );
782  }
783  TCanvas canvas(plotName);
784  TH1F *frame = new TH1F("frame", "Efficiency of "+effName, 1, v.getMin(), v.getMax()); frame->SetDirectory(0);
785  p->SetNameTitle(Form("hxy_%s", eff.GetName()), "Efficiency of "+effName);
786  p->GetXaxis()->SetTitle(strlen(v.getUnit()) ? Form("%s (%s)", v.GetName(), v.getUnit()) : v.GetName());
787  p->GetYaxis()->SetTitle("Efficiency of "+effName);
788  frame->GetXaxis()->SetTitle(strlen(v.getUnit()) ? Form("%s (%s)", v.GetName(), v.getUnit()) : v.GetName());
789  frame->GetYaxis()->SetTitle("Efficiency of "+effName);
790  frame->GetYaxis()->SetRangeUser(0,1);
791  frame->Draw();
792  p->SetLineWidth(2); p->SetMarkerStyle(kFullCircle); p->SetMarkerSize(1.2);
793  p->Draw("P SAME");
794  canvas.Write();
795  delete frame;
796  delete p;
797 }
798 
799 void TagProbeFitter::makeEfficiencyPlot2D(RooDataSet& eff, RooRealVar& v1, RooRealVar& v2, const TString& plotName, const TString& plotTitle, const TString& effName, const char *catName, int catIndex){
800  TCanvas canvas(plotName);
801  canvas.SetRightMargin(0.15);
802  TH2F* h = new TH2F(plotName, plotName, v1.getBinning().numBins(), v1.getBinning().array(), v2.getBinning().numBins(), v2.getBinning().array());
803  const RooArgSet* set = eff.get();
804  RooRealVar* e = (RooRealVar*) set->find("efficiency");
805  RooRealVar* v1_ = (RooRealVar*) set->find(v1.GetName());
806  RooRealVar* v2_ = (RooRealVar*) set->find(v2.GetName());
807  h->SetTitle(TString::Format("%s;%s%s;%s%s;Efficiency of %s", plotTitle.Data(),
808  v1.GetTitle(), TString(v1.getUnit()).Length()==0?"":TString::Format(" (%s)", v1.getUnit()).Data(),
809  v2.GetTitle(), TString(v2.getUnit()).Length()==0?"":TString::Format(" (%s)", v2.getUnit()).Data(), effName.Data()));
810  h->SetOption("colztexte");
811  h->GetZaxis()->SetRangeUser(-0.001,1.001);
812  h->SetStats(kFALSE);
813  for(int i=0; i<eff.numEntries(); i++){
814  const RooArgSet *entry = eff.get(i);
815  if (catName != 0 && entry->getCatIndex(catName) != catIndex) continue;
816  h->SetBinContent(h->FindBin(v1_->getVal(), v2_->getVal()), e->getVal());
817  h->SetBinError(h->FindBin(v1_->getVal(), v2_->getVal()), (e->getErrorHi()-e->getErrorLo())/2.);
818  }
819  h->Draw();
820  canvas.Draw();
821  canvas.Write();
822  delete h;
823 }
824 
825 void TagProbeFitter::doSBSEfficiency(RooWorkspace* w, RooRealVar& efficiency){
826 }
827 
828 void TagProbeFitter::doCntEfficiency(RooWorkspace* w, RooRealVar& efficiency){
829  int pass = w->data("data")->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Passed");
830  int fail = w->data("data")->sumEntries("_efficiencyCategory_==_efficiencyCategory_::Failed");
831  double e = (pass+fail == 0) ? 0 : pass/double(pass+fail);
832  // Use Clopper-Pearson
833  double alpha = (1.0 - .68540158589942957)/2;
834  double lo = (pass == 0) ? 0.0 : ROOT::Math::beta_quantile( alpha, pass, fail+1 );
835  double hi = (fail == 0) ? 1.0 : ROOT::Math::beta_quantile( 1-alpha, pass+1, fail );
837  //double lob, hib;
838  //Efficiency( pass, pass+fail, .68540158589942957, e, lob, hib );
839  //std::cerr << "CNT " << pass << "/" << fail << ": Clopper Pearson [" << lo << ", " << hi << "], Bayes [" << lob << ", " << hib << "]" << std::endl;
840  efficiency.setVal(e);
841  efficiency.setAsymError(lo-e, hi-e);
842 }
843 
844 void TagProbeFitter::varFixer(RooWorkspace* w, bool fix){
845  std::vector<std::string>::const_iterator it;
846  for(it=fixVars.begin(); it<fixVars.end(); it++){
847  if(w->var((*it).c_str()))
848  w->var((*it).c_str())->setAttribute("Constant",fix);
849  else{
850  std::cout << "TagProbeFitter: " << "Can't find a variable to fix: " << *it;
851  }
852  }
853 }
854 
855 void TagProbeFitter::varSaver(RooWorkspace* w){
856  if(!fixVarValues.empty()){
857  std::cout << "attempt to save variables more than once!" << std::endl;
858  return;
859  }
860  std::vector<std::string>::const_iterator it;
861  for(it=fixVars.begin(); it<fixVars.end(); it++){
862  fixVarValues.push_back(w->var((*it).c_str())->getVal());
863  }
864 
865 }
866 
867 void TagProbeFitter::varRestorer(RooWorkspace* w){
868  if(fixVarValues.size()==fixVars.size())
869  for(unsigned int i=0; i< fixVars.size(); i++){
870  std::cout << "setting variable " << fixVars[i].c_str() << std::endl;
871  w->var(fixVars[i].c_str())->setVal(fixVarValues[i]);
872  }
873  else{
874  std::cout << "fixVars and fixVarValues are not of the same size!" << std::endl;
875  }
876 }
877 
int i
Definition: DBlmapReader.cc:9
void doCntEfficiency(RooWorkspace *w, RooRealVar &efficiency)
calculate the efficiecny by counting in the dataset found in the workspace
float alpha
Definition: AMPTWrapper.h:95
tuple inputFileNames
Definition: mvaPFMET_cff.py:73
const double w
Definition: UKUtility.cc:23
void addPdf(std::string pdfName, std::vector< std::string > &pdfCommands)
static PFTauRenderPlugin instance
void setWeightVar(const std::string &weight)
set a variable to be used as weight for a dataset. empty string means no weights. ...
std::string calculateEfficiency(std::string dirName, std::string efficiencyCategory, std::string efficiencyState, std::vector< std::string > &unbinnedVariables, std::map< std::string, std::vector< double > > &binnedReals, std::map< std::string, std::vector< std::string > > &binnedCategories, std::vector< std::string > &binToPDFmap)
calculate the efficiency for a particular binning of the data; it saves everything in the directory &quot;...
static const int WARNING
bool addThresholdCategory(std::string categoryName, std::string title, std::string varName, double cutValue)
adds a new category based on a cut
bool ev
def canvas
Definition: svgfig.py:481
void setQuiet(bool quiet_=true)
suppress most of the output from RooFit and Minuit
TagProbeFitter(const std::vector< std::string > &inputFileNames, std::string inputDirectoryName, std::string inputTreeName, std::string outputFileName, int numCPU=1, bool saveWorkspace_=false, bool floatShapeParameters=true, const std::vector< std::string > &fixVars_=std::vector< std::string >())
construct the fitter with the inputFileName, inputDirectoryName, inputTreeName, outputFileName and sp...
bool addExpression(std::string expressionName, std::string title, std::string expression, const std::vector< std::string > &arguments)
adds a new category based on a cut
def cat
Definition: eostools.py:400
void saveEfficiencyPlots(RooDataSet &eff, const TString &effName, RooArgSet &binnedVariables, RooArgSet &mappedCategories)
saves the efficiency plots
void varSaver(RooWorkspace *w)
store values in the vector
void makeEfficiencyPlot2D(RooDataSet &eff, RooRealVar &v1, RooRealVar &v2, const TString &plotName, const TString &plotTitle, const TString &effName, const char *catName=0, int catIndex=-1)
makes the 2D plot
int j
Definition: DBlmapReader.cc:9
void varRestorer(RooWorkspace *w)
restore variables&#39;s values for fit starting point
void saveFitPlot(RooWorkspace *w)
saves the fit canvas
~TagProbeFitter()
destructor closes the files
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
void setInitialValues(RooWorkspace *w)
sets initial values of the PDF parameters based on the data available in the workspace ...
void saveDistributionsPlot(RooWorkspace *w)
saves the distributions canvas
void varFixer(RooWorkspace *w, bool fix)
fix or release variables selected by user
std::vector< std::vector< double > > tmp
Definition: MVATrainer.cc:100
TString units(TString variable, Char_t axis)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
MultiGaussianState< N > multiState(const std::vector< MultiGaussianState< N >::Vector > &, const std::vector< MultiGaussianState< N >::Matrix > &, const std::vector< double > &)
void setBinsForMassPlots(int bins)
set number of bins to use when making the plots; 0 = automatic
void doSBSEfficiency(RooWorkspace *w, RooRealVar &efficiency)
calculate the efficiecny with side band substraction in the dataset found in the workspace ...
tuple cout
Definition: gather_cfg.py:121
void createPdf(RooWorkspace *w, std::vector< std::string > &pdfCommands)
creates the simultaneous PDF in the workspace according to the &quot;pdfCommands&quot;
void doFitEfficiency(RooWorkspace *w, std::string pdfName, RooRealVar &efficiency)
calculate the efficiecny with a simulataneous maximum likelihood fit in the dataset found in the work...
int col
Definition: cuy.py:1008
bool addCategory(std::string categoryName, std::string title, std::string expression)
adds a new category variable to the set of variables describing the data in the tree; &quot;expression&quot; is...
bool addVariable(std::string variableName, std::string title, double low, double hi, std::string units)
adds a new real variable to the set of variables describing the data in the tree
void makeEfficiencyPlot1D(RooDataSet &eff, RooRealVar &v, const TString &plotName, const TString &plotTitle, const TString &effName, const char *catName=0, int catIndex=-1)
makes the 1D plot