RooAbsNumGenerator.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAbsNumGenerator.cxx 34064 2010-06-22 15:05:19Z 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 // Class RooAbsNumGenerator is the abstract base class for MC event generator
00021 // implementations like RooAcceptReject and RooFoam
00022 // END_HTML
00023 //
00024 
00025 
00026 #include "RooFit.h"
00027 #include "Riostream.h"
00028 
00029 #include "RooAbsNumGenerator.h"
00030 #include "RooAbsReal.h"
00031 #include "RooCategory.h"
00032 #include "RooRealVar.h"
00033 #include "RooDataSet.h"
00034 #include "RooRandom.h"
00035 #include "RooErrorHandler.h"
00036 
00037 #include "TString.h"
00038 #include "TIterator.h"
00039 #include "RooMsgService.h"
00040 #include "TClass.h"
00041 #include "RooRealBinding.h"
00042 
00043 #include <assert.h>
00044 
00045 ClassImp(RooAbsNumGenerator)
00046   ;
00047 
00048 
00049 //_____________________________________________________________________________
00050 RooAbsNumGenerator::RooAbsNumGenerator(const RooAbsReal &func, const RooArgSet &genVars, Bool_t verbose, const RooAbsReal* maxFuncVal) :
00051   TNamed(func), _cloneSet(0), _funcClone(0), _funcMaxVal(maxFuncVal), _verbose(verbose), _funcValStore(0), _funcValPtr(0), _cache(0)
00052 {
00053   // Initialize an accept-reject generator for the specified distribution function,
00054   // which must be non-negative but does not need to be normalized over the
00055   // variables to be generated, genVars. The function and its dependents are
00056   // cloned and so will not be disturbed during the generation process.
00057 
00058   // Clone the function and all nodes that it depends on so that this generator
00059   // is independent of any existing objects.
00060   RooArgSet nodes(func,func.GetName());
00061   _cloneSet= (RooArgSet*) nodes.snapshot(kTRUE);
00062   if (!_cloneSet) {
00063     coutE(Generation) << "RooAbsNumGenerator::RooAbsNumGenerator(" << GetName() << ") Couldn't deep-clone function, abort," << endl ;
00064     RooErrorHandler::softAbort() ;
00065   }
00066 
00067   // Find the clone in the snapshot list
00068   _funcClone = (RooAbsReal*)_cloneSet->find(func.GetName());
00069 
00070 
00071   // Check that each argument is fundamental, and separate them into
00072   // sets of categories and reals. Check that the area of the generating
00073   // space is finite.
00074   _isValid= kTRUE;
00075   TIterator *iterator= genVars.createIterator();
00076   const RooAbsArg *found = 0;
00077   const RooAbsArg *arg   = 0;
00078   while((arg= (const RooAbsArg*)iterator->Next())) {
00079     if(!arg->isFundamental()) {
00080       coutE(Generation) << fName << "::" << ClassName() << ": cannot generate values for derived \""
00081                         << arg->GetName() << "\"" << endl;
00082       _isValid= kFALSE;
00083       continue;
00084     }
00085     // look for this argument in the generating function's dependents
00086     found= (const RooAbsArg*)_cloneSet->find(arg->GetName());
00087     if(found) {
00088       arg= found;
00089     } else {
00090       // clone any variables we generate that we haven't cloned already
00091       arg= _cloneSet->addClone(*arg);
00092     }
00093     assert(0 != arg);
00094     // is this argument a category or a real?
00095     const RooCategory *catVar= dynamic_cast<const RooCategory*>(arg);
00096     const RooRealVar *realVar= dynamic_cast<const RooRealVar*>(arg);
00097     if(0 != catVar) {
00098       _catVars.add(*catVar);
00099     }
00100     else if(0 != realVar) {
00101       if(realVar->hasMin() && realVar->hasMax()) {
00102         _realVars.add(*realVar);
00103       }
00104       else {
00105         coutE(Generation) << fName << "::" << ClassName() << ": cannot generate values for \""
00106                           << realVar->GetName() << "\" with unbound range" << endl;
00107         _isValid= kFALSE;
00108       }
00109     }
00110     else {
00111       coutE(Generation) << fName << "::" << ClassName() << ": cannot generate values for \""
00112                         << arg->GetName() << "\" with unexpected type" << endl;
00113       _isValid= kFALSE;
00114     }
00115   }
00116   delete iterator;
00117   if(!_isValid) {
00118     coutE(Generation) << fName << "::" << ClassName() << ": constructor failed with errors" << endl;
00119     return;
00120   }
00121 
00122   // create a fundamental type for storing function values
00123   _funcValStore= dynamic_cast<RooRealVar*>(_funcClone->createFundamental());
00124   assert(0 != _funcValStore);
00125 
00126   // create a new dataset to cache trial events and function values
00127   RooArgSet cacheArgs(_catVars);
00128   cacheArgs.add(_realVars);
00129   cacheArgs.add(*_funcValStore);
00130   _cache= new RooDataSet("cache","Accept-Reject Event Cache",cacheArgs);
00131   assert(0 != _cache);
00132 
00133   // attach our function clone to the cache dataset
00134   const RooArgSet *cacheVars= _cache->get();
00135   assert(0 != cacheVars);
00136   _funcClone->recursiveRedirectServers(*cacheVars,kFALSE);
00137 
00138   // update ours sets of category and real args to refer to the cache dataset
00139   const RooArgSet *dataVars= _cache->get();
00140   _catVars.replace(*dataVars);
00141   _realVars.replace(*dataVars);
00142 
00143   // find the function value in the dataset
00144   _funcValPtr= (RooRealVar*)dataVars->find(_funcValStore->GetName());
00145 
00146 }
00147 
00148 
00149 
00150 //_____________________________________________________________________________
00151 RooAbsNumGenerator::~RooAbsNumGenerator() 
00152 {
00153   // Destructor
00154   delete _cloneSet;
00155   delete _cache ;
00156   delete _funcValStore ;
00157 }
00158 
00159 
00160 
00161 //_____________________________________________________________________________
00162 void RooAbsNumGenerator::attachParameters(const RooArgSet& vars) 
00163 {
00164   // Reattach original parameters to function clone
00165 
00166   RooArgSet newParams(vars) ;
00167   newParams.remove(*_cache->get(),kTRUE,kTRUE) ;
00168   _funcClone->recursiveRedirectServers(newParams) ;
00169 }
00170 
00171 
00172 
00173 
00174 
00175 //_____________________________________________________________________________
00176 void RooAbsNumGenerator::printName(ostream& os) const 
00177 {
00178   // Print name of the generator
00179 
00180   os << GetName() ;
00181 }
00182 
00183 
00184 
00185 //_____________________________________________________________________________
00186 void RooAbsNumGenerator::printTitle(ostream& os) const 
00187 {
00188   // Print the title of the generator
00189 
00190   os << GetTitle() ;
00191 }
00192 
00193 
00194 
00195 //_____________________________________________________________________________
00196 void RooAbsNumGenerator::printClassName(ostream& os) const 
00197 {
00198   // Print the class name of the generator
00199 
00200   os << IsA()->GetName() ;
00201 }
00202 
00203 
00204 
00205 //_____________________________________________________________________________
00206 void RooAbsNumGenerator::printArgs(ostream& os) const 
00207 {
00208   // Print the arguments of the generator
00209 
00210   os << "[ function=" << _funcClone->GetName() << " catobs=" << _catVars << " realobs=" << _realVars << " ]" ;
00211 }
00212 

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