#include <cmath>
#include <limits>
#ifndef ROOT_TMath
#include "TMath.h"
#endif
#ifndef ROOT_TMVA_PDEFoamDistr
#include "TMVA/PDEFoamDistr.h"
#endif
ClassImp(TMVA::PDEFoamDistr)
TMVA::PDEFoamDistr::PDEFoamDistr()
: TObject(),
fPDEFoam(NULL),
fBst(NULL),
fDensityCalc(kEVENT_DENSITY),
fLogger( new MsgLogger("PDEFoamDistr"))
{}
TMVA::PDEFoamDistr::~PDEFoamDistr()
{
if (fBst) delete fBst;
delete fLogger;
}
TMVA::PDEFoamDistr::PDEFoamDistr(const PDEFoamDistr &distr)
: TObject(),
fPDEFoam (distr.fPDEFoam),
fBst (distr.fBst),
fDensityCalc (kEVENT_DENSITY),
fLogger( new MsgLogger("PDEFoamDistr"))
{
Log() << kFATAL << "COPY CONSTRUCTOR NOT IMPLEMENTED" << Endl;
}
void TMVA::PDEFoamDistr::Initialize()
{
if (!GetPDEFoam())
Log() << kFATAL << "<PDEFoamDistr::Initialize()> Pointer to owner not set!" << Endl;
if (fBst) delete fBst;
fBst = new TMVA::BinarySearchTree();
if (!fBst){
Log() << kFATAL << "<PDEFoamDistr::Initialize> "
<< "ERROR: an not create binary tree !" << Endl;
}
fBst->SetPeriode(GetPDEFoam()->GetTotDim());
}
void TMVA::PDEFoamDistr::FillBinarySearchTree( const Event* ev, EFoamType ft, Bool_t NoNegWeights )
{
if((NoNegWeights && ev->GetWeight()<=0) || ev->GetOriginalWeight()==0)
return;
TMVA::Event *event = new TMVA::Event(*ev);
if (ft==kMultiTarget){
std::vector<Float_t> targets = ev->GetTargets();
for (UInt_t i = 0; i < targets.size(); i++)
event->SetVal(i+ev->GetValues().size(), targets.at(i));
event->GetTargets().clear();
}
fBst->Insert(event);
delete event;
}
Double_t TMVA::PDEFoamDistr::Density( Double_t *Xarg, Double_t &event_density )
{
if (!GetPDEFoam())
Log() << kFATAL << "<PDEFoamDistr::Density()> Pointer to owner not set!" << Endl;
if (!fBst)
Log() << kFATAL << "<PDEFoamDistr::Density()> Binary tree not found!"<< Endl;
Int_t Dim = GetPDEFoam()->GetTotDim();
Float_t VolFrac = GetPDEFoam()->GetVolumeFraction();
for (Int_t idim=0; idim<Dim; idim++)
Xarg[idim] = GetPDEFoam()->VarTransformInvers(idim, Xarg[idim]);
std::vector<Double_t> lb(Dim);
std::vector<Double_t> ub(Dim);
const Double_t probevolume_inv = std::pow((VolFrac/2), Dim);
for (Int_t idim = 0; idim < Dim; idim++) {
Double_t volsize=(GetPDEFoam()->GetXmax(idim)
- GetPDEFoam()->GetXmin(idim)) / VolFrac;
lb[idim] = Xarg[idim] - volsize;
ub[idim] = Xarg[idim] + volsize;
}
TMVA::Volume volume(&lb, &ub);
std::vector<const TMVA::BinarySearchTreeNode*> nodes;
fBst->SearchVolume(&volume, &nodes);
const UInt_t count = nodes.size();
event_density = count * probevolume_inv;
Double_t weighted_count = 0.;
for (UInt_t j=0; j<nodes.size(); j++)
weighted_count += (nodes.at(j))->GetWeight();
if (FillDiscriminator()){
Double_t N_sig = 0;
for (UInt_t j=0; j<count; j++){
if (nodes.at(j)->IsSignal()) N_sig += nodes.at(j)->GetWeight();
}
return (N_sig/(weighted_count+0.1))*probevolume_inv;
}
else if (FillTarget0()){
Double_t N_tar = 0;
for (UInt_t j=0; j<count; j++) {
N_tar += ((nodes.at(j))->GetTargets()).at(0) * ((nodes.at(j))->GetWeight());
}
return (N_tar/(weighted_count+0.1))*probevolume_inv;
}
return ((weighted_count+0.1)*probevolume_inv);
}
void TMVA::PDEFoamDistr::FillHist(PDEFoamCell* cell, std::vector<TH1F*> &hsig, std::vector<TH1F*> &hbkg, std::vector<TH1F*> &hsig_unw, std::vector<TH1F*> &hbkg_unw)
{
if (!GetPDEFoam())
Log() << kFATAL << "<PDEFoamDistr::FillHist> Pointer to owner not set!" << Endl;
Int_t Dim = GetPDEFoam()->GetTotDim();
if (!cell)
Log() << kFATAL << "<PDEFoamDistr::FillHist> Null pointer for cell given!" << Endl;
if (Int_t(hsig.size()) != Dim || Int_t(hbkg.size()) != Dim ||
Int_t(hsig_unw.size()) != Dim || Int_t(hbkg_unw.size()) != Dim)
Log() << kFATAL << "<PDEFoamDistr::FillHist> Edge histograms have wrong size!" << Endl;
for (Int_t idim=0; idim<Dim; idim++) {
if (!hsig.at(idim) || !hbkg.at(idim) ||
!hsig_unw.at(idim) || !hbkg_unw.at(idim))
Log() << kFATAL << "<PDEFoamDistr::FillHist> Histogram not initialized!" << Endl;
}
PDEFoamVect cellSize(Dim);
PDEFoamVect cellPosi(Dim);
cell->GetHcub(cellPosi, cellSize);
std::vector<Double_t> lb(Dim);
std::vector<Double_t> ub(Dim);
for (Int_t idim = 0; idim < Dim; idim++) {
lb[idim] = GetPDEFoam()->VarTransformInvers(idim, cellPosi[idim] - std::numeric_limits<float>::epsilon());
ub[idim] = GetPDEFoam()->VarTransformInvers(idim, cellPosi[idim] + cellSize[idim] + std::numeric_limits<float>::epsilon());
}
TMVA::Volume volume(&lb, &ub);
std::vector<const TMVA::BinarySearchTreeNode*> nodes;
fBst->SearchVolume(&volume, &nodes);
std::vector<Float_t> xmin(Dim, std::numeric_limits<float>::max());
std::vector<Float_t> xmax(Dim, -std::numeric_limits<float>::max());
for (UInt_t iev=0; iev<nodes.size(); iev++) {
std::vector<Float_t> ev = nodes.at(iev)->GetEventV();
for (Int_t idim=0; idim<Dim; 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);
}
}
for (Int_t idim=0; idim<Dim; idim++) {
hsig.at(idim)->GetXaxis()->SetLimits(GetPDEFoam()->VarTransform(idim,xmin.at(idim)),
GetPDEFoam()->VarTransform(idim,xmax.at(idim)));
hbkg.at(idim)->GetXaxis()->SetLimits(GetPDEFoam()->VarTransform(idim,xmin.at(idim)),
GetPDEFoam()->VarTransform(idim,xmax.at(idim)));
hsig_unw.at(idim)->GetXaxis()->SetLimits(GetPDEFoam()->VarTransform(idim,xmin.at(idim)),
GetPDEFoam()->VarTransform(idim,xmax.at(idim)));
hbkg_unw.at(idim)->GetXaxis()->SetLimits(GetPDEFoam()->VarTransform(idim,xmin.at(idim)),
GetPDEFoam()->VarTransform(idim,xmax.at(idim)));
hsig.at(idim)->Reset();
hbkg.at(idim)->Reset();
hsig_unw.at(idim)->Reset();
hbkg_unw.at(idim)->Reset();
}
for (UInt_t iev=0; iev<nodes.size(); iev++) {
std::vector<Float_t> ev = nodes.at(iev)->GetEventV();
Float_t wt = nodes.at(iev)->GetWeight();
Bool_t signal = nodes.at(iev)->IsSignal();
for (Int_t idim=0; idim<Dim; idim++) {
if (signal) {
hsig.at(idim)->Fill(GetPDEFoam()->VarTransform(idim,ev.at(idim)), wt);
hsig_unw.at(idim)->Fill(GetPDEFoam()->VarTransform(idim,ev.at(idim)), 1);
} else {
hbkg.at(idim)->Fill(GetPDEFoam()->VarTransform(idim,ev.at(idim)), wt);
hbkg_unw.at(idim)->Fill(GetPDEFoam()->VarTransform(idim,ev.at(idim)), 1);
}
}
}
}