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" 12 #include "RootTools.h" 15 #include "TEfficiency.h" 16 #include "TDirectory.h" 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" 26 #include "CutTreeSelector.h" 33 void Acclaim::CutOptimizer::setDebug(
bool db){
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);
43 double Acclaim::CutOptimizer::FisherResult::getWeight(
const char* expression){
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];
55 TString Acclaim::CutOptimizer::FisherResult::getFisherFormula()
const{
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);
66 ExpressionMap::const_iterator eit = fExpressions.find(i-1);
67 if(eit!=fExpressions.end()){
68 command +=
"+(" + w +
"*" + eit->second +
")";
71 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find expression " << i-1 << std::endl;
80 void Acclaim::CutOptimizer::FisherResult::Print(Option_t* opt)
const{
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);
88 std::cout <<
"Variable " << i <<
" = constant, weight = " << wit->second << std::endl;
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;
96 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find expression " << i-1 << std::endl;
105 TH2D* Acclaim::CutOptimizer::FisherResult::makeTimeHist(
int nBinsX,
int nBinsY, TTree* t, EColor col,
int varInd,
const char* extraName)
const{
112 histName = TString::Format(
"h%sFisher", extraName);
113 histTitle = TString::Format(
"%s: Fisher Discriminant", extraName);
114 command = getFisherFormula();
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;
124 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", couldn't find expression " << varInd-1 << std::endl;
126 histName = TString::Format(
"h%s_%s", t->GetName(), eit->second.Data());
127 histTitle = eit->second +
" (weight " + w +
")";
128 command = eit->second;
134 TH2D* h =
new TH2D(histName, histTitle, nBinsX, RootTools::a3StartTime, RootTools::a3EndTime, nBinsY, 0, 1);
136 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0) 137 h->SetCanExtend(TH1::kAllAxes);
139 h->SetBit(TH1::kCanRebin);
141 command +=
":realTime>>" + histName;
142 t->Draw(command,
"" ,
"goff");
143 std::cerr << h->Integral() << std::endl;
144 h->SetLineColor(col);
145 h->SetFillColor(col);
150 void Acclaim::CutOptimizer::FisherResult::getResultFromXML(
const char* filename){
153 std::cerr <<
"In " << __PRETTY_FUNCTION__ <<
", trying to read back in the xml file: " << filename << std::endl;
157 TXMLEngine* xml =
new TXMLEngine;
160 XMLDocPointer_t xmldoc = xml->ParseFile(filename);
166 XMLNodePointer_t mainnode = xml->DocGetRootElement(xmldoc);
168 parseNode(xml, mainnode, 1);
170 xml->FreeDoc(xmldoc);
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;
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;
187 SetTitle(getFisherFormula());
197 void Acclaim::CutOptimizer::FisherResult::parseNode(TXMLEngine* xml, XMLNodePointer_t node, Int_t level){
203 TString nodeName = xml->GetNodeName(node);
205 if(nodeName==
"Variable" || nodeName ==
"Coefficient"){
219 XMLAttrPointer_t attr = xml->GetFirstAttr(node);
221 TString attName(xml->GetAttrName(attr));
222 TString attValue(xml->GetAttrValue(attr));
224 attr = xml->GetNextAttr(attr);
226 if(attName ==
"VarIndex"){
229 else if(attName ==
"Index"){
232 else if(attName ==
"Value"){
235 else if(attName ==
"Expression"){
236 expression = attValue;
240 if(varIndex!=
"" && expression !=
""){
241 int vi = atoi(varIndex.Data());
242 fExpressions[vi] = expression;
244 else if (index!=
"" && weight !=
""){
245 int vi = atoi(index.Data());
246 fWeights[vi] = atof(weight.Data());
258 XMLNodePointer_t child = xml->GetChild(node);
260 parseNode(xml, child, level+2);
261 child = xml->GetNext(child);
282 : fSignalGlob(signalGlob), fBackgroundGlob(backgroundGlob ? backgroundGlob :
""), fOutFile(NULL),
283 fSignalTree(NULL), fBackgroundTree(NULL)
286 fSignalTree =
new TChain(
"thermalTree");
287 fBackgroundTree =
new TChain(
"thermalTree");
289 fSignalTree->Add(signalGlob);
290 fBackgroundTree->Add(backgroundGlob);
292 std::cout <<
"found signal with " << fSignalTree->GetEntries() <<
" entries." << std::endl;
293 std::cout <<
"found background with " << fBackgroundTree->GetEntries() <<
" entries." << std::endl;
324 TString ofName = outFileName;
326 ofName =
"CutOptimizer";
329 const char* fNameChar = ofName.Data();
330 const char** argv = &fNameChar;
429 TString bName = formStr;
434 bName.ReplaceAll(
"sum.",
"");
435 bName.ReplaceAll(
"()",
"");
436 bName.ReplaceAll(
"(",
"_");
437 bName.ReplaceAll(
")",
"_");
438 bName.ReplaceAll(
"[]",
"");
439 bName.ReplaceAll(
"[",
"_");
440 bName.ReplaceAll(
"]",
"_");
441 bName.ReplaceAll(
".",
"_");
442 bName.ReplaceAll(
"TMath::",
"");
443 bName.ReplaceAll(
"FFTtools::",
"");
444 bName.ReplaceAll(
",",
"_");
445 bName.ReplaceAll(
"$",
"");
449 bName.ReplaceAll(
"/",
"_over_");
450 bName.ReplaceAll(
"+",
"_plus_");
451 bName.ReplaceAll(
"-",
"_minus_");
452 bName.ReplaceAll(
"*",
"_times_");
453 bName.ReplaceAll(
"==",
"_eq_");
454 bName.ReplaceAll(
">=",
"_ge_");
455 bName.ReplaceAll(
"<=",
"_le_");
456 bName.ReplaceAll(
">",
"_gt_");
457 bName.ReplaceAll(
"<",
"_lt_");
458 bName.ReplaceAll(
"%",
"_modulo_");
459 bName.ReplaceAll(
" ",
"");
460 bName.ReplaceAll(
"__",
"_");
462 bName.Remove(TString::kLeading,
'_');
463 bName.Remove(TString::kTrailing,
'_');
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";
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";
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";
479 else if(bName==
"wrap_peak_phi_minus_mc_phi_360_0"){
482 else if(bName==
"_peak_theta_plus_mc_theta"){
485 else if(bName==
"wrap_peak_phi_minus_wais_phi_360_0"){
488 else if(bName==
"wrap_peak_phi_minus_sun_phi_360_0"){
491 else if(bName==
"floor_Iteration_over_5"){
494 else if(bName==
"Iteration_modulo_5"){
497 else if(bName==
"mc_weight_gt_0_times_mc_weight_plus_1_times_mc_weight_eq_0"){
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){
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;
519 fOutFile = makeOutputFile(fileName);
521 if(!fSignalTree || !fBackgroundTree){
522 std::cerr <<
"Error in " << __PRETTY_FUNCTION__ <<
", Non-existent signal or background tree. " 523 <<
"Can't optimize! Aborting!" << std::endl;
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;
534 gROOT->ProcessLine(
"#include \"FFTtools.h\"");
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);
554 std::cout <<
"creating reduced signal tree..." << std::endl;
556 TCut signalCuts =
"";
557 for(UInt_t sc=0; sc < signalSelection.size(); sc++){
558 signalCuts += *signalSelection[sc];
563 TTree* signalTree2 = fSignalTree->CopyTree(signalCuts.GetTitle());
564 signalTree2->SetName(
"signalTree");
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];
577 TTree* backgroundTree2 = fBackgroundTree->CopyTree(backgroundCuts.GetTitle());
578 backgroundTree2->SetName(
"backgroundTree");
583 delete fBackgroundTree;
584 fBackgroundTree = NULL;
586 signalTree2->SetBranchStatus(
"*", 0);
587 backgroundTree2->SetBranchStatus(
"*", 0);
589 for(UInt_t i=0; i < formulaStrings.size(); i++){
590 signalTree2->SetBranchStatus(formulaStrings[i], 1);
591 backgroundTree2->SetBranchStatus(formulaStrings[i], 1);
593 signalTree2->SetBranchStatus(
"weight", 1);
594 backgroundTree2->SetBranchStatus(
"weight", 1);
595 signalTree2->SetBranchStatus(
"realTime", 1);
596 backgroundTree2->SetBranchStatus(
"realTime", 1);
602 signalTree2->Show(0);
603 backgroundTree2->Show(0);
605 dl.AddTree(signalTree2,
"Signal");
606 dl.AddTree(backgroundTree2,
"Background");
615 for(UInt_t vInd=0; vInd < formulaStrings.size(); vInd++){
616 dl.AddVariable(formulaStrings.at(vInd));
618 dl.SetWeightExpression(
"weight");
620 TString methodTitle =
"tc";
622 factory.BookMethod(&dl, TMVA::Types::EMVA::kFisher, methodTitle,
"");
629 factory.TrainAllMethods();
630 factory.TestAllMethods();
631 factory.EvaluateAllMethods();
633 TString weightFileName = dlName +
"/weights/" + factoryName +
"_" + methodTitle +
".weights.xml";
635 FisherResult result(weightFileName.Data());
639 signalTree2->SetBranchStatus(
"*", 1);
640 backgroundTree2->SetBranchStatus(
"*", 1);
642 const int nBinsX = 1024;
643 const int nBinsY = 1024;
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]);
659 TH2D* hSignal2 = result.makeTimeHist(nBinsX, nBinsY, signalTree2, kRed, 0, extraNames[0]);
660 TH2D* hBackground2 = result.makeTimeHist(nBinsX, nBinsY, backgroundTree2, kBlue, 0, extraNames[1]);
662 TH1D* hSignal = hSignal2->ProjectionY();
663 TH1D* hBackground = hBackground2->ProjectionY();
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());
670 double cumulativeSignal = 1;
671 double cumulativeBackground = 1;
673 for(
int bx=1; bx <= nBinsY; bx++){
674 hSigInt->SetBinContent(bx, cumulativeSignal);
675 hBackInt->SetBinContent(bx, cumulativeBackground);
677 cumulativeSignal -= hSignal->GetBinContent(bx);
678 cumulativeBackground -= hBackground->GetBinContent(bx);
683 hBackground->Write();
687 for(
unsigned i=0; i < signalSelection.size(); i++){
723 std::cerr <<
"Exception in " << __PRETTY_FUNCTION__ <<
" can't optimize for some reason!" << std::endl;
729 std::cout <<
"==> wrote root file " << fOutFile->GetName() << std::endl;
730 std::cout <<
"==> TMVAnalysis is done!" << std::endl;
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.
static TString branchifyName(const char *formStr)
**
TFile * makeOutputFile(const char *outFileName)