ROOT logo
// @(#)root/tmva $Id: PDF.cxx 29195 2009-06-24 10:39:49Z brun $
// Author: Asen Christov, Andreas Hoecker, Joerg Stelzer, Helge Voss, Kai Voss

/**********************************************************************************
 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
 * Package: TMVA                                                                  *
 * Class  : PDF                                                                   *
 * Web    : http://tmva.sourceforge.net                                           *
 *                                                                                *
 * Description:                                                                   *
 *      Implementation (see header for description)                               *
 *                                                                                *
 * Authors (alphabetical):                                                        *
 *      Asen Christov   <christov@physik.uni-freiburg.de> - Freiburg U., Germany  *
 *      Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland              *
 *      Helge Voss      <Helge.Voss@cern.ch>     - MPI-K Heidelberg, Germany      *
 *      Kai Voss        <Kai.Voss@cern.ch>       - U. of Victoria, Canada         *
 *                                                                                *
 * Copyright (c) 2005:                                                            *
 *      CERN, Switzerland                                                         * 
 *      U. of Victoria, Canada                                                    * 
 *      MPI-K Heidelberg, Germany                                                 * 
 *      Freiburg U., Germany                                                      * 
 *                                                                                *
 * Redistribution and use in source and binary forms, with or without             *
 * modification, are permitted according to the terms listed in LICENSE           *
 * (http://tmva.sourceforge.net/LICENSE)                                          *
 **********************************************************************************/

#include <iomanip>
#include <cstdlib>

#include "TMath.h"
#include "TXMLEngine.h"
#include "TF1.h"
#include "TH1F.h"
#include "TVectorD.h"

#include "TMVA/Tools.h"
#include "TMVA/PDF.h"
#include "TMVA/TSpline1.h"
#include "TMVA/TSpline2.h"
#include "TMVA/Version.h"

// static configuration settings
const Int_t    TMVA::PDF::fgNbin_PdfHist      = 10000;
const Bool_t   TMVA::PDF::fgManualIntegration = kTRUE;
const Double_t TMVA::PDF::fgEpsilon           = 1.0e-12;
TMVA::PDF*     TMVA::PDF::fgThisPDF           = 0;

ClassImp(TMVA::PDF)

//_______________________________________________________________________
TMVA::PDF::PDF( const TString& name, Bool_t norm )
   : Configurable   (""),
     fUseHistogram  ( kFALSE ),
     fPDFName       ( name ),
     fNsmooth       ( 0 ),
     fMinNsmooth    (-1 ),
     fMaxNsmooth    (-1 ),
     fNSmoothHist   ( 0 ),
     fInterpolMethod( PDF::kSpline2 ),
     fSpline        ( 0 ),
     fPDFHist       ( 0 ),
     fHist          ( 0 ),
     fHistOriginal  ( 0 ),
     fGraph         ( 0 ),
     fIGetVal       ( 0 ),
     fHistAvgEvtPerBin  ( 0 ),
     fHistDefinedNBins  ( 0 ),
     fKDEtypeString     ( 0 ),
     fKDEiterString     ( 0 ),
     fBorderMethodString( 0 ),
     fInterpolateString ( 0 ),
     fKDEtype       ( KDEKernel::kNone ),
     fKDEiter       ( KDEKernel::kNonadaptiveKDE ),
     fKDEborder     ( KDEKernel::kNoTreatment ),
     fFineFactor    ( 0. ),
     fReadingVersion( 0 ),
     fCheckHist     ( kFALSE ),
     fNormalize     ( norm ),
     fSuffix        ( "" ),
     fLogger        ( new MsgLogger(this) )
{
   // default constructor needed for ROOT I/O
   fgThisPDF = this;
}

//_______________________________________________________________________
TMVA::PDF::PDF( const TString& name,
                const TH1 *hist,
                PDF::EInterpolateMethod method,
                Int_t minnsmooth,
                Int_t maxnsmooth,
                Bool_t checkHist,
                Bool_t norm) :
   Configurable   (""),
   fUseHistogram  ( kFALSE ),
   fPDFName       ( name ),
   fMinNsmooth    ( minnsmooth ),
   fMaxNsmooth    ( maxnsmooth ),
   fNSmoothHist   ( 0 ),
   fInterpolMethod( method ),
   fSpline        ( 0 ),
   fPDFHist       ( 0 ),
   fHist          ( 0 ),
   fHistOriginal  ( 0 ),
   fGraph         ( 0 ),
   fIGetVal       ( 0 ),
   fHistAvgEvtPerBin  ( 0 ),
   fHistDefinedNBins  ( 0 ),
   fKDEtypeString     ( 0 ),
   fKDEiterString     ( 0 ),
   fBorderMethodString( 0 ),
   fInterpolateString ( 0 ),
   fKDEtype       ( KDEKernel::kNone ),
   fKDEiter       ( KDEKernel::kNonadaptiveKDE ),
   fKDEborder     ( KDEKernel::kNoTreatment ),
   fFineFactor    ( 0. ),
   fReadingVersion( 0 ),
   fCheckHist     ( checkHist ),
   fNormalize     ( norm ),
   fSuffix        ( "" ),
   fLogger        ( new MsgLogger(this) )
{  
   // constructor of spline based PDF: 
   BuildPDF( hist );
}

//_______________________________________________________________________
TMVA::PDF::PDF( const TString& name,
                const TH1* hist,
                KDEKernel::EKernelType ktype,
                KDEKernel::EKernelIter kiter, 
                KDEKernel::EKernelBorder kborder,
                Float_t FineFactor,
                Bool_t norm) :
   Configurable   (""),
   fUseHistogram  ( kFALSE ),
   fPDFName       ( name ),
   fNsmooth       ( 0 ),
   fMinNsmooth    (-1 ),
   fMaxNsmooth    (-1 ),
   fNSmoothHist   ( 0 ),
   fInterpolMethod( PDF::kSpline0 ),
   fSpline        ( 0 ),
   fPDFHist       ( 0 ),
   fHist          ( 0 ),
   fHistOriginal  ( 0 ),
   fGraph         ( 0 ),
   fIGetVal       ( 0 ),
   fHistAvgEvtPerBin  ( 0 ),
   fHistDefinedNBins  ( 0 ),
   fKDEtypeString     ( 0 ),
   fKDEiterString     ( 0 ),
   fBorderMethodString( 0 ),
   fInterpolateString ( 0 ),
   fKDEtype       ( ktype ),
   fKDEiter       ( kiter ),
   fKDEborder     ( kborder ),
   fFineFactor    ( FineFactor),
   fReadingVersion( 0 ),
   fCheckHist     ( kFALSE ),
   fNormalize     ( norm ),
   fSuffix        ( "" ),
   fLogger        ( new MsgLogger(this) )
{
   // constructor of kernel based PDF:
   BuildPDF( hist );
}

//_______________________________________________________________________
TMVA::PDF::PDF( const TString& name,
                const TString& options,
                const TString& suffix,
                PDF* defaultPDF,
                Bool_t norm) :
   Configurable   (options),
   fUseHistogram  ( kFALSE ),
   fPDFName       ( name ),
   fNsmooth       ( 0 ),
   fMinNsmooth    ( -1 ),
   fMaxNsmooth    ( -1 ),
   fNSmoothHist   ( 0 ),
   fInterpolMethod( PDF::kSpline0 ),
   fSpline        ( 0 ),
   fPDFHist       ( 0 ),
   fHist          ( 0 ),
   fHistOriginal  ( 0 ),
   fGraph         ( 0 ),
   fIGetVal       ( 0 ),
   fHistAvgEvtPerBin  ( 50 ),
   fHistDefinedNBins  ( 0 ),
   fKDEtypeString     ( "Gauss" ),
   fKDEiterString     ( "Nonadaptive" ),
   fBorderMethodString( "None" ),
   fInterpolateString ( "Spline2" ),
   fKDEtype       ( KDEKernel::kNone ),
   fKDEiter       ( KDEKernel::kNonadaptiveKDE ),
   fKDEborder     ( KDEKernel::kNoTreatment ),
   fFineFactor    ( 1. ),
   fReadingVersion( 0 ),
   fCheckHist     ( kFALSE ),
   fNormalize     ( norm ),
   fSuffix        ( suffix ),
   fLogger        ( new MsgLogger(this) )
{
   if (defaultPDF != 0) {
      fNsmooth            = defaultPDF->fNsmooth;
      fMinNsmooth         = defaultPDF->fMinNsmooth;
      fMaxNsmooth         = defaultPDF->fMaxNsmooth;
      fHistAvgEvtPerBin   = defaultPDF->fHistAvgEvtPerBin;
      fHistAvgEvtPerBin   = defaultPDF->fHistAvgEvtPerBin;
      fInterpolateString  = defaultPDF->fInterpolateString;
      fKDEtypeString      = defaultPDF->fKDEtypeString;
      fKDEiterString      = defaultPDF->fKDEiterString;
      fFineFactor         = defaultPDF->fFineFactor;
      fBorderMethodString = defaultPDF->fBorderMethodString;
      fCheckHist          = defaultPDF->fCheckHist;
      fHistDefinedNBins   = defaultPDF->fHistDefinedNBins;
   }
}

//___________________fNSmoothHist____________________________________________________
TMVA::PDF::~PDF()
{
   // destructor
   if (fSpline       != NULL) delete fSpline; 
   if (fHist         != NULL) delete fHist;
   if (fPDFHist      != NULL) delete fPDFHist;
   if (fHistOriginal != NULL) delete fHistOriginal;
   if (fIGetVal      != NULL) delete fIGetVal;   
   if (fGraph        != NULL) delete fGraph; 
   delete fLogger;
}

//_______________________________________________________________________
void TMVA::PDF::BuildPDF( const TH1* hist ) 
{
   fgThisPDF = this;

   // sanity check
   if (hist == NULL) Log() << kFATAL << "Called without valid histogram pointer!" << Endl;

   // histogram should be non empty
   if (hist->GetEntries() <= 0) 
      Log() << kFATAL << "Number of entries <= 0 in histogram: " << hist->GetTitle() << Endl;

   if (fInterpolMethod == PDF::kKDE) {
      Log() << "Create " 
            << ((fKDEiter == KDEKernel::kNonadaptiveKDE) ? "nonadaptive " : 
                (fKDEiter == KDEKernel::kAdaptiveKDE)    ? "adaptive "    : "??? ") 
            << ((fKDEtype == KDEKernel::kGauss)          ? "Gauss "       : "??? ")
            << "type KDE kernel for histogram: \"" << hist->GetName() << "\""
            << Endl;
   }
   else {
      // another sanity check (nsmooth<0 indicated build with KDE)
      if (fMinNsmooth<0) 
         Log() << kFATAL << "PDF construction called with minnsmooth<0" << Endl;
      else if (fMaxNsmooth<=0)
         fMaxNsmooth = fMinNsmooth;
      else if (fMaxNsmooth<fMinNsmooth)
         Log() << kFATAL << "PDF construction called with maxnsmooth<minnsmooth" << Endl;
   }

   fHistOriginal = (TH1F*)hist->Clone( TString(hist->GetName()) + "_original" );
   fHist         = (TH1F*)hist->Clone( TString(hist->GetName()) + "_smoothed" );
   fHistOriginal->SetTitle( fHistOriginal->GetName() ); // reset to new title as well
   fHist        ->SetTitle( fHist->GetName() );

   // do not store in current target file
   fHistOriginal->SetDirectory(0);
   fHist        ->SetDirectory(0);
   fUseHistogram = kFALSE;

   if (fInterpolMethod == PDF::kKDE) BuildKDEPDF();
   else                              BuildSplinePDF();
}

//_______________________________________________________________________
Int_t TMVA::PDF::GetHistNBins ( Int_t evtNum )
{
   Int_t ResolutionFactor = (fInterpolMethod == PDF::kKDE) ? 5 : 1;
   if (evtNum == 0 && fHistDefinedNBins == 0)
      Log() << kFATAL << "No number of bins set for PDF" << Endl;
   else if (fHistDefinedNBins > 0)
      return fHistDefinedNBins * ResolutionFactor;
   else if ( evtNum > 0 && fHistAvgEvtPerBin > 0 )
      return evtNum / fHistAvgEvtPerBin * ResolutionFactor;
   else 
      Log() << kFATAL << "No number of bins or average event per bin set for PDF" << fHistAvgEvtPerBin << Endl;
   return 0;
}
//_______________________________________________________________________
void TMVA::PDF::BuildSplinePDF() 
{
   // build the PDF from the original histograms

   // (not useful for discrete distributions, or if no splines are requested)
   if (fInterpolMethod != PDF::kSpline0 && fCheckHist) CheckHist();
   // use ROOT TH1 smooth method
   fNSmoothHist = 0;
   if (fMaxNsmooth > 0 && fMinNsmooth >=0 ) SmoothHistogram();

   // fill histogramm to graph
   FillHistToGraph();

   //   fGraph->Print();
   switch (fInterpolMethod) {

   case kSpline0:
      // use original histogram as reference
      // this is useful, eg, for discrete variables
      fUseHistogram = kTRUE;
      break;

   case kSpline1:
      fSpline = new TMVA::TSpline1( "spline1", new TGraph(*fGraph) );
      break;

   case kSpline2:
      fSpline = new TMVA::TSpline2( "spline2", new TGraph(*fGraph) );
      break;

   case kSpline3:
      fSpline = new TSpline3( "spline3", new TGraph(*fGraph) );
      break;
    
   case kSpline5:
      fSpline = new TSpline5( "spline5", new TGraph(*fGraph) );
      break;

   default:
      Log() << kWARNING << "No valid interpolation method given! Use Spline2" << Endl;
      fSpline = new TMVA::TSpline2( "spline2", new TGraph(*fGraph) );
      Log() << kFATAL << " Well.. .thinking about it, I better quit so you notice you are forced to fix the mistake " << Endl;
      std::exit(1);
   }
   // fill into histogram 
   FillSplineToHist();

   if (!UseHistogram()) {
      fSpline->SetTitle( (TString)fHist->GetTitle() + fSpline->GetTitle() );
      fSpline->SetName ( (TString)fHist->GetName()  + fSpline->GetName()  );
   }

   // sanity check
   Double_t integral = GetIntegral();
   if (integral < 0) Log() << kFATAL << "Integral: " << integral << " <= 0" << Endl;

   // normalize
   if (fNormalize)
      if (integral>0) fPDFHist->Scale( 1.0/integral );

   fPDFHist->SetDirectory(0);
}

//_______________________________________________________________________
void TMVA::PDF::BuildKDEPDF()
{
   // creates high-binned reference histogram to be used instead of the
   // PDF for speed reasons
   fPDFHist = new TH1F( "", "", fgNbin_PdfHist, GetXmin(), GetXmax() );
   fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_KDE" );
   fPDFHist->SetName ( (TString)fHist->GetName()  + "_hist_from_KDE" );
   
   // create the kernel object  
   Float_t histoLowEdge   = fHist->GetBinLowEdge(1);
   Float_t histoUpperEdge = fPDFHist->GetBinLowEdge(fPDFHist->GetNbinsX()) + fPDFHist->GetBinWidth(fPDFHist->GetNbinsX());
   KDEKernel *kern = new TMVA::KDEKernel( fKDEiter, 
                                          fHist, histoLowEdge, histoUpperEdge,
                                          fKDEborder, fFineFactor );
   kern->SetKernelType(fKDEtype);
   
   for (Int_t i=1;i<fHist->GetNbinsX();i++) {
      // loop over the bins of the original histo
      for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
         // loop over the bins of the new histo and fill it
         fPDFHist->AddBinContent(j,fHist->GetBinContent(i)*
                                 kern->GetBinKernelIntegral(fPDFHist->GetBinLowEdge(j),
                                                            fPDFHist->GetBinLowEdge(j+1),
                                                            fHist->GetBinCenter(i),
                                                            i)
                                 );
      }
      if (fKDEborder == 3) { // mirror the saples and fill them again
         // in order to save time do the mirroring only for the first (the lowwer) 1/5 of the histo to the left; 
         // and the last (the higher) 1/5 of the histo to the right.
         // the middle part of the histo, which is not mirrored, has no influence on the border effects anyway ...
         if (i < fHist->GetNbinsX()/5  ) {  // the first (the lowwer) 1/5 of the histo
            for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
               // loop over the bins of the PDF histo and fill it
               fPDFHist->AddBinContent(j,fHist->GetBinContent(i)*
                                       kern->GetBinKernelIntegral(fPDFHist->GetBinLowEdge(j),
                                                                  fPDFHist->GetBinLowEdge(j+1),
                                                                  2*histoLowEdge-fHist->GetBinCenter(i), //  mirroring to the left
                                                                  i)
                                       );
            }
         }
         if (i > 4*fHist->GetNbinsX()/5) { // the last (the higher) 1/5 of the histo
            for (Int_t j=1;j<fPDFHist->GetNbinsX();j++) {
               // loop over the bins of the PDF histo and fill it
               fPDFHist->AddBinContent( j,fHist->GetBinContent(i)*
                                        kern->GetBinKernelIntegral(fPDFHist->GetBinLowEdge(j),
                                                                   fPDFHist->GetBinLowEdge(j+1),
                                                                   2*histoUpperEdge-fHist->GetBinCenter(i), i) );
            }
         }
      }
   }
          
   fPDFHist->SetEntries(fHist->GetEntries());

   delete kern;
 
   // sanity check
   Double_t integral = GetIntegral();
   if (integral < 0) Log() << kFATAL << "Integral: " << integral << " <= 0" << Endl; 

   // normalize 
   if (fNormalize)
      if (integral>0) fPDFHist->Scale( 1.0/integral );
   fPDFHist->SetDirectory(0);
}

//_______________________________________________________________________
void TMVA::PDF::SmoothHistogram()
{
   if (fMaxNsmooth == fMinNsmooth) {
      fHist->Smooth( fMinNsmooth );
      return;
   }

   //calculating Mean, RMS of the relative errors and using them to set
   //the bounderies of the liniar transformation
   Float_t Err=0, ErrAvg=0, ErrRMS=0 ; Int_t num=0, smooth;
   for (Int_t bin=0; bin<fHist->GetNbinsX(); bin++) {
      if (fHist->GetBinContent(bin+1) <= fHist->GetBinError(bin+1)) continue;
      Err = fHist->GetBinError(bin+1) / fHist->GetBinContent(bin+1);
      ErrAvg += Err; ErrRMS += Err*Err; num++;
   }
   ErrAvg /= num;
   ErrRMS = TMath::Sqrt(ErrRMS/num-ErrAvg*ErrAvg) ;
   
   //liniarly convent the histogram to a vector of smoothnum
   Float_t MaxErr=ErrAvg+ErrRMS, MinErr=ErrAvg-ErrRMS;
   fNSmoothHist = new TH1I("","",fHist->GetNbinsX(),0,fHist->GetNbinsX());
   fNSmoothHist->SetTitle( (TString)fHist->GetTitle() + "_Nsmooth" );
   fNSmoothHist->SetName ( (TString)fHist->GetName()  + "_Nsmooth" );
   for (Int_t bin=0; bin<fHist->GetNbinsX(); bin++) {
      if (fHist->GetBinContent(bin+1) <= fHist->GetBinError(bin+1))
         smooth=fMaxNsmooth;
      else {
         Err = fHist->GetBinError(bin+1) / fHist->GetBinContent(bin+1);
         smooth=(Int_t)((Err-MinErr) /(MaxErr-MinErr) * (fMaxNsmooth-fMinNsmooth)) + fMinNsmooth;
      }
      smooth = TMath::Max(fMinNsmooth,TMath::Min(fMaxNsmooth,smooth));
      fNSmoothHist->SetBinContent(bin+1,smooth);
   }

   //find regions of constant smoothnum, starting from the highest amount of 
   //smoothing. So the last iteration all the histogram will be smoothed as a whole
   for (Int_t n=fMaxNsmooth; n>=0; n--) {
      //all the histogram has to be smoothed at least fMinNsmooth
      if (n <= fMinNsmooth) { fHist->Smooth(); continue; }
      Int_t MinBin=-1,MaxBin =-1;
      for (Int_t bin=0; bin < fHist->GetNbinsX(); bin++) {
         if (fNSmoothHist->GetBinContent(bin+1) >= n) {
            if (MinBin==-1) MinBin = bin;
            else MaxBin=bin;
         }
         else if (MaxBin >= 0) {
#if ROOT_VERSION_CODE > ROOT_VERSION(5,19,2)
            fHist->Smooth(1,"R");
#else
            fHist->Smooth(1,MinBin+1,MaxBin+1);
#endif
            MinBin=MaxBin=-1;
         }
         else     // can't smooth a single bin
            MinBin = -1;
      }
   }
}

//_______________________________________________________________________
void TMVA::PDF::FillHistToGraph()
{
   fGraph=new TGraph(fHist);
   return;
   Int_t PointNum = fHist->GetXaxis()->GetNbins();
   Double_t Factor=PointNum/(fHist->GetBinLowEdge(PointNum)+fHist->GetBinWidth(PointNum)-fHist->GetBinLowEdge(1));
   fGraph = new TGraph(PointNum+2);
   fGraph->SetPoint(0,fHist->GetBinLowEdge(1),0);
   for (Int_t i=0;i<PointNum;i++)
      fGraph->SetPoint(i+1,fHist->GetBinCenter(i+1), fHist->GetBinContent(i+1) / (fHist->GetBinWidth(i+1) * Factor));
   fGraph->SetPoint(PointNum+1,fHist->GetBinLowEdge(PointNum)+fHist->GetBinWidth(PointNum),0);
}

//_______________________________________________________________________
void TMVA::PDF::FillSplineToHist()
{
   // creates high-binned reference histogram to be used instead of the 
   // PDF for speed reasons 

   if (UseHistogram()) {
      // no spline given, use the original histogram
      fPDFHist = (TH1*)fHist->Clone();
      fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_spline0" );
      fPDFHist->SetName ( (TString)fHist->GetName()  + "_hist_from_spline0" );
   }
   else {
      // create new reference histogram
      fPDFHist = new TH1F( "", "", fgNbin_PdfHist, GetXmin(), GetXmax() );
      fPDFHist->SetTitle( (TString)fHist->GetTitle() + "_hist from_" + fSpline->GetTitle() );
      fPDFHist->SetName ( (TString)fHist->GetName()  + "_hist_from_" + fSpline->GetTitle() );

      for (Int_t bin=1; bin <= fgNbin_PdfHist; bin++) {
         Double_t x = fPDFHist->GetBinCenter( bin );
         Double_t y = fSpline->Eval( x );
         // sanity correction: in cases where strong slopes exist, accidentally, the 
         // splines can go to zero; in this case we set the corresponding bin content
         // equal to the bin content of the original histogram
         if (y <= fgEpsilon) y = fHist->GetBinContent( fHist->FindBin( x ) );
         fPDFHist->SetBinContent( bin, TMath::Max(y, fgEpsilon) );
      }
   }
   fPDFHist->SetDirectory(0);
}

//_______________________________________________________________________
void TMVA::PDF::CheckHist() const
{
   // sanity check: compare PDF with original histogram
   if (fHist == NULL) {
      Log() << kFATAL << "<CheckHist> Called without valid histogram pointer!" << Endl;
   }

   Int_t nbins = fHist->GetNbinsX();

   Int_t emptyBins=0;
   // count number of empty bins
   for (Int_t bin=1; bin<=nbins; bin++) 
      if (fHist->GetBinContent(bin) == 0) emptyBins++;

   if (((Float_t)emptyBins/(Float_t)nbins) > 0.5) {
      Log() << kWARNING << "More than 50% (" << (((Float_t)emptyBins/(Float_t)nbins)*100)
            <<"%) of the bins in hist '" 
            << fHist->GetName() << "' are empty!" << Endl;
      Log() << kWARNING << "X_min=" << GetXmin() 
            << " mean=" << fHist->GetMean() << " X_max= " << GetXmax() << Endl;  
   }
}

//_______________________________________________________________________
void TMVA::PDF::ValidatePDF( TH1* originalHist ) const
{
   // comparison of original histogram with reference PDF

   // if no histogram is given, use the original one (the one the PDF was made from)
   if (!originalHist) originalHist = fHistOriginal;

   Int_t    nbins = originalHist->GetNbinsX();

   // treat errors properly
   if (originalHist->GetSumw2()->GetSize() == 0) originalHist->Sumw2();

   // ---- first validation: simple(st) possible chi2 test
   // count number of empty bins
   Double_t chi2 = 0;
   Int_t    ndof = 0;
   Int_t    nc1  = 0; // deviation counters
   Int_t    nc2  = 0; // deviation counters
   Int_t    nc3  = 0; // deviation counters
   Int_t    nc6  = 0; // deviation counters
   for (Int_t bin=1; bin<=nbins; bin++) {
      Double_t x  = originalHist->GetBinCenter( bin );
      Double_t y  = originalHist->GetBinContent( bin );
      Double_t ey = originalHist->GetBinError( bin );

      Int_t binPdfHist = fPDFHist->FindBin( x );

      Double_t yref = GetVal( x );      
      Double_t rref = ( originalHist->GetSumOfWeights()/fPDFHist->GetSumOfWeights() * 
                        originalHist->GetBinWidth( bin )/fPDFHist->GetBinWidth( binPdfHist ) );

      if (y > 0) {
         ndof++;
         Double_t d = TMath::Abs( (y - yref*rref)/ey );
         chi2 += d*d;
         if (d > 1) { nc1++; if (d > 2) { nc2++; if (d > 3) { nc3++; if (d > 6) nc6++; } } }
      }
   }
   
   Log() << "Validation result for PDF \"" << originalHist->GetTitle() << "\"" << ": " << Endl;
   Log() << Form( "    chi2/ndof(!=0) = %.1f/%i = %.2f (Prob = %.2f)", 
                  chi2, ndof, chi2/ndof, TMath::Prob( chi2, ndof ) ) << Endl;
   Log() << Form( "    #bins-found(#expected-bins) deviating > [1,2,3,6] sigmas: " \
                  "[%i(%i),%i(%i),%i(%i),%i(%i)]", 
                  nc1, Int_t(TMath::Prob(1.0,1)*ndof), nc2, Int_t(TMath::Prob(4.0,1)*ndof),
                  nc3, Int_t(TMath::Prob(9.0,1)*ndof), nc6, Int_t(TMath::Prob(36.0,1)*ndof) ) << Endl;
}

//_______________________________________________________________________
Double_t TMVA::PDF::GetIntegral() const
{
   // computes normalisation

   Double_t integral = fPDFHist->GetSumOfWeights();
   integral *= GetPdfHistBinWidth();

   return integral;
}

//_______________________________________________________________________
Double_t TMVA::PDF::IGetVal( Double_t* x, Double_t* ) 
{
   // static external auxiliary function (integrand)
   return ThisPDF()->GetVal( x[0] );
}

//_______________________________________________________________________
Double_t TMVA::PDF::GetIntegral( Double_t xmin, Double_t xmax ) 
{  
   // computes PDF integral within given ranges
   Double_t  integral = 0;

   if (fgManualIntegration) {

      // compute integral by summing over bins
      Int_t imin = fPDFHist->FindBin(xmin);
      Int_t imax = fPDFHist->FindBin(xmax);
      if (imin < 1)                     imin = 1;
      if (imax > fPDFHist->GetNbinsX()) imax = fPDFHist->GetNbinsX();

      for (Int_t bini = imin; bini <= imax; bini++) {
         Float_t dx = fPDFHist->GetBinWidth(bini);
         // correct for bin fractions in first and last bin
         if      (bini == imin) dx = fPDFHist->GetBinLowEdge(bini+1) - xmin;
         else if (bini == imax) dx = xmax - fPDFHist->GetBinLowEdge(bini);         
         if (dx < 0 && dx > -1.0e-8) dx = 0; // protect against float->double numerical effects
         if (dx<0) {
            Log() << kWARNING
                  << "dx   = " << dx   << std::endl
                  << "bini = " << bini << std::endl
                  << "xmin = " << xmin << std::endl
                  << "xmax = " << xmax << std::endl
                  << "imin = " << imin << std::endl
                  << "imax = " << imax << std::endl
                  << "low edge of imin" << fPDFHist->GetBinLowEdge(imin) << std::endl
                  << "low edge of imin+1" << fPDFHist->GetBinLowEdge(imin+1) << Endl;
            Log() << kFATAL << "<GetIntegral> dx = " << dx << " < 0" << Endl;
         }
         integral += fPDFHist->GetBinContent(bini)*dx;
      }

   }
   else {

      // compute via Gaussian quadrature (C++ version of CERNLIB function DGAUSS)
      if (fIGetVal == 0) fIGetVal = new TF1( "IGetVal", PDF::IGetVal, GetXmin(), GetXmax(), 0 );
      integral = fIGetVal->Integral( xmin, xmax );
   }

   return integral;
}

//_____________________________________________________________________
Double_t TMVA::PDF::GetVal( Double_t x ) const
{  
   // returns value PDF(x)

   // check which is filled
   Int_t bin = fPDFHist->FindBin(x);
   bin = TMath::Max(bin,1);
   bin = TMath::Min(bin,fPDFHist->GetNbinsX());
   
   Double_t retval = 0;

   if (UseHistogram()) {
      // use directly histogram bins (this is for discrete PDFs)
      retval = fPDFHist->GetBinContent( bin );
   } 
   else {
      // linear interpolation
      Int_t nextbin = bin;
      if ((x > fPDFHist->GetBinCenter(bin) && bin != fPDFHist->GetNbinsX()) || bin == 1)
         nextbin++;
      else
         nextbin--;  
      
      // linear interpolation between adjacent bins
      Double_t dx = fPDFHist->GetBinCenter( bin )  - fPDFHist->GetBinCenter( nextbin );
      Double_t dy = fPDFHist->GetBinContent( bin ) - fPDFHist->GetBinContent( nextbin );
      retval = fPDFHist->GetBinContent( bin ) + (x - fPDFHist->GetBinCenter( bin ))*dy/dx;
   }

   return TMath::Max( retval, fgEpsilon );
}

//_______________________________________________________________________
void TMVA::PDF::DeclareOptions()
{
   // define the options (their key words) that can be set in the option string 
   // know options:
   // PDFInterpol[ivar] <string>   Spline0, Spline1, Spline2 <default>, Spline3, Spline5, KDE  used to interpolate reference histograms
   //             if no variable index is given, it is valid for ALL the variables
   //
   // NSmooth           <int>    how often the input histos are smoothed
   // MinNSmooth        <int>    min number of smoothing iterations, for bins with most data
   // MaxNSmooth        <int>    max number of smoothing iterations, for bins with least data
   // NAvEvtPerBin      <int>    minimum average number of events per PDF bin 
   // TransformOutput   <bool>   transform (often strongly peaked) likelihood output through sigmoid inversion
   // fKDEtype          <KernelType>   type of the Kernel to use (1 is Gaussian)
   // fKDEiter          <KerneIter>    number of iterations (1 --> "static KDE", 2 --> "adaptive KDE")
   // fBorderMethod     <KernelBorder> the method to take care about "border" effects (1=no treatment , 2=kernel renormalization, 3=sample mirroring)

   DeclareOptionRef( fNsmooth, Form("NSmooth%s",fSuffix.Data()),
                     "Number of smoothing iterations for the input histograms" );
   DeclareOptionRef( fMinNsmooth, Form("MinNSmooth%s",fSuffix.Data()),
                     "Min number of smoothing iterations, for bins with most data" );

   DeclareOptionRef( fMaxNsmooth, Form("MaxNSmooth%s",fSuffix.Data()),
                     "Max number of smoothing iterations, for bins with least data" );

   DeclareOptionRef( fHistAvgEvtPerBin, Form("NAvEvtPerBin%s",fSuffix.Data()),
                     "Average number of events per PDF bin" );

   DeclareOptionRef( fHistDefinedNBins, Form("Nbins%s",fSuffix.Data()),
                     "Defined number of bins for the histogram from which the PDF is created" );

   DeclareOptionRef( fCheckHist, Form("CheckHist%s",fSuffix.Data()),
                     "Whether or not to check the source histogram of the PDF" );

   DeclareOptionRef( fInterpolateString, Form("PDFInterpol%s",fSuffix.Data()), 
                     "Interpolation method for reference histograms (e.g. Spline2 or KDE)" );
   AddPreDefVal(TString("Spline0")); // take histogram                    
   AddPreDefVal(TString("Spline1")); // linear interpolation between bins 
   AddPreDefVal(TString("Spline2")); // quadratic interpolation           
   AddPreDefVal(TString("Spline3")); // cubic interpolation               
   AddPreDefVal(TString("Spline5")); // fifth order polynome interpolation
   AddPreDefVal(TString("KDE"));     // use kernel density estimator

   DeclareOptionRef( fKDEtypeString, Form("KDEtype%s",fSuffix.Data()), "KDE kernel type (1=Gauss)" );
   AddPreDefVal(TString("Gauss"));

   DeclareOptionRef( fKDEiterString, Form("KDEiter%s",fSuffix.Data()), "Number of iterations (1=non-adaptive, 2=adaptive)" );
   AddPreDefVal(TString("Nonadaptive"));
   AddPreDefVal(TString("Adaptive"));

   DeclareOptionRef( fFineFactor , Form("KDEFineFactor%s",fSuffix.Data()), 
                     "Fine tuning factor for Adaptive KDE: Factor to multyply the width of the kernel");

   DeclareOptionRef( fBorderMethodString, Form("KDEborder%s",fSuffix.Data()),
                     "Border effects treatment (1=no treatment , 2=kernel renormalization, 3=sample mirroring)" );
   AddPreDefVal(TString("None"));
   AddPreDefVal(TString("Renorm"));
   AddPreDefVal(TString("Mirror"));

   SetConfigName( GetName() );
   SetConfigDescription( "Configuration options for the PDF class" );
}

//_______________________________________________________________________
void TMVA::PDF::ProcessOptions() 
{
   
   if (fNsmooth < 0) fNsmooth = 0; // set back to default

   if (fMaxNsmooth < 0 || fMinNsmooth < 0) { // use "Nsmooth" variable
      fMinNsmooth = fMaxNsmooth = fNsmooth;
   }

   if (fMaxNsmooth < fMinNsmooth && fMinNsmooth >= 0) { // sanity check
      Log() << kFATAL << "ERROR: MaxNsmooth = " 
            << fMaxNsmooth << " < MinNsmooth = " << fMinNsmooth << Endl;
   }

   if (fMaxNsmooth < 0 || fMinNsmooth < 0) {
      Log() << kFATAL << "ERROR: MaxNsmooth = " 
            << fMaxNsmooth << " or MinNsmooth = " << fMinNsmooth << " smaller than zero" << Endl;
   }

   //processing the options
   if      (fInterpolateString == "Spline0") fInterpolMethod = TMVA::PDF::kSpline0;
   else if (fInterpolateString == "Spline1") fInterpolMethod = TMVA::PDF::kSpline1;
   else if (fInterpolateString == "Spline2") fInterpolMethod = TMVA::PDF::kSpline2;
   else if (fInterpolateString == "Spline3") fInterpolMethod = TMVA::PDF::kSpline3;
   else if (fInterpolateString == "Spline5") fInterpolMethod = TMVA::PDF::kSpline5;
   else if (fInterpolateString == "KDE"    ) fInterpolMethod = TMVA::PDF::kKDE;
   else if (fInterpolateString != ""       ) {
      Log() << kFATAL << "unknown setting for option 'InterpolateMethod': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
   }

   // init KDE options
   if      (fKDEtypeString == "Gauss"      ) fKDEtype = KDEKernel::kGauss;
   else if (fKDEtypeString != ""           )
      Log() << kFATAL << "unknown setting for option 'KDEtype': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
   if      (fKDEiterString == "Nonadaptive") fKDEiter = KDEKernel::kNonadaptiveKDE;
   else if (fKDEiterString == "Adaptive"   ) fKDEiter = KDEKernel::kAdaptiveKDE;
   else if (fKDEiterString != ""           )// nothing more known
      Log() << kFATAL << "unknown setting for option 'KDEiter': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
   
   if       ( fBorderMethodString == "None"   ) fKDEborder= KDEKernel::kNoTreatment;
   else if  ( fBorderMethodString == "Renorm" ) fKDEborder= KDEKernel::kKernelRenorm;
   else if  ( fBorderMethodString == "Mirror" ) fKDEborder= KDEKernel::kSampleMirror;
   else if  ( fKDEiterString != ""            ) { // nothing more known
      Log() << kFATAL << "unknown setting for option 'KDEBorder': " << fKDEtypeString << ((fSuffix=="")?"":Form(" for pdf with suffix %s",fSuffix.Data())) << Endl;
   }
}

//_______________________________________________________________________
void TMVA::PDF::AddXMLTo( void* parent ) 
{
   // XML file writing
   void* pdfxml = gTools().xmlengine().NewChild(parent, 0, "PDF");
   gTools().AddAttr(pdfxml, "Name",           fPDFName );
   gTools().AddAttr(pdfxml, "MinNSmooth",     fMinNsmooth );
   gTools().AddAttr(pdfxml, "MaxNSmooth",     fMaxNsmooth );
   gTools().AddAttr(pdfxml, "InterpolMethod", fInterpolMethod );
   gTools().AddAttr(pdfxml, "KDE_type",       fKDEtype );
   gTools().AddAttr(pdfxml, "KDE_iter",       fKDEiter );
   gTools().AddAttr(pdfxml, "KDE_border",     fKDEborder );
   gTools().AddAttr(pdfxml, "KDE_finefactor", fFineFactor );
   void* pdfhist = gTools().xmlengine().NewChild(pdfxml,0,"Histogram" );
   TH1*  histToWrite = GetOriginalHist();
   Bool_t hasEquidistantBinning = gTools().HistoHasEquidistantBins(*histToWrite);
   gTools().AddAttr(pdfhist, "Name",  histToWrite->GetName() );
   gTools().AddAttr(pdfhist, "NBins", histToWrite->GetNbinsX() );
   gTools().AddAttr(pdfhist, "XMin",  histToWrite->GetXaxis()->GetXmin() );
   gTools().AddAttr(pdfhist, "XMax",  histToWrite->GetXaxis()->GetXmax() );
   gTools().AddAttr(pdfhist, "HasEquidistantBins", hasEquidistantBinning );

   TString bincontent("");
   for (Int_t i=0; i<histToWrite->GetNbinsX(); i++) {
      bincontent += gTools().StringFromDouble(histToWrite->GetBinContent(i+1));
      bincontent += " ";
   }
   gTools().xmlengine().AddRawLine(pdfhist, bincontent );
   
   if (!hasEquidistantBinning) {
      void* pdfhistbins = gTools().xmlengine().NewChild(pdfxml,0,"HistogramBinning" );
      gTools().AddAttr(pdfhistbins, "NBins", histToWrite->GetNbinsX() );
      TString binns("");
      for (Int_t i=1; i<=histToWrite->GetNbinsX()+1; i++) {
         binns += gTools().StringFromDouble(histToWrite->GetXaxis()->GetBinLowEdge(i));
         binns += " ";
      }
      gTools().xmlengine().AddRawLine(pdfhistbins, binns );      
   }
}

//_______________________________________________________________________
void TMVA::PDF::ReadXML( void* pdfnode ) 
{
   // XML file reading
   UInt_t enumint;

   gTools().ReadAttr(pdfnode, "MinNSmooth",     fMinNsmooth );
   gTools().ReadAttr(pdfnode, "MaxNSmooth",     fMaxNsmooth );
   gTools().ReadAttr(pdfnode, "InterpolMethod", enumint ); fInterpolMethod = EInterpolateMethod(enumint);
   gTools().ReadAttr(pdfnode, "KDE_type",       enumint ); fKDEtype        = KDEKernel::EKernelType(enumint);
   gTools().ReadAttr(pdfnode, "KDE_iter",       enumint ); fKDEiter        = KDEKernel::EKernelIter(enumint);
   gTools().ReadAttr(pdfnode, "KDE_border",     enumint ); fKDEborder      = KDEKernel::EKernelBorder(enumint);
   gTools().ReadAttr(pdfnode, "KDE_finefactor", fFineFactor );

   TString hname;
   UInt_t nbins;
   Double_t xmin, xmax;
   Bool_t hasEquidistantBinning;

   void* histch = gTools().xmlengine().GetChild(pdfnode);
   gTools().ReadAttr( histch, "Name",  hname );
   gTools().ReadAttr( histch, "NBins", nbins );
   gTools().ReadAttr( histch, "XMin",  xmin );
   gTools().ReadAttr( histch, "XMax",  xmax );
   gTools().ReadAttr( histch, "HasEquidistantBins", hasEquidistantBinning );

   // recreate the original hist
   TH1* newhist = 0;
   if (hasEquidistantBinning) {
      newhist = new TH1F( hname, hname, nbins, xmin, xmax );
      newhist->SetDirectory(0);
      const char* content = gTools().xmlengine().GetNodeContent(histch);
      std::stringstream s(content);
      Double_t val;
      for (UInt_t i=0; i<nbins; i++) {
         s >> val;
         newhist->SetBinContent(i+1,val);
      }
   }
   else{
      const char* content = gTools().xmlengine().GetNodeContent(histch);
      std::stringstream s(content);
      Double_t val;
      void* binch = gTools().GetNextChild(histch);
      UInt_t nbinning;
      gTools().ReadAttr( binch, "NBins", nbinning );
      TVectorD binns(nbinning+1);
      if (nbinning != nbins) {
         Log() << kFATAL << "Number of bins in content and binning array differs"<<Endl;
      } 
      const char* binString = gTools().xmlengine().GetNodeContent(binch);
      std::stringstream sb(binString);
      for (UInt_t i=0; i<=nbins; i++) sb >> binns[i];
      newhist =  new TH1F( hname, hname, nbins, binns.GetMatrixArray() );
      newhist->SetDirectory(0);
      for (UInt_t i=0; i<nbins; i++) {
         s >> val;
         newhist->SetBinContent(i+1,val);
      }
   }

   TString hnameSmooth = hname;
   hnameSmooth.ReplaceAll( "_original", "_smoothed" );
   
   if (fHistOriginal != 0) delete fHistOriginal;
   fHistOriginal = newhist;
   fHist = (TH1F*)fHistOriginal->Clone( hnameSmooth );
   fHist->SetTitle( hnameSmooth );
   fHist->SetDirectory(0);
   
   if (fMinNsmooth > 0) BuildSplinePDF();
   else if (fMinNsmooth == 0 &&  fKDEtype == KDEKernel::kNone) BuildSplinePDF(); 
   else if (fMinNsmooth == 0 &&  fKDEtype != KDEKernel::kNone) BuildKDEPDF(); 
   else                 BuildKDEPDF();
}

//_______________________________________________________________________
ostream& TMVA::operator<< ( ostream& os, const PDF& pdf )
{ 
   // write the pdf
   os << "MinNSmooth      " << pdf.fMinNsmooth << std::endl;
   os << "MaxNSmooth      " << pdf.fMaxNsmooth << std::endl;
   os << "InterpolMethod  " << pdf.fInterpolMethod << std::endl;
   os << "KDE_type        " << pdf.fKDEtype << std::endl;
   os << "KDE_iter        " << pdf.fKDEiter << std::endl;
   os << "KDE_border      " << pdf.fKDEborder << std::endl;
   os << "KDE_finefactor  " << pdf.fFineFactor << std::endl;

   TH1* histToWrite = pdf.GetOriginalHist();

   const Int_t nBins = histToWrite->GetNbinsX();

   // note: this is a schema change introduced for v3.7.3
   os << "Histogram       " 
      << histToWrite->GetName() 
      << "   " << nBins                                 // nbins
      << "   " << std::setprecision(12) << histToWrite->GetXaxis()->GetXmin()    // x_min
      << "   " << std::setprecision(12) << histToWrite->GetXaxis()->GetXmax()    // x_max
      << std::endl;

   // write the smoothed hist
   os << "Weights " << std::endl;
   os << std::setprecision(8);
   for (Int_t i=0; i<nBins; i++) {
      os << std::setw(15) << std::left << histToWrite->GetBinContent(i+1) << " ";
      if ((i+1)%5==0) os << std::endl;
   }
   return os; // Return the output stream.
}

//_______________________________________________________________________
istream& TMVA::operator>> ( istream& istr, PDF& pdf )
{ 
   // read the tree from an istream
   TString devnullS;
   Int_t   valI;
   Int_t   nbins;
   Float_t xmin, xmax;
   TString hname="_original";
   Bool_t doneReading = kFALSE;
   while (!doneReading) {
      istr >> devnullS;
      if (devnullS=="NSmooth")
         {istr >> pdf.fMinNsmooth; pdf.fMaxNsmooth=pdf.fMinNsmooth;}
      else if (devnullS=="MinNSmooth") istr >> pdf.fMinNsmooth;
      else if (devnullS=="MaxNSmooth") istr >> pdf.fMaxNsmooth;
      // have to do this with strings to be more stable with developing code
      else if (devnullS == "InterpolMethod") { istr >> valI; pdf.fInterpolMethod = PDF::EInterpolateMethod(valI);}
      else if (devnullS == "KDE_type")       { istr >> valI; pdf.fKDEtype        = KDEKernel::EKernelType(valI); }
      else if (devnullS == "KDE_iter")       { istr >> valI; pdf.fKDEiter        = KDEKernel::EKernelIter(valI);}
      else if (devnullS == "KDE_border")     { istr >> valI; pdf.fKDEborder      = KDEKernel::EKernelBorder(valI);}
      else if (devnullS == "KDE_finefactor") {
         istr  >> pdf.fFineFactor;
         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.
            istr  >> nbins >> xmin >> xmax;
            doneReading = kTRUE;
         }
      }
      else if (devnullS == "Histogram")     { istr  >> hname >> nbins >> xmin >> xmax; }
      else if (devnullS == "Weights")       { doneReading = kTRUE; }
   }

   TString hnameSmooth = hname;
   hnameSmooth.ReplaceAll( "_original", "_smoothed" );

   // recreate the original hist
   TH1* newhist = new TH1F( hname,hname, nbins, xmin, xmax );
   newhist->SetDirectory(0);
   Float_t val;
   for (Int_t i=0; i<nbins; i++) {
      istr >> val;
      newhist->SetBinContent(i+1,val);
   }
   
   if (pdf.fHistOriginal != 0) delete pdf.fHistOriginal;
   pdf.fHistOriginal = newhist;
   pdf.fHist = (TH1F*)pdf.fHistOriginal->Clone( hnameSmooth );
   pdf.fHist->SetTitle( hnameSmooth );
   pdf.fHist->SetDirectory(0);

   if (pdf.fMinNsmooth>0) pdf.BuildSplinePDF();
   else                   pdf.BuildKDEPDF();

   return istr;
}
 PDF.cxx:1
 PDF.cxx:2
 PDF.cxx:3
 PDF.cxx:4
 PDF.cxx:5
 PDF.cxx:6
 PDF.cxx:7
 PDF.cxx:8
 PDF.cxx:9
 PDF.cxx:10
 PDF.cxx:11
 PDF.cxx:12
 PDF.cxx:13
 PDF.cxx:14
 PDF.cxx:15
 PDF.cxx:16
 PDF.cxx:17
 PDF.cxx:18
 PDF.cxx:19
 PDF.cxx:20
 PDF.cxx:21
 PDF.cxx:22
 PDF.cxx:23
 PDF.cxx:24
 PDF.cxx:25
 PDF.cxx:26
 PDF.cxx:27
 PDF.cxx:28
 PDF.cxx:29
 PDF.cxx:30
 PDF.cxx:31
 PDF.cxx:32
 PDF.cxx:33
 PDF.cxx:34
 PDF.cxx:35
 PDF.cxx:36
 PDF.cxx:37
 PDF.cxx:38
 PDF.cxx:39
 PDF.cxx:40
 PDF.cxx:41
 PDF.cxx:42
 PDF.cxx:43
 PDF.cxx:44
 PDF.cxx:45
 PDF.cxx:46
 PDF.cxx:47
 PDF.cxx:48
 PDF.cxx:49
 PDF.cxx:50
 PDF.cxx:51
 PDF.cxx:52
 PDF.cxx:53
 PDF.cxx:54
 PDF.cxx:55
 PDF.cxx:56
 PDF.cxx:57
 PDF.cxx:58
 PDF.cxx:59
 PDF.cxx:60
 PDF.cxx:61
 PDF.cxx:62
 PDF.cxx:63
 PDF.cxx:64
 PDF.cxx:65
 PDF.cxx:66
 PDF.cxx:67
 PDF.cxx:68
 PDF.cxx:69
 PDF.cxx:70
 PDF.cxx:71
 PDF.cxx:72
 PDF.cxx:73
 PDF.cxx:74
 PDF.cxx:75
 PDF.cxx:76
 PDF.cxx:77
 PDF.cxx:78
 PDF.cxx:79
 PDF.cxx:80
 PDF.cxx:81
 PDF.cxx:82
 PDF.cxx:83
 PDF.cxx:84
 PDF.cxx:85
 PDF.cxx:86
 PDF.cxx:87
 PDF.cxx:88
 PDF.cxx:89
 PDF.cxx:90
 PDF.cxx:91
 PDF.cxx:92
 PDF.cxx:93
 PDF.cxx:94
 PDF.cxx:95
 PDF.cxx:96
 PDF.cxx:97
 PDF.cxx:98
 PDF.cxx:99
 PDF.cxx:100
 PDF.cxx:101
 PDF.cxx:102
 PDF.cxx:103
 PDF.cxx:104
 PDF.cxx:105
 PDF.cxx:106
 PDF.cxx:107
 PDF.cxx:108
 PDF.cxx:109
 PDF.cxx:110
 PDF.cxx:111
 PDF.cxx:112
 PDF.cxx:113
 PDF.cxx:114
 PDF.cxx:115
 PDF.cxx:116
 PDF.cxx:117
 PDF.cxx:118
 PDF.cxx:119
 PDF.cxx:120
 PDF.cxx:121
 PDF.cxx:122
 PDF.cxx:123
 PDF.cxx:124
 PDF.cxx:125
 PDF.cxx:126
 PDF.cxx:127
 PDF.cxx:128
 PDF.cxx:129
 PDF.cxx:130
 PDF.cxx:131
 PDF.cxx:132
 PDF.cxx:133
 PDF.cxx:134
 PDF.cxx:135
 PDF.cxx:136
 PDF.cxx:137
 PDF.cxx:138
 PDF.cxx:139
 PDF.cxx:140
 PDF.cxx:141
 PDF.cxx:142
 PDF.cxx:143
 PDF.cxx:144
 PDF.cxx:145
 PDF.cxx:146
 PDF.cxx:147
 PDF.cxx:148
 PDF.cxx:149
 PDF.cxx:150
 PDF.cxx:151
 PDF.cxx:152
 PDF.cxx:153
 PDF.cxx:154
 PDF.cxx:155
 PDF.cxx:156
 PDF.cxx:157
 PDF.cxx:158
 PDF.cxx:159
 PDF.cxx:160
 PDF.cxx:161
 PDF.cxx:162
 PDF.cxx:163
 PDF.cxx:164
 PDF.cxx:165
 PDF.cxx:166
 PDF.cxx:167
 PDF.cxx:168
 PDF.cxx:169
 PDF.cxx:170
 PDF.cxx:171
 PDF.cxx:172
 PDF.cxx:173
 PDF.cxx:174
 PDF.cxx:175
 PDF.cxx:176
 PDF.cxx:177
 PDF.cxx:178
 PDF.cxx:179
 PDF.cxx:180
 PDF.cxx:181
 PDF.cxx:182
 PDF.cxx:183
 PDF.cxx:184
 PDF.cxx:185
 PDF.cxx:186
 PDF.cxx:187
 PDF.cxx:188
 PDF.cxx:189
 PDF.cxx:190
 PDF.cxx:191
 PDF.cxx:192
 PDF.cxx:193
 PDF.cxx:194
 PDF.cxx:195
 PDF.cxx:196
 PDF.cxx:197
 PDF.cxx:198
 PDF.cxx:199
 PDF.cxx:200
 PDF.cxx:201
 PDF.cxx:202
 PDF.cxx:203
 PDF.cxx:204
 PDF.cxx:205
 PDF.cxx:206
 PDF.cxx:207
 PDF.cxx:208
 PDF.cxx:209
 PDF.cxx:210
 PDF.cxx:211
 PDF.cxx:212
 PDF.cxx:213
 PDF.cxx:214
 PDF.cxx:215
 PDF.cxx:216
 PDF.cxx:217
 PDF.cxx:218
 PDF.cxx:219
 PDF.cxx:220
 PDF.cxx:221
 PDF.cxx:222
 PDF.cxx:223
 PDF.cxx:224
 PDF.cxx:225
 PDF.cxx:226
 PDF.cxx:227
 PDF.cxx:228
 PDF.cxx:229
 PDF.cxx:230
 PDF.cxx:231
 PDF.cxx:232
 PDF.cxx:233
 PDF.cxx:234
 PDF.cxx:235
 PDF.cxx:236
 PDF.cxx:237
 PDF.cxx:238
 PDF.cxx:239
 PDF.cxx:240
 PDF.cxx:241
 PDF.cxx:242
 PDF.cxx:243
 PDF.cxx:244
 PDF.cxx:245
 PDF.cxx:246
 PDF.cxx:247
 PDF.cxx:248
 PDF.cxx:249
 PDF.cxx:250
 PDF.cxx:251
 PDF.cxx:252
 PDF.cxx:253
 PDF.cxx:254
 PDF.cxx:255
 PDF.cxx:256
 PDF.cxx:257
 PDF.cxx:258
 PDF.cxx:259
 PDF.cxx:260
 PDF.cxx:261
 PDF.cxx:262
 PDF.cxx:263
 PDF.cxx:264
 PDF.cxx:265
 PDF.cxx:266
 PDF.cxx:267
 PDF.cxx:268
 PDF.cxx:269
 PDF.cxx:270
 PDF.cxx:271
 PDF.cxx:272
 PDF.cxx:273
 PDF.cxx:274
 PDF.cxx:275
 PDF.cxx:276
 PDF.cxx:277
 PDF.cxx:278
 PDF.cxx:279
 PDF.cxx:280
 PDF.cxx:281
 PDF.cxx:282
 PDF.cxx:283
 PDF.cxx:284
 PDF.cxx:285
 PDF.cxx:286
 PDF.cxx:287
 PDF.cxx:288
 PDF.cxx:289
 PDF.cxx:290
 PDF.cxx:291
 PDF.cxx:292
 PDF.cxx:293
 PDF.cxx:294
 PDF.cxx:295
 PDF.cxx:296
 PDF.cxx:297
 PDF.cxx:298
 PDF.cxx:299
 PDF.cxx:300
 PDF.cxx:301
 PDF.cxx:302
 PDF.cxx:303
 PDF.cxx:304
 PDF.cxx:305
 PDF.cxx:306
 PDF.cxx:307
 PDF.cxx:308
 PDF.cxx:309
 PDF.cxx:310
 PDF.cxx:311
 PDF.cxx:312
 PDF.cxx:313
 PDF.cxx:314
 PDF.cxx:315
 PDF.cxx:316
 PDF.cxx:317
 PDF.cxx:318
 PDF.cxx:319
 PDF.cxx:320
 PDF.cxx:321
 PDF.cxx:322
 PDF.cxx:323
 PDF.cxx:324
 PDF.cxx:325
 PDF.cxx:326
 PDF.cxx:327
 PDF.cxx:328
 PDF.cxx:329
 PDF.cxx:330
 PDF.cxx:331
 PDF.cxx:332
 PDF.cxx:333
 PDF.cxx:334
 PDF.cxx:335
 PDF.cxx:336
 PDF.cxx:337
 PDF.cxx:338
 PDF.cxx:339
 PDF.cxx:340
 PDF.cxx:341
 PDF.cxx:342
 PDF.cxx:343
 PDF.cxx:344
 PDF.cxx:345
 PDF.cxx:346
 PDF.cxx:347
 PDF.cxx:348
 PDF.cxx:349
 PDF.cxx:350
 PDF.cxx:351
 PDF.cxx:352
 PDF.cxx:353
 PDF.cxx:354
 PDF.cxx:355
 PDF.cxx:356
 PDF.cxx:357
 PDF.cxx:358
 PDF.cxx:359
 PDF.cxx:360
 PDF.cxx:361
 PDF.cxx:362
 PDF.cxx:363
 PDF.cxx:364
 PDF.cxx:365
 PDF.cxx:366
 PDF.cxx:367
 PDF.cxx:368
 PDF.cxx:369
 PDF.cxx:370
 PDF.cxx:371
 PDF.cxx:372
 PDF.cxx:373
 PDF.cxx:374
 PDF.cxx:375
 PDF.cxx:376
 PDF.cxx:377
 PDF.cxx:378
 PDF.cxx:379
 PDF.cxx:380
 PDF.cxx:381
 PDF.cxx:382
 PDF.cxx:383
 PDF.cxx:384
 PDF.cxx:385
 PDF.cxx:386
 PDF.cxx:387
 PDF.cxx:388
 PDF.cxx:389
 PDF.cxx:390
 PDF.cxx:391
 PDF.cxx:392
 PDF.cxx:393
 PDF.cxx:394
 PDF.cxx:395
 PDF.cxx:396
 PDF.cxx:397
 PDF.cxx:398
 PDF.cxx:399
 PDF.cxx:400
 PDF.cxx:401
 PDF.cxx:402
 PDF.cxx:403
 PDF.cxx:404
 PDF.cxx:405
 PDF.cxx:406
 PDF.cxx:407
 PDF.cxx:408
 PDF.cxx:409
 PDF.cxx:410
 PDF.cxx:411
 PDF.cxx:412
 PDF.cxx:413
 PDF.cxx:414
 PDF.cxx:415
 PDF.cxx:416
 PDF.cxx:417
 PDF.cxx:418
 PDF.cxx:419
 PDF.cxx:420
 PDF.cxx:421
 PDF.cxx:422
 PDF.cxx:423
 PDF.cxx:424
 PDF.cxx:425
 PDF.cxx:426
 PDF.cxx:427
 PDF.cxx:428
 PDF.cxx:429
 PDF.cxx:430
 PDF.cxx:431
 PDF.cxx:432
 PDF.cxx:433
 PDF.cxx:434
 PDF.cxx:435
 PDF.cxx:436
 PDF.cxx:437
 PDF.cxx:438
 PDF.cxx:439
 PDF.cxx:440
 PDF.cxx:441
 PDF.cxx:442
 PDF.cxx:443
 PDF.cxx:444
 PDF.cxx:445
 PDF.cxx:446
 PDF.cxx:447
 PDF.cxx:448
 PDF.cxx:449
 PDF.cxx:450
 PDF.cxx:451
 PDF.cxx:452
 PDF.cxx:453
 PDF.cxx:454
 PDF.cxx:455
 PDF.cxx:456
 PDF.cxx:457
 PDF.cxx:458
 PDF.cxx:459
 PDF.cxx:460
 PDF.cxx:461
 PDF.cxx:462
 PDF.cxx:463
 PDF.cxx:464
 PDF.cxx:465
 PDF.cxx:466
 PDF.cxx:467
 PDF.cxx:468
 PDF.cxx:469
 PDF.cxx:470
 PDF.cxx:471
 PDF.cxx:472
 PDF.cxx:473
 PDF.cxx:474
 PDF.cxx:475
 PDF.cxx:476
 PDF.cxx:477
 PDF.cxx:478
 PDF.cxx:479
 PDF.cxx:480
 PDF.cxx:481
 PDF.cxx:482
 PDF.cxx:483
 PDF.cxx:484
 PDF.cxx:485
 PDF.cxx:486
 PDF.cxx:487
 PDF.cxx:488
 PDF.cxx:489
 PDF.cxx:490
 PDF.cxx:491
 PDF.cxx:492
 PDF.cxx:493
 PDF.cxx:494
 PDF.cxx:495
 PDF.cxx:496
 PDF.cxx:497
 PDF.cxx:498
 PDF.cxx:499
 PDF.cxx:500
 PDF.cxx:501
 PDF.cxx:502
 PDF.cxx:503
 PDF.cxx:504
 PDF.cxx:505
 PDF.cxx:506
 PDF.cxx:507
 PDF.cxx:508
 PDF.cxx:509
 PDF.cxx:510
 PDF.cxx:511
 PDF.cxx:512
 PDF.cxx:513
 PDF.cxx:514
 PDF.cxx:515
 PDF.cxx:516
 PDF.cxx:517
 PDF.cxx:518
 PDF.cxx:519
 PDF.cxx:520
 PDF.cxx:521
 PDF.cxx:522
 PDF.cxx:523
 PDF.cxx:524
 PDF.cxx:525
 PDF.cxx:526
 PDF.cxx:527
 PDF.cxx:528
 PDF.cxx:529
 PDF.cxx:530
 PDF.cxx:531
 PDF.cxx:532
 PDF.cxx:533
 PDF.cxx:534
 PDF.cxx:535
 PDF.cxx:536
 PDF.cxx:537
 PDF.cxx:538
 PDF.cxx:539
 PDF.cxx:540
 PDF.cxx:541
 PDF.cxx:542
 PDF.cxx:543
 PDF.cxx:544
 PDF.cxx:545
 PDF.cxx:546
 PDF.cxx:547
 PDF.cxx:548
 PDF.cxx:549
 PDF.cxx:550
 PDF.cxx:551
 PDF.cxx:552
 PDF.cxx:553
 PDF.cxx:554
 PDF.cxx:555
 PDF.cxx:556
 PDF.cxx:557
 PDF.cxx:558
 PDF.cxx:559
 PDF.cxx:560
 PDF.cxx:561
 PDF.cxx:562
 PDF.cxx:563
 PDF.cxx:564
 PDF.cxx:565
 PDF.cxx:566
 PDF.cxx:567
 PDF.cxx:568
 PDF.cxx:569
 PDF.cxx:570
 PDF.cxx:571
 PDF.cxx:572
 PDF.cxx:573
 PDF.cxx:574
 PDF.cxx:575
 PDF.cxx:576
 PDF.cxx:577
 PDF.cxx:578
 PDF.cxx:579
 PDF.cxx:580
 PDF.cxx:581
 PDF.cxx:582
 PDF.cxx:583
 PDF.cxx:584
 PDF.cxx:585
 PDF.cxx:586
 PDF.cxx:587
 PDF.cxx:588
 PDF.cxx:589
 PDF.cxx:590
 PDF.cxx:591
 PDF.cxx:592
 PDF.cxx:593
 PDF.cxx:594
 PDF.cxx:595
 PDF.cxx:596
 PDF.cxx:597
 PDF.cxx:598
 PDF.cxx:599
 PDF.cxx:600
 PDF.cxx:601
 PDF.cxx:602
 PDF.cxx:603
 PDF.cxx:604
 PDF.cxx:605
 PDF.cxx:606
 PDF.cxx:607
 PDF.cxx:608
 PDF.cxx:609
 PDF.cxx:610
 PDF.cxx:611
 PDF.cxx:612
 PDF.cxx:613
 PDF.cxx:614
 PDF.cxx:615
 PDF.cxx:616
 PDF.cxx:617
 PDF.cxx:618
 PDF.cxx:619
 PDF.cxx:620
 PDF.cxx:621
 PDF.cxx:622
 PDF.cxx:623
 PDF.cxx:624
 PDF.cxx:625
 PDF.cxx:626
 PDF.cxx:627
 PDF.cxx:628
 PDF.cxx:629
 PDF.cxx:630
 PDF.cxx:631
 PDF.cxx:632
 PDF.cxx:633
 PDF.cxx:634
 PDF.cxx:635
 PDF.cxx:636
 PDF.cxx:637
 PDF.cxx:638
 PDF.cxx:639
 PDF.cxx:640
 PDF.cxx:641
 PDF.cxx:642
 PDF.cxx:643
 PDF.cxx:644
 PDF.cxx:645
 PDF.cxx:646
 PDF.cxx:647
 PDF.cxx:648
 PDF.cxx:649
 PDF.cxx:650
 PDF.cxx:651
 PDF.cxx:652
 PDF.cxx:653
 PDF.cxx:654
 PDF.cxx:655
 PDF.cxx:656
 PDF.cxx:657
 PDF.cxx:658
 PDF.cxx:659
 PDF.cxx:660
 PDF.cxx:661
 PDF.cxx:662
 PDF.cxx:663
 PDF.cxx:664
 PDF.cxx:665
 PDF.cxx:666
 PDF.cxx:667
 PDF.cxx:668
 PDF.cxx:669
 PDF.cxx:670
 PDF.cxx:671
 PDF.cxx:672
 PDF.cxx:673
 PDF.cxx:674
 PDF.cxx:675
 PDF.cxx:676
 PDF.cxx:677
 PDF.cxx:678
 PDF.cxx:679
 PDF.cxx:680
 PDF.cxx:681
 PDF.cxx:682
 PDF.cxx:683
 PDF.cxx:684
 PDF.cxx:685
 PDF.cxx:686
 PDF.cxx:687
 PDF.cxx:688
 PDF.cxx:689
 PDF.cxx:690
 PDF.cxx:691
 PDF.cxx:692
 PDF.cxx:693
 PDF.cxx:694
 PDF.cxx:695
 PDF.cxx:696
 PDF.cxx:697
 PDF.cxx:698
 PDF.cxx:699
 PDF.cxx:700
 PDF.cxx:701
 PDF.cxx:702
 PDF.cxx:703
 PDF.cxx:704
 PDF.cxx:705
 PDF.cxx:706
 PDF.cxx:707
 PDF.cxx:708
 PDF.cxx:709
 PDF.cxx:710
 PDF.cxx:711
 PDF.cxx:712
 PDF.cxx:713
 PDF.cxx:714
 PDF.cxx:715
 PDF.cxx:716
 PDF.cxx:717
 PDF.cxx:718
 PDF.cxx:719
 PDF.cxx:720
 PDF.cxx:721
 PDF.cxx:722
 PDF.cxx:723
 PDF.cxx:724
 PDF.cxx:725
 PDF.cxx:726
 PDF.cxx:727
 PDF.cxx:728
 PDF.cxx:729
 PDF.cxx:730
 PDF.cxx:731
 PDF.cxx:732
 PDF.cxx:733
 PDF.cxx:734
 PDF.cxx:735
 PDF.cxx:736
 PDF.cxx:737
 PDF.cxx:738
 PDF.cxx:739
 PDF.cxx:740
 PDF.cxx:741
 PDF.cxx:742
 PDF.cxx:743
 PDF.cxx:744
 PDF.cxx:745
 PDF.cxx:746
 PDF.cxx:747
 PDF.cxx:748
 PDF.cxx:749
 PDF.cxx:750
 PDF.cxx:751
 PDF.cxx:752
 PDF.cxx:753
 PDF.cxx:754
 PDF.cxx:755
 PDF.cxx:756
 PDF.cxx:757
 PDF.cxx:758
 PDF.cxx:759
 PDF.cxx:760
 PDF.cxx:761
 PDF.cxx:762
 PDF.cxx:763
 PDF.cxx:764
 PDF.cxx:765
 PDF.cxx:766
 PDF.cxx:767
 PDF.cxx:768
 PDF.cxx:769
 PDF.cxx:770
 PDF.cxx:771
 PDF.cxx:772
 PDF.cxx:773
 PDF.cxx:774
 PDF.cxx:775
 PDF.cxx:776
 PDF.cxx:777
 PDF.cxx:778
 PDF.cxx:779
 PDF.cxx:780
 PDF.cxx:781
 PDF.cxx:782
 PDF.cxx:783
 PDF.cxx:784
 PDF.cxx:785
 PDF.cxx:786
 PDF.cxx:787
 PDF.cxx:788
 PDF.cxx:789
 PDF.cxx:790
 PDF.cxx:791
 PDF.cxx:792
 PDF.cxx:793
 PDF.cxx:794
 PDF.cxx:795
 PDF.cxx:796
 PDF.cxx:797
 PDF.cxx:798
 PDF.cxx:799
 PDF.cxx:800
 PDF.cxx:801
 PDF.cxx:802
 PDF.cxx:803
 PDF.cxx:804
 PDF.cxx:805
 PDF.cxx:806
 PDF.cxx:807
 PDF.cxx:808
 PDF.cxx:809
 PDF.cxx:810
 PDF.cxx:811
 PDF.cxx:812
 PDF.cxx:813
 PDF.cxx:814
 PDF.cxx:815
 PDF.cxx:816
 PDF.cxx:817
 PDF.cxx:818
 PDF.cxx:819
 PDF.cxx:820
 PDF.cxx:821
 PDF.cxx:822
 PDF.cxx:823
 PDF.cxx:824
 PDF.cxx:825
 PDF.cxx:826
 PDF.cxx:827
 PDF.cxx:828
 PDF.cxx:829
 PDF.cxx:830
 PDF.cxx:831
 PDF.cxx:832
 PDF.cxx:833
 PDF.cxx:834
 PDF.cxx:835
 PDF.cxx:836
 PDF.cxx:837
 PDF.cxx:838
 PDF.cxx:839
 PDF.cxx:840
 PDF.cxx:841
 PDF.cxx:842
 PDF.cxx:843
 PDF.cxx:844
 PDF.cxx:845
 PDF.cxx:846
 PDF.cxx:847
 PDF.cxx:848
 PDF.cxx:849
 PDF.cxx:850
 PDF.cxx:851
 PDF.cxx:852
 PDF.cxx:853
 PDF.cxx:854
 PDF.cxx:855
 PDF.cxx:856
 PDF.cxx:857
 PDF.cxx:858
 PDF.cxx:859
 PDF.cxx:860
 PDF.cxx:861
 PDF.cxx:862
 PDF.cxx:863
 PDF.cxx:864
 PDF.cxx:865
 PDF.cxx:866
 PDF.cxx:867
 PDF.cxx:868
 PDF.cxx:869
 PDF.cxx:870
 PDF.cxx:871
 PDF.cxx:872
 PDF.cxx:873
 PDF.cxx:874
 PDF.cxx:875
 PDF.cxx:876
 PDF.cxx:877
 PDF.cxx:878
 PDF.cxx:879
 PDF.cxx:880
 PDF.cxx:881
 PDF.cxx:882
 PDF.cxx:883
 PDF.cxx:884
 PDF.cxx:885
 PDF.cxx:886
 PDF.cxx:887
 PDF.cxx:888
 PDF.cxx:889
 PDF.cxx:890
 PDF.cxx:891
 PDF.cxx:892
 PDF.cxx:893
 PDF.cxx:894
 PDF.cxx:895
 PDF.cxx:896
 PDF.cxx:897
 PDF.cxx:898
 PDF.cxx:899
 PDF.cxx:900
 PDF.cxx:901
 PDF.cxx:902
 PDF.cxx:903
 PDF.cxx:904
 PDF.cxx:905
 PDF.cxx:906
 PDF.cxx:907
 PDF.cxx:908
 PDF.cxx:909
 PDF.cxx:910
 PDF.cxx:911
 PDF.cxx:912
 PDF.cxx:913
 PDF.cxx:914
 PDF.cxx:915
 PDF.cxx:916
 PDF.cxx:917
 PDF.cxx:918
 PDF.cxx:919
 PDF.cxx:920
 PDF.cxx:921
 PDF.cxx:922
 PDF.cxx:923
 PDF.cxx:924
 PDF.cxx:925
 PDF.cxx:926
 PDF.cxx:927
 PDF.cxx:928
 PDF.cxx:929
 PDF.cxx:930
 PDF.cxx:931
 PDF.cxx:932
 PDF.cxx:933
 PDF.cxx:934
 PDF.cxx:935
 PDF.cxx:936
 PDF.cxx:937
 PDF.cxx:938
 PDF.cxx:939
 PDF.cxx:940
 PDF.cxx:941
 PDF.cxx:942
 PDF.cxx:943
 PDF.cxx:944
 PDF.cxx:945
 PDF.cxx:946
 PDF.cxx:947
 PDF.cxx:948
 PDF.cxx:949
 PDF.cxx:950
 PDF.cxx:951
 PDF.cxx:952
 PDF.cxx:953
 PDF.cxx:954
 PDF.cxx:955
 PDF.cxx:956
 PDF.cxx:957
 PDF.cxx:958
 PDF.cxx:959
 PDF.cxx:960
 PDF.cxx:961
 PDF.cxx:962
 PDF.cxx:963
 PDF.cxx:964
 PDF.cxx:965
 PDF.cxx:966
 PDF.cxx:967
 PDF.cxx:968
 PDF.cxx:969
 PDF.cxx:970
 PDF.cxx:971
 PDF.cxx:972
 PDF.cxx:973
 PDF.cxx:974
 PDF.cxx:975
 PDF.cxx:976
 PDF.cxx:977
 PDF.cxx:978
 PDF.cxx:979
 PDF.cxx:980
 PDF.cxx:981
 PDF.cxx:982
 PDF.cxx:983
 PDF.cxx:984
 PDF.cxx:985
 PDF.cxx:986
 PDF.cxx:987
 PDF.cxx:988
 PDF.cxx:989
 PDF.cxx:990
 PDF.cxx:991
 PDF.cxx:992
 PDF.cxx:993
 PDF.cxx:994
 PDF.cxx:995
 PDF.cxx:996
 PDF.cxx:997
 PDF.cxx:998
 PDF.cxx:999
 PDF.cxx:1000
 PDF.cxx:1001
 PDF.cxx:1002
 PDF.cxx:1003
 PDF.cxx:1004
 PDF.cxx:1005
 PDF.cxx:1006
 PDF.cxx:1007
 PDF.cxx:1008
 PDF.cxx:1009
 PDF.cxx:1010
 PDF.cxx:1011
 PDF.cxx:1012
 PDF.cxx:1013
 PDF.cxx:1014
 PDF.cxx:1015
 PDF.cxx:1016
 PDF.cxx:1017
 PDF.cxx:1018
 PDF.cxx:1019