Logo ROOT   6.07/09
Reference Guide
PDF.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Asen Christov, Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss, Jan Therhaag, Eckhard von Toerne
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : PDF *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation (see header for description) *
12  * *
13  * Authors (alphabetical): *
14  * Asen Christov <christov@physik.uni-freiburg.de> - Freiburg U., Germany *
15  * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
16  * Jan Therhaag <Jan.Therhaag@cern.ch> - U of Bonn, Germany *
17  * Eckhard von Toerne <evt@physik.uni-bonn.de> - U of Bonn, Germany *
18  * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
19  * Kai Voss <Kai.Voss@cern.ch> - U. of Victoria, Canada *
20  * *
21  * Copyright (c) 2005-2011: *
22  * CERN, Switzerland *
23  * U. of Victoria, Canada *
24  * MPI-K Heidelberg, Germany *
25  * Freiburg U., Germany *
26  * U. of Bonn, Germany *
27  * *
28  * Redistribution and use in source and binary forms, with or without *
29  * modification, are permitted according to the terms listed in LICENSE *
30  * (http://tmva.sourceforge.net/LICENSE) *
31  **********************************************************************************/
32 
33 #include "TMVA/PDF.h"
34 
35 #include "TMVA/Configurable.h"
36 #include "TMVA/KDEKernel.h"
37 #include "TMVA/MsgLogger.h"
38 #include "TMVA/Types.h"
39 #include "TMVA/Tools.h"
40 #include "TMVA/TSpline1.h"
41 #include "TMVA/TSpline2.h"
42 #include "TMVA/Version.h"
43 
44 #include "Riostream.h"
45 #include "TF1.h"
46 #include "TH1F.h"
47 #include "TMath.h"
48 #include "TVectorD.h"
49 
50 #include <cstdlib>
51 #include <iomanip>
52 
53 // static configuration settings
54 const Int_t TMVA::PDF::fgNbin_PdfHist = 10000;
56 const Double_t TMVA::PDF::fgEpsilon = 1.0e-12;
57 
59 
60 ////////////////////////////////////////////////////////////////////////////////
61 /// default constructor needed for ROOT I/O
62 
64 : Configurable (""),
65  fUseHistogram ( kFALSE ),
66  fPDFName ( name ),
67  fNsmooth ( 0 ),
68  fMinNsmooth (-1 ),
69  fMaxNsmooth (-1 ),
70  fNSmoothHist ( 0 ),
71  fInterpolMethod( PDF::kSpline2 ),
72  fSpline ( 0 ),
73  fPDFHist ( 0 ),
74  fHist ( 0 ),
75  fHistOriginal ( 0 ),
76  fGraph ( 0 ),
77  fIGetVal ( 0 ),
78  fHistAvgEvtPerBin ( 0 ),
79  fHistDefinedNBins ( 0 ),
80  fKDEtypeString ( 0 ),
81  fKDEiterString ( 0 ),
82  fBorderMethodString( 0 ),
83  fInterpolateString ( 0 ),
84  fKDEtype ( KDEKernel::kNone ),
85  fKDEiter ( KDEKernel::kNonadaptiveKDE ),
86  fKDEborder ( KDEKernel::kNoTreatment ),
87  fFineFactor ( 0. ),
88  fReadingVersion( 0 ),
89  fCheckHist ( kFALSE ),
90  fNormalize ( norm ),
91  fSuffix ( "" ),
92  fLogger ( 0 )
93 {
94  fLogger = new MsgLogger(this);
95  GetThisPdfThreadLocal() = this;
96 }
97 
98 ////////////////////////////////////////////////////////////////////////////////
99 /// constructor of spline based PDF:
100 
102  const TH1 *hist,
104  Int_t minnsmooth,
105  Int_t maxnsmooth,
106  Bool_t checkHist,
107  Bool_t norm) :
108  Configurable (""),
109  fUseHistogram ( kFALSE ),
110  fPDFName ( name ),
111  fMinNsmooth ( minnsmooth ),
112  fMaxNsmooth ( maxnsmooth ),
113  fNSmoothHist ( 0 ),
114  fInterpolMethod( method ),
115  fSpline ( 0 ),
116  fPDFHist ( 0 ),
117  fHist ( 0 ),
118  fHistOriginal ( 0 ),
119  fGraph ( 0 ),
120  fIGetVal ( 0 ),
121  fHistAvgEvtPerBin ( 0 ),
122  fHistDefinedNBins ( 0 ),
123  fKDEtypeString ( 0 ),
124  fKDEiterString ( 0 ),
125  fBorderMethodString( 0 ),
126  fInterpolateString ( 0 ),
127  fKDEtype ( KDEKernel::kNone ),
128  fKDEiter ( KDEKernel::kNonadaptiveKDE ),
129  fKDEborder ( KDEKernel::kNoTreatment ),
130  fFineFactor ( 0. ),
131  fReadingVersion( 0 ),
132  fCheckHist ( checkHist ),
133  fNormalize ( norm ),
134  fSuffix ( "" ),
135  fLogger ( 0 )
136 {
137  fLogger = new MsgLogger(this);
138  BuildPDF( hist );
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////
142 /// constructor of kernel based PDF:
143 
145  const TH1* hist,
148  KDEKernel::EKernelBorder kborder,
149  Float_t FineFactor,
150  Bool_t norm) :
151  Configurable (""),
152  fUseHistogram ( kFALSE ),
153  fPDFName ( name ),
154  fNsmooth ( 0 ),
155  fMinNsmooth (-1 ),
156  fMaxNsmooth (-1 ),
157  fNSmoothHist ( 0 ),
159  fSpline ( 0 ),
160  fPDFHist ( 0 ),
161  fHist ( 0 ),
162  fHistOriginal ( 0 ),
163  fGraph ( 0 ),
164  fIGetVal ( 0 ),
165  fHistAvgEvtPerBin ( 0 ),
166  fHistDefinedNBins ( 0 ),
167  fKDEtypeString ( 0 ),
168  fKDEiterString ( 0 ),
169  fBorderMethodString( 0 ),
170  fInterpolateString ( 0 ),
171  fKDEtype ( ktype ),
172  fKDEiter ( kiter ),
173  fKDEborder ( kborder ),
174  fFineFactor ( FineFactor),
175  fReadingVersion( 0 ),
176  fCheckHist ( kFALSE ),
177  fNormalize ( norm ),
178  fSuffix ( "" ),
179  fLogger ( 0 )
180 {
181  fLogger = new MsgLogger(this);
182  BuildPDF( hist );
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 
188  const TString& options,
189  const TString& suffix,
190  PDF* defaultPDF,
191  Bool_t norm) :
192  Configurable (options),
193  fUseHistogram ( kFALSE ),
194  fPDFName ( name ),
195  fNsmooth ( 0 ),
196  fMinNsmooth ( -1 ),
197  fMaxNsmooth ( -1 ),
198  fNSmoothHist ( 0 ),
200  fSpline ( 0 ),
201  fPDFHist ( 0 ),
202  fHist ( 0 ),
203  fHistOriginal ( 0 ),
204  fGraph ( 0 ),
205  fIGetVal ( 0 ),
206  fHistAvgEvtPerBin ( 50 ),
207  fHistDefinedNBins ( 0 ),
208  fKDEtypeString ( "Gauss" ),
209  fKDEiterString ( "Nonadaptive" ),
210  fBorderMethodString( "None" ),
211  fInterpolateString ( "Spline2" ),
212  fKDEtype ( KDEKernel::kNone ),
213  fKDEiter ( KDEKernel::kNonadaptiveKDE ),
214  fKDEborder ( KDEKernel::kNoTreatment ),
215  fFineFactor ( 1. ),
216  fReadingVersion( 0 ),
217  fCheckHist ( kFALSE ),
218  fNormalize ( norm ),
219  fSuffix ( suffix ),
220  fLogger ( 0 )
221 {
222  fLogger = new MsgLogger(this);
223  if (defaultPDF != 0) {
224  fNsmooth = defaultPDF->fNsmooth;
225  fMinNsmooth = defaultPDF->fMinNsmooth;
226  fMaxNsmooth = defaultPDF->fMaxNsmooth;
227  fHistAvgEvtPerBin = defaultPDF->fHistAvgEvtPerBin;
228  fHistAvgEvtPerBin = defaultPDF->fHistAvgEvtPerBin;
230  fKDEtypeString = defaultPDF->fKDEtypeString;
231  fKDEiterString = defaultPDF->fKDEiterString;
232  fFineFactor = defaultPDF->fFineFactor;
234  fCheckHist = defaultPDF->fCheckHist;
235  fHistDefinedNBins = defaultPDF->fHistDefinedNBins;
236  }
237 }
238 
239 //___________________fNSmoothHist____________________________________________________
241 {
242  // destructor
243  if (fSpline != NULL) delete fSpline;
244  if (fHist != NULL) delete fHist;
245  if (fPDFHist != NULL) delete fPDFHist;
246  if (fHistOriginal != NULL) delete fHistOriginal;
247  if (fIGetVal != NULL) delete fIGetVal;
248  if (fGraph != NULL) delete fGraph;
249  delete fLogger;
250 }
251 
252 ////////////////////////////////////////////////////////////////////////////////
253 
254 void TMVA::PDF::BuildPDF( const TH1* hist )
255 {
256  GetThisPdfThreadLocal() = this;
257  // sanity check
258  if (hist == NULL) Log() << kFATAL << "Called without valid histogram pointer!" << Endl;
259 
260  // histogram should be non empty
261  if (hist->GetEntries() <= 0)
262  Log() << kFATAL << "Number of entries <= 0 (" << hist->GetEntries() << " in histogram: " << hist->GetTitle() << Endl;
263 
264  if (fInterpolMethod == PDF::kKDE) {
265  Log()<< kDEBUG << "Create "
266  << ((fKDEiter == KDEKernel::kNonadaptiveKDE) ? "nonadaptive " :
267  (fKDEiter == KDEKernel::kAdaptiveKDE) ? "adaptive " : "??? ")
268  << ((fKDEtype == KDEKernel::kGauss) ? "Gauss " : "??? ")
269  << "type KDE kernel for histogram: \"" << hist->GetName() << "\""
270  << Endl;
271  }
272  else {
273  // another sanity check (nsmooth<0 indicated build with KDE)
274  if (fMinNsmooth<0)
275  Log() << kFATAL << "PDF construction called with minnsmooth<0" << Endl;
276  else if (fMaxNsmooth<=0)
278  else if (fMaxNsmooth<fMinNsmooth)
279  Log() << kFATAL << "PDF construction called with maxnsmooth<minnsmooth" << Endl;
280  }
281 
282  fHistOriginal = (TH1F*)hist->Clone( TString(hist->GetName()) + "_original" );
283  fHist = (TH1F*)hist->Clone( TString(hist->GetName()) + "_smoothed" );
284  fHistOriginal->SetTitle( fHistOriginal->GetName() ); // reset to new title as well
285  fHist ->SetTitle( fHist->GetName() );
286 
287  // do not store in current target file
289  fHist ->SetDirectory(0);
291 
293  else BuildSplinePDF();
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 
299 {
300  Int_t ResolutionFactor = (fInterpolMethod == PDF::kKDE) ? 5 : 1;
301  if (evtNum == 0 && fHistDefinedNBins == 0)
302  Log() << kFATAL << "No number of bins set for PDF" << Endl;
303  else if (fHistDefinedNBins > 0)
304  return fHistDefinedNBins * ResolutionFactor;
305  else if ( evtNum > 0 && fHistAvgEvtPerBin > 0 )
306  return evtNum / fHistAvgEvtPerBin * ResolutionFactor;
307  else
308  Log() << kFATAL << "No number of bins or average event per bin set for PDF" << fHistAvgEvtPerBin << Endl;
309  return 0;
310 }
311 
312 ////////////////////////////////////////////////////////////////////////////////
313 /// build the PDF from the original histograms
314 
316 {
317  // (not useful for discrete distributions, or if no splines are requested)
319  // use ROOT TH1 smooth method
320  fNSmoothHist = 0;
321  if (fMaxNsmooth > 0 && fMinNsmooth >=0 ) SmoothHistogram();
322 
323  // fill histogramm to graph
324  FillHistToGraph();
325 
326  // fGraph->Print();
327  switch (fInterpolMethod) {
328 
329  case kSpline0:
330  // use original histogram as reference
331  // this is useful, eg, for discrete variables
333  break;
334 
335  case kSpline1:
336  fSpline = new TMVA::TSpline1( "spline1", new TGraph(*fGraph) );
337  break;
338 
339  case kSpline2:
340  fSpline = new TMVA::TSpline2( "spline2", new TGraph(*fGraph) );
341  break;
342 
343  case kSpline3:
344  fSpline = new TSpline3( "spline3", new TGraph(*fGraph) );
345  break;
346 
347  case kSpline5:
348  fSpline = new TSpline5( "spline5", new TGraph(*fGraph) );
349  break;
350 
351  default:
352  Log() << kWARNING << "No valid interpolation method given! Use Spline2" << Endl;
353  fSpline = new TMVA::TSpline2( "spline2", new TGraph(*fGraph) );
354  Log() << kFATAL << " Well.. .thinking about it, I better quit so you notice you are forced to fix the mistake " << Endl;
355  std::exit(1);
356  }
357  // fill into histogram
359 
360  if (!UseHistogram()) {
363  }
364 
365 
366  // sanity check
367  Double_t integral = GetIntegral();
368  if (integral < 0) Log() << kFATAL << "Integral: " << integral << " <= 0" << Endl;
369 
370  // normalize
371  if (fNormalize)
372  if (integral>0) fPDFHist->Scale( 1.0/integral );
373 
375 }
376 
377 ////////////////////////////////////////////////////////////////////////////////
378 /// creates high-binned reference histogram to be used instead of the
379 /// PDF for speed reasons
380 
382 {
383  fPDFHist = new TH1F( "", "", fgNbin_PdfHist, GetXmin(), GetXmax() );
384  fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_KDE" );
385  fPDFHist->SetName ( (TString)fHist->GetName() + "_hist_from_KDE" );
386 
387  // create the kernel object
388  Float_t histoLowEdge = fHist->GetBinLowEdge(1);
390  KDEKernel *kern = new TMVA::KDEKernel( fKDEiter,
391  fHist, histoLowEdge, histoUpperEdge,
393  kern->SetKernelType(fKDEtype);
394 
395  for (Int_t i=1;i<fHist->GetNbinsX();i++) {
396  // loop over the bins of the original histo
397  for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
398  // loop over the bins of the new histo and fill it
401  fPDFHist->GetBinLowEdge(j+1),
402  fHist->GetBinCenter(i),
403  i)
404  );
405  }
406  if (fKDEborder == 3) { // mirror the saples and fill them again
407  // in order to save time do the mirroring only for the first (the lowwer) 1/5 of the histo to the left;
408  // and the last (the higher) 1/5 of the histo to the right.
409  // the middle part of the histo, which is not mirrored, has no influence on the border effects anyway ...
410  if (i < fHist->GetNbinsX()/5 ) { // the first (the lowwer) 1/5 of the histo
411  for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
412  // loop over the bins of the PDF histo and fill it
415  fPDFHist->GetBinLowEdge(j+1),
416  2*histoLowEdge-fHist->GetBinCenter(i), // mirroring to the left
417  i)
418  );
419  }
420  }
421  if (i > 4*fHist->GetNbinsX()/5) { // the last (the higher) 1/5 of the histo
422  for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
423  // loop over the bins of the PDF histo and fill it
426  fPDFHist->GetBinLowEdge(j+1),
427  2*histoUpperEdge-fHist->GetBinCenter(i), i) );
428  }
429  }
430  }
431  }
432 
434 
435  delete kern;
436 
437  // sanity check
438  Double_t integral = GetIntegral();
439  if (integral < 0) Log() << kFATAL << "Integral: " << integral << " <= 0" << Endl;
440 
441  // normalize
442  if (fNormalize)
443  if (integral>0) fPDFHist->Scale( 1.0/integral );
445 }
446 
447 ////////////////////////////////////////////////////////////////////////////////
448 
450 {
451  if(fHist->GetNbinsX()==1) return;
452  if (fMaxNsmooth == fMinNsmooth) {
454  return;
455  }
456 
457  //calculating Mean, RMS of the relative errors and using them to set
458  //the bounderies of the liniar transformation
459  Float_t Err=0, ErrAvg=0, ErrRMS=0 ; Int_t num=0, smooth;
460  for (Int_t bin=0; bin<fHist->GetNbinsX(); bin++) {
461  if (fHist->GetBinContent(bin+1) <= fHist->GetBinError(bin+1)) continue;
462  Err = fHist->GetBinError(bin+1) / fHist->GetBinContent(bin+1);
463  ErrAvg += Err; ErrRMS += Err*Err; num++;
464  }
465  ErrAvg /= num;
466  ErrRMS = TMath::Sqrt(ErrRMS/num-ErrAvg*ErrAvg) ;
467 
468  //liniarly convent the histogram to a vector of smoothnum
469  Float_t MaxErr=ErrAvg+ErrRMS, MinErr=ErrAvg-ErrRMS;
470  fNSmoothHist = new TH1I("","",fHist->GetNbinsX(),0,fHist->GetNbinsX());
471  fNSmoothHist->SetTitle( (TString)fHist->GetTitle() + "_Nsmooth" );
472  fNSmoothHist->SetName ( (TString)fHist->GetName() + "_Nsmooth" );
473  for (Int_t bin=0; bin<fHist->GetNbinsX(); bin++) {
474  if (fHist->GetBinContent(bin+1) <= fHist->GetBinError(bin+1))
475  smooth=fMaxNsmooth;
476  else {
477  Err = fHist->GetBinError(bin+1) / fHist->GetBinContent(bin+1);
478  smooth=(Int_t)((Err-MinErr) /(MaxErr-MinErr) * (fMaxNsmooth-fMinNsmooth)) + fMinNsmooth;
479  }
480  smooth = TMath::Max(fMinNsmooth,TMath::Min(fMaxNsmooth,smooth));
481  fNSmoothHist->SetBinContent(bin+1,smooth);
482  }
483 
484  //find regions of constant smoothnum, starting from the highest amount of
485  //smoothing. So the last iteration all the histogram will be smoothed as a whole
486  for (Int_t n=fMaxNsmooth; n>=0; n--) {
487  //all the histogram has to be smoothed at least fMinNsmooth
488  if (n <= fMinNsmooth) { fHist->Smooth(); continue; }
489  Int_t MinBin=-1,MaxBin =-1;
490  for (Int_t bin=0; bin < fHist->GetNbinsX(); bin++) {
491  if (fNSmoothHist->GetBinContent(bin+1) >= n) {
492  if (MinBin==-1) MinBin = bin;
493  else MaxBin=bin;
494  }
495  else if (MaxBin >= 0) {
496 #if ROOT_VERSION_CODE > ROOT_VERSION(5,19,2)
497  fHist->Smooth(1,"R");
498 #else
499  fHist->Smooth(1,MinBin+1,MaxBin+1);
500 #endif
501  MinBin=MaxBin=-1;
502  }
503  else // can't smooth a single bin
504  MinBin = -1;
505  }
506  }
507 }
508 
509 ////////////////////////////////////////////////////////////////////////////////
510 /// Simple conversion
511 
513 {
514  fGraph=new TGraph(fHist);
515 }
516 
517 ////////////////////////////////////////////////////////////////////////////////
518 /// creates high-binned reference histogram to be used instead of the
519 /// PDF for speed reasons
520 
522 {
523  if (UseHistogram()) {
524  // no spline given, use the original histogram
525  fPDFHist = (TH1*)fHist->Clone();
526  fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_spline0" );
527  fPDFHist->SetName ( (TString)fHist->GetName() + "_hist_from_spline0" );
528  }
529  else {
530  // create new reference histogram
531  fPDFHist = new TH1F( "", "", fgNbin_PdfHist, GetXmin(), GetXmax() );
532  fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_" + fSpline->GetTitle() );
533  fPDFHist->SetName ( (TString)fHist->GetName() + "_hist_from_" + fSpline->GetTitle() );
534 
535  for (Int_t bin=1; bin <= fgNbin_PdfHist; bin++) {
536  Double_t x = fPDFHist->GetBinCenter( bin );
537  Double_t y = fSpline->Eval( x );
538  // sanity correction: in cases where strong slopes exist, accidentally, the
539  // splines can go to zero; in this case we set the corresponding bin content
540  // equal to the bin content of the original histogram
541  if (y <= fgEpsilon) y = fHist->GetBinContent( fHist->FindBin( x ) );
543  }
544  }
546 }
547 
548 ////////////////////////////////////////////////////////////////////////////////
549 /// sanity check: compare PDF with original histogram
550 
552 {
553  if (fHist == NULL) {
554  Log() << kFATAL << "<CheckHist> Called without valid histogram pointer!" << Endl;
555  }
556 
557  Int_t nbins = fHist->GetNbinsX();
558 
559  Int_t emptyBins=0;
560  // count number of empty bins
561  for (Int_t bin=1; bin<=nbins; bin++)
562  if (fHist->GetBinContent(bin) == 0) emptyBins++;
563 
564  if (((Float_t)emptyBins/(Float_t)nbins) > 0.5) {
565  Log() << kWARNING << "More than 50% (" << (((Float_t)emptyBins/(Float_t)nbins)*100)
566  <<"%) of the bins in hist '"
567  << fHist->GetName() << "' are empty!" << Endl;
568  Log() << kWARNING << "X_min=" << GetXmin()
569  << " mean=" << fHist->GetMean() << " X_max= " << GetXmax() << Endl;
570  }
571 }
572 
573 ////////////////////////////////////////////////////////////////////////////////
574 /// comparison of original histogram with reference PDF
575 
576 void TMVA::PDF::ValidatePDF( TH1* originalHist ) const
577 {
578  // if no histogram is given, use the original one (the one the PDF was made from)
579  if (!originalHist) originalHist = fHistOriginal;
580 
581  Int_t nbins = originalHist->GetNbinsX();
582 
583  // treat errors properly
584  if (originalHist->GetSumw2()->GetSize() == 0) originalHist->Sumw2();
585 
586  // ---- first validation: simple(st) possible chi2 test
587  // count number of empty bins
588  Double_t chi2 = 0;
589  Int_t ndof = 0;
590  Int_t nc1 = 0; // deviation counters
591  Int_t nc2 = 0; // deviation counters
592  Int_t nc3 = 0; // deviation counters
593  Int_t nc6 = 0; // deviation counters
594  for (Int_t bin=1; bin<=nbins; bin++) {
595  Double_t x = originalHist->GetBinCenter( bin );
596  Double_t y = originalHist->GetBinContent( bin );
597  Double_t ey = originalHist->GetBinError( bin );
598 
599  Int_t binPdfHist = fPDFHist->FindBin( x );
600  if (binPdfHist<0) continue; // happens only if hist-dim>3
601 
602  Double_t yref = GetVal( x );
603  Double_t rref = ( originalHist->GetSumOfWeights()/fPDFHist->GetSumOfWeights() *
604  originalHist->GetBinWidth( bin )/fPDFHist->GetBinWidth( binPdfHist ) );
605 
606  if (y > 0) {
607  ndof++;
608  Double_t d = TMath::Abs( (y - yref*rref)/ey );
609  // std::cout << "bin: " << bin << " val: " << x << " data(err): " << y << "(" << ey << ") pdf: "
610  // << yref << " dev(chi2): " << d << "(" << chi2 << ") rref: " << rref << std::endl;
611  chi2 += d*d;
612  if (d > 1) { nc1++; if (d > 2) { nc2++; if (d > 3) { nc3++; if (d > 6) nc6++; } } }
613  }
614  }
615 
616  Log() << kDEBUG << "Validation result for PDF \"" << originalHist->GetTitle() << "\"" << ": " << Endl;
617  Log() << kDEBUG << Form( " chi2/ndof(!=0) = %.1f/%i = %.2f (Prob = %.2f)",
618  chi2, ndof, chi2/ndof, TMath::Prob( chi2, ndof ) ) << Endl;
619  if ((1.0 - TMath::Prob( chi2, ndof )) > 0.9999994) {
620  Log() << kDEBUG << "Comparison of the original histogram \"" << originalHist->GetTitle() << "\"" << Endl;
621  Log() << kDEBUG << "with the corresponding PDF gave a chi2/ndof of " << chi2/ndof << "," << Endl;
622  Log() << kDEBUG << "which corresponds to a deviation of more than 5 sigma! Please check!" << Endl;
623  }
624  Log() << kDEBUG << Form( " #bins-found(#expected-bins) deviating > [1,2,3,6] sigmas: " \
625  "[%i(%i),%i(%i),%i(%i),%i(%i)]",
626  nc1, Int_t(TMath::Prob(1.0,1)*ndof), nc2, Int_t(TMath::Prob(4.0,1)*ndof),
627  nc3, Int_t(TMath::Prob(9.0,1)*ndof), nc6, Int_t(TMath::Prob(36.0,1)*ndof) ) << Endl;
628 }
629 
630 ////////////////////////////////////////////////////////////////////////////////
631 /// computes normalisation
632 
634 {
635  Double_t integral = fPDFHist->GetSumOfWeights();
636  integral *= GetPdfHistBinWidth();
637 
638  return integral;
639 }
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// static external auxiliary function (integrand)
643 
645 {
646  return ThisPDF()->GetVal( x[0] );
647 }
648 
649 ////////////////////////////////////////////////////////////////////////////////
650 /// computes PDF integral within given ranges
651 
653 {
654  Double_t integral = 0;
655 
656  if (fgManualIntegration) {
657 
658  // compute integral by summing over bins
659  Int_t imin = fPDFHist->FindBin(xmin);
660  Int_t imax = fPDFHist->FindBin(xmax);
661  if (imin < 1) imin = 1;
662  if (imax > fPDFHist->GetNbinsX()) imax = fPDFHist->GetNbinsX();
663 
664  for (Int_t bini = imin; bini <= imax; bini++) {
665  Float_t dx = fPDFHist->GetBinWidth(bini);
666  // correct for bin fractions in first and last bin
667  if (bini == imin) dx = fPDFHist->GetBinLowEdge(bini+1) - xmin;
668  else if (bini == imax) dx = xmax - fPDFHist->GetBinLowEdge(bini);
669  if (dx < 0 && dx > -1.0e-8) dx = 0; // protect against float->double numerical effects
670  if (dx<0) {
671  Log() << kWARNING
672  << "dx = " << dx << std::endl
673  << "bini = " << bini << std::endl
674  << "xmin = " << xmin << std::endl
675  << "xmax = " << xmax << std::endl
676  << "imin = " << imin << std::endl
677  << "imax = " << imax << std::endl
678  << "low edge of imin" << fPDFHist->GetBinLowEdge(imin) << std::endl
679  << "low edge of imin+1" << fPDFHist->GetBinLowEdge(imin+1) << Endl;
680  Log() << kFATAL << "<GetIntegral> dx = " << dx << " < 0" << Endl;
681  }
682  integral += fPDFHist->GetBinContent(bini)*dx;
683  }
684 
685  }
686  else {
687 
688  // compute via Gaussian quadrature (C++ version of CERNLIB function DGAUSS)
689  if (fIGetVal == 0) fIGetVal = new TF1( "IGetVal", PDF::IGetVal, GetXmin(), GetXmax(), 0 );
690  integral = fIGetVal->Integral( xmin, xmax );
691  }
692 
693  return integral;
694 }
695 
696 ////////////////////////////////////////////////////////////////////////////////
697 /// returns value PDF(x)
698 
700 {
701  // check which is filled
702  Int_t bin = fPDFHist->FindBin(x);
703  bin = TMath::Max(bin,1);
704  bin = TMath::Min(bin,fPDFHist->GetNbinsX());
705 
706  Double_t retval = 0;
707 
708  if (UseHistogram()) {
709  // use directly histogram bins (this is for discrete PDFs)
710  retval = fPDFHist->GetBinContent( bin );
711  }
712  else {
713  // linear interpolation
714  Int_t nextbin = bin;
715  if ((x > fPDFHist->GetBinCenter(bin) && bin != fPDFHist->GetNbinsX()) || bin == 1)
716  nextbin++;
717  else
718  nextbin--;
719 
720  // linear interpolation between adjacent bins
721  Double_t dx = fPDFHist->GetBinCenter( bin ) - fPDFHist->GetBinCenter( nextbin );
722  Double_t dy = fPDFHist->GetBinContent( bin ) - fPDFHist->GetBinContent( nextbin );
723  retval = fPDFHist->GetBinContent( bin ) + (x - fPDFHist->GetBinCenter( bin ))*dy/dx;
724  }
725 
726  return TMath::Max( retval, fgEpsilon );
727 }
728 
729 ////////////////////////////////////////////////////////////////////////////////
730 /// returns value PDF^{-1}(y)
731 
732 Double_t TMVA::PDF::GetValInverse( Double_t y, Bool_t isMonotonouslyIncreasingFunction ) const
733 {
734  Int_t lowerBin=0, higherBin=0;
735  Double_t lowerBinValue=0, higherBinValue=0;
736  FindBinInverse(fPDFHist,lowerBin,higherBin,lowerBinValue,higherBinValue,y,isMonotonouslyIncreasingFunction);
737 
738  Double_t xValueLowerBin =fPDFHist->GetBinCenter (lowerBin);
739  Double_t xValueHigherBin=fPDFHist->GetBinCenter (higherBin);
740 
741  Double_t length =(higherBinValue-lowerBinValue);
742  Double_t fraction=lowerBinValue;
743  if (length>1.0e-10)
744  fraction=(y-lowerBinValue)/length;
745 
746  Double_t lengthX =xValueHigherBin-xValueLowerBin;
747  Double_t x =xValueLowerBin+lengthX*fraction;
748 
749  // comparison for test purposes
750  // std::cout << "lb " << lowerBin << " hb " << higherBin << " lbv " << lowerBinValue << " hbv " << higherBinValue << " frac " << fraction << std::endl;
751  // std::cout << "y " << y << " inv x " << x << " straight y " << GetVal(x) << std::endl;
752 
753  return x;
754 }
755 
756 ////////////////////////////////////////////////////////////////////////////////
757 /// find bin from value on ordinate
758 
759 void TMVA::PDF::FindBinInverse( const TH1* histogram, Int_t& lowerBin, Int_t& higherBin, Double_t& lowerBinValue, Double_t& higherBinValue,
760  Double_t y, Bool_t isMonotonouslyIncreasingFunction ) const
761 {
762  if (isMonotonouslyIncreasingFunction) {
763  higherBin=histogram->GetNbinsX();
764  lowerBin =0;
765 
766  Int_t bin=higherBin/2;
767 
768  while (bin>lowerBin && bin<higherBin) {
769  Double_t binContent=histogram->GetBinContent(bin);
770 
771  if (y<binContent) {
772  higherBin =bin;
773  higherBinValue=binContent;
774  }
775  else if (y>=binContent){
776  lowerBin =bin;
777  lowerBinValue =binContent;
778  }
779  bin=lowerBin+(higherBin-lowerBin)/2;
780  }
781  return;
782  }
783  // search sequentially
784  for (Int_t bin=0, binEnd=histogram->GetNbinsX(); bin<binEnd; ++bin) {
785  Double_t binContent=histogram->GetBinContent(bin);
786  if (binContent<y) {
787  lowerBin =bin;
788  higherBin=bin;
789  lowerBinValue =binContent;
790  higherBinValue=binContent;
791  }
792  else {
793  higherBin=bin;
794  higherBinValue=binContent;
795  break;
796  }
797  }
798 }
799 
800 
801 ////////////////////////////////////////////////////////////////////////////////
802 /// define the options (their key words) that can be set in the option string
803 /// know options:
804 /// PDFInterpol[ivar] <string> Spline0, Spline1, Spline2 <default>, Spline3, Spline5, KDE used to interpolate reference histograms
805 /// if no variable index is given, it is valid for ALL the variables
806 ///
807 /// NSmooth <int> how often the input histos are smoothed
808 /// MinNSmooth <int> min number of smoothing iterations, for bins with most data
809 /// MaxNSmooth <int> max number of smoothing iterations, for bins with least data
810 /// NAvEvtPerBin <int> minimum average number of events per PDF bin
811 /// TransformOutput <bool> transform (often strongly peaked) likelihood output through sigmoid inversion
812 /// fKDEtype <KernelType> type of the Kernel to use (1 is Gaussian)
813 /// fKDEiter <KerneIter> number of iterations (1 --> "static KDE", 2 --> "adaptive KDE")
814 /// fBorderMethod <KernelBorder> the method to take care about "border" effects (1=no treatment , 2=kernel renormalization, 3=sample mirroring)
815 
817 {
818  DeclareOptionRef( fNsmooth, Form("NSmooth%s",fSuffix.Data()),
819  "Number of smoothing iterations for the input histograms" );
820  DeclareOptionRef( fMinNsmooth, Form("MinNSmooth%s",fSuffix.Data()),
821  "Min number of smoothing iterations, for bins with most data" );
822 
823  DeclareOptionRef( fMaxNsmooth, Form("MaxNSmooth%s",fSuffix.Data()),
824  "Max number of smoothing iterations, for bins with least data" );
825 
826  DeclareOptionRef( fHistAvgEvtPerBin, Form("NAvEvtPerBin%s",fSuffix.Data()),
827  "Average number of events per PDF bin" );
828 
830  "Defined number of bins for the histogram from which the PDF is created" );
831 
832  DeclareOptionRef( fCheckHist, Form("CheckHist%s",fSuffix.Data()),
833  "Whether or not to check the source histogram of the PDF" );
834 
835  DeclareOptionRef( fInterpolateString, Form("PDFInterpol%s",fSuffix.Data()),
836  "Interpolation method for reference histograms (e.g. Spline2 or KDE)" );
837  AddPreDefVal(TString("Spline0")); // take histogram
838  AddPreDefVal(TString("Spline1")); // linear interpolation between bins
839  AddPreDefVal(TString("Spline2")); // quadratic interpolation
840  AddPreDefVal(TString("Spline3")); // cubic interpolation
841  AddPreDefVal(TString("Spline5")); // fifth order polynome interpolation
842  AddPreDefVal(TString("KDE")); // use kernel density estimator
843 
844  DeclareOptionRef( fKDEtypeString, Form("KDEtype%s",fSuffix.Data()), "KDE kernel type (1=Gauss)" );
845  AddPreDefVal(TString("Gauss"));
846 
847  DeclareOptionRef( fKDEiterString, Form("KDEiter%s",fSuffix.Data()), "Number of iterations (1=non-adaptive, 2=adaptive)" );
848  AddPreDefVal(TString("Nonadaptive"));
849  AddPreDefVal(TString("Adaptive"));
850 
851  DeclareOptionRef( fFineFactor , Form("KDEFineFactor%s",fSuffix.Data()),
852  "Fine tuning factor for Adaptive KDE: Factor to multyply the width of the kernel");
853 
855  "Border effects treatment (1=no treatment , 2=kernel renormalization, 3=sample mirroring)" );
856  AddPreDefVal(TString("None"));
857  AddPreDefVal(TString("Renorm"));
858  AddPreDefVal(TString("Mirror"));
859 
860  SetConfigName( GetName() );
861  SetConfigDescription( "Configuration options for the PDF class" );
862 }
863 
864 ////////////////////////////////////////////////////////////////////////////////
865 
867 {
868  if (fNsmooth < 0) fNsmooth = 0; // set back to default
869 
870  if (fMaxNsmooth < 0 || fMinNsmooth < 0) { // use "Nsmooth" variable
872  }
873 
874  if (fMaxNsmooth < fMinNsmooth && fMinNsmooth >= 0) { // sanity check
875  Log() << kFATAL << "ERROR: MaxNsmooth = "
876  << fMaxNsmooth << " < MinNsmooth = " << fMinNsmooth << Endl;
877  }
878 
879  if (fMaxNsmooth < 0 || fMinNsmooth < 0) {
880  Log() << kFATAL << "ERROR: MaxNsmooth = "
881  << fMaxNsmooth << " or MinNsmooth = " << fMinNsmooth << " smaller than zero" << Endl;
882  }
883 
884  //processing the options
886  else if (fInterpolateString == "Spline1") fInterpolMethod = TMVA::PDF::kSpline1;
887  else if (fInterpolateString == "Spline2") fInterpolMethod = TMVA::PDF::kSpline2;
888  else if (fInterpolateString == "Spline3") fInterpolMethod = TMVA::PDF::kSpline3;
889  else if (fInterpolateString == "Spline5") fInterpolMethod = TMVA::PDF::kSpline5;
890  else if (fInterpolateString == "KDE" ) fInterpolMethod = TMVA::PDF::kKDE;
891  else if (fInterpolateString != "" ) {
892  Log() << kFATAL << "unknown setting for option 'InterpolateMethod': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
893  }
894 
895  // init KDE options
896  if (fKDEtypeString == "Gauss" ) fKDEtype = KDEKernel::kGauss;
897  else if (fKDEtypeString != "" )
898  Log() << kFATAL << "unknown setting for option 'KDEtype': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
899  if (fKDEiterString == "Nonadaptive") fKDEiter = KDEKernel::kNonadaptiveKDE;
900  else if (fKDEiterString == "Adaptive" ) fKDEiter = KDEKernel::kAdaptiveKDE;
901  else if (fKDEiterString != "" )// nothing more known
902  Log() << kFATAL << "unknown setting for option 'KDEiter': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
903 
907  else if ( fKDEiterString != "" ) { // nothing more known
908  Log() << kFATAL << "unknown setting for option 'KDEBorder': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
909  }
910 }
911 
912 ////////////////////////////////////////////////////////////////////////////////
913 /// XML file writing
914 
915 void TMVA::PDF::AddXMLTo( void* parent )
916 {
917  void* pdfxml = gTools().AddChild(parent, "PDF");
918  gTools().AddAttr(pdfxml, "Name", fPDFName );
919  gTools().AddAttr(pdfxml, "MinNSmooth", fMinNsmooth );
920  gTools().AddAttr(pdfxml, "MaxNSmooth", fMaxNsmooth );
921  gTools().AddAttr(pdfxml, "InterpolMethod", fInterpolMethod );
922  gTools().AddAttr(pdfxml, "KDE_type", fKDEtype );
923  gTools().AddAttr(pdfxml, "KDE_iter", fKDEiter );
924  gTools().AddAttr(pdfxml, "KDE_border", fKDEborder );
925  gTools().AddAttr(pdfxml, "KDE_finefactor", fFineFactor );
926  void* pdfhist = gTools().AddChild(pdfxml,"Histogram" );
927  TH1* histToWrite = GetOriginalHist();
928  Bool_t hasEquidistantBinning = gTools().HistoHasEquidistantBins(*histToWrite);
929  gTools().AddAttr(pdfhist, "Name", histToWrite->GetName() );
930  gTools().AddAttr(pdfhist, "NBins", histToWrite->GetNbinsX() );
931  gTools().AddAttr(pdfhist, "XMin", histToWrite->GetXaxis()->GetXmin() );
932  gTools().AddAttr(pdfhist, "XMax", histToWrite->GetXaxis()->GetXmax() );
933  gTools().AddAttr(pdfhist, "HasEquidistantBins", hasEquidistantBinning );
934 
935  TString bincontent("");
936  for (Int_t i=0; i<histToWrite->GetNbinsX(); i++) {
937  bincontent += gTools().StringFromDouble(histToWrite->GetBinContent(i+1));
938  bincontent += " ";
939  }
940  gTools().AddRawLine(pdfhist, bincontent );
941 
942  if (!hasEquidistantBinning) {
943  void* pdfhistbins = gTools().AddChild(pdfxml,"HistogramBinning" );
944  gTools().AddAttr(pdfhistbins, "NBins", histToWrite->GetNbinsX() );
945  TString binns("");
946  for (Int_t i=1; i<=histToWrite->GetNbinsX()+1; i++) {
947  binns += gTools().StringFromDouble(histToWrite->GetXaxis()->GetBinLowEdge(i));
948  binns += " ";
949  }
950  gTools().AddRawLine(pdfhistbins, binns );
951  }
952 }
953 
954 ////////////////////////////////////////////////////////////////////////////////
955 /// XML file reading
956 
957 void TMVA::PDF::ReadXML( void* pdfnode )
958 {
959  UInt_t enumint;
960 
961  gTools().ReadAttr(pdfnode, "MinNSmooth", fMinNsmooth );
962  gTools().ReadAttr(pdfnode, "MaxNSmooth", fMaxNsmooth );
963  gTools().ReadAttr(pdfnode, "InterpolMethod", enumint ); fInterpolMethod = EInterpolateMethod(enumint);
964  gTools().ReadAttr(pdfnode, "KDE_type", enumint ); fKDEtype = KDEKernel::EKernelType(enumint);
965  gTools().ReadAttr(pdfnode, "KDE_iter", enumint ); fKDEiter = KDEKernel::EKernelIter(enumint);
966  gTools().ReadAttr(pdfnode, "KDE_border", enumint ); fKDEborder = KDEKernel::EKernelBorder(enumint);
967  gTools().ReadAttr(pdfnode, "KDE_finefactor", fFineFactor );
968 
969  TString hname;
970  UInt_t nbins;
971  Double_t xmin, xmax;
972  Bool_t hasEquidistantBinning;
973 
974  void* histch = gTools().GetChild(pdfnode);
975  gTools().ReadAttr( histch, "Name", hname );
976  gTools().ReadAttr( histch, "NBins", nbins );
977  gTools().ReadAttr( histch, "XMin", xmin );
978  gTools().ReadAttr( histch, "XMax", xmax );
979  gTools().ReadAttr( histch, "HasEquidistantBins", hasEquidistantBinning );
980 
981  // recreate the original hist
982  TH1* newhist = 0;
983  if (hasEquidistantBinning) {
984  newhist = new TH1F( hname, hname, nbins, xmin, xmax );
985  newhist->SetDirectory(0);
986  const char* content = gTools().GetContent(histch);
987  std::stringstream s(content);
988  Double_t val;
989  for (UInt_t i=0; i<nbins; i++) {
990  s >> val;
991  newhist->SetBinContent(i+1,val);
992  }
993  }
994  else {
995  const char* content = gTools().GetContent(histch);
996  std::stringstream s(content);
997  Double_t val;
998  void* binch = gTools().GetNextChild(histch);
999  UInt_t nbinning;
1000  gTools().ReadAttr( binch, "NBins", nbinning );
1001  TVectorD binns(nbinning+1);
1002  if (nbinning != nbins) {
1003  Log() << kFATAL << "Number of bins in content and binning array differs"<<Endl;
1004  }
1005  const char* binString = gTools().GetContent(binch);
1006  std::stringstream sb(binString);
1007  for (UInt_t i=0; i<=nbins; i++) sb >> binns[i];
1008  newhist = new TH1F( hname, hname, nbins, binns.GetMatrixArray() );
1009  newhist->SetDirectory(0);
1010  for (UInt_t i=0; i<nbins; i++) {
1011  s >> val;
1012  newhist->SetBinContent(i+1,val);
1013  }
1014  }
1015 
1016  TString hnameSmooth = hname;
1017  hnameSmooth.ReplaceAll( "_original", "_smoothed" );
1018 
1019  if (fHistOriginal != 0) delete fHistOriginal;
1020  fHistOriginal = newhist;
1021  fHist = (TH1F*)fHistOriginal->Clone( hnameSmooth );
1022  fHist->SetTitle( hnameSmooth );
1023  fHist->SetDirectory(0);
1024 
1026  else BuildSplinePDF();
1027 }
1028 
1029 ////////////////////////////////////////////////////////////////////////////////
1030 /// write the pdf
1031 
1032 std::ostream& TMVA::operator<< ( std::ostream& os, const PDF& pdf )
1033 {
1034  Int_t dp = os.precision();
1035  os << "MinNSmooth " << pdf.fMinNsmooth << std::endl;
1036  os << "MaxNSmooth " << pdf.fMaxNsmooth << std::endl;
1037  os << "InterpolMethod " << pdf.fInterpolMethod << std::endl;
1038  os << "KDE_type " << pdf.fKDEtype << std::endl;
1039  os << "KDE_iter " << pdf.fKDEiter << std::endl;
1040  os << "KDE_border " << pdf.fKDEborder << std::endl;
1041  os << "KDE_finefactor " << pdf.fFineFactor << std::endl;
1042 
1043  TH1* histToWrite = pdf.GetOriginalHist();
1044 
1045  const Int_t nBins = histToWrite->GetNbinsX();
1046 
1047  // note: this is a schema change introduced for v3.7.3
1048  os << "Histogram "
1049  << histToWrite->GetName()
1050  << " " << nBins // nbins
1051  << " " << std::setprecision(12) << histToWrite->GetXaxis()->GetXmin() // x_min
1052  << " " << std::setprecision(12) << histToWrite->GetXaxis()->GetXmax() // x_max
1053  << std::endl;
1054 
1055  // write the smoothed hist
1056  os << "Weights " << std::endl;
1057  os << std::setprecision(8);
1058  for (Int_t i=0; i<nBins; i++) {
1059  os << std::setw(15) << std::left << histToWrite->GetBinContent(i+1) << std::right << " ";
1060  if ((i+1)%5==0) os << std::endl;
1061  }
1062 
1063  os << std::setprecision(dp);
1064  return os; // Return the output stream.
1065 }
1066 
1067 ////////////////////////////////////////////////////////////////////////////////
1068 /// read the tree from an std::istream
1069 
1070 std::istream& TMVA::operator>> ( std::istream& istr, PDF& pdf )
1071 {
1072  TString devnullS;
1073  Int_t valI;
1074  Int_t nbins=-1; // default binning will cause an exit
1075  Float_t xmin=-1., xmax=-1.;
1076  TString hname="_original";
1077  Bool_t doneReading = kFALSE;
1078  while (!doneReading) {
1079  istr >> devnullS;
1080  if (devnullS=="NSmooth")
1081  {istr >> pdf.fMinNsmooth; pdf.fMaxNsmooth=pdf.fMinNsmooth;}
1082  else if (devnullS=="MinNSmooth") istr >> pdf.fMinNsmooth;
1083  else if (devnullS=="MaxNSmooth") istr >> pdf.fMaxNsmooth;
1084  // have to do this with strings to be more stable with developing code
1085  else if (devnullS == "InterpolMethod") { istr >> valI; pdf.fInterpolMethod = PDF::EInterpolateMethod(valI);}
1086  else if (devnullS == "KDE_type") { istr >> valI; pdf.fKDEtype = KDEKernel::EKernelType(valI); }
1087  else if (devnullS == "KDE_iter") { istr >> valI; pdf.fKDEiter = KDEKernel::EKernelIter(valI);}
1088  else if (devnullS == "KDE_border") { istr >> valI; pdf.fKDEborder = KDEKernel::EKernelBorder(valI);}
1089  else if (devnullS == "KDE_finefactor") {
1090  istr >> pdf.fFineFactor;
1091  if (pdf.GetReadingVersion() != 0 && pdf.GetReadingVersion() < TMVA_VERSION(3,7,3)) { // here we expect the histogram limits if the version is below 3.7.3. When version == 0, the newest TMVA version is assumed.
1092  // coverity[tainted_data_argument]
1093  istr >> nbins >> xmin >> xmax;
1094  doneReading = kTRUE;
1095  }
1096  }
1097  else if (devnullS == "Histogram") { istr >> hname >> nbins >> xmin >> xmax; }
1098  else if (devnullS == "Weights") { doneReading = kTRUE; }
1099  }
1100 
1101  TString hnameSmooth = hname;
1102  hnameSmooth.ReplaceAll( "_original", "_smoothed" );
1103 
1104  // recreate the original hist
1105  if (nbins==-1) {
1106  std::cout << "PDF, trying to create a histogram without defined binning"<< std::endl;
1107  std::exit(1);
1108  }
1109  TH1* newhist = new TH1F( hname,hname, nbins, xmin, xmax );
1110  newhist->SetDirectory(0);
1111  Float_t val;
1112  for (Int_t i=0; i<nbins; i++) {
1113  istr >> val;
1114  newhist->SetBinContent(i+1,val);
1115  }
1116 
1117  if (pdf.fHistOriginal != 0) delete pdf.fHistOriginal;
1118  pdf.fHistOriginal = newhist;
1119  pdf.fHist = (TH1F*)pdf.fHistOriginal->Clone( hnameSmooth );
1120  pdf.fHist->SetTitle( hnameSmooth );
1121  pdf.fHist->SetDirectory(0);
1122 
1123  if (pdf.fMinNsmooth>=0) pdf.BuildSplinePDF();
1124  else {
1125  pdf.fInterpolMethod = PDF::kKDE;
1126  pdf.BuildKDEPDF();
1127  }
1128 
1129  return istr;
1130 }
1131 
1133 {
1134  // return global "this" pointer of PDF
1135  return GetThisPdfThreadLocal();
1136 }
Bool_t UseHistogram() const
Definition: PDF.h:152
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:52
virtual Int_t FindBin(Double_t x, Double_t y=0, Double_t z=0)
Return Global bin number corresponding to x,y,z.
Definition: TH1.cxx:3442
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
Definition: TH1.cxx:5893
Int_t fMaxNsmooth
Definition: PDF.h:177
TString fBorderMethodString
Definition: PDF.h:193
float xmin
Definition: THbookFile.cxx:93
THist< 1, int, THistStatContent > TH1I
Definition: THist.hxx:304
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:162
void ReadXML(void *pdfnode)
XML file reading.
Definition: PDF.cxx:957
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4640
Int_t fHistAvgEvtPerBin
Definition: PDF.h:188
static const Double_t fgEpsilon
Definition: PDF.h:171
float Float_t
Definition: RtypesCore.h:53
virtual void SetDirectory(TDirectory *dir)
By default when an histogram is created, it is added to the list of histogram objects in the current ...
Definition: TH1.cxx:8008
Double_t GetXmin() const
Definition: PDF.h:112
TString fPDFName
Definition: PDF.h:174
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
void SmoothHistogram()
Definition: PDF.cxx:449
void BuildPDF(const TH1 *theHist)
Definition: PDF.cxx:254
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
THist< 1, float, THistStatContent, THistStatUncertainty > TH1F
Definition: THist.hxx:302
OptionBase * DeclareOptionRef(T &ref, const TString &name, const TString &desc="")
Double_t GetIntegral() const
computes normalisation
Definition: PDF.cxx:633
Float_t fFineFactor
Definition: PDF.h:199
void FindBinInverse(const TH1 *histogram, Int_t &lowerBin, Int_t &higherBin, Double_t &lowerBinValue, Double_t &higherBinValue, Double_t y, Bool_t isMonotonouslyIncreasingFunction=kFALSE) const
find bin from value on ordinate
Definition: PDF.cxx:759
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition: TAxis.cxx:504
static const Int_t fgNbin_PdfHist
Definition: PDF.h:169
Basic string class.
Definition: TString.h:137
tomato 1-D histogram with a float per channel (see TH1 documentation)}
Definition: TH1.h:575
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
TString fKDEtypeString
Definition: PDF.h:191
virtual void Smooth(Int_t ntimes=1, Option_t *option="")
Smooth bin contents of this histogram.
Definition: TH1.cxx:6151
int nbins[3]
PDF(const TString &name, Bool_t norm=kTRUE)
default constructor needed for ROOT I/O
Definition: PDF.cxx:63
virtual Int_t GetNbinsX() const
Definition: TH1.h:301
virtual Double_t Integral(Double_t a, Double_t b, Double_t epsrel=1.e-12)
IntegralOneDim or analytical integral.
Definition: TF1.cxx:2272
virtual Double_t GetEntries() const
Return the current number of entries.
Definition: TH1.cxx:4055
void AddAttr(void *node, const char *, const T &value, Int_t precision=16)
Definition: Tools.h:309
void * AddChild(void *parent, const char *childname, const char *content=0, bool isRootNode=false)
add child node
Definition: Tools.cxx:1134
Short_t Abs(Short_t d)
Definition: TMathBase.h:110
Double_t Prob(Double_t chi2, Int_t ndf)
Computation of the probability for a certain Chi-squared (chi2) and number of degrees of freedom (ndf...
Definition: TMath.cxx:624
TObject * Clone(const char *newname=0) const
Make a complete copy of the underlying object.
Definition: TH1.cxx:2546
TF1 * fIGetVal
needed to create PDF from histogram
Definition: PDF.h:186
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:8230
const char * Data() const
Definition: TString.h:349
TMVA::PDF::EInterpolateMethod fInterpolMethod
Definition: PDF.h:180
Tools & gTools()
Definition: Tools.cxx:79
Double_t x[n]
Definition: legend1.C:17
UInt_t fReadingVersion
Definition: PDF.h:201
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8219
static PDF * ThisPDF(void)
Definition: PDF.cxx:1132
void * GetChild(void *parent, const char *childname=0)
get child node
Definition: Tools.cxx:1158
Bool_t fCheckHist
Definition: PDF.h:203
Bool_t fUseHistogram
Definition: PDF.h:163
virtual TArrayD * GetSumw2()
Definition: TH1.h:317
Definition: PDF.h:71
TString fKDEiterString
Definition: PDF.h:192
virtual void AddBinContent(Int_t bin)
Increment bin content by 1.
Definition: TH1.cxx:1195
static const Bool_t fgManualIntegration
Definition: PDF.h:170
void ValidatePDF(TH1 *original=0) const
comparison of original histogram with reference PDF
Definition: PDF.cxx:576
Double_t GetXmin() const
Definition: TAxis.h:139
Bool_t AddRawLine(void *node, const char *raw)
XML helpers.
Definition: Tools.cxx:1198
void BuildSplinePDF()
build the PDF from the original histograms
Definition: PDF.cxx:315
Int_t GetHistNBins(Int_t evtNum=0)
Definition: PDF.cxx:298
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8208
MsgLogger & Log() const
message logger
Definition: PDF.h:208
virtual Double_t GetMean(Int_t axis=1) const
For axis = 1,2 or 3 returns the mean value of the histogram along X,Y or Z axis.
Definition: TH1.cxx:6717
TH1 * fHistOriginal
Definition: PDF.h:184
TString StringFromDouble(Double_t d)
string tools
Definition: Tools.cxx:1241
TH1 * GetOriginalHist() const
Definition: PDF.h:102
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:8280
Bool_t HistoHasEquidistantBins(const TH1 &h)
Definition: Tools.cxx:1495
unsigned int UInt_t
Definition: RtypesCore.h:42
char * Form(const char *fmt,...)
const Handle_t kNone
Definition: GuiTypes.h:89
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7057
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
const char * GetContent(void *node)
XML helpers.
Definition: Tools.cxx:1182
void ReadAttr(void *node, const char *, T &value)
Definition: Tools.h:296
float xmax
Definition: THbookFile.cxx:93
UInt_t GetReadingVersion() const
Definition: PDF.h:128
Double_t GetValInverse(Double_t y, Bool_t isMonotonouslyIncreasingFunction=kFALSE) const
returns value PDF^{-1}(y)
Definition: PDF.cxx:732
Int_t fNsmooth
Definition: PDF.h:175
std::ostream & operator<<(std::ostream &os, const BinaryTree &tree)
print the tree recursinvely using the << operator
Definition: BinaryTree.cxx:159
std::istream & operator>>(std::istream &istr, BinaryTree &tree)
read the tree from an std::istream
Definition: BinaryTree.cxx:205
Int_t fMinNsmooth
Definition: PDF.h:176
MsgLogger * fLogger
the suffix for options
Definition: PDF.h:207
Int_t GetSize() const
Definition: TArray.h:49
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8028
void DeclareOptions()
define the options (their key words) that can be set in the option string know options: PDFInterpol[i...
Definition: PDF.cxx:816
TH1 * fNSmoothHist
Definition: PDF.h:178
#define TMVA_VERSION(a, b, c)
Definition: Version.h:48
void CheckHist() const
sanity check: compare PDF with original histogram
Definition: PDF.cxx:551
#define ClassImp(name)
Definition: Rtypes.h:279
void BuildKDEPDF()
creates high-binned reference histogram to be used instead of the PDF for speed reasons ...
Definition: PDF.cxx:381
static PDF *& GetThisPdfThreadLocal()
Definition: PDF.h:213
Float_t GetBinKernelIntegral(Float_t lowr, Float_t highr, Float_t mean, Int_t binnum)
calculates the integral of the Kernel
Definition: KDEKernel.cxx:218
Double_t GetVal(Double_t x) const
returns value PDF(x)
Definition: PDF.cxx:699
double Double_t
Definition: RtypesCore.h:55
Bool_t fNormalize
Definition: PDF.h:204
Int_t fHistDefinedNBins
Definition: PDF.h:189
Double_t GetXmax() const
Definition: TAxis.h:140
void * GetNextChild(void *prevchild, const char *childname=0)
XML helpers.
Definition: Tools.cxx:1170
Double_t y[n]
Definition: legend1.C:17
Double_t ey[n]
Definition: legend1.C:17
The TH1 histogram class.
Definition: TH1.h:80
TGraph * fGraph
Definition: PDF.h:185
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
void AddPreDefVal(const T &)
Definition: Configurable.h:174
void AddXMLTo(void *parent)
XML file writing.
Definition: PDF.cxx:915
Double_t GetPdfHistBinWidth() const
Definition: PDF.h:146
TString fSuffix
Definition: PDF.h:206
TH1 * fPDFHist
the used spline type
Definition: PDF.h:182
void SetConfigName(const char *n)
Definition: Configurable.h:69
virtual Double_t Eval(Double_t x) const =0
Abstract ClassifierFactory template that handles arbitrary types.
TH1 * fHist
Definition: PDF.h:183
void Err(int level, const char *msg, int size)
virtual ~PDF()
Definition: PDF.cxx:240
TSpline * fSpline
Definition: PDF.h:181
void ProcessOptions()
Definition: PDF.cxx:866
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
1-Dim function class
Definition: TF1.h:149
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition: TH1.cxx:8087
A Graph is a graphics object made of two arrays X and Y with npoints each.
Definition: TGraph.h:53
static Double_t IGetVal(Double_t *, Double_t *)
static external auxiliary function (integrand)
Definition: PDF.cxx:644
const char * GetName() const
Returns name of object.
Definition: PDF.h:124
#define NULL
Definition: Rtypes.h:82
KDEKernel::EKernelIter fKDEiter
Definition: PDF.h:197
TString()
TString default ctor.
Definition: TString.cxx:88
virtual void SetEntries(Double_t n)
Definition: TH1.h:387
void SetKernelType(EKernelType ktype=kGauss)
fIter == 1 —> nonadaptive KDE fIter == 2 —> adaptive KDE
Definition: KDEKernel.cxx:113
virtual void SetTitle(const char *title)
Change (i.e.
Definition: TH1.cxx:5984
TString fInterpolateString
Definition: PDF.h:194
Double_t Sqrt(Double_t x)
Definition: TMath.h:464
virtual Double_t GetBinError(Int_t bin) const
Return value of error associated to bin number bin.
Definition: TH1.cxx:8130
const Bool_t kTRUE
Definition: Rtypes.h:91
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:155
void FillSplineToHist()
creates high-binned reference histogram to be used instead of the PDF for speed reasons ...
Definition: PDF.cxx:521
double norm(double *x, double *p)
Definition: unuranDistr.cxx:40
EInterpolateMethod
Definition: PDF.h:78
KDEKernel::EKernelBorder fKDEborder
Definition: PDF.h:198
KDEKernel::EKernelType fKDEtype
Definition: PDF.h:196
const Int_t n
Definition: legend1.C:16
Double_t GetXmax() const
Definition: PDF.h:113
void FillHistToGraph()
Simple conversion.
Definition: PDF.cxx:512
char name[80]
Definition: TGX11.cxx:109
TAxis * GetXaxis()
Definition: TH1.h:324
void SetConfigDescription(const char *d)
Definition: Configurable.h:70