Sophie

Sophie

distrib > Fedora > 18 > x86_64 > by-pkgid > 8c86774a3e53d77cc119f53a2b94a57a > files > 1256

root-tutorial-5.34.14-2.fc18.noarch.rpm

//////////////////////////////////////////////////////////////////////////
//
// 'NUMERIC ALGORITHM TUNING' RooFit tutorial macro #903 
// 
//  Caching of slow numeric integrals and parameterizations of slow
//  numeric integrals
//
// 07/2008 - Wouter Verkerke 
// 
/////////////////////////////////////////////////////////////////////////

#ifndef __CINT__
#include "RooGlobalFunc.h"
#endif
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooDataHist.h"
#include "RooGaussian.h"
#include "RooConstVar.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "RooPlot.h"
#include "RooWorkspace.h"
#include "RooExpensiveObjectCache.h"
#include "TFile.h"
#include "TH1.h"

using namespace RooFit ;

RooWorkspace* getWorkspace(Int_t mode) ;

void rf903_numintcache(Int_t mode=0)
{
  // Mode = 0 : Run plain fit (slow)
  // Mode = 1 : Generate workspace with precalculated integral and store it on file (prepare for accelerated running)
  // Mode = 2 : Run fit from previously stored workspace including cached integrals (fast, requires run in mode=1 first)

  // C r e a t e ,   s a v e   o r   l o a d   w o r k s p a c e   w i t h   p . d . f . 
  // -----------------------------------------------------------------------------------

  // Make/load workspace, exit here in mode 1
  RooWorkspace* w = getWorkspace(mode) ;
  if (mode==1) {

    // Show workspace that was created
    w->Print() ;

    // Show plot of cached integral values
    RooDataHist* hhcache = (RooDataHist*) w->expensiveObjectCache().getObj(1) ;

    new TCanvas("rf903_numintcache","rf903_numintcache",600,600) ;
    hhcache->createHistogram("a")->Draw() ;
    
    return ;
  }


  // U s e   p . d . f .   f r o m   w o r k s p a c e   f o r   g e n e r a t i o n   a n d   f i t t i n g 
  // -----------------------------------------------------------------------------------

  // This is always slow (need to find maximum function value empirically in 3D space)
  RooDataSet* d = w->pdf("model")->generate(RooArgSet(*w->var("x"),*w->var("y"),*w->var("z")),1000) ;

  // This is slow in mode 0, but fast in mode 1
  w->pdf("model")->fitTo(*d,Verbose(kTRUE),Timer(kTRUE)) ; 

  // Projection on x (always slow as 2D integral over Y,Z at fitted value of a is not cached)
  RooPlot* framex = w->var("x")->frame(Title("Projection of 3D model on X")) ;
  d->plotOn(framex) ;
  w->pdf("model")->plotOn(framex) ;

  // Draw x projection on canvas
  new TCanvas("rf903_numintcache","rf903_numintcache",600,600) ;
  framex->Draw() ;

  // Make workspace available on command line after macro finishes
  gDirectory->Add(w) ;

  return ;

 
}



RooWorkspace* getWorkspace(Int_t mode) 
{
  // C r e a t e ,   s a v e   o r   l o a d   w o r k s p a c e   w i t h   p . d . f . 
  // -----------------------------------------------------------------------------------
  //
  // Mode = 0 : Create workspace for plain running (no integral caching)
  // Mode = 1 : Generate workspace with precalculated integral and store it on file
  // Mode = 2 : Load previously stored workspace from file

  RooWorkspace* w(0) ;

  if (mode!=2) {

    // Create empty workspace workspace 
    w = new RooWorkspace("w",1) ;

    // Make a difficult to normalize  p.d.f. in 3 dimensions that is integrated numerically.
    w->factory("EXPR::model('1/((x-a)*(x-a)+0.01)+1/((y-a)*(y-a)+0.01)+1/((z-a)*(z-a)+0.01)',x[-1,1],y[-1,1],z[-1,1],a[-5,5])") ;
  }

  if (mode==1) {
    
    // Instruct model to precalculate normalization integral that integrate at least
    // two dimensions numerically. In this specific case the integral value for
    // all values of parameter 'a' are stored in a histogram and available for use 
    // in subsequent fitting and plotting operations (interpolation is applied)
    w->pdf("model")->setNormValueCaching(3) ;
    
    // Evaluate p.d.f. once to trigger filling of cache
    RooArgSet normSet(*w->var("x"),*w->var("y"),*w->var("z")) ;
    w->pdf("model")->getVal(&normSet) ;
    w->writeToFile("rf903_numintcache.root") ;

  } 

  if (mode==2) {    
    // Load preexisting workspace from file in mode==2
    TFile* f = new TFile("rf903_numintcache.root") ;
    w = (RooWorkspace*) f->Get("w") ;
  }

  // Return created or loaded workspace
  return w ;
}