RooNumIntFactory.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooNumIntFactory.cxx 37372 2010-12-07 16:35:49Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooNumIntFactory is a factory to instantiate numeric integrators
00021 // from a given function binding and a given configuration. The factory
00022 // searches for a numeric integrator registered with the factory that
00023 // has the ability to perform the numeric integration. The choice of
00024 // method may depend on the number of dimensions integrated,
00025 // the nature of the integration limits (closed or open ended) and
00026 // the preference of the caller as encoded in the configuration object.
00027 // END_HTML
00028 //
00029 
00030 #include "TClass.h"
00031 #include "Riostream.h"
00032 
00033 #include "RooFit.h"
00034 
00035 #include "RooNumIntFactory.h"
00036 #include "RooArgSet.h"
00037 #include "RooAbsFunc.h"
00038 #include "RooNumIntConfig.h"
00039 #include "RooNumber.h"
00040 
00041 #include "RooIntegrator1D.h"
00042 #include "RooIntegrator2D.h"
00043 #include "RooSegmentedIntegrator1D.h"
00044 #include "RooSegmentedIntegrator2D.h"
00045 #include "RooImproperIntegrator1D.h"
00046 #include "RooMCIntegrator.h"
00047 #include "RooGaussKronrodIntegrator1D.h"
00048 #include "RooAdaptiveGaussKronrodIntegrator1D.h"
00049 #include "RooAdaptiveIntegratorND.h"
00050 #include "RooSentinel.h"
00051 
00052 #include "RooMsgService.h"
00053 
00054 using namespace std ;
00055 
00056 ClassImp(RooNumIntFactory)
00057 ;
00058 
00059 RooNumIntFactory* RooNumIntFactory::_instance = 0 ;
00060 
00061 
00062 
00063 //_____________________________________________________________________________
00064 RooNumIntFactory::RooNumIntFactory()
00065 {
00066   // Constructor. Register all known integrators by calling
00067   // their static registration functions
00068 
00069   _instance = this ;
00070 
00071   RooIntegrator1D::registerIntegrator(*this) ;
00072   RooIntegrator2D::registerIntegrator(*this) ;
00073   RooSegmentedIntegrator1D::registerIntegrator(*this) ;
00074   RooSegmentedIntegrator2D::registerIntegrator(*this) ;
00075   RooImproperIntegrator1D::registerIntegrator(*this) ;
00076   RooMCIntegrator::registerIntegrator(*this) ;
00077   RooAdaptiveGaussKronrodIntegrator1D::registerIntegrator(*this) ;
00078   RooGaussKronrodIntegrator1D::registerIntegrator(*this) ;  
00079   RooAdaptiveIntegratorND::registerIntegrator(*this) ;
00080 
00081   RooNumIntConfig::defaultConfig().method1D().setLabel("RooIntegrator1D") ;
00082   RooNumIntConfig::defaultConfig().method1DOpen().setLabel("RooImproperIntegrator1D") ;
00083   RooNumIntConfig::defaultConfig().method2D().setLabel("RooAdaptiveIntegratorND") ;
00084   RooNumIntConfig::defaultConfig().methodND().setLabel("RooAdaptiveIntegratorND") ;
00085   
00086 }
00087 
00088 
00089 
00090 //_____________________________________________________________________________
00091 RooNumIntFactory::~RooNumIntFactory()
00092 {
00093   // Destructor
00094 
00095   std::map<std::string,pair<RooAbsIntegrator*,std::string> >::iterator iter = _map.begin() ;
00096   while (iter != _map.end()) {
00097     delete iter->second.first ;
00098     ++iter ;
00099   }  
00100 }
00101 
00102 
00103 //_____________________________________________________________________________
00104 RooNumIntFactory::RooNumIntFactory(const RooNumIntFactory& other) : TObject(other)
00105 {
00106   // Copy constructor
00107 }
00108 
00109 
00110 
00111 //_____________________________________________________________________________
00112 RooNumIntFactory& RooNumIntFactory::instance()
00113 {
00114   // Static method returning reference to singleton instance of factory
00115 
00116   if (_instance==0) {
00117     new RooNumIntFactory ;
00118     RooSentinel::activate() ;
00119   } 
00120   return *_instance ;
00121 }
00122 
00123 
00124 //_____________________________________________________________________________
00125 void RooNumIntFactory::cleanup()
00126 {
00127   // Cleanup routine called by atexit() handler installed by RooSentinel
00128 
00129   if (_instance) {
00130     delete _instance ;
00131     _instance = 0 ;
00132   }
00133 }
00134 
00135 
00136 
00137 //_____________________________________________________________________________
00138 Bool_t RooNumIntFactory::storeProtoIntegrator(RooAbsIntegrator* proto, const RooArgSet& defConfig, const char* depName) 
00139 {
00140   // Method accepting registration of a prototype numeric integrator along with a RooArgSet of its
00141   // default configuration options and an optional list of names of other numeric integrators
00142   // on which this integrator depends. Returns true if integrator was previously registered
00143 
00144   TString name = proto->IsA()->GetName() ;
00145 
00146   if (getProtoIntegrator(name)) {
00147     //cout << "RooNumIntFactory::storeIntegrator() ERROR: integrator '" << name << "' already registered" << endl ;
00148     return kTRUE ;
00149   }
00150 
00151   // Add to factory 
00152   _map[name.Data()] = make_pair<RooAbsIntegrator*,std::string>(proto,depName) ;
00153 
00154   // Add default config to master config
00155   RooNumIntConfig::defaultConfig().addConfigSection(proto,defConfig) ;
00156   
00157   return kFALSE ;
00158 }
00159 
00160 
00161 
00162 //_____________________________________________________________________________
00163 const RooAbsIntegrator* RooNumIntFactory::getProtoIntegrator(const char* name) 
00164 {
00165   // Return prototype integrator with given (class) name
00166 
00167   if (_map.count(name)==0) {
00168     return 0 ;
00169   } 
00170   
00171   return _map[name].first ;
00172 }
00173 
00174 
00175 
00176 //_____________________________________________________________________________
00177 const char* RooNumIntFactory::getDepIntegratorName(const char* name) 
00178 {
00179   // Get list of class names of integrators needed by integrator named 'name'
00180   if (_map.count(name)==0) {
00181     return 0 ;
00182   }
00183 
00184   return _map[name].second.c_str() ;
00185 }
00186 
00187 
00188 
00189 //_____________________________________________________________________________
00190 RooAbsIntegrator* RooNumIntFactory::createIntegrator(RooAbsFunc& func, const RooNumIntConfig& config, Int_t ndimPreset) 
00191 {
00192   // Construct a numeric integrator instance that operates on function 'func' and is configured
00193   // with 'config'. If ndimPreset is greater than zero that number is taken as the dimensionality
00194   // of the integration, otherwise it is queried from 'func'. This function iterators over list
00195   // of available prototype integrators and returns an clone attached to the given function of
00196   // the first class that matches the specifications of the requested integration considering
00197   // the number of dimensions, the nature of the limits (open ended vs closed) and the user
00198   // preference stated in 'config'
00199 
00200   // First determine dimensionality and domain of integrand  
00201   Int_t ndim = ndimPreset>0 ? ndimPreset : ((Int_t)func.getDimension()) ;
00202 
00203   Bool_t openEnded = kFALSE ;
00204   Int_t i ;
00205   for (i=0 ; i<ndim ; i++) {
00206     if(RooNumber::isInfinite(func.getMinLimit(i)) ||
00207        RooNumber::isInfinite(func.getMaxLimit(i))) {
00208       openEnded = kTRUE ;
00209     }
00210   }
00211 
00212   // Find method defined configuration
00213   TString method ;
00214   switch(ndim) {
00215   case 1:
00216     method = openEnded ? config.method1DOpen().getLabel() : config.method1D().getLabel() ;
00217     break ;
00218 
00219   case 2:
00220     method = openEnded ? config.method2DOpen().getLabel() : config.method2D().getLabel() ;
00221     break ;
00222 
00223   default:
00224     method = openEnded ? config.methodNDOpen().getLabel() : config.methodND().getLabel() ;
00225     break ;
00226   }
00227 
00228   // Check that a method was defined for this case
00229   if (!method.CompareTo("N/A")) {
00230     oocoutE((TObject*)0,Integration) << "RooNumIntFactory::createIntegrator: No integration method has been defined for " 
00231                                      << (openEnded?"an open ended ":"a ") << ndim << "-dimensional integral" << endl ;
00232     return 0 ;    
00233   }
00234 
00235   // Retrieve proto integrator and return clone configured for the requested integration task
00236   const RooAbsIntegrator* proto = getProtoIntegrator(method) ;  
00237   RooAbsIntegrator* engine =  proto->clone(func,config) ;
00238   if (config.printEvalCounter()) {
00239     engine->setPrintEvalCounter(kTRUE) ;
00240   }
00241   return engine ;
00242 }

Generated on Tue Jul 5 15:06:53 2011 for ROOT_528-00b_version by  doxygen 1.5.1