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 }