00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "RooFit.h"
00032 #include "Riostream.h"
00033 
00034 #include "TIterator.h"
00035 #include "TList.h"
00036 #include "RooRealSumPdf.h"
00037 #include "RooRealProxy.h"
00038 #include "RooPlot.h"
00039 #include "RooRealVar.h"
00040 #include "RooAddGenContext.h"
00041 #include "RooRealConstant.h"
00042 #include "RooRealIntegral.h"
00043 #include "RooMsgService.h"
00044 
00045 
00046 
00047 ClassImp(RooRealSumPdf)
00048 ;
00049 
00050 
00051 
00052 RooRealSumPdf::RooRealSumPdf() 
00053 {
00054   
00055   
00056   _funcIter  = _funcList.createIterator() ;
00057   _coefIter  = _coefList.createIterator() ;
00058   _extended = kFALSE ;
00059 }
00060 
00061 
00062 
00063 
00064 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title) :
00065   RooAbsPdf(name,title), 
00066   _normIntMgr(this,10),
00067   _haveLastCoef(kFALSE),
00068   _funcList("!funcList","List of functions",this),
00069   _coefList("!coefList","List of coefficients",this),
00070   _extended(kFALSE)
00071 {
00072   
00073   _funcIter   = _funcList.createIterator() ;
00074   _coefIter  = _coefList.createIterator() ;
00075 }
00076 
00077 
00078 
00079 
00080 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title,
00081                      RooAbsReal& func1, RooAbsReal& func2, RooAbsReal& coef1) : 
00082   RooAbsPdf(name,title),
00083   _normIntMgr(this,10),
00084   _haveLastCoef(kFALSE),
00085   _funcList("!funcList","List of functions",this),
00086   _coefList("!coefList","List of coefficients",this),
00087   _extended(kFALSE)
00088 {
00089   
00090   
00091   
00092 
00093   
00094   _funcIter  = _funcList.createIterator() ;
00095   _coefIter = _coefList.createIterator() ;
00096 
00097   _funcList.add(func1) ;  
00098   _funcList.add(func2) ;
00099   _coefList.add(coef1) ;
00100 
00101 }
00102 
00103 
00104 
00105 RooRealSumPdf::RooRealSumPdf(const char *name, const char *title, const RooArgList& inFuncList, const RooArgList& inCoefList, Bool_t extended) :
00106   RooAbsPdf(name,title),
00107   _normIntMgr(this,10),
00108   _haveLastCoef(kFALSE),
00109   _funcList("!funcList","List of functions",this),
00110   _coefList("!coefList","List of coefficients",this),
00111   _extended(extended)
00112 { 
00113   
00114   
00115   
00116   
00117   
00118 
00119   if (!(inFuncList.getSize()==inCoefList.getSize()+1 || inFuncList.getSize()==inCoefList.getSize())) {
00120     coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() 
00121                           << ") number of pdfs and coefficients inconsistent, must have Nfunc=Ncoef or Nfunc=Ncoef+1" << endl ;
00122     assert(0) ;
00123   }
00124 
00125   _funcIter  = _funcList.createIterator() ;
00126   _coefIter = _coefList.createIterator() ;
00127  
00128   
00129   TIterator* funcIter = inFuncList.createIterator() ;
00130   TIterator* coefIter = inCoefList.createIterator() ;
00131   RooAbsArg* func ;
00132   RooAbsArg* coef ;
00133 
00134   while((coef = (RooAbsArg*)coefIter->Next())) {
00135     func = (RooAbsArg*) funcIter->Next() ;
00136 
00137     if (!dynamic_cast<RooAbsReal*>(coef)) {
00138       coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") coefficient " << coef->GetName() << " is not of type RooAbsReal, ignored" << endl ;
00139       continue ;
00140     }
00141     if (!dynamic_cast<RooAbsReal*>(func)) {
00142       coutW(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") func " << func->GetName() << " is not of type RooAbsReal, ignored" << endl ;
00143       continue ;
00144     }
00145     _funcList.add(*func) ;
00146     _coefList.add(*coef) ;    
00147   }
00148 
00149   func = (RooAbsReal*) funcIter->Next() ;
00150   if (func) {
00151     if (!dynamic_cast<RooAbsReal*>(func)) {
00152       coutE(InputArguments) << "RooRealSumPdf::RooRealSumPdf(" << GetName() << ") last func " << coef->GetName() << " is not of type RooAbsReal, fatal error" << endl ;
00153       assert(0) ;
00154     }
00155     _funcList.add(*func) ;  
00156   } else {
00157     _haveLastCoef = kTRUE ;
00158   }
00159   
00160   delete funcIter ;
00161   delete coefIter  ;
00162 }
00163 
00164 
00165 
00166 
00167 
00168 RooRealSumPdf::RooRealSumPdf(const RooRealSumPdf& other, const char* name) :
00169   RooAbsPdf(other,name),
00170   _normIntMgr(other._normIntMgr,this),
00171   _haveLastCoef(other._haveLastCoef),
00172   _funcList("!funcList",this,other._funcList),
00173   _coefList("!coefList",this,other._coefList),
00174   _extended(other._extended)
00175 {
00176   
00177 
00178   _funcIter  = _funcList.createIterator() ;
00179   _coefIter = _coefList.createIterator() ;
00180 }
00181 
00182 
00183 
00184 
00185 RooRealSumPdf::~RooRealSumPdf()
00186 {
00187   
00188   delete _funcIter ;
00189   delete _coefIter ;
00190 }
00191 
00192 
00193 
00194 
00195 
00196 
00197 RooAbsPdf::ExtendMode RooRealSumPdf::extendMode() const 
00198 {
00199   return (_extended && (_funcList.getSize()==_coefList.getSize())) ? CanBeExtended : CanNotBeExtended ;
00200 }
00201 
00202 
00203 
00204 
00205 
00206 Double_t RooRealSumPdf::evaluate() const 
00207 {
00208   
00209 
00210   Double_t value(0) ;
00211 
00212   
00213   _funcIter->Reset() ;
00214   _coefIter->Reset() ;
00215   RooAbsReal* coef ;
00216   RooAbsReal* func ;
00217       
00218   
00219   Double_t lastCoef(1) ;
00220   while((coef=(RooAbsReal*)_coefIter->Next())) {
00221     func = (RooAbsReal*)_funcIter->Next() ;
00222     Double_t coefVal = coef->getVal() ;
00223     if (coefVal) {
00224       cxcoutD(Eval) << "RooRealSumPdf::eval(" << GetName() << ") coefVal = " << coefVal << " funcVal = " << func->getVal() << endl ;
00225       if (func->isSelectedComp()) {
00226         value += func->getVal()*coefVal ;
00227       }
00228       lastCoef -= coef->getVal() ;
00229     }
00230   }
00231   
00232   if (!_haveLastCoef) {
00233     
00234     func = (RooAbsReal*) _funcIter->Next() ;
00235     if (func->isSelectedComp()) {
00236       value += func->getVal()*lastCoef ;
00237     }
00238 
00239     cxcoutD(Eval) << "RooRealSumPdf::eval(" << GetName() << ") lastCoef = " << lastCoef << " funcVal = " << func->getVal() << endl ;
00240     
00241     
00242     if (lastCoef<0 || lastCoef>1) {
00243       coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName() 
00244                   << " WARNING: sum of FUNC coefficients not in range [0-1], value=" 
00245                   << 1-lastCoef << endl ;
00246     } 
00247   }
00248 
00249   return value ;
00250 }
00251 
00252 
00253 
00254 
00255 
00256 Bool_t RooRealSumPdf::checkObservables(const RooArgSet* nset) const 
00257 {
00258   
00259   
00260   
00261   
00262   
00263   
00264 
00265   Bool_t ret(kFALSE) ;
00266 
00267   _funcIter->Reset() ;
00268   _coefIter->Reset() ;
00269   RooAbsReal* coef ;
00270   RooAbsReal* func ;
00271   while((coef=(RooAbsReal*)_coefIter->Next())) {
00272     func = (RooAbsReal*)_funcIter->Next() ;
00273     if (func->observableOverlaps(nset,*coef)) {
00274       coutE(InputArguments) << "RooRealSumPdf::checkObservables(" << GetName() << "): ERROR: coefficient " << coef->GetName() 
00275                             << " and FUNC " << func->GetName() << " have one or more observables in common" << endl ;
00276       ret = kTRUE ;
00277     }
00278     if (coef->dependsOn(*nset)) {
00279       coutE(InputArguments) << "RooRealPdf::checkObservables(" << GetName() << "): ERROR coefficient " << coef->GetName() 
00280                             << " depends on one or more of the following observables" ; nset->Print("1") ;
00281       ret = kTRUE ;
00282     }
00283   }
00284   
00285   return ret ;
00286 }
00287 
00288 
00289 
00290 
00291 
00292 Int_t RooRealSumPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars, 
00293                                              const RooArgSet* normSet2, const char* ) const 
00294 {
00295   
00296 
00297   
00298   if (allVars.getSize()==0) return 0 ;
00299   if (_forceNumInt) return 0 ;
00300 
00301   
00302   analVars.add(allVars) ;
00303   RooArgSet* normSet = normSet2 ? getObservables(normSet2) : 0 ;
00304 
00305 
00306   
00307   Int_t sterileIdx(-1) ;
00308   CacheElem* cache = (CacheElem*) _normIntMgr.getObj(normSet,&analVars,&sterileIdx,0) ;
00309   if (cache) {
00310     return _normIntMgr.lastIndex()+1 ;
00311   }
00312   
00313   
00314   cache = new CacheElem ;
00315 
00316   
00317   _funcIter->Reset() ;
00318   RooAbsReal *func ;
00319   while((func=(RooAbsReal*)_funcIter->Next())) {
00320     RooAbsReal* funcInt = func->createIntegral(analVars) ;
00321     cache->_funcIntList.addOwned(*funcInt) ;
00322     if (normSet && normSet->getSize()>0) {
00323       RooAbsReal* funcNorm = func->createIntegral(*normSet) ;
00324       cache->_funcNormList.addOwned(*funcNorm) ;
00325     }
00326   }
00327 
00328   
00329   Int_t code = _normIntMgr.setObj(normSet,&analVars,(RooAbsCacheElement*)cache,0) ;
00330 
00331   if (normSet) {
00332     delete normSet ;
00333   }
00334 
00335   return code+1 ; 
00336 }
00337 
00338 
00339 
00340 
00341 
00342 Double_t RooRealSumPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet2, const char* ) const 
00343 {
00344   
00345   
00346 
00347   
00348   if (code==0) return getVal(normSet2) ;
00349 
00350 
00351   
00352   CacheElem* cache = (CacheElem*) _normIntMgr.getObjByIndex(code-1) ;
00353 
00354   TIterator* funcIntIter = cache->_funcIntList.createIterator() ;
00355   _coefIter->Reset() ;
00356   _funcIter->Reset() ;
00357   RooAbsReal *coef(0), *funcInt(0), *func(0) ;
00358   Double_t value(0) ;
00359 
00360   
00361   Double_t lastCoef(1) ;
00362   while((coef=(RooAbsReal*)_coefIter->Next())) {
00363     funcInt = (RooAbsReal*)funcIntIter->Next() ;
00364     func    = (RooAbsReal*)_funcIter->Next() ;
00365     Double_t coefVal = coef->getVal(normSet2) ;
00366     if (coefVal) {
00367       if (func->isSelectedComp()) {
00368         value += funcInt->getVal()*coefVal ;
00369       }
00370       lastCoef -= coef->getVal(normSet2) ;
00371     }
00372   }
00373   
00374   if (!_haveLastCoef) {
00375     
00376     funcInt = (RooAbsReal*) funcIntIter->Next() ;
00377     if (func->isSelectedComp()) {
00378       value += funcInt->getVal()*lastCoef ;
00379     }
00380     
00381     
00382     if (lastCoef<0 || lastCoef>1) {
00383       coutW(Eval) << "RooRealSumPdf::evaluate(" << GetName() 
00384                   << " WARNING: sum of FUNC coefficients not in range [0-1], value=" 
00385                   << 1-lastCoef << endl ;
00386     } 
00387   }
00388 
00389   delete funcIntIter ;
00390   
00391   Double_t normVal(1) ;
00392   if (normSet2) {
00393     normVal = 0 ;
00394 
00395     
00396     RooAbsReal* funcNorm ;
00397     TIterator* funcNormIter = cache->_funcNormList.createIterator() ;
00398     _coefIter->Reset() ;
00399     while((coef=(RooAbsReal*)_coefIter->Next())) {
00400       funcNorm = (RooAbsReal*)funcNormIter->Next() ;
00401       Double_t coefVal = coef->getVal(normSet2) ;
00402       if (coefVal) {
00403         normVal += funcNorm->getVal()*coefVal ;
00404       }
00405     }
00406     
00407     
00408     if (!_haveLastCoef) {
00409       funcNorm = (RooAbsReal*) funcNormIter->Next() ;
00410       normVal += funcNorm->getVal()*lastCoef ;
00411     }
00412       
00413     delete funcNormIter ;      
00414   }
00415 
00416   return value / normVal;
00417 }
00418 
00419 
00420 
00421 Double_t RooRealSumPdf::expectedEvents(const RooArgSet* nset) const
00422 {
00423  
00424  RooArgSet* nset2 = nset? getObservables(*nset) : 0 ;
00425  RooAbsReal* integral = createIntegral(nset2?*nset2:RooArgSet());
00426  delete nset2 ;
00427 
00428  double ret = integral->getVal();
00429  delete integral;
00430 
00431  return ret;
00432 }
00433 
00434 
00435 
00436 void RooRealSumPdf::printMetaArgs(ostream& os) const 
00437 {
00438   
00439   
00440 
00441   _funcIter->Reset() ;
00442   _coefIter->Reset() ;
00443 
00444   Bool_t first(kTRUE) ;
00445     
00446   RooAbsArg* coef, *func ;
00447   if (_coefList.getSize()!=0) { 
00448     while((coef=(RooAbsArg*)_coefIter->Next())) {
00449       if (!first) {
00450         os << " + " ;
00451       } else {
00452         first = kFALSE ;
00453       }
00454       func=(RooAbsArg*)_funcIter->Next() ;
00455       os << coef->GetName() << " * " << func->GetName() ;
00456     }
00457     func = (RooAbsArg*) _funcIter->Next() ;
00458     if (func) {
00459       os << " + [%] * " << func->GetName() ;
00460     }
00461   } else {
00462     
00463     while((func=(RooAbsArg*)_funcIter->Next())) {
00464       if (!first) {
00465         os << " + " ;
00466       } else {
00467         first = kFALSE ;
00468       }
00469       os << func->GetName() ; 
00470     }  
00471   }
00472 
00473   os << " " ;    
00474 }