00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <algorithm>
00025 #include <list>
00026
00027 #include "TMVA/RuleCut.h"
00028 #include "TMVA/DecisionTree.h"
00029 #include "TMVA/MsgLogger.h"
00030
00031
00032 TMVA::RuleCut::RuleCut( const std::vector<const Node*> & nodes )
00033 : fCutNeve(0),
00034 fPurity(0),
00035 fLogger(new MsgLogger("RuleFit"))
00036 {
00037
00038 MakeCuts( nodes );
00039 }
00040
00041
00042 TMVA::RuleCut::RuleCut()
00043 : fCutNeve(0),
00044 fPurity(0),
00045 fLogger(new MsgLogger("RuleFit"))
00046 {
00047
00048 }
00049
00050
00051 TMVA::RuleCut::~RuleCut() {
00052
00053 delete fLogger;
00054 }
00055
00056
00057
00058 void TMVA::RuleCut::MakeCuts( const std::vector<const Node*> & nodes )
00059 {
00060
00061
00062
00063 UInt_t nnodes = nodes.size();
00064 if (nnodes<2) {
00065 Log() << kWARNING << "<MakeCuts()> Empty cut created." << Endl;
00066 return;
00067 }
00068
00069
00070 const DecisionTreeNode* dtn = dynamic_cast<const DecisionTreeNode*>(nodes.back());
00071 if(!dtn) return;
00072 fCutNeve = dtn->GetNEvents();
00073 fPurity = dtn->GetPurity();
00074
00075
00076 typedef std::pair<Double_t,Int_t> CutDir_t;
00077 typedef std::pair<Int_t,CutDir_t> SelCut_t;
00078
00079
00080 fSelector.clear();
00081 fCutMin.clear();
00082 fCutMax.clear();
00083 fCutDoMin.clear();
00084 fCutDoMax.clear();
00085
00086
00087
00088 std::list<SelCut_t> allsel;
00089 Int_t sel;
00090 Double_t val;
00091 Int_t dir;
00092 const Node *nextNode;
00093 for ( UInt_t i=0; i<nnodes-1; i++) {
00094 nextNode = nodes[i+1];
00095 const DecisionTreeNode* dtn_ = dynamic_cast<const DecisionTreeNode*>(nodes[i]);
00096 if(!dtn_) return;
00097 sel = dtn_->GetSelector();
00098 val = dtn_->GetCutValue();
00099 if (nodes[i]->GetRight() == nextNode) {
00100 dir = 1;
00101 }
00102 else if (nodes[i]->GetLeft() == nextNode) {
00103 dir = -1;
00104 }
00105 else {
00106 Log() << kFATAL << "<MakeTheRule> BUG! Should not be here - an end-node before the end!" << Endl;
00107 dir = 0;
00108 }
00109 allsel.push_back(SelCut_t(sel,CutDir_t(val,dir)));
00110 }
00111
00112 allsel.sort();
00113 Int_t prevSel=-1;
00114 Int_t nsel=0;
00115 Bool_t firstMin=kTRUE;
00116 Bool_t firstMax=kTRUE;
00117 for ( std::list<SelCut_t>::const_iterator it = allsel.begin(); it!=allsel.end(); it++ ) {
00118 sel = (*it).first;
00119 val = (*it).second.first;
00120 dir = (*it).second.second;
00121 if (sel!=prevSel) {
00122 firstMin = kTRUE;
00123 firstMax = kTRUE;
00124 nsel++;
00125 fSelector.push_back(sel);
00126 fCutMin.resize( fSelector.size(),0);
00127 fCutMax.resize( fSelector.size(),0);
00128 fCutDoMin.resize( fSelector.size(), kFALSE);
00129 fCutDoMax.resize( fSelector.size(), kFALSE);
00130 }
00131 switch ( dir ) {
00132 case 1:
00133 if ((val<fCutMin[nsel-1]) || firstMin) {
00134 fCutMin[nsel-1] = val;
00135 fCutDoMin[nsel-1] = kTRUE;
00136 firstMin = kFALSE;
00137 }
00138 break;
00139 case -1:
00140 if ((val>fCutMax[nsel-1]) || firstMax) {
00141 fCutMax[nsel-1] = val;
00142 fCutDoMax[nsel-1] = kTRUE;
00143 firstMax = kFALSE;
00144 }
00145 default:
00146 break;
00147 }
00148 prevSel = sel;
00149 }
00150 }
00151
00152
00153 UInt_t TMVA::RuleCut::GetNcuts() const
00154 {
00155
00156 UInt_t rval=0;
00157 for (UInt_t i=0; i<fSelector.size(); i++) {
00158 if (fCutDoMin[i]) rval += 1;
00159 if (fCutDoMax[i]) rval += 1;
00160 }
00161 return rval;
00162 }
00163
00164 Bool_t TMVA::RuleCut::GetCutRange(Int_t sel,Double_t &rmin, Double_t &rmax, Bool_t &dormin, Bool_t &dormax) const
00165 {
00166
00167 dormin=kFALSE;
00168 dormax=kFALSE;
00169 Bool_t done=kFALSE;
00170 Bool_t foundIt=kFALSE;
00171 UInt_t ind=0;
00172 while (!done) {
00173 foundIt = (Int_t(fSelector[ind])==sel);
00174 ind++;
00175 done = (foundIt || (ind==fSelector.size()));
00176 }
00177 if (!foundIt) return kFALSE;
00178 rmin = fCutMin[ind-1];
00179 rmax = fCutMax[ind-1];
00180 dormin = fCutDoMin[ind-1];
00181 dormax = fCutDoMax[ind-1];
00182 return kTRUE;
00183 }