#include <algorithm>
#include "Riostream.h"
#include "TMVA/DecisionTreeNode.h"
#include "TMVA/Tools.h"
#include "TMVA/Event.h"
using std::string;
ClassImp(TMVA::DecisionTreeNode)
TMVA::MsgLogger* TMVA::DecisionTreeNode::fgLogger = 0;
   
TMVA::DecisionTreeNode::DecisionTreeNode()
   : TMVA::Node(),
     fCutValue(0),
     fCutType ( kTRUE ),
     fSelector ( -1 ),  
     fNSigEvents ( 0 ),
     fNBkgEvents ( 0 ),
     fNEvents ( -1 ),
     fNSigEvents_unweighted ( 0 ),
     fNBkgEvents_unweighted ( 0 ),
     fNEvents_unweighted ( 0 ),
     fSeparationIndex (-1 ),
     fSeparationGain ( -1 ),
     fNodeType (-99 ),
     fSequence ( 0 ) 
{
   
   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
}
TMVA::DecisionTreeNode::DecisionTreeNode(TMVA::Node* p, char pos)
   : TMVA::Node(p, pos), 
     fCutValue( 0 ),
     fCutType ( kTRUE ),
     fSelector( -1 ),  
     fNSigEvents ( 0 ),
     fNBkgEvents ( 0 ),
     fNEvents ( -1 ),
     fNSigEvents_unweighted ( 0 ),
     fNBkgEvents_unweighted ( 0 ),
     fNEvents_unweighted ( 0 ),
     fSeparationIndex( -1 ),
     fSeparationGain ( -1 ),
     fNodeType( -99 ),
     fSequence( 0 ) 
{
   
   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
   
   if (pos == 'r' ){
      ULong_t tmp =1; for (UInt_t i=1; i<this->GetDepth(); i++) {tmp *= 2; }  
      fSequence =  ((DecisionTreeNode*)p)->GetSequence() + tmp;
   } else {
      fSequence =  ((DecisionTreeNode*)p)->GetSequence();
   }      
}
TMVA::DecisionTreeNode::DecisionTreeNode(const TMVA::DecisionTreeNode &n,
                                         DecisionTreeNode* parent)
   : TMVA::Node(n),
     fCutValue( n.fCutValue ),
     fCutType ( n.fCutType ),
     fSelector( n.fSelector ),  
     fNSigEvents ( n.fNSigEvents ),
     fNBkgEvents ( n.fNBkgEvents ),
     fNEvents ( n.fNEvents ),
     fNSigEvents_unweighted ( n.fNSigEvents_unweighted ),
     fNBkgEvents_unweighted ( n.fNBkgEvents_unweighted ),
     fNEvents_unweighted ( n.fNEvents_unweighted ),
     fSeparationIndex( n.fSeparationIndex ),
     fSeparationGain ( n.fSeparationGain ),
     fNodeType( n.fNodeType ),
     fSequence( n.fSequence )  
{
   
   
   if (!fgLogger) fgLogger = new TMVA::MsgLogger( "DecisionTreeNode" );
   this->SetParent( parent );
   if (n.GetLeft() == 0 ) this->SetLeft(NULL);
   else this->SetLeft( new DecisionTreeNode( *((DecisionTreeNode*)(n.GetLeft())),this));
   
   if (n.GetRight() == 0 ) this->SetRight(NULL);
   else this->SetRight( new DecisionTreeNode( *((DecisionTreeNode*)(n.GetRight())),this));
}
Bool_t TMVA::DecisionTreeNode::GoesRight(const TMVA::Event & e) const
{
   
   Bool_t result;
  
   result =  (e.GetVal(this->GetSelector()) > this->GetCutValue() );
  
   if (fCutType == kTRUE) return result; 
   else return !result;
}
Bool_t TMVA::DecisionTreeNode::GoesLeft(const TMVA::Event & e) const
{
   
   if (!this->GoesRight(e)) return kTRUE;
   else return kFALSE;
}
Double_t TMVA::DecisionTreeNode::GetPurity( void ) const  
{
   
   
   
   if ( ( this->GetNSigEvents() + this->GetNBkgEvents() ) > 0 ) {
      return this->GetNSigEvents() / ( this->GetNSigEvents() + this->GetNBkgEvents()); 
   }
   else {
      *fgLogger << kINFO << "Zero events in purity calcuation , retrun purity=0.5" << Endl;
      return 0.5;
   }
}
void TMVA::DecisionTreeNode::Print(ostream& os) const
{
   
   os << "< ***  "  << endl; 
   os << " d: "     << this->GetDepth()
      << " seq: "   << this->GetSequence()
      << " ivar: "  << this->GetSelector()
      << " cut: "   << this->GetCutValue() 
      << " cType: " << this->GetCutType() 
      << " s: "     << this->GetNSigEvents()
      << " b: "     << this->GetNBkgEvents()
      << " nEv: "   << this->GetNEvents()
      << " suw: "     << this->GetNSigEvents_unweighted()
      << " buw: "     << this->GetNBkgEvents_unweighted()
      << " nEvuw: "   << this->GetNEvents_unweighted()
      << " sepI: "  << this->GetSeparationIndex()
      << " sepG: "  << this->GetSeparationGain()
      << " nType: " << this->GetNodeType()
      <<endl;
   
   os << "My address is " << long(this) << ", ";
   if (this->GetParent() != NULL) os << " parent at addr: "         << long(this->GetParent()) ;
   if (this->GetLeft()   != NULL) os << " left daughter at addr: "  << long(this->GetLeft());
   if (this->GetRight()  != NULL) os << " right daughter at addr: " << long(this->GetRight()) ;
   
   os << " **** > "<< endl;
}
void TMVA::DecisionTreeNode::PrintRec(ostream& os) const
{
   
   os << this->GetDepth() 
      << " "         << this->GetPos() 
      << " seq: "    << this->GetSequence()
      << " ivar: "   << this->GetSelector()
      << " cut: "    << this->GetCutValue() 
      << " cType: "  << this->GetCutType() 
      << " s: "      << this->GetNSigEvents()
      << " b: "      << this->GetNBkgEvents()
      << " nEv: "    << this->GetNEvents()
      << " suw: "     << this->GetNSigEvents_unweighted()
      << " buw: "     << this->GetNBkgEvents_unweighted()
      << " nEvuw: "   << this->GetNEvents_unweighted()
      << " sepI: "   << this->GetSeparationIndex()
      << " sepG: "   << this->GetSeparationGain()
      << " nType: "  << this->GetNodeType()
      <<endl;
  
   if (this->GetLeft()  != NULL) this->GetLeft() ->PrintRec(os);
   if (this->GetRight() != NULL) this->GetRight()->PrintRec(os);
}
Bool_t TMVA::DecisionTreeNode::ReadDataRecord( istream& is ) 
{
   
   string tmp;
   Double_t dtmp1, dtmp2, dtmp3, dtmp4, dtmp5, dtmp6, dtmp7, dtmp8, dtmp9, dtmp10;
   Int_t depth, itmp1, itmp2;
   ULong_t lseq;
   char pos;
   
   
   is >> depth;                                         
   if ( depth==-1 ) { delete this; return kFALSE; }
   is >> pos ;                                          
   this->SetDepth(depth);
   this->SetPos(pos);
   is >> tmp >> lseq                                    
      >> tmp >> itmp1                                   
      >> tmp >> dtmp1                                   
      >> tmp >> dtmp2                                   
      >> tmp >> dtmp3                                   
      >> tmp >> dtmp4                                   
      >> tmp >> dtmp5                                   
      >> tmp >> dtmp6                                   
      >> tmp >> dtmp7                                   
      >> tmp >> dtmp8                                   
      >> tmp >> dtmp9                                   
      >> tmp >> dtmp10                                  
      >> tmp >> itmp2;                                  
   
   this->SetSelector((UInt_t)itmp1);
   this->SetCutValue(dtmp1);
   this->SetCutType(dtmp2);
   this->SetNSigEvents(dtmp3);
   this->SetNBkgEvents(dtmp4);
   this->SetNEvents(dtmp5);
   this->SetNSigEvents_unweighted(dtmp6);
   this->SetNBkgEvents_unweighted(dtmp7);
   this->SetNEvents_unweighted(dtmp8);
   this->SetSeparationIndex(dtmp9);
   this->SetSeparationGain(dtmp10);
   this->SetNodeType(itmp2);
   this->SetSequence(lseq);
   return kTRUE;
}
void TMVA::DecisionTreeNode::ReadRec( istream& is,  char &pos, UInt_t &depth,
                                      TMVA::Node* parent )
{
   
   if (!ReadDataRecord(is)) return;
   depth = GetDepth();
   pos   = GetPos();
   
   while( parent!=0 && parent->GetDepth() != GetDepth()-1) parent=parent->GetParent();
   if (parent!=0) {
      SetParent(parent);
      if (GetPos()=='l') parent->SetLeft(this);
      if (GetPos()=='r') parent->SetRight(this);
   }
   
   char childPos;
   UInt_t childDepth;
   TMVA::Node * newNode = new TMVA::DecisionTreeNode();
   newNode->ReadRec(is, childPos, childDepth, this);
}
void TMVA::DecisionTreeNode::ClearNodeAndAllDaughters()
{
   
   fNSigEvents=0;
   fNBkgEvents=0;
   fNEvents = 0;
   fNSigEvents_unweighted=0;
   fNBkgEvents_unweighted=0;
   fNEvents_unweighted = 0;
   fSeparationIndex=-1;
   fSeparationGain=-1;
   if (this->GetLeft()  != NULL) ((DecisionTreeNode*)(this->GetLeft()))->ClearNodeAndAllDaughters();
   if (this->GetRight() != NULL) ((DecisionTreeNode*)(this->GetRight()))->ClearNodeAndAllDaughters();
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.