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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include "RooFit.h"
00045 #include "Riostream.h"
00046 #include "TClass.h"
00047
00048 #include "TIterator.h"
00049 #include "RooProdPdf.h"
00050 #include "RooRealProxy.h"
00051 #include "RooProdGenContext.h"
00052 #include "RooGenProdProj.h"
00053 #include "RooProduct.h"
00054 #include "RooNameReg.h"
00055 #include "RooMsgService.h"
00056 #include "RooFormulaVar.h"
00057 #include "RooRealVar.h"
00058 #include "RooAddition.h"
00059 #include "RooGlobalFunc.h"
00060 #include "RooConstVar.h"
00061 #include "RooWorkspace.h"
00062 #include "RooRangeBoolean.h"
00063 #include "RooCustomizer.h"
00064 #include "RooRealIntegral.h"
00065
00066 #include <string.h>
00067 #include <sstream>
00068
00069 #ifndef _WIN32
00070 #include <strings.h>
00071 #else
00072
00073 static char *strtok_r(char *s1, const char *s2, char **lasts)
00074 {
00075 char *ret;
00076
00077 if (s1 == NULL)
00078 s1 = *lasts;
00079 while(*s1 && strchr(s2, *s1))
00080 ++s1;
00081 if(*s1 == '\0')
00082 return NULL;
00083 ret = s1;
00084 while(*s1 && !strchr(s2, *s1))
00085 ++s1;
00086 if(*s1)
00087 *s1++ = '\0';
00088 *lasts = s1;
00089 return ret;
00090 }
00091
00092 #endif
00093
00094
00095 #include "TSystem.h"
00096
00097 ClassImp(RooProdPdf)
00098 ;
00099
00100
00101
00102
00103 RooProdPdf::RooProdPdf() :
00104 _curNormSet(0),
00105 _cutOff(0),
00106 _extendedIndex(-1),
00107 _useDefaultGen(kFALSE),
00108 _refRangeName(0),
00109 _selfNorm(kTRUE)
00110 {
00111
00112 _pdfIter = _pdfList.createIterator() ;
00113 }
00114
00115
00116
00117
00118 RooProdPdf::RooProdPdf(const char *name, const char *title, Double_t cutOff) :
00119 RooAbsPdf(name,title),
00120 _cacheMgr(this,10),
00121 _genCode(10),
00122 _cutOff(cutOff),
00123 _pdfList("!pdfs","List of PDFs",this),
00124 _extendedIndex(-1),
00125 _useDefaultGen(kFALSE),
00126 _refRangeName(0),
00127 _selfNorm(kTRUE)
00128 {
00129
00130 _pdfIter = _pdfList.createIterator() ;
00131 }
00132
00133
00134
00135
00136 RooProdPdf::RooProdPdf(const char *name, const char *title,
00137 RooAbsPdf& pdf1, RooAbsPdf& pdf2, Double_t cutOff) :
00138 RooAbsPdf(name,title),
00139 _cacheMgr(this,10),
00140 _genCode(10),
00141 _cutOff(cutOff),
00142 _pdfList("!pdfs","List of PDFs",this),
00143 _pdfIter(_pdfList.createIterator()),
00144 _extendedIndex(-1),
00145 _useDefaultGen(kFALSE),
00146 _refRangeName(0),
00147 _selfNorm(kTRUE)
00148 {
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 _pdfList.add(pdf1) ;
00167 RooArgSet* nset1 = new RooArgSet("nset") ;
00168 _pdfNSetList.Add(nset1) ;
00169 if (pdf1.canBeExtended()) {
00170 _extendedIndex = _pdfList.index(&pdf1) ;
00171 }
00172
00173 _pdfList.add(pdf2) ;
00174 RooArgSet* nset2 = new RooArgSet("nset") ;
00175 _pdfNSetList.Add(nset2) ;
00176
00177 if (pdf2.canBeExtended()) {
00178 if (_extendedIndex>=0) {
00179
00180 coutW(InputArguments) << "RooProdPdf::RooProdPdf(" << GetName()
00181 << ") multiple components with extended terms detected,"
00182 << " product will not be extendible." << endl ;
00183 _extendedIndex=-1 ;
00184 } else {
00185 _extendedIndex=_pdfList.index(&pdf2) ;
00186 }
00187 }
00188 }
00189
00190
00191
00192
00193 RooProdPdf::RooProdPdf(const char* name, const char* title, const RooArgList& inPdfList, Double_t cutOff) :
00194 RooAbsPdf(name,title),
00195 _cacheMgr(this,10),
00196 _genCode(10),
00197 _cutOff(cutOff),
00198 _pdfList("!pdfs","List of PDFs",this),
00199 _pdfIter(_pdfList.createIterator()),
00200 _extendedIndex(-1),
00201 _useDefaultGen(kFALSE),
00202 _refRangeName(0),
00203 _selfNorm(kTRUE)
00204 {
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221 TIterator* iter = inPdfList.createIterator() ;
00222 RooAbsArg* arg ;
00223 Int_t numExtended(0) ;
00224 while((arg=(RooAbsArg*)iter->Next())) {
00225 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
00226 if (!pdf) {
00227 coutW(InputArguments) << "RooProdPdf::RooProdPdf(" << GetName() << ") list arg "
00228 << pdf->GetName() << " is not a PDF, ignored" << endl ;
00229 continue ;
00230 }
00231 _pdfList.add(*pdf) ;
00232
00233 RooArgSet* nset = new RooArgSet("nset") ;
00234 _pdfNSetList.Add(nset) ;
00235
00236 if (pdf->canBeExtended()) {
00237 _extendedIndex = _pdfList.index(pdf) ;
00238 numExtended++ ;
00239 }
00240 }
00241
00242
00243 if (numExtended>1) {
00244 coutW(InputArguments) << "RooProdPdf::RooProdPdf(" << GetName()
00245 << ") WARNING: multiple components with extended terms detected,"
00246 << " product will not be extendible." << endl ;
00247 _extendedIndex = -1 ;
00248 }
00249
00250 delete iter ;
00251 }
00252
00253
00254
00255
00256 RooProdPdf::RooProdPdf(const char* name, const char* title, const RooArgSet& fullPdfSet,
00257 const RooCmdArg& arg1, const RooCmdArg& arg2,
00258 const RooCmdArg& arg3, const RooCmdArg& arg4,
00259 const RooCmdArg& arg5, const RooCmdArg& arg6,
00260 const RooCmdArg& arg7, const RooCmdArg& arg8) :
00261 RooAbsPdf(name,title),
00262 _cacheMgr(this,10),
00263 _genCode(10),
00264 _cutOff(0),
00265 _pdfList("!pdfs","List of PDFs",this),
00266 _pdfIter(_pdfList.createIterator()),
00267 _extendedIndex(-1),
00268 _useDefaultGen(kFALSE),
00269 _refRangeName(0),
00270 _selfNorm(kTRUE)
00271 {
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 RooLinkedList l ;
00299 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
00300 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
00301 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
00302 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
00303
00304 initializeFromCmdArgList(fullPdfSet,l) ;
00305 }
00306
00307
00308
00309
00310 RooProdPdf::RooProdPdf(const char* name, const char* title,
00311 const RooCmdArg& arg1, const RooCmdArg& arg2,
00312 const RooCmdArg& arg3, const RooCmdArg& arg4,
00313 const RooCmdArg& arg5, const RooCmdArg& arg6,
00314 const RooCmdArg& arg7, const RooCmdArg& arg8) :
00315 RooAbsPdf(name,title),
00316 _cacheMgr(this,10),
00317 _genCode(10),
00318 _cutOff(0),
00319 _pdfList("!pdfList","List of PDFs",this),
00320 _pdfIter(_pdfList.createIterator()),
00321 _extendedIndex(-1),
00322 _useDefaultGen(kFALSE),
00323 _refRangeName(0),
00324 _selfNorm(kTRUE)
00325 {
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352 RooLinkedList l ;
00353 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
00354 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
00355 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
00356 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
00357
00358 initializeFromCmdArgList(RooArgSet(),l) ;
00359 }
00360
00361
00362
00363
00364 RooProdPdf::RooProdPdf(const char* name, const char* title, const RooArgSet& fullPdfSet, const RooLinkedList& cmdArgList) :
00365 RooAbsPdf(name,title),
00366 _cacheMgr(this,10),
00367 _genCode(10),
00368 _cutOff(0),
00369 _pdfList("!pdfs","List of PDFs",this),
00370 _pdfIter(_pdfList.createIterator()),
00371 _extendedIndex(-1),
00372 _useDefaultGen(kFALSE),
00373 _refRangeName(0),
00374 _selfNorm(kTRUE)
00375 {
00376
00377 initializeFromCmdArgList(fullPdfSet, cmdArgList) ;
00378 }
00379
00380
00381
00382
00383 RooProdPdf::RooProdPdf(const RooProdPdf& other, const char* name) :
00384 RooAbsPdf(other,name),
00385 _cacheMgr(other._cacheMgr,this),
00386 _genCode(other._genCode),
00387 _cutOff(other._cutOff),
00388 _pdfList("!pdfs",this,other._pdfList),
00389 _pdfIter(_pdfList.createIterator()),
00390 _extendedIndex(other._extendedIndex),
00391 _useDefaultGen(other._useDefaultGen),
00392 _refRangeName(other._refRangeName),
00393 _selfNorm(other._selfNorm),
00394 _defNormSet(other._defNormSet)
00395 {
00396
00397
00398
00399 TIterator* iter = other._pdfNSetList.MakeIterator() ;
00400 RooArgSet* nset ;
00401 while((nset=(RooArgSet*)iter->Next())) {
00402 RooArgSet* tmp = (RooArgSet*) nset->snapshot() ;
00403 tmp->setName(nset->GetName()) ;
00404 _pdfNSetList.Add(tmp) ;
00405 }
00406 delete iter ;
00407
00408 }
00409
00410
00411
00412
00413 void RooProdPdf::initializeFromCmdArgList(const RooArgSet& fullPdfSet, const RooLinkedList& l)
00414 {
00415
00416
00417
00418 Int_t numExtended(0) ;
00419
00420
00421 TIterator* siter = fullPdfSet.createIterator() ;
00422 RooAbsPdf* pdf ;
00423 while((pdf=(RooAbsPdf*)siter->Next())) {
00424 _pdfList.add(*pdf) ;
00425 RooArgSet* nset1 = new RooArgSet("nset") ;
00426 _pdfNSetList.Add(nset1) ;
00427
00428 if (pdf->canBeExtended()) {
00429 _extendedIndex = _pdfList.index(pdf) ;
00430 numExtended++ ;
00431 }
00432
00433 }
00434 delete siter ;
00435
00436
00437 TIterator* iter = l.MakeIterator() ;
00438 RooCmdArg* carg ;
00439 while((carg=(RooCmdArg*)iter->Next())) {
00440
00441 if (!TString(carg->GetName()).CompareTo("Conditional")) {
00442
00443 Int_t argType = carg->getInt(0) ;
00444 RooArgSet* pdfSet = (RooArgSet*) carg->getSet(0) ;
00445 RooArgSet* normSet = (RooArgSet*) carg->getSet(1) ;
00446
00447 TIterator* siter2 = pdfSet->createIterator() ;
00448 RooAbsPdf* thePdf ;
00449 while((thePdf=(RooAbsPdf*)siter2->Next())) {
00450 _pdfList.add(*thePdf) ;
00451
00452 if (argType==0) {
00453 RooArgSet* tmp = (RooArgSet*) normSet->snapshot() ;
00454 tmp->setName("nset") ;
00455 _pdfNSetList.Add(tmp) ;
00456 } else {
00457 RooArgSet* tmp = (RooArgSet*) normSet->snapshot() ;
00458 tmp->setName("cset") ;
00459 _pdfNSetList.Add(tmp) ;
00460 }
00461
00462 if (thePdf->canBeExtended()) {
00463 _extendedIndex = _pdfList.index(thePdf) ;
00464 numExtended++ ;
00465 }
00466
00467 }
00468 delete siter2 ;
00469
00470
00471 } else if (TString(carg->GetName()).CompareTo("")) {
00472 coutW(InputArguments) << "Unknown arg: " << carg->GetName() << endl ;
00473 }
00474 }
00475
00476
00477 if (numExtended>1) {
00478 coutW(InputArguments) << "RooProdPdf::RooProdPdf(" << GetName()
00479 << ") WARNING: multiple components with extended terms detected,"
00480 << " product will not be extendible." << endl ;
00481 _extendedIndex = -1 ;
00482 }
00483
00484
00485 delete iter ;
00486 }
00487
00488
00489
00490
00491 RooProdPdf::~RooProdPdf()
00492 {
00493
00494
00495 _pdfNSetList.Delete() ;
00496 delete _pdfIter ;
00497 }
00498
00499
00500
00501
00502 Double_t RooProdPdf::getVal(const RooArgSet* set) const
00503 {
00504
00505 _curNormSet = (RooArgSet*)set ;
00506 return RooAbsPdf::getVal(set) ;
00507 }
00508
00509
00510
00511
00512 Double_t RooProdPdf::evaluate() const
00513 {
00514
00515
00516 Int_t code ;
00517 RooArgList *plist(0) ;
00518 RooLinkedList *nlist(0) ;
00519 getPartIntList(_curNormSet,0,plist,nlist,code) ;
00520
00521
00522
00523 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(_curNormSet,0,&code,0) ;
00524 Double_t ret = calculate(*cache) ;
00525
00526 return ret ;
00527 }
00528
00529
00530
00531
00532 Double_t RooProdPdf::calculate(const RooArgList* partIntList, const RooLinkedList* normSetList) const
00533 {
00534
00535
00536
00537 RooAbsReal* partInt ;
00538 RooArgSet* normSet ;
00539 Double_t value(1.0) ;
00540 Int_t n = partIntList->getSize() ;
00541
00542 Int_t i ;
00543 for (i=0 ; i<n ; i++) {
00544 partInt = ((RooAbsReal*)partIntList->at(i)) ;
00545 normSet = ((RooArgSet*)normSetList->At(i)) ;
00546 Double_t piVal = partInt->getVal(normSet->getSize()>0 ? normSet : 0) ;
00547
00548 value *= piVal ;
00549 if (value<_cutOff) {
00550 break ;
00551 }
00552 }
00553
00554 return value ;
00555 }
00556
00557
00558
00559
00560 Double_t RooProdPdf::calculate(const RooProdPdf::CacheElem& cache, Bool_t ) const
00561 {
00562
00563
00564
00565
00566
00567 Double_t value(1.0) ;
00568
00569 if (cache._isRearranged) {
00570
00571 if (dologD(Eval)) {
00572 cxcoutD(Eval) << "RooProdPdf::calculate(" << GetName() << ") rearranged product calculation"
00573 << " calculate: num = " << cache._rearrangedNum->GetName() << " = " << cache._rearrangedNum->getVal() << endl ;
00574
00575 cxcoutD(Eval) << "calculate: den = " << cache._rearrangedDen->GetName() << " = " << cache._rearrangedDen->getVal() << endl ;
00576
00577 }
00578
00579 value = cache._rearrangedNum->getVal() / cache._rearrangedDen->getVal() ;
00580
00581 } else {
00582
00583 cxcoutD(Eval) << "RooProdPdf::calculate(" << GetName() << ") regular product chain calculation" << endl ;
00584
00585 RooAbsReal* partInt ;
00586 RooArgSet* normSet ;
00587 Int_t n = cache._partList.getSize() ;
00588
00589 Int_t i ;
00590 for (i=0 ; i<n ; i++) {
00591 partInt = ((RooAbsReal*)cache._partList.at(i)) ;
00592 normSet = ((RooArgSet*)cache._normList.At(i)) ;
00593 Double_t piVal = partInt->getVal(normSet->getSize()>0 ? normSet : 0) ;
00594
00595 if (dynamic_cast<RooAbsPdf*>(partInt)) {
00596 cxcoutD(Eval) << "product term " << partInt->GetName() << " normalized over " << (normSet?*normSet:RooArgSet())
00597 << " = " << partInt->getVal() << " / " << ((RooAbsPdf*)partInt)->getNorm(normSet) << " = " << piVal << endl ;
00598 } else {
00599 cxcoutD(Eval) << "product term " << partInt->GetName() << " normalized over " << (normSet?*normSet:RooArgSet()) << " = " << piVal << endl ;
00600 }
00601 value *= piVal ;
00602 if (value<_cutOff) {
00603 break ;
00604 }
00605 }
00606 }
00607
00608 cxcoutD(Eval) << "return value = " << value << endl ;
00609 return value ;
00610 }
00611
00612
00613
00614
00615 void RooProdPdf::factorizeProduct(const RooArgSet& normSet, const RooArgSet& intSet,
00616 RooLinkedList& termList, RooLinkedList& normList,
00617 RooLinkedList& impDepList, RooLinkedList& crossDepList,
00618 RooLinkedList& intList) const
00619 {
00620
00621
00622 _pdfIter->Reset() ;
00623 RooAbsPdf* pdf ;
00624
00625
00626 RooLinkedList depAllList ;
00627 RooLinkedList depIntNoNormList ;
00628
00629
00630 RooArgSet* term(0) ;
00631 RooArgSet* termNormDeps(0) ;
00632 RooArgSet* termAllDeps(0) ;
00633 RooArgSet* termIntDeps(0) ;
00634 RooArgSet* termIntNoNormDeps(0) ;
00635 TIterator* lIter = termList.MakeIterator() ;
00636 TIterator* ldIter = normList.MakeIterator() ;
00637 TIterator* laIter = depAllList.MakeIterator() ;
00638 TIterator* nIter = _pdfNSetList.MakeIterator() ;
00639 RooArgSet* pdfNSet, *pdfNSetOrig, *pdfCSet ;
00640
00641
00642 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
00643 pdfNSetOrig = (RooArgSet*) nIter->Next() ;
00644 lIter->Reset() ;
00645 ldIter->Reset() ;
00646 laIter->Reset() ;
00647
00648
00649 if (string("nset")==pdfNSetOrig->GetName()) {
00650 pdfNSet = pdf->getObservables(*pdfNSetOrig) ;
00651 pdfCSet = new RooArgSet ;
00652 } else if (string("cset") == pdfNSetOrig->GetName()) {
00653 RooArgSet* tmp = pdf->getObservables(normSet) ;
00654 tmp->remove(*pdfNSetOrig,kTRUE,kTRUE) ;
00655 pdfCSet = pdfNSetOrig ;
00656 pdfNSet = tmp ;
00657 } else {
00658
00659 pdfNSet = pdf->getObservables(*pdfNSetOrig) ;
00660 pdfCSet = new RooArgSet ;
00661 }
00662
00663
00664 RooArgSet pdfNormDeps ;
00665 RooArgSet pdfAllDeps ;
00666
00667
00668 RooArgSet* tmp = pdf->getObservables(normSet) ;
00669 pdfAllDeps.add(*tmp) ;
00670 delete tmp ;
00671
00672
00673
00674
00675
00676 if (pdfNSet->getSize()>0) {
00677
00678 RooArgSet* tmp2 = (RooArgSet*) pdfAllDeps.selectCommon(*pdfNSet) ;
00679 pdfNormDeps.add(*tmp2) ;
00680 delete tmp2 ;
00681 } else {
00682
00683 pdfNormDeps.add(pdfAllDeps) ;
00684 }
00685
00686
00687
00688 RooArgSet* pdfIntSet = pdf->getObservables(intSet) ;
00689
00690
00691 if (pdfNormDeps.getSize()==0 && pdfCSet->getSize()>0) {
00692 pdfIntSet->remove(*pdfCSet,kTRUE,kTRUE) ;
00693
00694 }
00695
00696 RooArgSet pdfIntNoNormDeps(*pdfIntSet) ;
00697 pdfIntNoNormDeps.remove(pdfNormDeps,kTRUE,kTRUE) ;
00698
00699
00700
00701
00702
00703 Bool_t done(kFALSE) ;
00704 while((term=(RooArgSet*)lIter->Next())) {
00705 termNormDeps=(RooArgSet*)ldIter->Next() ;
00706 termAllDeps=(RooArgSet*)laIter->Next() ;
00707
00708
00709
00710
00711
00712
00713
00714 Bool_t normOverlap = pdfNormDeps.overlaps(*termNormDeps) ;
00715
00716
00717 if (normOverlap) {
00718
00719
00720 term->add(*pdf) ;
00721 termNormDeps->add(pdfNormDeps,kFALSE) ;
00722 termAllDeps->add(pdfAllDeps,kFALSE) ;
00723 if (!termIntDeps) {
00724 termIntDeps = new RooArgSet("termIntDeps") ;
00725 }
00726 termIntDeps->add(*pdfIntSet,kFALSE) ;
00727 if (!termIntNoNormDeps) {
00728 termIntNoNormDeps = new RooArgSet("termIntNoNormDeps") ;
00729 }
00730 termIntNoNormDeps->add(pdfIntNoNormDeps,kFALSE) ;
00731 done = kTRUE ;
00732 }
00733 }
00734
00735
00736 if (!done) {
00737 if (!(pdfNormDeps.getSize()==0&&pdfAllDeps.getSize()==0&&pdfIntSet->getSize()==0) || normSet.getSize()==0) {
00738
00739 term = new RooArgSet("term") ;
00740 termNormDeps = new RooArgSet("termNormDeps") ;
00741 termAllDeps = new RooArgSet("termAllDeps") ;
00742 termIntDeps = new RooArgSet("termIntDeps") ;
00743 termIntNoNormDeps = new RooArgSet("termIntNoNormDeps") ;
00744
00745 term->add(*pdf) ;
00746 termNormDeps->add(pdfNormDeps,kFALSE) ;
00747 termAllDeps->add(pdfAllDeps,kFALSE) ;
00748 termIntDeps->add(*pdfIntSet,kFALSE) ;
00749 termIntNoNormDeps->add(pdfIntNoNormDeps,kFALSE) ;
00750
00751 termList.Add(term) ;
00752 normList.Add(termNormDeps) ;
00753 depAllList.Add(termAllDeps) ;
00754 intList.Add(termIntDeps) ;
00755 depIntNoNormList.Add(termIntNoNormDeps) ;
00756 }
00757 }
00758
00759
00760 delete pdfNSet ;
00761 delete pdfIntSet ;
00762 if (pdfCSet != pdfNSetOrig) {
00763 delete pdfCSet ;
00764 }
00765 }
00766
00767
00768 lIter->Reset() ;
00769 ldIter->Reset() ;
00770 laIter->Reset() ;
00771 TIterator* innIter = depIntNoNormList.MakeIterator() ;
00772
00773
00774
00775 while((term=(RooArgSet*)lIter->Next())) {
00776 RooArgSet* normDeps = (RooArgSet*) ldIter->Next() ;
00777 RooArgSet* allDeps = (RooArgSet*) laIter->Next() ;
00778 RooArgSet* intNoNormDeps = (RooArgSet*) innIter->Next() ;
00779
00780
00781 RooArgSet impDeps(*allDeps) ;
00782 impDeps.remove(*normDeps,kTRUE,kTRUE) ;
00783 impDepList.Add(impDeps.snapshot()) ;
00784
00785
00786
00787
00788 RooArgSet* crossDeps = (RooArgSet*) intNoNormDeps->selectCommon(*normDeps) ;
00789 crossDepList.Add(crossDeps->snapshot()) ;
00790
00791 delete crossDeps ;
00792 }
00793
00794
00795 depAllList.Delete() ;
00796 depIntNoNormList.Delete() ;
00797
00798 delete nIter ;
00799 delete lIter ;
00800 delete ldIter ;
00801 delete laIter ;
00802 delete innIter ;
00803
00804 return ;
00805 }
00806
00807
00808
00809
00810
00811 void RooProdPdf::getPartIntList(const RooArgSet* nset, const RooArgSet* iset,
00812 pRooArgList& partList, pRooLinkedList& nsetList,
00813 Int_t& code, const char* isetRangeName) const
00814 {
00815
00816
00817
00818
00819
00820 RooArgList* partListPointer=(RooArgList*)partList ;
00821 RooLinkedList* nsetListPointer=(RooLinkedList*)nsetList ;
00822
00823
00824
00825
00826
00827
00828
00829 Int_t sterileIdx(-1) ;
00830
00831 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(nset,iset,&sterileIdx,RooNameReg::ptr(isetRangeName)) ;
00832 if (cache) {
00833 code = _cacheMgr.lastIndex() ;
00834 partList = &cache->_partList ;
00835 nsetList = &cache->_normList ;
00836
00837 return ;
00838 }
00839
00840
00841 cache = new CacheElem ;
00842
00843
00844 RooLinkedList terms, norms, imp, ints, cross ;
00845
00846
00847
00848
00849 RooArgSet factNset(nset ? (*nset) : _defNormSet) ;
00850
00851
00852 factorizeProduct(factNset,iset?(*iset):RooArgSet(),terms,norms,imp,cross,ints) ;
00853
00854 RooArgSet *norm, *integ, *xdeps, *imps ;
00855
00856
00857 RooLinkedList groupedList ;
00858 RooArgSet outerIntDeps ;
00859
00860 groupProductTerms(groupedList,outerIntDeps,terms,norms,imp,ints,cross) ;
00861 TIterator* gIter = groupedList.MakeIterator() ;
00862 RooLinkedList* group ;
00863
00864
00865
00866
00867 map<string,RooArgSet> ratioTerms ;
00868 while((group=(RooLinkedList*)gIter->Next())) {
00869 if (group->GetSize()==1) {
00870
00871
00872 RooArgSet* term = (RooArgSet*) group->At(0) ;
00873
00874 Int_t termIdx = terms.IndexOf(term) ;
00875 norm=(RooArgSet*) norms.At(termIdx) ;
00876 imps=(RooArgSet*)imp.At(termIdx) ;
00877 RooArgSet termNSet(*norm), termImpSet(*imps) ;
00878
00879
00880
00881
00882 if (termImpSet.getSize()>0 && _refRangeName!=0) {
00883
00884
00885
00886
00887 Bool_t rangeIdentical(kTRUE) ;
00888 TIterator* niter = termNSet.createIterator() ;
00889 RooRealVar* normObs ;
00890
00891 while((normObs=(RooRealVar*)niter->Next())) {
00892
00893 if(_normRange.Length()>0){
00894 if (normObs->getMin(_normRange.Data())!=normObs->getMin(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00895 if (normObs->getMax(_normRange.Data())!=normObs->getMax(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00896 }
00897 else{
00898 if (normObs->getMin()!=normObs->getMin(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00899 if (normObs->getMax()!=normObs->getMax(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00900 }
00901 }
00902 delete niter ;
00903
00904
00905 if (!rangeIdentical || 1) {
00906
00907 RooAbsReal* ratio = makeCondPdfRatioCorr(*(RooAbsReal*)term->first(),termNSet,termImpSet,normRange(),RooNameReg::str(_refRangeName)) ;
00908 ostringstream str ; termImpSet.printValue(str) ;
00909 ratioTerms[str.str()].add(*ratio) ;
00910 }
00911 }
00912
00913 } else {
00914
00915
00916 RooArgSet compTermSet, compTermNorm ;
00917 TIterator* tIter = group->MakeIterator() ;
00918 RooArgSet* term ;
00919 while((term=(RooArgSet*)tIter->Next())) {
00920
00921 Int_t termIdx = terms.IndexOf(term) ;
00922 norm=(RooArgSet*) norms.At(termIdx) ;
00923 imps=(RooArgSet*)imp.At(termIdx) ;
00924 RooArgSet termNSet(*norm), termImpSet(*imps) ;
00925
00926 if (termImpSet.getSize()>0 && _refRangeName!=0) {
00927
00928
00929 Bool_t rangeIdentical(kTRUE) ;
00930 TIterator* niter = termNSet.createIterator() ;
00931 RooRealVar* normObs ;
00932
00933 if(_normRange.Length()>0){
00934 while((normObs=(RooRealVar*)niter->Next())) {
00935 if (normObs->getMin(_normRange.Data())!=normObs->getMin(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00936 if (normObs->getMax(_normRange.Data())!=normObs->getMax(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00937 }
00938 }
00939 else{
00940 while((normObs=(RooRealVar*)niter->Next())) {
00941 if (normObs->getMin()!=normObs->getMin(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00942 if (normObs->getMax()!=normObs->getMax(RooNameReg::str(_refRangeName))) rangeIdentical=kFALSE ;
00943 }
00944 }
00945
00946 delete niter ;
00947 if (!rangeIdentical || 1) {
00948
00949 RooAbsReal* ratio = makeCondPdfRatioCorr(*(RooAbsReal*)term->first(),termNSet,termImpSet,normRange(),RooNameReg::str(_refRangeName)) ;
00950 ostringstream str ; termImpSet.printValue(str) ;
00951 ratioTerms[str.str()].add(*ratio) ;
00952 }
00953 }
00954 }
00955 delete tIter ;
00956 }
00957
00958 }
00959 gIter->Reset() ;
00960
00961
00962
00963 while((group=(RooLinkedList*)gIter->Next())) {
00964 if (group->GetSize()==1) {
00965 RooArgSet* term = (RooArgSet*) group->At(0) ;
00966
00967 Int_t termIdx = terms.IndexOf(term) ;
00968 norm=(RooArgSet*) norms.At(termIdx) ;
00969 imps=(RooArgSet*)imp.At(termIdx) ;
00970 RooArgSet termNSet(*norm), termImpSet(*imps) ;
00971
00972
00973 ostringstream str ; termNSet.printValue(str) ;
00974 if (ratioTerms[str.str()].getSize()>0) {
00975
00976 term->add(ratioTerms[str.str()]) ;
00977 }
00978
00979 } else {
00980
00981 RooArgSet compTermSet, compTermNorm ;
00982 TIterator* tIter = group->MakeIterator() ;
00983 RooArgSet* term ;
00984 while((term=(RooArgSet*)tIter->Next())) {
00985
00986 Int_t termIdx = terms.IndexOf(term) ;
00987 norm=(RooArgSet*) norms.At(termIdx) ;
00988 imps=(RooArgSet*)imp.At(termIdx) ;
00989 RooArgSet termNSet(*norm), termImpSet(*imps) ;
00990
00991
00992 ostringstream str ; termNSet.printValue(str) ;
00993 if (ratioTerms[str.str()].getSize()>0) {
00994
00995 term->add(ratioTerms[str.str()]) ;
00996 }
00997
00998 }
00999 delete tIter ;
01000 }
01001 }
01002 gIter->Reset() ;
01003
01004
01005 while((group=(RooLinkedList*)gIter->Next())) {
01006
01007
01008
01009
01010 if (group->GetSize()==1) {
01011
01012 RooArgSet* term = (RooArgSet*) group->At(0) ;
01013
01014 Int_t termIdx = terms.IndexOf(term) ;
01015 norm=(RooArgSet*) norms.At(termIdx) ;
01016 integ=(RooArgSet*) ints.At(termIdx) ;
01017 xdeps=(RooArgSet*)cross.At(termIdx) ;
01018 imps=(RooArgSet*)imp.At(termIdx) ;
01019
01020 RooArgSet termNSet, termISet, termXSet, termImpSet ;
01021
01022
01023 termISet.add(*integ) ;
01024 termNSet.add(*norm) ;
01025
01026
01027 termXSet.add(*xdeps) ;
01028 termImpSet.add(*imps) ;
01029
01030
01031
01032
01033
01034
01035
01036 Bool_t isOwned ;
01037 vector<RooAbsReal*> func = processProductTerm(nset,iset,isetRangeName,term,termNSet,termISet,isOwned) ;
01038 if (func[0]) {
01039 cache->_partList.add(*func[0]) ;
01040 if (isOwned) cache->_ownedList.addOwned(*func[0]) ;
01041
01042 cache->_normList.Add(norm->snapshot(kFALSE)) ;
01043
01044 cache->_numList.addOwned(*func[1]) ;
01045 cache->_denList.addOwned(*func[2]) ;
01046
01047
01048
01049 }
01050 } else {
01051
01052
01053 RooArgSet compTermSet, compTermNorm, compTermNum, compTermDen ;
01054 TIterator* tIter = group->MakeIterator() ;
01055 RooArgSet* term ;
01056 while((term=(RooArgSet*)tIter->Next())) {
01057
01058
01059
01060 Int_t termIdx = terms.IndexOf(term) ;
01061 norm=(RooArgSet*) norms.At(termIdx) ;
01062 integ=(RooArgSet*) ints.At(termIdx) ;
01063 xdeps=(RooArgSet*)cross.At(termIdx) ;
01064 imps=(RooArgSet*)imp.At(termIdx) ;
01065
01066 RooArgSet termNSet, termISet, termXSet, termImpSet ;
01067 termISet.add(*integ) ;
01068 termNSet.add(*norm) ;
01069 termXSet.add(*xdeps) ;
01070 termImpSet.add(*imps) ;
01071
01072
01073 termISet.remove(outerIntDeps,kTRUE,kTRUE) ;
01074
01075
01076
01077
01078
01079
01080
01081 Bool_t isOwned ;
01082 vector<RooAbsReal*> func = processProductTerm(nset,iset,isetRangeName,term,termNSet,termISet,isOwned,kTRUE) ;
01083
01084 if (func[0]) {
01085 compTermSet.add(*func[0]) ;
01086 if (isOwned) cache->_ownedList.addOwned(*func[0]) ;
01087 compTermNorm.add(*norm,kFALSE) ;
01088
01089 compTermNum.add(*func[1]) ;
01090 compTermDen.add(*func[2]) ;
01091
01092
01093
01094
01095
01096
01097 }
01098 }
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109 const char* prodname = makeRGPPName("SPECPROD",compTermSet,outerIntDeps,RooArgSet(),isetRangeName) ;
01110 RooProduct* prodtmp = new RooProduct(prodname,prodname,compTermSet) ;
01111 cache->_ownedList.addOwned(*prodtmp) ;
01112
01113 const char* intname = makeRGPPName("SPECINT",compTermSet,outerIntDeps,RooArgSet(),isetRangeName) ;
01114 RooRealIntegral* inttmp = new RooRealIntegral(intname,intname,*prodtmp,outerIntDeps,0,0,isetRangeName) ;
01115 inttmp->setStringAttribute("PROD_TERM_TYPE","SPECINT") ;
01116
01117 cache->_ownedList.addOwned(*inttmp) ;
01118 cache->_partList.add(*inttmp);
01119
01120
01121 string prodname_num = makeRGPPName("SPECPROD_NUM",compTermNum,RooArgSet(),RooArgSet(),0) ;
01122 RooProduct* prodtmp_num = new RooProduct(prodname_num.c_str(),prodname_num.c_str(),compTermNum) ;
01123 prodtmp_num->addOwnedComponents(compTermNum) ;
01124 cache->_ownedList.addOwned(*prodtmp_num) ;
01125
01126
01127 string prodname_den = makeRGPPName("SPECPROD_DEN",compTermDen,RooArgSet(),RooArgSet(),0) ;
01128 RooProduct* prodtmp_den = new RooProduct(prodname_den.c_str(),prodname_den.c_str(),compTermDen) ;
01129 prodtmp_den->addOwnedComponents(compTermDen) ;
01130 cache->_ownedList.addOwned(*prodtmp_den) ;
01131
01132
01133 string name = Form("SPEC_RATIO(%s,%s)",prodname_num.c_str(),prodname_den.c_str()) ;
01134 RooFormulaVar* ndr = new RooFormulaVar(name.c_str(),"@0/@1",RooArgList(*prodtmp_num,*prodtmp_den)) ;
01135
01136
01137 RooAbsReal* numtmp = ndr->createIntegral(outerIntDeps,isetRangeName) ;
01138 numtmp->addOwnedComponents(*ndr) ;
01139
01140 cache->_numList.addOwned(*numtmp) ;
01141 cache->_denList.addOwned(*(RooAbsArg*)RooFit::RooConst(1).clone("1")) ;
01142 cache->_normList.Add(compTermNorm.snapshot(kFALSE)) ;
01143
01144 delete tIter ;
01145 }
01146 }
01147 delete gIter ;
01148
01149
01150 code = _cacheMgr.setObj(nset,iset,(RooAbsCacheElement*)cache,RooNameReg::ptr(isetRangeName)) ;
01151
01152
01153 partList = &cache->_partList ;
01154 nsetList = &cache->_normList;
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166 partListPointer=(RooArgList*)partList ;
01167 nsetListPointer=(RooLinkedList*)nsetList ;
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181 if (_normRange.Contains(",")) {
01182 rearrangeProduct(*cache) ;
01183 }
01184
01185
01186 groupedList.Delete() ;
01187 terms.Delete() ;
01188 ints.Delete() ;
01189 imp.Delete() ;
01190 norms.Delete() ;
01191 cross.Delete() ;
01192 }
01193
01194
01195
01196
01197
01198 RooAbsReal* RooProdPdf::makeCondPdfRatioCorr(RooAbsReal& pdf, const RooArgSet& termNset, const RooArgSet& , const char* normRangeTmp, const char* refRange) const
01199 {
01200
01201 RooAbsReal* ratio_num = pdf.createIntegral(termNset,normRangeTmp) ;
01202 RooAbsReal* ratio_den = pdf.createIntegral(termNset,refRange) ;
01203 RooFormulaVar* ratio = new RooFormulaVar(Form("ratio(%s,%s)",ratio_num->GetName(),ratio_den->GetName()),"@0/@1",
01204 RooArgList(*ratio_num,*ratio_den)) ;
01205
01206 ratio->addOwnedComponents(RooArgSet(*ratio_num,*ratio_den)) ;
01207 ratio->setAttribute("RATIO_TERM") ;
01208 return ratio ;
01209 }
01210
01211
01212
01213
01214
01215 void RooProdPdf::rearrangeProduct(RooProdPdf::CacheElem& cache) const
01216 {
01217 TIterator* iterp = cache._partList.createIterator() ;
01218 TIterator* iter1 = cache._numList.createIterator() ;
01219 TIterator* iter2 = cache._denList.createIterator() ;
01220 TIterator* itern = cache._normList.MakeIterator() ;
01221 RooAbsReal* part, *num, *den ;
01222 RooArgSet* nset ;
01223 RooArgSet nomList ;
01224
01225 list<string> rangeComps ;
01226 char buf[1024] ;
01227 strlcpy(buf,_normRange.Data(),1024) ;
01228 char* save(0) ;
01229 char* token = strtok_r(buf,",",&save) ;
01230 while(token) {
01231 rangeComps.push_back(token) ;
01232 token = strtok_r(0,",",&save) ;
01233 }
01234
01235
01236 map<string,RooArgSet> denListList ;
01237 RooArgSet specIntDeps ;
01238 string specIntRange ;
01239
01240
01241
01242 while((part=(RooAbsReal*)iterp->Next())) {
01243
01244
01245 nset = (RooArgSet*) itern->Next() ;
01246 num = (RooAbsReal*) iter1->Next() ;
01247 den = (RooAbsReal*) iter2->Next() ;
01248
01249
01250
01251
01252
01253
01254 RooFormulaVar* ratio(0) ;
01255 RooArgSet origNumTerm ;
01256
01257 if (string("SPECINT")==part->getStringAttribute("PROD_TERM_TYPE")) {
01258
01259 RooRealIntegral* orig = (RooRealIntegral*) num;
01260 RooFormulaVar* specratio = (RooFormulaVar*) &orig->integrand() ;
01261 RooProduct* func = (RooProduct*) specratio->getParameter(0) ;
01262
01263 RooArgSet* comps = orig->getComponents() ;
01264 TIterator* iter = comps->createIterator() ;
01265 RooAbsArg* carg ;
01266 while((carg=(RooAbsArg*)iter->Next())) {
01267 if (carg->getAttribute("RATIO_TERM")) {
01268 ratio = (RooFormulaVar*)carg ;
01269 break ;
01270 }
01271 }
01272 delete iter ;
01273 delete comps ;
01274
01275 if (ratio) {
01276 RooCustomizer cust(*func,"blah") ;
01277 cust.replaceArg(*ratio,RooFit::RooConst(1)) ;
01278 RooAbsArg* funcCust = cust.build() ;
01279
01280
01281 nomList.add(*funcCust) ;
01282 } else {
01283 nomList.add(*func) ;
01284 }
01285
01286
01287 } else {
01288
01289
01290 RooAbsReal* func = num;
01291
01292 if (func->InheritsFrom(RooRealIntegral::Class())) {
01293 func = (RooAbsReal*) &((RooRealIntegral*)(func))->integrand();
01294 }
01295 if (func->InheritsFrom(RooProduct::Class())) {
01296
01297 RooArgSet comps(((RooProduct*)(func))->components()) ;
01298 TIterator* iter = comps.createIterator() ;
01299 RooAbsArg* arg ;
01300 while((arg=(RooAbsArg*)iter->Next())) {
01301 if (arg->getAttribute("RATIO_TERM")) {
01302 ratio = (RooFormulaVar*)(arg) ;
01303 } else {
01304 origNumTerm.add(*arg) ;
01305 }
01306 }
01307 delete iter ;
01308 }
01309
01310 if (ratio) {
01311
01312
01313 nomList.add(origNumTerm) ;
01314 } else {
01315 nomList.add(*num) ;
01316 }
01317
01318 }
01319
01320 for (list<string>::iterator iter = rangeComps.begin() ; iter != rangeComps.end() ; ++iter) {
01321
01322
01323
01324
01325 if (string("SPECINT")==part->getStringAttribute("PROD_TERM_TYPE")) {
01326
01327
01328 RooRealIntegral* orig = (RooRealIntegral*) num;
01329 RooFormulaVar* specRatio = (RooFormulaVar*) &orig->integrand() ;
01330 specIntDeps.add(orig->intVars()) ;
01331 if (orig->intRange()) {
01332 specIntRange = orig->intRange() ;
01333 }
01334
01335 RooProduct* dentmp = (RooProduct*) specRatio->getParameter(1) ;
01336
01337
01338
01339
01340
01341 RooArgSet comps(dentmp->components()) ;
01342 TIterator* piter = comps.createIterator() ;
01343 RooAbsReal* parg ;
01344 while((parg=(RooAbsReal*)piter->Next())) {
01345
01346
01347 if (ratio && parg->dependsOn(*ratio)) {
01348
01349
01350
01351 RooAbsReal* specializedRatio = specializeRatio(*(RooFormulaVar*)ratio,iter->c_str()) ;
01352
01353
01354
01355
01356
01357 RooAbsArg *partCust(0) ;
01358 if (parg->InheritsFrom(RooAddition::Class())) {
01359
01360
01361
01362 RooAddition* tmpadd = (RooAddition*)(parg) ;
01363
01364 RooCustomizer cust(*tmpadd->list1().first(),Form("blah_%s",iter->c_str())) ;
01365 cust.replaceArg(*ratio,*specializedRatio) ;
01366 partCust = cust.build() ;
01367
01368 } else {
01369 RooCustomizer cust(*parg,Form("blah_%s",iter->c_str())) ;
01370 cust.replaceArg(*ratio,*specializedRatio) ;
01371 partCust = cust.build() ;
01372 }
01373
01374
01375
01376
01377
01378 RooAbsReal* specializedPartCust = specializeIntegral(*(RooAbsReal*)partCust,iter->c_str()) ;
01379
01380
01381 string name = Form("%s_divided_by_ratio",specializedPartCust->GetName()) ;
01382 RooFormulaVar* specIntFinal = new RooFormulaVar(name.c_str(),"@0/@1",RooArgList(*specializedPartCust,*specializedRatio)) ;
01383
01384 denListList[*iter].add(*specIntFinal) ;
01385 } else {
01386
01387
01388
01389
01390 denListList[*iter].add(*specializeIntegral(*parg,iter->c_str())) ;
01391
01392 }
01393 }
01394
01395 delete piter ;
01396
01397
01398 } else {
01399
01400 if (ratio) {
01401
01402 RooAbsReal* specRatio = specializeRatio(*(RooFormulaVar*)ratio,iter->c_str()) ;
01403
01404
01405
01406
01407 RooArgSet tmp(origNumTerm) ;
01408 tmp.add(*specRatio) ;
01409 string pname = makeRGPPName("PROD",tmp,RooArgSet(),RooArgSet(),0) ;
01410 RooProduct* specDenProd = new RooProduct(pname.c_str(),pname.c_str(),tmp) ;
01411 RooAbsReal* specInt(0) ;
01412
01413 if (den->InheritsFrom(RooRealIntegral::Class())) {
01414 specInt = specDenProd->createIntegral(((RooRealIntegral*)den)->intVars(),iter->c_str()) ;
01415 } else if (den->InheritsFrom(RooAddition::Class())) {
01416 RooAddition* orig = (RooAddition*)den ;
01417 RooRealIntegral* origInt = (RooRealIntegral*) orig->list1().first() ;
01418 specInt = specDenProd->createIntegral(origInt->intVars(),iter->c_str()) ;
01419 } else {
01420 throw string("this should not happen") ;
01421 }
01422
01423
01424 string name = Form("%s_divided_by_ratio",specInt->GetName()) ;
01425 RooFormulaVar* specIntFinal = new RooFormulaVar(name.c_str(),"@0/@1",RooArgList(*specInt,*specRatio)) ;
01426 denListList[*iter].add(*specIntFinal) ;
01427 } else {
01428 denListList[*iter].add(*specializeIntegral(*den,iter->c_str())) ;
01429 }
01430
01431 }
01432 }
01433
01434 }
01435
01436
01437 if (nomList.getSize()==0) {
01438 delete iter1 ;
01439 delete iter2 ;
01440 delete itern ;
01441 return ;
01442 }
01443
01444 string name = Form("%s_numerator",GetName()) ;
01445
01446
01447 RooAbsReal* numerator = new RooProduct(name.c_str(),name.c_str(),nomList) ;
01448
01449 RooArgSet products ;
01450
01451 for (map<string,RooArgSet>::iterator iter = denListList.begin() ; iter != denListList.end() ; ++iter) {
01452
01453 name = Form("%s_denominator_comp_%s",GetName(),iter->first.c_str()) ;
01454
01455 RooProduct* prod_comp = new RooProduct(name.c_str(),name.c_str(),iter->second) ;
01456 products.add(*prod_comp) ;
01457 }
01458 name = Form("%s_denominator_sum",GetName()) ;
01459 RooAbsReal* norm = new RooAddition(name.c_str(),name.c_str(),products) ;
01460 norm->addOwnedComponents(products) ;
01461
01462 if (specIntDeps.getSize()>0) {
01463
01464
01465 string namesr = Form("SPEC_RATIO(%s,%s)",numerator->GetName(),norm->GetName()) ;
01466 RooFormulaVar* ndr = new RooFormulaVar(namesr.c_str(),"@0/@1",RooArgList(*numerator,*norm)) ;
01467
01468
01469 RooAbsReal* numtmp = ndr->createIntegral(specIntDeps,specIntRange.c_str()) ;
01470
01471 numerator = numtmp ;
01472 norm = (RooAbsReal*) RooFit::RooConst(1).Clone() ;
01473 }
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485 cache._rearrangedNum = numerator ;
01486 cache._rearrangedDen = norm ;
01487 cache._isRearranged = kTRUE ;
01488
01489 delete iter1 ;
01490 delete iter2 ;
01491 delete iterp ;
01492 delete itern ;
01493
01494 }
01495
01496
01497
01498 RooAbsReal* RooProdPdf::specializeRatio(RooFormulaVar& input, const char* targetRangeName) const
01499 {
01500 RooRealIntegral* numint = (RooRealIntegral*) input.getParameter(0) ;
01501 RooRealIntegral* denint = (RooRealIntegral*) input.getParameter(1) ;
01502
01503 RooAbsReal* numint_spec = specializeIntegral(*numint,targetRangeName) ;
01504
01505 RooAbsReal* ret = new RooFormulaVar(Form("ratio(%s,%s)",numint_spec->GetName(),denint->GetName()),"@0/@1",RooArgList(*numint_spec,*denint)) ;
01506 ret->addOwnedComponents(*numint_spec) ;
01507
01508 return ret ;
01509 }
01510
01511
01512
01513
01514 RooAbsReal* RooProdPdf::specializeIntegral(RooAbsReal& input, const char* targetRangeName) const
01515 {
01516 if (input.InheritsFrom(RooRealIntegral::Class())) {
01517
01518
01519 RooRealIntegral* orig = (RooRealIntegral*)&input ;
01520
01521 return orig->integrand().createIntegral(orig->intVars(),targetRangeName) ;
01522
01523 } else if (input.InheritsFrom(RooAddition::Class())) {
01524
01525
01526 RooAddition* orig = (RooAddition*)&input ;
01527 RooRealIntegral* origInt = (RooRealIntegral*) orig->list1().first() ;
01528
01529 return origInt->integrand().createIntegral(origInt->intVars(),targetRangeName) ;
01530
01531 } else {
01532
01533
01534 }
01535
01536 return &input ;
01537 }
01538
01539
01540
01541 void RooProdPdf::groupProductTerms(RooLinkedList& groupedTerms, RooArgSet& outerIntDeps,
01542 const RooLinkedList& terms, const RooLinkedList& norms,
01543 const RooLinkedList& imps, const RooLinkedList& ints, const RooLinkedList& ) const
01544 {
01545
01546
01547
01548 TIterator* tIter = terms.MakeIterator() ;
01549 RooArgSet* term ;
01550 while((term=(RooArgSet*)tIter->Next())) {
01551 RooLinkedList* group = new RooLinkedList ;
01552 group->Add(term) ;
01553 groupedTerms.Add(group) ;
01554 }
01555 delete tIter ;
01556
01557
01558 RooArgSet allImpDeps ;
01559 TIterator* iIter = imps.MakeIterator() ;
01560 RooArgSet *impDeps ;
01561 while((impDeps=(RooArgSet*)iIter->Next())) {
01562 allImpDeps.add(*impDeps,kFALSE) ;
01563 }
01564 delete iIter ;
01565
01566
01567 RooArgSet allIntDeps ;
01568 iIter = ints.MakeIterator() ;
01569 RooArgSet *intDeps ;
01570 while((intDeps=(RooArgSet*)iIter->Next())) {
01571 allIntDeps.add(*intDeps,kFALSE) ;
01572 }
01573 delete iIter ;
01574
01575 RooArgSet* tmp = (RooArgSet*) allIntDeps.selectCommon(allImpDeps) ;
01576 outerIntDeps.removeAll() ;
01577 outerIntDeps.add(*tmp) ;
01578 delete tmp ;
01579
01580
01581 TIterator* oidIter = outerIntDeps.createIterator() ;
01582 TIterator* glIter = groupedTerms.MakeIterator() ;
01583 RooAbsArg* outerIntDep ;
01584 while ((outerIntDep =(RooAbsArg*)oidIter->Next())) {
01585
01586
01587 RooLinkedList* newGroup = 0 ;
01588
01589
01590 RooLinkedList* group ;
01591 glIter->Reset() ;
01592 Bool_t needMerge = kFALSE ;
01593 while((group=(RooLinkedList*)glIter->Next())) {
01594
01595
01596 RooArgSet* term2 ;
01597 TIterator* tIter2 = group->MakeIterator() ;
01598 while((term2=(RooArgSet*)tIter2->Next())) {
01599
01600 Int_t termIdx = terms.IndexOf(term2) ;
01601 RooArgSet* termNormDeps = (RooArgSet*) norms.At(termIdx) ;
01602 RooArgSet* termIntDeps = (RooArgSet*) ints.At(termIdx) ;
01603 RooArgSet* termImpDeps = (RooArgSet*) imps.At(termIdx) ;
01604
01605 if (termNormDeps->contains(*outerIntDep) ||
01606 termIntDeps->contains(*outerIntDep) ||
01607 termImpDeps->contains(*outerIntDep)) {
01608 needMerge = kTRUE ;
01609 }
01610
01611 }
01612
01613 if (needMerge) {
01614
01615 if (newGroup==0) {
01616 newGroup = new RooLinkedList ;
01617 }
01618
01619
01620 tIter2->Reset() ;
01621 while((term2=(RooArgSet*)tIter2->Next())) {
01622 newGroup->Add(term2) ;
01623 }
01624
01625
01626 groupedTerms.Remove(group) ;
01627 delete group ;
01628 }
01629 delete tIter2 ;
01630 }
01631
01632 if (newGroup) {
01633 groupedTerms.Add(newGroup) ;
01634 }
01635
01636 }
01637
01638 delete glIter ;
01639 delete oidIter ;
01640 }
01641
01642
01643
01644
01645 std::vector<RooAbsReal*> RooProdPdf::processProductTerm(const RooArgSet* nset, const RooArgSet* iset, const char* isetRangeName,
01646 const RooArgSet* term,const RooArgSet& termNSet, const RooArgSet& termISet,
01647 Bool_t& isOwned, Bool_t forceWrap) const
01648 {
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 vector<RooAbsReal*> ret(3) ; ret[0] = 0 ; ret[1] = 0 ; ret[2] = 0 ;
01663
01664
01665
01666
01667 if (termNSet.getSize()>0 && termNSet.getSize()==termISet.getSize() && isetRangeName==0) {
01668
01669
01670
01671
01672
01673 return ret ;
01674 }
01675
01676
01677
01678 if (nset && termNSet.getSize()==0) {
01679
01680
01681
01682
01683 return ret ;
01684 }
01685
01686 if (iset && termISet.getSize()>0) {
01687 if (term->getSize()==1) {
01688
01689
01690
01691
01692 TIterator* pIter = term->createIterator() ;
01693 RooAbsPdf* pdf = (RooAbsPdf*) pIter->Next() ;
01694 delete pIter ;
01695
01696 RooAbsReal* partInt = pdf->createIntegral(termISet,termNSet,isetRangeName) ;
01697
01698 partInt->setStringAttribute("PROD_TERM_TYPE","IIIa") ;
01699
01700 isOwned=kTRUE ;
01701
01702
01703
01704 ret[0] = partInt ;
01705
01706
01707 ret[1] = pdf->createIntegral(termISet,isetRangeName) ;
01708 ret[2] = pdf->createIntegral(termNSet,normRange()) ;
01709
01710 return ret ;
01711
01712
01713 } else {
01714
01715
01716
01717
01718
01719 const char* name = makeRGPPName("GENPROJ_",*term,termISet,termNSet,isetRangeName) ;
01720 RooAbsReal* partInt = new RooGenProdProj(name,name,*term,termISet,termNSet,isetRangeName) ;
01721 partInt->setStringAttribute("PROD_TERM_TYPE","IIIb") ;
01722
01723
01724
01725
01726 isOwned=kTRUE ;
01727 ret[0] = partInt ;
01728
01729 const char* name1 = makeRGPPName("PROD",*term,RooArgSet(),RooArgSet(),0) ;
01730
01731
01732 RooProduct* tmp_prod = new RooProduct(name1,name1,*term) ;
01733
01734 ret[1] = tmp_prod->createIntegral(termISet,isetRangeName) ;
01735 ret[2] = tmp_prod->createIntegral(termNSet,normRange()) ;
01736
01737 return ret ;
01738 }
01739 }
01740
01741
01742
01743 if (nset && nset->getSize()>0 && term->getSize()>1) {
01744
01745
01746 const char* name = makeRGPPName("GENPROJ_",*term,termISet,termNSet,isetRangeName) ;
01747 RooAbsReal* partInt = new RooGenProdProj(name,name,*term,termISet,termNSet,isetRangeName,normRange()) ;
01748 partInt->setStringAttribute("PROD_TERM_TYPE","IVa") ;
01749
01750
01751
01752
01753 isOwned=kTRUE ;
01754 ret[0] = partInt ;
01755
01756 const char* name1 = makeRGPPName("PROD",*term,RooArgSet(),RooArgSet(),0) ;
01757
01758
01759 RooProduct* tmp_prod = new RooProduct(name1,name1,*term) ;
01760
01761 ret[1] = tmp_prod->createIntegral(termISet,isetRangeName) ;
01762 ret[2] = tmp_prod->createIntegral(termNSet,normRange()) ;
01763
01764 return ret ;
01765 }
01766
01767
01768
01769 TIterator* pIter = term->createIterator() ;
01770 RooAbsPdf* pdf ;
01771 while((pdf=(RooAbsPdf*)pIter->Next())) {
01772
01773 if (forceWrap) {
01774
01775
01776 TString name(pdf->GetName()) ;
01777 name.Append("_NORM[") ;
01778 TIterator* nIter = termNSet.createIterator() ;
01779 RooAbsArg* arg ;
01780 Bool_t first(kTRUE) ;
01781 while((arg=(RooAbsArg*)nIter->Next())) {
01782 if (!first) {
01783 name.Append(",") ;
01784 } else {
01785 first=kFALSE ;
01786 }
01787 name.Append(arg->GetName()) ;
01788 }
01789 if (normRange()) {
01790 name.Append("|") ;
01791 name.Append(normRange()) ;
01792 }
01793 name.Append("]") ;
01794 delete nIter ;
01795
01796
01797 RooAbsReal* partInt = new RooRealIntegral(name.Data(),name.Data(),*pdf,RooArgSet(),&termNSet) ;
01798 partInt->setStringAttribute("PROD_TERM_TYPE","IVb") ;
01799 isOwned=kTRUE ;
01800
01801
01802
01803 delete pIter ;
01804 ret[0] = partInt ;
01805
01806 ret[1] = pdf->createIntegral(RooArgSet()) ;
01807 ret[2] = pdf->createIntegral(termNSet,normRange()) ;
01808
01809 return ret ;
01810
01811
01812 } else {
01813 isOwned=kFALSE ;
01814
01815 delete pIter ;
01816
01817 pdf->setStringAttribute("PROD_TERM_TYPE","IVb") ;
01818 ret[0] = pdf ;
01819
01820 ret[1] = pdf->createIntegral(RooArgSet()) ;
01821 ret[2] = termNSet.getSize()>0 ? pdf->createIntegral(termNSet,normRange()) : ((RooAbsReal*)RooFit::RooConst(1).clone("1")) ;
01822 return ret ;
01823 }
01824 }
01825 delete pIter ;
01826
01827 coutE(Eval) << "RooProdPdf::processProductTerm(" << GetName() << ") unidentified term!!!" << endl ;
01828 return ret ;
01829 }
01830
01831
01832
01833
01834
01835 const char* RooProdPdf::makeRGPPName(const char* pfx, const RooArgSet& term, const RooArgSet& iset,
01836 const RooArgSet& nset, const char* isetRangeName) const
01837 {
01838
01839
01840 static TString pname ;
01841 pname = pfx ;
01842 pname.Append("[") ;
01843
01844 TIterator* pIter = term.createIterator() ;
01845
01846
01847 Bool_t first(kTRUE) ;
01848 RooAbsPdf* pdf ;
01849 while((pdf=(RooAbsPdf*)pIter->Next())) {
01850 if (first) {
01851 first = kFALSE ;
01852 } else {
01853 pname.Append("_X_") ;
01854 }
01855 pname.Append(pdf->GetName()) ;
01856 }
01857 delete pIter ;
01858 pname.Append("]") ;
01859
01860 pname.Append(integralNameSuffix(iset,&nset,isetRangeName,kTRUE)) ;
01861
01862 return pname.Data() ;
01863 }
01864
01865
01866
01867
01868 Bool_t RooProdPdf::forceAnalyticalInt(const RooAbsArg& ) const
01869 {
01870
01871 return kTRUE ;
01872 }
01873
01874
01875
01876
01877 Int_t RooProdPdf::getAnalyticalIntegralWN(RooArgSet& allVars, RooArgSet& analVars,
01878 const RooArgSet* normSet, const char* rangeName) const
01879 {
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890
01891
01892
01893
01894 if (_forceNumInt) return 0 ;
01895
01896
01897 analVars.add(allVars) ;
01898
01899
01900 Int_t code ;
01901 RooArgList *plist(0) ;
01902 RooLinkedList *nlist(0) ;
01903 getPartIntList(normSet,&allVars,plist,nlist,code,rangeName) ;
01904
01905
01906 return code+1 ;
01907 }
01908
01909
01910
01911
01912
01913 Double_t RooProdPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
01914 {
01915
01916
01917
01918 if (code==0) {
01919 return getVal(normSet) ;
01920 }
01921
01922
01923
01924
01925 CacheElem* cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1) ;
01926
01927 RooArgList* partIntList(0) ;
01928 RooLinkedList* normList(0) ;
01929
01930
01931 if (cache==0) {
01932 RooArgSet* vars = getParameters(RooArgSet()) ;
01933 RooArgSet* nset = _cacheMgr.nameSet1ByIndex(code-1)->select(*vars) ;
01934 RooArgSet* iset = _cacheMgr.nameSet2ByIndex(code-1)->select(*vars) ;
01935
01936 Int_t code2(-1) ;
01937 getPartIntList(nset,iset,partIntList,normList,code2,rangeName) ;
01938
01939 delete vars ;
01940 delete nset ;
01941 delete iset ;
01942
01943
01944
01945 cache = (CacheElem*) _cacheMgr.getObj(nset,iset,&code2,RooNameReg::ptr(rangeName)) ;
01946
01947
01948 } else {
01949
01950 partIntList = &cache->_partList ;
01951 normList = &cache->_normList ;
01952
01953 }
01954
01955
01956
01957 Double_t val = calculate(*cache,kTRUE) ;
01958
01959
01960 return val ;
01961 }
01962
01963
01964
01965
01966 Bool_t RooProdPdf::checkObservables(const RooArgSet* ) const
01967 {
01968
01969 return kFALSE ;
01970
01971 }
01972
01973
01974
01975
01976
01977 RooAbsPdf::ExtendMode RooProdPdf::extendMode() const
01978 {
01979
01980
01981 return (_extendedIndex>=0) ? ((RooAbsPdf*)_pdfList.at(_extendedIndex))->extendMode() : CanNotBeExtended ;
01982 }
01983
01984
01985
01986
01987 Double_t RooProdPdf::expectedEvents(const RooArgSet* nset) const
01988 {
01989
01990
01991
01992 if (_extendedIndex<0) {
01993 coutE(Generation) << "ERROR: Requesting expected number of events from a RooProdPdf that does not contain an extended p.d.f" << endl ;
01994 }
01995 assert(_extendedIndex>=0) ;
01996 return ((RooAbsPdf*)_pdfList.at(_extendedIndex))->expectedEvents(nset) ;
01997 }
01998
01999
02000
02001
02002
02003 RooAbsGenContext* RooProdPdf::genContext(const RooArgSet &vars, const RooDataSet *prototype,
02004 const RooArgSet* auxProto, Bool_t verbose) const
02005 {
02006
02007
02008 if (_useDefaultGen) return RooAbsPdf::genContext(vars,prototype,auxProto,verbose) ;
02009 return new RooProdGenContext(*this,vars,prototype,auxProto,verbose) ;
02010 }
02011
02012
02013
02014
02015 Int_t RooProdPdf::getGenerator(const RooArgSet& directVars, RooArgSet &generateVars, Bool_t staticInitOK) const
02016 {
02017
02018
02019
02020 if (!_useDefaultGen) return 0 ;
02021
02022
02023 RooArgSet directSafe ;
02024 TIterator* dIter = directVars.createIterator() ;
02025 RooAbsArg* arg ;
02026 while((arg=(RooAbsArg*)dIter->Next())) {
02027 if (isDirectGenSafe(*arg)) directSafe.add(*arg) ;
02028 }
02029 delete dIter ;
02030
02031
02032
02033 _pdfIter->Reset() ;
02034 RooAbsPdf* pdf ;
02035 Int_t code[64], n(0) ;
02036 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
02037 RooArgSet pdfDirect ;
02038 code[n] = pdf->getGenerator(directSafe,pdfDirect,staticInitOK) ;
02039 if (code[n]!=0) {
02040 generateVars.add(pdfDirect) ;
02041 }
02042 n++ ;
02043 }
02044
02045
02046 if (generateVars.getSize()>0) {
02047 Int_t masterCode = _genCode.store(code,n) ;
02048 return masterCode+1 ;
02049 } else {
02050 return 0 ;
02051 }
02052 }
02053
02054
02055
02056
02057 void RooProdPdf::initGenerator(Int_t code)
02058 {
02059
02060
02061
02062 if (!_useDefaultGen) return ;
02063
02064 const Int_t* codeList = _genCode.retrieve(code-1) ;
02065 _pdfIter->Reset() ;
02066 RooAbsPdf* pdf ;
02067 Int_t i(0) ;
02068 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
02069 if (codeList[i]!=0) {
02070 pdf->initGenerator(codeList[i]) ;
02071 }
02072 i++ ;
02073 }
02074 }
02075
02076
02077
02078
02079 void RooProdPdf::generateEvent(Int_t code)
02080 {
02081
02082
02083
02084
02085 if (!_useDefaultGen) return ;
02086
02087 const Int_t* codeList = _genCode.retrieve(code-1) ;
02088 _pdfIter->Reset() ;
02089 RooAbsPdf* pdf ;
02090 Int_t i(0) ;
02091 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
02092 if (codeList[i]!=0) {
02093 pdf->generateEvent(codeList[i]) ;
02094 }
02095 i++ ;
02096 }
02097
02098 }
02099
02100
02101
02102
02103 RooProdPdf::CacheElem::~CacheElem()
02104 {
02105
02106
02107 if (_rearrangedNum) delete _rearrangedNum ;
02108 if (_rearrangedDen) delete _rearrangedDen ;
02109
02110 }
02111
02112
02113
02114
02115 RooArgList RooProdPdf::CacheElem::containedArgs(Action)
02116 {
02117
02118 RooArgList ret ;
02119 ret.add(_partList) ;
02120 ret.add(_numList) ;
02121 ret.add(_denList) ;
02122 if (_rearrangedNum) ret.add(*_rearrangedNum) ;
02123 if (_rearrangedDen) ret.add(*_rearrangedDen) ;
02124 return ret ;
02125
02126 }
02127
02128
02129
02130
02131 void RooProdPdf::CacheElem::printCompactTreeHook(ostream& os, const char* indent, Int_t curElem, Int_t maxElem)
02132 {
02133
02134
02135 if (curElem==0) {
02136 os << indent << "RooProdPdf begin partial integral cache" << endl ;
02137 }
02138
02139 TIterator* iter = _partList.createIterator() ;
02140 RooAbsArg* arg ;
02141 TString indent2(indent) ;
02142 indent2 += Form("[%d] ",curElem) ;
02143 while((arg=(RooAbsArg*)iter->Next())) {
02144 arg->printCompactTree(os,indent2) ;
02145 }
02146 delete iter ;
02147
02148 if (curElem==maxElem) {
02149 os << indent << "RooProdPdf end partial integral cache" << endl ;
02150 }
02151 }
02152
02153
02154
02155
02156 Bool_t RooProdPdf::isDirectGenSafe(const RooAbsArg& arg) const
02157 {
02158
02159
02160
02161
02162 if (!_useDefaultGen) return RooAbsPdf::isDirectGenSafe(arg) ;
02163
02164
02165 _pdfIter->Reset() ;
02166 RooAbsPdf* pdf, *thePdf(0) ;
02167 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
02168
02169 if (pdf->dependsOn(arg)) {
02170
02171
02172
02173 if (thePdf) return kFALSE ;
02174
02175 thePdf = pdf ;
02176 }
02177 }
02178
02179 return thePdf?(thePdf->isDirectGenSafe(arg)):kFALSE ;
02180 }
02181
02182
02183
02184
02185 RooArgSet* RooProdPdf::findPdfNSet(RooAbsPdf& pdf) const
02186 {
02187
02188
02189 Int_t idx = _pdfList.index(&pdf) ;
02190 if (idx<0) return 0 ;
02191 return (RooArgSet*) _pdfNSetList.At(idx) ;
02192 }
02193
02194
02195
02196
02197 RooArgSet* RooProdPdf::getConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, Bool_t stripDisconnected) const
02198 {
02199
02200
02201
02202
02203
02204 RooArgSet constraints ;
02205 RooArgSet pdfParams, conParams ;
02206
02207
02208 TIterator* piter = _pdfList.createIterator() ;
02209 RooAbsPdf* pdf ;
02210 while((pdf=(RooAbsPdf*)piter->Next())) {
02211
02212
02213 if (!pdf->dependsOnValue(observables) && pdf->dependsOnValue(constrainedParams)) {
02214 constraints.add(*pdf) ;
02215 RooArgSet* tmp = pdf->getParameters(observables) ;
02216 conParams.add(*tmp,kTRUE) ;
02217 delete tmp ;
02218 } else {
02219 RooArgSet* tmp = pdf->getParameters(observables) ;
02220 pdfParams.add(*tmp,kTRUE) ;
02221 delete tmp ;
02222 }
02223 }
02224
02225
02226 RooArgSet* finalConstraints = new RooArgSet("constraints") ;
02227 TIterator* citer = constraints.createIterator() ;
02228 while((pdf=(RooAbsPdf*)citer->Next())) {
02229 if (pdf->dependsOnValue(pdfParams) || !stripDisconnected) {
02230 finalConstraints->add(*pdf) ;
02231 } else {
02232 coutI(Minimization) << "RooProdPdf::getConstraints(" << GetName() << ") omitting term " << pdf->GetName()
02233 << " as constraint term as it does not share any parameters with the other pdfs in product. "
02234 << "To force inclusion in likelihood, add an explicit Constrain() argument for the target parameter" << endl ;
02235 }
02236 }
02237 delete citer ;
02238 delete piter ;
02239
02240
02241
02242 RooArgSet* cexl = (RooArgSet*) conParams.selectCommon(constrainedParams) ;
02243 cexl->remove(pdfParams,kTRUE,kTRUE) ;
02244 constrainedParams.remove(*cexl,kTRUE,kTRUE) ;
02245 delete cexl ;
02246
02247 return finalConstraints ;
02248 }
02249
02250
02251
02252
02253
02254 void RooProdPdf::getParametersHook(const RooArgSet* nset, RooArgSet* params, Bool_t stripDisconnected) const
02255 {
02256 if (!stripDisconnected) return ;
02257 if (!nset || nset->getSize()==0) return ;
02258
02259
02260 RooArgList *plist(0) ;
02261 RooLinkedList *nlist(0) ;
02262 Int_t code ;
02263 getPartIntList(nset,0,plist,nlist,code) ;
02264
02265
02266 TIterator* titer = plist->createIterator() ;
02267 TIterator* piter = params->createIterator() ;
02268 RooAbsReal* term, *param ;
02269 RooArgSet tostrip ;
02270 while((param=(RooAbsReal*)piter->Next())) {
02271 Bool_t anyDep(kFALSE) ;
02272 titer->Reset() ;
02273 while((term=(RooAbsReal*)titer->Next())) {
02274 if (term->dependsOnValue(*param)) {
02275 anyDep=kTRUE ;
02276 }
02277 }
02278 if (!anyDep) {
02279 tostrip.add(*param) ;
02280 }
02281 }
02282 delete piter ;
02283 delete titer ;
02284
02285 if (tostrip.getSize()>0) {
02286 params->remove(tostrip,kTRUE,kTRUE);
02287 }
02288
02289 }
02290
02291
02292
02293
02294 void RooProdPdf::selectNormalizationRange(const char* rangeName, Bool_t force)
02295 {
02296
02297
02298
02299 if (!force && _refRangeName) {
02300 return ;
02301 }
02302
02303 fixRefRange(rangeName) ;
02304 }
02305
02306
02307
02308
02309
02310 void RooProdPdf::fixRefRange(const char* rangeName)
02311 {
02312 _refRangeName = (TNamed*)RooNameReg::ptr(rangeName) ;
02313 }
02314
02315
02316
02317
02318 std::list<Double_t>* RooProdPdf::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
02319 {
02320
02321 _pdfIter->Reset() ;
02322 RooAbsPdf* pdf ;
02323 while((pdf=(RooAbsPdf*)_pdfIter->Next())) {
02324 list<Double_t>* hint = pdf->plotSamplingHint(obs,xlo,xhi) ;
02325 if (hint) {
02326 return hint ;
02327 }
02328 }
02329
02330 return 0 ;
02331 }
02332
02333
02334
02335
02336 void RooProdPdf::printMetaArgs(ostream& os) const
02337 {
02338
02339
02340
02341 TIterator* niter = _pdfNSetList.MakeIterator() ;
02342 for (int i=0 ; i<_pdfList.getSize() ; i++) {
02343 if (i>0) os << " * " ;
02344 RooArgSet* ncset = (RooArgSet*) niter->Next() ;
02345 os << _pdfList.at(i)->GetName() ;
02346 if (ncset->getSize()>0) {
02347 if (string("nset")==ncset->GetName()) {
02348 os << *ncset ;
02349 } else {
02350 os << "|" ;
02351 TIterator* nciter = ncset->createIterator() ;
02352 RooAbsArg* arg ;
02353 Bool_t first(kTRUE) ;
02354 while((arg=(RooAbsArg*)nciter->Next())) {
02355 if (!first) {
02356 os << "," ;
02357 } else {
02358 first = kFALSE ;
02359 }
02360 os << arg->GetName() ;
02361 }
02362 }
02363 }
02364 }
02365 os << " " ;
02366 delete niter ;
02367 }