Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
rf903_numintcache.C
Go to the documentation of this file.
1 /// \file
2 /// \ingroup tutorial_roofit
3 /// \notebook -js
4 /// Numeric algorithm tuning: caching of slow numeric integrals and parameterization of slow numeric integrals
5 ///
6 /// \macro_image
7 /// \macro_output
8 /// \macro_code
9 /// \author 07/2008 - Wouter Verkerke
10 
11 #include "RooRealVar.h"
12 #include "RooDataSet.h"
13 #include "RooDataHist.h"
14 #include "RooGaussian.h"
15 #include "RooConstVar.h"
16 #include "TCanvas.h"
17 #include "TAxis.h"
18 #include "RooPlot.h"
19 #include "RooWorkspace.h"
21 #include "TFile.h"
22 #include "TH1.h"
23 
24 using namespace RooFit;
25 
26 RooWorkspace *getWorkspace(Int_t mode);
27 
28 void rf903_numintcache(Int_t mode = 0)
29 {
30  // Mode = 0 : Run plain fit (slow)
31  // Mode = 1 : Generate workspace with pre-calculated integral and store it on file (prepare for accelerated running)
32  // Mode = 2 : Run fit from previously stored workspace including cached integrals (fast, requires run in mode=1
33  // first)
34 
35  // 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 .
36  // -----------------------------------------------------------------------------------
37 
38  // Make/load workspace, exit here in mode 1
39  RooWorkspace *w1 = getWorkspace(mode);
40  if (mode == 1) {
41 
42  // Show workspace that was created
43  w1->Print();
44 
45  // Show plot of cached integral values
46  RooDataHist *hhcache = (RooDataHist *)w1->expensiveObjectCache().getObj(1);
47  if (hhcache) {
48 
49  new TCanvas("rf903_numintcache", "rf903_numintcache", 600, 600);
50  hhcache->createHistogram("a")->Draw();
51 
52  } else {
53  Error("rf903_numintcache", "Cached histogram is not existing in workspace");
54  }
55  return;
56  }
57 
58  // 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
59  // -----------------------------------------------------------------------------------
60 
61  // This is always slow (need to find maximum function value empirically in 3D space)
62  RooDataSet *d = w1->pdf("model")->generate(RooArgSet(*w1->var("x"), *w1->var("y"), *w1->var("z")), 1000);
63 
64  // This is slow in mode 0, but fast in mode 1
65  w1->pdf("model")->fitTo(*d, Verbose(kTRUE), Timer(kTRUE));
66 
67  // Projection on x (always slow as 2D integral over Y,Z at fitted value of a is not cached)
68  RooPlot *framex = w1->var("x")->frame(Title("Projection of 3D model on X"));
69  d->plotOn(framex);
70  w1->pdf("model")->plotOn(framex);
71 
72  // Draw x projection on canvas
73  new TCanvas("rf903_numintcache", "rf903_numintcache", 600, 600);
74  framex->Draw();
75 
76  // Make workspace available on command line after macro finishes
77  gDirectory->Add(w1);
78 
79  return;
80 }
81 
82 RooWorkspace *getWorkspace(Int_t mode)
83 {
84  // 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 .
85  // -----------------------------------------------------------------------------------
86  //
87  // Mode = 0 : Create workspace for plain running (no integral caching)
88  // Mode = 1 : Generate workspace with pre-calculated integral and store it on file
89  // Mode = 2 : Load previously stored workspace from file
90 
91  RooWorkspace *w(0);
92 
93  if (mode != 2) {
94 
95  // Create empty workspace workspace
96  w = new RooWorkspace("w", 1);
97 
98  // Make a difficult to normalize p.d.f. in 3 dimensions that is integrated numerically.
99  w->factory("EXPR::model('1/((x-a)*(x-a)+0.01)+1/((y-a)*(y-a)+0.01)+1/"
100  "((z-a)*(z-a)+0.01)',x[-1,1],y[-1,1],z[-1,1],a[-5,5])");
101  }
102 
103  if (mode == 1) {
104 
105  // Instruct model to pre-calculate normalization integral that integrate at least
106  // two dimensions numerically. In this specific case the integral value for
107  // all values of parameter 'a' are stored in a histogram and available for use
108  // in subsequent fitting and plotting operations (interpolation is applied)
109 
110  // w->pdf("model")->setNormValueCaching(3) ;
111  w->pdf("model")->setStringAttribute("CACHEPARMINT", "x:y:z");
112 
113  // Evaluate p.d.f. once to trigger filling of cache
114  RooArgSet normSet(*w->var("x"), *w->var("y"), *w->var("z"));
115  w->pdf("model")->getVal(&normSet);
116  w->writeToFile("rf903_numintcache.root");
117  }
118 
119  if (mode == 2) {
120  // Load preexisting workspace from file in mode==2
121  TFile *f = new TFile("rf903_numintcache.root");
122  w = (RooWorkspace *)f->Get("w");
123  }
124 
125  // Return created or loaded workspace
126  return w;
127 }