// @(#)root/tmva $Id$
// Author: Alexander Voigt

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Classes: PDEFoamDecisionTreeDensity                                            *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      This class provides an interface between the Binary search tree           *
 *      and the PDEFoam object.  In order to build-up the foam one needs to       *
 *      calculate the density of events at a given point (sampling during         *
 *      Foam build-up).  The function PDEFoamDecisionTreeDensity::Density()       *
 *      does this job. It uses a binary search tree, filled with training         *
 *      events, in order to provide this density.                                 *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Tancredi Carli   - CERN, Switzerland                                      *
 *      Dominik Dannheim - CERN, Switzerland                                      *
 *      S. Jadach        - Institute of Nuclear Physics, Cracow, Poland           *
 *      Alexander Voigt  - TU Dresden, Germany                                    *
 *      Peter Speckmayer - CERN, Switzerland                                      *
 *                                                                                *
 * Copyright (c) 2010:                                                            *
 *      CERN, Switzerland                                                         *
 *      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)                                          *
 **********************************************************************************/

//_____________________________________________________________________
//
// PDEFoamDecisionTreeDensity
//
// This is a concrete implementation of PDEFoam.  The Density(...)
// function returns allways 0.  The function FillHistograms() is
// added, which returns all events in a given TMVA::Volume.
// _____________________________________________________________________

#include <limits>

#ifndef ROOT_TMVA_PDEFoamDecisionTreeDensity
#include "TMVA/PDEFoamDecisionTreeDensity.h"
#endif

ClassImp(TMVA::PDEFoamDecisionTreeDensity)

//_____________________________________________________________________
TMVA::PDEFoamDecisionTreeDensity::PDEFoamDecisionTreeDensity()
   : PDEFoamDensityBase()
   , fClass(0)
{}

//_____________________________________________________________________
TMVA::PDEFoamDecisionTreeDensity::PDEFoamDecisionTreeDensity(std::vector<Double_t> box, UInt_t cls)
   : PDEFoamDensityBase(box)
   , fClass(cls)
{
   // User construcor:
   //
   // Parameters:
   //
   // - box - size of the range-searching box (n-dimensional
   //   std::vector)
   //
   // - cls - event class used for the range-searching
}

//_____________________________________________________________________
TMVA::PDEFoamDecisionTreeDensity::PDEFoamDecisionTreeDensity(const PDEFoamDecisionTreeDensity &distr)
   : PDEFoamDensityBase(distr)
   , fClass(distr.fClass)
{
   // Copy constructor
}

//_____________________________________________________________________
Double_t TMVA::PDEFoamDecisionTreeDensity::Density(std::vector<Double_t>& /* Xarg */,
                                                   Double_t&              /* event_density */)
{
   // This function is not used in the decision tree like PDEFoam,
   // instead FillHist() is used.
   return 0;
}

//_____________________________________________________________________
void TMVA::PDEFoamDecisionTreeDensity::FillHistograms(TMVA::Volume &volume, std::vector<TH1D*> &hsig,
                                                      std::vector<TH1D*> &hbkg, std::vector<TH1D*> &hsig_unw,
                                                      std::vector<TH1D*> &hbkg_unw)
{
   // Fill the given histograms with signal and background events,
   // which are found in the volume.
   //
   // Parameters:
   //
   // - volume - volume box to search in
   //
   // - hsig, hbkg, hsig_unw, hbkg_unw - histograms with weighted and
   //   unweighted signal and background events

   // sanity check
   if (hsig.size() != volume.fLower->size()
       || hbkg.size() != volume.fLower->size()
       || hsig_unw.size() != volume.fLower->size()
       || hbkg_unw.size() != volume.fLower->size())
      Log() << kFATAL << "<PDEFoamDistr::FillHistograms> Edge histograms have wrong size!" << Endl;

   // check histograms
   for (UInt_t idim = 0; idim < hsig.size(); ++idim) {
      if (!hsig.at(idim) || !hbkg.at(idim) ||
          !hsig_unw.at(idim) || !hbkg_unw.at(idim))
         Log() << kFATAL << "<PDEFoamDistr::FillHist> Histograms not initialized!" << Endl;
   }

   // BST nodes found in volume
   std::vector<const TMVA::BinarySearchTreeNode*> nodes;

   // do range searching
   fBst->SearchVolume(&volume, &nodes);

   // calc xmin and xmax of events found in cell
   std::vector<Float_t> xmin(volume.fLower->size(), std::numeric_limits<float>::max());
   std::vector<Float_t> xmax(volume.fLower->size(), -std::numeric_limits<float>::max());
   for (std::vector<const TMVA::BinarySearchTreeNode*>::const_iterator it = nodes.begin();
        it != nodes.end(); ++it) {
      std::vector<Float_t> ev = (*it)->GetEventV();
      for (UInt_t idim = 0; idim < xmin.size(); ++idim) {
         if (ev.at(idim) < xmin.at(idim))  xmin.at(idim) = ev.at(idim);
         if (ev.at(idim) > xmax.at(idim))  xmax.at(idim) = ev.at(idim);
      }
   }

   // reset histogram ranges to xmin, xmax found in volume
   for (UInt_t idim = 0; idim < hsig.size(); ++idim) {
      hsig.at(idim)->GetXaxis()->SetLimits(xmin.at(idim), xmax.at(idim));
      hbkg.at(idim)->GetXaxis()->SetLimits(xmin.at(idim), xmax.at(idim));
      hsig_unw.at(idim)->GetXaxis()->SetLimits(xmin.at(idim), xmax.at(idim));
      hbkg_unw.at(idim)->GetXaxis()->SetLimits(xmin.at(idim), xmax.at(idim));
      hsig.at(idim)->Reset();
      hbkg.at(idim)->Reset();
      hsig_unw.at(idim)->Reset();
      hbkg_unw.at(idim)->Reset();
   }

   // fill histograms with events found
   for (std::vector<const TMVA::BinarySearchTreeNode*>::const_iterator it = nodes.begin();
        it != nodes.end(); ++it) {
      std::vector<Float_t> ev = (*it)->GetEventV();
      Float_t              wt = (*it)->GetWeight();
      for (UInt_t idim = 0; idim < ev.size(); ++idim) {
         if ((*it)->GetClass() == fClass) {
            hsig.at(idim)->Fill(ev.at(idim), wt);
            hsig_unw.at(idim)->Fill(ev.at(idim), 1);
         } else {
            hbkg.at(idim)->Fill(ev.at(idim), wt);
            hbkg_unw.at(idim)->Fill(ev.at(idim), 1);
         }
      }
   }
}
 PDEFoamDecisionTreeDensity.cxx:1
 PDEFoamDecisionTreeDensity.cxx:2
 PDEFoamDecisionTreeDensity.cxx:3
 PDEFoamDecisionTreeDensity.cxx:4
 PDEFoamDecisionTreeDensity.cxx:5
 PDEFoamDecisionTreeDensity.cxx:6
 PDEFoamDecisionTreeDensity.cxx:7
 PDEFoamDecisionTreeDensity.cxx:8
 PDEFoamDecisionTreeDensity.cxx:9
 PDEFoamDecisionTreeDensity.cxx:10
 PDEFoamDecisionTreeDensity.cxx:11
 PDEFoamDecisionTreeDensity.cxx:12
 PDEFoamDecisionTreeDensity.cxx:13
 PDEFoamDecisionTreeDensity.cxx:14
 PDEFoamDecisionTreeDensity.cxx:15
 PDEFoamDecisionTreeDensity.cxx:16
 PDEFoamDecisionTreeDensity.cxx:17
 PDEFoamDecisionTreeDensity.cxx:18
 PDEFoamDecisionTreeDensity.cxx:19
 PDEFoamDecisionTreeDensity.cxx:20
 PDEFoamDecisionTreeDensity.cxx:21
 PDEFoamDecisionTreeDensity.cxx:22
 PDEFoamDecisionTreeDensity.cxx:23
 PDEFoamDecisionTreeDensity.cxx:24
 PDEFoamDecisionTreeDensity.cxx:25
 PDEFoamDecisionTreeDensity.cxx:26
 PDEFoamDecisionTreeDensity.cxx:27
 PDEFoamDecisionTreeDensity.cxx:28
 PDEFoamDecisionTreeDensity.cxx:29
 PDEFoamDecisionTreeDensity.cxx:30
 PDEFoamDecisionTreeDensity.cxx:31
 PDEFoamDecisionTreeDensity.cxx:32
 PDEFoamDecisionTreeDensity.cxx:33
 PDEFoamDecisionTreeDensity.cxx:34
 PDEFoamDecisionTreeDensity.cxx:35
 PDEFoamDecisionTreeDensity.cxx:36
 PDEFoamDecisionTreeDensity.cxx:37
 PDEFoamDecisionTreeDensity.cxx:38
 PDEFoamDecisionTreeDensity.cxx:39
 PDEFoamDecisionTreeDensity.cxx:40
 PDEFoamDecisionTreeDensity.cxx:41
 PDEFoamDecisionTreeDensity.cxx:42
 PDEFoamDecisionTreeDensity.cxx:43
 PDEFoamDecisionTreeDensity.cxx:44
 PDEFoamDecisionTreeDensity.cxx:45
 PDEFoamDecisionTreeDensity.cxx:46
 PDEFoamDecisionTreeDensity.cxx:47
 PDEFoamDecisionTreeDensity.cxx:48
 PDEFoamDecisionTreeDensity.cxx:49
 PDEFoamDecisionTreeDensity.cxx:50
 PDEFoamDecisionTreeDensity.cxx:51
 PDEFoamDecisionTreeDensity.cxx:52
 PDEFoamDecisionTreeDensity.cxx:53
 PDEFoamDecisionTreeDensity.cxx:54
 PDEFoamDecisionTreeDensity.cxx:55
 PDEFoamDecisionTreeDensity.cxx:56
 PDEFoamDecisionTreeDensity.cxx:57
 PDEFoamDecisionTreeDensity.cxx:58
 PDEFoamDecisionTreeDensity.cxx:59
 PDEFoamDecisionTreeDensity.cxx:60
 PDEFoamDecisionTreeDensity.cxx:61
 PDEFoamDecisionTreeDensity.cxx:62
 PDEFoamDecisionTreeDensity.cxx:63
 PDEFoamDecisionTreeDensity.cxx:64
 PDEFoamDecisionTreeDensity.cxx:65
 PDEFoamDecisionTreeDensity.cxx:66
 PDEFoamDecisionTreeDensity.cxx:67
 PDEFoamDecisionTreeDensity.cxx:68
 PDEFoamDecisionTreeDensity.cxx:69
 PDEFoamDecisionTreeDensity.cxx:70
 PDEFoamDecisionTreeDensity.cxx:71
 PDEFoamDecisionTreeDensity.cxx:72
 PDEFoamDecisionTreeDensity.cxx:73
 PDEFoamDecisionTreeDensity.cxx:74
 PDEFoamDecisionTreeDensity.cxx:75
 PDEFoamDecisionTreeDensity.cxx:76
 PDEFoamDecisionTreeDensity.cxx:77
 PDEFoamDecisionTreeDensity.cxx:78
 PDEFoamDecisionTreeDensity.cxx:79
 PDEFoamDecisionTreeDensity.cxx:80
 PDEFoamDecisionTreeDensity.cxx:81
 PDEFoamDecisionTreeDensity.cxx:82
 PDEFoamDecisionTreeDensity.cxx:83
 PDEFoamDecisionTreeDensity.cxx:84
 PDEFoamDecisionTreeDensity.cxx:85
 PDEFoamDecisionTreeDensity.cxx:86
 PDEFoamDecisionTreeDensity.cxx:87
 PDEFoamDecisionTreeDensity.cxx:88
 PDEFoamDecisionTreeDensity.cxx:89
 PDEFoamDecisionTreeDensity.cxx:90
 PDEFoamDecisionTreeDensity.cxx:91
 PDEFoamDecisionTreeDensity.cxx:92
 PDEFoamDecisionTreeDensity.cxx:93
 PDEFoamDecisionTreeDensity.cxx:94
 PDEFoamDecisionTreeDensity.cxx:95
 PDEFoamDecisionTreeDensity.cxx:96
 PDEFoamDecisionTreeDensity.cxx:97
 PDEFoamDecisionTreeDensity.cxx:98
 PDEFoamDecisionTreeDensity.cxx:99
 PDEFoamDecisionTreeDensity.cxx:100
 PDEFoamDecisionTreeDensity.cxx:101
 PDEFoamDecisionTreeDensity.cxx:102
 PDEFoamDecisionTreeDensity.cxx:103
 PDEFoamDecisionTreeDensity.cxx:104
 PDEFoamDecisionTreeDensity.cxx:105
 PDEFoamDecisionTreeDensity.cxx:106
 PDEFoamDecisionTreeDensity.cxx:107
 PDEFoamDecisionTreeDensity.cxx:108
 PDEFoamDecisionTreeDensity.cxx:109
 PDEFoamDecisionTreeDensity.cxx:110
 PDEFoamDecisionTreeDensity.cxx:111
 PDEFoamDecisionTreeDensity.cxx:112
 PDEFoamDecisionTreeDensity.cxx:113
 PDEFoamDecisionTreeDensity.cxx:114
 PDEFoamDecisionTreeDensity.cxx:115
 PDEFoamDecisionTreeDensity.cxx:116
 PDEFoamDecisionTreeDensity.cxx:117
 PDEFoamDecisionTreeDensity.cxx:118
 PDEFoamDecisionTreeDensity.cxx:119
 PDEFoamDecisionTreeDensity.cxx:120
 PDEFoamDecisionTreeDensity.cxx:121
 PDEFoamDecisionTreeDensity.cxx:122
 PDEFoamDecisionTreeDensity.cxx:123
 PDEFoamDecisionTreeDensity.cxx:124
 PDEFoamDecisionTreeDensity.cxx:125
 PDEFoamDecisionTreeDensity.cxx:126
 PDEFoamDecisionTreeDensity.cxx:127
 PDEFoamDecisionTreeDensity.cxx:128
 PDEFoamDecisionTreeDensity.cxx:129
 PDEFoamDecisionTreeDensity.cxx:130
 PDEFoamDecisionTreeDensity.cxx:131
 PDEFoamDecisionTreeDensity.cxx:132
 PDEFoamDecisionTreeDensity.cxx:133
 PDEFoamDecisionTreeDensity.cxx:134
 PDEFoamDecisionTreeDensity.cxx:135
 PDEFoamDecisionTreeDensity.cxx:136
 PDEFoamDecisionTreeDensity.cxx:137
 PDEFoamDecisionTreeDensity.cxx:138
 PDEFoamDecisionTreeDensity.cxx:139
 PDEFoamDecisionTreeDensity.cxx:140
 PDEFoamDecisionTreeDensity.cxx:141
 PDEFoamDecisionTreeDensity.cxx:142
 PDEFoamDecisionTreeDensity.cxx:143
 PDEFoamDecisionTreeDensity.cxx:144
 PDEFoamDecisionTreeDensity.cxx:145
 PDEFoamDecisionTreeDensity.cxx:146
 PDEFoamDecisionTreeDensity.cxx:147
 PDEFoamDecisionTreeDensity.cxx:148
 PDEFoamDecisionTreeDensity.cxx:149
 PDEFoamDecisionTreeDensity.cxx:150
 PDEFoamDecisionTreeDensity.cxx:151
 PDEFoamDecisionTreeDensity.cxx:152
 PDEFoamDecisionTreeDensity.cxx:153
 PDEFoamDecisionTreeDensity.cxx:154
 PDEFoamDecisionTreeDensity.cxx:155
 PDEFoamDecisionTreeDensity.cxx:156
 PDEFoamDecisionTreeDensity.cxx:157
 PDEFoamDecisionTreeDensity.cxx:158
 PDEFoamDecisionTreeDensity.cxx:159
 PDEFoamDecisionTreeDensity.cxx:160
 PDEFoamDecisionTreeDensity.cxx:161
 PDEFoamDecisionTreeDensity.cxx:162
 PDEFoamDecisionTreeDensity.cxx:163