Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooNumIntConfig.cxx
Go to the documentation of this file.
1 /*****************************************************************************
2  * Project: RooFit *
3  * Package: RooFitCore *
4  * @(#)root/roofitcore:$Id$
5  * Authors: *
6  * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7  * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8  * *
9  * Copyright (c) 2000-2005, Regents of the University of California *
10  * and Stanford University. All rights reserved. *
11  * *
12  * Redistribution and use in source and binary forms, *
13  * with or without modification, are permitted according to the terms *
14  * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15  *****************************************************************************/
16 
17 /**
18 \file RooNumIntConfig.cxx
19 \class RooNumIntConfig
20 \ingroup Roofitcore
21 
22 RooNumIntConfig holds the configuration parameters of the various
23 numeric integrators used by RooRealIntegral. RooRealIntegral and RooAbsPdf
24 use this class in the (normalization) integral configuration interface
25 **/
26 
27 #include "RooFit.h"
28 #include "Riostream.h"
29 
30 #include "RooNumIntConfig.h"
31 #include "RooArgSet.h"
32 #include "RooAbsIntegrator.h"
33 #include "RooNumIntFactory.h"
34 #include "RooMsgService.h"
35 
36 #include "TClass.h"
37 
38 
39 
40 using namespace std;
41 
42 ClassImp(RooNumIntConfig)
43 
44 
45 ////////////////////////////////////////////////////////////////////////////////
46 /// Return reference to instance of default numeric integrator configuration object
47 
48 RooNumIntConfig& RooNumIntConfig::defaultConfig()
49 {
50  static RooNumIntConfig theConfig;
51  static bool initStarted = false;
52 
53  if (!initStarted) {
54  // This is needed to break a deadlock. We need the RooNumIntFactory constructor
55  // to initialise us, but this constructor will call back to us again.
56  // Here, we ensure that we can return the instance to the factory constructor by
57  // flipping the bool, but we only return to the outside world when the factory
58  // is done constructing (i.e. we leave this block).
59  initStarted = true;
60  RooNumIntFactory::instance();
61  }
62 
63  return theConfig;
64 }
65 
66 
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 /// Constructor
70 
71 RooNumIntConfig::RooNumIntConfig() :
72  _epsAbs(1e-7),
73  _epsRel(1e-7),
74  _printEvalCounter(kFALSE),
75  _method1D("method1D","1D integration method"),
76  _method2D("method2D","2D integration method"),
77  _methodND("methodND","ND integration method"),
78  _method1DOpen("method1DOpen","1D integration method in open domain"),
79  _method2DOpen("method2DOpen","2D integration method in open domain"),
80  _methodNDOpen("methodNDOpen","ND integration method in open domain")
81 {
82  // Set all methods to undefined
83  // Defined methods will be registered by static initialization routines
84  // of the various numeric integrator engines
85  _method1D.defineType("N/A",0) ;
86  _method2D.defineType("N/A",0) ;
87  _methodND.defineType("N/A",0) ;
88  _method1DOpen.defineType("N/A",0) ;
89  _method2DOpen.defineType("N/A",0) ;
90  _methodNDOpen.defineType("N/A",0) ;
91 }
92 
93 
94 ////////////////////////////////////////////////////////////////////////////////
95 /// Destructor
96 
97 RooNumIntConfig::~RooNumIntConfig()
98 {
99  // Delete all configuration data
100  _configSets.Delete() ;
101 }
102 
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Copy constructor
106 
107 RooNumIntConfig::RooNumIntConfig(const RooNumIntConfig& other) :
108  TObject(other), RooPrintable(other),
109  _epsAbs(other._epsAbs),
110  _epsRel(other._epsRel),
111  _printEvalCounter(other._printEvalCounter),
112  _method1D(other._method1D),
113  _method2D(other._method2D),
114  _methodND(other._methodND),
115  _method1DOpen(other._method1DOpen),
116  _method2DOpen(other._method2DOpen),
117  _methodNDOpen(other._methodNDOpen)
118 {
119  // Clone all configuration dat
120  TIterator* iter = other._configSets.MakeIterator() ;
121  RooArgSet* set ;
122  while((set=(RooArgSet*)iter->Next())) {
123  RooArgSet* setCopy = (RooArgSet*) set->snapshot() ;
124  setCopy->setName(set->GetName()) ;
125  _configSets.Add(setCopy);
126  }
127  delete iter ;
128 }
129 
130 
131 ////////////////////////////////////////////////////////////////////////////////
132 /// Assignment operator from other RooNumIntConfig
133 
134 RooNumIntConfig& RooNumIntConfig::operator=(const RooNumIntConfig& other)
135 {
136  // Prevent self-assignment
137  if (&other==this) {
138  return *this ;
139  }
140 
141  // Copy common properties
142  _epsAbs = other._epsAbs ;
143  _epsRel = other._epsRel ;
144  _method1D.setIndex(other._method1D.getIndex()) ;
145  _method2D.setIndex(other._method2D.getIndex()) ;
146  _methodND.setIndex(other._methodND.getIndex()) ;
147  _method1DOpen.setIndex(other._method1DOpen.getIndex()) ;
148  _method2DOpen.setIndex(other._method2DOpen.getIndex()) ;
149  _methodNDOpen.setIndex(other._methodNDOpen.getIndex()) ;
150 
151  // Delete old integrator-specific configuration data
152  _configSets.Delete() ;
153 
154  // Copy new integrator-specific data
155  TIterator* iter = other._configSets.MakeIterator() ;
156  RooArgSet* set ;
157  while((set=(RooArgSet*)iter->Next())) {
158  RooArgSet* setCopy = (RooArgSet*) set->snapshot() ;
159  setCopy->setName(set->GetName()) ;
160  _configSets.Add(setCopy);
161  }
162  delete iter ;
163 
164  return *this ;
165 }
166 
167 
168 
169 ////////////////////////////////////////////////////////////////////////////////
170 /// Add a configuration section for a particular integrator. Integrator name and capabilities are
171 /// automatically determined from instance passed as 'proto'. The defaultConfig object is associated
172 /// as the default configuration for the integrator.
173 
174 Bool_t RooNumIntConfig::addConfigSection(const RooAbsIntegrator* proto, const RooArgSet& inDefaultConfig)
175 {
176  TString name = proto->IsA()->GetName() ;
177 
178  // Register integrator for appropriate dimensionalities
179  if (proto->canIntegrate1D()) {
180  _method1D.defineType(name) ;
181  if (proto->canIntegrateOpenEnded()) {
182  _method1DOpen.defineType(name) ;
183  }
184  }
185 
186  if (proto->canIntegrate2D()) {
187  _method2D.defineType(name) ;
188  if (proto->canIntegrateOpenEnded()) {
189  _method2DOpen.defineType(name) ;
190  }
191  }
192 
193  if (proto->canIntegrateND()) {
194  _methodND.defineType(name) ;
195  if (proto->canIntegrateOpenEnded()) {
196  _methodNDOpen.defineType(name) ;
197  }
198  }
199 
200  // Store default configuration parameters
201  RooArgSet* config = (RooArgSet*) inDefaultConfig.snapshot() ;
202  config->setName(name) ;
203  _configSets.Add(config) ;
204 
205  return kFALSE ;
206 }
207 
208 
209 
210 ////////////////////////////////////////////////////////////////////////////////
211 /// Return section with configuration parameters for integrator with given (class) name
212 
213 RooArgSet& RooNumIntConfig::getConfigSection(const char* name)
214 {
215  return const_cast<RooArgSet&>((const_cast<const RooNumIntConfig*>(this)->getConfigSection(name))) ;
216 }
217 
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 /// Retrieve configuration information specific to integrator with given name
221 
222 const RooArgSet& RooNumIntConfig::getConfigSection(const char* name) const
223 {
224  static RooArgSet dummy ;
225  RooArgSet* config = (RooArgSet*) _configSets.FindObject(name) ;
226  if (!config) {
227  oocoutE((TObject*)0,InputArguments) << "RooNumIntConfig::getIntegrator: ERROR: no configuration stored for integrator '" << name << "'" << endl ;
228  return dummy ;
229  }
230  return *config ;
231 }
232 
233 
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Set absolute convergence criteria (convergence if abs(Err)<newEpsAbs)
237 
238 void RooNumIntConfig::setEpsAbs(Double_t newEpsAbs)
239 {
240  if (newEpsAbs<0) {
241  oocoutE((TObject*)0,InputArguments) << "RooNumIntConfig::setEpsAbs: ERROR: target absolute precision must be greater or equal than zero" << endl ;
242  return ;
243  }
244  _epsAbs = newEpsAbs ;
245 }
246 
247 
248 RooPrintable::StyleOption RooNumIntConfig::defaultPrintStyle(Option_t* opt) const
249 {
250  if (!opt) {
251  return kStandard ;
252  }
253 
254  TString o(opt) ;
255  o.ToLower() ;
256 
257  if (o.Contains("v")) {
258  return kVerbose ;
259  }
260  return kStandard ;
261 }
262 
263 
264 
265 ////////////////////////////////////////////////////////////////////////////////
266 /// Set relative convergence criteria (convergence if abs(Err)/abs(Int)<newEpsRel)
267 
268 void RooNumIntConfig::setEpsRel(Double_t newEpsRel)
269 {
270  if (newEpsRel<0) {
271  oocoutE((TObject*)0,InputArguments) << "RooNumIntConfig::setEpsRel: ERROR: target absolute precision must be greater or equal than zero" << endl ;
272  return ;
273  }
274  _epsRel = newEpsRel ;
275 }
276 
277 
278 
279 ////////////////////////////////////////////////////////////////////////////////
280 /// Detailed printing interface
281 
282 void RooNumIntConfig::printMultiline(ostream &os, Int_t /*content*/, Bool_t verbose, TString indent) const
283 {
284  os << indent << "Requested precision: " << _epsAbs << " absolute, " << _epsRel << " relative" << endl << endl ;
285  if (_printEvalCounter) {
286  os << indent << "Printing of function evaluation counter for each integration enabled" << endl << endl ;
287  }
288 
289  os << indent << "1-D integration method: " << _method1D.getLabel() ;
290  if (_method1DOpen.getIndex()!=_method1D.getIndex()) {
291  os << " (" << _method1DOpen.getLabel() << " if open-ended)" << endl ;
292  } else {
293  os << endl ;
294  }
295  os << indent << "2-D integration method: " << _method2D.getLabel() ;
296  if (_method2DOpen.getIndex()!=_method2D.getIndex()) {
297  os << " (" << _method2DOpen.getLabel() << " if open-ended)" << endl ;
298  } else {
299  os << endl ;
300  }
301  os << indent << "N-D integration method: " << _methodND.getLabel() ;
302  if (_methodNDOpen.getIndex()!=_methodND.getIndex()) {
303  os << " (" << _methodNDOpen.getLabel() << " if open-ended)" << endl ;
304  } else {
305  os << endl ;
306  }
307 
308  if (verbose) {
309 
310  os << endl << "Available integration methods:" << endl << endl ;
311  TIterator* cIter = _configSets.MakeIterator() ;
312  RooArgSet* configSet ;
313  while ((configSet=(RooArgSet*)cIter->Next())) {
314 
315  os << indent << "*** " << configSet->GetName() << " ***" << endl ;
316  os << indent << "Capabilities: " ;
317  const RooAbsIntegrator* proto = RooNumIntFactory::instance().getProtoIntegrator(configSet->GetName()) ;
318  if (proto->canIntegrate1D()) os << "[1-D] " ;
319  if (proto->canIntegrate2D()) os << "[2-D] " ;
320  if (proto->canIntegrateND()) os << "[N-D] " ;
321  if (proto->canIntegrateOpenEnded()) os << "[OpenEnded] " ;
322  os << endl ;
323 
324  os << "Configuration: " << endl ;
325  configSet->printMultiline(os,kName|kValue) ;
326  //configSet->writeToStream(os,kFALSE) ;
327 
328  const char* depName = RooNumIntFactory::instance().getDepIntegratorName(configSet->GetName()) ;
329  if (strlen(depName)>0) {
330  os << indent << "(Depends on '" << depName << "')" << endl ;
331  }
332  os << endl ;
333 
334  }
335 
336  delete cIter ;
337  }
338 }