/***************************************************************************** * Project: RooFit * * Package: RooFitCore * * @(#)root/roofitcore:$Id$ * Authors: * * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu * * DK, David Kirkby, UC Irvine, dkirkby@uci.edu * * * * Copyright (c) 2000-2005, Regents of the University of California * * and Stanford University. All rights reserved. * * * * Redistribution and use in source and binary forms, * * with or without modification, are permitted according to the terms * * listed in LICENSE (http://roofit.sourceforge.net/license.txt) * *****************************************************************************/ ////////////////////////////////////////////////////////////////////////////// // // BEGIN_HTML // RooNumIntConfig holds the configuration parameters of the various // numeric integrators used by RooRealIntegral. RooRealIntegral and RooAbsPdf // use this class in the (normalization) integral configuration interface // END_HTML // #include "RooFit.h" #include "Riostream.h" #include "RooNumIntConfig.h" #include "RooArgSet.h" #include "RooAbsIntegrator.h" #include "RooNumIntFactory.h" #include "RooMsgService.h" #include "TClass.h" using namespace std; ClassImp(RooNumIntConfig) ; RooNumIntConfig* RooNumIntConfig::_default = 0 ; //////////////////////////////////////////////////////////////////////////////// /// Function called by atexit() handler installed by RooSentinel to /// cleanup global objects at end of job void RooNumIntConfig::cleanup() { if (_default) { delete _default ; _default = 0 ; } } //////////////////////////////////////////////////////////////////////////////// /// Return reference to instance of default numeric integrator configuration object RooNumIntConfig& RooNumIntConfig::defaultConfig() { // Instantiate object if it doesn't exist yet if (_default==0) { _default = new RooNumIntConfig ; RooNumIntFactory::instance() ; } return *_default ; } //////////////////////////////////////////////////////////////////////////////// /// Constructor RooNumIntConfig::RooNumIntConfig() : _epsAbs(1e-7), _epsRel(1e-7), _printEvalCounter(kFALSE), _method1D("method1D","1D integration method"), _method2D("method2D","2D integration method"), _methodND("methodND","ND integration method"), _method1DOpen("method1DOpen","1D integration method in open domain"), _method2DOpen("method2DOpen","2D integration method in open domain"), _methodNDOpen("methodNDOpen","ND integration method in open domain") { // Set all methods to undefined // Defined methods will be registered by static initialization routines // of the various numeric integrator engines _method1D.defineType("N/A",0) ; _method2D.defineType("N/A",0) ; _methodND.defineType("N/A",0) ; _method1DOpen.defineType("N/A",0) ; _method2DOpen.defineType("N/A",0) ; _methodNDOpen.defineType("N/A",0) ; } //////////////////////////////////////////////////////////////////////////////// /// Destructor RooNumIntConfig::~RooNumIntConfig() { // Delete all configuration data _configSets.Delete() ; } //////////////////////////////////////////////////////////////////////////////// /// Copy constructor RooNumIntConfig::RooNumIntConfig(const RooNumIntConfig& other) : TObject(other), RooPrintable(other), _epsAbs(other._epsAbs), _epsRel(other._epsRel), _printEvalCounter(other._printEvalCounter), _method1D(other._method1D), _method2D(other._method2D), _methodND(other._methodND), _method1DOpen(other._method1DOpen), _method2DOpen(other._method2DOpen), _methodNDOpen(other._methodNDOpen) { // Clone all configuration dat TIterator* iter = other._configSets.MakeIterator() ; RooArgSet* set ; while((set=(RooArgSet*)iter->Next())) { RooArgSet* setCopy = (RooArgSet*) set->snapshot() ; setCopy->setName(set->GetName()) ; _configSets.Add(setCopy); } delete iter ; } //////////////////////////////////////////////////////////////////////////////// /// Assignment operator from other RooNumIntConfig RooNumIntConfig& RooNumIntConfig::operator=(const RooNumIntConfig& other) { // Prevent self-assignment if (&other==this) { return *this ; } // Copy common properties _epsAbs = other._epsAbs ; _epsRel = other._epsRel ; _method1D.setIndex(other._method1D.getIndex()) ; _method2D.setIndex(other._method2D.getIndex()) ; _methodND.setIndex(other._methodND.getIndex()) ; _method1DOpen.setIndex(other._method1DOpen.getIndex()) ; _method2DOpen.setIndex(other._method2DOpen.getIndex()) ; _methodNDOpen.setIndex(other._methodNDOpen.getIndex()) ; // Delete old integrator-specific configuration data _configSets.Delete() ; // Copy new integrator-specific data TIterator* iter = other._configSets.MakeIterator() ; RooArgSet* set ; while((set=(RooArgSet*)iter->Next())) { RooArgSet* setCopy = (RooArgSet*) set->snapshot() ; setCopy->setName(set->GetName()) ; _configSets.Add(setCopy); } delete iter ; return *this ; } //////////////////////////////////////////////////////////////////////////////// /// Add a configuration section for a particular integrator. Integrator name and capabilities are /// automatically determined from instance passed as 'proto'. The defaultConfig object is associated /// as the default configuration for the integrator. Bool_t RooNumIntConfig::addConfigSection(const RooAbsIntegrator* proto, const RooArgSet& inDefaultConfig) { TString name = proto->IsA()->GetName() ; // Register integrator for appropriate dimensionalities if (proto->canIntegrate1D()) { _method1D.defineType(name) ; if (proto->canIntegrateOpenEnded()) { _method1DOpen.defineType(name) ; } } if (proto->canIntegrate2D()) { _method2D.defineType(name) ; if (proto->canIntegrateOpenEnded()) { _method2DOpen.defineType(name) ; } } if (proto->canIntegrateND()) { _methodND.defineType(name) ; if (proto->canIntegrateOpenEnded()) { _methodNDOpen.defineType(name) ; } } // Store default configuration parameters RooArgSet* config = (RooArgSet*) inDefaultConfig.snapshot() ; config->setName(name) ; _configSets.Add(config) ; return kFALSE ; } //////////////////////////////////////////////////////////////////////////////// /// Return section with configuration parameters for integrator with given (class) name RooArgSet& RooNumIntConfig::getConfigSection(const char* name) { return const_cast((const_cast(this)->getConfigSection(name))) ; } //////////////////////////////////////////////////////////////////////////////// /// Retrieve configuration information specific to integrator with given name const RooArgSet& RooNumIntConfig::getConfigSection(const char* name) const { static RooArgSet dummy ; RooArgSet* config = (RooArgSet*) _configSets.FindObject(name) ; if (!config) { oocoutE((TObject*)0,InputArguments) << "RooNumIntConfig::getIntegrator: ERROR: no configuration stored for integrator '" << name << "'" << endl ; return dummy ; } return *config ; } //////////////////////////////////////////////////////////////////////////////// /// Set absolute convergence criteria (convergence if abs(Err)Next())) { os << indent << "*** " << configSet->GetName() << " ***" << endl ; os << indent << "Capabilities: " ; const RooAbsIntegrator* proto = RooNumIntFactory::instance().getProtoIntegrator(configSet->GetName()) ; if (proto->canIntegrate1D()) os << "[1-D] " ; if (proto->canIntegrate2D()) os << "[2-D] " ; if (proto->canIntegrateND()) os << "[N-D] " ; if (proto->canIntegrateOpenEnded()) os << "[OpenEnded] " ; os << endl ; os << "Configuration: " << endl ; configSet->printMultiline(os,kName|kValue) ; //configSet->writeToStream(os,kFALSE) ; const char* depName = RooNumIntFactory::instance().getDepIntegratorName(configSet->GetName()) ; if (strlen(depName)>0) { os << indent << "(Depends on '" << depName << "')" << endl ; } os << endl ; } delete cIter ; } }