00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048 #include <iostream>
00049 #include <iomanip>
00050 #include <fstream>
00051 #include <sstream>
00052 #include <cassert>
00053 #include <climits>
00054
00055 #include "TMVA/Event.h"
00056 #include "TMVA/Tools.h"
00057 #include "TMVA/PDEFoam.h"
00058 #include "TMVA/MsgLogger.h"
00059 #include "TMVA/Types.h"
00060
00061 #ifndef ROOT_TStyle
00062 #include "TStyle.h"
00063 #endif
00064 #ifndef ROOT_TObject
00065 #include "TObject.h"
00066 #endif
00067 #ifndef ROOT_TH1D
00068 #include "TH1D.h"
00069 #endif
00070 #ifndef ROOT_TMath
00071 #include "TMath.h"
00072 #endif
00073 #ifndef ROOT_TVectorT
00074 #include "TVectorT.h"
00075 #endif
00076 #ifndef ROOT_TRandom3
00077 #include "TRandom3.h"
00078 #endif
00079 #ifndef ROOT_TColor
00080 #include "TColor.h"
00081 #endif
00082
00083 ClassImp(TMVA::PDEFoam)
00084
00085 static const Float_t gHigh= FLT_MAX;
00086 static const Float_t gVlow=-FLT_MAX;
00087
00088 using namespace std;
00089
00090
00091 TMVA::PDEFoam::PDEFoam() :
00092 fName("PDEFoam"),
00093 fDim(0),
00094 fNCells(0),
00095 fNBin(5),
00096 fNSampl(2000),
00097 fEvPerBin(0),
00098 fMaskDiv(0),
00099 fInhiDiv(0),
00100 fNoAct(1),
00101 fLastCe(-1),
00102 fCells(0),
00103 fHistEdg(0),
00104 fRvec(0),
00105 fPseRan(new TRandom3(4356)),
00106 fAlpha(0),
00107 fFoamType(kDiscr),
00108 fXmin(0),
00109 fXmax(0),
00110 fNElements(0),
00111 fNmin(100),
00112 fMaxDepth(0),
00113 fVolFrac(30.0),
00114 fFillFoamWithOrigWeights(kFALSE),
00115 fDTSeparation(kFoam),
00116 fPeekMax(kTRUE),
00117 fDistr(new PDEFoamDistr()),
00118 fTimer(new Timer(0, "PDEFoam", kTRUE)),
00119 fVariableNames(new TObjArray()),
00120 fLogger(new MsgLogger("PDEFoam"))
00121 {
00122
00123 }
00124
00125
00126 TMVA::PDEFoam::PDEFoam(const TString& Name) :
00127 fName(Name),
00128 fDim(0),
00129 fNCells(1000),
00130 fNBin(5),
00131 fNSampl(2000),
00132 fEvPerBin(0),
00133 fMaskDiv(0),
00134 fInhiDiv(0),
00135 fNoAct(1),
00136 fLastCe(-1),
00137 fCells(0),
00138 fHistEdg(0),
00139 fRvec(0),
00140 fPseRan(new TRandom3(4356)),
00141 fAlpha(0),
00142 fFoamType(kDiscr),
00143 fXmin(0),
00144 fXmax(0),
00145 fNElements(0),
00146 fNmin(100),
00147 fMaxDepth(0),
00148 fVolFrac(30.0),
00149 fFillFoamWithOrigWeights(kFALSE),
00150 fDTSeparation(kFoam),
00151 fPeekMax(kTRUE),
00152 fDistr(new PDEFoamDistr()),
00153 fTimer(new Timer(1, "PDEFoam", kTRUE)),
00154 fVariableNames(new TObjArray()),
00155 fLogger(new MsgLogger("PDEFoam"))
00156 {
00157
00158 if(strlen(Name) > 128)
00159 Log() << kFATAL << "Name too long " << Name.Data() << Endl;
00160 }
00161
00162
00163 TMVA::PDEFoam::~PDEFoam()
00164 {
00165
00166
00167 delete fVariableNames;
00168 delete fTimer;
00169 if (fDistr) delete fDistr;
00170 if (fPseRan) delete fPseRan;
00171 if (fXmin) delete [] fXmin; fXmin=0;
00172 if (fXmax) delete [] fXmax; fXmax=0;
00173
00174 if(fCells!= 0) {
00175 for(Int_t i=0; i<fNCells; i++) delete fCells[i];
00176 delete [] fCells;
00177 }
00178 delete [] fRvec;
00179 delete [] fAlpha;
00180 delete [] fMaskDiv;
00181 delete [] fInhiDiv;
00182
00183 delete fLogger;
00184 }
00185
00186
00187 TMVA::PDEFoam::PDEFoam(const PDEFoam &From) :
00188 TObject(From)
00189 , fDim(0)
00190 , fNCells(0)
00191 , fNBin(0)
00192 , fNSampl(0)
00193 , fEvPerBin(0)
00194 , fMaskDiv(0)
00195 , fInhiDiv(0)
00196 , fNoAct(0)
00197 , fLastCe(0)
00198 , fCells(0)
00199 , fHistEdg(0)
00200 , fRvec(0)
00201 , fPseRan(0)
00202 , fAlpha(0)
00203 , fFoamType(kSeparate)
00204 , fXmin(0)
00205 , fXmax(0)
00206 , fNElements(0)
00207 , fNmin(0)
00208 , fMaxDepth(0)
00209 , fVolFrac(30.0)
00210 , fFillFoamWithOrigWeights(kFALSE)
00211 , fDTSeparation(kFoam)
00212 , fPeekMax(kTRUE)
00213 , fDistr(0)
00214 , fTimer(0)
00215 , fVariableNames(0)
00216 , fLogger(new MsgLogger("PDEFoam"))
00217 {
00218
00219 Log() << kFATAL << "COPY CONSTRUCTOR NOT IMPLEMENTED" << Endl;
00220 }
00221
00222
00223 void TMVA::PDEFoam::SetDim(Int_t kDim)
00224 {
00225
00226 if (kDim < 1)
00227 Log() << kFATAL << "<SetDim>: Dimension is zero or negative!" << Endl;
00228
00229 fDim = kDim;
00230 if (fXmin) delete [] fXmin;
00231 if (fXmax) delete [] fXmax;
00232 fXmin = new Double_t[GetTotDim()];
00233 fXmax = new Double_t[GetTotDim()];
00234 }
00235
00236
00237 void TMVA::PDEFoam::SetXmin(Int_t idim, Double_t wmin)
00238 {
00239
00240 if (idim<0 || idim>=GetTotDim())
00241 Log() << kFATAL << "<SetXmin>: Dimension out of bounds!" << Endl;
00242
00243 fXmin[idim]=wmin;
00244 }
00245
00246
00247 void TMVA::PDEFoam::SetXmax(Int_t idim, Double_t wmax)
00248 {
00249
00250 if (idim<0 || idim>=GetTotDim())
00251 Log() << kFATAL << "<SetXmax>: Dimension out of bounds!" << Endl;
00252
00253 fXmax[idim]=wmax;
00254 }
00255
00256
00257 void TMVA::PDEFoam::Create()
00258 {
00259
00260
00261
00262
00263
00264
00265
00266 Bool_t addStatus = TH1::AddDirectoryStatus();
00267 TH1::AddDirectory(kFALSE);
00268
00269 if(fPseRan==0) Log() << kFATAL << "Random number generator not set" << Endl;
00270 if(fDistr==0) Log() << kFATAL << "Distribution function not set" << Endl;
00271 if(fDim==0) Log() << kFATAL << "Zero dimension not allowed" << Endl;
00272
00273
00274
00275
00276
00277 fRvec = new Double_t[fDim];
00278 if(fRvec==0) Log() << kFATAL << "Cannot initialize buffer fRvec" << Endl;
00279
00280 if(fDim>0){
00281 fAlpha = new Double_t[fDim];
00282 if(fAlpha==0) Log() << kFATAL << "Cannot initialize buffer fAlpha" << Endl;
00283 }
00284
00285
00286 if(fInhiDiv == 0){
00287 fInhiDiv = new Int_t[fDim];
00288 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
00289 }
00290
00291 if(fMaskDiv == 0){
00292 fMaskDiv = new Int_t[fDim];
00293 for(Int_t i=0; i<fDim; i++) fMaskDiv[i]=1;
00294 }
00295
00296 fHistEdg = new TObjArray(fDim);
00297 for(Int_t i=0; i<fDim; i++){
00298 TString hname, htitle;
00299 hname = fName+TString("_HistEdge_");
00300 hname += i;
00301 htitle = TString("Edge Histogram No. ");
00302 htitle += i;
00303 (*fHistEdg)[i] = new TH1D(hname.Data(),htitle.Data(),fNBin,0.0, 1.0);
00304 ((TH1D*)(*fHistEdg)[i])->Sumw2();
00305 }
00306
00307
00308
00309
00310
00311
00312 InitCells();
00313 Grow();
00314
00315 TH1::AddDirectory(addStatus);
00316
00317
00318 SetNElements(2);
00319 ResetCellElements();
00320 }
00321
00322
00323 void TMVA::PDEFoam::InitCells()
00324 {
00325
00326
00327
00328 fLastCe =-1;
00329 if(fCells!= 0) {
00330 for(Int_t i=0; i<fNCells; i++) delete fCells[i];
00331 delete [] fCells;
00332 }
00333
00334 fCells = new PDEFoamCell*[fNCells];
00335 for(Int_t i=0; i<fNCells; i++){
00336 fCells[i]= new PDEFoamCell(fDim);
00337 fCells[i]->SetSerial(i);
00338 }
00339 if(fCells==0) Log() << kFATAL << "Cannot initialize CELLS" << Endl;
00340
00341
00342 if (GetNmin() > 0) {
00343 SetNElements(1);
00344 ResetCellElements(true);
00345 }
00346
00347
00348
00349
00350 CellFill(1, 0);
00351
00352
00353 for(Long_t iCell=0; iCell<=fLastCe; iCell++){
00354 if (fDTSeparation != kFoam)
00355 DTExplore( fCells[iCell] );
00356 else
00357 Explore( fCells[iCell] );
00358 }
00359 }
00360
00361
00362 Int_t TMVA::PDEFoam::CellFill(Int_t Status, PDEFoamCell *parent)
00363 {
00364
00365
00366
00367 PDEFoamCell *cell;
00368 if (fLastCe==fNCells){
00369 Log() << kFATAL << "Too many cells" << Endl;
00370 }
00371 fLastCe++;
00372
00373 cell = fCells[fLastCe];
00374
00375 cell->Fill(Status, parent, 0, 0);
00376
00377 cell->SetBest( -1);
00378 cell->SetXdiv(0.5);
00379 Double_t xInt2,xDri2;
00380 if(parent!=0){
00381 xInt2 = 0.5*parent->GetIntg();
00382 xDri2 = 0.5*parent->GetDriv();
00383 cell->SetIntg(xInt2);
00384 cell->SetDriv(xDri2);
00385 }else{
00386 cell->SetIntg(0.0);
00387 cell->SetDriv(0.0);
00388 }
00389 return fLastCe;
00390 }
00391
00392
00393 void TMVA::PDEFoam::Explore(PDEFoamCell *cell)
00394 {
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412 Double_t wt, dx, xBest, yBest;
00413 Double_t intOld, driOld;
00414
00415 Long_t iev;
00416 Double_t nevMC;
00417 Int_t i, j, k;
00418 Int_t nProj, kBest;
00419 Double_t ceSum[5], xproj;
00420
00421 Double_t event_density = 0;
00422 Double_t totevents = 0;
00423 Double_t toteventsOld = 0;
00424
00425 PDEFoamVect cellSize(fDim);
00426 PDEFoamVect cellPosi(fDim);
00427
00428 cell->GetHcub(cellPosi,cellSize);
00429
00430 PDEFoamCell *parent;
00431
00432 Double_t *xRand = new Double_t[fDim];
00433
00434 Double_t *volPart=0;
00435
00436 cell->CalcVolume();
00437 dx = cell->GetVolume();
00438 intOld = cell->GetIntg();
00439 driOld = cell->GetDriv();
00440 if (GetNmin() > 0)
00441 toteventsOld = GetBuildUpCellEvents(cell);
00442
00443
00444
00445
00446 ceSum[0]=0;
00447 ceSum[1]=0;
00448 ceSum[2]=0;
00449 ceSum[3]=gHigh;
00450 ceSum[4]=gVlow;
00451
00452 for (i=0;i<fDim;i++) ((TH1D *)(*fHistEdg)[i])->Reset();
00453
00454 Double_t nevEff=0.;
00455
00456 for (iev=0;iev<fNSampl;iev++){
00457 MakeAlpha();
00458
00459 if (fDim>0) for (j=0; j<fDim; j++) xRand[j]= cellPosi[j] +fAlpha[j]*(cellSize[j]);
00460
00461 wt = dx*Eval(xRand, event_density);
00462 totevents += dx*event_density;
00463
00464 nProj = 0;
00465 if (fDim>0) {
00466 for (k=0; k<fDim; k++) {
00467 xproj =fAlpha[k];
00468 ((TH1D *)(*fHistEdg)[nProj])->Fill(xproj,wt);
00469 nProj++;
00470 }
00471 }
00472
00473 ceSum[0] += wt;
00474 ceSum[1] += wt*wt;
00475 ceSum[2]++;
00476 if (ceSum[3]>wt) ceSum[3]=wt;
00477 if (ceSum[4]<wt) ceSum[4]=wt;
00478
00479 nevEff = ceSum[0]*ceSum[0]/ceSum[1];
00480 if ( nevEff >= fNBin*fEvPerBin) break;
00481 }
00482 totevents /= fNSampl;
00483
00484
00485
00486 if (cell==fCells[0] && ceSum[0]<=0.0){
00487 if (ceSum[0]==0.0)
00488 Log() << kFATAL << "No events were found during exploration of "
00489 << "root cell. Please check PDEFoam parameters nSampl "
00490 << "and VolFrac." << Endl;
00491 else
00492 Log() << kWARNING << "Negative number of events found during "
00493 << "exploration of root cell" << Endl;
00494 }
00495
00496
00497
00498 for (k=0; k<fDim;k++){
00499 fMaskDiv[k] =1;
00500 if ( fInhiDiv[k]==1) fMaskDiv[k] =0;
00501 }
00502 kBest=-1;
00503
00504
00505 nevMC = ceSum[2];
00506 Double_t intTrue = ceSum[0]/(nevMC+0.000001);
00507 Double_t intDriv=0.;
00508
00509 if (kBest == -1) Varedu(ceSum,kBest,xBest,yBest);
00510 intDriv =sqrt(ceSum[1]/nevMC) -intTrue;
00511
00512
00513 cell->SetBest(kBest);
00514 cell->SetXdiv(xBest);
00515 cell->SetIntg(intTrue);
00516 cell->SetDriv(intDriv);
00517 if (GetNmin() > 0)
00518 SetCellElement(cell, 0, totevents);
00519
00520
00521 Double_t parIntg, parDriv;
00522 for (parent = cell->GetPare(); parent!=0; parent = parent->GetPare()){
00523 parIntg = parent->GetIntg();
00524 parDriv = parent->GetDriv();
00525 parent->SetIntg( parIntg +intTrue -intOld );
00526 parent->SetDriv( parDriv +intDriv -driOld );
00527 if (GetNmin() > 0)
00528 SetCellElement( parent, 0, GetBuildUpCellEvents(parent) + totevents - toteventsOld);
00529 }
00530 delete [] volPart;
00531 delete [] xRand;
00532 }
00533
00534
00535 void TMVA::PDEFoam::DTExplore(PDEFoamCell *cell)
00536 {
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 if (!cell)
00552 Log() << kFATAL << "<DTExplore> Null pointer given!" << Endl;
00553
00554
00555 std::vector<TH1F*> hsig, hbkg, hsig_unw, hbkg_unw;
00556 for (Int_t idim=0; idim<fDim; idim++) {
00557 hsig.push_back( new TH1F(Form("hsig_%i",idim),
00558 Form("signal[%i]",idim), fNBin, 0, 1 ));
00559 hbkg.push_back( new TH1F(Form("hbkg_%i",idim),
00560 Form("background[%i]",idim), fNBin, 0, 1 ));
00561 hsig_unw.push_back( new TH1F(Form("hsig_unw_%i",idim),
00562 Form("signal_unw[%i]",idim), fNBin, 0, 1 ));
00563 hbkg_unw.push_back( new TH1F(Form("hbkg_unw_%i",idim),
00564 Form("background_unw[%i]",idim), fNBin, 0, 1 ));
00565 }
00566
00567
00568 fDistr->FillHist(cell, hsig, hbkg, hsig_unw, hbkg_unw);
00569
00570
00571 Float_t xBest = 0.5;
00572 Int_t kBest = -1;
00573 Float_t maxGain = -1.0;
00574 Float_t nTotS = hsig.at(0)->Integral(0, hsig.at(0)->GetNbinsX()+1);
00575 Float_t nTotB = hbkg.at(0)->Integral(0, hbkg.at(0)->GetNbinsX()+1);
00576 Float_t nTotS_unw = hsig_unw.at(0)->Integral(0, hsig_unw.at(0)->GetNbinsX()+1);
00577 Float_t nTotB_unw = hbkg_unw.at(0)->Integral(0, hbkg_unw.at(0)->GetNbinsX()+1);
00578 Float_t parentGain = (nTotS+nTotB) * GetSeparation(nTotS,nTotB);
00579
00580 for (Int_t idim=0; idim<fDim; idim++) {
00581 Float_t nSelS=hsig.at(idim)->GetBinContent(0);
00582 Float_t nSelB=hbkg.at(idim)->GetBinContent(0);
00583 Float_t nSelS_unw=hsig_unw.at(idim)->GetBinContent(0);
00584 Float_t nSelB_unw=hbkg_unw.at(idim)->GetBinContent(0);
00585 for(Int_t jLo=1; jLo<fNBin; jLo++) {
00586 nSelS += hsig.at(idim)->GetBinContent(jLo);
00587 nSelB += hbkg.at(idim)->GetBinContent(jLo);
00588 nSelS_unw += hsig_unw.at(idim)->GetBinContent(jLo);
00589 nSelB_unw += hbkg_unw.at(idim)->GetBinContent(jLo);
00590
00591
00592
00593 if ( !( (nSelS_unw + nSelB_unw) >= GetNmin() &&
00594 (nTotS_unw-nSelS_unw + nTotB_unw-nSelB_unw) >= GetNmin() ) )
00595 continue;
00596
00597 Float_t xLo = 1.0*jLo/fNBin;
00598
00599
00600 Float_t leftGain = ((nTotS - nSelS) + (nTotB - nSelB))
00601 * GetSeparation(nTotS-nSelS,nTotB-nSelB);
00602 Float_t rightGain = (nSelS+nSelB) * GetSeparation(nSelS,nSelB);
00603 Float_t gain = parentGain - leftGain - rightGain;
00604
00605 if (gain >= maxGain) {
00606 maxGain = gain;
00607 xBest = xLo;
00608 kBest = idim;
00609 }
00610 }
00611 }
00612
00613 if (kBest >= fDim || kBest < 0)
00614 Log() << kWARNING << "No best division edge found!" << Endl;
00615
00616
00617 cell->SetBest(kBest);
00618 cell->SetXdiv(xBest);
00619 if (nTotB+nTotS > 0)
00620 cell->SetIntg( nTotS/(nTotB+nTotS) );
00621 else
00622 cell->SetIntg( 0.0 );
00623 cell->SetDriv(maxGain);
00624 cell->CalcVolume();
00625
00626
00627
00628 if (GetNmin() > 0)
00629 SetCellElement( cell, 0, nTotS + nTotB);
00630
00631
00632 for (UInt_t ih=0; ih<hsig.size(); ih++) delete hsig.at(ih);
00633 for (UInt_t ih=0; ih<hbkg.size(); ih++) delete hbkg.at(ih);
00634 for (UInt_t ih=0; ih<hsig_unw.size(); ih++) delete hsig_unw.at(ih);
00635 for (UInt_t ih=0; ih<hbkg_unw.size(); ih++) delete hbkg_unw.at(ih);
00636 }
00637
00638
00639 Float_t TMVA::PDEFoam::GetSeparation(Float_t s, Float_t b)
00640 {
00641
00642
00643
00644
00645 if (s+b <= 0 || s < 0 || b < 0 )
00646 return 0;
00647
00648 Float_t p = s/(s+b);
00649
00650 switch(fDTSeparation) {
00651 case kFoam:
00652 return p;
00653 case kGiniIndex:
00654 return p*(1-p);
00655 case kMisClassificationError:
00656 return 1 - TMath::Max(p, 1-p);
00657 case kCrossEntropy:
00658 return (p<=0 || p >=1 ? 0 : -p*TMath::Log(p) - (1-p)*TMath::Log(1-p));
00659 default:
00660 Log() << kFATAL << "Unknown separation type" << Endl;
00661 break;
00662 }
00663
00664 return 0;
00665 }
00666
00667
00668 void TMVA::PDEFoam::Varedu(Double_t ceSum[5], Int_t &kBest, Double_t &xBest, Double_t &yBest)
00669 {
00670
00671
00672
00673
00674
00675 Double_t nent = ceSum[2];
00676 Double_t swAll = ceSum[0];
00677 Double_t sswAll = ceSum[1];
00678 Double_t ssw = sqrt(sswAll)/sqrt(nent);
00679
00680 Double_t swIn,swOut,sswIn,sswOut,xLo,xUp;
00681 kBest =-1;
00682 xBest =0.5;
00683 yBest =1.0;
00684 Double_t maxGain=0.0;
00685
00686 for(Int_t kProj=0; kProj<fDim; kProj++) {
00687 if( fMaskDiv[kProj]) {
00688
00689 Double_t sigmIn =0.0; Double_t sigmOut =0.0;
00690 Double_t sswtBest = gHigh;
00691 Double_t gain =0.0;
00692 Double_t xMin=0.0; Double_t xMax=0.0;
00693
00694 for(Int_t jLo=1; jLo<=fNBin; jLo++) {
00695 Double_t aswIn=0; Double_t asswIn=0;
00696 for(Int_t jUp=jLo; jUp<=fNBin;jUp++) {
00697 aswIn += ((TH1D *)(*fHistEdg)[kProj])->GetBinContent(jUp);
00698 asswIn += Sqr(((TH1D *)(*fHistEdg)[kProj])->GetBinError( jUp));
00699 xLo=(jLo-1.0)/fNBin;
00700 xUp=(jUp*1.0)/fNBin;
00701 swIn = aswIn/nent;
00702 swOut = (swAll-aswIn)/nent;
00703 sswIn = sqrt(asswIn) /sqrt(nent*(xUp-xLo)) *(xUp-xLo);
00704 sswOut= sqrt(sswAll-asswIn)/sqrt(nent*(1.0-xUp+xLo)) *(1.0-xUp+xLo);
00705 if( (sswIn+sswOut) < sswtBest) {
00706 sswtBest = sswIn+sswOut;
00707 gain = ssw-sswtBest;
00708 sigmIn = sswIn -swIn;
00709 sigmOut = sswOut-swOut;
00710 xMin = xLo;
00711 xMax = xUp;
00712 }
00713 }
00714 }
00715 Int_t iLo = (Int_t) (fNBin*xMin);
00716 Int_t iUp = (Int_t) (fNBin*xMax);
00717
00718 if(gain>=maxGain) {
00719 maxGain=gain;
00720 kBest=kProj;
00721 xBest=xMin;
00722 yBest=xMax;
00723 if(iLo == 0) xBest=yBest;
00724 if(iUp == fNBin) yBest=xBest;
00725 }
00726 }
00727 }
00728
00729 if( (kBest >= fDim) || (kBest<0) )
00730 Log() << kFATAL << "Something wrong with kBest" << Endl;
00731 }
00732
00733
00734 void TMVA::PDEFoam::MakeAlpha()
00735 {
00736
00737
00738
00739
00740 fPseRan->RndmArray(fDim,fRvec);
00741 for(Int_t k=0; k<fDim; k++) fAlpha[k] = fRvec[k];
00742 }
00743
00744
00745 Long_t TMVA::PDEFoam::PeekMax()
00746 {
00747
00748
00749
00750
00751
00752
00753 Long_t iCell = -1;
00754
00755 Long_t i;
00756 Double_t drivMax, driv;
00757 Bool_t bCutNmin = kTRUE;
00758 Bool_t bCutMaxDepth = kTRUE;
00759
00760 drivMax = 0;
00761 for(i=0; i<=fLastCe; i++) {
00762 if( fCells[i]->GetStat() == 1 ) {
00763
00764 if (fCells[i]->GetDriv() < std::numeric_limits<float>::epsilon())
00765 continue;
00766
00767 driv = TMath::Abs( fCells[i]->GetDriv());
00768
00769
00770 if (GetMaxDepth() > 0)
00771 bCutMaxDepth = fCells[i]->GetDepth() < GetMaxDepth();
00772
00773
00774 if (GetNmin() > 0)
00775 bCutNmin = GetBuildUpCellEvents(fCells[i]) > GetNmin();
00776
00777
00778 if(driv > drivMax && bCutNmin && bCutMaxDepth) {
00779 drivMax = driv;
00780 iCell = i;
00781 }
00782 }
00783 }
00784
00785 if (iCell == -1){
00786 if (!bCutNmin)
00787 Log() << kVERBOSE << "Warning: No cell with more than "
00788 << GetNmin() << " events found!" << Endl;
00789 else if (!bCutMaxDepth)
00790 Log() << kVERBOSE << "Warning: Maximum depth reached: "
00791 << GetMaxDepth() << Endl;
00792 else
00793 Log() << kWARNING << "Warning: PDEFoam::PeekMax: no more candidate cells (drivMax>0) found for further splitting." << Endl;
00794 }
00795
00796 return(iCell);
00797 }
00798
00799
00800 Long_t TMVA::PDEFoam::PeekLast()
00801 {
00802
00803
00804
00805
00806
00807 Long_t iCell = -1;
00808
00809 Bool_t bCutNmin = kTRUE;
00810 Bool_t bCutMaxDepth = kTRUE;
00811
00812 for(Long_t i=fLastCe; i>=0; i--) {
00813 if( fCells[i]->GetStat() == 1 ) {
00814
00815 if (fCells[i]->GetDriv() < std::numeric_limits<float>::epsilon())
00816 continue;
00817
00818
00819 if (GetMaxDepth() > 0)
00820 bCutMaxDepth = fCells[i]->GetDepth() < GetMaxDepth();
00821
00822
00823 if (GetNmin() > 0)
00824 bCutNmin = GetBuildUpCellEvents(fCells[i]) > GetNmin();
00825
00826
00827 if(bCutNmin && bCutMaxDepth) {
00828 iCell = i;
00829 break;
00830 }
00831 }
00832 }
00833
00834 if (iCell == -1){
00835 if (!bCutNmin)
00836 Log() << kVERBOSE << "Warning: No cell with more than "
00837 << GetNmin() << " events found!" << Endl;
00838 else if (!bCutMaxDepth)
00839 Log() << kVERBOSE << "Warning: Maximum depth reached: "
00840 << GetMaxDepth() << Endl;
00841 else
00842 Log() << kWARNING << "Warning: PDEFoam::PeekLast: no more candidate cells found for further splitting." << Endl;
00843 }
00844
00845 return(iCell);
00846 }
00847
00848
00849 Int_t TMVA::PDEFoam::Divide(PDEFoamCell *cell)
00850 {
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 Double_t xdiv;
00861 Int_t kBest;
00862
00863 if(fLastCe+1 >= fNCells) Log() << kFATAL << "Buffer limit is reached, fLastCe=fnBuf" << Endl;
00864
00865 cell->SetStat(0);
00866 fNoAct++;
00867
00868 xdiv = cell->GetXdiv();
00869 kBest = cell->GetBest();
00870 if( kBest<0 || kBest>=fDim ) Log() << kFATAL << "Wrong kBest" << Endl;
00871
00872
00873
00874
00875
00876 Int_t d1 = CellFill(1, cell);
00877 Int_t d2 = CellFill(1, cell);
00878 cell->SetDau0((fCells[d1]));
00879 cell->SetDau1((fCells[d2]));
00880 if (fDTSeparation != kFoam) {
00881 DTExplore( (fCells[d1]) );
00882 DTExplore( (fCells[d2]) );
00883 } else {
00884 Explore( (fCells[d1]) );
00885 Explore( (fCells[d2]) );
00886 }
00887 return 1;
00888 }
00889
00890
00891 Double_t TMVA::PDEFoam::Eval(Double_t *xRand, Double_t &event_density)
00892 {
00893
00894
00895 return fDistr->Density(xRand, event_density);
00896 }
00897
00898
00899 void TMVA::PDEFoam::Grow()
00900 {
00901
00902
00903
00904
00905
00906 fTimer->Init(fNCells);
00907
00908 Long_t iCell;
00909 PDEFoamCell* newCell;
00910
00911 while ( (fLastCe+2) < fNCells ) {
00912 if (fPeekMax)
00913 iCell = PeekMax();
00914 else
00915 iCell = PeekLast();
00916
00917 if ( (iCell<0) || (iCell>fLastCe) ) {
00918 Log() << kVERBOSE << "Break: "<< fLastCe+1 << " cells created" << Endl;
00919
00920 for (Long_t jCell=fLastCe+1; jCell<fNCells; jCell++)
00921 delete fCells[jCell];
00922 fNCells = fLastCe+1;
00923 break;
00924 }
00925 newCell = fCells[iCell];
00926
00927 OutputGrow();
00928
00929 if ( Divide( newCell )==0) break;
00930 }
00931 OutputGrow( kTRUE );
00932 CheckAll(1);
00933
00934 Log() << kVERBOSE << GetNActiveCells() << " active cells created" << Endl;
00935 }
00936
00937
00938 void TMVA::PDEFoam::SetInhiDiv(Int_t iDim, Int_t InhiDiv)
00939 {
00940
00941
00942
00943
00944 if(fDim==0) Log() << kFATAL << "SetInhiDiv: fDim=0" << Endl;
00945 if(fInhiDiv == 0) {
00946 fInhiDiv = new Int_t[ fDim ];
00947 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
00948 }
00949
00950 if( ( 0<=iDim) && (iDim<fDim)) {
00951 fInhiDiv[iDim] = InhiDiv;
00952 } else
00953 Log() << kFATAL << "Wrong iDim" << Endl;
00954 }
00955
00956
00957 void TMVA::PDEFoam::CheckAll(Int_t level)
00958 {
00959
00960
00961
00962
00963
00964 Int_t errors, warnings;
00965 PDEFoamCell *cell;
00966 Long_t iCell;
00967
00968 errors = 0; warnings = 0;
00969 if (level==1) Log() << kVERBOSE << "Performing consistency checks for created foam" << Endl;
00970 for(iCell=1; iCell<=fLastCe; iCell++) {
00971 cell = fCells[iCell];
00972
00973 if( ((cell->GetDau0()==0) && (cell->GetDau1()!=0) ) ||
00974 ((cell->GetDau1()==0) && (cell->GetDau0()!=0) ) ) {
00975 errors++;
00976 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has only one daughter " << iCell << Endl;
00977 }
00978 if( (cell->GetDau0()==0) && (cell->GetDau1()==0) && (cell->GetStat()==0) ) {
00979 errors++;
00980 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has no daughter and is inactive " << iCell << Endl;
00981 }
00982 if( (cell->GetDau0()!=0) && (cell->GetDau1()!=0) && (cell->GetStat()==1) ) {
00983 errors++;
00984 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has two daughters and is active " << iCell << Endl;
00985 }
00986
00987
00988 if( (cell->GetPare())!=fCells[0] ) {
00989 if ( (cell != cell->GetPare()->GetDau0()) && (cell != cell->GetPare()->GetDau1()) ) {
00990 errors++;
00991 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d parent not pointing to this cell " << iCell << Endl;
00992 }
00993 }
00994
00995
00996 if(cell->GetDau0()!=0) {
00997 if(cell != (cell->GetDau0())->GetPare()) {
00998 errors++;
00999 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d daughter 0 not pointing to this cell " << iCell << Endl;
01000 }
01001 }
01002 if(cell->GetDau1()!=0) {
01003 if(cell != (cell->GetDau1())->GetPare()) {
01004 errors++;
01005 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d daughter 1 not pointing to this cell " << iCell << Endl;
01006 }
01007 }
01008 if(cell->GetVolume()<1E-50) {
01009 errors++;
01010 if(level==1) Log() << kFATAL << "ERROR: Cell no. " << iCell << " has Volume of <1E-50" << Endl;
01011 }
01012 }
01013
01014
01015 for(iCell=0; iCell<=fLastCe; iCell++) {
01016 cell = fCells[iCell];
01017 if( (cell->GetStat()==1) && (cell->GetVolume()<1E-11) ) {
01018 errors++;
01019 if(level==1) Log() << kFATAL << "ERROR: Cell no. " << iCell << " is active but Volume is 0 " << Endl;
01020 }
01021 }
01022
01023 if(level==1){
01024 Log() << kVERBOSE << "Check has found " << errors << " errors and " << warnings << " warnings." << Endl;
01025 }
01026 if(errors>0){
01027 Info("CheckAll","Check - found total %d errors \n",errors);
01028 }
01029 }
01030
01031
01032 void TMVA::PDEFoam::PrintCell(Long_t iCell)
01033 {
01034
01035
01036 if (iCell < 0 || iCell > fLastCe) {
01037 Log() << kWARNING << "<PrintCell(iCell=" << iCell
01038 << ")>: cell number " << iCell << " out of bounds!"
01039 << Endl;
01040 return;
01041 }
01042
01043 PDEFoamVect cellPosi(fDim), cellSize(fDim);
01044 fCells[iCell]->GetHcub(cellPosi,cellSize);
01045 Int_t kBest = fCells[iCell]->GetBest();
01046 Double_t xBest = fCells[iCell]->GetXdiv();
01047
01048 Log() << "Cell[" << iCell << "]={ ";
01049 Log() << " " << fCells[iCell] << " " << Endl;
01050 Log() << " Xdiv[abs. coord.]="
01051 << VarTransformInvers(kBest,cellPosi[kBest] + xBest*cellSize[kBest])
01052 << Endl;
01053 Log() << " Abs. coord. = (";
01054 for (Int_t idim=0; idim<fDim; idim++) {
01055 Log() << "dim[" << idim << "]={"
01056 << VarTransformInvers(idim,cellPosi[idim]) << ","
01057 << VarTransformInvers(idim,cellPosi[idim] + cellSize[idim])
01058 << "}";
01059 if (idim < fDim-1)
01060 Log() << ", ";
01061 }
01062 Log() << ")" << Endl;
01063 fCells[iCell]->Print("1");
01064 Log()<<"}"<<Endl;
01065 }
01066
01067
01068 void TMVA::PDEFoam::PrintCells(void)
01069 {
01070
01071
01072 for(Long_t iCell=0; iCell<=fLastCe; iCell++)
01073 PrintCell(iCell);
01074 }
01075
01076
01077 void TMVA::PDEFoam::RemoveEmptyCell( Int_t iCell )
01078 {
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088 Double_t volume = fCells[iCell]->GetVolume();
01089
01090 if (!fCells[iCell]->GetStat() || volume>0){
01091 Log() << kDEBUG << "<RemoveEmptyCell>: cell " << iCell
01092 << "is not active or has volume>0 ==> doesn't need to be removed" << Endl;
01093 return;
01094 }
01095
01096
01097 PDEFoamCell *pCell = fCells[iCell]->GetPare();
01098 PDEFoamCell *ppCell = fCells[iCell]->GetPare()->GetPare();
01099
01100
01101 PDEFoamCell *sCell;
01102 if (pCell->GetDau0() == fCells[iCell])
01103 sCell = pCell->GetDau1();
01104 else
01105 sCell = pCell->GetDau0();
01106
01107
01108 if (pCell->GetIntg() != sCell->GetIntg())
01109 Log() << kWARNING << "<RemoveEmptyCell> Error: cell integrals are not equal!"
01110 << " Intg(parent cell)=" << pCell->GetIntg()
01111 << " Intg(sister cell)=" << sCell->GetIntg()
01112 << Endl;
01113
01114
01115 if (ppCell->GetDau0() == pCell)
01116 ppCell->SetDau0(sCell);
01117 else
01118 ppCell->SetDau1(sCell);
01119
01120
01121 sCell->SetPare(ppCell);
01122
01123
01124 fCells[iCell]->SetStat(0);
01125 pCell->SetStat(0);
01126 }
01127
01128
01129 void TMVA::PDEFoam::CheckCells( Bool_t remove_empty_cells )
01130 {
01131
01132
01133
01134 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01135 if (!fCells[iCell]->GetStat())
01136 continue;
01137
01138 Double_t volume = fCells[iCell]->GetVolume();
01139 if (volume<1e-10){
01140 if (volume<=0){
01141 Log() << kWARNING << "Critical: cell volume negative or zero! volume="
01142 << volume << " cell number: " << iCell << Endl;
01143
01144 if (remove_empty_cells){
01145 Log() << kWARNING << "Remove cell " << iCell << Endl;
01146 RemoveEmptyCell(iCell);
01147 }
01148 }
01149 else {
01150 Log() << kWARNING << "Cell volume close to zero! volume="
01151 << volume << " cell number: " << iCell << Endl;
01152 }
01153 }
01154 }
01155 }
01156
01157
01158 void TMVA::PDEFoam::PrintCellElements()
01159 {
01160
01161
01162
01163 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01164 if (!fCells[iCell]->GetStat()) continue;
01165
01166 Log() << "cell[" << iCell << "] elements: [";
01167 for (UInt_t i=0; i<GetNElements(); i++){
01168 if (i>0) Log() << " ; ";
01169 Log() << GetCellElement(fCells[iCell], i);
01170 }
01171 Log() << "]" << Endl;
01172 }
01173 }
01174
01175
01176 void TMVA::PDEFoam::ResetCellElements(Bool_t allcells)
01177 {
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 if (!fCells || GetNElements()==0) return;
01189
01190
01191 Log() << kVERBOSE << "Delete old cell elements" << Endl;
01192 for(Long_t iCell=0; iCell<fNCells; iCell++) {
01193 if (fCells[iCell]->GetElement() != 0){
01194 delete dynamic_cast<TVectorD*>(fCells[iCell]->GetElement());
01195 fCells[iCell]->SetElement(0);
01196 }
01197 }
01198
01199 if (allcells){
01200 Log() << kVERBOSE << "Reset new cell elements to "
01201 << GetNElements() << " value(s) per cell" << Endl;
01202 } else {
01203 Log() << kVERBOSE << "Reset active cell elements to "
01204 << GetNElements() << " value(s) per cell" << Endl;
01205 }
01206
01207
01208 for(Long_t iCell=0; iCell<(allcells ? fNCells : fLastCe+1); iCell++) {
01209
01210 if (!allcells && !(fCells[iCell]->GetStat()))
01211 continue;
01212
01213 TVectorD *elem = new TVectorD(GetNElements());
01214 for (UInt_t i=0; i<GetNElements(); i++)
01215 (*elem)(i) = 0.;
01216
01217 fCells[iCell]->SetElement(elem);
01218 }
01219 }
01220
01221
01222 void TMVA::PDEFoam::CalcCellTarget()
01223 {
01224
01225
01226
01227
01228 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01229 if (!(fCells[iCell]->GetStat()))
01230 continue;
01231
01232 Double_t N_ev = GetCellElement(fCells[iCell], 0);
01233 Double_t tar = GetCellElement(fCells[iCell], 1);
01234
01235 if (N_ev > 1e-20){
01236 SetCellElement(fCells[iCell], 0, tar/N_ev);
01237 SetCellElement(fCells[iCell], 1, tar/TMath::Sqrt(N_ev));
01238 }
01239 else {
01240 SetCellElement(fCells[iCell], 0, 0.0 );
01241 SetCellElement(fCells[iCell], 1, -1 );
01242 }
01243 }
01244 }
01245
01246
01247 void TMVA::PDEFoam::CalcCellDiscr()
01248 {
01249
01250
01251
01252
01253 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01254 if (!(fCells[iCell]->GetStat()))
01255 continue;
01256
01257 Double_t N_sig = GetCellElement(fCells[iCell], 0);
01258 Double_t N_bg = GetCellElement(fCells[iCell], 1);
01259
01260 if (N_sig<0.) {
01261 Log() << kWARNING << "Negative number of signal events in cell " << iCell
01262 << ": " << N_sig << ". Set to 0." << Endl;
01263 N_sig=0.;
01264 }
01265 if (N_bg<0.) {
01266 Log() << kWARNING << "Negative number of background events in cell " << iCell
01267 << ": " << N_bg << ". Set to 0." << Endl;
01268 N_bg=0.;
01269 }
01270
01271
01272 if (N_sig+N_bg > 1e-10){
01273 SetCellElement(fCells[iCell], 0, N_sig/(N_sig+N_bg));
01274 SetCellElement(fCells[iCell], 1, TMath::Sqrt( Sqr ( N_sig/Sqr(N_sig+N_bg))*N_sig +
01275 Sqr ( N_bg /Sqr(N_sig+N_bg))*N_bg ) );
01276
01277 }
01278 else {
01279 SetCellElement(fCells[iCell], 0, 0.5);
01280 SetCellElement(fCells[iCell], 1, 1. );
01281 }
01282 }
01283 }
01284
01285
01286 Double_t TMVA::PDEFoam::GetCellDiscr( std::vector<Float_t> &xvec, EKernel kernel )
01287 {
01288
01289
01290
01291
01292
01293
01294 std::vector<Float_t> txvec(VarTransform(xvec));
01295
01296
01297 PDEFoamCell *cell= FindCell(txvec);
01298
01299 if (!cell) return -999.;
01300
01301 switch (kernel) {
01302 case kNone:
01303 return GetCellValue(cell, kDiscriminator);
01304
01305 case kGaus: {
01306 Double_t result = 0.;
01307 Double_t norm = 0.;
01308
01309 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01310 if (!(fCells[iCell]->GetStat())) continue;
01311
01312
01313 Double_t cell_discr = GetCellValue(fCells[iCell], kDiscriminator);
01314 Double_t gau = WeightGaus(fCells[iCell], txvec);
01315
01316 result += gau * cell_discr;
01317 norm += gau;
01318 }
01319
01320 return result / norm;
01321 }
01322
01323 case kLinN:
01324 return WeightLinNeighbors(txvec, kDiscriminator);
01325
01326 default:
01327 Log() << kFATAL << "GetCellDiscr: ERROR: wrong kernel!" << Endl;
01328 return 0;
01329 }
01330
01331 return 0;
01332 }
01333
01334
01335 void TMVA::PDEFoam::FillFoamCells(const Event* ev, Bool_t NoNegWeights)
01336 {
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349 std::vector<Float_t> values = ev->GetValues();
01350 std::vector<Float_t> targets = ev->GetTargets();
01351 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
01352 EFoamType ft = GetFoamType();
01353
01354 if((NoNegWeights && weight<=0) || weight==0)
01355 return;
01356
01357 if (ft == kMultiTarget)
01358 values.insert(values.end(), targets.begin(), targets.end());
01359
01360
01361 std::vector<Float_t> tvalues = VarTransform(values);
01362 PDEFoamCell *cell = FindCell(tvalues);
01363 if (!cell) {
01364 Log() << kFATAL << "<PDEFoam::FillFoamCells>: No cell found!" << Endl;
01365 return;
01366 }
01367
01368
01369 switch (ft) {
01370 case kSeparate:
01371 case kMultiTarget:
01372
01373
01374 SetCellElement(cell, 0, GetCellElement(cell, 0) + weight);
01375 SetCellElement(cell, 1, GetCellElement(cell, 1) + weight*weight);
01376 break;
01377
01378 case kDiscr:
01379
01380
01381 if (ev->GetClass() == 0)
01382 SetCellElement(cell, 0, GetCellElement(cell, 0) + weight);
01383 else
01384 SetCellElement(cell, 1, GetCellElement(cell, 1) + weight);
01385 break;
01386
01387 case kMonoTarget:
01388
01389
01390 SetCellElement(cell, 0, GetCellElement(cell, 0) + weight);
01391 SetCellElement(cell, 1, GetCellElement(cell, 1) + weight*targets.at(0));
01392 break;
01393
01394 default:
01395 Log() << kFATAL << "<FillFoamCells>: unmatched foam type!" << Endl;
01396 break;
01397 }
01398 }
01399
01400
01401 Double_t TMVA::PDEFoam::GetCellRegValue0( std::vector<Float_t> &xvec, EKernel kernel )
01402 {
01403
01404
01405
01406 std::vector<Float_t> txvec(VarTransform(xvec));
01407 PDEFoamCell *cell = FindCell(txvec);
01408
01409 if (!cell) {
01410 Log() << kFATAL << "<GetCellRegValue0> ERROR: No cell found!" << Endl;
01411 return -999.;
01412 }
01413
01414 switch (kernel) {
01415 case kNone:
01416 if (GetCellValue(cell, kTarget0Error) != -1)
01417
01418 return GetCellValue(cell, kTarget0);
01419 else
01420
01421 return GetAverageNeighborsValue(txvec, kTarget0);
01422 break;
01423
01424 case kGaus: {
01425
01426
01427 Double_t result = 0.;
01428 Double_t norm = 0.;
01429
01430 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01431 if (!(fCells[iCell]->GetStat())) continue;
01432
01433
01434 Double_t cell_val = 0;
01435 if (GetCellValue(fCells[iCell], kTarget0Error) != -1)
01436
01437 cell_val = GetCellValue(fCells[iCell], kTarget0);
01438 else
01439
01440 cell_val = GetAverageNeighborsValue(txvec, kTarget0);
01441 Double_t gau = WeightGaus(fCells[iCell], txvec);
01442
01443 result += gau * cell_val;
01444 norm += gau;
01445 }
01446 return result / norm;
01447 }
01448 break;
01449 case kLinN:
01450 if (GetCellValue(cell, kTarget0Error) != -1)
01451
01452 return WeightLinNeighbors(txvec, kTarget0, -1, -1, kTRUE);
01453 else
01454
01455
01456 return GetAverageNeighborsValue(txvec, kTarget0);
01457 break;
01458
01459 default:
01460 Log() << kFATAL << "<GetCellRegValue0>: unknown kernel!" << Endl;
01461 return 0.;
01462 }
01463
01464 return 0.;
01465 }
01466
01467
01468 Double_t TMVA::PDEFoam::GetAverageNeighborsValue( std::vector<Float_t> &txvec,
01469 ECellValue cv )
01470 {
01471
01472
01473
01474
01475
01476
01477
01478
01479 const Double_t xoffset = 1.e-6;
01480 Double_t norm = 0;
01481 Double_t result = 0;
01482
01483 PDEFoamCell *cell = FindCell(txvec);
01484 PDEFoamVect cellSize(GetTotDim());
01485 PDEFoamVect cellPosi(GetTotDim());
01486 cell->GetHcub(cellPosi, cellSize);
01487
01488
01489 for (Int_t dim=0; dim<GetTotDim(); dim++) {
01490 std::vector<Float_t> ntxvec(txvec);
01491 PDEFoamCell* left_cell = 0;
01492 PDEFoamCell* right_cell = 0;
01493
01494
01495 ntxvec[dim] = cellPosi[dim]-xoffset;
01496 left_cell = FindCell(ntxvec);
01497 if (!CellValueIsUndefined(left_cell)){
01498
01499 result += GetCellValue(left_cell, cv);
01500 norm++;
01501 }
01502
01503 ntxvec[dim] = cellPosi[dim]+cellSize[dim]+xoffset;
01504 right_cell = FindCell(ntxvec);
01505 if (!CellValueIsUndefined(right_cell)){
01506
01507 result += GetCellValue(right_cell, cv);
01508 norm++;
01509 }
01510 }
01511 if (norm>0) result /= norm;
01512 else result = 0;
01513
01514 return result;
01515 }
01516
01517
01518 Bool_t TMVA::PDEFoam::CellValueIsUndefined( PDEFoamCell* cell )
01519 {
01520
01521
01522 EFoamType ft = GetFoamType();
01523 switch(ft){
01524 case kSeparate:
01525 return kFALSE;
01526 case kDiscr:
01527 return kFALSE;
01528 case kMonoTarget:
01529 return GetCellValue(cell, kTarget0Error) == -1;
01530 case kMultiTarget:
01531 return kFALSE;
01532 default:
01533 return kFALSE;
01534 }
01535 return kFALSE;
01536 }
01537
01538
01539 std::vector<Float_t> TMVA::PDEFoam::GetCellTargets( std::vector<Float_t> &tvals, ETargetSelection ts )
01540 {
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554 std::vector<Float_t> target(GetTotDim()-tvals.size(), 0);
01555 std::vector<Float_t> norm(target);
01556 Double_t max_dens = 0.;
01557
01558
01559 std::vector<PDEFoamCell*> cells = FindCells(tvals);
01560 if (cells.size()<1) return target;
01561
01562
01563 std::vector<PDEFoamCell*>::iterator cell_it(cells.begin());
01564 for (cell_it=cells.begin(); cell_it!=cells.end(); cell_it++){
01565
01566
01567 Double_t cell_density = GetCellValue(*cell_it, kDensity);
01568
01569
01570 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
01571 (*cell_it)->GetHcub(cellPosi, cellSize);
01572
01573
01574
01575 if (ts==kMean){
01576
01577 for (UInt_t itar=0; itar<target.size(); itar++){
01578 UInt_t idim = itar+tvals.size();
01579 target.at(itar) += cell_density *
01580 VarTransformInvers(idim, cellPosi[idim]+0.5*cellSize[idim]);
01581 norm.at(itar) += cell_density;
01582 }
01583 } else {
01584
01585 if (cell_density > max_dens){
01586 max_dens = cell_density;
01587
01588 for (UInt_t itar=0; itar<target.size(); itar++){
01589 UInt_t idim = itar+tvals.size();
01590 target.at(itar) =
01591 VarTransformInvers(idim, cellPosi[idim]+0.5*cellSize[idim]);
01592 }
01593 }
01594 }
01595 }
01596
01597
01598 if (ts==kMean){
01599 for (UInt_t itar=0; itar<target.size(); itar++){
01600 if (norm.at(itar)>1.0e-15)
01601 target.at(itar) /= norm.at(itar);
01602 else
01603
01604
01605 target.at(itar) = (fXmax[itar+tvals.size()]-fXmin[itar+tvals.size()])/2.;
01606 }
01607 }
01608
01609 return target;
01610 }
01611
01612
01613 std::vector<Float_t> TMVA::PDEFoam::GetProjectedRegValue( std::vector<Float_t> &vals, EKernel kernel, ETargetSelection ts )
01614 {
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626 const Float_t xsmall = 1.e-7;
01627 for (UInt_t l=0; l<vals.size(); l++) {
01628 if (vals.at(l) <= fXmin[l]){
01629 vals.at(l) = fXmin[l] + xsmall;
01630 }
01631 else if (vals.at(l) >= fXmax[l]){
01632 vals.at(l) = fXmax[l] - xsmall;
01633 }
01634 }
01635
01636
01637 std::vector<Float_t> txvec(VarTransform(vals));
01638
01639
01640 switch (kernel) {
01641 case kNone:
01642 return GetCellTargets(txvec, ts);
01643
01644 case kGaus: {
01645
01646 std::vector<Float_t> target(GetTotDim()-txvec.size(), 0);
01647 std::vector<Float_t> norm(target);
01648
01649
01650 for (Long_t ice=0; ice<=fLastCe; ice++) {
01651 if (!(fCells[ice]->GetStat())) continue;
01652
01653
01654 Double_t gau = WeightGaus(fCells[ice], txvec, vals.size());
01655
01656 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
01657 fCells[ice]->GetHcub(cellPosi, cellSize);
01658
01659
01660 std::vector<Float_t> new_vec;
01661 for (UInt_t k=0; k<txvec.size(); k++)
01662 new_vec.push_back(cellPosi[k] + 0.5*cellSize[k]);
01663
01664 std::vector<Float_t> val = GetCellTargets(new_vec, ts);
01665 for (UInt_t itar=0; itar<target.size(); itar++){
01666 target.at(itar) += gau * val.at(itar);
01667 norm.at(itar) += gau;
01668 }
01669 }
01670
01671
01672 for (UInt_t itar=0; itar<target.size(); itar++){
01673 if (norm.at(itar)<1.0e-20){
01674 Log() << kWARNING << "Warning: norm too small!" << Endl;
01675 target.at(itar) = 0.;
01676 } else
01677 target.at(itar) /= norm.at(itar);
01678 }
01679 return target;
01680 }
01681 break;
01682
01683 default:
01684 Log() << kFATAL << "<GetProjectedRegValue>: unsupported kernel!" << Endl;
01685 return std::vector<Float_t>(GetTotDim()-txvec.size(), 0);
01686 }
01687
01688 return std::vector<Float_t>(GetTotDim()-txvec.size(), 0);
01689 }
01690
01691
01692 Double_t TMVA::PDEFoam::GetCellDensity( std::vector<Float_t> &xvec, EKernel kernel )
01693 {
01694
01695
01696
01697
01698
01699 std::vector<Float_t> txvec(VarTransform(xvec));
01700 PDEFoamCell *cell = FindCell(txvec);
01701
01702 if (!cell) {
01703 Log() << kFATAL << "<GetCellDensity(event)> ERROR: No cell found!" << Endl;
01704 return -999.;
01705 }
01706
01707 switch (kernel) {
01708 case kNone:
01709
01710 return GetCellValue(cell, kDensity);
01711
01712 case kGaus: {
01713
01714
01715 Double_t result = 0;
01716 Double_t norm = 0.;
01717
01718 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
01719 if (!(fCells[iCell]->GetStat())) continue;
01720
01721
01722 Double_t cell_dens = GetCellValue(fCells[iCell], kDensity);
01723 Double_t gau = WeightGaus(fCells[iCell], txvec);
01724
01725 result += gau * cell_dens;
01726 norm += gau;
01727 }
01728
01729 return result / norm;
01730 }
01731 break;
01732
01733 case kLinN:
01734 return WeightLinNeighbors(txvec, kDensity);
01735
01736 default:
01737 Log() << kFATAL << "<GetCellDensity(event)> unknown kernel!" << Endl;
01738 return 0.;
01739 }
01740
01741 return 0;
01742 }
01743
01744
01745 Double_t TMVA::PDEFoam::GetCellValue( PDEFoamCell* cell, ECellValue cv )
01746 {
01747
01748
01749
01750
01751 switch(cv){
01752
01753 case kTarget0:
01754 if (GetFoamType() == kMonoTarget) return GetCellElement(cell, 0);
01755 break;
01756
01757 case kTarget0Error:
01758 if (GetFoamType() == kMonoTarget) return GetCellElement(cell, 1);
01759 break;
01760
01761 case kDiscriminator:
01762 if (GetFoamType() == kDiscr) return GetCellElement(cell, 0);
01763 break;
01764
01765 case kDiscriminatorError:
01766 if (GetFoamType() == kDiscr) return GetCellElement(cell, 1);
01767 break;
01768
01769 case kMeanValue:
01770 return cell->GetIntg();
01771 break;
01772
01773 case kRms:
01774 return cell->GetDriv();
01775 break;
01776
01777 case kRmsOvMean:
01778 if (cell->GetIntg() != 0) return cell->GetDriv()/cell->GetIntg();
01779 break;
01780
01781 case kNev:
01782 if (GetFoamType() == kSeparate || GetFoamType() == kMultiTarget)
01783 return GetCellElement(cell, 0);
01784 break;
01785
01786 case kDensity: {
01787
01788 Double_t volume = cell->GetVolume();
01789 if ( volume > 1.0e-10 ){
01790 return GetCellValue(cell, kNev)/volume;
01791 } else {
01792 if (volume<=0){
01793 cell->Print("1");
01794 Log() << kWARNING << "<GetCellDensity(cell)>: ERROR: cell volume"
01795 << " negative or zero!"
01796 << " ==> return cell density 0!"
01797 << " cell volume=" << volume
01798 << " cell entries=" << GetCellValue(cell, kNev) << Endl;
01799 return 0;
01800 } else
01801 Log() << kWARNING << "<GetCellDensity(cell)>: WARNING: cell volume"
01802 << " close to zero!"
01803 << " cell volume: " << volume << Endl;
01804 }
01805 }
01806
01807 default:
01808 return 0;
01809 }
01810
01811 return 0;
01812 }
01813
01814
01815 Double_t TMVA::PDEFoam::GetCellValue(std::vector<Float_t> &xvec, ECellValue cv)
01816 {
01817
01818
01819
01820
01821 std::vector<Float_t> txvec(VarTransform(xvec));
01822 return GetCellValue(FindCell(txvec), cv);
01823 }
01824
01825
01826 Double_t TMVA::PDEFoam::GetBuildUpCellEvents( PDEFoamCell* cell )
01827 {
01828
01829
01830 return GetCellElement(cell, 0);
01831 }
01832
01833
01834 Double_t TMVA::PDEFoam::WeightLinNeighbors( std::vector<Float_t> &txvec, ECellValue cv, Int_t dim1, Int_t dim2, Bool_t TreatEmptyCells )
01835 {
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859 Double_t result = 0.;
01860 UInt_t norm = 0;
01861 const Double_t xoffset = 1.e-6;
01862
01863 if (txvec.size() != UInt_t(GetTotDim()))
01864 Log() << kFATAL << "Wrong dimension of event variable!" << Endl;
01865
01866
01867 PDEFoamCell *cell= FindCell(txvec);
01868 PDEFoamVect cellSize(GetTotDim());
01869 PDEFoamVect cellPosi(GetTotDim());
01870 cell->GetHcub(cellPosi, cellSize);
01871
01872 Double_t cellval = 0;
01873 if (!(TreatEmptyCells && CellValueIsUndefined(cell)))
01874
01875 cellval = GetCellValue(cell, cv);
01876 else
01877
01878
01879 cellval = GetAverageNeighborsValue(txvec, cv);
01880
01881
01882 for (Int_t dim=0; dim<GetTotDim(); dim++) {
01883 std::vector<Float_t> ntxvec(txvec);
01884 Double_t mindist;
01885 PDEFoamCell *mindistcell = 0;
01886
01887 mindist = (txvec[dim]-cellPosi[dim])/cellSize[dim];
01888 if (mindist<0.5) {
01889 ntxvec[dim] = cellPosi[dim]-xoffset;
01890 mindistcell = FindCell(ntxvec);
01891 } else {
01892 mindist=1-mindist;
01893 ntxvec[dim] = cellPosi[dim]+cellSize[dim]+xoffset;
01894 mindistcell = FindCell(ntxvec);
01895 }
01896 Double_t mindistcellval = 0;
01897 if (dim1>=0 && dim1<GetTotDim() &&
01898 dim2>=0 && dim2<GetTotDim() &&
01899 dim1!=dim2){
01900 cellval = GetProjectionCellValue(cell, dim1, dim2, cv);
01901 mindistcellval = GetProjectionCellValue(mindistcell, dim1, dim2, cv);
01902 } else {
01903 mindistcellval = GetCellValue(mindistcell, cv);
01904 }
01905
01906
01907 if (!(TreatEmptyCells && CellValueIsUndefined(mindistcell))){
01908 result += cellval * (0.5 + mindist);
01909 result += mindistcellval * (0.5 - mindist);
01910 norm++;
01911 }
01912 }
01913 if (norm==0) return cellval;
01914 else return result/norm;
01915 }
01916
01917
01918 Float_t TMVA::PDEFoam::WeightGaus( PDEFoamCell* cell, std::vector<Float_t> &txvec,
01919 UInt_t dim )
01920 {
01921
01922
01923
01924
01925
01926
01927
01928
01929
01930
01931
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941 PDEFoamVect cellSize(GetTotDim());
01942 PDEFoamVect cellPosi(GetTotDim());
01943 cell->GetHcub(cellPosi, cellSize);
01944
01945
01946 UInt_t dims;
01947 if (dim == 0)
01948 dims = GetTotDim();
01949 else if (dim <= UInt_t(GetTotDim()))
01950 dims = dim;
01951 else {
01952 Log() << kFATAL << "ERROR: too many given dimensions for Gaus weight!" << Endl;
01953 return 0.;
01954 }
01955
01956
01957 std::vector<Float_t> cell_center;
01958 for (UInt_t i=0; i<dims; i++){
01959 if (txvec[i]<0.) txvec[i]=0.;
01960 if (txvec[i]>1.) txvec[i]=1.;
01961
01962 if (cellPosi[i] > txvec.at(i))
01963 cell_center.push_back(cellPosi[i]);
01964 else if (cellPosi[i]+cellSize[i] < txvec.at(i))
01965 cell_center.push_back(cellPosi[i]+cellSize[i]);
01966 else
01967 cell_center.push_back(txvec.at(i));
01968 }
01969
01970 Float_t distance = 0.;
01971 for (UInt_t i=0; i<dims; i++)
01972 distance += Sqr(txvec.at(i)-cell_center.at(i));
01973 distance = TMath::Sqrt(distance);
01974
01975 Float_t width = 1./GetVolumeFraction();
01976 if (width < 1.0e-10)
01977 Log() << kWARNING << "Warning: wrong volume fraction: " << GetVolumeFraction() << Endl;
01978
01979
01980 return TMath::Gaus(distance, 0, width, kFALSE);
01981 }
01982
01983
01984 TMVA::PDEFoamCell* TMVA::PDEFoam::FindCell( std::vector<Float_t> &xvec )
01985 {
01986
01987
01988
01989
01990
01991
01992
01993
01994 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
01995 PDEFoamCell *cell, *cell0;
01996
01997 cell=fCells[0];
01998 Int_t idim=0;
01999 while (cell->GetStat()!=1) {
02000 idim=cell->GetBest();
02001 cell0=cell->GetDau0();
02002 cell0->GetHcub(cellPosi0,cellSize0);
02003
02004 if (xvec.at(idim)<=cellPosi0[idim]+cellSize0[idim])
02005 cell=cell0;
02006 else
02007 cell=(cell->GetDau1());
02008 }
02009 return cell;
02010 }
02011
02012
02013 void TMVA::PDEFoam::FindCellsRecursive(std::vector<Float_t> &txvec, PDEFoamCell* cell, std::vector<PDEFoamCell*> &cells)
02014 {
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
02030 PDEFoamCell *cell0;
02031 Int_t idim=0;
02032
02033 while (cell->GetStat()!=1) {
02034 idim=cell->GetBest();
02035
02036 if (idim < Int_t(txvec.size())){
02037
02038 cell0=cell->GetDau0();
02039 cell0->GetHcub(cellPosi0,cellSize0);
02040
02041 if (txvec.at(idim)<=cellPosi0[idim]+cellSize0[idim])
02042 cell=cell0;
02043 else
02044 cell=cell->GetDau1();
02045 } else {
02046
02047 FindCellsRecursive(txvec, cell->GetDau0(), cells);
02048 FindCellsRecursive(txvec, cell->GetDau1(), cells);
02049 return;
02050 }
02051 }
02052 cells.push_back(cell);
02053 }
02054
02055
02056 std::vector<TMVA::PDEFoamCell*> TMVA::PDEFoam::FindCells(std::vector<Float_t> &txvec)
02057 {
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071 std::vector<PDEFoamCell*> cells(0);
02072
02073
02074 FindCellsRecursive(txvec, fCells[0], cells);
02075
02076 return cells;
02077 }
02078
02079
02080 TH1D* TMVA::PDEFoam::Draw1Dim( const char *opt, Int_t nbin )
02081 {
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100 if ( GetTotDim()!=1 ) return 0;
02101
02102
02103 ECellValue cell_value = kNev;
02104 EFoamType foam_type = GetFoamType();
02105 if (strcmp(opt,"cell_value")==0){
02106 switch (foam_type) {
02107 case kSeparate:
02108 case kMultiTarget:
02109 cell_value = kNev;
02110 break;
02111 case kDiscr:
02112 cell_value = kDiscriminator;
02113 break;
02114 case kMonoTarget:
02115 cell_value = kTarget0;
02116 break;
02117 default:
02118 Log() << kFATAL << "<Draw1Dim>: unknown foam type" << Endl;
02119 return 0;
02120 }
02121 } else if (strcmp(opt,"rms")==0){
02122 cell_value = kRms;
02123 } else if (strcmp(opt,"rms_ov_mean")==0){
02124 cell_value = kRmsOvMean;
02125 } else {
02126 Log() << kFATAL << "<Draw1Dim>: unknown option:" << opt << Endl;
02127 return 0;
02128 }
02129
02130
02131 TString hname(Form("h%s",opt));
02132
02133 TH1D* h1=(TH1D*)gDirectory->Get(hname);
02134 if (h1) delete h1;
02135 h1= new TH1D(hname, Form("1-dimensional Foam: %s", opt), nbin, fXmin[0], fXmax[0]);
02136
02137 if (!h1) Log() << kFATAL << "ERROR: Can not create histo" << hname << Endl;
02138
02139 std::vector<Float_t> xvec(GetTotDim(), 0.);
02140
02141
02142 for (Int_t ibinx=1; ibinx<=nbin; ibinx++) {
02143 xvec.at(0) = h1->GetBinCenter(ibinx);
02144
02145
02146 std::vector<Float_t> txvec(VarTransform(xvec));
02147
02148
02149 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
02150 if (!(fCells[iCell]->GetStat())) continue;
02151
02152
02153 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
02154 fCells[iCell]->GetHcub(cellPosi,cellSize);
02155
02156
02157 const Double_t xsmall = 1.e-10;
02158 if (!( (txvec.at(0)>cellPosi[0]-xsmall) &&
02159 (txvec.at(0)<=cellPosi[0]+cellSize[0]+xsmall) ) )
02160 continue;
02161
02162 Double_t vol = fCells[iCell]->GetVolume();
02163 if (vol<1e-10) {
02164 Log() << kWARNING << "Project: ERROR: Volume too small!" << Endl;
02165 continue;
02166 }
02167
02168
02169 h1->SetBinContent(ibinx,
02170 GetCellValue(fCells[iCell], cell_value) + h1->GetBinContent(ibinx));
02171 }
02172 }
02173 return h1;
02174 }
02175
02176
02177 TH2D* TMVA::PDEFoam::Project2( Int_t idim1, Int_t idim2, const char *opt, const char *ker, UInt_t nbin )
02178 {
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202 if ((idim1>=GetTotDim()) || (idim1<0) ||
02203 (idim2>=GetTotDim()) || (idim2<0) ||
02204 (idim1==idim2) )
02205 return 0;
02206
02207
02208 ECellValue cell_value = kNev;
02209 EFoamType foam_type = GetFoamType();
02210 if (strcmp(opt,"cell_value")==0){
02211 switch (foam_type) {
02212 case kSeparate:
02213 case kMultiTarget:
02214 cell_value = kNev;
02215 break;
02216 case kDiscr:
02217 cell_value = kDiscriminator;
02218 break;
02219 case kMonoTarget:
02220 cell_value = kTarget0;
02221 break;
02222 default:
02223 Log() << kFATAL << "<Draw1Dim>: unknown foam type" << Endl;
02224 return 0;
02225 }
02226 } else if (strcmp(opt,"rms")==0){
02227 cell_value = kRms;
02228 } else if (strcmp(opt,"rms_ov_mean")==0){
02229 cell_value = kRmsOvMean;
02230 } else {
02231 Log() << kFATAL << "unknown option given" << Endl;
02232 return 0;
02233 }
02234
02235
02236 EKernel kernel = kNone;
02237 if (!strcmp(ker, "kNone"))
02238 kernel = kNone;
02239 else if (!strcmp(ker, "kGaus"))
02240 kernel = kGaus;
02241 else if (!strcmp(ker, "kLinN"))
02242 kernel = kLinN;
02243 else
02244 Log() << kWARNING << "Warning: wrong kernel! using kNone instead" << Endl;
02245
02246
02247
02248
02249 if (nbin>1000){
02250 Log() << kWARNING << "Warning: number of bins too big: " << nbin
02251 << " Using 1000 bins for each dimension instead." << Endl;
02252 nbin = 1000;
02253 } else if (nbin<1) {
02254 Log() << kWARNING << "Wrong bin number: " << nbin
02255 << "; set nbin=50" << Endl;
02256 nbin = 50;
02257 }
02258
02259
02260 TString hname(Form("h%s_%d_vs_%d",opt,idim1,idim2));
02261
02262
02263 TH2D* h1=(TH2D*)gDirectory->Get(hname.Data());
02264 if (h1) delete h1;
02265 h1= new TH2D(hname.Data(), Form("%s var%d vs var%d",opt,idim1,idim2), nbin, fXmin[idim1], fXmax[idim1], nbin, fXmin[idim2], fXmax[idim2]);
02266
02267 if (!h1) Log() << kFATAL << "ERROR: Can not create histo" << hname << Endl;
02268
02269
02270
02271 for (Long_t iCell=0; iCell<=fLastCe; iCell++) {
02272 if (!(fCells[iCell]->GetStat())) continue;
02273
02274
02275 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
02276 fCells[iCell]->GetHcub(cellPosi,cellSize);
02277
02278
02279
02280 Double_t var = GetProjectionCellValue(fCells[iCell], idim1, idim2, cell_value);
02281
02282
02283 Double_t x1 = VarTransformInvers( idim1, cellPosi[idim1] );
02284 Double_t y1 = VarTransformInvers( idim2, cellPosi[idim2] );
02285
02286
02287 Double_t x2 = VarTransformInvers( idim1, cellPosi[idim1]+cellSize[idim1] );
02288 Double_t y2 = VarTransformInvers( idim2, cellPosi[idim2]+cellSize[idim2] );
02289
02290
02291
02292 Int_t xbin_start = TMath::Max(1, h1->GetXaxis()->FindBin(x1));
02293 Int_t xbin_stop = h1->GetXaxis()->FindBin(x2);
02294
02295
02296 Int_t ybin_start = TMath::Max(1, h1->GetYaxis()->FindBin(y1));
02297 Int_t ybin_stop = h1->GetYaxis()->FindBin(y2);
02298
02299
02300 for (Int_t ibinx=xbin_start; ibinx<xbin_stop; ibinx++) {
02301 for (Int_t ibiny=ybin_start; ibiny<ybin_stop; ibiny++) {
02302
02303
02304 if (kernel == kGaus){
02305 Double_t result = 0.;
02306 Double_t norm = 0.;
02307
02308
02309 Double_t x_curr =
02310 VarTransform( idim1, ((x2-x1)*ibinx - x2*xbin_start + x1*xbin_stop)/(xbin_stop-xbin_start) );
02311 Double_t y_curr =
02312 VarTransform( idim2, ((y2-y1)*ibiny - y2*ybin_start + y1*ybin_stop)/(ybin_stop-ybin_start) );
02313
02314
02315 for (Long_t ice=0; ice<=fLastCe; ice++) {
02316 if (!(fCells[ice]->GetStat())) continue;
02317
02318
02319 Double_t cell_var = GetProjectionCellValue(fCells[ice], idim1, idim2, cell_value);
02320
02321
02322 std::vector<Float_t> coor;
02323 for (Int_t i=0; i<GetTotDim(); i++) {
02324 if (i == idim1)
02325 coor.push_back(x_curr);
02326 else if (i == idim2)
02327 coor.push_back(y_curr);
02328 else
02329 coor.push_back(cellPosi[i] + 0.5*cellSize[i]);
02330 }
02331
02332
02333 Double_t weight_ = WeightGaus(fCells[ice], coor);
02334
02335 result += weight_ * cell_var;
02336 norm += weight_;
02337 }
02338 var = result/norm;
02339 }
02340 else if (kernel == kLinN){
02341
02342 Double_t x_curr =
02343 VarTransform( idim1, ((x2-x1)*ibinx - x2*xbin_start + x1*xbin_stop)/(xbin_stop-xbin_start) );
02344 Double_t y_curr =
02345 VarTransform( idim2, ((y2-y1)*ibiny - y2*ybin_start + y1*ybin_stop)/(ybin_stop-ybin_start) );
02346
02347
02348 std::vector<Float_t> coor;
02349 for (Int_t i=0; i<GetTotDim(); i++) {
02350 if (i == idim1)
02351 coor.push_back(x_curr);
02352 else if (i == idim2)
02353 coor.push_back(y_curr);
02354 else
02355 coor.push_back(cellPosi[i] + 0.5*cellSize[i]);
02356 }
02357
02358 var = WeightLinNeighbors(coor, cell_value, idim1, idim2);
02359 }
02360
02361
02362
02363 h1->SetBinContent(ibinx, ibiny, var + h1->GetBinContent(ibinx, ibiny));
02364 }
02365 }
02366 }
02367
02368 return h1;
02369 }
02370
02371
02372 Double_t TMVA::PDEFoam::GetProjectionCellValue( PDEFoamCell* cell,
02373 Int_t idim1,
02374 Int_t idim2,
02375 ECellValue cv )
02376 {
02377
02378
02379
02380
02381
02382
02383 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
02384 cell->GetHcub(cellPosi,cellSize);
02385 const Double_t foam_area = (fXmax[idim1]-fXmin[idim1])*(fXmax[idim2]-fXmin[idim2]);
02386
02387
02388 switch (cv) {
02389 case kNev: {
02390
02391 Double_t area = cellSize[idim1] * cellSize[idim2];
02392 if (area<1e-20){
02393 Log() << kWARNING << "<Project2>: Warning, cell volume too small --> skiping cell!" << Endl;
02394 return 0;
02395 }
02396
02397
02398 return GetCellValue(cell, kNev)/(area*foam_area);
02399 }
02400
02401 case kRms:
02402 return GetCellValue(cell, kRms);
02403
02404 case kRmsOvMean:
02405 return GetCellValue(cell, kRmsOvMean);
02406
02407 case kDiscriminator: {
02408
02409 Double_t area_cell = 1.;
02410 for (Int_t d1=0; d1<GetTotDim(); d1++){
02411 if ((d1!=idim1) && (d1!=idim2))
02412 area_cell *= cellSize[d1];
02413 }
02414 if (area_cell<1e-20){
02415 Log() << kWARNING << "<Project2>: Warning, cell volume too small --> skiping cell!" << Endl;
02416 return 0;
02417 }
02418
02419
02420
02421 return GetCellValue(cell, kDiscriminator)*area_cell;
02422 }
02423
02424 case kDiscriminatorError:
02425 return GetCellValue(cell, kDiscriminator);
02426
02427 case kTarget0:
02428
02429 return GetCellValue(cell, kTarget0);
02430 default:
02431 Log() << kFATAL << "<Project2>: unknown option" << Endl;
02432 return 0;
02433 }
02434 }
02435
02436
02437 Double_t TMVA::PDEFoam::GetCellElement( PDEFoamCell *cell, UInt_t i )
02438 {
02439
02440
02441 if (i >= GetNElements()) Log() << kFATAL << "ERROR: Index out of range" << Endl;
02442
02443
02444 TVectorD *vec = (TVectorD*)cell->GetElement();
02445
02446 if (!vec) Log() << kFATAL << "<GetCellElement> ERROR: cell element is not a TVectorD*" << Endl;
02447
02448 return (*vec)(i);
02449 }
02450
02451
02452 void TMVA::PDEFoam::SetCellElement( PDEFoamCell *cell, UInt_t i, Double_t value )
02453 {
02454
02455
02456 if (i >= GetNElements()) {
02457 Log() << kFATAL << "ERROR: Index out of range" << Endl;
02458 return;
02459 }
02460
02461
02462 TVectorD *vec = (TVectorD*)cell->GetElement();
02463
02464 if (!vec) Log() << kFATAL << "<SetCellElement> ERROR: cell element is not a TVectorD*" << Endl;
02465
02466 (*vec)(i) = value;
02467 }
02468
02469
02470 void TMVA::PDEFoam::OutputGrow( Bool_t finished )
02471 {
02472
02473
02474
02475 if (finished) {
02476 Log() << kINFO << "Elapsed time: " + fTimer->GetElapsedTime()
02477 << " " << Endl;
02478 return;
02479 }
02480
02481 Int_t modulo = 1;
02482
02483 if (fNCells >= 100) modulo = Int_t(fNCells/100);
02484 if (fLastCe%modulo == 0) fTimer->DrawProgressBar( fLastCe );
02485 }
02486
02487
02488 void TMVA::PDEFoam::RootPlot2dim( const TString& filename, TString opt,
02489 Bool_t CreateCanvas, Bool_t colors, Bool_t log_colors )
02490 {
02491
02492
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529 if (GetTotDim() != 2)
02530 Log() << kFATAL << "RootPlot2dim() can only be used with "
02531 << "two-dimensional foams!" << Endl;
02532
02533
02534 ECellValue cell_value = kNev;
02535 EFoamType foam_type = GetFoamType();
02536 Bool_t plotcellnumber = kFALSE;
02537 Bool_t fillcells = kTRUE;
02538 if (opt.Contains("cell_value")){
02539 switch (foam_type) {
02540 case kSeparate:
02541 case kMultiTarget:
02542 cell_value = kNev;
02543 break;
02544 case kDiscr:
02545 cell_value = kDiscriminator;
02546 break;
02547 case kMonoTarget:
02548 cell_value = kTarget0;
02549 break;
02550 default:
02551 Log() << kFATAL << "<Draw1Dim>: unknown foam type" << Endl;
02552 return;
02553 }
02554 } else if (opt.Contains("rms_ov_mean")){
02555 cell_value = kRmsOvMean;
02556 } else if (opt.Contains("rms")){
02557 cell_value = kRms;
02558 } else {
02559 fillcells = kFALSE;
02560 }
02561 if (opt.Contains("cellnumber"))
02562 plotcellnumber = kTRUE;
02563
02564
02565 std::ofstream outfile(filename, std::ios::out);
02566
02567 outfile<<"{" << std::endl;
02568
02569
02570 if (!colors) {
02571
02572 outfile << "TColor *graycolors[100];" << std::endl;
02573 outfile << "for (Int_t i=0.; i<100; i++)" << std::endl;
02574 outfile << " graycolors[i]=new TColor(1000+i, 1-(Float_t)i/100.,1-(Float_t)i/100.,1-(Float_t)i/100.);"<< std::endl;
02575 }
02576 if (CreateCanvas)
02577 outfile << "cMap = new TCanvas(\"" << fName << "\",\"Cell Map for "
02578 << fName << "\",600,600);" << std::endl;
02579
02580 outfile<<"TBox*a=new TBox();"<<std::endl;
02581 outfile<<"a->SetFillStyle(0);"<<std::endl;
02582 outfile<<"a->SetLineWidth(4);"<<std::endl;
02583 outfile<<"TBox *b1=new TBox();"<<std::endl;
02584 outfile<<"TText*t=new TText();"<<endl;
02585 if (fillcells) {
02586 outfile << (colors ? "gStyle->SetPalette(1, 0);" : "gStyle->SetPalette(0);")
02587 << std::endl;
02588 outfile <<"b1->SetFillStyle(1001);"<<std::endl;
02589 outfile<<"TBox *b2=new TBox();"<<std::endl;
02590 outfile <<"b2->SetFillStyle(0);"<<std::endl;
02591 }
02592 else {
02593 outfile <<"b1->SetFillStyle(0);"<<std::endl;
02594 }
02595
02596 if (fillcells)
02597 (colors ? gStyle->SetPalette(1, 0) : gStyle->SetPalette(0) );
02598
02599 Double_t zmin = 1E8;
02600 Double_t zmax = -1E8;
02601
02602
02603
02604 if (fillcells) {
02605 for (Long_t iCell=1; iCell<=fLastCe; iCell++) {
02606 if ( fCells[iCell]->GetStat() == 1) {
02607 Double_t value = GetCellValue(fCells[iCell], cell_value);
02608 if (value<zmin)
02609 zmin=value;
02610 if (value>zmax)
02611 zmax=value;
02612 }
02613 }
02614 outfile << "// observed minimum and maximum of distribution: " << std::endl;
02615 outfile << "// Double_t zmin = "<< zmin << ";" << std::endl;
02616 outfile << "// Double_t zmax = "<< zmax << ";" << std::endl;
02617 }
02618
02619 if (log_colors) {
02620 if (zmin<1)
02621 zmin=1;
02622 zmin=TMath::Log(zmin);
02623 zmax=TMath::Log(zmax);
02624 outfile << "// logarthmic color scale used " << std::endl;
02625 }
02626 else outfile << "// linear color scale used " << std::endl;
02627
02628 outfile << "// used minimum and maximum of distribution (taking into account log scale if applicable): " << std::endl;
02629 outfile << "Double_t zmin = "<< zmin << ";" << std::endl;
02630 outfile << "Double_t zmax = "<< zmax << ";" << std::endl;
02631
02632 Double_t x1,y1,x2,y2,x,y;
02633 Double_t offs = 0.01;
02634 Double_t lpag = 1-2*offs;
02635 Int_t ncolors = colors ? gStyle->GetNumberOfColors() : 100;
02636 Double_t scale = (ncolors-1)/(zmax - zmin);
02637 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
02638
02639
02640
02641 outfile << "// =========== Rectangular cells ==========="<< std::endl;
02642 for (Long_t iCell=1; iCell<=fLastCe; iCell++) {
02643 if ( fCells[iCell]->GetStat() == 1) {
02644 fCells[iCell]->GetHcub(cellPosi,cellSize);
02645 x1 = offs+lpag*(cellPosi[0]);
02646 y1 = offs+lpag*(cellPosi[1]);
02647 x2 = offs+lpag*(cellPosi[0]+cellSize[0]);
02648 y2 = offs+lpag*(cellPosi[1]+cellSize[1]);
02649
02650 if (fillcells) {
02651
02652 Double_t value = GetCellValue(fCells[iCell], cell_value);
02653
02654 if (log_colors) {
02655 if (value<1.) value=1;
02656 value = TMath::Log(value);
02657 }
02658
02659
02660 Int_t color;
02661 if (colors)
02662 color = gStyle->GetColorPalette(Int_t((value-zmin)*scale));
02663 else
02664 color = 1000+(Int_t((value-zmin)*scale));
02665
02666
02667 outfile << "b1->SetFillColor(" << color << ");" << std::endl;
02668 }
02669
02670
02671 outfile<<"b1->DrawBox("<<x1<<","<<y1<<","<<x2<<","<<y2<<");"<<std::endl;
02672 if (fillcells)
02673 outfile<<"b2->DrawBox("<<x1<<","<<y1<<","<<x2<<","<<y2<<");"<<std::endl;
02674
02675
02676 if (plotcellnumber) {
02677 outfile<<"t->SetTextColor(4);"<<endl;
02678 if(fLastCe<51)
02679 outfile<<"t->SetTextSize(0.025);"<<endl;
02680 else if(fLastCe<251)
02681 outfile<<"t->SetTextSize(0.015);"<<endl;
02682 else
02683 outfile<<"t->SetTextSize(0.008);"<<endl;
02684 x = offs+lpag*(cellPosi[0]+0.5*cellSize[0]);
02685 y = offs+lpag*(cellPosi[1]+0.5*cellSize[1]);
02686 outfile<<"t->DrawText("<<x<<","<<y<<","<<"\""<<iCell<<"\""<<");"<<endl;
02687 }
02688 }
02689 }
02690 outfile<<"// ============== End Rectangles ==========="<< std::endl;
02691
02692 outfile << "}" << std::endl;
02693 outfile.flush();
02694 outfile.close();
02695 }
02696
02697
02698 void TMVA::PDEFoam::FillBinarySearchTree( const Event* ev, Bool_t NoNegWeights )
02699 {
02700
02701 GetDistr()->FillBinarySearchTree(ev, GetFoamType(), NoNegWeights);
02702 }
02703
02704
02705 void TMVA::PDEFoam::DeleteBinarySearchTree()
02706 {
02707
02708 if(fDistr) delete fDistr;
02709 fDistr = NULL;
02710 }
02711
02712
02713 void TMVA::PDEFoam::Init()
02714 {
02715
02716
02717 GetDistr()->SetPDEFoam(this);
02718 GetDistr()->Initialize();
02719 }
02720
02721
02722 void TMVA::PDEFoam::SetFoamType( EFoamType ft )
02723 {
02724
02725
02726 switch (ft) {
02727 case kDiscr:
02728 GetDistr()->SetDensityCalc(kDISCRIMINATOR);
02729 break;
02730 case kMonoTarget:
02731 GetDistr()->SetDensityCalc(kTARGET);
02732 break;
02733 default:
02734 GetDistr()->SetDensityCalc(kEVENT_DENSITY);
02735 break;
02736 }
02737
02738 fFoamType = ft;
02739 }
02740
02741
02742 ostream& TMVA::operator<< ( ostream& os, const TMVA::PDEFoam& pdefoam )
02743 {
02744
02745 pdefoam.PrintStream(os);
02746 return os;
02747 }
02748
02749
02750 istream& TMVA::operator>> ( istream& istr, TMVA::PDEFoam& pdefoam )
02751 {
02752
02753 pdefoam.ReadStream(istr);
02754 return istr;
02755 }
02756
02757
02758 void TMVA::PDEFoam::ReadStream( istream & istr )
02759 {
02760
02761
02762
02763 istr >> fLastCe;
02764 istr >> fNCells;
02765
02766 istr >> fDim;
02767 if (fDim < 1 || fDim >= INT_MAX) {
02768 Log() << kERROR << "Foam dimension " << GetTotDim() << "our of range!" << Endl;
02769 return;
02770 }
02771
02772 Double_t vfr = -1.;
02773 istr >> vfr;
02774 SetVolumeFraction(vfr);
02775
02776 Log() << kVERBOSE << "Foam dimension: " << GetTotDim() << Endl;
02777
02778
02779 if (fXmin) delete [] fXmin;
02780 if (fXmax) delete [] fXmax;
02781 fXmin = new Double_t[GetTotDim()];
02782 fXmax = new Double_t[GetTotDim()];
02783 for (Int_t i=0; i<GetTotDim(); i++)
02784 istr >> fXmin[i];
02785 for (Int_t i=0; i<GetTotDim(); i++)
02786 istr >> fXmax[i];
02787 }
02788
02789
02790 void TMVA::PDEFoam::PrintStream( ostream & ostr ) const
02791 {
02792
02793
02794
02795 ostr << fLastCe << std::endl;
02796 ostr << fNCells << std::endl;
02797 ostr << fDim << std::endl;
02798 ostr << GetVolumeFraction() << std::endl;
02799
02800
02801 for (Int_t i=0; i<GetTotDim(); i++)
02802 ostr << fXmin[i] << std::endl;
02803 for (Int_t i=0; i<GetTotDim(); i++)
02804 ostr << fXmax[i] << std::endl;
02805 }
02806
02807
02808 void TMVA::PDEFoam::AddXMLTo( void* parent )
02809 {
02810
02811
02812 void *variables = gTools().AddChild( parent, "Variables" );
02813 gTools().AddAttr( variables, "LastCe", fLastCe );
02814 gTools().AddAttr( variables, "nCells", fNCells );
02815 gTools().AddAttr( variables, "Dim", fDim );
02816 gTools().AddAttr( variables, "VolumeFraction", GetVolumeFraction() );
02817
02818 void *xmin_wrap;
02819 for (Int_t i=0; i<GetTotDim(); i++){
02820 xmin_wrap = gTools().AddChild( variables, "Xmin" );
02821 gTools().AddAttr( xmin_wrap, "Index", i );
02822 gTools().AddAttr( xmin_wrap, "Value", fXmin[i] );
02823 }
02824
02825 void *xmax_wrap;
02826 for (Int_t i=0; i<GetTotDim(); i++){
02827 xmax_wrap = gTools().AddChild( variables, "Xmax" );
02828 gTools().AddAttr( xmax_wrap, "Index", i );
02829 gTools().AddAttr( xmax_wrap, "Value", fXmax[i] );
02830 }
02831 }
02832
02833
02834 void TMVA::PDEFoam::ReadXML( void* parent )
02835 {
02836 void *variables = gTools().GetChild( parent );
02837 gTools().ReadAttr( variables, "LastCe", fLastCe );
02838 gTools().ReadAttr( variables, "nCells", fNCells );
02839 gTools().ReadAttr( variables, "Dim", fDim );
02840 if (fDim < 1 || fDim >= INT_MAX) {
02841 Log() << kERROR << "Foam dimension " << GetTotDim() << "our of range!" << Endl;
02842 return;
02843 }
02844 Float_t volfr;
02845 gTools().ReadAttr( variables, "VolumeFraction", volfr );
02846 SetVolumeFraction( volfr );
02847
02848 if (fXmin) delete [] fXmin;
02849 if (fXmax) delete [] fXmax;
02850 fXmin = new Double_t[GetTotDim()];
02851 fXmax = new Double_t[GetTotDim()];
02852
02853 void *xmin_wrap = gTools().GetChild( variables );
02854 for (Int_t counter=0; counter<fDim; counter++) {
02855 Int_t i=0;
02856 gTools().ReadAttr( xmin_wrap , "Index", i );
02857 if (i >= GetTotDim() || i<0)
02858 Log() << kFATAL << "dimension index out of range:" << i << Endl;
02859 gTools().ReadAttr( xmin_wrap , "Value", fXmin[i] );
02860 xmin_wrap = gTools().GetNextChild( xmin_wrap );
02861 }
02862
02863 void *xmax_wrap = xmin_wrap;
02864 for (Int_t counter=0; counter<fDim; counter++) {
02865 Int_t i=0;
02866 gTools().ReadAttr( xmax_wrap , "Index", i );
02867 if (i >= GetTotDim() || i<0)
02868 Log() << kFATAL << "dimension index out of range:" << i << Endl;
02869 gTools().ReadAttr( xmax_wrap , "Value", fXmax[i] );
02870 xmax_wrap = gTools().GetNextChild( xmax_wrap );
02871 }
02872 }