Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
Node.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate Data analysis *
6  * Package: TMVA *
7  * Classes: Node *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation (see header file for description) *
12  * *
13  * Authors (alphabetical): *
14  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
15  * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
16  * Kai Voss <Kai.Voss@cern.ch> - U. of Victoria, Canada *
17  * *
18  * CopyRight (c) 2005: *
19  * CERN, Switzerland *
20  * U. of Victoria, Canada *
21  * MPI-K Heidelberg, Germany *
22  * *
23  * Redistribution and use in source and binary forms, with or without *
24  * modification, are permitted according to the terms listed in LICENSE *
25  * (http://tmva.sourceforge.net/LICENSE) *
26  **********************************************************************************/
27 
28 /*! \class TMVA::Node
29 \ingroup TMVA
30 Node for the BinarySearch or Decision Trees.
31 
32 For the binary search tree, it basically consists of the EVENT, and
33 pointers to the parent and daughters
34 
35 In case of the Decision Tree, it specifies parent and daughters, as
36 well as "which variable is used" in the selection of this node,
37 including the respective cut value.
38 */
39 
40 #include <stdexcept>
41 #include <iosfwd>
42 #include <iostream>
43 
44 #include "TMVA/Node.h"
45 #include "TMVA/Tools.h"
46 
47 ClassImp(TMVA::Node);
48 
49 Int_t TMVA::Node::fgCount = 0;
50 
51 TMVA::Node::Node()
52  : fParent( NULL ),
53  fLeft ( NULL),
54  fRight ( NULL ),
55  fPos ( 'u' ),
56  fDepth ( 0 ),
57  fParentTree( NULL )
58 {
59  // default constructor
60  fgCount++;
61 }
62 
63 ////////////////////////////////////////////////////////////////////////////////
64 /// constructor of a daughter node as a daughter of 'p'
65 
66 TMVA::Node::Node( Node* p, char pos )
67  : fParent ( p ),
68  fLeft ( NULL ),
69  fRight( NULL ),
70  fPos ( pos ),
71  fDepth( p->GetDepth() + 1),
72  fParentTree(p->GetParentTree())
73 {
74  fgCount++;
75  if (fPos == 'l' ) p->SetLeft(this);
76  else if (fPos == 'r' ) p->SetRight(this);
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// copy constructor, make sure you don't just copy the pointer to the node, but
81 /// that the parents/daughters are initialized to 0 (and set by the copy
82 /// constructors of the derived classes
83 
84 TMVA::Node::Node ( const Node &n )
85  : fParent( NULL ),
86  fLeft ( NULL),
87  fRight ( NULL ),
88  fPos ( n.fPos ),
89  fDepth ( n.fDepth ),
90  fParentTree( NULL )
91 {
92  fgCount++;
93 }
94 
95 ////////////////////////////////////////////////////////////////////////////////
96 /// node destructor
97 
98 TMVA::Node::~Node()
99 {
100  fgCount--;
101 }
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 /// returns the global number of instantiated nodes
105 
106 int TMVA::Node::GetCount()
107 {
108  return fgCount;
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 ///recursively go through the part of the tree below this node and count all daughters
113 
114 Int_t TMVA::Node::CountMeAndAllDaughters() const
115 {
116  Int_t n=1;
117  if (this->GetLeft() != NULL)
118  n+= this->GetLeft()->CountMeAndAllDaughters();
119  if (this->GetRight() != NULL)
120  n+= this->GetRight()->CountMeAndAllDaughters();
121 
122  return n;
123 }
124 
125 // print a node
126 ////////////////////////////////////////////////////////////////////////////////
127 /// output operator for a node
128 
129 std::ostream& TMVA::operator<<( std::ostream& os, const TMVA::Node& node )
130 {
131  node.Print(os);
132  return os; // Return the output stream.
133 }
134 
135 ////////////////////////////////////////////////////////////////////////////////
136 /// output operator with a pointer to the node (which still prints the node itself)
137 
138 std::ostream& TMVA::operator<<( std::ostream& os, const TMVA::Node* node )
139 {
140  if (node!=NULL) node->Print(os);
141  return os; // Return the output stream.
142 }
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 /// add attributes to XML
146 
147 void* TMVA::Node::AddXMLTo( void* parent ) const
148 {
149  std::stringstream s("");
150  AddContentToNode(s);
151  void* node = gTools().AddChild(parent, "Node", s.str().c_str());
152  gTools().AddAttr( node, "pos", fPos );
153  gTools().AddAttr( node, "depth", fDepth );
154  this->AddAttributesToNode(node);
155  if (this->GetLeft()) this->GetLeft()->AddXMLTo(node);
156  if (this->GetRight()) this->GetRight()->AddXMLTo(node);
157  return node;
158 }
159 
160 ////////////////////////////////////////////////////////////////////////////////
161 /// read attributes from XML
162 
163 void TMVA::Node::ReadXML( void* node, UInt_t tmva_Version_Code )
164 {
165  ReadAttributes(node, tmva_Version_Code);
166  const char* content = gTools().GetContent(node);
167  if (content) {
168  std::stringstream s(content);
169  ReadContent(s);
170  }
171  gTools().ReadAttr( node, "pos", fPos );
172  gTools().ReadAttr( node, "depth", fDepth );
173 
174  void* ch = gTools().GetChild(node);
175  while (ch) {
176  Node* n = CreateNode();
177  n->ReadXML(ch, tmva_Version_Code);
178  if (n->GetPos()=='l') { this->SetLeft(n); }
179  else if(n->GetPos()=='r') { this->SetRight(n); }
180  else {
181  std::cout << "neither left nor right" << std::endl;
182  }
183  ch = gTools().GetNextChild(ch);
184  }
185 }