Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
PDEFoam.cxx
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: S.Jadach, Tancredi Carli, Dominik Dannheim, Alexander Voigt
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6 * Package: TMVA *
7 * Classes: PDEFoam *
8 * Web : http://tmva.sourceforge.net *
9 * *
10 * Description: *
11 * Implementations *
12 * *
13 * Authors (alphabetical): *
14 * Tancredi Carli - CERN, Switzerland *
15 * Dominik Dannheim - CERN, Switzerland *
16 * S. Jadach - Institute of Nuclear Physics, Cracow, Poland *
17 * Alexander Voigt - TU Dresden, Germany *
18 * Peter Speckmayer - CERN, Switzerland *
19 * *
20 * Copyright (c) 2008, 2010: *
21 * CERN, Switzerland *
22 * MPI-K Heidelberg, Germany *
23 * *
24 * Redistribution and use in source and binary forms, with or without *
25 * modification, are permitted according to the terms listed in LICENSE *
26 * (http://tmva.sourceforge.net/LICENSE) *
27 **********************************************************************************/
28
29/*! \class TMVA::PDEFoam
30\ingroup TMVA
31
32Implementation of PDEFoam
33
34The PDEFoam method is an extension of the PDERS method, which uses
35self-adapting binning to divide the multi-dimensional phase space
36in a finite number of hyper-rectangles (boxes).
37
38For a given number of boxes, the binning algorithm adjusts the size
39and position of the boxes inside the multidimensional phase space,
40minimizing the variance of the signal and background densities inside
41the boxes. The binned density information is stored in binary trees,
42allowing for a very fast and memory-efficient classification of
43events.
44
45The implementation of the PDEFoam is based on the monte-carlo
46integration package TFoam included in the analysis package ROOT.
47
48The class TMVA::PDEFoam defines the default interface for the
49PDEFoam variants:
50
51 - PDEFoamEvent
52 - PDEFoamDiscriminant
53 - PDEFoamTarget
54 - PDEFoamMultiTarget
55 - PDEFoamDecisionTree
56
57Per default PDEFoam stores in the cells the number of events (event
58weights) and therefore acts as an event density estimator.
59However, the above listed derived classes override this behaviour
60to implement certain PDEFoam variations.
61
62In order to use PDEFoam the user has to set the density estimator
63of the type TMVA::PDEFoamDensityBase, which is used to during the foam
64build-up. The default PDEFoam should be used with
65PDEFoamEventDensity.
66*/
67
68#include "TMVA/PDEFoam.h"
69
70#include "TMVA/Event.h"
71#include "TMVA/MsgLogger.h"
73#include "TMVA/Timer.h"
74#include "TMVA/Tools.h"
75#include "TMVA/Types.h"
76
77#include "TStyle.h"
78#include "TObject.h"
79#include "TH1D.h"
80#include "TMath.h"
81#include "TVectorT.h"
82#include "TRandom3.h"
83#include "TColor.h"
84#include "TDirectory.h"
85#include "TObjArray.h"
86
87#include <cassert>
88#include <fstream>
89#include <iostream>
90#include <limits>
91#include <sstream>
92
94
95static const Float_t kHigh= FLT_MAX;
96static const Float_t kVlow=-FLT_MAX;
97
98using namespace std;
99
100////////////////////////////////////////////////////////////////////////////////
101/// Default constructor for streamer, user should not use it.
102
104 fName("PDEFoam"),
105 fDim(0),
106 fNCells(0),
107 fNBin(5),
108 fNSampl(2000),
109 fEvPerBin(0),
110 fMaskDiv(0),
111 fInhiDiv(0),
112 fNoAct(1),
113 fLastCe(-1),
114 fCells(0),
115 fHistEdg(0),
116 fRvec(0),
117 fPseRan(new TRandom3(4356)),
118 fAlpha(0),
119 fFoamType(kSeparate),
120 fXmin(0),
121 fXmax(0),
122 fNElements(0),
123 fNmin(100),
124 fMaxDepth(0),
125 fVolFrac(1.0/15.0),
126 fFillFoamWithOrigWeights(kFALSE),
127 fDTSeparation(kFoam),
128 fPeekMax(kTRUE),
129 fDistr(NULL),
130 fTimer(new Timer(0, "PDEFoam", kTRUE)),
131 fVariableNames(new TObjArray()),
132 fLogger(new MsgLogger("PDEFoam"))
133{
134 // fVariableNames may delete it's heap-based content
135 if (fVariableNames)
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// User constructor, to be employed by the user
141
143 fName(name),
144 fDim(0),
145 fNCells(1000),
146 fNBin(5),
147 fNSampl(2000),
148 fEvPerBin(0),
149 fMaskDiv(0),
150 fInhiDiv(0),
151 fNoAct(1),
152 fLastCe(-1),
153 fCells(0),
154 fHistEdg(0),
155 fRvec(0),
156 fPseRan(new TRandom3(4356)),
157 fAlpha(0),
158 fFoamType(kSeparate),
159 fXmin(0),
160 fXmax(0),
161 fNElements(0),
162 fNmin(100),
163 fMaxDepth(0),
164 fVolFrac(1.0/15.0),
165 fFillFoamWithOrigWeights(kFALSE),
166 fDTSeparation(kFoam),
167 fPeekMax(kTRUE),
168 fDistr(NULL),
169 fTimer(new Timer(1, "PDEFoam", kTRUE)),
170 fVariableNames(new TObjArray()),
171 fLogger(new MsgLogger("PDEFoam"))
172{
173 if(strlen(name) > 128)
174 Log() << kFATAL << "Name too long " << name.Data() << Endl;
175
176 // fVariableNames may delete it's heap-based content
177 if (fVariableNames)
179}
180
181////////////////////////////////////////////////////////////////////////////////
182/// Default destructor
183
185{
186 delete fVariableNames;
187 delete fTimer;
188 if (fDistr) delete fDistr;
189 if (fPseRan) delete fPseRan;
190 if (fXmin) { delete [] fXmin; fXmin=0; }
191 if (fXmax) { delete [] fXmax; fXmax=0; }
192
193 ResetCellElements();
194 if(fCells!= 0) {
195 for(Int_t i=0; i<fNCells; i++) delete fCells[i]; // PDEFoamCell*[]
196 delete [] fCells;
197 }
198 delete [] fRvec; //double[]
199 delete [] fAlpha; //double[]
200 delete [] fMaskDiv; //int[]
201 delete [] fInhiDiv; //int[]
202
203 delete fLogger;
204}
205
206////////////////////////////////////////////////////////////////////////////////
207/// Copy Constructor NOT IMPLEMENTED (NEVER USED)
208
210 TObject(from)
211 , fDim(0)
212 , fNCells(0)
213 , fNBin(0)
214 , fNSampl(0)
215 , fEvPerBin(0)
216 , fMaskDiv(0)
217 , fInhiDiv(0)
218 , fNoAct(0)
219 , fLastCe(0)
220 , fCells(0)
221 , fHistEdg(0)
222 , fRvec(0)
223 , fPseRan(0)
224 , fAlpha(0)
225 , fFoamType(kSeparate)
226 , fXmin(0)
227 , fXmax(0)
228 , fNElements(0)
229 , fNmin(0)
230 , fMaxDepth(0)
231 , fVolFrac(1.0/15.0)
232 , fFillFoamWithOrigWeights(kFALSE)
233 , fDTSeparation(kFoam)
234 , fPeekMax(kTRUE)
235 , fDistr(0)
236 , fTimer(0)
237 , fVariableNames(0)
238 , fLogger(new MsgLogger(*from.fLogger))
239{
240 Log() << kFATAL << "COPY CONSTRUCTOR NOT IMPLEMENTED" << Endl;
241
242 // fVariableNames may delete it's heap-based content
243 if (fVariableNames)
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Sets dimension of cubical space
249
251{
252 if (kDim < 1)
253 Log() << kFATAL << "<SetDim>: Dimension is zero or negative!" << Endl;
254
255 fDim = kDim;
256 if (fXmin) delete [] fXmin;
257 if (fXmax) delete [] fXmax;
258 fXmin = new Double_t[GetTotDim()];
259 fXmax = new Double_t[GetTotDim()];
260}
262////////////////////////////////////////////////////////////////////////////////
263/// set lower foam bound in dimension idim
266{
267 if (idim<0 || idim>=GetTotDim())
268 Log() << kFATAL << "<SetXmin>: Dimension out of bounds!" << Endl;
269
270 fXmin[idim]=wmin;
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// set upper foam bound in dimension idim
275
277{
278 if (idim<0 || idim>=GetTotDim())
279 Log() << kFATAL << "<SetXmax>: Dimension out of bounds!" << Endl;
280
281 fXmax[idim]=wmax;
282}
283
284////////////////////////////////////////////////////////////////////////////////
285/// Basic initialization of FOAM invoked by the user.
286/// IMPORTANT: Random number generator and the distribution object has to be
287/// provided using SetPseRan and SetRho prior to invoking this initializator!
288///
289/// After the foam is grown, space for 2 variables is reserved in
290/// every cell. They are used for filling the foam cells.
291
293{
294 Bool_t addStatus = TH1::AddDirectoryStatus();
296
297 if(fPseRan==0) Log() << kFATAL << "Random number generator not set" << Endl;
298 if(fDistr==0) Log() << kFATAL << "Distribution function not set" << Endl;
299 if(fDim==0) Log() << kFATAL << "Zero dimension not allowed" << Endl;
300
301 /////////////////////////////////////////////////////////////////////////
302 // ALLOCATE SMALL LISTS //
303 // it is done globally, not for each cell, to save on allocation time //
304 /////////////////////////////////////////////////////////////////////////
305 fRvec = new Double_t[fDim]; // Vector of random numbers
306 if(fRvec==0) Log() << kFATAL << "Cannot initialize buffer fRvec" << Endl;
307
308 if(fDim>0){
309 fAlpha = new Double_t[fDim]; // sum<1 for internal parametrization of the simplex
310 if(fAlpha==0) Log() << kFATAL << "Cannot initialize buffer fAlpha" << Endl;
311 }
312
313 //====== List of directions inhibited for division
314 if(fInhiDiv == 0){
315 fInhiDiv = new Int_t[fDim];
316 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
317 }
318 //====== Dynamic mask used in Explore for edge determination
319 if(fMaskDiv == 0){
320 fMaskDiv = new Int_t[fDim];
321 for(Int_t i=0; i<fDim; i++) fMaskDiv[i]=1;
322 }
323 //====== Initialize list of histograms
324 fHistEdg = new TObjArray(fDim); // Initialize list of histograms
325 for(Int_t i=0; i<fDim; i++){
326 TString hname, htitle;
327 hname = fName+TString("_HistEdge_");
328 hname += i;
329 htitle = TString("Edge Histogram No. ");
330 htitle += i;
331 (*fHistEdg)[i] = new TH1D(hname.Data(),htitle.Data(),fNBin,0.0, 1.0); // Initialize histogram for each edge
332 ((TH1D*)(*fHistEdg)[i])->Sumw2();
333 }
334
335 // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //
336 // BUILD-UP of the FOAM //
337 // ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| //
338
339 // prepare PDEFoam for growing
340 ResetCellElements(); // reset all cell elements
341
342 // Define and explore root cell(s)
343 InitCells();
344 Grow();
345
346 TH1::AddDirectory(addStatus);
347
348 // prepare PDEFoam for the filling with events
349 ResetCellElements(); // reset all cell elements
350} // Create
351
352////////////////////////////////////////////////////////////////////////////////
353/// Internal subprogram used by Create.
354/// It initializes "root part" of the FOAM of the tree of cells.
355
357{
358 fLastCe =-1; // Index of the last cell
359 if(fCells!= 0) {
360 for(Int_t i=0; i<fNCells; i++) delete fCells[i];
361 delete [] fCells;
362 }
363
364 fCells = new(nothrow) PDEFoamCell*[fNCells];
365 if (!fCells) {
366 Log() << kFATAL << "not enough memory to create " << fNCells
367 << " cells" << Endl;
368 }
369 for(Int_t i=0; i<fNCells; i++){
370 fCells[i]= new PDEFoamCell(fDim); // Allocate BIG list of cells
371 fCells[i]->SetSerial(i);
372 }
373
374 /////////////////////////////////////////////////////////////////////////////
375 // Single Root Hypercube //
376 /////////////////////////////////////////////////////////////////////////////
377 CellFill(1, 0); // 0-th cell ACTIVE
378
379 // Exploration of the root cell(s)
380 for(Long_t iCell=0; iCell<=fLastCe; iCell++){
381 Explore( fCells[iCell] ); // Exploration of root cell(s)
382 }
383}//InitCells
384
385////////////////////////////////////////////////////////////////////////////////
386/// Internal subprogram used by Create.
387/// It initializes content of the newly allocated active cell.
388
390{
391 PDEFoamCell *cell;
392 if (fLastCe==fNCells){
393 Log() << kFATAL << "Too many cells" << Endl;
394 }
395 fLastCe++; // 0-th cell is the first
396
397 cell = fCells[fLastCe];
398
399 cell->Fill(status, parent, 0, 0);
400
401 cell->SetBest( -1); // pointer for planning division of the cell
402 cell->SetXdiv(0.5); // factor for division
403 Double_t xInt2,xDri2;
404 if(parent!=0){
405 xInt2 = 0.5*parent->GetIntg();
406 xDri2 = 0.5*parent->GetDriv();
407 cell->SetIntg(xInt2);
408 cell->SetDriv(xDri2);
409 }else{
410 cell->SetIntg(0.0);
411 cell->SetDriv(0.0);
412 }
413 return fLastCe;
414}
415
416////////////////////////////////////////////////////////////////////////////////
417/// Internal subprogram used by Create.
418/// It explores newly defined cell with help of special short MC sampling.
419/// As a result, estimates of kTRUE and drive volume is defined/determined
420/// Average and dispersion of the weight distribution will is found along
421/// each edge and the best edge (minimum dispersion, best maximum weight)
422/// is memorized for future use.
423/// The optimal division point for eventual future cell division is
424/// determined/recorded. Recorded are also minimum and maximum weight etc.
425/// The volume estimate in all (inactive) parent cells is updated.
426/// Note that links to parents and initial volume = 1/2 parent has to be
427/// already defined prior to calling this routine.
428///
429/// If fNmin > 0 then the total number of (training) events found in
430/// the cell during the exploration is stored in the cell. This
431/// information is used within PeekMax() to avoid splitting cells
432/// which contain less than fNmin events.
433
435{
436 Double_t wt, dx, xBest=0, yBest;
437 Double_t intOld, driOld;
438
439 Long_t iev;
440 Double_t nevMC;
441 Int_t i, j, k;
442 Int_t nProj, kBest;
443 Double_t ceSum[5], xproj;
444
445 Double_t event_density = 0;
446 Double_t totevents = 0;
447 Double_t toteventsOld = 0;
448
449 PDEFoamVect cellSize(fDim);
450 PDEFoamVect cellPosi(fDim);
451
452 cell->GetHcub(cellPosi,cellSize);
453
454 PDEFoamCell *parent;
455
456 Double_t *xRand = new Double_t[fDim];
457
458 Double_t *volPart=0;
459
460 // calculate volume scale
461 Double_t vol_scale = 1.0;
462 for (Int_t idim = 0; idim < fDim; ++idim)
463 vol_scale *= fXmax[idim] - fXmin[idim];
464
465 cell->CalcVolume();
466 dx = cell->GetVolume() * vol_scale;
467 intOld = cell->GetIntg(); //memorize old values,
468 driOld = cell->GetDriv(); //will be needed for correcting parent cells
469 toteventsOld = GetCellElement(cell, 0);
470
471 /////////////////////////////////////////////////////
472 // Special Short MC sampling to probe cell //
473 /////////////////////////////////////////////////////
474 ceSum[0]=0;
475 ceSum[1]=0;
476 ceSum[2]=0;
477 ceSum[3]=kHigh; //wtmin
478 ceSum[4]=kVlow; //wtmax
479
480 for (i=0;i<fDim;i++) ((TH1D *)(*fHistEdg)[i])->Reset(); // Reset histograms
481
482 Double_t nevEff=0.;
483 // ||||||||||||||||||||||||||BEGIN MC LOOP|||||||||||||||||||||||||||||
484 for (iev=0;iev<fNSampl;iev++){
485 MakeAlpha(); // generate uniformly vector inside hypercube
486
487 if (fDim>0) for (j=0; j<fDim; j++) xRand[j]= cellPosi[j] +fAlpha[j]*(cellSize[j]);
488
489 wt = dx*Eval(xRand, event_density);
490 totevents += event_density;
491
492 nProj = 0;
493 if (fDim>0) {
494 for (k=0; k<fDim; k++) {
495 xproj =fAlpha[k];
496 ((TH1D *)(*fHistEdg)[nProj])->Fill(xproj,wt);
497 nProj++;
498 }
499 }
500
501 ceSum[0] += wt; // sum of weights
502 ceSum[1] += wt*wt; // sum of weights squared
503 ceSum[2]++; // sum of 1
504 if (ceSum[3]>wt) ceSum[3]=wt; // minimum weight;
505 if (ceSum[4]<wt) ceSum[4]=wt; // maximum weight
506 // test MC loop exit condition
507 if (ceSum[1]>0) nevEff = ceSum[0]*ceSum[0]/ceSum[1];
508 else nevEff = 0;
509 if ( nevEff >= fNBin*fEvPerBin) break;
510 } // ||||||||||||||||||||||||||END MC LOOP|||||||||||||||||||||||||||||
511 totevents *= dx;
512
513 if (fNSampl>0) totevents /= fNSampl;
514
515 // make sure that, if root cell is explored, more than zero
516 // events were found.
517 if (cell==fCells[0] && ceSum[0]<=0.0){
518 if (ceSum[0]==0.0)
519 Log() << kFATAL << "No events were found during exploration of "
520 << "root cell. Please check PDEFoam parameters nSampl "
521 << "and VolFrac." << Endl;
522 else
523 Log() << kWARNING << "Negative number of events found during "
524 << "exploration of root cell" << Endl;
525 }
526
527 //------------------------------------------------------------------
528 //--- predefine logics of searching for the best division edge ---
529 for (k=0; k<fDim;k++){
530 fMaskDiv[k] =1; // default is all
531 if ( fInhiDiv[k]==1) fMaskDiv[k] =0; // inhibit some...
532 }
533 kBest=-1;
534
535 /////////////////////////////////////////////////////////////////////////////
536
537 nevMC = ceSum[2];
538 Double_t intTrue = ceSum[0]/(nevMC+0.000001);
539 Double_t intDriv=0.;
540
541 if (kBest == -1) Varedu(ceSum,kBest,xBest,yBest); // determine the best edge,
542 intDriv =sqrt(ceSum[1]/nevMC) -intTrue; // Foam build-up, sqrt(<w**2>) -<w>
543
544 //=================================================================================
545 cell->SetBest(kBest);
546 cell->SetXdiv(xBest);
547 cell->SetIntg(intTrue);
548 cell->SetDriv(intDriv);
549 SetCellElement(cell, 0, totevents);
550
551 // correct/update integrals in all parent cells to the top of the tree
552 Double_t parIntg, parDriv;
553 for (parent = cell->GetPare(); parent!=0; parent = parent->GetPare()){
554 parIntg = parent->GetIntg();
555 parDriv = parent->GetDriv();
556 parent->SetIntg( parIntg +intTrue -intOld );
557 parent->SetDriv( parDriv +intDriv -driOld );
558 SetCellElement( parent, 0, GetCellElement(parent, 0) + totevents - toteventsOld);
559 }
560 delete [] volPart;
561 delete [] xRand;
562}
563
564////////////////////////////////////////////////////////////////////////////////
565/// Internal subprogram used by Create.
566/// In determines the best edge candidate and the position of the cell division plane
567/// in case of the variance reduction for future cell division,
568/// using results of the MC exploration run stored in fHistEdg
569
570void TMVA::PDEFoam::Varedu(Double_t ceSum[5], Int_t &kBest, Double_t &xBest, Double_t &yBest)
571{
572 Double_t nent = ceSum[2];
573 // Double_t swAll = ceSum[0];
574 Double_t sswAll = ceSum[1];
575 Double_t ssw = sqrt(sswAll)/sqrt(nent);
576 //
577 Double_t sswIn,sswOut,xLo,xUp;
578 kBest =-1;
579 xBest =0.5;
580 yBest =1.0;
581 Double_t maxGain=0.0;
582 // Now go over all projections kProj
583 for(Int_t kProj=0; kProj<fDim; kProj++) {
584 if( fMaskDiv[kProj]) {
585 // initialize search over bins
586 // Double_t sigmIn =0.0; Double_t sigmOut =0.0;
587 Double_t sswtBest = kHigh;
588 Double_t gain =0.0;
589 Double_t xMin=0.0; Double_t xMax=0.0;
590 // Double loop over all pairs jLo<jUp
591 for(Int_t jLo=1; jLo<=fNBin; jLo++) {
592 // Double_t aswIn=0;
593 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));
597 xLo=(jLo-1.0)/fNBin;
598 xUp=(jUp*1.0)/fNBin;
599 // swIn = aswIn/nent;
600 // swOut = (swAll-aswIn)/nent;
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;
608 gain = ssw-sswtBest;
609 // sigmIn = sswIn -swIn; // Debug
610 // sigmOut = sswOut-swOut; // Debug
611 xMin = xLo;
612 xMax = xUp;
613 }
614 }//jUp
615 }//jLo
616 Int_t iLo = (Int_t) (fNBin*xMin);
617 Int_t iUp = (Int_t) (fNBin*xMax);
618
619 if(gain>=maxGain) {
620 maxGain=gain;
621 kBest=kProj; // <--- !!!!! The best edge
622 xBest=xMin;
623 yBest=xMax;
624 if(iLo == 0) xBest=yBest; // The best division point
625 if(iUp == fNBin) yBest=xBest; // this is not really used
626 }
627 }
628 } //kProj
629
630 if( (kBest >= fDim) || (kBest<0) )
631 Log() << kFATAL << "Something wrong with kBest" << Endl;
632} //PDEFoam::Varedu
633
634////////////////////////////////////////////////////////////////////////////////
635/// Internal subprogram used by Create.
636/// Provides random vector Alpha 0< Alpha(i) < 1
637
639{
640 // simply generate and load kDim uniform random numbers
641 fPseRan->RndmArray(fDim,fRvec); // kDim random numbers needed
642 for(Int_t k=0; k<fDim; k++) fAlpha[k] = fRvec[k];
643} //MakeAlpha
644
645////////////////////////////////////////////////////////////////////////////////
646/// Internal subprogram used by Create. It finds cell with maximal
647/// driver integral for the purpose of the division. This function
648/// is overridden by the PDEFoam Class to apply cuts on the number
649/// of events in the cell (fNmin) and the cell tree depth
650/// (GetMaxDepth() > 0) during cell buildup.
651
653{
654 Long_t iCell = -1;
655
656 Long_t i;
657 Double_t drivMax, driv, xDiv;
658 Bool_t bCutNmin = kTRUE;
659 Bool_t bCutMaxDepth = kTRUE;
660 // drivMax = kVlow;
661 drivMax = 0; // only split cells if gain>0 (this also avoids splitting at cell boundary)
662 for(i=0; i<=fLastCe; i++) {//without root
663 if( fCells[i]->GetStat() == 1 ) {
664 // if driver integral < numeric limit, skip cell
665 driv = fCells[i]->GetDriv();
666 if (driv < std::numeric_limits<float>::epsilon())
667 continue;
668
669 // do not split cell at the edges
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())
673 continue;
674
675 // apply cut on depth
676 if (GetMaxDepth() > 0)
677 bCutMaxDepth = fCells[i]->GetDepth() < GetMaxDepth();
678
679 // apply Nmin-cut
680 if (GetNmin() > 0)
681 bCutNmin = GetCellElement(fCells[i], 0) > GetNmin();
682
683 // choose cell
684 if(driv > drivMax && bCutNmin && bCutMaxDepth) {
685 drivMax = driv;
686 iCell = i;
687 }
688 }
689 }
690
691 if (iCell == -1){
692 if (!bCutNmin)
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;
698 else
699 Log() << kWARNING << "<PDEFoam::PeekMax>: no more candidate cells (drivMax>0) found for further splitting." << Endl;
700 }
701
702 return(iCell);
703}
704
705////////////////////////////////////////////////////////////////////////////////
706/// Internal subprogram used by Create.
707/// It divides cell iCell into two daughter cells.
708/// The iCell is retained and tagged as inactive, daughter cells are appended
709/// at the end of the buffer.
710/// New vertex is added to list of vertices.
711/// List of active cells is updated, iCell removed, two daughters added
712/// and their properties set with help of MC sampling (PDEFoam_Explore)
713/// Returns Code RC=-1 of buffer limit is reached, fLastCe=fnBuf.
714
716{
717 // Double_t xdiv;
718 Int_t kBest;
719
720 if(fLastCe+1 >= fNCells) Log() << kFATAL << "Buffer limit is reached, fLastCe=fnBuf" << Endl;
721
722 cell->SetStat(0); // reset cell as inactive
723 fNoAct++;
724
725 // xdiv = cell->GetXdiv();
726 kBest = cell->GetBest();
727 if( kBest<0 || kBest>=fDim ) Log() << kFATAL << "Wrong kBest" << Endl;
728
729 //////////////////////////////////////////////////////////////////
730 // define two daughter cells (active) //
731 //////////////////////////////////////////////////////////////////
732
733 Int_t d1 = CellFill(1, cell);
734 Int_t d2 = CellFill(1, cell);
735 cell->SetDau0((fCells[d1]));
736 cell->SetDau1((fCells[d2]));
737
738 Explore( (fCells[d1]) );
739 Explore( (fCells[d2]) );
740
741 return 1;
742} // PDEFoam_Divide
743
744////////////////////////////////////////////////////////////////////////////////
745/// Internal subprogram.
746/// Evaluates (training) distribution.
747
749{
750 // Transform variable xRand, since Foam boundaries are [0,1] and
751 // fDistr is filled with events which range in [fXmin,fXmax]
752 //
753 // Transformation: [0, 1] --> [xmin, xmax]
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]) );
758
759 return GetDistr()->Density(xvec, event_density);
760}
761
762////////////////////////////////////////////////////////////////////////////////
763/// Internal subprogram used by Create.
764/// It grow new cells by the binary division process.
765/// This function is overridden by the PDEFoam class to stop the foam buildup process
766/// if one of the cut conditions stop the cell split.
767
769{
770 fTimer->Init(fNCells);
771
772 Long_t iCell;
773 PDEFoamCell* newCell;
774
775 while ( (fLastCe+2) < fNCells ) { // this condition also checked inside Divide
776 iCell = PeekMax(); // peek up cell with maximum driver integral
777
778 if ( (iCell<0) || (iCell>fLastCe) ) {
779 Log() << kVERBOSE << "Break: "<< fLastCe+1 << " cells created" << Endl;
780 // remove remaining empty cells
781 for (Long_t jCell=fLastCe+1; jCell<fNCells; jCell++)
782 delete fCells[jCell];
783 fNCells = fLastCe+1;
784 break;
785 }
786 newCell = fCells[iCell];
787
788 OutputGrow();
789
790 if ( Divide( newCell )==0) break; // and divide it into two
791 }
792 OutputGrow( kTRUE );
793 CheckAll(1); // set arg=1 for more info
794
795 Log() << kVERBOSE << GetNActiveCells() << " active cells created" << Endl;
796}// Grow
797
798////////////////////////////////////////////////////////////////////////////////
799/// This can be called before Create, after setting kDim
800/// It defines which variables are excluded in the process of the cell division.
801/// For example 'FoamX->SetInhiDiv(1, 1);' inhibits division of y-variable.
802
804{
805 if(fDim==0) Log() << kFATAL << "SetInhiDiv: fDim=0" << Endl;
806 if(fInhiDiv == 0) {
807 fInhiDiv = new Int_t[ fDim ];
808 for(Int_t i=0; i<fDim; i++) fInhiDiv[i]=0;
809 }
810 //
811 if( ( 0<=iDim) && (iDim<fDim)) {
812 fInhiDiv[iDim] = inhiDiv;
813 } else
814 Log() << kFATAL << "Wrong iDim" << Endl;
815}//SetInhiDiv
816
817////////////////////////////////////////////////////////////////////////////////
818/// User utility, miscellaneous and debug.
819/// Checks all pointers in the tree of cells. This is useful auto-diagnostic.
820/// level=0, no printout, failures causes STOP
821/// level=1, printout, failures lead to WARNINGS only
822
824{
825 Int_t errors, warnings;
826 PDEFoamCell *cell;
827 Long_t iCell;
828
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];
833 // checking general rules
834 if( ((cell->GetDau0()==0) && (cell->GetDau1()!=0) ) ||
835 ((cell->GetDau1()==0) && (cell->GetDau0()!=0) ) ) {
836 errors++;
837 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has only one daughter " << iCell << Endl;
838 }
839 if( (cell->GetDau0()==0) && (cell->GetDau1()==0) && (cell->GetStat()==0) ) {
840 errors++;
841 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has no daughter and is inactive " << iCell << Endl;
842 }
843 if( (cell->GetDau0()!=0) && (cell->GetDau1()!=0) && (cell->GetStat()==1) ) {
844 errors++;
845 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d has two daughters and is active " << iCell << Endl;
846 }
847
848 // checking parents
849 if( (cell->GetPare())!=fCells[0] ) { // not child of the root
850 if ( (cell != cell->GetPare()->GetDau0()) && (cell != cell->GetPare()->GetDau1()) ) {
851 errors++;
852 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d parent not pointing to this cell " << iCell << Endl;
853 }
854 }
855
856 // checking daughters
857 if(cell->GetDau0()!=0) {
858 if(cell != (cell->GetDau0())->GetPare()) {
859 errors++;
860 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d daughter 0 not pointing to this cell " << iCell << Endl;
861 }
862 }
863 if(cell->GetDau1()!=0) {
864 if(cell != (cell->GetDau1())->GetPare()) {
865 errors++;
866 if (level==1) Log() << kFATAL << "ERROR: Cell's no %d daughter 1 not pointing to this cell " << iCell << Endl;
867 }
868 }
869 if(cell->GetVolume()<1E-50) {
870 errors++;
871 if(level==1) Log() << kFATAL << "ERROR: Cell no. " << iCell << " has Volume of <1E-50" << Endl;
872 }
873 }// loop after cells;
874
875 // Check for cells with Volume=0
876 for(iCell=0; iCell<=fLastCe; iCell++) {
877 cell = fCells[iCell];
878 if( (cell->GetStat()==1) && (cell->GetVolume()<1E-11) ) {
879 errors++;
880 if(level==1) Log() << kFATAL << "ERROR: Cell no. " << iCell << " is active but Volume is 0 " << Endl;
881 }
882 }
883 // summary
884 if(level==1){
885 Log() << kVERBOSE << "Check has found " << errors << " errors and " << warnings << " warnings." << Endl;
886 }
887 if(errors>0){
888 Info("CheckAll","Check - found total %d errors \n",errors);
889 }
890} // Check
891
892////////////////////////////////////////////////////////////////////////////////
893/// Prints geometry of and elements of 'iCell', as well as relations
894/// to parent and daughter cells.
895
897{
898 if (iCell < 0 || iCell > fLastCe) {
899 Log() << kWARNING << "<PrintCell(iCell=" << iCell
900 << ")>: cell number " << iCell << " out of bounds!"
901 << Endl;
902 return;
903 }
904
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();
909
910 Log() << "Cell[" << iCell << "]={ ";
911 Log() << " " << fCells[iCell] << " " << Endl; // extra DEBUG
912 Log() << " Xdiv[abs. coord.]="
913 << VarTransformInvers(kBest,cellPosi[kBest] + xBest*cellSize[kBest])
914 << Endl;
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])
920 << "}";
921 if (idim < fDim-1)
922 Log() << ", ";
923 }
924 Log() << ")" << Endl;
925 fCells[iCell]->Print("1");
926 // print the cell elements
927 Log() << "Elements: [";
928 TVectorD *vec = (TVectorD*)fCells[iCell]->GetElement();
929 if (vec != NULL){
930 for (Int_t i=0; i<vec->GetNrows(); i++){
931 if (i>0) Log() << ", ";
932 Log() << GetCellElement(fCells[iCell], i);
933 }
934 } else
935 Log() << "not set";
936 Log() << "]" << Endl;
937 Log()<<"}"<<Endl;
938}
939
940////////////////////////////////////////////////////////////////////////////////
941/// Prints geometry of ALL cells of the FOAM
942
944{
945 for(Long_t iCell=0; iCell<=fLastCe; iCell++)
946 PrintCell(iCell);
947}
948
949////////////////////////////////////////////////////////////////////////////////
950/// This function fills a weight 'wt' into the PDEFoam cell, which
951/// corresponds to the given event 'ev'. Per default cell element 0
952/// is filled with the weight 'wt', and cell element 1 is filled
953/// with the squared weight. This function can be overridden by a
954/// subclass in order to change the values stored in the foam cells.
955
957{
958 // find corresponding foam cell
959 std::vector<Float_t> values = ev->GetValues();
960 std::vector<Float_t> tvalues = VarTransform(values);
961 PDEFoamCell *cell = FindCell(tvalues);
962
963 // 0. Element: Sum of weights 'wt'
964 // 1. Element: Sum of weights 'wt' squared
965 SetCellElement(cell, 0, GetCellElement(cell, 0) + wt);
966 SetCellElement(cell, 1, GetCellElement(cell, 1) + wt*wt);
967}
968
969////////////////////////////////////////////////////////////////////////////////
970/// Remove the cell elements from all cells.
971
973{
974 if (!fCells) return;
975
976 Log() << kVERBOSE << "Delete cell elements" << Endl;
977 for (Long_t iCell = 0; iCell < fNCells; ++iCell) {
978 TObject* elements = fCells[iCell]->GetElement();
979 if (elements) {
980 delete elements;
981 fCells[iCell]->SetElement(NULL);
982 }
983 }
984}
985
986////////////////////////////////////////////////////////////////////////////////
987/// Returns true, if the value of the given cell is undefined.
988/// Default value: kFALSE. This function can be overridden by
989/// sub-classes.
990
992{
993 return kFALSE;
994}
995
996////////////////////////////////////////////////////////////////////////////////
997/// This function finds the cell, which corresponds to the given
998/// untransformed event vector 'xvec' and return its value, which is
999/// given by the parameter 'cv'. If kernel != NULL, then
1000/// PDEFoamKernelBase::Estimate() is called on the transformed event
1001/// variables.
1002///
1003/// Parameters:
1004///
1005/// - xvec - event vector (untransformed, [fXmin,fXmax])
1006///
1007/// - cv - the cell value to return
1008///
1009/// - kernel - PDEFoam kernel estimator. If NULL is given, than the
1010/// pure cell value is returned
1011///
1012/// Return:
1013///
1014/// The cell value, corresponding to 'xvec', estimated by the given
1015/// kernel.
1016
1017Float_t TMVA::PDEFoam::GetCellValue(const std::vector<Float_t> &xvec, ECellValue cv, PDEFoamKernelBase *kernel)
1018{
1019 std::vector<Float_t> txvec(VarTransform(xvec));
1020 if (kernel == NULL)
1021 return GetCellValue(FindCell(txvec), cv);
1022 else
1023 return kernel->Estimate(this, txvec, cv);
1024}
1025
1026////////////////////////////////////////////////////////////////////////////////
1027/// This function finds all cells, which corresponds to the given
1028/// (incomplete) untransformed event vector 'xvec' and returns the
1029/// cell values, according to the parameter 'cv'.
1030///
1031/// Parameters:
1032///
1033/// - xvec - map for the untransformed vector. The key (Int_t) is
1034/// the dimension, and the value (Float_t) is the event
1035/// coordinate. Note that not all coordinates have to be
1036/// specified.
1037///
1038/// - cv - cell values to return
1039///
1040/// Return:
1041///
1042/// cell values from all cells that were found
1043
1044std::vector<Float_t> TMVA::PDEFoam::GetCellValue( const std::map<Int_t,Float_t>& xvec, ECellValue cv )
1045{
1046 // transformed event
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)));
1050
1051 // find all cells, which correspond to the transformed event
1052 std::vector<PDEFoamCell*> cells = FindCells(txvec);
1053
1054 // get the cell values
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));
1060
1061 return cell_values;
1062}
1063
1064////////////////////////////////////////////////////////////////////////////////
1065/// Find cell that contains 'xvec' (in foam coordinates [0,1]).
1066///
1067/// Loop to find cell that contains 'xvec' starting at root cell,
1068/// and traversing binary tree to find the cell quickly. Note, that
1069/// if 'xvec' lies outside the foam, the cell which is nearest to
1070/// 'xvec' is returned. (The returned pointer should never be
1071/// NULL.)
1072///
1073/// Parameters:
1074///
1075/// - xvec - event vector (in foam coordinates [0,1])
1076///
1077/// Return:
1078///
1079/// PDEFoam cell corresponding to 'xvec'
1080
1081TMVA::PDEFoamCell* TMVA::PDEFoam::FindCell( const std::vector<Float_t> &xvec ) const
1082{
1083 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
1084 PDEFoamCell *cell, *cell0;
1085
1086 cell=fCells[0]; // start with root cell
1087 Int_t idim=0;
1088 while (cell->GetStat()!=1) { //go down binary tree until cell is found
1089 idim=cell->GetBest(); // dimension that changed
1090 cell0=cell->GetDau0();
1091 cell0->GetHcub(cellPosi0,cellSize0);
1092
1093 if (xvec.at(idim)<=cellPosi0[idim]+cellSize0[idim])
1094 cell=cell0;
1095 else
1096 cell=(cell->GetDau1());
1097 }
1098 return cell;
1099}
1100
1101////////////////////////////////////////////////////////////////////////////////
1102/// This is a helper function for std::vector<PDEFoamCell*>
1103/// FindCells(...) and a generalisation of PDEFoamCell* FindCell().
1104/// It saves in 'cells' all cells, which contain the coordinates
1105/// specifies in 'txvec'. Note, that not all coordinates have to be
1106/// specified in 'txvec'.
1107///
1108/// Parameters:
1109///
1110/// - txvec - event vector in foam coordinates [0,1]. The key is
1111/// the dimension and the value is the event coordinate. Note,
1112/// that not all coordinates have to be specified.
1113///
1114/// - cell - cell to start searching with (usually root cell
1115/// fCells[0])
1116///
1117/// - cells - list of cells that were found
1118
1119void TMVA::PDEFoam::FindCells(const std::map<Int_t, Float_t> &txvec, PDEFoamCell* cell, std::vector<PDEFoamCell*> &cells) const
1120{
1121 PDEFoamVect cellPosi0(GetTotDim()), cellSize0(GetTotDim());
1122 PDEFoamCell *cell0;
1123 Int_t idim=0;
1124
1125 while (cell->GetStat()!=1) { //go down binary tree until cell is found
1126 idim=cell->GetBest(); // dimension that changed
1127
1128 // check if dimension 'idim' is specified in 'txvec'
1129 map<Int_t, Float_t>::const_iterator it = txvec.find(idim);
1130
1131 if (it != txvec.end()){
1132 // case 1: cell is splitten in a dimension which is specified
1133 // in txvec
1134 cell0=cell->GetDau0();
1135 cell0->GetHcub(cellPosi0,cellSize0);
1136 // check, whether left daughter cell contains txvec
1137 if (it->second <= cellPosi0[idim] + cellSize0[idim])
1138 cell=cell0;
1139 else
1140 cell=cell->GetDau1();
1141 } else {
1142 // case 2: cell is splitten in target dimension
1143 FindCells(txvec, cell->GetDau0(), cells);
1144 FindCells(txvec, cell->GetDau1(), cells);
1145 return;
1146 }
1147 }
1148 cells.push_back(cell);
1149}
1150
1151////////////////////////////////////////////////////////////////////////////////
1152/// Find all cells, that contain txvec. This function can be used,
1153/// when the dimension of the foam is greater than the dimension of
1154/// txvec. E.g. this is the case for multi-target regression.
1155///
1156/// Parameters:
1157///
1158/// - txvec - event vector of variables, transformed into foam
1159/// coordinates [0,1]. The size of txvec can be smaller than the
1160/// dimension of the foam.
1161///
1162/// Return value:
1163///
1164/// - vector of cells, that fit txvec
1165
1166std::vector<TMVA::PDEFoamCell*> TMVA::PDEFoam::FindCells(const std::vector<Float_t> &txvec) const
1167{
1168 // copy the coordinates from 'txvec' into a map
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)));
1172
1173 // the cells found
1174 std::vector<PDEFoamCell*> cells(0);
1175
1176 // loop over all target dimensions
1177 FindCells(txvec_map, fCells[0], cells);
1178
1179 return cells;
1180}
1181
1182////////////////////////////////////////////////////////////////////////////////
1183/// Find all cells, that contain the coordinates specified in txvec.
1184/// The key in 'txvec' is the dimension, and the corresponding value
1185/// is the coordinate. Note, that not all coordinates have to be
1186/// specified in txvec.
1187///
1188/// Parameters:
1189///
1190/// - txvec - map of coordinates (transformed into foam coordinates
1191/// [0,1])
1192///
1193/// Return value:
1194///
1195/// - vector of cells, that fit txvec
1196
1197std::vector<TMVA::PDEFoamCell*> TMVA::PDEFoam::FindCells(const std::map<Int_t, Float_t> &txvec) const
1198{
1199 // the cells found
1200 std::vector<PDEFoamCell*> cells(0);
1201
1202 // loop over all target dimensions
1203 FindCells(txvec, fCells[0], cells);
1204
1205 return cells;
1206}
1207
1208////////////////////////////////////////////////////////////////////////////////
1209/// Draws 1-dimensional foam (= histogram)
1210///
1211/// Parameters:
1212///
1213/// - cell_value - the cell value to draw
1214///
1215/// - nbin - number of bins of result histogram
1216///
1217/// - kernel - a PDEFoam kernel.
1218
1219TH1D* TMVA::PDEFoam::Draw1Dim( ECellValue cell_value, Int_t nbin, PDEFoamKernelBase *kernel )
1220{
1221 // avoid plotting of wrong dimensions
1222 if ( GetTotDim()!=1 )
1223 Log() << kFATAL << "<Draw1Dim>: function can only be used for 1-dimensional foams!"
1224 << Endl;
1225
1226 TString hname("h_1dim");
1227 TH1D* h1=(TH1D*)gDirectory->Get(hname);
1228 if (h1) delete h1;
1229 h1= new TH1D(hname, "1-dimensional Foam", nbin, fXmin[0], fXmax[0]);
1230
1231 if (!h1) Log() << kFATAL << "ERROR: Can not create histo" << hname << Endl;
1232
1233 // loop over all bins
1234 for (Int_t ibinx=1; ibinx<=h1->GetNbinsX(); ++ibinx) {
1235 // get event vector corresponding to bin
1236 std::vector<Float_t> txvec;
1237 txvec.push_back( VarTransform(0, h1->GetBinCenter(ibinx)) );
1238 Float_t val = 0;
1239 if (kernel != NULL) {
1240 // get cell value using the kernel
1241 val = kernel->Estimate(this, txvec, cell_value);
1242 } else {
1243 val = GetCellValue(FindCell(txvec), cell_value);
1244 }
1245 // fill value to histogram
1246 h1->SetBinContent(ibinx, val + h1->GetBinContent(ibinx));
1247 }
1248
1249 return h1;
1250}
1251
1252////////////////////////////////////////////////////////////////////////////////
1253/// Project foam variable idim1 and variable idim2 to histogram.
1254///
1255/// Parameters:
1256///
1257/// - idim1, idim2 - dimensions to project to
1258///
1259/// - cell_value - the cell value to draw
1260///
1261/// - kernel - a PDEFoam kernel (optional). If NULL is given, the
1262/// kernel is ignored and the pure cell values are
1263/// plotted.
1264///
1265/// - nbin - number of bins in x and y direction of result histogram
1266/// (optional, default is 50).
1267///
1268/// Returns:
1269/// a 2-dimensional histogram
1270
1271TH2D* TMVA::PDEFoam::Project2( Int_t idim1, Int_t idim2, ECellValue cell_value, PDEFoamKernelBase *kernel, UInt_t nbin )
1272{
1273 // avoid plotting of wrong dimensions
1274 if ((idim1>=GetTotDim()) || (idim1<0) ||
1275 (idim2>=GetTotDim()) || (idim2<0) ||
1276 (idim1==idim2) )
1277 Log() << kFATAL << "<Project2>: wrong dimensions given: "
1278 << idim1 << ", " << idim2 << Endl;
1279
1280 // root can not handle too many bins in one histogram --> catch this
1281 // Furthermore, to have more than 1000 bins in the histogram doesn't make
1282 // sense.
1283 if (nbin>1000){
1284 Log() << kWARNING << "Warning: number of bins too big: " << nbin
1285 << " Using 1000 bins for each dimension instead." << Endl;
1286 nbin = 1000;
1287 } else if (nbin<1) {
1288 Log() << kWARNING << "Wrong bin number: " << nbin
1289 << "; set nbin=50" << Endl;
1290 nbin = 50;
1291 }
1292
1293 // create result histogram
1294 TString hname(Form("h_%d_vs_%d",idim1,idim2));
1295
1296 // if histogram with this name already exists, delete it
1297 TH2D* h1=(TH2D*)gDirectory->Get(hname.Data());
1298 if (h1) delete h1;
1299 h1= new TH2D(hname.Data(), Form("var%d vs var%d",idim1,idim2), nbin, fXmin[idim1], fXmax[idim1], nbin, fXmin[idim2], fXmax[idim2]);
1300
1301 if (!h1) Log() << kFATAL << "ERROR: Can not create histo" << hname << Endl;
1302
1303 // ============== start projection algorithm ================
1304 // loop over all histogram bins (2-dim)
1305 for (Int_t xbin = 1; xbin <= h1->GetNbinsX(); ++xbin) {
1306 for (Int_t ybin = 1; ybin <= h1->GetNbinsY(); ++ybin) {
1307 // calculate the phase space point, which corresponds to this
1308 // bin combination
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));
1312
1313 // find the cells, which corresponds to this phase space
1314 // point
1315 std::vector<TMVA::PDEFoamCell*> cells = FindCells(txvec);
1316
1317 // loop over cells and fill the histogram with the cell
1318 // values
1319 Float_t sum_cv = 0; // sum of the cell values
1320 for (std::vector<TMVA::PDEFoamCell*>::const_iterator it = cells.begin();
1321 it != cells.end(); ++it) {
1322 // get cell position and size
1323 PDEFoamVect cellPosi(GetTotDim()), cellSize(GetTotDim());
1324 (*it)->GetHcub(cellPosi,cellSize);
1325 // Create complete event vector from txvec. The missing
1326 // coordinates of txvec are set to the cell center.
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]);
1331 else
1332 tvec.push_back(txvec[i]);
1333 }
1334 if (kernel != NULL) {
1335 // get the cell value using the kernel
1336 sum_cv += kernel->Estimate(this, tvec, cell_value);
1337 } else {
1338 sum_cv += GetCellValue(FindCell(tvec), cell_value);
1339 }
1340 }
1341
1342 // fill the bin content
1343 h1->SetBinContent(xbin, ybin, sum_cv + h1->GetBinContent(xbin, ybin));
1344 }
1345 }
1346
1347 return h1;
1348}
1349
1350////////////////////////////////////////////////////////////////////////////////
1351/// Returns the cell value of 'cell' corresponding to the given
1352/// option 'cv'. This function should be overridden by the subclass
1353/// in order to specify which cell elements to return for a given
1354/// cell value 'cv'. By default kValue returns cell element 0, and
1355/// kValueError returns cell element 1.
1356
1358{
1359 // calculate cell value (depending on the given option 'cv')
1360 switch (cv) {
1361
1362 case kValue:
1363 return GetCellElement(cell, 0);
1364
1365 case kValueError:
1366 return GetCellElement(cell, 1);
1367
1368 case kValueDensity: {
1369
1370 Double_t volume = cell->GetVolume();
1371 if (volume > numeric_limits<double>::epsilon()) {
1372 return GetCellValue(cell, kValue)/volume;
1373 } else {
1374 if (volume<=0){
1375 cell->Print("1"); // debug output
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;
1381 } else {
1382 Log() << kWARNING << "<GetCellDensity(cell)>: WARNING: cell volume"
1383 << " close to zero!"
1384 << " cell volume: " << volume << Endl;
1385 }
1386 }
1387 }
1388 return 0;
1389
1390 case kMeanValue:
1391 return cell->GetIntg();
1392
1393 case kRms:
1394 return cell->GetDriv();
1395
1396 case kRmsOvMean:
1397 if (cell->GetIntg() != 0)
1398 return cell->GetDriv()/cell->GetIntg();
1399 else
1400 return 0;
1401
1402 case kCellVolume:
1403 return cell->GetVolume();
1404
1405 default:
1406 Log() << kFATAL << "<GetCellValue>: unknown cell value" << Endl;
1407 return 0;
1408 }
1409
1410 return 0;
1411}
1412
1413////////////////////////////////////////////////////////////////////////////////
1414/// Returns cell element i of cell 'cell'. If the cell has no
1415/// elements or the index 'i' is out of range, than 0 is returned.
1416
1418{
1419 // dynamic_cast doesn't seem to work here ?!
1420 TVectorD *vec = (TVectorD*)cell->GetElement();
1421
1422 // if vec is not set or index out of range, return 0
1423 if (!vec || i >= (UInt_t) vec->GetNrows())
1424 return 0;
1425
1426 return (*vec)(i);
1427}
1428
1429////////////////////////////////////////////////////////////////////////////////
1430/// Set cell element i of cell to value. If the cell element i does
1431/// not exist, it is created.
1432
1434{
1435 TVectorD *vec = NULL;
1436
1437 // if no cell elements are set, create TVectorD with i+1 entries,
1438 // ranging from [0,i]
1439 if (cell->GetElement() == NULL) {
1440 vec = new TVectorD(i+1);
1441 vec->Zero(); // set all values to zero
1442 (*vec)(i) = value; // set element i to value
1443 cell->SetElement(vec);
1444 } else {
1445 // dynamic_cast doesn't seem to work here ?!
1446 vec = (TVectorD*)cell->GetElement();
1447 if (!vec)
1448 Log() << kFATAL << "<SetCellElement> ERROR: cell element is not a TVectorD*" << Endl;
1449 // check vector size and resize if necessary
1450 if (i >= (UInt_t) vec->GetNrows())
1451 vec->ResizeTo(0,i);
1452 // set element i to value
1453 (*vec)(i) = value;
1454 }
1455}
1456
1457////////////////////////////////////////////////////////////////////////////////
1458/// Overridden function of PDEFoam to avoid native foam output.
1459/// Draw TMVA-process bar instead.
1460
1462{
1463 if (finished) {
1464 Log() << kINFO << "Elapsed time: " + fTimer->GetElapsedTime()
1465 << " " << Endl;
1466 return;
1467 }
1468
1469 Int_t modulo = 1;
1470
1471 if (fNCells >= 100) modulo = Int_t(fNCells/100);
1472 if (fLastCe%modulo == 0) fTimer->DrawProgressBar( fLastCe );
1473}
1474
1475////////////////////////////////////////////////////////////////////////////////
1476/// Debugging tool which plots the cells of a 2-dimensional PDEFoam
1477/// as rectangles in C++ format readable for ROOT.
1478///
1479/// Parameters:
1480/// - filename - filename of output root macro
1481///
1482/// - opt - cell_value, rms, rms_ov_mean
1483/// If cell_value is set, the following values will be filled into
1484/// the result histogram:
1485/// - number of events - in case of classification with 2 separate
1486/// foams or multi-target regression
1487/// - discriminator - in case of classification with one
1488/// unified foam
1489/// - target - in case of mono-target regression
1490/// If none of {cell_value, rms, rms_ov_mean} is given, the cells
1491/// will not be filled.
1492/// If 'opt' contains the string 'cellnumber', the index of
1493/// each cell is draw in addition.
1494///
1495/// - createCanvas - whether to create a new canvas or not
1496///
1497/// - colors - whether to fill cells with colors or shades of grey
1498///
1499/// Example:
1500///
1501/// The following commands load a mono-target regression foam from
1502/// file 'foam.root' and create a ROOT macro 'output.C', which
1503/// draws all PDEFoam cells with little boxes. The latter are
1504/// filled with colors according to the target value stored in the
1505/// cell. Also the cell number is drawn.
1506///
1507/// TFile file("foam.root");
1508/// TMVA::PDEFoam *foam = (TMVA::PDEFoam*) gDirectory->Get("MonoTargetRegressionFoam");
1509/// foam->RootPlot2dim("output.C","cell_value,cellnumber");
1510/// gROOT->Macro("output.C");
1511
1513 Bool_t createCanvas, Bool_t colors )
1514{
1515 if (GetTotDim() != 2)
1516 Log() << kFATAL << "RootPlot2dim() can only be used with "
1517 << "two-dimensional foams!" << Endl;
1518
1519 // select value to plot
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")){
1528 cell_value = kRms;
1529 } else {
1530 fillcells = kFALSE;
1531 }
1532 if (opt.Contains("cellnumber"))
1533 plotcellnumber = kTRUE;
1534
1535 // open file (root macro)
1536 std::ofstream outfile(filename, std::ios::out);
1537
1538 outfile<<"{" << std::endl;
1539
1540 // declare boxes and set the fill styles
1541 if (!colors) { // define grayscale colors from light to dark,
1542 // starting from color index 1000
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;
1546 }
1547 if (createCanvas)
1548 outfile << "cMap = new TCanvas(\"" << fName << "\",\"Cell Map for "
1549 << fName << "\",600,600);" << std::endl;
1550
1551 outfile<<"TBox*a=new TBox();"<<std::endl;
1552 outfile<<"a->SetFillStyle(0);"<<std::endl; // big frame
1553 outfile<<"a->SetLineWidth(4);"<<std::endl;
1554 outfile<<"TBox *b1=new TBox();"<<std::endl; // single cell
1555 outfile<<"TText*t=new TText();"<<std::endl; // text for numbering
1556 if (fillcells) {
1557 outfile << (colors ? "gStyle->SetPalette(1, 0);" : "gStyle->SetPalette(0);")
1558 << std::endl;
1559 outfile <<"b1->SetFillStyle(1001);"<<std::endl;
1560 outfile<<"TBox *b2=new TBox();"<<std::endl; // single cell
1561 outfile <<"b2->SetFillStyle(0);"<<std::endl;
1562 }
1563 else {
1564 outfile <<"b1->SetFillStyle(0);"<<std::endl;
1565 }
1566
1567 if (fillcells)
1568 (colors ? gStyle->SetPalette(1, 0) : gStyle->SetPalette(0) );
1569
1570 Float_t zmin = 1E8; // minimal value (for color calculation)
1571 Float_t zmax = -1E8; // maximal value (for color calculation)
1572
1573 // if cells shall be filled, calculate minimal and maximal plot
1574 // value --> store in zmin and zmax
1575 if (fillcells) {
1576 for (Long_t iCell=1; iCell<=fLastCe; iCell++) {
1577 if ( fCells[iCell]->GetStat() == 1) {
1578 Float_t value = GetCellValue(fCells[iCell], cell_value);
1579 if (value<zmin)
1580 zmin=value;
1581 if (value>zmax)
1582 zmax=value;
1583 }
1584 }
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;
1588 }
1589
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;
1593
1594 Float_t x1,y1,x2,y2,x,y; // box and text coordinates
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());
1600
1601 // loop over cells and draw a box for every cell (and maybe the
1602 // cell number as well)
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]);
1611
1612 if (fillcells) {
1613 // get cell value
1614 Float_t value = GetCellValue(fCells[iCell], cell_value);
1615
1616 // calculate fill color
1617 Int_t color;
1618 if (colors)
1619 color = gStyle->GetColorPalette(Int_t((value-zmin)*scale));
1620 else
1621 color = 1000+(Int_t((value-zmin)*scale));
1622
1623 // set fill color of box b1
1624 outfile << "b1->SetFillColor(" << color << ");" << std::endl;
1625 }
1626
1627 // cell rectangle
1628 outfile<<"b1->DrawBox("<<x1<<","<<y1<<","<<x2<<","<<y2<<");"<<std::endl;
1629 if (fillcells)
1630 outfile<<"b2->DrawBox("<<x1<<","<<y1<<","<<x2<<","<<y2<<");"<<std::endl;
1631
1632 // cell number
1633 if (plotcellnumber) {
1634 outfile<<"t->SetTextColor(4);"<<std::endl;
1635 if(fLastCe<51)
1636 outfile<<"t->SetTextSize(0.025);"<<std::endl; // text for numbering
1637 else if(fLastCe<251)
1638 outfile<<"t->SetTextSize(0.015);"<<std::endl;
1639 else
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;
1644 }
1645 }
1646 }
1647 outfile<<"// ============== End Rectangles ==========="<< std::endl;
1648
1649 outfile << "}" << std::endl;
1650 outfile.flush();
1651 outfile.close();
1652}
1653
1654////////////////////////////////////////////////////////////////////////////////
1655/// Insert event to internal foam's density estimator
1656/// PDEFoamDensityBase.
1657
1659{
1660 GetDistr()->FillBinarySearchTree(ev);
1661}
1662
1663////////////////////////////////////////////////////////////////////////////////
1664/// Delete the foam's density estimator, which contains the binary
1665/// search tree.
1666
1668{
1669 if(fDistr) delete fDistr;
1670 fDistr = NULL;
1671}
static const Float_t kVlow
Definition PDEFoam.cxx:96
static const Float_t kHigh
Definition PDEFoam.cxx:95
static const double x2[5]
static const double x1[5]
int Int_t
Definition RtypesCore.h:45
const Bool_t kFALSE
Definition RtypesCore.h:101
long Long_t
Definition RtypesCore.h:54
float Float_t
Definition RtypesCore.h:57
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
#define gDirectory
Definition TDirectory.h:385
void Info(const char *location, const char *msgfmt,...)
Use this function for informational messages.
Definition TError.cxx:220
char name[80]
Definition TGX11.cxx:110
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition TStyle.h:413
TVectorT< Double_t > TVectorD
Definition TVectorDfwd.h:23
Color * colors
Definition X3DBuffer.c:21
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:478
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
1-D histogram with a double per channel (see TH1 documentation)}
Definition TH1.h:618
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:8971
virtual Int_t GetNbinsY() const
Definition TH1.h:297
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1283
TAxis * GetXaxis()
Get the behaviour adopted by the object about the statoverflows. See EStatOverflows for more informat...
Definition TH1.h:320
virtual Int_t GetNbinsX() const
Definition TH1.h:296
TAxis * GetYaxis()
Definition TH1.h:321
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition TH1.cxx:9052
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:4994
static Bool_t AddDirectoryStatus()
Static function: cannot be inlined on Windows/NT.
Definition TH1.cxx:751
2-D histogram with a double per channel (see TH1 documentation)}
Definition TH2.h:292
std::vector< Float_t > & GetValues()
Definition Event.h:94
ostringstream derivative to redirect and format output
Definition MsgLogger.h:57
void Fill(Int_t, PDEFoamCell *, PDEFoamCell *, PDEFoamCell *)
Fills in certain data into newly allocated cell.
void SetDau0(PDEFoamCell *Daug)
Definition PDEFoamCell.h:96
void SetXdiv(Double_t Xdiv)
Definition PDEFoamCell.h:80
void Print(Option_t *option) const
Printout of the cell geometry parameters for the debug purpose.
void SetElement(TObject *fobj)
Int_t GetStat() const
Definition PDEFoamCell.h:91
void CalcVolume()
Calculates volume of the cell using size params which are calculated.
PDEFoamCell * GetPare() const
Definition PDEFoamCell.h:93
PDEFoamCell * GetDau1() const
Definition PDEFoamCell.h:95
Double_t GetIntg() const
Definition PDEFoamCell.h:86
void SetStat(Int_t Stat)
Definition PDEFoamCell.h:92
PDEFoamCell * GetDau0() const
Definition PDEFoamCell.h:94
Int_t GetBest() const
Definition PDEFoamCell.h:78
Double_t GetDriv() const
Definition PDEFoamCell.h:87
void SetDau1(PDEFoamCell *Daug)
Definition PDEFoamCell.h:97
Double_t GetVolume() const
Definition PDEFoamCell.h:85
TObject * GetElement() const
void SetDriv(Double_t Driv)
Definition PDEFoamCell.h:89
void SetBest(Int_t Best)
Definition PDEFoamCell.h:79
void GetHcub(PDEFoamVect &, PDEFoamVect &) const
Provides size and position of the cell These parameter are calculated by analyzing information in all...
void SetIntg(Double_t Intg)
Definition PDEFoamCell.h:88
This class is the abstract kernel interface for PDEFoam.
virtual Float_t Estimate(PDEFoam *, std::vector< Float_t > &, ECellValue)=0
Implementation of PDEFoam.
Definition PDEFoam.h:79
void Varedu(Double_t[], Int_t &, Double_t &, Double_t &)
Internal subprogram used by Create.
Definition PDEFoam.cxx:570
Double_t GetCellElement(const PDEFoamCell *cell, UInt_t i) const
Returns cell element i of cell 'cell'.
Definition PDEFoam.cxx:1417
void DeleteBinarySearchTree()
Delete the foam's density estimator, which contains the binary search tree.
Definition PDEFoam.cxx:1667
void MakeAlpha()
Internal subprogram used by Create.
Definition PDEFoam.cxx:638
TObjArray * fVariableNames
timer for graphical output
Definition PDEFoam.h:117
virtual Float_t GetCellValue(const std::vector< Float_t > &xvec, ECellValue cv, PDEFoamKernelBase *)
This function finds the cell, which corresponds to the given untransformed event vector 'xvec' and re...
Definition PDEFoam.cxx:1017
void OutputGrow(Bool_t finished=false)
message logger
Definition PDEFoam.cxx:1461
void SetCellElement(PDEFoamCell *cell, UInt_t i, Double_t value)
Set cell element i of cell to value.
Definition PDEFoam.cxx:1433
Int_t Divide(PDEFoamCell *)
Internal subprogram used by Create.
Definition PDEFoam.cxx:715
MsgLogger & Log() const
Definition PDEFoam.h:240
void PrintCell(Long_t iCell=0)
Prints geometry of and elements of 'iCell', as well as relations to parent and daughter cells.
Definition PDEFoam.cxx:896
void ResetCellElements()
Remove the cell elements from all cells.
Definition PDEFoam.cxx:972
void Grow()
Internal subprogram used by Create.
Definition PDEFoam.cxx:768
Double_t Eval(Double_t *xRand, Double_t &event_density)
Internal subprogram.
Definition PDEFoam.cxx:748
void PrintCells()
Prints geometry of ALL cells of the FOAM.
Definition PDEFoam.cxx:943
void SetXmax(Int_t idim, Double_t wmax)
set upper foam bound in dimension idim
Definition PDEFoam.cxx:276
virtual ~PDEFoam()
Default destructor.
Definition PDEFoam.cxx:184
PDEFoam()
Default constructor for streamer, user should not use it.
Definition PDEFoam.cxx:103
TH1D * Draw1Dim(ECellValue cell_value, Int_t nbin, PDEFoamKernelBase *kernel=NULL)
Draws 1-dimensional foam (= histogram)
Definition PDEFoam.cxx:1219
virtual Bool_t CellValueIsUndefined(PDEFoamCell *)
Returns true, if the value of the given cell is undefined.
Definition PDEFoam.cxx:991
virtual void FillFoamCells(const Event *ev, Float_t wt)
This function fills a weight 'wt' into the PDEFoam cell, which corresponds to the given event 'ev'.
Definition PDEFoam.cxx:956
void Create()
Basic initialization of FOAM invoked by the user.
Definition PDEFoam.cxx:292
void SetInhiDiv(Int_t, Int_t)
This can be called before Create, after setting kDim It defines which variables are excluded in the p...
Definition PDEFoam.cxx:803
void InitCells()
Internal subprogram used by Create.
Definition PDEFoam.cxx:356
PDEFoamCell * FindCell(const std::vector< Float_t > &) const
Find cell that contains 'xvec' (in foam coordinates [0,1]).
Definition PDEFoam.cxx:1081
void FillBinarySearchTree(const Event *ev)
Insert event to internal foam's density estimator PDEFoamDensityBase.
Definition PDEFoam.cxx:1658
virtual TH2D * Project2(Int_t idim1, Int_t idim2, ECellValue cell_value=kValue, PDEFoamKernelBase *kernel=NULL, UInt_t nbin=50)
Project foam variable idim1 and variable idim2 to histogram.
Definition PDEFoam.cxx:1271
virtual void Explore(PDEFoamCell *Cell)
Internal subprogram used by Create.
Definition PDEFoam.cxx:434
void SetXmin(Int_t idim, Double_t wmin)
set lower foam bound in dimension idim
Definition PDEFoam.cxx:265
std::vector< TMVA::PDEFoamCell * > FindCells(const std::vector< Float_t > &) const
Find all cells, that contain txvec.
Definition PDEFoam.cxx:1166
Int_t CellFill(Int_t, PDEFoamCell *)
Internal subprogram used by Create.
Definition PDEFoam.cxx:389
Long_t PeekMax()
Internal subprogram used by Create.
Definition PDEFoam.cxx:652
void RootPlot2dim(const TString &filename, TString opt, Bool_t createCanvas=kTRUE, Bool_t colors=kTRUE)
Debugging tool which plots the cells of a 2-dimensional PDEFoam as rectangles in C++ format readable ...
Definition PDEFoam.cxx:1512
void CheckAll(Int_t)
User utility, miscellaneous and debug.
Definition PDEFoam.cxx:823
void SetDim(Int_t kDim)
Sets dimension of cubical space.
Definition PDEFoam.cxx:250
Timing information for training and evaluation of MVA methods.
Definition Timer.h:58
An array of TObjects.
Definition TObjArray.h:31
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Print(Option_t *option="") const
This method must be overridden when a class wants to print itself.
Definition TObject.cxx:622
Random number generator class based on M.
Definition TRandom3.h:27
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:624
void SetPalette(Int_t ncolors=kBird, Int_t *colors=0, Float_t alpha=1.)
See TColor::SetPalette.
Definition TStyle.cxx:1782
Int_t GetColorPalette(Int_t i) const
Return color number i in current palette.
Definition TStyle.cxx:1056
Int_t GetNumberOfColors() const
Return number of colors in the color palette.
Definition TStyle.cxx:1122
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
TH1F * h1
Definition legend1.C:5
MsgLogger & Endl(MsgLogger &ml)
Definition MsgLogger.h:148
Short_t Abs(Short_t d)
Definition TMathBase.h:120