// @(#)root/tmva $Id$
// Author: Tancredi Carli, Dominik Dannheim, Alexander Voigt

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Classes: PDEFoamTargetDensity                                                  *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      The TFDSITR 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 PDEFoamTargetDensity::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) 2008, 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)                                          *
 **********************************************************************************/

//_____________________________________________________________________
//
// PDEFoamTargetDensity
//
// This is a concrete implementation of PDEFoam.  Density(...)
// estimates the target density (target number: fTarget) at a given
// phase-space point using range-searching.
// _____________________________________________________________________

#include <cmath>

#ifndef ROOT_TMVA_PDEFoamTargetDensity
#include "TMVA/PDEFoamTargetDensity.h"
#endif

ClassImp(TMVA::PDEFoamTargetDensity)

//_____________________________________________________________________
TMVA::PDEFoamTargetDensity::PDEFoamTargetDensity()
   : PDEFoamDensityBase()
   , fTarget(0)
{}

//_____________________________________________________________________
TMVA::PDEFoamTargetDensity::PDEFoamTargetDensity(std::vector<Double_t> box, UInt_t target)
   : PDEFoamDensityBase(box)
   , fTarget(target)
{
   // User construcor
   //
   // Parameters:
   //
   // - box - size of the range-searching box (n-dimensional
   //   std::vector)
   //
   // - target - the target number to calculate the density for
}

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

//_____________________________________________________________________
Double_t TMVA::PDEFoamTargetDensity::Density(std::vector<Double_t> &xev, Double_t &event_density)
{
   // This function is needed during the foam buildup.  It returns the
   // average target value within the range-searching box at point
   // xev, divided by volume (specified by fBox).
   //
   // Parameters:
   //
   // - xev - event vector (in [fXmin,fXmax]) to place the box at
   //
   // - event_density - here the event density is stored
   //
   // Returns:
   //
   // Average target value in the range-searching volume at point
   // 'xev', divided by the box volume.

   if (!fBst)
      Log() << kFATAL << "<PDEFoamTargetDensity::Density()> Binary tree not found!" << Endl;

   //create volume around point to be found
   std::vector<Double_t> lb(GetBox().size());
   std::vector<Double_t> ub(GetBox().size());

   // probevolume relative to hypercube with edge length 1:
   const Double_t probevolume_inv = 1.0 / GetBoxVolume();

   // set upper and lower bound for search volume
   for (UInt_t idim = 0; idim < GetBox().size(); ++idim) {
      lb[idim] = xev[idim] - GetBox().at(idim) / 2.0;
      ub[idim] = xev[idim] + GetBox().at(idim) / 2.0;
   }

   TMVA::Volume volume(&lb, &ub);                        // volume to search in
   std::vector<const TMVA::BinarySearchTreeNode*> nodes; // BST nodes found

   // do range searching
   const Double_t sumOfWeights = fBst->SearchVolume(&volume, &nodes);

   // store density based on total number of events
   event_density = nodes.size() * probevolume_inv;

   Double_t n_tar = 0;           // number of target events found
   // now sum over all nodes->GetTarget(0);
   for (std::vector<const TMVA::BinarySearchTreeNode*>::const_iterator it = nodes.begin();
        it != nodes.end(); ++it) {
      n_tar += ((*it)->GetTargets()).at(fTarget) * ((*it)->GetWeight());
   }

   // return:  (n_tar/n_total) / (cell_volume)
   return (n_tar / (sumOfWeights + 0.1)) * probevolume_inv;
}
 PDEFoamTargetDensity.cxx:1
 PDEFoamTargetDensity.cxx:2
 PDEFoamTargetDensity.cxx:3
 PDEFoamTargetDensity.cxx:4
 PDEFoamTargetDensity.cxx:5
 PDEFoamTargetDensity.cxx:6
 PDEFoamTargetDensity.cxx:7
 PDEFoamTargetDensity.cxx:8
 PDEFoamTargetDensity.cxx:9
 PDEFoamTargetDensity.cxx:10
 PDEFoamTargetDensity.cxx:11
 PDEFoamTargetDensity.cxx:12
 PDEFoamTargetDensity.cxx:13
 PDEFoamTargetDensity.cxx:14
 PDEFoamTargetDensity.cxx:15
 PDEFoamTargetDensity.cxx:16
 PDEFoamTargetDensity.cxx:17
 PDEFoamTargetDensity.cxx:18
 PDEFoamTargetDensity.cxx:19
 PDEFoamTargetDensity.cxx:20
 PDEFoamTargetDensity.cxx:21
 PDEFoamTargetDensity.cxx:22
 PDEFoamTargetDensity.cxx:23
 PDEFoamTargetDensity.cxx:24
 PDEFoamTargetDensity.cxx:25
 PDEFoamTargetDensity.cxx:26
 PDEFoamTargetDensity.cxx:27
 PDEFoamTargetDensity.cxx:28
 PDEFoamTargetDensity.cxx:29
 PDEFoamTargetDensity.cxx:30
 PDEFoamTargetDensity.cxx:31
 PDEFoamTargetDensity.cxx:32
 PDEFoamTargetDensity.cxx:33
 PDEFoamTargetDensity.cxx:34
 PDEFoamTargetDensity.cxx:35
 PDEFoamTargetDensity.cxx:36
 PDEFoamTargetDensity.cxx:37
 PDEFoamTargetDensity.cxx:38
 PDEFoamTargetDensity.cxx:39
 PDEFoamTargetDensity.cxx:40
 PDEFoamTargetDensity.cxx:41
 PDEFoamTargetDensity.cxx:42
 PDEFoamTargetDensity.cxx:43
 PDEFoamTargetDensity.cxx:44
 PDEFoamTargetDensity.cxx:45
 PDEFoamTargetDensity.cxx:46
 PDEFoamTargetDensity.cxx:47
 PDEFoamTargetDensity.cxx:48
 PDEFoamTargetDensity.cxx:49
 PDEFoamTargetDensity.cxx:50
 PDEFoamTargetDensity.cxx:51
 PDEFoamTargetDensity.cxx:52
 PDEFoamTargetDensity.cxx:53
 PDEFoamTargetDensity.cxx:54
 PDEFoamTargetDensity.cxx:55
 PDEFoamTargetDensity.cxx:56
 PDEFoamTargetDensity.cxx:57
 PDEFoamTargetDensity.cxx:58
 PDEFoamTargetDensity.cxx:59
 PDEFoamTargetDensity.cxx:60
 PDEFoamTargetDensity.cxx:61
 PDEFoamTargetDensity.cxx:62
 PDEFoamTargetDensity.cxx:63
 PDEFoamTargetDensity.cxx:64
 PDEFoamTargetDensity.cxx:65
 PDEFoamTargetDensity.cxx:66
 PDEFoamTargetDensity.cxx:67
 PDEFoamTargetDensity.cxx:68
 PDEFoamTargetDensity.cxx:69
 PDEFoamTargetDensity.cxx:70
 PDEFoamTargetDensity.cxx:71
 PDEFoamTargetDensity.cxx:72
 PDEFoamTargetDensity.cxx:73
 PDEFoamTargetDensity.cxx:74
 PDEFoamTargetDensity.cxx:75
 PDEFoamTargetDensity.cxx:76
 PDEFoamTargetDensity.cxx:77
 PDEFoamTargetDensity.cxx:78
 PDEFoamTargetDensity.cxx:79
 PDEFoamTargetDensity.cxx:80
 PDEFoamTargetDensity.cxx:81
 PDEFoamTargetDensity.cxx:82
 PDEFoamTargetDensity.cxx:83
 PDEFoamTargetDensity.cxx:84
 PDEFoamTargetDensity.cxx:85
 PDEFoamTargetDensity.cxx:86
 PDEFoamTargetDensity.cxx:87
 PDEFoamTargetDensity.cxx:88
 PDEFoamTargetDensity.cxx:89
 PDEFoamTargetDensity.cxx:90
 PDEFoamTargetDensity.cxx:91
 PDEFoamTargetDensity.cxx:92
 PDEFoamTargetDensity.cxx:93
 PDEFoamTargetDensity.cxx:94
 PDEFoamTargetDensity.cxx:95
 PDEFoamTargetDensity.cxx:96
 PDEFoamTargetDensity.cxx:97
 PDEFoamTargetDensity.cxx:98
 PDEFoamTargetDensity.cxx:99
 PDEFoamTargetDensity.cxx:100
 PDEFoamTargetDensity.cxx:101
 PDEFoamTargetDensity.cxx:102
 PDEFoamTargetDensity.cxx:103
 PDEFoamTargetDensity.cxx:104
 PDEFoamTargetDensity.cxx:105
 PDEFoamTargetDensity.cxx:106
 PDEFoamTargetDensity.cxx:107
 PDEFoamTargetDensity.cxx:108
 PDEFoamTargetDensity.cxx:109
 PDEFoamTargetDensity.cxx:110
 PDEFoamTargetDensity.cxx:111
 PDEFoamTargetDensity.cxx:112
 PDEFoamTargetDensity.cxx:113
 PDEFoamTargetDensity.cxx:114
 PDEFoamTargetDensity.cxx:115
 PDEFoamTargetDensity.cxx:116
 PDEFoamTargetDensity.cxx:117
 PDEFoamTargetDensity.cxx:118
 PDEFoamTargetDensity.cxx:119
 PDEFoamTargetDensity.cxx:120
 PDEFoamTargetDensity.cxx:121
 PDEFoamTargetDensity.cxx:122
 PDEFoamTargetDensity.cxx:123
 PDEFoamTargetDensity.cxx:124
 PDEFoamTargetDensity.cxx:125
 PDEFoamTargetDensity.cxx:126
 PDEFoamTargetDensity.cxx:127
 PDEFoamTargetDensity.cxx:128
 PDEFoamTargetDensity.cxx:129
 PDEFoamTargetDensity.cxx:130
 PDEFoamTargetDensity.cxx:131
 PDEFoamTargetDensity.cxx:132