BinaryTree.cxx

Go to the documentation of this file.
00001 // @(#)root/tmva $Id: BinaryTree.cxx 37986 2011-02-04 21:42:15Z pcanal $
00002 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss
00003 
00004 /**********************************************************************************
00005  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
00006  * Package: TMVA                                                                  *
00007  * Class  : TMVA::BinaryTree                                                      *
00008  * Web    : http://tmva.sourceforge.net                                           *
00009  *                                                                                *
00010  * Description:                                                                   *
00011  *      Implementation (see header file for description)                          *
00012  *                                                                                *
00013  * Authors (alphabetical):                                                        *
00014  *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
00015  *      Joerg Stelzer   <stelzer@cern.ch>        - DESY, Germany                  *
00016  *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
00017  *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
00018  *                                                                                *
00019  * Copyright (c) 2005:                                                            *
00020  *      CERN, Switzerland                                                         *
00021  *      DESY, Germany                                                             *
00022  *      U. of Victoria, Canada                                                    *
00023  *      MPI-K Heidelberg, Germany                                                 *
00024  *                                                                                *
00025  * Redistribution and use in source and binary forms, with or without             *
00026  * modification, are permitted according to the terms listed in LICENSE           *
00027  * (http://tmva.sourceforge.net/LICENSE)                                          *
00028  **********************************************************************************/
00029 
00030 //////////////////////////////////////////////////////////////////////////
00031 //                                                                      //
00032 // BinaryTree                                                           //
00033 //                                                                      //
00034 // Base class for BinarySearch and Decision Trees                       //
00035 //                                                                      //
00036 //////////////////////////////////////////////////////////////////////////
00037 
00038 #include <string>
00039 #include <stdexcept>
00040 
00041 #include "TMVA/BinaryTree.h"
00042 #include "TMVA/MsgLogger.h"
00043 #include "TMVA/Event.h"
00044 #include "TMVA/Tools.h"
00045 
00046 ClassImp(TMVA::BinaryTree)
00047 
00048 TMVA::MsgLogger* TMVA::BinaryTree::fgLogger = 0;
00049 
00050 //_______________________________________________________________________
00051 TMVA::BinaryTree::BinaryTree( void )
00052    : fRoot  ( NULL ),
00053      fNNodes( 0 ),
00054      fDepth ( 0 )
00055 {
00056    // constructor for a yet "empty" tree. Needs to be filled afterwards
00057    if (!fgLogger) fgLogger =  new MsgLogger("BinaryTree");
00058 }
00059 
00060 //_______________________________________________________________________
00061 TMVA::BinaryTree::~BinaryTree( void )
00062 {
00063    //destructor (deletes the nodes and "events" if owned by the tree
00064    this->DeleteNode( fRoot );
00065    fRoot=0;
00066 }
00067 
00068 //_______________________________________________________________________
00069 void TMVA::BinaryTree::DeleteNode( TMVA::Node* node )
00070 {
00071    // protected, recursive, function used by the class destructor and when Pruning
00072    if (node != NULL) { //If the node is not NULL...
00073       this->DeleteNode(node->GetLeft());  //Delete its left node.
00074       this->DeleteNode(node->GetRight()); //Delete its right node.
00075 
00076       delete node;                // Delete the node in memory
00077    }
00078 }
00079 
00080 //_______________________________________________________________________
00081 TMVA::Node* TMVA::BinaryTree::GetLeftDaughter( Node *n)
00082 {
00083    // get left daughter node current node "n"
00084    return (Node*) n->GetLeft();
00085 }
00086 
00087 //_______________________________________________________________________
00088 TMVA::Node* TMVA::BinaryTree::GetRightDaughter( Node *n)
00089 {
00090    // get right daughter node current node "n"
00091    return (Node*) n->GetRight();
00092 }
00093 
00094 //_______________________________________________________________________
00095 UInt_t TMVA::BinaryTree::CountNodes(TMVA::Node *n)
00096 {
00097    // return the number of nodes in the tree. (make a new count --> takes time)
00098 
00099    if (n == NULL){ //default, start at the tree top, then descend recursively
00100       n = (Node*)this->GetRoot();
00101       if (n == NULL) return 0 ;
00102    }
00103 
00104    UInt_t countNodes=1;
00105 
00106    if (this->GetLeftDaughter(n) != NULL){
00107       countNodes += this->CountNodes( this->GetLeftDaughter(n) );
00108    }
00109    if (this->GetRightDaughter(n) != NULL) {
00110       countNodes += this->CountNodes( this->GetRightDaughter(n) );
00111    }
00112 
00113    return fNNodes = countNodes;
00114 }
00115 
00116 //_______________________________________________________________________
00117 void TMVA::BinaryTree::Print(ostream & os) const
00118 {
00119    // recursively print the tree
00120    this->GetRoot()->PrintRec(os);
00121    os << "-1" << std::endl;
00122 }
00123 
00124 //_______________________________________________________________________
00125 void* TMVA::BinaryTree::AddXMLTo(void* parent) const {
00126    // add attributes to XML
00127 
00128    void* bdt = gTools().AddChild(parent, "BinaryTree");
00129    gTools().AddAttr( bdt, "type" , ClassName() );
00130    this->GetRoot()->AddXMLTo(bdt);
00131    return bdt;
00132 }
00133 
00134 //_______________________________________________________________________
00135 void TMVA::BinaryTree::ReadXML(void* node, UInt_t tmva_Version_Code ) {
00136    // read attributes from XML
00137 
00138    this->DeleteNode( fRoot );
00139    fRoot= CreateNode();
00140 
00141    void* trnode = gTools().GetChild(node);
00142    fRoot->ReadXML(trnode, tmva_Version_Code);
00143 
00144    this->SetTotalTreeDepth();
00145 }
00146 
00147 
00148 //_______________________________________________________________________
00149 ostream& TMVA::operator<< (ostream& os, const TMVA::BinaryTree& tree)
00150 {
00151    // print the tree recursinvely using the << operator
00152    tree.Print(os);
00153    return os; // Return the output stream.
00154 }
00155 
00156 //_______________________________________________________________________
00157 void TMVA::BinaryTree::Read(istream & istr, UInt_t tmva_Version_Code )
00158 {
00159    // Read the binary tree from an input stream.
00160    // The input stream format depends on the tree type,
00161    // it is defined be the node of the tree
00162 
00163    Node * currentNode = GetRoot();
00164    Node* parent = 0;
00165 
00166    if(currentNode==0) {
00167       currentNode=CreateNode();
00168       SetRoot(currentNode);
00169    }
00170 
00171    while(1) {
00172       if ( ! currentNode->ReadDataRecord(istr, tmva_Version_Code) ) {
00173          delete currentNode;
00174          this->SetTotalTreeDepth();
00175          return;
00176       }
00177 
00178       // find parent node
00179       while( parent!=0 && parent->GetDepth() != currentNode->GetDepth()-1) parent=parent->GetParent();
00180       
00181       if (parent!=0) { // link new node to parent
00182          currentNode->SetParent(parent);
00183          if (currentNode->GetPos()=='l') parent->SetLeft(currentNode);
00184          if (currentNode->GetPos()=='r') parent->SetRight(currentNode);
00185       }
00186 
00187       parent = currentNode; // latest node read might be parent of new one
00188 
00189       currentNode = CreateNode(); // create a new node to be read next
00190    }
00191 }
00192 
00193 //_______________________________________________________________________
00194 istream& TMVA::operator>> (istream& istr, TMVA::BinaryTree& tree)
00195 { 
00196    // read the tree from an istream
00197    tree.Read(istr);
00198    return istr;
00199 }
00200 //_______________________________________________________________________
00201 void TMVA::BinaryTree::SetTotalTreeDepth( Node *n)
00202 {
00203    // descend a tree to find all its leaf nodes, fill max depth reached in the
00204    // tree at the same time. 
00205 
00206    if (n == NULL){ //default, start at the tree top, then descend recursively
00207       n = (Node*) this->GetRoot();
00208       if (n == NULL) {
00209          Log() << kFATAL << "SetTotalTreeDepth: started with undefined ROOT node" <<Endl;
00210          return ;
00211       }
00212    } 
00213    if (this->GetLeftDaughter(n) != NULL){
00214       this->SetTotalTreeDepth( this->GetLeftDaughter(n) );
00215    }
00216    if (this->GetRightDaughter(n) != NULL) {
00217       this->SetTotalTreeDepth( this->GetRightDaughter(n) );
00218    }
00219    if (n->GetDepth() > this->GetTotalTreeDepth()) this->SetTotalTreeDepth(n->GetDepth());
00220 
00221    return;
00222 }

Generated on Tue Jul 5 15:16:41 2011 for ROOT_528-00b_version by  doxygen 1.5.1