// @(#)root/tmva $Id$    
// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss 

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate Data analysis       *
 * Package: TMVA                                                                  *
 * Classes: Node                                                                  *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header file for description)                          *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * CopyRight (c) 2005:                                                            *
 *      CERN, Switzerland                                                         * 
 *      U. of Victoria, Canada                                                    * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

//_______________________________________________________________________
/*
  Node for the BinarySearch or Decision Trees.
  
  For the binary search tree, it basically consists of the EVENT, and
  pointers to the parent and daughters

  In case of the Decision Tree, it specifies parent and daughters, as
  well as "which variable is used" in the selection of this node,
  including the respective cut value.
*/
//______________________________________________________________________

#include <stdexcept>
#include <iosfwd>
#include <iostream>

#include "TMVA/Node.h"
#include "TMVA/Tools.h"

ClassImp(TMVA::Node)

Int_t TMVA::Node::fgCount = 0;

TMVA::Node::Node() 
   : fParent( NULL ),
     fLeft  ( NULL),
     fRight ( NULL ),
     fPos   ( 'u' ),
     fDepth ( 0 ),
     fParentTree( NULL )
{
   // default constructor
   fgCount++;
}

//_______________________________________________________________________
TMVA::Node::Node( Node* p, char pos ) 
   : fParent ( p ), 
     fLeft ( NULL ), 
     fRight( NULL ),  
     fPos  ( pos ), 
     fDepth( p->GetDepth() + 1), 
     fParentTree(p->GetParentTree()) 
{
   // constructor of a daughter node as a daughter of 'p'

   fgCount++;
   if (fPos == 'l' ) p->SetLeft(this);
   else if (fPos == 'r' ) p->SetRight(this);
}

//_______________________________________________________________________
TMVA::Node::Node ( const Node &n ) 
   : fParent( NULL ), 
     fLeft  ( NULL), 
     fRight ( NULL ), 
     fPos   ( n.fPos ), 
     fDepth ( n.fDepth ), 
     fParentTree( NULL )
{
   // copy constructor, make sure you don't just copy the poiter to the node, but
   // that the parents/daugthers are initialized to 0 (and set by the copy 
   // constructors of the derived classes 
   fgCount++;
}

//_______________________________________________________________________
TMVA::Node::~Node()
{
   // node destructor
   fgCount--;
}

//_______________________________________________________________________
int TMVA::Node::GetCount()
{
   // retuns the global number of instantiated nodes
   return fgCount;
}

//_______________________________________________________________________
Int_t TMVA::Node::CountMeAndAllDaughters() const 
{
   //recursively go through the part of the tree below this node and count all daughters
   Int_t n=1;
   if (this->GetLeft() != NULL) 
      n+= this->GetLeft()->CountMeAndAllDaughters(); 
   if (this->GetRight() != NULL) 
      n+= this->GetRight()->CountMeAndAllDaughters(); 
  
   return n;
}

// print a node
//_______________________________________________________________________
std::ostream& TMVA::operator<<( std::ostream& os, const TMVA::Node& node )
{ 
   // output operator for a node  
   node.Print(os);
   return os;                // Return the output stream.
}

//_______________________________________________________________________
std::ostream& TMVA::operator<<( std::ostream& os, const TMVA::Node* node )
{ 
   // output operator with a pointer to the node (which still prints the node itself)
   if (node!=NULL) node->Print(os);
   return os;                // Return the output stream.
}

//_______________________________________________________________________
void* TMVA::Node::AddXMLTo( void* parent ) const
{
   // add attributes to XML
   std::stringstream s("");
   AddContentToNode(s);
   void* node = gTools().AddChild(parent, "Node", s.str().c_str());
   gTools().AddAttr( node, "pos",   fPos );
   gTools().AddAttr( node, "depth", fDepth );
   this->AddAttributesToNode(node);
   if (this->GetLeft())  this->GetLeft()->AddXMLTo(node);
   if (this->GetRight()) this->GetRight()->AddXMLTo(node);
   return node;
}

//_______________________________________________________________________
void TMVA::Node::ReadXML( void* node,  UInt_t tmva_Version_Code )
{
   // read attributes from XML
   ReadAttributes(node, tmva_Version_Code);
   const char* content = gTools().GetContent(node);
   if (content) {
      std::stringstream s(content);
      ReadContent(s);
   }
   gTools().ReadAttr( node, "pos",   fPos );
   gTools().ReadAttr( node, "depth", fDepth );

   void* ch = gTools().GetChild(node);
   while (ch) {
      Node* n = CreateNode();
      n->ReadXML(ch, tmva_Version_Code);
      if (n->GetPos()=='l')     { this->SetLeft(n);  }
      else if(n->GetPos()=='r') { this->SetRight(n); }
      else { 
	 std::cout << "neither left nor right" << std::endl;
      }
      ch = gTools().GetNextChild(ch);
   }
}
 Node.cxx:1
 Node.cxx:2
 Node.cxx:3
 Node.cxx:4
 Node.cxx:5
 Node.cxx:6
 Node.cxx:7
 Node.cxx:8
 Node.cxx:9
 Node.cxx:10
 Node.cxx:11
 Node.cxx:12
 Node.cxx:13
 Node.cxx:14
 Node.cxx:15
 Node.cxx:16
 Node.cxx:17
 Node.cxx:18
 Node.cxx:19
 Node.cxx:20
 Node.cxx:21
 Node.cxx:22
 Node.cxx:23
 Node.cxx:24
 Node.cxx:25
 Node.cxx:26
 Node.cxx:27
 Node.cxx:28
 Node.cxx:29
 Node.cxx:30
 Node.cxx:31
 Node.cxx:32
 Node.cxx:33
 Node.cxx:34
 Node.cxx:35
 Node.cxx:36
 Node.cxx:37
 Node.cxx:38
 Node.cxx:39
 Node.cxx:40
 Node.cxx:41
 Node.cxx:42
 Node.cxx:43
 Node.cxx:44
 Node.cxx:45
 Node.cxx:46
 Node.cxx:47
 Node.cxx:48
 Node.cxx:49
 Node.cxx:50
 Node.cxx:51
 Node.cxx:52
 Node.cxx:53
 Node.cxx:54
 Node.cxx:55
 Node.cxx:56
 Node.cxx:57
 Node.cxx:58
 Node.cxx:59
 Node.cxx:60
 Node.cxx:61
 Node.cxx:62
 Node.cxx:63
 Node.cxx:64
 Node.cxx:65
 Node.cxx:66
 Node.cxx:67
 Node.cxx:68
 Node.cxx:69
 Node.cxx:70
 Node.cxx:71
 Node.cxx:72
 Node.cxx:73
 Node.cxx:74
 Node.cxx:75
 Node.cxx:76
 Node.cxx:77
 Node.cxx:78
 Node.cxx:79
 Node.cxx:80
 Node.cxx:81
 Node.cxx:82
 Node.cxx:83
 Node.cxx:84
 Node.cxx:85
 Node.cxx:86
 Node.cxx:87
 Node.cxx:88
 Node.cxx:89
 Node.cxx:90
 Node.cxx:91
 Node.cxx:92
 Node.cxx:93
 Node.cxx:94
 Node.cxx:95
 Node.cxx:96
 Node.cxx:97
 Node.cxx:98
 Node.cxx:99
 Node.cxx:100
 Node.cxx:101
 Node.cxx:102
 Node.cxx:103
 Node.cxx:104
 Node.cxx:105
 Node.cxx:106
 Node.cxx:107
 Node.cxx:108
 Node.cxx:109
 Node.cxx:110
 Node.cxx:111
 Node.cxx:112
 Node.cxx:113
 Node.cxx:114
 Node.cxx:115
 Node.cxx:116
 Node.cxx:117
 Node.cxx:118
 Node.cxx:119
 Node.cxx:120
 Node.cxx:121
 Node.cxx:122
 Node.cxx:123
 Node.cxx:124
 Node.cxx:125
 Node.cxx:126
 Node.cxx:127
 Node.cxx:128
 Node.cxx:129
 Node.cxx:130
 Node.cxx:131
 Node.cxx:132
 Node.cxx:133
 Node.cxx:134
 Node.cxx:135
 Node.cxx:136
 Node.cxx:137
 Node.cxx:138
 Node.cxx:139
 Node.cxx:140
 Node.cxx:141
 Node.cxx:142
 Node.cxx:143
 Node.cxx:144
 Node.cxx:145
 Node.cxx:146
 Node.cxx:147
 Node.cxx:148
 Node.cxx:149
 Node.cxx:150
 Node.cxx:151
 Node.cxx:152
 Node.cxx:153
 Node.cxx:154
 Node.cxx:155
 Node.cxx:156
 Node.cxx:157
 Node.cxx:158
 Node.cxx:159
 Node.cxx:160
 Node.cxx:161
 Node.cxx:162
 Node.cxx:163
 Node.cxx:164
 Node.cxx:165
 Node.cxx:166
 Node.cxx:167
 Node.cxx:168
 Node.cxx:169
 Node.cxx:170
 Node.cxx:171
 Node.cxx:172
 Node.cxx:173
 Node.cxx:174
 Node.cxx:175
 Node.cxx:176
 Node.cxx:177
 Node.cxx:178