Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
MethodPDEFoam.cxx
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: Tancredi Carli, Dominik Dannheim, Alexander Voigt
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate Data analysis *
6 * Package: TMVA *
7 * Class : MethodPDEFoam *
8 * *
9 * *
10 * Description: *
11 * Implementation (see header for description) *
12 * *
13 * Authors (alphabetical): *
14 * Tancredi Carli - CERN, Switzerland *
15 * Dominik Dannheim - CERN, Switzerland *
16 * Alexander Voigt - TU Dresden, Germany *
17 * Peter Speckmayer - CERN, Switzerland *
18 * *
19 * Original author of the TFoam implementation: *
20 * S. Jadach - Institute of Nuclear Physics, Cracow, Poland *
21 * *
22 * Copyright (c) 2008, 2010: *
23 * CERN, Switzerland *
24 * MPI-K Heidelberg, Germany *
25 * *
26 * Redistribution and use in source and binary forms, with or without *
27 * modification, are permitted according to the terms listed in LICENSE *
28 * (see tmva/doc/LICENSE) *
29 **********************************************************************************/
30
31/*! \class TMVA::MethodPDEFoam
32\ingroup TMVA
33
34The PDEFoam method is an extension of the PDERS method, which
35divides the multi-dimensional phase space in a finite number of
36hyper-rectangles (cells) of constant event density. This "foam" of
37cells is filled with averaged probability-density information
38sampled from a training event sample.
39
40For a given number of cells, the binning algorithm adjusts the size
41and position of the cells inside the multidimensional phase space
42based on a binary-split algorithm, minimizing the variance of the
43event density in the cell.
44The binned event density information of the final foam is stored in
45binary trees, allowing for a fast and memory-efficient
46classification of events.
47
48The implementation of PDEFoam is based on the Monte-Carlo
49integration package TFoam included in the analysis package ROOT.
50*/
51
52#include "TMVA/MethodPDEFoam.h"
53
55#include "TMVA/Config.h"
56#include "TMVA/Configurable.h"
57#include "TMVA/CrossEntropy.h"
58#include "TMVA/DataSet.h"
59#include "TMVA/DataSetInfo.h"
60#include "TMVA/Event.h"
61#include "TMVA/GiniIndex.h"
63#include "TMVA/IMethod.h"
65#include "TMVA/MethodBase.h"
66#include "TMVA/MsgLogger.h"
67#include "TMVA/Ranking.h"
68#include "TMVA/SdivSqrtSplusB.h"
69#include "TMVA/SeparationBase.h"
70#include "TMVA/Tools.h"
71#include "TMVA/Types.h"
72#include "TMVA/VariableInfo.h"
73
74#include "TMath.h"
75#include "TH1F.h"
76#include "TFile.h"
77
78REGISTER_METHOD(PDEFoam)
79
80
81////////////////////////////////////////////////////////////////////////////////
82/// init PDEFoam objects
83
85 const TString& methodTitle,
88 MethodBase( jobName, Types::kPDEFoam, methodTitle, dsi, theOption)
89 , fSigBgSeparated(kFALSE)
90 , fFrac(0.001)
91 , fDiscrErrCut(-1.0)
92 , fVolFrac(1.0/15.0)
93 , fnCells(999)
94 , fnActiveCells(500)
95 , fnSampl(2000)
96 , fnBin(5)
97 , fEvPerBin(10000)
98 , fCompress(kTRUE)
99 , fMultiTargetRegression(kFALSE)
100 , fNmin(100)
101 , fCutNmin(kTRUE)
102 , fMaxDepth(0)
103 , fKernelStr("None")
104 , fKernel(kNone)
105 , fKernelEstimator(NULL)
106 , fTargetSelectionStr("Mean")
107 , fTargetSelection(kMean)
108 , fFillFoamWithOrigWeights(kFALSE)
109 , fUseYesNoCell(kFALSE)
110 , fDTLogic("None")
111 , fDTSeparation(kFoam)
112 , fPeekMax(kTRUE)
113 , fXmin()
114 , fXmax()
115 , fFoam()
116{
117}
118
119////////////////////////////////////////////////////////////////////////////////
120/// constructor from weight file
121
123 const TString& theWeightFile) :
124 MethodBase( Types::kPDEFoam, dsi, theWeightFile)
125 , fSigBgSeparated(kFALSE)
126 , fFrac(0.001)
127 , fDiscrErrCut(-1.0)
128 , fVolFrac(1.0/15.0)
129 , fnCells(999)
130 , fnActiveCells(500)
131 , fnSampl(2000)
132 , fnBin(5)
133 , fEvPerBin(10000)
134 , fCompress(kTRUE)
135 , fMultiTargetRegression(kFALSE)
136 , fNmin(100)
137 , fCutNmin(kTRUE)
138 , fMaxDepth(0)
139 , fKernelStr("None")
140 , fKernel(kNone)
141 , fKernelEstimator(NULL)
142 , fTargetSelectionStr("Mean")
143 , fTargetSelection(kMean)
144 , fFillFoamWithOrigWeights(kFALSE)
145 , fUseYesNoCell(kFALSE)
146 , fDTLogic("None")
147 , fDTSeparation(kFoam)
148 , fPeekMax(kTRUE)
149 , fXmin()
150 , fXmax()
151 , fFoam()
152{
153}
154
155////////////////////////////////////////////////////////////////////////////////
156/// PDEFoam can handle classification with multiple classes and regression
157/// with one or more regression-targets
158
166
167////////////////////////////////////////////////////////////////////////////////
168/// default initialization called by all constructors
169
171{
172 // init PDEFoam options
173 fSigBgSeparated = kFALSE; // default: unified foam
174 fFrac = 0.001; // fraction of outlier events
175 fDiscrErrCut = -1.; // cut on discriminator error
176 fVolFrac = 1./15.; // range searching box size
177 fnActiveCells = 500; // number of active cells to create
178 fnCells = fnActiveCells*2-1; // total number of cells
179 fnSampl = 2000; // number of sampling points in cell
180 fnBin = 5; // number of bins in edge histogram
181 fEvPerBin = 10000; // number of events per bin
182 fNmin = 100; // minimum number of events in cell
183 fMaxDepth = 0; // cell tree depth (default: unlimited)
184 fFillFoamWithOrigWeights = kFALSE; // fill orig. weights into foam
185 fUseYesNoCell = kFALSE; // return -1 or 1 for bg or signal events
186 fDTLogic = "None"; // decision tree algorithmus
187 fDTSeparation = kFoam; // separation type
188
189 fKernel = kNone; // default: use no kernel
190 fKernelEstimator= NULL; // kernel estimator used during evaluation
191 fTargetSelection= kMean; // default: use mean for target selection (only multi target regression!)
192
193 fCompress = kTRUE; // compress ROOT output file
194 fMultiTargetRegression = kFALSE; // multi-target regression
195
196 DeleteFoams();
197
198 if (fUseYesNoCell)
199 SetSignalReferenceCut( 0.0 ); // MVA output in [-1, 1]
200 else
201 SetSignalReferenceCut( 0.5 ); // MVA output in [0, 1]
202}
203
204////////////////////////////////////////////////////////////////////////////////
205/// Declare MethodPDEFoam options
206
208{
209 DeclareOptionRef( fSigBgSeparated = kFALSE, "SigBgSeparate", "Separate foams for signal and background" );
210 DeclareOptionRef( fFrac = 0.001, "TailCut", "Fraction of outlier events that are excluded from the foam in each dimension" );
211 DeclareOptionRef( fVolFrac = 1./15., "VolFrac", "Size of sampling box, used for density calculation during foam build-up (maximum value: 1.0 is equivalent to volume of entire foam)");
212 DeclareOptionRef( fnActiveCells = 500, "nActiveCells", "Maximum number of active cells to be created by the foam");
213 DeclareOptionRef( fnSampl = 2000, "nSampl", "Number of generated MC events per cell");
214 DeclareOptionRef( fnBin = 5, "nBin", "Number of bins in edge histograms");
215 DeclareOptionRef( fCompress = kTRUE, "Compress", "Compress foam output file");
216 DeclareOptionRef( fMultiTargetRegression = kFALSE, "MultiTargetRegression", "Do regression with multiple targets");
217 DeclareOptionRef( fNmin = 100, "Nmin", "Number of events in cell required to split cell");
218 DeclareOptionRef( fMaxDepth = 0, "MaxDepth", "Maximum depth of cell tree (0=unlimited)");
219 DeclareOptionRef( fFillFoamWithOrigWeights = kFALSE, "FillFoamWithOrigWeights", "Fill foam with original or boost weights");
220 DeclareOptionRef( fUseYesNoCell = kFALSE, "UseYesNoCell", "Return -1 or 1 for bkg or signal like events");
221 DeclareOptionRef( fDTLogic = "None", "DTLogic", "Use decision tree algorithm to split cells");
222 AddPreDefVal(TString("None"));
223 AddPreDefVal(TString("GiniIndex"));
224 AddPreDefVal(TString("MisClassificationError"));
225 AddPreDefVal(TString("CrossEntropy"));
226 AddPreDefVal(TString("GiniIndexWithLaplace"));
227 AddPreDefVal(TString("SdivSqrtSplusB"));
228
229 DeclareOptionRef( fKernelStr = "None", "Kernel", "Kernel type used");
230 AddPreDefVal(TString("None"));
231 AddPreDefVal(TString("Gauss"));
232 AddPreDefVal(TString("LinNeighbors"));
233 DeclareOptionRef( fTargetSelectionStr = "Mean", "TargetSelection", "Target selection method");
234 AddPreDefVal(TString("Mean"));
235 AddPreDefVal(TString("Mpv"));
236}
237
238
239////////////////////////////////////////////////////////////////////////////////
240/// options that are used ONLY for the READER to ensure backward compatibility
241
244 DeclareOptionRef(fCutNmin = kTRUE, "CutNmin", "Requirement for minimal number of events in cell");
245 DeclareOptionRef(fPeekMax = kTRUE, "PeekMax", "Peek cell with max. loss for the next split");
246}
247
248////////////////////////////////////////////////////////////////////////////////
249/// process user options
250
252{
253 if (!(fFrac>=0. && fFrac<=1.)) {
254 Log() << kWARNING << "TailCut not in [0.,1] ==> using 0.001 instead" << Endl;
255 fFrac = 0.001;
256 }
257
258 if (fnActiveCells < 1) {
259 Log() << kWARNING << "invalid number of active cells specified: "
260 << fnActiveCells << "; setting nActiveCells=2" << Endl;
261 fnActiveCells = 2;
262 }
263 fnCells = fnActiveCells*2-1;
264
265 // DT logic is only applicable if a single foam is trained
266 if (fSigBgSeparated && fDTLogic != "None") {
267 Log() << kFATAL << "Decision tree logic works only for a single foam (SigBgSeparate=F)" << Endl;
268 }
269
270 // set separation to use
271 if (fDTLogic == "None")
272 fDTSeparation = kFoam;
273 else if (fDTLogic == "GiniIndex")
274 fDTSeparation = kGiniIndex;
275 else if (fDTLogic == "MisClassificationError")
276 fDTSeparation = kMisClassificationError;
277 else if (fDTLogic == "CrossEntropy")
278 fDTSeparation = kCrossEntropy;
279 else if (fDTLogic == "GiniIndexWithLaplace")
280 fDTSeparation = kGiniIndexWithLaplace;
281 else if (fDTLogic == "SdivSqrtSplusB")
282 fDTSeparation = kSdivSqrtSplusB;
283 else {
284 Log() << kWARNING << "Unknown separation type: " << fDTLogic
285 << ", setting to None" << Endl;
286 fDTLogic = "None";
287 fDTSeparation = kFoam;
288 }
289
290 if (fKernelStr == "None" ) fKernel = kNone;
291 else if (fKernelStr == "Gauss" ) fKernel = kGaus;
292 else if (fKernelStr == "LinNeighbors") fKernel = kLinN;
293
294 if (fTargetSelectionStr == "Mean" ) fTargetSelection = kMean;
295 else fTargetSelection = kMpv;
296 // sanity check: number of targets > 1 and MultiTargetRegression=F
297 // makes no sense --> set MultiTargetRegression=T
298 if (DoRegression() && Data()->GetNTargets() > 1 && !fMultiTargetRegression) {
299 Log() << kWARNING << "Warning: number of targets > 1"
300 << " and MultiTargetRegression=F was set, this makes no sense!"
301 << " --> I'm setting MultiTargetRegression=T" << Endl;
302 fMultiTargetRegression = kTRUE;
303 }
304}
305
306////////////////////////////////////////////////////////////////////////////////
307/// destructor
308
310{
311 DeleteFoams();
312
313 if (fKernelEstimator != NULL)
314 delete fKernelEstimator;
315}
316
317////////////////////////////////////////////////////////////////////////////////
318/// Determine foam range [fXmin, fXmax] for all dimensions, such
319/// that a fraction of 'fFrac' events lie outside the foam.
320
322{
323 fXmin.clear();
324 fXmax.clear();
325 UInt_t kDim = GetNvar(); // == Data()->GetNVariables();
326 UInt_t tDim = Data()->GetNTargets();
327 UInt_t vDim = Data()->GetNVariables();
328 if (fMultiTargetRegression)
329 kDim += tDim;
330
331 Float_t *xmin = new Float_t[kDim];
332 Float_t *xmax = new Float_t[kDim];
333
334 // set default values
335 for (UInt_t dim=0; dim<kDim; dim++) {
336 xmin[dim] = FLT_MAX;
337 xmax[dim] = FLT_MIN;
338 }
339
340 Log() << kDEBUG << "Number of training events: " << Data()->GetNTrainingEvents() << Endl;
341 Int_t nevoutside = (Int_t)((Data()->GetNTrainingEvents())*(fFrac)); // number of events that are outside the range
342 Int_t rangehistbins = 10000; // number of bins in histos
343
344 // loop over all testing signal and BG events and clac minimal and
345 // maximal value of every variable
346 for (Long64_t i=0; i<(GetNEvents()); i++) { // events loop
347 const Event* ev = GetEvent(i);
348 for (UInt_t dim=0; dim<kDim; dim++) { // variables loop
349 Float_t val;
350 if (fMultiTargetRegression) {
351 if (dim < vDim)
352 val = ev->GetValue(dim);
353 else
354 val = ev->GetTarget(dim-vDim);
355 }
356 else
357 val = ev->GetValue(dim);
358
359 if (val<xmin[dim])
360 xmin[dim] = val;
361 if (val>xmax[dim])
362 xmax[dim] = val;
363 }
364 }
365
366 // Create and fill histograms for each dimension (with same events
367 // as before), to determine range based on number of events outside
368 // the range
369 TH1F **range_h = new TH1F*[kDim];
370 for (UInt_t dim=0; dim<kDim; dim++) {
371 range_h[dim] = new TH1F(TString::Format("range%i", dim), "range", rangehistbins, xmin[dim], xmax[dim]);
372 }
373
374 // fill all testing events into histos
375 for (Long64_t i=0; i<GetNEvents(); i++) {
376 const Event* ev = GetEvent(i);
377 for (UInt_t dim=0; dim<kDim; dim++) {
378 if (fMultiTargetRegression) {
379 if (dim < vDim)
380 range_h[dim]->Fill(ev->GetValue(dim));
381 else
382 range_h[dim]->Fill(ev->GetTarget(dim-vDim));
383 }
384 else
385 range_h[dim]->Fill(ev->GetValue(dim));
386 }
387 }
388
389 // calc Xmin, Xmax from Histos
390 for (UInt_t dim=0; dim<kDim; dim++) {
391 for (Int_t i=1; i<(rangehistbins+1); i++) { // loop over bins
392 if (range_h[dim]->Integral(0, i) > nevoutside) { // calc left limit (integral over bins 0..i = nevoutside)
393 xmin[dim]=range_h[dim]->GetBinLowEdge(i);
394 break;
395 }
396 }
397 for (Int_t i=rangehistbins; i>0; i--) { // calc right limit (integral over bins i..max = nevoutside)
398 if (range_h[dim]->Integral(i, (rangehistbins+1)) > nevoutside) {
399 xmax[dim]=range_h[dim]->GetBinLowEdge(i+1);
400 break;
401 }
402 }
403 }
404 // now xmin[] and xmax[] contain upper/lower limits for every dimension
405
406 // copy xmin[], xmax[] values to the class variable
407 fXmin.clear();
408 fXmax.clear();
409 for (UInt_t dim=0; dim<kDim; dim++) {
410 fXmin.push_back(xmin[dim]);
411 fXmax.push_back(xmax[dim]);
412 }
413
414
415 delete[] xmin;
416 delete[] xmax;
417
418 // delete histos
419 for (UInt_t dim=0; dim<kDim; dim++)
420 delete range_h[dim];
421 delete[] range_h;
422
423 return;
424}
425
426////////////////////////////////////////////////////////////////////////////////
427/// Train PDE-Foam depending on the set options
428
430{
431 Log() << kVERBOSE << "Calculate Xmin and Xmax for every dimension" << Endl;
432 CalcXminXmax();
433
434 // delete foams
435 DeleteFoams();
436
437 // start training
438 if (DoRegression()) {
439 if (fMultiTargetRegression)
440 TrainMultiTargetRegression();
441 else
442 TrainMonoTargetRegression();
443 }
444 else {
445 if (DoMulticlass())
446 TrainMultiClassification();
447 else {
448 if (DataInfo().GetNormalization() != "EQUALNUMEVENTS" ) {
449 Log() << kHEADER << "NormMode=" << DataInfo().GetNormalization()
450 << " chosen. Note that only NormMode=EqualNumEvents"
451 << " ensures that Discriminant values correspond to"
452 << " signal probabilities." << Endl;
453 }
454
455 Log() << kDEBUG << "N_sig for training events: " << Data()->GetNEvtSigTrain() << Endl;
456 Log() << kDEBUG << "N_bg for training events: " << Data()->GetNEvtBkgdTrain() << Endl;
457 Log() << kDEBUG << "User normalization: " << DataInfo().GetNormalization().Data() << Endl;
458
459 if (fSigBgSeparated)
460 TrainSeparatedClassification();
461 else
462 TrainUnifiedClassification();
463 }
464 }
465
466 // delete the binary search tree in order to save memory
467 for(UInt_t i=0; i<fFoam.size(); i++) {
468 if(fFoam.at(i))
469 fFoam.at(i)->DeleteBinarySearchTree();
470 }
471}
472
473////////////////////////////////////////////////////////////////////////////////
474/// Creation of 2 separated foams: one for signal events, one for
475/// background events. At the end the foam cells of fFoam[0] will
476/// contain the average number of signal events and fFoam[1] will
477/// contain the average number of background events.
478
480{
482 foamcaption[0] = "SignalFoam";
483 foamcaption[1] = "BgFoam";
484
485 for(int i=0; i<2; i++) {
486 // create 2 PDEFoams
487 fFoam.push_back( InitFoam(foamcaption[i], kSeparate) );
488
489 Log() << kVERBOSE << "Filling binary search tree of " << foamcaption[i]
490 << " with events" << Endl;
491 // insert event to BinarySearchTree
492 for (Long64_t k=0; k<GetNEvents(); ++k) {
493 const Event* ev = GetEvent(k);
494 if ((i==0 && DataInfo().IsSignal(ev)) || (i==1 && !DataInfo().IsSignal(ev)))
495 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
496 fFoam.back()->FillBinarySearchTree(ev);
497 }
498
499 Log() << kINFO << "Build up " << foamcaption[i] << Endl;
500 fFoam.back()->Create(); // build foam
501
502 Log() << kVERBOSE << "Filling foam cells with events" << Endl;
503 // loop over all events -> fill foam cells
504 for (Long64_t k=0; k<GetNEvents(); ++k) {
505 const Event* ev = GetEvent(k);
506 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
507 if ((i==0 && DataInfo().IsSignal(ev)) || (i==1 && !DataInfo().IsSignal(ev)))
508 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
509 fFoam.back()->FillFoamCells(ev, weight);
510 }
511 }
512}
513
514////////////////////////////////////////////////////////////////////////////////
515/// Create only one unified foam (fFoam[0]) whose cells contain the
516/// average discriminator (N_sig)/(N_sig + N_bg)
517
519{
520 fFoam.push_back( InitFoam("DiscrFoam", kDiscr, fSignalClass) );
521
522 Log() << kVERBOSE << "Filling binary search tree of discriminator foam with events" << Endl;
523 // insert event to BinarySearchTree
524 for (Long64_t k=0; k<GetNEvents(); ++k) {
525 const Event* ev = GetEvent(k);
526 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
527 fFoam.back()->FillBinarySearchTree(ev);
528 }
529
530 Log() << kINFO << "Build up discriminator foam" << Endl;
531 fFoam.back()->Create(); // build foam
532
533 Log() << kVERBOSE << "Filling foam cells with events" << Endl;
534 // loop over all training events -> fill foam cells with N_sig and N_Bg
535 for (Long64_t k=0; k<GetNEvents(); ++k) {
536 const Event* ev = GetEvent(k);
537 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
538 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
539 fFoam.back()->FillFoamCells(ev, weight);
540 }
541
542 Log() << kVERBOSE << "Calculate cell discriminator"<< Endl;
543 // calc discriminator (and it's error) for each cell
544 fFoam.back()->Finalize();
545}
546
547////////////////////////////////////////////////////////////////////////////////
548/// Create one unified foam (see TrainUnifiedClassification()) for
549/// each class, where the cells of foam i (fFoam[i]) contain the
550/// average fraction of events of class i, i.e.
551///
552/// D = number events of class i / total number of events
553
555{
556 for (UInt_t iClass=0; iClass<DataInfo().GetNClasses(); ++iClass) {
557
558 fFoam.push_back( InitFoam(TString::Format("MultiClassFoam%u",iClass), kMultiClass, iClass) );
559
560 Log() << kVERBOSE << "Filling binary search tree of multiclass foam "
561 << iClass << " with events" << Endl;
562 // insert event to BinarySearchTree
563 for (Long64_t k=0; k<GetNEvents(); ++k) {
564 const Event* ev = GetEvent(k);
565 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
566 fFoam.back()->FillBinarySearchTree(ev);
567 }
568
569 Log() << kINFO << "Build up multiclass foam " << iClass << Endl;
570 fFoam.back()->Create(); // build foam
571
572 Log() << kVERBOSE << "Filling foam cells with events" << Endl;
573 // loop over all training events and fill foam cells with signal
574 // and background events
575 for (Long64_t k=0; k<GetNEvents(); ++k) {
576 const Event* ev = GetEvent(k);
577 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
578 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
579 fFoam.back()->FillFoamCells(ev, weight);
580 }
581
582 Log() << kVERBOSE << "Calculate cell discriminator"<< Endl;
583 // calc discriminator (and it's error) for each cell
584 fFoam.back()->Finalize();
585 }
586}
587
588////////////////////////////////////////////////////////////////////////////////
589/// Training one (mono target regression) foam, whose cells contain
590/// the average 0th target. The dimension of the foam = number of
591/// non-targets (= number of variables).
592
594{
595 if (Data()->GetNTargets() != 1) {
596 Log() << kFATAL << "Can't do mono-target regression with "
597 << Data()->GetNTargets() << " targets!" << Endl;
598 }
599
600 Log() << kDEBUG << "MethodPDEFoam: number of Targets: " << Data()->GetNTargets() << Endl;
601
602 fFoam.push_back( InitFoam("MonoTargetRegressionFoam", kMonoTarget) );
603
604 Log() << kVERBOSE << "Filling binary search tree with events" << Endl;
605 // insert event to BinarySearchTree
606 for (Long64_t k=0; k<GetNEvents(); ++k) {
607 const Event* ev = GetEvent(k);
608 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
609 fFoam.back()->FillBinarySearchTree(ev);
610 }
611
612 Log() << kINFO << "Build mono target regression foam" << Endl;
613 fFoam.back()->Create(); // build foam
614
615 Log() << kVERBOSE << "Filling foam cells with events" << Endl;
616 // loop over all events -> fill foam cells with target
617 for (Long64_t k=0; k<GetNEvents(); ++k) {
618 const Event* ev = GetEvent(k);
619 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
620 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
621 fFoam.back()->FillFoamCells(ev, weight);
622 }
623
624 Log() << kVERBOSE << "Calculate average cell targets"<< Endl;
625 // calc weight (and it's error) for each cell
626 fFoam.back()->Finalize();
627}
628
629////////////////////////////////////////////////////////////////////////////////
630/// Training one (multi target regression) foam, whose cells contain
631/// the average event density. The dimension of the foam = number
632/// of non-targets + number of targets.
633
635{
636 Log() << kDEBUG << "Number of variables: " << Data()->GetNVariables() << Endl;
637 Log() << kDEBUG << "Number of Targets: " << Data()->GetNTargets() << Endl;
638 Log() << kDEBUG << "Dimension of foam: " << Data()->GetNVariables()+Data()->GetNTargets() << Endl;
639 if (fKernel==kLinN)
640 Log() << kFATAL << "LinNeighbors kernel currently not supported"
641 << " for multi target regression" << Endl;
642
643 fFoam.push_back( InitFoam("MultiTargetRegressionFoam", kMultiTarget) );
644
645 Log() << kVERBOSE << "Filling binary search tree of multi target regression foam with events"
646 << Endl;
647 // insert event to BinarySearchTree
648 for (Long64_t k=0; k<GetNEvents(); ++k) {
649 Event *ev = new Event(*GetEvent(k));
650 // since in multi-target regression targets are handled like
651 // variables --> remove targets and add them to the event variabels
652 std::vector<Float_t> targets(ev->GetTargets());
653 const UInt_t nVariables = ev->GetValues().size();
654 for (UInt_t i = 0; i < targets.size(); ++i)
655 ev->SetVal(i+nVariables, targets.at(i));
656 ev->GetTargets().clear();
657 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
658 fFoam.back()->FillBinarySearchTree(ev);
659 // since the binary search tree copies the event, one can delete
660 // it
661 delete ev;
662 }
663
664 Log() << kINFO << "Build multi target regression foam" << Endl;
665 fFoam.back()->Create(); // build foam
666
667 Log() << kVERBOSE << "Filling foam cells with events" << Endl;
668 // loop over all events -> fill foam cells with number of events
669 for (Long64_t k=0; k<GetNEvents(); ++k) {
670 Event *ev = new Event(*GetEvent(k));
671 // since in multi-target regression targets are handled like
672 // variables --> remove targets and add them to the event variabels
673 std::vector<Float_t> targets = ev->GetTargets();
674 const UInt_t nVariables = ev->GetValues().size();
675 Float_t weight = fFillFoamWithOrigWeights ? ev->GetOriginalWeight() : ev->GetWeight();
676 for (UInt_t i = 0; i < targets.size(); ++i)
677 ev->SetVal(i+nVariables, targets.at(i));
678 ev->GetTargets().clear();
679 if (!(IgnoreEventsWithNegWeightsInTraining() && ev->GetWeight()<=0))
680 fFoam.back()->FillFoamCells(ev, weight);
681 // since the PDEFoam copies the event, one can delete it
682 delete ev;
683 }
684}
685
686////////////////////////////////////////////////////////////////////////////////
687/// Return Mva-Value.
688///
689/// In case of `fSigBgSeparated==false` (one unified PDEFoam was
690/// trained) the function returns the content of the cell, which
691/// corresponds to the current TMVA::Event, i.e. D =
692/// N_sig/(N_bg+N_sig).
693///
694/// In case of `fSigBgSeparated==true` (two separate PDEFoams were
695/// trained) the function returns
696///
697/// D = Density_sig/(Density_sig+Density_bg)
698///
699/// where 'Density_sig' is the content of the cell in the signal
700/// PDEFoam (fFoam[0]) and 'Density_bg' is the content of the cell
701/// in the background PDEFoam (fFoam[1]).
702///
703/// In both cases the error on the discriminant is stored in 'err'
704/// and 'errUpper'. (Of course err and errUpper must be non-zero
705/// and point to valid address to make this work.)
706
708{
709 const Event* ev = GetEvent();
710 Double_t discr = 0.;
711
712 if (fSigBgSeparated) {
713 std::vector<Float_t> xvec = ev->GetValues();
714
715 Double_t density_sig = 0.; // calc signal event density
716 Double_t density_bg = 0.; // calc background event density
717 density_sig = fFoam.at(0)->GetCellValue(xvec, kValueDensity, fKernelEstimator);
718 density_bg = fFoam.at(1)->GetCellValue(xvec, kValueDensity, fKernelEstimator);
719
720 // calc discriminator (normed!)
721 if ( (density_sig+density_bg) > 0 )
723 else
724 discr = 0.5; // assume 50% signal probability, if no events found (bad assumption, but can be overruled by cut on error)
725 }
726 else { // Signal and Bg not separated
727 // get discriminator direct from the foam
728 discr = fFoam.at(0)->GetCellValue(ev->GetValues(), kValue, fKernelEstimator);
729 }
730
731 // calculate the error
732 if (err || errUpper) {
733 const Double_t discr_error = CalculateMVAError();
734 if (err != 0) *err = discr_error;
735 if (errUpper != 0) *errUpper = discr_error;
736 }
737
738 if (fUseYesNoCell)
739 return (discr < 0.5 ? -1 : 1);
740 else
741 return discr;
742}
743
744////////////////////////////////////////////////////////////////////////////////
745/// Calculate the error on the Mva value
746///
747/// If `fSigBgSeparated == true` the error is calculated from the
748/// number of events in the signal and background PDEFoam cells.
749///
750/// If `fSigBgSeparated == false`, the error is taken directly from
751/// the PDEFoam cell.
752
754{
755 const Event* ev = GetEvent(); // current event
756 Double_t mvaError = 0.0; // the error on the Mva value
757
758 if (fSigBgSeparated) {
759 const std::vector<Float_t>& xvec = ev->GetValues();
760
761 const Double_t neventsB = fFoam.at(1)->GetCellValue(xvec, kValue, fKernelEstimator);
762 const Double_t neventsS = fFoam.at(0)->GetCellValue(xvec, kValue, fKernelEstimator);
763 const Double_t scaleB = 1.;
764 // estimation of statistical error on counted signal/background events
765 const Double_t errorS = neventsS == 0 ? 1.0 : TMath::Sqrt(neventsS);
766 const Double_t errorB = neventsB == 0 ? 1.0 : TMath::Sqrt(neventsB);
767
768 if ((neventsS > 1e-10) || (neventsB > 1e-10)) {
769 // eq. (5) in paper T.Carli, B.Koblitz 2002
771 Sqr(scaleB * neventsS / Sqr(neventsS + scaleB * neventsB) * errorB));
772 } else {
773 mvaError = 1.0;
774 }
775 } else { // Signal and Bg not separated
776 // get discriminator error direct from the foam
777 mvaError = fFoam.at(0)->GetCellValue(ev->GetValues(), kValueError, fKernelEstimator);
778 }
779
780 return mvaError;
781}
782
783////////////////////////////////////////////////////////////////////////////////
784/// Get the multiclass MVA response for the PDEFoam classifier. The
785/// returned MVA values are normalized, i.e. their sum equals 1.
786
787const std::vector<Float_t>& TMVA::MethodPDEFoam::GetMulticlassValues()
788{
789 const TMVA::Event *ev = GetEvent();
790 std::vector<Float_t> xvec = ev->GetValues();
791
792 if (fMulticlassReturnVal == NULL)
793 fMulticlassReturnVal = new std::vector<Float_t>();
794 fMulticlassReturnVal->clear();
795 fMulticlassReturnVal->reserve(DataInfo().GetNClasses());
796
797 std::vector<Float_t> temp; // temp class. values
798 UInt_t nClasses = DataInfo().GetNClasses();
799 temp.reserve(nClasses);
800 for (UInt_t iClass = 0; iClass < nClasses; ++iClass) {
801 temp.push_back(fFoam.at(iClass)->GetCellValue(xvec, kValue, fKernelEstimator));
802 }
803
804 for (UInt_t iClass = 0; iClass < nClasses; ++iClass) {
805 Float_t norm = 0.0; // normalization
806 for (UInt_t j = 0; j < nClasses; ++j) {
807 if (iClass != j)
808 norm += exp(temp[j] - temp[iClass]);
809 }
810 fMulticlassReturnVal->push_back(1.0 / (1.0 + norm));
811 }
812
813 return *fMulticlassReturnVal;
814}
815
816////////////////////////////////////////////////////////////////////////////////
817/// Compute ranking of input variables from the number of cuts made
818/// in each PDEFoam dimension. The PDEFoam dimension (the variable)
819/// for which the most cuts were done is ranked highest.
820
822{
823 // create the ranking object
824 fRanking = new Ranking(GetName(), "Variable Importance");
825 std::vector<Float_t> importance(GetNvar(), 0);
826
827 // determine variable importances
828 for (UInt_t ifoam = 0; ifoam < fFoam.size(); ++ifoam) {
829 // get the number of cuts made in every dimension of foam
830 PDEFoamCell *root_cell = fFoam.at(ifoam)->GetRootCell();
831 std::vector<UInt_t> nCuts(fFoam.at(ifoam)->GetTotDim(), 0);
832 GetNCuts(root_cell, nCuts);
833
834 // fill the importance vector (ignoring the target dimensions in
835 // case of a multi-target regression foam)
836 UInt_t sumOfCuts = 0;
837 std::vector<Float_t> tmp_importance;
838 for (UInt_t ivar = 0; ivar < GetNvar(); ++ivar) {
839 sumOfCuts += nCuts.at(ivar);
840 tmp_importance.push_back( nCuts.at(ivar) );
841 }
842 // normalization of the variable importances of this foam: the
843 // sum of all variable importances equals 1 for this foam
844 for (UInt_t ivar = 0; ivar < GetNvar(); ++ivar) {
845 if (sumOfCuts > 0)
847 else
848 tmp_importance.at(ivar) = 0;
849 }
850 // the overall variable importance is the average over all foams
851 for (UInt_t ivar = 0; ivar < GetNvar(); ++ivar) {
852 importance.at(ivar) += tmp_importance.at(ivar) / fFoam.size();
853 }
854 }
855
856 // fill ranking vector
857 for (UInt_t ivar = 0; ivar < GetNvar(); ++ivar) {
858 fRanking->AddRank(Rank(GetInputLabel(ivar), importance.at(ivar)));
859 }
860
861 return fRanking;
862}
863
864////////////////////////////////////////////////////////////////////////////////
865/// Fill in 'nCuts' the number of cuts made in every foam dimension,
866/// starting at the root cell 'cell'.
867///
868/// Parameters:
869///
870/// - cell - root cell to start the counting from
871///
872/// - nCuts - the number of cuts are saved in this vector
873
875{
876 if (cell == NULL || cell->GetStat() == 1) // cell is active
877 return;
878
879 nCuts.at(cell->GetBest())++;
880
881 if (cell->GetDau0() != NULL)
882 GetNCuts(cell->GetDau0(), nCuts);
883 if (cell->GetDau1() != NULL)
884 GetNCuts(cell->GetDau1(), nCuts);
885}
886
887////////////////////////////////////////////////////////////////////////////////
888/// Set Xmin, Xmax for every dimension in the given pdefoam object
889
891{
892 if (!pdefoam){
893 Log() << kFATAL << "Null pointer given!" << Endl;
894 return;
895 }
896
897 UInt_t num_vars = GetNvar();
898 if (fMultiTargetRegression)
899 num_vars += Data()->GetNTargets();
900
901 for (UInt_t idim=0; idim<num_vars; idim++) { // set upper/ lower limit in foam
902 Log()<< kDEBUG << "foam: SetXmin[dim="<<idim<<"]: " << fXmin.at(idim) << Endl;
903 Log()<< kDEBUG << "foam: SetXmax[dim="<<idim<<"]: " << fXmax.at(idim) << Endl;
904 pdefoam->SetXmin(idim, fXmin.at(idim));
905 pdefoam->SetXmax(idim, fXmax.at(idim));
906 }
907}
908
909////////////////////////////////////////////////////////////////////////////////
910/// Create a new PDEFoam, set the PDEFoam options (nCells, nBin,
911/// Xmin, Xmax, etc.) and initialize the PDEFoam by calling
912/// pdefoam->Initialize().
913///
914/// Parameters:
915///
916/// - foamcaption - name of PDEFoam object
917///
918/// - ft - type of PDEFoam
919///
920/// Candidates are:
921/// - kSeparate - creates TMVA::PDEFoamEvent
922/// - kDiscr - creates TMVA::PDEFoamDiscriminant
923/// - kMonoTarget - creates TMVA::PDEFoamTarget
924/// - kMultiTarget - creates TMVA::MultiTarget
925/// - kMultiClass - creates TMVA::PDEFoamDiscriminant
926///
927/// If 'fDTSeparation != kFoam' then a TMVA::PDEFoamDecisionTree
928/// is created (the separation type depends on fDTSeparation).
929///
930/// - cls - marked event class (optional, default value = 0)
931
933{
934 // number of foam dimensions
935 Int_t dim = 1;
936 if (ft == kMultiTarget)
937 // dimension of foam = number of targets + non-targets
938 dim = Data()->GetNTargets() + Data()->GetNVariables();
939 else
940 dim = GetNvar();
941
942 // calculate range-searching box
943 std::vector<Double_t> box;
944 for (Int_t idim = 0; idim < dim; ++idim) {
945 box.push_back((fXmax.at(idim) - fXmin.at(idim))* fVolFrac);
946 }
947
948 // create PDEFoam and PDEFoamDensityBase
951 if (fDTSeparation == kFoam) {
952 // use PDEFoam algorithm
953 switch (ft) {
954 case kSeparate:
957 break;
958 case kMultiTarget:
959 pdefoam = new PDEFoamMultiTarget(foamcaption, fTargetSelection);
961 break;
962 case kDiscr:
963 case kMultiClass:
966 break;
967 case kMonoTarget:
970 break;
971 default:
972 Log() << kFATAL << "Unknown PDEFoam type!" << Endl;
973 break;
974 }
975 } else {
976 // create a decision tree like PDEFoam
977
978 // create separation type class, which is owned by
979 // PDEFoamDecisionTree (i.e. PDEFoamDecisionTree will delete it)
981 switch (fDTSeparation) {
982 case kGiniIndex:
983 sepType = new GiniIndex();
984 break;
985 case kMisClassificationError:
987 break;
988 case kCrossEntropy:
989 sepType = new CrossEntropy();
990 break;
991 case kGiniIndexWithLaplace:
993 break;
994 case kSdivSqrtSplusB:
995 sepType = new SdivSqrtSplusB();
996 break;
997 default:
998 Log() << kFATAL << "Separation type " << fDTSeparation
999 << " currently not supported" << Endl;
1000 break;
1001 }
1002 switch (ft) {
1003 case kDiscr:
1004 case kMultiClass:
1007 break;
1008 default:
1009 Log() << kFATAL << "Decision tree cell split algorithm is only"
1010 << " available for (multi) classification with a single"
1011 << " PDE-Foam (SigBgSeparate=F)" << Endl;
1012 break;
1013 }
1014 }
1015
1016 if (pdefoam) pdefoam->SetDensity(density);
1017 else Log() << kFATAL << "PDEFoam pointer not set, exiting.." << Endl;
1018
1019 // create pdefoam kernel
1020 fKernelEstimator = CreatePDEFoamKernel();
1021
1022 // set fLogger attributes
1023 pdefoam->Log().SetMinType(this->Log().GetMinType());
1024
1025 // set PDEFoam parameters
1026 pdefoam->SetDim( dim);
1027 pdefoam->SetnCells( fnCells); // optional
1028 pdefoam->SetnSampl( fnSampl); // optional
1029 pdefoam->SetnBin( fnBin); // optional
1030 pdefoam->SetEvPerBin( fEvPerBin); // optional
1031
1032 // cuts
1033 pdefoam->SetNmin(fNmin);
1034 pdefoam->SetMaxDepth(fMaxDepth); // maximum cell tree depth
1035
1036 // Init PDEFoam
1037 pdefoam->Initialize();
1038
1039 // Set Xmin, Xmax
1040 SetXminXmax(pdefoam);
1041
1042 return pdefoam;
1043}
1044
1045////////////////////////////////////////////////////////////////////////////////
1046/// Return regression values for both multi- and mono-target regression
1047
1048const std::vector<Float_t>& TMVA::MethodPDEFoam::GetRegressionValues()
1049{
1050 if (fRegressionReturnVal == 0) fRegressionReturnVal = new std::vector<Float_t>();
1051 fRegressionReturnVal->clear();
1052 fRegressionReturnVal->reserve(Data()->GetNTargets());
1053
1054 const Event* ev = GetEvent();
1055 std::vector<Float_t> vals = ev->GetValues(); // get array of event variables (non-targets)
1056
1057 if (vals.empty()) {
1058 Log() << kWARNING << "<GetRegressionValues> value vector is empty. " << Endl;
1059 }
1060
1061 if (fMultiTargetRegression) {
1062 // create std::map from event variables
1063 std::map<Int_t, Float_t> xvec;
1064 for (UInt_t i=0; i<vals.size(); ++i)
1065 xvec.insert(std::pair<Int_t, Float_t>(i, vals.at(i)));
1066 // get the targets
1067 std::vector<Float_t> targets = fFoam.at(0)->GetCellValue( xvec, kValue );
1068
1069 // sanity check
1070 if (targets.size() != Data()->GetNTargets())
1071 Log() << kFATAL << "Something wrong with multi-target regression foam: "
1072 << "number of targets does not match the DataSet()" << Endl;
1073 for(UInt_t i=0; i<targets.size(); i++)
1074 fRegressionReturnVal->push_back(targets.at(i));
1075 }
1076 else {
1077 fRegressionReturnVal->push_back(fFoam.at(0)->GetCellValue(vals, kValue, fKernelEstimator));
1078 }
1079
1080 // apply inverse transformation to regression values
1081 Event * evT = new Event(*ev);
1082 for (UInt_t itgt = 0; itgt < Data()->GetNTargets(); itgt++) {
1083 evT->SetTarget(itgt, fRegressionReturnVal->at(itgt) );
1084 }
1085 const Event* evT2 = GetTransformationHandler().InverseTransform( evT );
1086 fRegressionReturnVal->clear();
1087 for (UInt_t itgt = 0; itgt < Data()->GetNTargets(); itgt++) {
1088 fRegressionReturnVal->push_back( evT2->GetTarget(itgt) );
1089 }
1090
1091 delete evT;
1092
1093 return (*fRegressionReturnVal);
1094}
1095
1096////////////////////////////////////////////////////////////////////////////////
1097/// create a pdefoam kernel estimator, depending on the current
1098/// value of fKernel
1099
1101{
1102 switch (fKernel) {
1103 case kNone:
1104 return new PDEFoamKernelTrivial();
1105 case kLinN:
1106 return new PDEFoamKernelLinN();
1107 case kGaus:
1108 return new PDEFoamKernelGauss(fVolFrac/2.0);
1109 default:
1110 Log() << kFATAL << "Kernel: " << fKernel << " not supported!" << Endl;
1111 return NULL;
1112 }
1113 return NULL;
1114}
1115
1116////////////////////////////////////////////////////////////////////////////////
1117/// Deletes all trained foams
1118
1120{
1121 for (UInt_t i=0; i<fFoam.size(); i++)
1122 if (fFoam.at(i)) delete fFoam.at(i);
1123 fFoam.clear();
1124}
1125
1126////////////////////////////////////////////////////////////////////////////////
1127/// reset MethodPDEFoam:
1128///
1129/// - delete all PDEFoams
1130/// - delete the kernel estimator
1131
1133{
1134 DeleteFoams();
1135
1136 if (fKernelEstimator != NULL) {
1137 delete fKernelEstimator;
1138 fKernelEstimator = NULL;
1139 }
1140}
1141
1142////////////////////////////////////////////////////////////////////////////////
1143
1146
1147////////////////////////////////////////////////////////////////////////////////
1148/// create XML output of PDEFoam method variables
1149
1151{
1152 void* wght = gTools().AddChild(parent, "Weights");
1153 gTools().AddAttr( wght, "SigBgSeparated", fSigBgSeparated );
1154 gTools().AddAttr( wght, "Frac", fFrac );
1155 gTools().AddAttr( wght, "DiscrErrCut", fDiscrErrCut );
1156 gTools().AddAttr( wght, "VolFrac", fVolFrac );
1157 gTools().AddAttr( wght, "nCells", fnCells );
1158 gTools().AddAttr( wght, "nSampl", fnSampl );
1159 gTools().AddAttr( wght, "nBin", fnBin );
1160 gTools().AddAttr( wght, "EvPerBin", fEvPerBin );
1161 gTools().AddAttr( wght, "Compress", fCompress );
1162 gTools().AddAttr( wght, "DoRegression", DoRegression() );
1163 gTools().AddAttr( wght, "CutNmin", fNmin>0 );
1164 gTools().AddAttr( wght, "Nmin", fNmin );
1165 gTools().AddAttr( wght, "CutRMSmin", false );
1166 gTools().AddAttr( wght, "RMSmin", 0.0 );
1167 gTools().AddAttr( wght, "Kernel", KernelToUInt(fKernel) );
1168 gTools().AddAttr( wght, "TargetSelection", TargetSelectionToUInt(fTargetSelection) );
1169 gTools().AddAttr( wght, "FillFoamWithOrigWeights", fFillFoamWithOrigWeights );
1170 gTools().AddAttr( wght, "UseYesNoCell", fUseYesNoCell );
1171
1172 // save foam borders Xmin[i], Xmax[i]
1173 void *xmin_wrap;
1174 for (UInt_t i=0; i<fXmin.size(); i++){
1175 xmin_wrap = gTools().AddChild( wght, "Xmin" );
1176 gTools().AddAttr( xmin_wrap, "Index", i );
1177 gTools().AddAttr( xmin_wrap, "Value", fXmin.at(i) );
1178 }
1179 void *xmax_wrap;
1180 for (UInt_t i=0; i<fXmax.size(); i++){
1181 xmax_wrap = gTools().AddChild( wght, "Xmax" );
1182 gTools().AddAttr( xmax_wrap, "Index", i );
1183 gTools().AddAttr( xmax_wrap, "Value", fXmax.at(i) );
1184 }
1185
1186 // write foams to xml file
1187 WriteFoamsToFile();
1188}
1189
1190////////////////////////////////////////////////////////////////////////////////
1191/// Write PDEFoams to file
1192
1194{
1195 // fill variable names into foam
1196 FillVariableNamesToFoam();
1197
1198 TString rfname( GetWeightFileName() );
1199
1200 // replace in case of txt weight file
1201 rfname.ReplaceAll( TString(".") + gConfig().GetIONames().fWeightFileExtension + ".txt", ".xml" );
1202
1203 // add foam indicator to distinguish from main weight file
1204 rfname.ReplaceAll( ".xml", "_foams.root" );
1205
1206 TFile *rootFile = 0;
1207 if (fCompress) rootFile = new TFile(rfname, "RECREATE", "foamfile", 9);
1208 else rootFile = new TFile(rfname, "RECREATE");
1209
1210 // write the foams
1211 for (UInt_t i=0; i<fFoam.size(); ++i) {
1212 Log() << "writing foam " << fFoam.at(i)->GetFoamName().Data()
1213 << " to file" << Endl;
1214 fFoam.at(i)->Write(fFoam.at(i)->GetFoamName().Data());
1215 }
1216
1217 rootFile->Close();
1218 Log() << kINFO << "Foams written to file: "
1219 << gTools().Color("lightblue") << rfname << gTools().Color("reset") << Endl;
1220}
1221
1222////////////////////////////////////////////////////////////////////////////////
1223/// read options and internal parameters
1224
1226{
1227 istr >> fSigBgSeparated; // Separate Sig and Bg, or not
1228 istr >> fFrac; // Fraction used for calc of Xmin, Xmax
1229 istr >> fDiscrErrCut; // cut on discriminant error
1230 istr >> fVolFrac; // volume fraction (used for density calculation during buildup)
1231 istr >> fnCells; // Number of Cells (500)
1232 istr >> fnSampl; // Number of MC events per cell in build-up (1000)
1233 istr >> fnBin; // Number of bins in build-up (100)
1234 istr >> fEvPerBin; // Maximum events (equiv.) per bin in build-up (1000)
1235 istr >> fCompress; // compress output file
1236
1237 Bool_t regr;
1238 istr >> regr; // regression foam
1239 SetAnalysisType( (regr ? Types::kRegression : Types::kClassification ) );
1240
1241 Bool_t CutNmin, CutRMSmin; // dummy for backwards compatible.
1242 Float_t RMSmin; // dummy for backwards compatible.
1243 istr >> CutNmin; // cut on minimal number of events in cell
1244 istr >> fNmin;
1245 istr >> CutRMSmin; // cut on minimal RMS in cell
1246 istr >> RMSmin;
1247
1248 UInt_t ker = 0;
1249 istr >> ker; // used kernel for GetMvaValue()
1250 fKernel = UIntToKernel(ker);
1251
1252 UInt_t ts = 0;
1253 istr >> ts; // used method for target selection
1254 fTargetSelection = UIntToTargetSelection(ts);
1255
1256 istr >> fFillFoamWithOrigWeights; // fill foam with original event weights
1257 istr >> fUseYesNoCell; // return -1 or 1 for bg or signal event
1258
1259 // clear old range and prepare new range
1260 fXmin.clear();
1261 fXmax.clear();
1262 UInt_t kDim = GetNvar();
1263 if (fMultiTargetRegression)
1264 kDim += Data()->GetNTargets();
1265 fXmin.assign(kDim, 0);
1266 fXmax.assign(kDim, 0);
1267
1268 // read range
1269 for (UInt_t i=0; i<kDim; i++)
1270 istr >> fXmin.at(i);
1271 for (UInt_t i=0; i<kDim; i++)
1272 istr >> fXmax.at(i);
1273
1274 // read pure foams from file
1275 ReadFoamsFromFile();
1276}
1277
1278////////////////////////////////////////////////////////////////////////////////
1279/// read PDEFoam variables from xml weight file
1280
1282{
1283 gTools().ReadAttr( wghtnode, "SigBgSeparated", fSigBgSeparated );
1284 gTools().ReadAttr( wghtnode, "Frac", fFrac );
1285 gTools().ReadAttr( wghtnode, "DiscrErrCut", fDiscrErrCut );
1286 gTools().ReadAttr( wghtnode, "VolFrac", fVolFrac );
1287 gTools().ReadAttr( wghtnode, "nCells", fnCells );
1288 gTools().ReadAttr( wghtnode, "nSampl", fnSampl );
1289 gTools().ReadAttr( wghtnode, "nBin", fnBin );
1290 gTools().ReadAttr( wghtnode, "EvPerBin", fEvPerBin );
1291 gTools().ReadAttr( wghtnode, "Compress", fCompress );
1292 Bool_t regr; // dummy for backwards compatible.
1293 gTools().ReadAttr( wghtnode, "DoRegression", regr );
1294 Bool_t CutNmin; // dummy for backwards compatible.
1295 gTools().ReadAttr( wghtnode, "CutNmin", CutNmin );
1296 gTools().ReadAttr( wghtnode, "Nmin", fNmin );
1297 Bool_t CutRMSmin; // dummy for backwards compatible.
1298 Float_t RMSmin; // dummy for backwards compatible.
1299 gTools().ReadAttr( wghtnode, "CutRMSmin", CutRMSmin );
1300 gTools().ReadAttr( wghtnode, "RMSmin", RMSmin );
1301 UInt_t ker = 0;
1302 gTools().ReadAttr( wghtnode, "Kernel", ker );
1303 fKernel = UIntToKernel(ker);
1304 UInt_t ts = 0;
1305 gTools().ReadAttr( wghtnode, "TargetSelection", ts );
1306 fTargetSelection = UIntToTargetSelection(ts);
1307 if (gTools().HasAttr(wghtnode, "FillFoamWithOrigWeights"))
1308 gTools().ReadAttr( wghtnode, "FillFoamWithOrigWeights", fFillFoamWithOrigWeights );
1309 if (gTools().HasAttr(wghtnode, "UseYesNoCell"))
1310 gTools().ReadAttr( wghtnode, "UseYesNoCell", fUseYesNoCell );
1311
1312 // clear old range [Xmin, Xmax] and prepare new range for reading
1313 fXmin.clear();
1314 fXmax.clear();
1315 UInt_t kDim = GetNvar();
1316 if (fMultiTargetRegression)
1317 kDim += Data()->GetNTargets();
1318 fXmin.assign(kDim, 0);
1319 fXmax.assign(kDim, 0);
1320
1321 // read foam range
1322 void *xmin_wrap = gTools().GetChild( wghtnode );
1323 for (UInt_t counter=0; counter<kDim; counter++) {
1324 UInt_t i=0;
1325 gTools().ReadAttr( xmin_wrap , "Index", i );
1326 if (i>=kDim)
1327 Log() << kFATAL << "dimension index out of range:" << i << Endl;
1328 gTools().ReadAttr( xmin_wrap , "Value", fXmin.at(i) );
1330 }
1331
1332 void *xmax_wrap = xmin_wrap;
1333 for (UInt_t counter=0; counter<kDim; counter++) {
1334 UInt_t i=0;
1335 gTools().ReadAttr( xmax_wrap , "Index", i );
1336 if (i>=kDim)
1337 Log() << kFATAL << "dimension index out of range:" << i << Endl;
1338 gTools().ReadAttr( xmax_wrap , "Value", fXmax.at(i) );
1340 }
1341
1342 // if foams exist, delete them
1343 DeleteFoams();
1344
1345 // read pure foams from file
1346 ReadFoamsFromFile();
1347
1348 // recreate the pdefoam kernel estimator
1349 if (fKernelEstimator != NULL)
1350 delete fKernelEstimator;
1351 fKernelEstimator = CreatePDEFoamKernel();
1352}
1353
1354////////////////////////////////////////////////////////////////////////////////
1355/// Reads a foam with name 'foamname' from file, and returns a clone
1356/// of the foam. The given ROOT file must be open. (The ROOT file
1357/// will not be closed in this function.)
1358///
1359/// Parameters:
1360///
1361/// - file - an open ROOT file
1362///
1363/// - foamname - name of foam to load from the file
1364///
1365/// Returns:
1366///
1367/// If a foam with name 'foamname' exists in the file, then it is
1368/// read from the file, cloned and returned. If a foam with name
1369/// 'foamname' does not exist in the file or the clone operation
1370/// does not succeed, then NULL is returned.
1371
1373{
1374 if (file == NULL) {
1375 Log() << kWARNING << "<ReadClonedFoamFromFile>: NULL pointer given" << Endl;
1376 return NULL;
1377 }
1378
1379 // try to load the foam from the file
1380 PDEFoam *foam = (PDEFoam*) file->Get(foamname);
1381 if (foam == NULL) {
1382 return NULL;
1383 }
1384 // try to clone the foam
1385 foam = (PDEFoam*) foam->Clone();
1386 if (foam == NULL) {
1387 Log() << kWARNING << "<ReadClonedFoamFromFile>: " << foamname
1388 << " could not be cloned!" << Endl;
1389 return NULL;
1390 }
1391
1392 return foam;
1393}
1394
1395////////////////////////////////////////////////////////////////////////////////
1396/// read foams from file
1397
1399{
1400 TString rfname( GetWeightFileName() );
1401
1402 // replace in case of txt weight file
1403 rfname.ReplaceAll( TString(".") + gConfig().GetIONames().fWeightFileExtension + ".txt", ".xml" );
1404
1405 // add foam indicator to distinguish from main weight file
1406 rfname.ReplaceAll( ".xml", "_foams.root" );
1407
1408 Log() << kINFO << "Read foams from file: " << gTools().Color("lightblue")
1409 << rfname << gTools().Color("reset") << Endl;
1410 TFile *rootFile = new TFile( rfname, "READ" );
1411 if (rootFile->IsZombie()) Log() << kFATAL << "Cannot open file \"" << rfname << "\"" << Endl;
1412
1413 // read foams from file
1414 if (DoRegression()) {
1415 if (fMultiTargetRegression)
1416 fFoam.push_back(ReadClonedFoamFromFile(rootFile, "MultiTargetRegressionFoam"));
1417 else
1418 fFoam.push_back(ReadClonedFoamFromFile(rootFile, "MonoTargetRegressionFoam"));
1419 } else {
1420 if (fSigBgSeparated) {
1421 fFoam.push_back(ReadClonedFoamFromFile(rootFile, "SignalFoam"));
1422 fFoam.push_back(ReadClonedFoamFromFile(rootFile, "BgFoam"));
1423 } else {
1424 // try to load discriminator foam
1425 PDEFoam *foam = ReadClonedFoamFromFile(rootFile, "DiscrFoam");
1426 if (foam != NULL)
1427 fFoam.push_back(foam);
1428 else {
1429 // load multiclass foams
1430 for (UInt_t iClass=0; iClass<DataInfo().GetNClasses(); ++iClass) {
1431 fFoam.push_back(ReadClonedFoamFromFile(rootFile, TString::Format("MultiClassFoam%u",iClass)));
1432 }
1433 }
1434 }
1435 }
1436
1437 // Close the root file. Note, that the foams are still present in
1438 // memory!
1439 rootFile->Close();
1440 delete rootFile;
1441
1442 for (UInt_t i=0; i<fFoam.size(); ++i) {
1443 if (!fFoam.at(0))
1444 Log() << kFATAL << "Could not load foam!" << Endl;
1445 }
1446}
1447
1448////////////////////////////////////////////////////////////////////////////////
1449/// convert UInt_t to EKernel (used for reading weight files)
1450
1452{
1453 switch(iker) {
1454 case 0: return kNone;
1455 case 1: return kGaus;
1456 case 2: return kLinN;
1457 default:
1458 Log() << kWARNING << "<UIntToKernel>: unknown kernel number: " << iker << Endl;
1459 return kNone;
1460 }
1461 return kNone;
1462}
1463
1464////////////////////////////////////////////////////////////////////////////////
1465/// convert UInt_t to ETargetSelection (used for reading weight files)
1466
1468{
1469 switch(its) {
1470 case 0: return kMean;
1471 case 1: return kMpv;
1472 default:
1473 Log() << kWARNING << "<UIntToTargetSelection>: unknown method TargetSelection: " << its << Endl;
1474 return kMean;
1475 }
1476 return kMean;
1477}
1478
1479////////////////////////////////////////////////////////////////////////////////
1480/// store the variable names in all foams
1481
1483{
1484 for (UInt_t ifoam=0; ifoam<fFoam.size(); ifoam++) {
1485 for (Int_t idim=0; idim<fFoam.at(ifoam)->GetTotDim(); idim++) {
1486 if(fMultiTargetRegression && (UInt_t)idim>=DataInfo().GetNVariables())
1487 fFoam.at(ifoam)->AddVariableName(DataInfo().GetTargetInfo(idim-DataInfo().GetNVariables()).GetExpression().Data());
1488 else
1489 fFoam.at(ifoam)->AddVariableName(DataInfo().GetVariableInfo(idim).GetExpression().Data());
1490 }
1491 }
1492}
1493
1494////////////////////////////////////////////////////////////////////////////////
1495/// write PDEFoam-specific classifier response
1496/// NOT IMPLEMENTED YET!
1497
1498void TMVA::MethodPDEFoam::MakeClassSpecific( std::ostream& /*fout*/, const TString& /*className*/ ) const
1499{
1500}
1501
1502////////////////////////////////////////////////////////////////////////////////
1503/// provide help message
1504
1506{
1507 Log() << Endl;
1508 Log() << gTools().Color("bold") << "--- Short description:" << gTools().Color("reset") << Endl;
1509 Log() << Endl;
1510 Log() << "PDE-Foam is a variation of the PDE-RS method using a self-adapting" << Endl;
1511 Log() << "binning method to divide the multi-dimensional variable space into a" << Endl;
1512 Log() << "finite number of hyper-rectangles (cells). The binning algorithm " << Endl;
1513 Log() << "adjusts the size and position of a predefined number of cells such" << Endl;
1514 Log() << "that the variance of the signal and background densities inside the " << Endl;
1515 Log() << "cells reaches a minimum" << Endl;
1516 Log() << Endl;
1517 Log() << gTools().Color("bold") << "--- Use of booking options:" << gTools().Color("reset") << Endl;
1518 Log() << Endl;
1519 Log() << "The PDEFoam classifier supports two different algorithms: " << Endl;
1520 Log() << Endl;
1521 Log() << " (1) Create one foam, which stores the signal over background" << Endl;
1522 Log() << " probability density. During foam buildup the variance of the" << Endl;
1523 Log() << " discriminant inside the cells is minimised." << Endl;
1524 Log() << Endl;
1525 Log() << " Booking option: SigBgSeparated=F" << Endl;
1526 Log() << Endl;
1527 Log() << " (2) Create two separate foams, one for the signal events and one for" << Endl;
1528 Log() << " background events. During foam buildup the variance of the" << Endl;
1529 Log() << " event density inside the cells is minimised separately for" << Endl;
1530 Log() << " signal and background." << Endl;
1531 Log() << Endl;
1532 Log() << " Booking option: SigBgSeparated=T" << Endl;
1533 Log() << Endl;
1534 Log() << "The following options can be set (the listed values are found to be a" << Endl;
1535 Log() << "good starting point for most applications):" << Endl;
1536 Log() << Endl;
1537 Log() << " SigBgSeparate False Separate Signal and Background" << Endl;
1538 Log() << " TailCut 0.001 Fraction of outlier events that excluded" << Endl;
1539 Log() << " from the foam in each dimension " << Endl;
1540 Log() << " VolFrac 0.0666 Volume fraction (used for density calculation" << Endl;
1541 Log() << " during foam build-up) " << Endl;
1542 Log() << " nActiveCells 500 Maximal number of active cells in final foam " << Endl;
1543 Log() << " nSampl 2000 Number of MC events per cell in foam build-up " << Endl;
1544 Log() << " nBin 5 Number of bins used in foam build-up " << Endl;
1545 Log() << " Nmin 100 Number of events in cell required to split cell" << Endl;
1546 Log() << " Kernel None Kernel type used (possible values are: None," << Endl;
1547 Log() << " Gauss)" << Endl;
1548 Log() << " Compress True Compress foam output file " << Endl;
1549 Log() << Endl;
1550 Log() << " Additional regression options:" << Endl;
1551 Log() << Endl;
1552 Log() << "MultiTargetRegression False Do regression with multiple targets " << Endl;
1553 Log() << " TargetSelection Mean Target selection method (possible values are: " << Endl;
1554 Log() << " Mean, Mpv)" << Endl;
1555 Log() << Endl;
1556 Log() << gTools().Color("bold") << "--- Performance optimisation:" << gTools().Color("reset") << Endl;
1557 Log() << Endl;
1558 Log() << "The performance of the two implementations was found to be similar for" << Endl;
1559 Log() << "most examples studied. For the same number of cells per foam, the two-" << Endl;
1560 Log() << "foam option approximately doubles the amount of computer memory needed" << Endl;
1561 Log() << "during classification. For special cases where the event-density" << Endl;
1562 Log() << "distribution of signal and background events is very different, the" << Endl;
1563 Log() << "two-foam option was found to perform significantly better than the" << Endl;
1564 Log() << "option with only one foam." << Endl;
1565 Log() << Endl;
1566 Log() << "In order to gain better classification performance we recommend to set" << Endl;
1567 Log() << "the parameter \"nActiveCells\" to a high value." << Endl;
1568 Log() << Endl;
1569 Log() << "The parameter \"VolFrac\" specifies the size of the sampling volume" << Endl;
1570 Log() << "during foam buildup and should be tuned in order to achieve optimal" << Endl;
1571 Log() << "performance. A larger box leads to a reduced statistical uncertainty" << Endl;
1572 Log() << "for small training samples and to smoother sampling. A smaller box on" << Endl;
1573 Log() << "the other hand increases the sensitivity to statistical fluctuations" << Endl;
1574 Log() << "in the training samples, but for sufficiently large training samples" << Endl;
1575 Log() << "it will result in a more precise local estimate of the sampled" << Endl;
1576 Log() << "density. In general, higher dimensional problems require larger box" << Endl;
1577 Log() << "sizes, due to the reduced average number of events per box volume. The" << Endl;
1578 Log() << "default value of 0.0666 was optimised for an example with 5" << Endl;
1579 Log() << "observables and training samples of the order of 50000 signal and" << Endl;
1580 Log() << "background events each." << Endl;
1581 Log() << Endl;
1582 Log() << "Furthermore kernel weighting can be activated, which will lead to an" << Endl;
1583 Log() << "additional performance improvement. Note that Gauss weighting will" << Endl;
1584 Log() << "significantly increase the response time of the method. LinNeighbors" << Endl;
1585 Log() << "weighting performs a linear interpolation with direct neighbor cells" << Endl;
1586 Log() << "for each dimension and is much faster than Gauss weighting." << Endl;
1587 Log() << Endl;
1588 Log() << "The classification results were found to be rather insensitive to the" << Endl;
1589 Log() << "values of the parameters \"nSamples\" and \"nBin\"." << Endl;
1590}
#define REGISTER_METHOD(CLASS)
for example
const Handle_t kNone
Definition GuiTypes.h:89
#define e(i)
Definition RSha256.hxx:103
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:72
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
float xmin
float xmax
TObject * Get(const char *namecycle) override
Return pointer to object identified by namecycle.
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:878
Implementation of the CrossEntropy as separation criterion.
Class that contains all the data information.
Definition DataSetInfo.h:62
Implementation of the GiniIndex With Laplace correction as separation criterion.
Implementation of the GiniIndex as separation criterion.
Definition GiniIndex.h:63
Virtual base Class for all MVA method.
Definition MethodBase.h:82
virtual void DeclareCompatibilityOptions()
options that are used ONLY for the READER to ensure backward compatibility they are hence without any...
The PDEFoam method is an extension of the PDERS method, which divides the multi-dimensional phase spa...
Double_t CalculateMVAError()
Calculate the error on the Mva value.
void DeclareCompatibilityOptions() override
options that are used ONLY for the READER to ensure backward compatibility
void TrainMultiClassification()
Create one unified foam (see TrainUnifiedClassification()) for each class, where the cells of foam i ...
void TrainMultiTargetRegression(void)
Training one (multi target regression) foam, whose cells contain the average event density.
void Train(void) override
Train PDE-Foam depending on the set options.
void DeleteFoams()
Deletes all trained foams.
virtual ~MethodPDEFoam(void)
destructor
void Init(void) override
default initialization called by all constructors
PDEFoam * InitFoam(TString, EFoamType, UInt_t cls=0)
Create a new PDEFoam, set the PDEFoam options (nCells, nBin, Xmin, Xmax, etc.) and initialize the PDE...
Bool_t HasAnalysisType(Types::EAnalysisType type, UInt_t numberClasses, UInt_t numberTargets) override
PDEFoam can handle classification with multiple classes and regression with one or more regression-ta...
void GetHelpMessage() const override
provide help message
void FillVariableNamesToFoam() const
store the variable names in all foams
void TrainMonoTargetRegression(void)
Training one (mono target regression) foam, whose cells contain the average 0th target.
void TrainUnifiedClassification(void)
Create only one unified foam (fFoam[0]) whose cells contain the average discriminator (N_sig)/(N_sig ...
void ReadFoamsFromFile()
read foams from file
void ProcessOptions() override
process user options
EKernel UIntToKernel(UInt_t iker)
convert UInt_t to EKernel (used for reading weight files)
PDEFoamKernelBase * CreatePDEFoamKernel()
create a pdefoam kernel estimator, depending on the current value of fKernel
void ReadWeightsFromStream(std::istream &i) override
read options and internal parameters
const std::vector< Float_t > & GetMulticlassValues() override
Get the multiclass MVA response for the PDEFoam classifier.
void Reset() override
reset MethodPDEFoam:
void MakeClassSpecific(std::ostream &, const TString &) const override
write PDEFoam-specific classifier response NOT IMPLEMENTED YET!
void AddWeightsXMLTo(void *parent) const override
create XML output of PDEFoam method variables
void CalcXminXmax()
Determine foam range [fXmin, fXmax] for all dimensions, such that a fraction of 'fFrac' events lie ou...
void GetNCuts(PDEFoamCell *cell, std::vector< UInt_t > &nCuts)
Fill in 'nCuts' the number of cuts made in every foam dimension, starting at the root cell 'cell'.
PDEFoam * ReadClonedFoamFromFile(TFile *, const TString &)
Reads a foam with name 'foamname' from file, and returns a clone of the foam.
const std::vector< Float_t > & GetRegressionValues() override
Return regression values for both multi- and mono-target regression.
MethodPDEFoam(const TString &jobName, const TString &methodTitle, DataSetInfo &dsi, const TString &theOption="PDEFoam")
init PDEFoam objects
ETargetSelection UIntToTargetSelection(UInt_t its)
convert UInt_t to ETargetSelection (used for reading weight files)
void DeclareOptions() override
Declare MethodPDEFoam options.
void ReadWeightsFromXML(void *wghtnode) override
read PDEFoam variables from xml weight file
void TrainSeparatedClassification(void)
Creation of 2 separated foams: one for signal events, one for background events.
void SetXminXmax(TMVA::PDEFoam *)
Set Xmin, Xmax for every dimension in the given pdefoam object.
void WriteFoamsToFile() const
Write PDEFoams to file.
Double_t GetMvaValue(Double_t *err=nullptr, Double_t *errUpper=nullptr) override
Return Mva-Value.
const Ranking * CreateRanking() override
Compute ranking of input variables from the number of cuts made in each PDEFoam dimension.
Implementation of the MisClassificationError as separation criterion.
This is a concrete implementation of PDEFoam.
This PDEFoam variant acts like a decision tree and stores in every cell the discriminant.
This is an abstract class, which provides an interface for a PDEFoam density estimator.
This is a concrete implementation of PDEFoam.
This PDEFoam variant stores in every cell the discriminant.
This is a concrete implementation of PDEFoam.
This PDEFoam variant stores in every cell the sum of event weights and the sum of the squared event w...
This class is the abstract kernel interface for PDEFoam.
This PDEFoam kernel estimates a cell value for a given event by weighting all cell values with a gaus...
This PDEFoam kernel estimates a cell value for a given event by weighting with cell values of the nea...
This class is a trivial PDEFoam kernel estimator.
This PDEFoam variant is used to estimate multiple targets by creating an event density foam (PDEFoamE...
This is a concrete implementation of PDEFoam.
This PDEFoam variant stores in every cell the average target fTarget (see the Constructor) as well as...
Implementation of PDEFoam.
Definition PDEFoam.h:79
Ranking for variables in method (implementation)
Definition Ranking.h:48
Implementation of the SdivSqrtSplusB as separation criterion.
An interface to calculate the "SeparationGain" for different separation criteria used in various trai...
const TString & Color(const TString &)
human readable color strings
Definition Tools.cxx:803
void ReadAttr(void *node, const char *, T &value)
read attribute from xml
Definition Tools.h:329
void * GetChild(void *parent, const char *childname=nullptr)
get child node
Definition Tools.cxx:1125
void AddAttr(void *node, const char *, const T &value, Int_t precision=16)
add attribute to xml
Definition Tools.h:347
void * AddChild(void *parent, const char *childname, const char *content=nullptr, bool isRootNode=false)
add child node
Definition Tools.cxx:1099
void * GetNextChild(void *prevchild, const char *childname=nullptr)
XML helpers.
Definition Tools.cxx:1137
Singleton class for Global types used by TMVA.
Definition Types.h:71
@ kMulticlass
Definition Types.h:129
@ kClassification
Definition Types.h:127
@ kRegression
Definition Types.h:128
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:987
Basic string class.
Definition TString.h:138
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2459
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
create variable transformations
Config & gConfig()
Tools & gTools()
MsgLogger & Endl(MsgLogger &ml)
Definition MsgLogger.h:148
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:675