CutOptimizer.cxx
1 #include "CutOptimizer.h"
2 #include "OutputConvention.h"
3 #include "DrawStrings.h"
4 #include "SummarySet.h"
5 #include "ProgressBar.h"
6 #include "AnitaEventSummary.h"
7 #include "TTreeFormula.h"
8 #include "TApplication.h"
9 #include "TXMLEngine.h"
10 #include "TMath.h"
11 #include "TBranch.h"
12 #include "RootTools.h"
13 #include "TH2D.h"
14 #include "TSystem.h"
15 #include "TEfficiency.h"
16 #include "TDirectory.h"
17 #include "TProof.h"
18 
19 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,10,0)
20 #include "TMVA/Factory.h"
21 #include "TMVA/DataLoader.h"
22 #include "TMVA/MethodBase.h"
23 #include "TMVA/MethodFisher.h"
24 #endif
25 
26 #include "CutTreeSelector.h"
27 
29 
30 bool debug = false;
31 
32 
33 void Acclaim::CutOptimizer::setDebug(bool db){
34  debug = db;
35 }
36 
37 void Acclaim::CutOptimizer::FisherResult::getExpressions(std::vector<TString>& expressions) const {
38  for(ExpressionMap::const_iterator it = fExpressions.begin(); it!= fExpressions.end(); it++){
39  expressions.push_back(it->second);
40  }
41 }
42 
43 double Acclaim::CutOptimizer::FisherResult::getWeight(const char* expression){
44 
45  TString expr(expression);
46  for(ExpressionMap::const_iterator it = fExpressions.begin(); it!= fExpressions.end(); it++){
47  if(it->second == expr){
48  return fWeights[it->first];
49  }
50  }
51  return 0;
52 }
53 
54 
55 TString Acclaim::CutOptimizer::FisherResult::getFisherFormula() const{
56 
57  TString command;
58  for(int i=0; i < (int)fWeights.size(); i++){
59  WeightMap::const_iterator wit = fWeights.find(i);
60  if(wit!=fWeights.end()){
61  TString w = TString::Format("%lf", wit->second);
62  if(i==0){
63  command = w;
64  }
65  else{
66  ExpressionMap::const_iterator eit = fExpressions.find(i-1);
67  if(eit!=fExpressions.end()){
68  command += "+(" + w + "*" + eit->second + ")";
69  }
70  else{
71  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", couldn't find expression " << i-1 << std::endl;
72  }
73  }
74  }
75  }
76  return command;
77 }
78 
79 
80 void Acclaim::CutOptimizer::FisherResult::Print(Option_t* opt) const{
81  (void) opt;
82  std::cout << "FisherResult:" << std::endl;
83  for(int i=0; i < (int)fWeights.size(); i++){
84  WeightMap::const_iterator wit = fWeights.find(i);
85  if(wit!=fWeights.end()){
86  TString w = TString::Format("%lf", wit->second);
87  if(i==0){
88  std::cout << "Variable " << i << " = constant, weight = " << wit->second << std::endl;
89  }
90  else{
91  ExpressionMap::const_iterator eit = fExpressions.find(i-1);
92  if(eit!=fExpressions.end()){
93  std::cout << "Variable " << i << " = " << eit->second << ", weight = " << w << std::endl;
94  }
95  else{
96  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", couldn't find expression " << i-1 << std::endl;
97  }
98  }
99  }
100  }
101 }
102 
103 
104 
105 TH2D* Acclaim::CutOptimizer::FisherResult::makeTimeHist(int nBinsX, int nBinsY, TTree* t, EColor col, int varInd, const char* extraName) const{
106 
107  TString histName;
108  TString histTitle;
109  TString command;
110 
111  if(varInd==0){
112  histName = TString::Format("h%sFisher", extraName);
113  histTitle = TString::Format("%s: Fisher Discriminant", extraName);
114  command = getFisherFormula();
115  }
116  else {
117  WeightMap::const_iterator wit = fWeights.find(varInd);
118  TString w = TString::Format("%lf", wit->second);
119  ExpressionMap::const_iterator eit = fExpressions.find(varInd-1);
120  if(eit!=fExpressions.end()){
121  std::cout << "Variable " << varInd << " = " << eit->second << ", weight = " << w << std::endl;
122  }
123  else{
124  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", couldn't find expression " << varInd-1 << std::endl;
125  }
126  histName = TString::Format("h%s_%s", t->GetName(), eit->second.Data());
127  histTitle = eit->second + " (weight " + w + ")";
128  command = eit->second;
129  }
130  if(command==""){
131  return NULL;
132  }
133 
134  TH2D* h = new TH2D(histName, histTitle, nBinsX, RootTools::a3StartTime, RootTools::a3EndTime, nBinsY, 0, 1);
135 
136 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0)
137  h->SetCanExtend(TH1::kAllAxes);
138 #else
139  h->SetBit(TH1::kCanRebin);
140 #endif
141  command += ":realTime>>" + histName;
142  t->Draw(command, "" ,"goff");
143  std::cerr << h->Integral() << std::endl;
144  h->SetLineColor(col);
145  h->SetFillColor(col);
146 
147  return h;
148 }
149 
150 void Acclaim::CutOptimizer::FisherResult::getResultFromXML(const char* filename){
151 
152  if(debug){
153  std::cerr << "In " << __PRETTY_FUNCTION__ << ", trying to read back in the xml file: " << filename << std::endl;
154  }
155 
156  // First create engine
157  TXMLEngine* xml = new TXMLEngine;
158  // Now try to parse xml file
159  // Only file with restricted xml syntax are supported
160  XMLDocPointer_t xmldoc = xml->ParseFile(filename);
161  if (xmldoc==0) {
162  delete xml;
163  return;
164  }
165  // take access to main node
166  XMLNodePointer_t mainnode = xml->DocGetRootElement(xmldoc);
167  // display recursively all nodes and subnodes
168  parseNode(xml, mainnode, 1);
169  // Release memory before exit
170  xml->FreeDoc(xmldoc);
171  delete xml;
172 
173 
174  if(debug){
175  std::cout << "I found expressions..." << std::endl;
176  ExpressionMap::const_iterator it;
177  for(it = fExpressions.begin(); it != fExpressions.end(); ++it){
178  std::cout << it->first << "\t" << it->second << std::endl;
179  }
180 
181  std::cout << "I found weights..." << std::endl;
182  WeightMap::const_iterator it2;
183  for(it2 = fWeights.begin(); it2 != fWeights.end(); ++it2){
184  std::cout << it2->first << "\t" << it2->second << std::endl;
185  }
186  }
187  SetTitle(getFisherFormula());
188 }
189 
190 
191 
192 
193 
194 
195 
196 
197 void Acclaim::CutOptimizer::FisherResult::parseNode(TXMLEngine* xml, XMLNodePointer_t node, Int_t level){
198 
199  // this function display all accessible information about xml node and its children
200  // printf("%*c node: %s\n",level,' ', xml->GetNodeName(node));
201  // // display namespace
202 
203  TString nodeName = xml->GetNodeName(node);
204 
205  if(nodeName=="Variable" || nodeName == "Coefficient"){
206 
207  TString varIndex;
208  TString expression;
209 
210  TString index;
211  TString weight;
212 
213  // XMLNsPointer_t ns = xml->GetNS(node);
214  // if (ns!=0){
215  // printf("%*c namespace: %s refer: %s\n",level+2,' ', xml->GetNSName(ns), xml->GetNSReference(ns));
216  // }
217 
218  // display attributes
219  XMLAttrPointer_t attr = xml->GetFirstAttr(node);
220  while (attr!=0) {
221  TString attName(xml->GetAttrName(attr));
222  TString attValue(xml->GetAttrValue(attr));
223  // printf("%*c attr: %s value: %s\n",level+2,' ', attName.Data(), attValue.Data());
224  attr = xml->GetNextAttr(attr);
225 
226  if(attName == "VarIndex"){
227  varIndex = attValue;
228  }
229  else if(attName == "Index"){
230  index = attValue;
231  }
232  else if(attName == "Value"){
233  weight = attValue;
234  }
235  else if(attName == "Expression"){
236  expression = attValue;
237  }
238  }
239 
240  if(varIndex!="" && expression != ""){
241  int vi = atoi(varIndex.Data());
242  fExpressions[vi] = expression;
243  }
244  else if (index!="" && weight != ""){
245  int vi = atoi(index.Data());
246  fWeights[vi] = atof(weight.Data());
247  }
248 
249  // display content (if exists)
250  // const char* content = xml->GetNodeContent(node);
251 
252  // if (content!=0){
253  // printf("%*c cont: %s\n",level+2,' ', content);
254  // }
255  }
256 
257  // parse all child nodes
258  XMLNodePointer_t child = xml->GetChild(node);
259  while (child!=0) {
260  parseNode(xml, child, level+2);
261  child = xml->GetNext(child);
262  }
263 }
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
280 Acclaim::CutOptimizer::CutOptimizer(const char* signalGlob, const char* backgroundGlob)
281 // Acclaim::CutOptimizer::CutOptimizer(const char* signalGlob, const char* backgroundGlob, bool doAllPeaks, bool save_trees)
282  : fSignalGlob(signalGlob), fBackgroundGlob(backgroundGlob ? backgroundGlob : ""), fOutFile(NULL),
283  fSignalTree(NULL), fBackgroundTree(NULL)
284 {
285 
286  fSignalTree = new TChain("thermalTree");
287  fBackgroundTree = new TChain("thermalTree");
288 
289  fSignalTree->Add(signalGlob);
290  fBackgroundTree->Add(backgroundGlob);
291 
292  std::cout << "found signal with " << fSignalTree->GetEntries() << " entries." << std::endl;
293  std::cout << "found background with " << fBackgroundTree->GetEntries() << " entries." << std::endl;
294 
295 }
296 
297 
298 
299 
300 
305 {
306 
307 }
308 
309 
310 
311 
312 
313 
321 TFile* Acclaim::CutOptimizer::makeOutputFile(const char* outFileName){
322 
323  int argc = 1;
324  TString ofName = outFileName;
325  if(ofName==""){
326  ofName = "CutOptimizer";
327  }
328 
329  const char* fNameChar = ofName.Data();
330  const char** argv = &fNameChar;
331 
332  OutputConvention oc(argc, (char**)argv);
333  TFile* f = oc.makeFile();
334  return f;
335 }
336 
337 
338 
339 
340 
341 
342 
343 
345 // * Constructor for the FormulaHolder
346 // *
347 // * @param c pointer to the TChain on which the formulae will be evaluated
348 // */
349 // Acclaim::CutOptimizer::FormulaHolder::FormulaHolder(TChain* c)
350 // : fChain(c)
351 // {
352 // if(fChain){
353 // fChain->SetNotify(this);
354 // }
355 // }
356 
357 // /**
358 // * TChain can only notify one object when the underlying tree changes.
359 // * The point of this class is to inherit from TObject and overload Notify(),
360 // * then pass that on to all the TFormulas I'm interested in.
361 // *
362 // * @return always returns true.
363 // */
364 // Bool_t Acclaim::CutOptimizer::FormulaHolder::Notify(){
365 // for(UInt_t i=0; i < fForms.size(); i++){
366 // fForms.at(i)->Notify();
367 // }
368 // return true;
369 // }
370 
371 
372 // /**
373 // * Destructor: Delete all the contained TFormula and unset the TChain Notification
374 // */
375 // Acclaim::CutOptimizer::FormulaHolder::~FormulaHolder(){
376 // for(UInt_t i=0; i < fForms.size(); i++){
377 // delete fForms.at(i);
378 // }
379 // if(fChain){
380 // fChain->SetNotify(NULL);
381 // }
382 
383 // }
384 
385 
386 
387 
388 
389 // /**
390 // * Creates a TFormula object, and put it in the vector
391 // *
392 // * @param formulaStr is the string from which to generate the formula
393 // *
394 // * @return the number of contained TFormula
395 // */
396 // size_t Acclaim::CutOptimizer::FormulaHolder::add(const char* formulaStr){
397 // const int nForms = fForms.size();
398 // TString formName = TString::Format("form%d", nForms);
399 // TTreeFormula* form = new TTreeFormula(formName, formulaStr, fChain);
400 
401 // // apprently this is the signature of an error
402 // // https://root-forum.cern.ch/t/check-the-status-of-a-ttreeformula/12596/2
403 // if(form->GetNdim()==0){
404 // std::cerr << "Warning in " << __PRETTY_FUNCTION__ << ", not using bad expression "
405 // << formulaStr << ", will not included in the output tree" << std::endl;
406 // delete form;
407 // }
408 // else{
409 // fForms.push_back(form);
410 // fFormStrs.push_back(formulaStr);
411 // }
412 
413 // return fForms.size();
414 // }
415 
416 
417 
418 
419 
420 
428 TString Acclaim::CutOptimizer::branchifyName(const char* formStr){
429  TString bName = formStr;
430 
431 
432 
433 
434  bName.ReplaceAll("sum.", ""); // remove the sum.
435  bName.ReplaceAll("()", ""); // remove function call bracket
436  bName.ReplaceAll("(", "_"); // remove standalone open paren...
437  bName.ReplaceAll(")", "_"); // ... and close paren
438  bName.ReplaceAll("[]", ""); // remove implicit loop iteration thingy
439  bName.ReplaceAll("[", "_"); // or explicit array entry...
440  bName.ReplaceAll("]", "_"); // ...
441  bName.ReplaceAll(".", "_"); // remove remaining dots
442  bName.ReplaceAll("TMath::", ""); // Remove TMath function namespace
443  bName.ReplaceAll("FFTtools::", ""); // Remove TMath function namespace
444  bName.ReplaceAll(",", "_"); // Remove TMath function namespace
445  bName.ReplaceAll("$", ""); // Remove special identifier
446 
447  // bName.ReplaceAll("AnitaPol::", ""); // Remove AnitaPol function namespace
448 
449  bName.ReplaceAll("/", "_over_"); // wordify arithmetic/logical operators
450  bName.ReplaceAll("+", "_plus_"); // wordify arithmetic/logical operators
451  bName.ReplaceAll("-", "_minus_"); // wordify arithmetic/logical operators
452  bName.ReplaceAll("*", "_times_"); // wordify arithmetic/logical operators
453  bName.ReplaceAll("==", "_eq_"); // wordify arithmetic/logical operators
454  bName.ReplaceAll(">=", "_ge_"); // wordify arithmetic/logical operators
455  bName.ReplaceAll("<=", "_le_"); // wordify arithmetic/logical operators
456  bName.ReplaceAll(">", "_gt_"); // wordify arithmetic/logical operators
457  bName.ReplaceAll("<", "_lt_"); // wordify arithmetic/logical operators
458  bName.ReplaceAll("%", "_modulo_"); // wordify arithmetic/logical operators
459  bName.ReplaceAll(" ", ""); // Remove any remaining spaces
460  bName.ReplaceAll("__", "_"); // Remove double underscore if there is one
461 
462  bName.Remove(TString::kLeading, '_'); // Remove leading underscore if there is one
463  bName.Remove(TString::kTrailing, '_'); // Remove trailing underscore if there is one
464 
465 
466 
467 
468  // some special cases...
469 
470  if(bName=="10_0_times__minus_0_2_times_coherent_filtered_fracPowerWindowEnds_0_minus_coherent_filtered_fracPowerWindowBegins_0__minus_0_1_times_coherent_filtered_fracPowerWindowEnds_1_minus_coherent_filtered_fracPowerWindowBegins_1__plus_0_1_times_coherent_filtered_fracPowerWindowEnds_3_minus_coherent_filtered_fracPowerWindowBegins_3__plus_0_2_times_coherent_filtered_fracPowerWindowEnds_4_minus_coherent_filtered_fracPowerWindowBegins_4"){
471  bName = "coherent_filtered_fracPowerWindowGradient";
472  }
473  else if(bName=="10_0_times__minus_0_2_times_deconvolved_filtered_fracPowerWindowEnds_0_minus_deconvolved_filtered_fracPowerWindowBegins_0__minus_0_1_times_deconvolved_filtered_fracPowerWindowEnds_1_minus_deconvolved_filtered_fracPowerWindowBegins_1__plus_0_1_times_deconvolved_filtered_fracPowerWindowEnds_3_minus_deconvolved_filtered_fracPowerWindowBegins_3__plus_0_2_times_deconvolved_filtered_fracPowerWindowEnds_4_minus_deconvolved_filtered_fracPowerWindowBegins_4"){
474  bName = "deconvolved_filtered_fracPowerWindowGradient";
475  }
476  else if(bName=="_Abs_peak_hwAngle_lt_Abs_peak_hwAngleXPol__times_Abs_peak_hwAngle_plus_Abs_peak_hwAngle_ge_Abs_peak_hwAngleXPol__times_Abs_peak_hwAngleXPol"){
477  bName = "minAbsHwAngle";
478  }
479  else if(bName=="wrap_peak_phi_minus_mc_phi_360_0"){
480  bName = "dPhi_mc";
481  }
482  else if(bName=="_peak_theta_plus_mc_theta"){
483  bName = "dTheta_mc";
484  }
485  else if(bName=="wrap_peak_phi_minus_wais_phi_360_0"){
486  bName = "dPhi_wais";
487  }
488  else if(bName=="wrap_peak_phi_minus_sun_phi_360_0"){
489  bName = "dPhi_sun";
490  }
491  else if(bName=="floor_Iteration_over_5"){
492  bName = "pol";
493  }
494  else if(bName=="Iteration_modulo_5"){
495  bName = "peakInd";
496  }
497  else if(bName=="mc_weight_gt_0_times_mc_weight_plus_1_times_mc_weight_eq_0"){
498  bName = "weight";
499  }
500 
501  return bName;
502 }
503 
504 
505 
506 
507 
508 
509 void Acclaim::CutOptimizer::optimize(const std::vector<const TCut*>& signalSelection,
510  const std::vector<const TCut*>& backgroundSelection,
511  const std::vector<TString>& formulaStrings, const char* fileName){
512 
513  // Someone with a bit more time can do the backwards compatibility
514 #if ROOT_VERSION_CODE < ROOT_VERSION(6,10,0)
515  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", TVMA changed a lot in recent ROOT versions. ";
516  std::cerr << "This class requires ROOT version at least 6.10, you only have " << ROOT_VERSION_CODE << std::endl;
517 #else
518 
519  fOutFile = makeOutputFile(fileName);
520 
521  if(!fSignalTree || !fBackgroundTree){
522  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", Non-existent signal or background tree. "
523  << "Can't optimize! Aborting!" << std::endl;
524  return;
525  }
526  if(fSignalTree->GetEntries() == 0 || fBackgroundTree->GetEntries() == 0){
527  std::cerr << "Error in " << __PRETTY_FUNCTION__ << ", "
528  << "signal tree contains " << fSignalTree->GetEntries() << " events and "
529  << "background tree contains " << fBackgroundTree->GetEntries() << " events. "
530  << "Can't optimize! Aborting!" << std::endl;
531  return;
532  }
533 
534  gROOT->ProcessLine("#include \"FFTtools.h\"");
535 
536  TString factoryName = "ThermalCut";
537  TString option = debug ? "V" : "silent";
538  TMVA::Factory factory(factoryName, fOutFile, option);
539  TString dlName = fOutFile->GetName();
540  dlName.ReplaceAll(".root", "");
541  TMVA::DataLoader dl(dlName);
542 
543 
544  // fSignalTree->SetBranchStatus("*", 0);
545  // fBackgroundTree->SetBranchStatus("*", 0);
546 
547  // for(UInt_t i=0; i < formulaStrings.size(); i++){
548  // fSignalTree->SetBranchStatus(formulaStrings[i], 1);
549  // fBackgroundTree->SetBranchStatus(formulaStrings[i], 1);
550  // }
551 
552 
553 
554  std::cout << "creating reduced signal tree..." << std::endl;
555  ProgressBar pSig(1);
556  TCut signalCuts = "";
557  for(UInt_t sc=0; sc < signalSelection.size(); sc++){
558  signalCuts += *signalSelection[sc];
559  }
560  // fSignalTree->Draw(">>sigEntries", signalCuts, "entrylist");
561  // TEntryList* sigEntries = (TEntryList*) gROOT->FindObject("sigEntries");
562  // fSignalTree->SetEntryList(sigEntries);
563  TTree* signalTree2 = fSignalTree->CopyTree(signalCuts.GetTitle());
564  signalTree2->SetName("signalTree");
565  pSig++;
566 
567 
568  std::cout << "creating reduced background tree..." << std::endl;
569  ProgressBar pBack(1);
570  TCut backgroundCuts = "";
571  for(UInt_t bc=0; bc < backgroundSelection.size(); bc++){
572  backgroundCuts += *backgroundSelection[bc];
573  }
574  // fBackgroundTree->Draw(">>backEntries", backgroundCuts, "entrylist");
575  // TEntryList* backEntries = (TEntryList*) gROOT->FindObject("backEntries");
576  // fBackgroundTree->SetEntryList(backEntries);
577  TTree* backgroundTree2 = fBackgroundTree->CopyTree(backgroundCuts.GetTitle());
578  backgroundTree2->SetName("backgroundTree");
579  pBack++;
580 
581  delete fSignalTree;
582  fSignalTree = NULL;
583  delete fBackgroundTree;
584  fBackgroundTree = NULL;
585 
586  signalTree2->SetBranchStatus("*", 0);
587  backgroundTree2->SetBranchStatus("*", 0);
588 
589  for(UInt_t i=0; i < formulaStrings.size(); i++){
590  signalTree2->SetBranchStatus(formulaStrings[i], 1);
591  backgroundTree2->SetBranchStatus(formulaStrings[i], 1);
592  }
593  signalTree2->SetBranchStatus("weight", 1);
594  backgroundTree2->SetBranchStatus("weight", 1);
595  signalTree2->SetBranchStatus("realTime", 1);
596  backgroundTree2->SetBranchStatus("realTime", 1);
597 
598 
599  // dl.AddSignalTree(fSignalTree);
600  // dl.AddBackgroundTree(fBackgroundTree);
601 
602  signalTree2->Show(0);
603  backgroundTree2->Show(0);
604 
605  dl.AddTree(signalTree2, "Signal");//, 1.0, signalCuts);
606  dl.AddTree(backgroundTree2, "Background");//, 1.0, backgroundCuts);
607  // dl.AddTree(fSignalTree, "Signal", 1.0, signalCuts);
608  // dl.AddTree(fBackgroundTree, "Background", 1.0, backgroundCuts);
609 
610  // std::cout << dl.GetDataSetInfo().GetClassInfo("Signal")->GetName() << std::endl;
611  // std::cout << dl.GetDataSetInfo().GetClassInfo("Background")->GetName() << std::endl;
612 
613 
614 
615  for(UInt_t vInd=0; vInd < formulaStrings.size(); vInd++){
616  dl.AddVariable(formulaStrings.at(vInd));
617  }
618  dl.SetWeightExpression("weight");
619 
620  TString methodTitle = "tc";
621 
622  factory.BookMethod(&dl, TMVA::Types::EMVA::kFisher, methodTitle, "");
623 
624  // If an inf/nan ends up in the training sample TMVA will throw an exception.
625  // We want to still write the signal/background trees to find out what went wrong,
626  // so let's wrap the attempt in a try/catch block
627  try
628  {
629  factory.TrainAllMethods();
630  factory.TestAllMethods();
631  factory.EvaluateAllMethods();
632 
633  TString weightFileName = dlName + "/weights/" + factoryName + "_" + methodTitle + ".weights.xml";
634 
635  FisherResult result(weightFileName.Data());
636  fOutFile->cd();
637 
638  // re-activate branches
639  signalTree2->SetBranchStatus("*", 1);
640  backgroundTree2->SetBranchStatus("*", 1);
641 
642  const int nBinsX = 1024;
643  const int nBinsY = 1024;
644 
645  const int nT = 2;
646  TTree* ts[nT] = {signalTree2, backgroundTree2};
647  const char* extraNames[nT] = {"Signal", "Background"};
648  for(int t=0; t < nT; t++){
649  EColor col = t == 0 ? kRed : kBlue;
650  for(UInt_t i=0; i < formulaStrings.size(); i++){
651  TH2D* h = result.makeTimeHist(nBinsX, nBinsY, ts[t], col, i, extraNames[t]);
652  if(h){
653  h->Write();
654  delete h;
655  }
656  }
657  }
658 
659  TH2D* hSignal2 = result.makeTimeHist(nBinsX, nBinsY, signalTree2, kRed, 0, extraNames[0]);
660  TH2D* hBackground2 = result.makeTimeHist(nBinsX, nBinsY, backgroundTree2, kBlue, 0, extraNames[1]);
661 
662  TH1D* hSignal = hSignal2->ProjectionY();
663  TH1D* hBackground = hBackground2->ProjectionY();
664 
665  TH1D* hSigInt = new TH1D("hSigInt", "hSigInt", nBinsY, hSignal->GetXaxis()->GetBinLowEdge(1), hSignal->GetXaxis()->GetBinUpEdge(nBinsY));
666  TH1D* hBackInt = new TH1D("hBackInt", "hBackInt", nBinsY, hBackground->GetXaxis()->GetBinLowEdge(1), hBackground->GetXaxis()->GetBinUpEdge(nBinsY));
667  hSignal->Scale(1./hSignal->Integral());
668  hBackground->Scale(1./hBackground->Integral());
669 
670  double cumulativeSignal = 1; //hSignal->Integral();
671  double cumulativeBackground = 1; //hBackground->Integral();
672 
673  for(int bx=1; bx <= nBinsY; bx++){
674  hSigInt->SetBinContent(bx, cumulativeSignal);
675  hBackInt->SetBinContent(bx, cumulativeBackground);
676 
677  cumulativeSignal -= hSignal->GetBinContent(bx);
678  cumulativeBackground -= hBackground->GetBinContent(bx);
679 
680  }
681  hSignal->Write();
682  hSigInt->Write();
683  hBackground->Write();
684  hBackInt->Write();
685 
686 
687  for(unsigned i=0; i < signalSelection.size(); i++){
688  // fSignalEffs[kSNR][kIfFirst][i]->SetDirectory(gDirectory);
689  // fSignalEffs[kEnergy][kIfFirst][i]->SetDirectory(gDirectory);
690  // fSignalEffs[kSNR][kInSequence][i]->SetDirectory(gDirectory);
691  // fSignalEffs[kEnergy][kInSequence][i]->SetDirectory(gDirectory);
692 
693 
694  // fSignalEffs[kSNR][kIfFirst][i]->Write();
695  // fSignalEffs[kEnergy][kIfFirst][i]->Write();
696  // fSignalEffs[kSNR][kInSequence][i]->Write();
697  // fSignalEffs[kEnergy][kInSequence][i]->Write();
698 
699 
700  // delete fSignalEffs[kSNR][kIfFirst][i];
701  // delete fSignalEffs[kEnergy][kIfFirst][i];
702  // delete fSignalEffs[kSNR][kInSequence][i];
703  // delete fSignalEffs[kEnergy][kInSequence][i];
704  }
705 
706  result.Write();
707 
708  delete hSignal;
709  hSignal = NULL;
710 
711  delete hSigInt;
712  hSigInt = NULL;
713 
714  delete hBackground;
715  hBackground = NULL;
716 
717  delete hBackInt;
718  hBackInt = NULL;
719 
720 
721  }
722  catch(...){
723  std::cerr << "Exception in " << __PRETTY_FUNCTION__ << " can't optimize for some reason!" << std::endl;
724  }
725 
726  fOutFile->Write();
727  fOutFile->Close();
728 
729  std::cout << "==> wrote root file " << fOutFile->GetName() << std::endl;
730  std::cout << "==> TMVAnalysis is done!" << std::endl;
731 
732 #endif
733 
734  }
CutOptimizer(const char *signalGlob, const char *backgroundGlob=NULL)
TFile * makeFile()
Create the new output file with proper name.
A class to systematically name files produced by my analysis programs.
Get the results of the Fisher Discriminant into a more useful form.
Definition: CutOptimizer.h:154
static TString branchifyName(const char *formStr)
**
TFile * makeOutputFile(const char *outFileName)