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

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Classes: PDEFoamCell                                                           *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Objects of this class are hyperrectangular cells organized in             *
 *      the binary tree. Special algoritm for encoding relalive                   *
 *      positioning of the cells saves total memory allocation needed             *
 *      for the system of cells.                                                  *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      S. Jadach        - Institute of Nuclear Physics, Cracow, Poland           *
 *      Tancredi Carli   - CERN, Switzerland                                      *
 *      Dominik Dannheim - CERN, Switzerland                                      *
 *      Alexander Voigt  - TU Dresden, Germany                                    *
 *                                                                                *
 * Copyright (c) 2008:                                                            *
 *      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)                                          *
 **********************************************************************************/

#include <iostream>
#include <ostream>

#ifndef ROOT_TMVA_PDEFoamCell
#include "TMVA/PDEFoamCell.h"
#endif

using namespace std;

ClassImp(TMVA::PDEFoamCell)

//_____________________________________________________________________
TMVA::PDEFoamCell::PDEFoamCell()
   : TObject(),
     fDim(0),
     fSerial(0),
     fStatus(1),
     fParent(0),
     fDaught0(0),
     fDaught1(0),
     fXdiv(0.0),
     fBest(0),
     fVolume(0.0),
     fIntegral(0.0),
     fDrive(0.0),
     fElement(0)
{
   // Default constructor for streamer
}

//_____________________________________________________________________
TMVA::PDEFoamCell::PDEFoamCell(Int_t kDim)
   : TObject(),
     fDim(kDim),
     fSerial(0),
     fStatus(1),
     fParent(0),
     fDaught0(0),
     fDaught1(0),
     fXdiv(0.0),
     fBest(0),
     fVolume(0.0),
     fIntegral(0.0),
     fDrive(0.0),
     fElement(0)
{
   // User constructor allocating single empty Cell
   if ( kDim <= 0 )
      Error( "PDEFoamCell", "Dimension has to be >0" );
}

//_____________________________________________________________________
TMVA::PDEFoamCell::PDEFoamCell(const PDEFoamCell &cell)
   : TObject(),
     fDim     (cell.fDim),
     fSerial  (cell.fSerial),
     fStatus  (cell.fStatus),
     fParent  (cell.fParent),
     fDaught0 (cell.fDaught0),
     fDaught1 (cell.fDaught1),
     fXdiv    (cell.fXdiv),
     fBest    (cell.fBest),
     fVolume  (cell.fVolume),
     fIntegral(cell.fIntegral),
     fDrive   (cell.fDrive),
     fElement (cell.fElement)
{
   // Copy constructor
   Error( "PDEFoamCell", "COPY CONSTRUCTOR NOT IMPLEMENTED" );
}

//_____________________________________________________________________
TMVA::PDEFoamCell::~PDEFoamCell()
{
   // Destructor
}

//_____________________________________________________________________
void TMVA::PDEFoamCell::Fill(Int_t status, PDEFoamCell *parent, PDEFoamCell *daugh1, PDEFoamCell *daugh2)
{
   // Fills in certain data into newly allocated cell

   fStatus  = status;
   fParent  = parent;
   fDaught0 = daugh1;
   fDaught1 = daugh2;
}

////////////////////////////////////////////////////////////////////////////////
//              GETTERS/SETTERS
////////////////////////////////////////////////////////////////////////////////

//_____________________________________________________________________
void    TMVA::PDEFoamCell::GetHcub( PDEFoamVect &cellPosi, PDEFoamVect &cellSize)  const
{
   // Provides size and position of the cell
   // These parameter are calculated by analyzing information in all parents
   // cells up to the root cell. It takes time but saves memory.
   if(fDim<1) return;
   const PDEFoamCell *pCell,*dCell;
   cellPosi = 0.0; cellSize=1.0; // load all components
   dCell = this;
   while(dCell != 0) {
      pCell = dCell->GetPare();
      if( pCell== 0) break;
      Int_t    kDiv = pCell->fBest;
      Double_t xDivi = pCell->fXdiv;
      if(dCell == pCell->GetDau0()  ) {
         cellSize[kDiv] *=xDivi;
         cellPosi[kDiv] *=xDivi;
      } else if(   dCell == pCell->GetDau1()  ) {
         cellSize[kDiv] *=(1.0-xDivi);
         cellPosi[kDiv]  =cellPosi[kDiv]*(1.0-xDivi)+xDivi;
      } else {
         Error( "GetHcub ","Something wrong with linked tree \n");
      }
      dCell=pCell;
   }//while
}//GetHcub

//_____________________________________________________________________
void    TMVA::PDEFoamCell::GetHSize( PDEFoamVect &cellSize)  const
{
   // Provides size of the cell
   // Size parameters are calculated by analyzing information in all parents
   // cells up to the root cell. It takes time but saves memory.
   if(fDim<1) return;
   const PDEFoamCell *pCell,*dCell;
   cellSize=1.0; // load all components
   dCell = this;
   while(dCell != 0) {
      pCell = dCell->GetPare();
      if( pCell== 0) break;
      Int_t    kDiv = pCell->fBest;
      Double_t xDivi = pCell->fXdiv;
      if(dCell == pCell->GetDau0() ) {
         cellSize[kDiv]=cellSize[kDiv]*xDivi;
      } else if(dCell == pCell->GetDau1()  ) {
         cellSize[kDiv]=cellSize[kDiv]*(1.0-xDivi);
      } else {
         Error( "GetHSize ","Something wrong with linked tree \n");
      }
      dCell=pCell;
   }//while
}//GetHSize

//_____________________________________________________________________
void TMVA::PDEFoamCell::CalcVolume(void)
{
   // Calculates volume of the cell using size params which are calculated

   Int_t k;
   Double_t volu=1.0;
   if(fDim>0) {         // h-cubical subspace
      PDEFoamVect cellSize(fDim);
      GetHSize(cellSize);
      for(k=0; k<fDim; k++) volu *= cellSize[k];
   }
   fVolume =volu;
}

//_____________________________________________________________________
UInt_t TMVA::PDEFoamCell::GetDepth()
{
   // Get depth of cell in binary tree, where the root cell has depth
   // 1

   // check wheter we are in the root cell
   if (fParent == 0)
      return 1;

   UInt_t depth = 1;
   PDEFoamCell *cell = this;
   while ((cell=cell->GetPare()) != 0){
      ++depth;
   }
   return depth;
}

//_____________________________________________________________________
UInt_t TMVA::PDEFoamCell::GetTreeDepth(UInt_t depth)
{
   // Get depth of cell tree, starting at this cell.

   if (GetStat() == 1)    // this is an active cell
      return depth + 1;

   UInt_t depth0 = 0, depth1 = 0;
   if (GetDau0() != NULL)
      depth0 = GetDau0()->GetTreeDepth(depth+1);
   if (GetDau1() != NULL)
      depth1 = GetDau1()->GetTreeDepth(depth+1);

   return (depth0 > depth1 ? depth0 : depth1);
}

//_____________________________________________________________________
void TMVA::PDEFoamCell::Print(Option_t *option) const
{
   // Printout of the cell geometry parameters for the debug purpose

   if (!option) Error( "Print", "No option set\n");

   std::cout <<  " Status= "<<     fStatus   <<",";
   std::cout <<  " Volume= "<<     fVolume   <<",";
   std::cout <<  " TrueInteg= " << fIntegral <<",";
   std::cout <<  " DriveInteg= "<< fDrive    <<",";
   std::cout << std::endl;;
   std::cout <<  " Xdiv= "<<fXdiv<<",";
   std::cout <<  " Best= "<<fBest<<",";
   std::cout <<  " Parent=  {"<< (GetPare() ? GetPare()->GetSerial() : -1) <<"} "; // extra DEBUG
   std::cout <<  " Daught0= {"<< (GetDau0() ? GetDau0()->GetSerial() : -1 )<<"} "; // extra DEBUG
   std::cout <<  " Daught1= {"<< (GetDau1() ? GetDau1()->GetSerial()  : -1 )<<"} "; // extra DEBUG
   std::cout << std::endl;;
   //
   //
   if (fDim>0 ) {
      PDEFoamVect cellPosi(fDim); PDEFoamVect cellSize(fDim);
      GetHcub(cellPosi,cellSize);
      std::cout <<"   Posi= "; cellPosi.Print("1"); std::cout<<","<< std::endl;;
      std::cout <<"   Size= "; cellSize.Print("1"); std::cout<<","<< std::endl;;
   }
}
 PDEFoamCell.cxx:1
 PDEFoamCell.cxx:2
 PDEFoamCell.cxx:3
 PDEFoamCell.cxx:4
 PDEFoamCell.cxx:5
 PDEFoamCell.cxx:6
 PDEFoamCell.cxx:7
 PDEFoamCell.cxx:8
 PDEFoamCell.cxx:9
 PDEFoamCell.cxx:10
 PDEFoamCell.cxx:11
 PDEFoamCell.cxx:12
 PDEFoamCell.cxx:13
 PDEFoamCell.cxx:14
 PDEFoamCell.cxx:15
 PDEFoamCell.cxx:16
 PDEFoamCell.cxx:17
 PDEFoamCell.cxx:18
 PDEFoamCell.cxx:19
 PDEFoamCell.cxx:20
 PDEFoamCell.cxx:21
 PDEFoamCell.cxx:22
 PDEFoamCell.cxx:23
 PDEFoamCell.cxx:24
 PDEFoamCell.cxx:25
 PDEFoamCell.cxx:26
 PDEFoamCell.cxx:27
 PDEFoamCell.cxx:28
 PDEFoamCell.cxx:29
 PDEFoamCell.cxx:30
 PDEFoamCell.cxx:31
 PDEFoamCell.cxx:32
 PDEFoamCell.cxx:33
 PDEFoamCell.cxx:34
 PDEFoamCell.cxx:35
 PDEFoamCell.cxx:36
 PDEFoamCell.cxx:37
 PDEFoamCell.cxx:38
 PDEFoamCell.cxx:39
 PDEFoamCell.cxx:40
 PDEFoamCell.cxx:41
 PDEFoamCell.cxx:42
 PDEFoamCell.cxx:43
 PDEFoamCell.cxx:44
 PDEFoamCell.cxx:45
 PDEFoamCell.cxx:46
 PDEFoamCell.cxx:47
 PDEFoamCell.cxx:48
 PDEFoamCell.cxx:49
 PDEFoamCell.cxx:50
 PDEFoamCell.cxx:51
 PDEFoamCell.cxx:52
 PDEFoamCell.cxx:53
 PDEFoamCell.cxx:54
 PDEFoamCell.cxx:55
 PDEFoamCell.cxx:56
 PDEFoamCell.cxx:57
 PDEFoamCell.cxx:58
 PDEFoamCell.cxx:59
 PDEFoamCell.cxx:60
 PDEFoamCell.cxx:61
 PDEFoamCell.cxx:62
 PDEFoamCell.cxx:63
 PDEFoamCell.cxx:64
 PDEFoamCell.cxx:65
 PDEFoamCell.cxx:66
 PDEFoamCell.cxx:67
 PDEFoamCell.cxx:68
 PDEFoamCell.cxx:69
 PDEFoamCell.cxx:70
 PDEFoamCell.cxx:71
 PDEFoamCell.cxx:72
 PDEFoamCell.cxx:73
 PDEFoamCell.cxx:74
 PDEFoamCell.cxx:75
 PDEFoamCell.cxx:76
 PDEFoamCell.cxx:77
 PDEFoamCell.cxx:78
 PDEFoamCell.cxx:79
 PDEFoamCell.cxx:80
 PDEFoamCell.cxx:81
 PDEFoamCell.cxx:82
 PDEFoamCell.cxx:83
 PDEFoamCell.cxx:84
 PDEFoamCell.cxx:85
 PDEFoamCell.cxx:86
 PDEFoamCell.cxx:87
 PDEFoamCell.cxx:88
 PDEFoamCell.cxx:89
 PDEFoamCell.cxx:90
 PDEFoamCell.cxx:91
 PDEFoamCell.cxx:92
 PDEFoamCell.cxx:93
 PDEFoamCell.cxx:94
 PDEFoamCell.cxx:95
 PDEFoamCell.cxx:96
 PDEFoamCell.cxx:97
 PDEFoamCell.cxx:98
 PDEFoamCell.cxx:99
 PDEFoamCell.cxx:100
 PDEFoamCell.cxx:101
 PDEFoamCell.cxx:102
 PDEFoamCell.cxx:103
 PDEFoamCell.cxx:104
 PDEFoamCell.cxx:105
 PDEFoamCell.cxx:106
 PDEFoamCell.cxx:107
 PDEFoamCell.cxx:108
 PDEFoamCell.cxx:109
 PDEFoamCell.cxx:110
 PDEFoamCell.cxx:111
 PDEFoamCell.cxx:112
 PDEFoamCell.cxx:113
 PDEFoamCell.cxx:114
 PDEFoamCell.cxx:115
 PDEFoamCell.cxx:116
 PDEFoamCell.cxx:117
 PDEFoamCell.cxx:118
 PDEFoamCell.cxx:119
 PDEFoamCell.cxx:120
 PDEFoamCell.cxx:121
 PDEFoamCell.cxx:122
 PDEFoamCell.cxx:123
 PDEFoamCell.cxx:124
 PDEFoamCell.cxx:125
 PDEFoamCell.cxx:126
 PDEFoamCell.cxx:127
 PDEFoamCell.cxx:128
 PDEFoamCell.cxx:129
 PDEFoamCell.cxx:130
 PDEFoamCell.cxx:131
 PDEFoamCell.cxx:132
 PDEFoamCell.cxx:133
 PDEFoamCell.cxx:134
 PDEFoamCell.cxx:135
 PDEFoamCell.cxx:136
 PDEFoamCell.cxx:137
 PDEFoamCell.cxx:138
 PDEFoamCell.cxx:139
 PDEFoamCell.cxx:140
 PDEFoamCell.cxx:141
 PDEFoamCell.cxx:142
 PDEFoamCell.cxx:143
 PDEFoamCell.cxx:144
 PDEFoamCell.cxx:145
 PDEFoamCell.cxx:146
 PDEFoamCell.cxx:147
 PDEFoamCell.cxx:148
 PDEFoamCell.cxx:149
 PDEFoamCell.cxx:150
 PDEFoamCell.cxx:151
 PDEFoamCell.cxx:152
 PDEFoamCell.cxx:153
 PDEFoamCell.cxx:154
 PDEFoamCell.cxx:155
 PDEFoamCell.cxx:156
 PDEFoamCell.cxx:157
 PDEFoamCell.cxx:158
 PDEFoamCell.cxx:159
 PDEFoamCell.cxx:160
 PDEFoamCell.cxx:161
 PDEFoamCell.cxx:162
 PDEFoamCell.cxx:163
 PDEFoamCell.cxx:164
 PDEFoamCell.cxx:165
 PDEFoamCell.cxx:166
 PDEFoamCell.cxx:167
 PDEFoamCell.cxx:168
 PDEFoamCell.cxx:169
 PDEFoamCell.cxx:170
 PDEFoamCell.cxx:171
 PDEFoamCell.cxx:172
 PDEFoamCell.cxx:173
 PDEFoamCell.cxx:174
 PDEFoamCell.cxx:175
 PDEFoamCell.cxx:176
 PDEFoamCell.cxx:177
 PDEFoamCell.cxx:178
 PDEFoamCell.cxx:179
 PDEFoamCell.cxx:180
 PDEFoamCell.cxx:181
 PDEFoamCell.cxx:182
 PDEFoamCell.cxx:183
 PDEFoamCell.cxx:184
 PDEFoamCell.cxx:185
 PDEFoamCell.cxx:186
 PDEFoamCell.cxx:187
 PDEFoamCell.cxx:188
 PDEFoamCell.cxx:189
 PDEFoamCell.cxx:190
 PDEFoamCell.cxx:191
 PDEFoamCell.cxx:192
 PDEFoamCell.cxx:193
 PDEFoamCell.cxx:194
 PDEFoamCell.cxx:195
 PDEFoamCell.cxx:196
 PDEFoamCell.cxx:197
 PDEFoamCell.cxx:198
 PDEFoamCell.cxx:199
 PDEFoamCell.cxx:200
 PDEFoamCell.cxx:201
 PDEFoamCell.cxx:202
 PDEFoamCell.cxx:203
 PDEFoamCell.cxx:204
 PDEFoamCell.cxx:205
 PDEFoamCell.cxx:206
 PDEFoamCell.cxx:207
 PDEFoamCell.cxx:208
 PDEFoamCell.cxx:209
 PDEFoamCell.cxx:210
 PDEFoamCell.cxx:211
 PDEFoamCell.cxx:212
 PDEFoamCell.cxx:213
 PDEFoamCell.cxx:214
 PDEFoamCell.cxx:215
 PDEFoamCell.cxx:216
 PDEFoamCell.cxx:217
 PDEFoamCell.cxx:218
 PDEFoamCell.cxx:219
 PDEFoamCell.cxx:220
 PDEFoamCell.cxx:221
 PDEFoamCell.cxx:222
 PDEFoamCell.cxx:223
 PDEFoamCell.cxx:224
 PDEFoamCell.cxx:225
 PDEFoamCell.cxx:226
 PDEFoamCell.cxx:227
 PDEFoamCell.cxx:228
 PDEFoamCell.cxx:229
 PDEFoamCell.cxx:230
 PDEFoamCell.cxx:231
 PDEFoamCell.cxx:232
 PDEFoamCell.cxx:233
 PDEFoamCell.cxx:234
 PDEFoamCell.cxx:235
 PDEFoamCell.cxx:236
 PDEFoamCell.cxx:237
 PDEFoamCell.cxx:238
 PDEFoamCell.cxx:239
 PDEFoamCell.cxx:240
 PDEFoamCell.cxx:241
 PDEFoamCell.cxx:242
 PDEFoamCell.cxx:243
 PDEFoamCell.cxx:244
 PDEFoamCell.cxx:245
 PDEFoamCell.cxx:246
 PDEFoamCell.cxx:247
 PDEFoamCell.cxx:248
 PDEFoamCell.cxx:249
 PDEFoamCell.cxx:250
 PDEFoamCell.cxx:251
 PDEFoamCell.cxx:252
 PDEFoamCell.cxx:253