RooAddition.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooAddition.cxx 37157 2010-12-01 19:14:59Z 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 // RooAddition calculates the sum of a set of RooAbsReal terms, or
00021 // when constructed with two sets, it sums the product of the terms
00022 // in the two sets. This class does not (yet) do any smart handling of integrals, 
00023 // i.e. all integrals of the product are handled numerically
00024 // END_HTML
00025 //
00026 
00027 
00028 #include "RooFit.h"
00029 
00030 #include "Riostream.h"
00031 #include <math.h>
00032 #include <memory>
00033 
00034 #include "RooAddition.h"
00035 #include "RooProduct.h"
00036 #include "RooAbsReal.h"
00037 #include "RooErrorHandler.h"
00038 #include "RooArgSet.h"
00039 #include "RooNameReg.h"
00040 #include "RooNLLVar.h"
00041 #include "RooChi2Var.h"
00042 #include "RooMsgService.h"
00043 
00044 ClassImp(RooAddition)
00045 ;
00046 
00047 
00048 //_____________________________________________________________________________
00049 RooAddition::RooAddition()
00050   : _setIter( _set.createIterator() )
00051 {
00052 }
00053 
00054 
00055 
00056 //_____________________________________________________________________________
00057 RooAddition::RooAddition(const char* name, const char* title, const RooArgSet& sumSet, Bool_t takeOwnership) 
00058   : RooAbsReal(name, title)
00059   , _set("!set","set of components",this)
00060   , _setIter( _set.createIterator() ) // yes, _setIter is defined _after_ _set ;-)
00061   , _cacheMgr(this,10)
00062 {
00063   // Constructor with a single set of RooAbsReals. The value of the function will be
00064   // the sum of the values in sumSet. If takeOwnership is true the RooAddition object
00065   // will take ownership of the arguments in sumSet
00066 
00067   std::auto_ptr<TIterator> inputIter( sumSet.createIterator() );
00068   RooAbsArg* comp ;
00069   while((comp = (RooAbsArg*)inputIter->Next())) {
00070     if (!dynamic_cast<RooAbsReal*>(comp)) {
00071       coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp->GetName() 
00072                             << " is not of type RooAbsReal" << endl ;
00073       RooErrorHandler::softAbort() ;
00074     }
00075     _set.add(*comp) ;
00076     if (takeOwnership) _ownedList.addOwned(*comp) ;
00077   }
00078 
00079 }
00080 
00081 
00082 
00083 //_____________________________________________________________________________
00084 RooAddition::RooAddition(const char* name, const char* title, const RooArgList& sumSet1, const RooArgList& sumSet2, Bool_t takeOwnership) 
00085     : RooAbsReal(name, title)
00086     , _set("!set","set of components",this)
00087     , _setIter( _set.createIterator() ) // yes, _setIter is defined _after_ _set ;-)
00088     , _cacheMgr(this,10)
00089 {
00090   // Constructor with two set of RooAbsReals. The value of the function will be
00091   //
00092   //  A = sum_i sumSet1(i)*sumSet2(i) 
00093   //
00094   // If takeOwnership is true the RooAddition object will take ownership of the arguments in sumSet
00095 
00096   if (sumSet1.getSize() != sumSet2.getSize()) {
00097     coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: input lists should be of equal length" << endl ;
00098     RooErrorHandler::softAbort() ;    
00099   }
00100 
00101   std::auto_ptr<TIterator> inputIter1( sumSet1.createIterator() );
00102   std::auto_ptr<TIterator> inputIter2( sumSet2.createIterator() );
00103   RooAbsArg *comp1(0),*comp2(0) ;
00104   while((comp1 = (RooAbsArg*)inputIter1->Next())) {
00105     if (!dynamic_cast<RooAbsReal*>(comp1)) {
00106       coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp1->GetName() 
00107                             << " in first list is not of type RooAbsReal" << endl ;
00108       RooErrorHandler::softAbort() ;
00109     }
00110     comp2 = (RooAbsArg*)inputIter2->Next();
00111     if (!dynamic_cast<RooAbsReal*>(comp2)) {
00112       coutE(InputArguments) << "RooAddition::ctor(" << GetName() << ") ERROR: component " << comp2->GetName() 
00113                             << " in first list is not of type RooAbsReal" << endl ;
00114       RooErrorHandler::softAbort() ;
00115     }
00116     // TODO: add flag to RooProduct c'tor to make it assume ownership...
00117     TString _name(name);
00118     _name.Append( "_[");
00119     _name.Append(comp1->GetName());
00120     _name.Append( "_x_");
00121     _name.Append(comp2->GetName());
00122     _name.Append( "]");
00123     RooProduct  *prod = new RooProduct( _name, _name , RooArgSet(*comp1, *comp2) /*, takeOwnership */ ) ;
00124     _set.add(*prod);
00125     _ownedList.addOwned(*prod) ;
00126     if (takeOwnership) {
00127         _ownedList.addOwned(*comp1) ;
00128         _ownedList.addOwned(*comp2) ;
00129     }
00130   }
00131 }
00132 
00133 
00134 
00135 //_____________________________________________________________________________
00136 RooAddition::RooAddition(const RooAddition& other, const char* name) 
00137     : RooAbsReal(other, name)
00138     , _set("!set",this,other._set)
00139     , _setIter( _set.createIterator() ) // yes, _setIter is defined _after_ _set ;-)
00140     , _cacheMgr(other._cacheMgr,this)
00141 {
00142   // Copy constructor
00143   
00144   // Member _ownedList is intentionally not copy-constructed -- ownership is not transferred
00145 }
00146 
00147 
00148 //_____________________________________________________________________________
00149 RooAddition::~RooAddition() 
00150 { // Destructor
00151   delete _setIter ;
00152 }
00153 
00154 //_____________________________________________________________________________
00155 Double_t RooAddition::evaluate() const 
00156 {
00157   // Calculate and return current value of self
00158   Double_t sum(0);
00159   const RooArgSet* nset = _set.nset() ;
00160 
00161   _setIter->Reset() ;
00162   RooAbsReal* comp ;
00163   while((comp=(RooAbsReal*)_setIter->Next())) {
00164       sum += comp->getVal(nset) ;
00165   }
00166   return sum ;
00167 }
00168 
00169 //_____________________________________________________________________________
00170 Double_t RooAddition::defaultErrorLevel() const 
00171 {
00172   // Return the default error level for MINUIT error analysis
00173   // If the addition contains one or more RooNLLVars and 
00174   // no RooChi2Vars, return the defaultErrorLevel() of
00175   // RooNLLVar. If the addition contains one ore more RooChi2Vars
00176   // and no RooNLLVars, return the defaultErrorLevel() of
00177   // RooChi2Var. If the addition contains neither or both
00178   // issue a warning message and return a value of 1
00179 
00180   RooAbsReal* nllArg(0) ;
00181   RooAbsReal* chi2Arg(0) ;
00182 
00183   RooAbsArg* arg ;
00184 
00185   _setIter->Reset() ;
00186   while((arg=(RooAbsArg*)_setIter->Next())) {
00187     if (dynamic_cast<RooNLLVar*>(arg)) {
00188       nllArg = (RooAbsReal*)arg ;
00189     }
00190     if (dynamic_cast<RooChi2Var*>(arg)) {
00191       chi2Arg = (RooAbsReal*)arg ;
00192     }
00193   }
00194 
00195   if (nllArg && !chi2Arg) {
00196     coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() 
00197                    << ") Summation contains a RooNLLVar, using its error level" << endl ;
00198     return nllArg->defaultErrorLevel() ;
00199   } else if (chi2Arg && !nllArg) {
00200     coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() 
00201                    << ") Summation contains a RooChi2Var, using its error level" << endl ;
00202     return chi2Arg->defaultErrorLevel() ;
00203   } else if (!nllArg && !chi2Arg) {
00204     coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: "
00205                    << "Summation contains neither RooNLLVar nor RooChi2Var server, using default level of 1.0" << endl ;
00206   } else {
00207     coutI(Fitting) << "RooAddition::defaultErrorLevel(" << GetName() << ") WARNING: "
00208                    << "Summation contains BOTH RooNLLVar and RooChi2Var server, using default level of 1.0" << endl ;
00209   }
00210 
00211   return 1.0 ;
00212 }
00213 
00214 
00215 //_____________________________________________________________________________
00216 void RooAddition::printMetaArgs(ostream& os) const 
00217 {
00218   _setIter->Reset() ;
00219 
00220   Bool_t first(kTRUE) ;
00221   RooAbsArg* arg;
00222   while((arg=(RooAbsArg*)_setIter->Next())) {
00223     if (!first) { os << " + " ;
00224     } else { first = kFALSE ; 
00225     }
00226     os << arg->GetName() ; 
00227   }  
00228   os << " " ;    
00229 }
00230 
00231 //_____________________________________________________________________________
00232 Int_t RooAddition::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const
00233 {
00234   
00235   // we always do things ourselves -- actually, always delegate further down the line ;-)
00236   analVars.add(allVars);
00237 
00238   // check if we already have integrals for this combination of factors
00239   Int_t sterileIndex(-1);
00240   CacheElem* cache = (CacheElem*) _cacheMgr.getObj(&analVars,&analVars,&sterileIndex,RooNameReg::ptr(rangeName));
00241   if (cache!=0) {
00242     Int_t code = _cacheMgr.lastIndex();
00243     return code+1;
00244   }
00245 
00246   // we don't, so we make it right here....
00247   cache = new CacheElem;
00248   _setIter->Reset();
00249   RooAbsReal *arg(0);
00250   while( (arg=(RooAbsReal*)_setIter->Next())!=0 ) {  // checked in c'tor that this will work...
00251       RooAbsReal *I = arg->createIntegral(analVars,rangeName);
00252       cache->_I.addOwned(*I);
00253   }
00254 
00255   Int_t code = _cacheMgr.setObj(&analVars,&analVars,(RooAbsCacheElement*)cache,RooNameReg::ptr(rangeName));
00256   return 1+code;
00257 }
00258 
00259 //_____________________________________________________________________________
00260 Double_t RooAddition::analyticalIntegral(Int_t code, const char* rangeName) const 
00261 {
00262   // Calculate integral internally from appropriate integral cache
00263 
00264   // note: rangeName implicit encoded in code: see _cacheMgr.setObj in getPartIntList...
00265   CacheElem *cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1);
00266   if (cache==0) {
00267     // cache got sterilized, trigger repopulation of this slot, then try again...
00268     std::auto_ptr<RooArgSet> vars( getParameters(RooArgSet()) );
00269     std::auto_ptr<RooArgSet> iset(  _cacheMgr.nameSet2ByIndex(code-1)->select(*vars) );
00270     RooArgSet dummy;
00271     Int_t code2 = getAnalyticalIntegral(*iset,dummy,rangeName);
00272     assert(code==code2); // must have revived the right (sterilized) slot...
00273     return analyticalIntegral(code2,rangeName);
00274   }
00275   assert(cache!=0);
00276 
00277   // loop over cache, and sum...
00278   std::auto_ptr<TIterator> iter( cache->_I.createIterator() );
00279   RooAbsReal *I;
00280   double result(0);
00281   while ( ( I=(RooAbsReal*)iter->Next() ) != 0 ) result += I->getVal();
00282   return result;
00283 
00284 }
00285 
00286 //_____________________________________________________________________________
00287 RooArgList RooAddition::CacheElem::containedArgs(Action)
00288 {
00289   // Return list of all RooAbsArgs in cache element
00290   RooArgList ret(_I) ;
00291   return ret ;
00292 }
00293 
00294 RooAddition::CacheElem::~CacheElem()
00295 {
00296   // Destructor
00297 }
00298 
00299 

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