#if ROOT_VERSION_CODE >= 364802
#ifndef ROOT_TMathBase
#include "TMathBase.h"
#endif
#else
#ifndef ROOT_TMath
#include "TMath.h"
#endif
#endif
#include "TMatrixDBase.h"
#include "TObjString.h"
#include "TTree.h"
#include "Riostream.h"
#include <stdexcept>
#include <stdlib.h>
#ifndef ROOT_TMVA_MethodBase
#include "TMVA/MethodBase.h"
#endif
#ifndef ROOT_TMVA_Tools
#include "TMVA/Tools.h"
#endif
#ifndef ROOT_TMVA_DataSet
#include "TMVA/DataSet.h"
#endif
#ifndef ROOT_TMVA_Event
#include "TMVA/Event.h"
#endif
#ifndef ROOT_TMVA_BinarySearchTree
#include "TMVA/BinarySearchTree.h"
#endif
ClassImp(TMVA::BinarySearchTree)
TMVA::BinarySearchTree::BinarySearchTree( void ) :
BinaryTree(),
fPeriod ( 1 ),
fCurrentDepth( 0 ),
fStatisticsIsValid( kFALSE ),
fSumOfWeights( 0 ),
fCanNormalize( kFALSE )
{
fLogger.SetSource( "BinarySearchTree" );
}
TMVA::BinarySearchTree::BinarySearchTree( const BinarySearchTree &b)
: BinaryTree(),
fPeriod ( b.fPeriod ),
fCurrentDepth( 0 ),
fStatisticsIsValid( kFALSE ),
fSumOfWeights( b.fSumOfWeights ),
fCanNormalize( kFALSE )
{
fLogger.SetSource( "BinarySearchTree" );
fLogger << kFATAL << " Copy constructor not implemented yet " << Endl;
}
TMVA::BinarySearchTree::~BinarySearchTree( void )
{
for(std::vector< pair<Double_t, const TMVA::Event*> >::iterator pIt = fNormalizeTreeTable.begin();
pIt != fNormalizeTreeTable.end(); pIt++) {
delete pIt->second;
}
}
void TMVA::BinarySearchTree::Insert( const Event* event )
{
fCurrentDepth=0;
fStatisticsIsValid = kFALSE;
if (this->GetRoot() == NULL) {
this->SetRoot( new BinarySearchTreeNode(event));
this->GetRoot()->SetPos('s');
this->GetRoot()->SetDepth(0);
fNNodes = 1;
fSumOfWeights = event->GetWeight();
((BinarySearchTreeNode*)this->GetRoot())->SetSelector((UInt_t)0);
this->SetPeriode(event->GetNVars());
}
else {
if (event->GetNVars() != (UInt_t)this->GetPeriode()) {
fLogger << kFATAL << "<Insert> event vector length != Periode specified in Binary Tree" << Endl
<< "--- event size: " << event->GetNVars() << " Periode: " << this->GetPeriode() << Endl
<< "--- and all this when trying filling the "<<fNNodes+1<<"th Node" << Endl;
}
this->Insert(event, this->GetRoot());
}
if (fCanNormalize) fNormalizeTreeTable.push_back( make_pair(0.0,new const Event(*event)) );
}
void TMVA::BinarySearchTree::Insert( const Event *event,
Node *node )
{
fCurrentDepth++;
fStatisticsIsValid = kFALSE;
if (node->GoesLeft(*event)){
if (node->GetLeft() != NULL){
this->Insert(event, node->GetLeft());
}
else {
BinarySearchTreeNode* current = new BinarySearchTreeNode(event);
fNNodes++;
fSumOfWeights += event->GetWeight();
current->SetSelector(fCurrentDepth%((Int_t)event->GetNVars()));
current->SetParent(node);
current->SetPos('l');
current->SetDepth( node->GetDepth() + 1 );
node->SetLeft(current);
}
}
else if (node->GoesRight(*event)) {
if (node->GetRight() != NULL) {
this->Insert(event, node->GetRight());
}
else {
BinarySearchTreeNode* current = new BinarySearchTreeNode(event);
fNNodes++;
fSumOfWeights += event->GetWeight();
current->SetSelector(fCurrentDepth%((Int_t)event->GetNVars()));
current->SetParent(node);
current->SetPos('r');
current->SetDepth( node->GetDepth() + 1 );
node->SetRight(current);
}
}
else fLogger << kFATAL << "<Insert> neither left nor right :)" << Endl;
}
TMVA::BinarySearchTreeNode* TMVA::BinarySearchTree::Search( Event* event ) const
{
return this->Search( event, this->GetRoot() );
}
TMVA::BinarySearchTreeNode* TMVA::BinarySearchTree::Search(Event* event, Node* node) const
{
if (node != NULL) {
if (((BinarySearchTreeNode*)(node))->EqualsMe(*event))
return (BinarySearchTreeNode*)node;
if (node->GoesLeft(*event))
return this->Search(event, node->GetLeft());
else
return this->Search(event, node->GetRight());
}
else return NULL;
}
Double_t TMVA::BinarySearchTree::GetSumOfWeights( void ) const
{
if (fSumOfWeights <= 0) {
fLogger << kWARNING << "you asked for the SumOfWeights, which is not filled yet"
<< " I call CalcStatistics which hopefully fixes things"
<< Endl;
}
if (fSumOfWeights <= 0) fLogger << kFATAL << " Zero events in your Search Tree" <<Endl;
return fSumOfWeights;
}
Double_t TMVA::BinarySearchTree::Fill( const MethodBase& callingMethod, TTree* theTree, Int_t theType )
{
Int_t nevents=0;
if (fSumOfWeights != 0) {
fLogger << kWARNING
<< "You are filling a search three that is not empty.. "
<< " do you know what you are doing?"
<< Endl;
}
fPeriod = callingMethod.GetVarTransform().GetNVariables();
const Event& event = callingMethod.GetEvent();
for (Int_t ievt=0; ievt<theTree->GetEntries(); ievt++) {
callingMethod.ReadEvent(theTree, ievt);
if (theType==-1 || event.Type()==theType) {
this->Insert( &event );
nevents++;
fSumOfWeights += event.GetWeight();
}
}
if (nevents == 0) {
fLogger << kFATAL << "<Fill> number of events in tree is zero: " << nevents << Endl;
}
CalcStatistics();
return fSumOfWeights;
}
Double_t TMVA::BinarySearchTree::Fill( std::vector<Event*> theTree, std::vector<Int_t> theVars,
Int_t theType )
{
fPeriod = (theVars).size();
Int_t nevents = 0;
Int_t n=theTree.size();
if (fSumOfWeights != 0) {
fLogger << kWARNING
<< "You are filling a search three that is not empty.. "
<< " do you know what you are doing?"
<< Endl;
}
for (Int_t ievt=0; ievt<n; ievt++) {
if (theType == -1 || theTree[ievt]->Type() == theType) {
Event *e = new Event(*theTree[ievt]);
this->Insert( e );
nevents++;
fSumOfWeights += e->GetWeight();
}
}
if (nevents == 0) {
fLogger << kFATAL << "<Fill> number of events "
<< "that got filled into the tree is <= zero: " << nevents << Endl;
}
CalcStatistics();
return fSumOfWeights;
}
Double_t TMVA::BinarySearchTree::Fill( std::vector<Event*> theTree, Int_t theType )
{
Int_t n=theTree.size();
Int_t nevents = 0;
if (fSumOfWeights != 0) {
fLogger << kWARNING
<< "You are filling a search three that is not empty.. "
<< " do you know what you are doing?"
<< Endl;
}
for (Int_t ievt=0; ievt<n; ievt++) {
if (theType == -1 || theTree[ievt]->Type() == theType) {
this->Insert( theTree[ievt] );
nevents++;
fSumOfWeights += theTree[ievt]->GetWeight();
}
}
CalcStatistics();
return fSumOfWeights;
}
void TMVA::BinarySearchTree::NormalizeTree ( std::vector< pair<Double_t, const TMVA::Event*> >::iterator leftBound,
std::vector< pair<Double_t, const TMVA::Event*> >::iterator rightBound,
UInt_t actDim )
{
if (leftBound == rightBound) return;
if (actDim == fPeriod) actDim = 0;
for (std::vector< pair<Double_t, const TMVA::Event*> >::iterator i=leftBound; i!=rightBound; i++) {
i->first = i->second->GetVal( actDim );
}
std::sort( leftBound, rightBound );
std::vector< pair<Double_t, const TMVA::Event*> >::iterator leftTemp = leftBound;
std::vector< pair<Double_t, const TMVA::Event*> >::iterator rightTemp = rightBound;
while (true) {
rightTemp--; if (rightTemp == leftTemp ) break;
leftTemp++; if (leftTemp == rightTemp) break;
}
std::vector< pair<Double_t, const TMVA::Event*> >::iterator mid = leftTemp;
std::vector< pair<Double_t, const TMVA::Event*> >::iterator midTemp = mid;
if (mid!=leftBound) midTemp--;
while (mid != leftBound && mid->second->GetVal( actDim ) == midTemp->second->GetVal( actDim )) {
mid--;
midTemp--;
}
Insert( mid->second );
NormalizeTree( leftBound, mid, actDim+1 );
mid++;
NormalizeTree( mid, rightBound, actDim+1 );
return;
}
void TMVA::BinarySearchTree::NormalizeTree()
{
SetNormalize( kFALSE );
Clear( NULL );
this->SetRoot(NULL);
NormalizeTree( fNormalizeTreeTable.begin(), fNormalizeTreeTable.end(), 0 );
}
void TMVA::BinarySearchTree::Clear( Node* n )
{
BinarySearchTreeNode* currentNode = (BinarySearchTreeNode*)(n == NULL ? this->GetRoot() : n);
if (currentNode->GetLeft() != 0) Clear( currentNode->GetLeft() );
if (currentNode->GetRight() != 0) Clear( currentNode->GetRight() );
if (n != NULL) delete n;
return;
}
Double_t TMVA::BinarySearchTree::SearchVolume( Volume* volume,
std::vector<const BinarySearchTreeNode*>* events )
{
return SearchVolume( this->GetRoot(), volume, 0, events );
}
Double_t TMVA::BinarySearchTree::SearchVolume( Node* t, Volume* volume, Int_t depth,
std::vector<const BinarySearchTreeNode*>* events )
{
if (t==NULL) return 0;
BinarySearchTreeNode* st = (BinarySearchTreeNode*)t;
Double_t count = 0.0;
if (InVolume( st->GetEventV(), volume )) {
count += st->GetWeight();
if (NULL != events) events->push_back( st );
}
if (st->GetLeft()==NULL && st->GetRight()==NULL) {
return count;
}
Bool_t tl, tr;
Int_t d = depth%this->GetPeriode();
if (d != st->GetSelector()) {
fLogger << kFATAL << "<SearchVolume> selector in Searchvolume "
<< d << " != " << "node "<< st->GetSelector() << Endl;
}
tl = (*(volume->fLower))[d] < st->GetEventV()[d];
tr = (*(volume->fUpper))[d] >= st->GetEventV()[d];
if (tl) count += SearchVolume( st->GetLeft(), volume, (depth+1), events );
if (tr) count += SearchVolume( st->GetRight(), volume, (depth+1), events );
return count;
}
Bool_t TMVA::BinarySearchTree::InVolume(const std::vector<Float_t>& event, Volume* volume ) const
{
Bool_t result = false;
for (UInt_t ivar=0; ivar< fPeriod; ivar++) {
result = ( (*(volume->fLower))[ivar] < event[ivar] &&
(*(volume->fUpper))[ivar] >= event[ivar] );
if (!result) break;
}
return result;
}
void TMVA::BinarySearchTree::CalcStatistics( Node* n )
{
if (fStatisticsIsValid) return;
BinarySearchTreeNode * currentNode = (BinarySearchTreeNode*)n;
if (n == NULL) {
fSumOfWeights = 0;
for (Int_t sb=0; sb<2; sb++) {
fNEventsW[sb] = 0;
fMeans[sb] = std::vector<Float_t>(fPeriod);
fRMS[sb] = std::vector<Float_t>(fPeriod);
fMin[sb] = std::vector<Float_t>(fPeriod);
fMax[sb] = std::vector<Float_t>(fPeriod);
fSum[sb] = std::vector<Double_t>(fPeriod);
fSumSq[sb] = std::vector<Double_t>(fPeriod);
for (UInt_t j=0; j<fPeriod; j++) {
fMeans[sb][j] = fRMS[sb][j] = fSum[sb][j] = fSumSq[sb][j] = 0;
fMin[sb][j] = 1.e25;
fMax[sb][j] = -1.e25;
}
}
currentNode = (BinarySearchTreeNode*) this->GetRoot();
if (currentNode == NULL) return;
}
const std::vector<Float_t> & evtVec = currentNode->GetEventV();
Double_t weight = currentNode->GetWeight();
Int_t type = currentNode->IsSignal() ? 0 : 1;
fNEventsW[type] += weight;
fSumOfWeights += weight;
for (UInt_t j=0; j<fPeriod; j++) {
Float_t val = evtVec[j];
fSum[type][j] += val*weight;
fSumSq[type][j] += val*val*weight;
if (val < fMin[type][j]) fMin[type][j] = val;
if (val > fMax[type][j]) fMax[type][j] = val;
}
if (currentNode->GetLeft() != 0) CalcStatistics( currentNode->GetLeft() );
if (currentNode->GetRight() != 0) CalcStatistics( currentNode->GetRight() );
if (n == NULL) {
for (Int_t sb=0; sb<2; sb++) {
for (UInt_t j=0; j<fPeriod; j++) {
if (fNEventsW[sb] == 0) { fMeans[sb][j] = fRMS[sb][j] = 0; continue; }
fMeans[sb][j] = fSum[sb][j]/fNEventsW[sb];
fRMS[sb][j] = TMath::Sqrt(fSumSq[sb][j]/fNEventsW[sb] - fMeans[sb][j]*fMeans[sb][j]);
}
}
fStatisticsIsValid = kTRUE;
}
return;
}
Int_t TMVA::BinarySearchTree::SearchVolumeWithMaxLimit( Volume *volume, std::vector<const BinarySearchTreeNode*>* events,
Int_t max_points )
{
if (this->GetRoot() == NULL) return 0;
std::queue< pair< const BinarySearchTreeNode*, Int_t > > queue;
std::pair< const BinarySearchTreeNode*, Int_t > st = make_pair( (const BinarySearchTreeNode*)this->GetRoot(), 0 );
queue.push( st );
Int_t count = 0;
while ( !queue.empty() ) {
st = queue.front(); queue.pop();
if (count == max_points)
return count;
if (InVolume( st.first->GetEventV(), volume )) {
count++;
if (NULL != events) events->push_back( st.first );
}
Bool_t tl, tr;
Int_t d = st.second;
if ( d == Int_t(this->GetPeriode()) ) d = 0;
if (d != st.first->GetSelector()) {
fLogger << kFATAL << "<SearchVolume> selector in Searchvolume "
<< d << " != " << "node "<< st.first->GetSelector() << Endl;
}
tl = (*(volume->fLower))[d] < st.first->GetEventV()[d] && st.first->GetLeft() != NULL;
tr = (*(volume->fUpper))[d] >= st.first->GetEventV()[d] && st.first->GetRight() != NULL;
if (tl) queue.push( make_pair( (const BinarySearchTreeNode*)st.first->GetLeft(), d+1 ) );
if (tr) queue.push( make_pair( (const BinarySearchTreeNode*)st.first->GetRight(), d+1 ) );
}
return count;
}
Last change: Wed Jun 25 08:48:05 2008
Last generated: 2008-06-25 08:48
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.