Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
RooNumGenFactory.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 RooNumGenFactory.cxx
19 \class RooNumGenFactory
20 \ingroup Roofitcore
21 
22 RooNumGenFactory is a factory to instantiate numeric integrators
23 from a given function binding and a given configuration. The factory
24 searches for a numeric integrator registered with the factory that
25 has the ability to perform the numeric integration. The choice of
26 method may depend on the number of dimensions integrated,
27 the nature of the integration limits (closed or open ended) and
28 the preference of the caller as encoded in the configuration object.
29 **/
30 
31 #include "TClass.h"
32 #include "Riostream.h"
33 
34 #include "RooFit.h"
35 
36 #include "RooNumGenFactory.h"
37 #include "RooArgSet.h"
38 #include "RooAbsFunc.h"
39 #include "RooNumGenConfig.h"
40 #include "RooNumber.h"
41 
42 #include "RooAcceptReject.h"
43 #include "RooFoamGenerator.h"
44 
45 
46 #include "RooMsgService.h"
47 
48 using namespace std ;
49 
50 ClassImp(RooNumGenFactory);
51 
52 
53 
54 ////////////////////////////////////////////////////////////////////////////////
55 /// Constructor. Register all known integrators by calling
56 /// their static registration functions
57 
58 RooNumGenFactory::RooNumGenFactory()
59 {
60  RooAcceptReject::registerSampler(*this) ;
61  RooFoamGenerator::registerSampler(*this) ;
62 
63  // Prepare default
64  RooNumGenConfig::defaultConfig().method1D(kFALSE,kFALSE).setLabel("RooFoamGenerator") ;
65  RooNumGenConfig::defaultConfig().method1D(kTRUE ,kFALSE).setLabel("RooAcceptReject") ;
66  RooNumGenConfig::defaultConfig().method1D(kFALSE,kTRUE ).setLabel("RooAcceptReject") ;
67  RooNumGenConfig::defaultConfig().method1D(kTRUE, kTRUE ).setLabel("RooAcceptReject") ;
68 
69  RooNumGenConfig::defaultConfig().method2D(kFALSE,kFALSE).setLabel("RooFoamGenerator") ;
70  RooNumGenConfig::defaultConfig().method2D(kTRUE ,kFALSE).setLabel("RooAcceptReject") ;
71  RooNumGenConfig::defaultConfig().method2D(kFALSE,kTRUE ).setLabel("RooAcceptReject") ;
72  RooNumGenConfig::defaultConfig().method2D(kTRUE, kTRUE ).setLabel("RooAcceptReject") ;
73 
74  RooNumGenConfig::defaultConfig().methodND(kFALSE,kFALSE).setLabel("RooFoamGenerator") ;
75  RooNumGenConfig::defaultConfig().methodND(kTRUE ,kFALSE).setLabel("RooAcceptReject") ;
76  RooNumGenConfig::defaultConfig().methodND(kFALSE,kTRUE ).setLabel("RooAcceptReject") ;
77  RooNumGenConfig::defaultConfig().methodND(kTRUE, kTRUE ).setLabel("RooAcceptReject") ;
78 
79 }
80 
81 
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 /// Destructor
85 
86 RooNumGenFactory::~RooNumGenFactory()
87 {
88  std::map<std::string,RooAbsNumGenerator*>::iterator iter = _map.begin() ;
89  while (iter != _map.end()) {
90  delete iter->second ;
91  ++iter ;
92  }
93 }
94 
95 
96 ////////////////////////////////////////////////////////////////////////////////
97 /// Copy constructor
98 
99 RooNumGenFactory::RooNumGenFactory(const RooNumGenFactory& other) : TObject(other)
100 {
101 }
102 
103 
104 
105 ////////////////////////////////////////////////////////////////////////////////
106 /// Static method returning reference to singleton instance of factory
107 
108 RooNumGenFactory& RooNumGenFactory::instance()
109 {
110  static RooNumGenFactory instance;
111  return instance;
112 }
113 
114 
115 ////////////////////////////////////////////////////////////////////////////////
116 /// Method accepting registration of a prototype numeric integrator along with a RooArgSet of its
117 /// default configuration options and an optional list of names of other numeric integrators
118 /// on which this integrator depends. Returns true if integrator was previously registered
119 
120 Bool_t RooNumGenFactory::storeProtoSampler(RooAbsNumGenerator* proto, const RooArgSet& defConfig)
121 {
122  TString name = proto->IsA()->GetName() ;
123 
124  if (getProtoSampler(name)) {
125  //cout << "RooNumGenFactory::storeSampler() ERROR: integrator '" << name << "' already registered" << endl ;
126  return kTRUE ;
127  }
128 
129  // Add to factory
130  _map[name.Data()] = proto ;
131 
132  // Add default config to master config
133  RooNumGenConfig::defaultConfig().addConfigSection(proto,defConfig) ;
134 
135  return kFALSE ;
136 }
137 
138 
139 
140 ////////////////////////////////////////////////////////////////////////////////
141 /// Return prototype integrator with given (class) name
142 
143 const RooAbsNumGenerator* RooNumGenFactory::getProtoSampler(const char* name)
144 {
145  if (_map.count(name)==0) {
146  return 0 ;
147  }
148 
149  return _map[name] ;
150 }
151 
152 
153 
154 ////////////////////////////////////////////////////////////////////////////////
155 /// Construct a numeric integrator instance that operates on function 'func' and is configured
156 /// with 'config'. If ndimPreset is greater than zero that number is taken as the dimensionality
157 /// of the integration, otherwise it is queried from 'func'. This function iterators over list
158 /// of available prototype integrators and returns an clone attached to the given function of
159 /// the first class that matches the specifications of the requested integration considering
160 /// the number of dimensions, the nature of the limits (open ended vs closed) and the user
161 /// preference stated in 'config'
162 
163 RooAbsNumGenerator* RooNumGenFactory::createSampler(RooAbsReal& func, const RooArgSet& genVars, const RooArgSet& condVars, const RooNumGenConfig& config, Bool_t verbose, RooAbsReal* maxFuncVal)
164 {
165  // Find method defined configuration
166  Int_t ndim = genVars.getSize() ;
167  Bool_t cond = (condVars.getSize() > 0) ? kTRUE : kFALSE ;
168 
169  Bool_t hasCat(kFALSE) ;
170  TIterator* iter = genVars.createIterator() ;
171  RooAbsArg* arg ;
172  while ((arg=(RooAbsArg*)iter->Next())) {
173  if (arg->IsA()==RooCategory::Class()) {
174  hasCat=kTRUE ;
175  break ;
176  }
177  }
178  delete iter ;
179 
180 
181  TString method ;
182  switch(ndim) {
183  case 1:
184  method = config.method1D(cond,hasCat).getLabel() ;
185  break ;
186 
187  case 2:
188  method = config.method2D(cond,hasCat).getLabel() ;
189  break ;
190 
191  default:
192  method = config.methodND(cond,hasCat).getLabel() ;
193  break ;
194  }
195 
196  // Check that a method was defined for this case
197  if (!method.CompareTo("N/A")) {
198  oocoutE((TObject*)0,Integration) << "RooNumGenFactory::createSampler: No sampler method has been defined for "
199  << (cond?"a conditional ":"a ") << ndim << "-dimensional p.d.f" << endl ;
200  return 0 ;
201  }
202 
203  // Retrieve proto integrator and return clone configured for the requested integration task
204  const RooAbsNumGenerator* proto = getProtoSampler(method) ;
205  RooAbsNumGenerator* engine = proto->clone(func,genVars,condVars,config,verbose,maxFuncVal) ;
206  return engine ;
207 }