94 ClassImp(TMVA::PDEFoam);
96 static const Float_t kHigh= FLT_MAX;
97 static const Float_t kVlow=-FLT_MAX;
104 TMVA::PDEFoam::PDEFoam() :
118 fPseRan(new TRandom3(4356)),
120 fFoamType(kSeparate),
127 fFillFoamWithOrigWeights(kFALSE),
128 fDTSeparation(kFoam),
131 fTimer(new Timer(0,
"PDEFoam", kTRUE)),
132 fVariableNames(new TObjArray()),
133 fLogger(new MsgLogger(
"PDEFoam"))
137 fVariableNames->SetOwner(kTRUE);
143 TMVA::PDEFoam::PDEFoam(
const TString& name) :
157 fPseRan(new TRandom3(4356)),
159 fFoamType(kSeparate),
166 fFillFoamWithOrigWeights(kFALSE),
167 fDTSeparation(kFoam),
170 fTimer(new Timer(1,
"PDEFoam", kTRUE)),
171 fVariableNames(new TObjArray()),
172 fLogger(new MsgLogger(
"PDEFoam"))
174 if(strlen(name) > 128)
175 Log() << kFATAL <<
"Name too long " << name.Data() << Endl;
179 fVariableNames->SetOwner(kTRUE);
185 TMVA::PDEFoam::~PDEFoam()
187 delete fVariableNames;
189 if (fDistr)
delete fDistr;
190 if (fPseRan)
delete fPseRan;
191 if (fXmin) {
delete [] fXmin; fXmin=0; }
192 if (fXmax) {
delete [] fXmax; fXmax=0; }
196 for(Int_t i=0; i<fNCells; i++)
delete fCells[i];
210 TMVA::PDEFoam::PDEFoam(
const PDEFoam &from) :
226 , fFoamType(kSeparate)
233 , fFillFoamWithOrigWeights(kFALSE)
234 , fDTSeparation(kFoam)
239 , fLogger(new MsgLogger(*from.fLogger))
241 Log() << kFATAL <<
"COPY CONSTRUCTOR NOT IMPLEMENTED" << Endl;
245 fVariableNames->SetOwner(kTRUE);
251 void TMVA::PDEFoam::SetDim(Int_t kDim)
254 Log() << kFATAL <<
"<SetDim>: Dimension is zero or negative!" << Endl;
257 if (fXmin)
delete [] fXmin;
258 if (fXmax)
delete [] fXmax;
259 fXmin =
new Double_t[GetTotDim()];
260 fXmax =
new Double_t[GetTotDim()];
266 void TMVA::PDEFoam::SetXmin(Int_t idim, Double_t wmin)
268 if (idim<0 || idim>=GetTotDim())
269 Log() << kFATAL <<
"<SetXmin>: Dimension out of bounds!" << Endl;
277 void TMVA::PDEFoam::SetXmax(Int_t idim, Double_t wmax)
279 if (idim<0 || idim>=GetTotDim())
280 Log() << kFATAL <<
"<SetXmax>: Dimension out of bounds!" << Endl;
293 void TMVA::PDEFoam::Create()
295 Bool_t addStatus = TH1::AddDirectoryStatus();
296 TH1::AddDirectory(kFALSE);
298 if(fPseRan==0) Log() << kFATAL <<
"Random number generator not set" << Endl;
299 if(fDistr==0) Log() << kFATAL <<
"Distribution function not set" << Endl;
300 if(fDim==0) Log() << kFATAL <<
"Zero dimension not allowed" << Endl;
306 fRvec =
new Double_t[fDim];
307 if(fRvec==0) Log() << kFATAL <<
"Cannot initialize buffer fRvec" << Endl;
310 fAlpha =
new Double_t[fDim];
311 if(fAlpha==0) Log() << kFATAL <<
"Cannot initialize buffer fAlpha" << Endl;
316 fInhiDiv =
new Int_t[fDim];
317 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
321 fMaskDiv =
new Int_t[fDim];
322 for(Int_t i=0; i<fDim; i++) fMaskDiv[i]=1;
325 fHistEdg =
new TObjArray(fDim);
326 for(Int_t i=0; i<fDim; i++){
327 TString hname, htitle;
328 hname = fName+TString(
"_HistEdge_");
330 htitle = TString(
"Edge Histogram No. ");
332 (*fHistEdg)[i] =
new TH1D(hname.Data(),htitle.Data(),fNBin,0.0, 1.0);
333 ((TH1D*)(*fHistEdg)[i])->Sumw2();
347 TH1::AddDirectory(addStatus);
357 void TMVA::PDEFoam::InitCells()
361 for(Int_t i=0; i<fNCells; i++)
delete fCells[i];
365 fCells =
new(nothrow) PDEFoamCell*[fNCells];
367 Log() << kFATAL <<
"not enough memory to create " << fNCells
370 for(Int_t i=0; i<fNCells; i++){
371 fCells[i]=
new PDEFoamCell(fDim);
372 fCells[i]->SetSerial(i);
381 for(Long_t iCell=0; iCell<=fLastCe; iCell++){
382 Explore( fCells[iCell] );
390 Int_t TMVA::PDEFoam::CellFill(Int_t status, PDEFoamCell *parent)
393 if (fLastCe==fNCells){
394 Log() << kFATAL <<
"Too many cells" << Endl;
398 cell = fCells[fLastCe];
400 cell->Fill(status, parent, 0, 0);
404 Double_t xInt2,xDri2;
406 xInt2 = 0.5*parent->GetIntg();
407 xDri2 = 0.5*parent->GetDriv();
408 cell->SetIntg(xInt2);
409 cell->SetDriv(xDri2);
435 void TMVA::PDEFoam::Explore(PDEFoamCell *cell)
437 Double_t wt, dx, xBest=0, yBest;
438 Double_t intOld, driOld;
444 Double_t ceSum[5], xproj;
446 Double_t event_density = 0;
447 Double_t totevents = 0;
448 Double_t toteventsOld = 0;
450 PDEFoamVect cellSize(fDim);
451 PDEFoamVect cellPosi(fDim);
453 cell->GetHcub(cellPosi,cellSize);
457 Double_t *xRand =
new Double_t[fDim];
462 Double_t vol_scale = 1.0;
463 for (Int_t idim = 0; idim < fDim; ++idim)
464 vol_scale *= fXmax[idim] - fXmin[idim];
467 dx = cell->GetVolume() * vol_scale;
468 intOld = cell->GetIntg();
469 driOld = cell->GetDriv();
470 toteventsOld = GetCellElement(cell, 0);
481 for (i=0;i<fDim;i++) ((TH1D *)(*fHistEdg)[i])->Reset();
485 for (iev=0;iev<fNSampl;iev++){
488 if (fDim>0)
for (j=0; j<fDim; j++) xRand[j]= cellPosi[j] +fAlpha[j]*(cellSize[j]);
490 wt = dx*Eval(xRand, event_density);
491 totevents += event_density;
495 for (k=0; k<fDim; k++) {
497 ((TH1D *)(*fHistEdg)[nProj])->Fill(xproj,wt);
505 if (ceSum[3]>wt) ceSum[3]=wt;
506 if (ceSum[4]<wt) ceSum[4]=wt;
508 if (ceSum[1]>0) nevEff = ceSum[0]*ceSum[0]/ceSum[1];
510 if ( nevEff >= fNBin*fEvPerBin)
break;
514 if (fNSampl>0) totevents /= fNSampl;
518 if (cell==fCells[0] && ceSum[0]<=0.0){
520 Log() << kFATAL <<
"No events were found during exploration of "
521 <<
"root cell. Please check PDEFoam parameters nSampl "
522 <<
"and VolFrac." << Endl;
524 Log() << kWARNING <<
"Negative number of events found during "
525 <<
"exploration of root cell" << Endl;
530 for (k=0; k<fDim;k++){
532 if ( fInhiDiv[k]==1) fMaskDiv[k] =0;
539 Double_t intTrue = ceSum[0]/(nevMC+0.000001);
542 if (kBest == -1) Varedu(ceSum,kBest,xBest,yBest);
543 intDriv =sqrt(ceSum[1]/nevMC) -intTrue;
546 cell->SetBest(kBest);
547 cell->SetXdiv(xBest);
548 cell->SetIntg(intTrue);
549 cell->SetDriv(intDriv);
550 SetCellElement(cell, 0, totevents);
553 Double_t parIntg, parDriv;
554 for (parent = cell->GetPare(); parent!=0; parent = parent->GetPare()){
555 parIntg = parent->GetIntg();
556 parDriv = parent->GetDriv();
557 parent->SetIntg( parIntg +intTrue -intOld );
558 parent->SetDriv( parDriv +intDriv -driOld );
559 SetCellElement( parent, 0, GetCellElement(parent, 0) + totevents - toteventsOld);
571 void TMVA::PDEFoam::Varedu(Double_t ceSum[5], Int_t &kBest, Double_t &xBest, Double_t &yBest)
573 Double_t nent = ceSum[2];
575 Double_t sswAll = ceSum[1];
576 Double_t ssw = sqrt(sswAll)/sqrt(nent);
578 Double_t sswIn,sswOut,xLo,xUp;
582 Double_t maxGain=0.0;
584 for(Int_t kProj=0; kProj<fDim; kProj++) {
585 if( fMaskDiv[kProj]) {
588 Double_t sswtBest = kHigh;
590 Double_t xMin=0.0; Double_t xMax=0.0;
592 for(Int_t jLo=1; jLo<=fNBin; jLo++) {
593 Double_t aswIn=0; Double_t asswIn=0;
594 for(Int_t jUp=jLo; jUp<=fNBin;jUp++) {
595 aswIn += ((TH1D *)(*fHistEdg)[kProj])->GetBinContent(jUp);
596 asswIn += Sqr(((TH1D *)(*fHistEdg)[kProj])->GetBinError( jUp));
601 if ( (xUp-xLo) < std::numeric_limits<double>::epsilon()) sswIn=0.;
602 else sswIn = sqrt(asswIn) /sqrt(nent*(xUp-xLo)) *(xUp-xLo);
603 if ( (1.0-xUp+xLo) < std::numeric_limits<double>::epsilon()) sswOut=0.;
604 else if ( sswAll-asswIn < std::numeric_limits<double>::epsilon()) sswOut=0.;
605 else sswOut= sqrt(sswAll-asswIn)/sqrt(nent*(1.0-xUp+xLo)) *(1.0-xUp+xLo);
606 if( (sswIn+sswOut) < sswtBest) {
607 sswtBest = sswIn+sswOut;
616 Int_t iLo = (Int_t) (fNBin*xMin);
617 Int_t iUp = (Int_t) (fNBin*xMax);
624 if(iLo == 0) xBest=yBest;
625 if(iUp == fNBin) yBest=xBest;
630 if( (kBest >= fDim) || (kBest<0) )
631 Log() << kFATAL <<
"Something wrong with kBest" << Endl;
638 void TMVA::PDEFoam::MakeAlpha()
641 fPseRan->RndmArray(fDim,fRvec);
642 for(Int_t k=0; k<fDim; k++) fAlpha[k] = fRvec[k];
652 Long_t TMVA::PDEFoam::PeekMax()
657 Double_t drivMax, driv, xDiv;
658 Bool_t bCutNmin = kTRUE;
659 Bool_t bCutMaxDepth = kTRUE;
662 for(i=0; i<=fLastCe; i++) {
663 if( fCells[i]->GetStat() == 1 ) {
665 driv = fCells[i]->GetDriv();
666 if (driv < std::numeric_limits<float>::epsilon())
670 xDiv = TMath::Abs(fCells[i]->GetXdiv());
671 if (xDiv <= std::numeric_limits<Double_t>::epsilon() ||
672 xDiv >= 1.0 - std::numeric_limits<Double_t>::epsilon())
676 if (GetMaxDepth() > 0)
677 bCutMaxDepth = fCells[i]->GetDepth() < GetMaxDepth();
681 bCutNmin = GetCellElement(fCells[i], 0) > GetNmin();
684 if(driv > drivMax && bCutNmin && bCutMaxDepth) {
693 Log() << kVERBOSE <<
"Warning: No cell with more than "
694 << GetNmin() <<
" events found!" << Endl;
695 else if (!bCutMaxDepth)
696 Log() << kVERBOSE <<
"Warning: Maximum depth reached: "
697 << GetMaxDepth() << Endl;
699 Log() << kWARNING <<
"<PDEFoam::PeekMax>: no more candidate cells (drivMax>0) found for further splitting." << Endl;
715 Int_t TMVA::PDEFoam::Divide(PDEFoamCell *cell)
720 if(fLastCe+1 >= fNCells) Log() << kFATAL <<
"Buffer limit is reached, fLastCe=fnBuf" << Endl;
726 kBest = cell->GetBest();
727 if( kBest<0 || kBest>=fDim ) Log() << kFATAL <<
"Wrong kBest" << Endl;
733 Int_t d1 = CellFill(1, cell);
734 Int_t d2 = CellFill(1, cell);
735 cell->SetDau0((fCells[d1]));
736 cell->SetDau1((fCells[d2]));
738 Explore( (fCells[d1]) );
739 Explore( (fCells[d2]) );
748 Double_t TMVA::PDEFoam::Eval(Double_t *xRand, Double_t &event_density)
754 std::vector<Double_t> xvec;
755 xvec.reserve(GetTotDim());
756 for (Int_t idim = 0; idim < GetTotDim(); ++idim)
757 xvec.push_back( VarTransformInvers(idim, xRand[idim]) );
759 return GetDistr()->Density(xvec, event_density);
768 void TMVA::PDEFoam::Grow()
770 fTimer->Init(fNCells);
773 PDEFoamCell* newCell;
775 while ( (fLastCe+2) < fNCells ) {
778 if ( (iCell<0) || (iCell>fLastCe) ) {
779 Log() << kVERBOSE <<
"Break: "<< fLastCe+1 <<
" cells created" << Endl;
781 for (Long_t jCell=fLastCe+1; jCell<fNCells; jCell++)
782 delete fCells[jCell];
786 newCell = fCells[iCell];
790 if ( Divide( newCell )==0)
break;
795 Log() << kVERBOSE << GetNActiveCells() <<
" active cells created" << Endl;
803 void TMVA::PDEFoam::SetInhiDiv(Int_t iDim, Int_t inhiDiv)
805 if(fDim==0) Log() << kFATAL <<
"SetInhiDiv: fDim=0" << Endl;
807 fInhiDiv =
new Int_t[ fDim ];
808 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
811 if( ( 0<=iDim) && (iDim<fDim)) {
812 fInhiDiv[iDim] = inhiDiv;
814 Log() << kFATAL <<
"Wrong iDim" << Endl;
823 void TMVA::PDEFoam::CheckAll(Int_t level)
825 Int_t errors, warnings;
829 errors = 0; warnings = 0;
830 if (level==1) Log() << kVERBOSE <<
"Performing consistency checks for created foam" << Endl;
831 for(iCell=1; iCell<=fLastCe; iCell++) {
832 cell = fCells[iCell];
834 if( ((cell->GetDau0()==0) && (cell->GetDau1()!=0) ) ||
835 ((cell->GetDau1()==0) && (cell->GetDau0()!=0) ) ) {
837 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d has only one daughter " << iCell << Endl;
839 if( (cell->GetDau0()==0) && (cell->GetDau1()==0) && (cell->GetStat()==0) ) {
841 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d has no daughter and is inactive " << iCell << Endl;
843 if( (cell->GetDau0()!=0) && (cell->GetDau1()!=0) && (cell->GetStat()==1) ) {
845 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d has two daughters and is active " << iCell << Endl;
849 if( (cell->GetPare())!=fCells[0] ) {
850 if ( (cell != cell->GetPare()->GetDau0()) && (cell != cell->GetPare()->GetDau1()) ) {
852 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d parent not pointing to this cell " << iCell << Endl;
857 if(cell->GetDau0()!=0) {
858 if(cell != (cell->GetDau0())->GetPare()) {
860 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d daughter 0 not pointing to this cell " << iCell << Endl;
863 if(cell->GetDau1()!=0) {
864 if(cell != (cell->GetDau1())->GetPare()) {
866 if (level==1) Log() << kFATAL <<
"ERROR: Cell's no %d daughter 1 not pointing to this cell " << iCell << Endl;
869 if(cell->GetVolume()<1E-50) {
871 if(level==1) Log() << kFATAL <<
"ERROR: Cell no. " << iCell <<
" has Volume of <1E-50" << Endl;
876 for(iCell=0; iCell<=fLastCe; iCell++) {
877 cell = fCells[iCell];
878 if( (cell->GetStat()==1) && (cell->GetVolume()<1E-11) ) {
880 if(level==1) Log() << kFATAL <<
"ERROR: Cell no. " << iCell <<
" is active but Volume is 0 " << Endl;
885 Log() << kVERBOSE <<
"Check has found " << errors <<
" errors and " << warnings <<
" warnings." << Endl;
888 Info(
"CheckAll",
"Check - found total %d errors \n",errors);
896 void TMVA::PDEFoam::PrintCell(Long_t iCell)
898 if (iCell < 0 || iCell > fLastCe) {
899 Log() << kWARNING <<
"<PrintCell(iCell=" << iCell
900 <<
")>: cell number " << iCell <<
" out of bounds!"
905 PDEFoamVect cellPosi(fDim), cellSize(fDim);
906 fCells[iCell]->GetHcub(cellPosi,cellSize);
907 Int_t kBest = fCells[iCell]->GetBest();
908 Double_t xBest = fCells[iCell]->GetXdiv();
910 Log() <<
"Cell[" << iCell <<
"]={ ";
911 Log() <<
" " << fCells[iCell] <<
" " << Endl;
912 Log() <<
" Xdiv[abs. coord.]="
913 << VarTransformInvers(kBest,cellPosi[kBest] + xBest*cellSize[kBest])
915 Log() <<
" Abs. coord. = (";
916 for (Int_t idim=0; idim<fDim; idim++) {
917 Log() <<
"dim[" << idim <<
"]={"
918 << VarTransformInvers(idim,cellPosi[idim]) <<
","
919 << VarTransformInvers(idim,cellPosi[idim] + cellSize[idim])
924 Log() <<
")" << Endl;
925 fCells[iCell]->Print(
"1");
927 Log() <<
"Elements: [";
928 TVectorD *vec = (TVectorD*)fCells[iCell]->GetElement();
930 for (Int_t i=0; i<vec->GetNrows(); i++){
931 if (i>0) Log() <<
", ";
932 Log() << GetCellElement(fCells[iCell], i);
936 Log() <<
"]" << Endl;
943 void TMVA::PDEFoam::PrintCells(
void)
945 for(Long_t iCell=0; iCell<=fLastCe; iCell++)
956 void TMVA::PDEFoam::FillFoamCells(
const Event* ev, Float_t wt)
959 std::vector<Float_t> values = ev->GetValues();
960 std::vector<Float_t> tvalues = VarTransform(values);
961 PDEFoamCell *cell = FindCell(tvalues);
965 SetCellElement(cell, 0, GetCellElement(cell, 0) + wt);
966 SetCellElement(cell, 1, GetCellElement(cell, 1) + wt*wt);
972 void TMVA::PDEFoam::ResetCellElements()
976 Log() << kVERBOSE <<
"Delete cell elements" << Endl;
977 for (Long_t iCell = 0; iCell < fNCells; ++iCell) {
978 TObject* elements = fCells[iCell]->GetElement();
981 fCells[iCell]->SetElement(NULL);
991 Bool_t TMVA::PDEFoam::CellValueIsUndefined( PDEFoamCell* )
1017 Float_t TMVA::PDEFoam::GetCellValue(
const std::vector<Float_t> &xvec, ECellValue cv, PDEFoamKernelBase *kernel)
1019 std::vector<Float_t> txvec(VarTransform(xvec));
1021 return GetCellValue(FindCell(txvec), cv);
1023 return kernel->Estimate(
this, txvec, cv);
1044 std::vector<Float_t> TMVA::PDEFoam::GetCellValue(
const std::map<Int_t,Float_t>& xvec, ECellValue cv )
1047 std::map<Int_t,Float_t> txvec;
1048 for (std::map<Int_t,Float_t>::const_iterator it=xvec.begin(); it!=xvec.end(); ++it)
1049 txvec.insert(std::pair<Int_t, Float_t>(it->first, VarTransform(it->first, it->second)));
1052 std::vector<PDEFoamCell*> cells = FindCells(txvec);
1055 std::vector<Float_t> cell_values;
1056 cell_values.reserve(cells.size());
1057 for (std::vector<PDEFoamCell*>::const_iterator cell_it=cells.begin();
1058 cell_it != cells.end(); ++cell_it)
1059 cell_values.push_back(GetCellValue(*cell_it, cv));
1081 TMVA::PDEFoamCell* TMVA::PDEFoam::FindCell(
const std::vector<Float_t> &xvec )
const
1083 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
1084 PDEFoamCell *cell, *cell0;
1088 while (cell->GetStat()!=1) {
1089 idim=cell->GetBest();
1090 cell0=cell->GetDau0();
1091 cell0->GetHcub(cellPosi0,cellSize0);
1093 if (xvec.at(idim)<=cellPosi0[idim]+cellSize0[idim])
1096 cell=(cell->GetDau1());
1119 void TMVA::PDEFoam::FindCells(
const std::map<Int_t, Float_t> &txvec, PDEFoamCell* cell, std::vector<PDEFoamCell*> &cells)
const
1121 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
1125 while (cell->GetStat()!=1) {
1126 idim=cell->GetBest();
1129 map<Int_t, Float_t>::const_iterator it = txvec.find(idim);
1131 if (it != txvec.end()){
1134 cell0=cell->GetDau0();
1135 cell0->GetHcub(cellPosi0,cellSize0);
1137 if (it->second <= cellPosi0[idim] + cellSize0[idim])
1140 cell=cell->GetDau1();
1143 FindCells(txvec, cell->GetDau0(), cells);
1144 FindCells(txvec, cell->GetDau1(), cells);
1148 cells.push_back(cell);
1166 std::vector<TMVA::PDEFoamCell*> TMVA::PDEFoam::FindCells(
const std::vector<Float_t> &txvec)
const
1169 std::map<Int_t, Float_t> txvec_map;
1170 for (UInt_t i=0; i<txvec.size(); ++i)
1171 txvec_map.insert(std::pair<Int_t, Float_t>(i, txvec.at(i)));
1174 std::vector<PDEFoamCell*> cells(0);
1177 FindCells(txvec_map, fCells[0], cells);
1197 std::vector<TMVA::PDEFoamCell*> TMVA::PDEFoam::FindCells(
const std::map<Int_t, Float_t> &txvec)
const
1200 std::vector<PDEFoamCell*> cells(0);
1203 FindCells(txvec, fCells[0], cells);
1219 TH1D* TMVA::PDEFoam::Draw1Dim( ECellValue cell_value, Int_t nbin, PDEFoamKernelBase *kernel )
1222 if ( GetTotDim()!=1 )
1223 Log() << kFATAL <<
"<Draw1Dim>: function can only be used for 1-dimensional foams!"
1226 TString hname(
"h_1dim");
1227 TH1D* h1=(TH1D*)gDirectory->Get(hname);
1229 h1=
new TH1D(hname,
"1-dimensional Foam", nbin, fXmin[0], fXmax[0]);
1231 if (!h1) Log() << kFATAL <<
"ERROR: Can not create histo" << hname << Endl;
1234 for (Int_t ibinx=1; ibinx<=h1->GetNbinsX(); ++ibinx) {
1236 std::vector<Float_t> txvec;
1237 txvec.push_back( VarTransform(0, h1->GetBinCenter(ibinx)) );
1239 if (kernel != NULL) {
1241 val = kernel->Estimate(
this, txvec, cell_value);
1243 val = GetCellValue(FindCell(txvec), cell_value);
1246 h1->SetBinContent(ibinx, val + h1->GetBinContent(ibinx));
1271 TH2D* TMVA::PDEFoam::Project2( Int_t idim1, Int_t idim2, ECellValue cell_value, PDEFoamKernelBase *kernel, UInt_t nbin )
1274 if ((idim1>=GetTotDim()) || (idim1<0) ||
1275 (idim2>=GetTotDim()) || (idim2<0) ||
1277 Log() << kFATAL <<
"<Project2>: wrong dimensions given: "
1278 << idim1 <<
", " << idim2 << Endl;
1284 Log() << kWARNING <<
"Warning: number of bins too big: " << nbin
1285 <<
" Using 1000 bins for each dimension instead." << Endl;
1287 }
else if (nbin<1) {
1288 Log() << kWARNING <<
"Wrong bin number: " << nbin
1289 <<
"; set nbin=50" << Endl;
1294 TString hname(Form(
"h_%d_vs_%d",idim1,idim2));
1297 TH2D* h1=(TH2D*)gDirectory->Get(hname.Data());
1299 h1=
new TH2D(hname.Data(), Form(
"var%d vs var%d",idim1,idim2), nbin, fXmin[idim1], fXmax[idim1], nbin, fXmin[idim2], fXmax[idim2]);
1301 if (!h1) Log() << kFATAL <<
"ERROR: Can not create histo" << hname << Endl;
1305 for (Int_t xbin = 1; xbin <= h1->GetNbinsX(); ++xbin) {
1306 for (Int_t ybin = 1; ybin <= h1->GetNbinsY(); ++ybin) {
1309 std::map<Int_t, Float_t> txvec;
1310 txvec[idim1] = VarTransform(idim1, h1->GetXaxis()->GetBinCenter(xbin));
1311 txvec[idim2] = VarTransform(idim2, h1->GetYaxis()->GetBinCenter(ybin));
1315 std::vector<TMVA::PDEFoamCell*> cells = FindCells(txvec);
1320 for (std::vector<TMVA::PDEFoamCell*>::const_iterator it = cells.begin();
1321 it != cells.end(); ++it) {
1323 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
1324 (*it)->GetHcub(cellPosi,cellSize);
1327 std::vector<Float_t> tvec;
1328 for (Int_t i=0; i<GetTotDim(); ++i) {
1329 if ( i != idim1 && i != idim2 )
1330 tvec.push_back(cellPosi[i] + 0.5*cellSize[i]);
1332 tvec.push_back(txvec[i]);
1334 if (kernel != NULL) {
1336 sum_cv += kernel->Estimate(
this, tvec, cell_value);
1338 sum_cv += GetCellValue(FindCell(tvec), cell_value);
1343 h1->SetBinContent(xbin, ybin, sum_cv + h1->GetBinContent(xbin, ybin));
1357 Float_t TMVA::PDEFoam::GetCellValue(
const PDEFoamCell* cell, ECellValue cv)
1363 return GetCellElement(cell, 0);
1366 return GetCellElement(cell, 1);
1368 case kValueDensity: {
1370 Double_t volume = cell->GetVolume();
1371 if (volume > numeric_limits<double>::epsilon()) {
1372 return GetCellValue(cell, kValue)/volume;
1376 Log() << kWARNING <<
"<GetCellDensity(cell)>: ERROR: cell volume"
1377 <<
" negative or zero!"
1378 <<
" ==> return cell density 0!"
1379 <<
" cell volume=" << volume
1380 <<
" cell entries=" << GetCellValue(cell, kValue) << Endl;
1382 Log() << kWARNING <<
"<GetCellDensity(cell)>: WARNING: cell volume"
1383 <<
" close to zero!"
1384 <<
" cell volume: " << volume << Endl;
1391 return cell->GetIntg();
1394 return cell->GetDriv();
1397 if (cell->GetIntg() != 0)
1398 return cell->GetDriv()/cell->GetIntg();
1403 return cell->GetVolume();
1406 Log() << kFATAL <<
"<GetCellValue>: unknown cell value" << Endl;
1417 Double_t TMVA::PDEFoam::GetCellElement(
const PDEFoamCell *cell, UInt_t i )
const
1420 TVectorD *vec = (TVectorD*)cell->GetElement();
1423 if (!vec || i >= (UInt_t) vec->GetNrows())
1433 void TMVA::PDEFoam::SetCellElement( PDEFoamCell *cell, UInt_t i, Double_t value )
1435 TVectorD *vec = NULL;
1439 if (cell->GetElement() == NULL) {
1440 vec =
new TVectorD(i+1);
1443 cell->SetElement(vec);
1446 vec = (TVectorD*)cell->GetElement();
1448 Log() << kFATAL <<
"<SetCellElement> ERROR: cell element is not a TVectorD*" << Endl;
1450 if (i >= (UInt_t) vec->GetNrows())
1461 void TMVA::PDEFoam::OutputGrow( Bool_t finished )
1464 Log() << kINFO <<
"Elapsed time: " + fTimer->GetElapsedTime()
1471 if (fNCells >= 100) modulo = Int_t(fNCells/100);
1472 if (fLastCe%modulo == 0) fTimer->DrawProgressBar( fLastCe );
1512 void TMVA::PDEFoam::RootPlot2dim(
const TString& filename, TString opt,
1513 Bool_t createCanvas, Bool_t colors )
1515 if (GetTotDim() != 2)
1516 Log() << kFATAL <<
"RootPlot2dim() can only be used with "
1517 <<
"two-dimensional foams!" << Endl;
1520 ECellValue cell_value = kValue;
1521 Bool_t plotcellnumber = kFALSE;
1522 Bool_t fillcells = kTRUE;
1523 if (opt.Contains(
"cell_value")){
1524 cell_value = kValue;
1525 }
else if (opt.Contains(
"rms_ov_mean")){
1526 cell_value = kRmsOvMean;
1527 }
else if (opt.Contains(
"rms")){
1532 if (opt.Contains(
"cellnumber"))
1533 plotcellnumber = kTRUE;
1536 std::ofstream outfile(filename, std::ios::out);
1538 outfile<<
"{" << std::endl;
1543 outfile <<
"TColor *graycolors[100];" << std::endl;
1544 outfile <<
"for (Int_t i=0.; i<100; i++)" << std::endl;
1545 outfile <<
" graycolors[i]=new TColor(1000+i, 1-(Float_t)i/100.,1-(Float_t)i/100.,1-(Float_t)i/100.);"<< std::endl;
1548 outfile <<
"cMap = new TCanvas(\"" << fName <<
"\",\"Cell Map for "
1549 << fName <<
"\",600,600);" << std::endl;
1551 outfile<<
"TBox*a=new TBox();"<<std::endl;
1552 outfile<<
"a->SetFillStyle(0);"<<std::endl;
1553 outfile<<
"a->SetLineWidth(4);"<<std::endl;
1554 outfile<<
"TBox *b1=new TBox();"<<std::endl;
1555 outfile<<
"TText*t=new TText();"<<std::endl;
1557 outfile << (colors ?
"gStyle->SetPalette(1, 0);" :
"gStyle->SetPalette(0);")
1559 outfile <<
"b1->SetFillStyle(1001);"<<std::endl;
1560 outfile<<
"TBox *b2=new TBox();"<<std::endl;
1561 outfile <<
"b2->SetFillStyle(0);"<<std::endl;
1564 outfile <<
"b1->SetFillStyle(0);"<<std::endl;
1568 (colors ? gStyle->SetPalette(1, 0) : gStyle->SetPalette(0) );
1571 Float_t zmax = -1E8;
1576 for (Long_t iCell=1; iCell<=fLastCe; iCell++) {
1577 if ( fCells[iCell]->GetStat() == 1) {
1578 Float_t value = GetCellValue(fCells[iCell], cell_value);
1585 outfile <<
"// observed minimum and maximum of distribution: " << std::endl;
1586 outfile <<
"// Float_t zmin = "<< zmin <<
";" << std::endl;
1587 outfile <<
"// Float_t zmax = "<< zmax <<
";" << std::endl;
1590 outfile <<
"// used minimum and maximum of distribution (taking into account log scale if applicable): " << std::endl;
1591 outfile <<
"Float_t zmin = "<< zmin <<
";" << std::endl;
1592 outfile <<
"Float_t zmax = "<< zmax <<
";" << std::endl;
1594 Float_t x1,y1,x2,y2,x,y;
1595 Float_t offs = 0.01;
1596 Float_t lpag = 1-2*offs;
1597 Int_t ncolors = colors ? gStyle->GetNumberOfColors() : 100;
1598 Float_t scale = (ncolors-1)/(zmax - zmin);
1599 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
1603 outfile <<
"// =========== Rectangular cells ==========="<< std::endl;
1604 for (Long_t iCell=1; iCell<=fLastCe; iCell++) {
1605 if ( fCells[iCell]->GetStat() == 1) {
1606 fCells[iCell]->GetHcub(cellPosi,cellSize);
1607 x1 = offs+lpag*(cellPosi[0]);
1608 y1 = offs+lpag*(cellPosi[1]);
1609 x2 = offs+lpag*(cellPosi[0]+cellSize[0]);
1610 y2 = offs+lpag*(cellPosi[1]+cellSize[1]);
1614 Float_t value = GetCellValue(fCells[iCell], cell_value);
1619 color = gStyle->GetColorPalette(Int_t((value-zmin)*scale));
1621 color = 1000+(Int_t((value-zmin)*scale));
1624 outfile <<
"b1->SetFillColor(" << color <<
");" << std::endl;
1628 outfile<<
"b1->DrawBox("<<x1<<
","<<y1<<
","<<x2<<
","<<y2<<
");"<<std::endl;
1630 outfile<<
"b2->DrawBox("<<x1<<
","<<y1<<
","<<x2<<
","<<y2<<
");"<<std::endl;
1633 if (plotcellnumber) {
1634 outfile<<
"t->SetTextColor(4);"<<std::endl;
1636 outfile<<
"t->SetTextSize(0.025);"<<std::endl;
1637 else if(fLastCe<251)
1638 outfile<<
"t->SetTextSize(0.015);"<<std::endl;
1640 outfile<<
"t->SetTextSize(0.008);"<<std::endl;
1641 x = offs+lpag*(cellPosi[0]+0.5*cellSize[0]);
1642 y = offs+lpag*(cellPosi[1]+0.5*cellSize[1]);
1643 outfile<<
"t->DrawText("<<x<<
","<<y<<
","<<
"\""<<iCell<<
"\""<<
");"<<std::endl;
1647 outfile<<
"// ============== End Rectangles ==========="<< std::endl;
1649 outfile <<
"}" << std::endl;
1658 void TMVA::PDEFoam::FillBinarySearchTree(
const Event* ev )
1660 GetDistr()->FillBinarySearchTree(ev);
1667 void TMVA::PDEFoam::DeleteBinarySearchTree()
1669 if(fDistr)
delete fDistr;