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
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 #include "RooFit.h"
00111 #include "RooMsgService.h"
00112
00113 #include "TClass.h"
00114 #include "Riostream.h"
00115 #include "TMath.h"
00116 #include "TObjString.h"
00117 #include "TPaveText.h"
00118 #include "TList.h"
00119 #include "TH1.h"
00120 #include "TH2.h"
00121 #include "TMatrixD.h"
00122 #include "TMatrixDSym.h"
00123 #include "RooAbsPdf.h"
00124 #include "RooDataSet.h"
00125 #include "RooArgSet.h"
00126 #include "RooArgProxy.h"
00127 #include "RooRealProxy.h"
00128 #include "RooRealVar.h"
00129 #include "RooGenContext.h"
00130 #include "RooPlot.h"
00131 #include "RooCurve.h"
00132 #include "RooNLLVar.h"
00133 #include "RooMinuit.h"
00134 #include "RooCategory.h"
00135 #include "RooNameReg.h"
00136 #include "RooCmdConfig.h"
00137 #include "RooGlobalFunc.h"
00138 #include "RooAddition.h"
00139 #include "RooRandom.h"
00140 #include "RooNumIntConfig.h"
00141 #include "RooProjectedPdf.h"
00142 #include "RooInt.h"
00143 #include "RooCustomizer.h"
00144 #include "RooConstraintSum.h"
00145 #include "RooParamBinning.h"
00146 #include "RooNumCdf.h"
00147 #include "RooFitResult.h"
00148 #include "RooNumGenConfig.h"
00149 #include "RooCachedReal.h"
00150 #include "RooXYChi2Var.h"
00151 #include "RooChi2Var.h"
00152 #include "RooMinimizer.h"
00153 #include "RooRealIntegral.h"
00154 #include <string>
00155
00156 ClassImp(RooAbsPdf)
00157 ;
00158
00159
00160 Int_t RooAbsPdf::_verboseEval = 0;
00161 Bool_t RooAbsPdf::_evalError = kFALSE ;
00162 TString RooAbsPdf::_normRangeOverride ;
00163
00164
00165 RooAbsPdf::RooAbsPdf() : _norm(0), _normSet(0), _minDimNormValueCache(999), _valueCacheIntOrder(2), _specGeneratorConfig(0)
00166 {
00167
00168 }
00169
00170
00171
00172
00173 RooAbsPdf::RooAbsPdf(const char *name, const char *title) :
00174 RooAbsReal(name,title), _norm(0), _normSet(0), _minDimNormValueCache(999), _valueCacheIntOrder(2), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
00175 {
00176
00177 resetErrorCounters() ;
00178 setTraceCounter(0) ;
00179 }
00180
00181
00182
00183
00184 RooAbsPdf::RooAbsPdf(const char *name, const char *title,
00185 Double_t plotMin, Double_t plotMax) :
00186 RooAbsReal(name,title,plotMin,plotMax), _norm(0), _normSet(0), _minDimNormValueCache(999), _valueCacheIntOrder(2), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
00187 {
00188
00189 resetErrorCounters() ;
00190 setTraceCounter(0) ;
00191 }
00192
00193
00194
00195
00196 RooAbsPdf::RooAbsPdf(const RooAbsPdf& other, const char* name) :
00197 RooAbsReal(other,name), _norm(0), _normSet(0), _minDimNormValueCache(other._minDimNormValueCache), _valueCacheIntOrder(other._valueCacheIntOrder),
00198 _normMgr(other._normMgr,this), _selectComp(other._selectComp), _normRange(other._normRange)
00199 {
00200
00201 resetErrorCounters() ;
00202 setTraceCounter(other._traceCount) ;
00203
00204 if (other._specGeneratorConfig) {
00205 _specGeneratorConfig = new RooNumGenConfig(*other._specGeneratorConfig) ;
00206 } else {
00207 _specGeneratorConfig = 0 ;
00208 }
00209 }
00210
00211
00212
00213
00214 RooAbsPdf::~RooAbsPdf()
00215 {
00216
00217
00218 if (_specGeneratorConfig) delete _specGeneratorConfig ;
00219 }
00220
00221
00222
00223
00224 Double_t RooAbsPdf::getVal(const RooArgSet* nset) const
00225 {
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236 if (!nset) {
00237 Double_t val = evaluate() ;
00238 Bool_t error = traceEvalPdf(val) ;
00239 cxcoutD(Tracing) << IsA()->GetName() << "::getVal(" << GetName()
00240 << "): value = " << val << " (unnormalized)" << endl ;
00241 if (error) {
00242 raiseEvalError() ;
00243 return 0 ;
00244 }
00245 return val ;
00246 }
00247
00248
00249 Bool_t nsetChanged(kFALSE) ;
00250 if (nset!=_normSet || _norm==0) {
00251 nsetChanged = syncNormalization(nset) ;
00252 }
00253
00254
00255 if ((isValueDirty() || nsetChanged || _norm->isValueDirty()) && operMode()!=AClean) {
00256
00257
00258 Double_t rawVal = evaluate() ;
00259 Bool_t error = traceEvalPdf(rawVal) ;
00260
00261
00262 Double_t normVal(_norm->getVal()) ;
00263
00264 Double_t normError(kFALSE) ;
00265 if (normVal==0.) {
00266 normError=kTRUE ;
00267 logEvalError("p.d.f normalization integral is zero") ;
00268 }
00269
00270
00271 if (normError||error) raiseEvalError() ;
00272
00273 _value = normError ? 0 : (rawVal / normVal) ;
00274
00275 cxcoutD(Tracing) << "RooAbsPdf::getVal(" << GetName() << ") new value with norm " << _norm->GetName() << " = " << rawVal << "/" << normVal << " = " << _value << endl ;
00276
00277 clearValueDirty() ;
00278 clearShapeDirty() ;
00279 }
00280
00281 if (_traceCount>0) {
00282 cxcoutD(Tracing) << "[" << _traceCount << "] " ;
00283 Int_t tmp = _traceCount ;
00284 _traceCount = 0 ;
00285 printStream(ccoutD(Tracing),kName|kValue|kArgs,kSingleLine) ;
00286 _traceCount = tmp-1 ;
00287 }
00288
00289 return _value ;
00290 }
00291
00292
00293
00294
00295 Double_t RooAbsPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
00296 {
00297
00298
00299
00300
00301
00302
00303 cxcoutD(Eval) << "RooAbsPdf::analyticalIntegralWN(" << GetName() << ") code = " << code << " normset = " << (normSet?*normSet:RooArgSet()) << endl ;
00304
00305
00306 if (code==0) return getVal(normSet) ;
00307 if (normSet) {
00308 return analyticalIntegral(code,rangeName) / getNorm(normSet) ;
00309 } else {
00310 return analyticalIntegral(code,rangeName) ;
00311 }
00312 }
00313
00314
00315
00316
00317 Bool_t RooAbsPdf::traceEvalPdf(Double_t value) const
00318 {
00319
00320
00321
00322
00323
00324 Bool_t error= isnan(value) || (value < 0);
00325 if (isnan(value)) {
00326 logEvalError(Form("p.d.f value is Not-a-Number (%f), forcing value to zero",value)) ;
00327 }
00328 if (value<0) {
00329 logEvalError(Form("p.d.f value is less than zero (%f), forcing value to zero",value)) ;
00330 }
00331
00332
00333 if(!error) return error ;
00334
00335
00336 if(++_errorCount <= 10) {
00337 cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
00338 if(_errorCount == 10) cxcoutD(Tracing) << "(no more will be printed) ";
00339 }
00340 else {
00341 return error ;
00342 }
00343
00344 Print() ;
00345 return error ;
00346 }
00347
00348
00349
00350
00351
00352 Double_t RooAbsPdf::getNorm(const RooArgSet* nset) const
00353 {
00354
00355
00356 if (!nset) return 1 ;
00357
00358 syncNormalization(nset,kTRUE) ;
00359 if (_verboseEval>1) cxcoutD(Tracing) << IsA()->GetName() << "::getNorm(" << GetName() << "): norm(" << _norm << ") = " << _norm->getVal() << endl ;
00360
00361 Double_t ret = _norm->getVal() ;
00362
00363 if (ret==0.) {
00364 if(++_errorCount <= 10) {
00365 coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ":: WARNING normalization is zero, nset = " ; nset->Print("1") ;
00366 if(_errorCount == 10) coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ") INFO: no more messages will be printed " << endl ;
00367 }
00368 }
00369
00370 return ret ;
00371 }
00372
00373
00374
00375
00376 const RooAbsReal* RooAbsPdf::getNormObj(const RooArgSet* nset, const RooArgSet* iset, const TNamed* rangeName) const
00377 {
00378
00379
00380
00381
00382
00383 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset,iset,0,rangeName) ;
00384 if (cache) {
00385 return cache->_norm ;
00386 }
00387
00388
00389 RooArgSet* depList = getObservables(iset) ;
00390 RooAbsReal* norm = createIntegral(*depList,*nset, *getIntegratorConfig(), RooNameReg::str(rangeName)) ;
00391 delete depList ;
00392
00393
00394 cache = new CacheElem(*norm) ;
00395 _normMgr.setObj(nset,iset,cache,rangeName) ;
00396
00397
00398 return norm ;
00399 }
00400
00401
00402
00403
00404 Bool_t RooAbsPdf::syncNormalization(const RooArgSet* nset, Bool_t adjustProxies) const
00405 {
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 _normSet = (RooArgSet*) nset ;
00420
00421
00422 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset) ;
00423 if (cache) {
00424
00425 Bool_t nsetChanged = (_norm!=cache->_norm) ;
00426 _norm = cache->_norm ;
00427
00428
00429
00430
00431 if (nsetChanged && adjustProxies) {
00432
00433 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
00434 }
00435
00436 return nsetChanged ;
00437 }
00438
00439
00440 if (adjustProxies) {
00441 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
00442 }
00443
00444 RooArgSet* depList = getObservables(nset) ;
00445
00446 if (_verboseEval>0) {
00447 if (!selfNormalized()) {
00448 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName()
00449 << ") recreating normalization integral " << endl ;
00450 if (depList) depList->printStream(ccoutD(Tracing),kName|kValue|kArgs,kSingleLine) ; else ccoutD(Tracing) << "<none>" << endl ;
00451 } else {
00452 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName() << ") selfNormalized, creating unit norm" << endl;
00453 }
00454 }
00455
00456
00457 if (selfNormalized() || !dependsOn(*depList)) {
00458 TString ntitle(GetTitle()) ; ntitle.Append(" Unit Normalization") ;
00459 TString nname(GetName()) ; nname.Append("_UnitNorm") ;
00460 _norm = new RooRealVar(nname.Data(),ntitle.Data(),1) ;
00461 } else {
00462 const char* nr = (_normRangeOverride.Length()>0 ? _normRangeOverride.Data() : (_normRange.Length()>0 ? _normRange.Data() : 0)) ;
00463
00464
00465 RooRealIntegral* normInt = (RooRealIntegral*) createIntegral(*depList,*getIntegratorConfig(),nr) ;
00466 normInt->getVal() ;
00467
00468
00469 RooArgSet* normParams = normInt->getVariables() ;
00470 if (normParams->getSize()>0 && normParams->getSize()<3 && normInt->numIntRealVars().getSize()>=_minDimNormValueCache) {
00471 coutI(Caching) << "RooAbsPdf::syncNormalization(" << GetName() << ") INFO: constructing " << normParams->getSize()
00472 << "-dim value cache for normalization integral over " << *depList << endl ;
00473 string name = Form("%s_CACHE_[%s]",normInt->GetName(),normParams->contentsString().c_str()) ;
00474 RooCachedReal* cachedNorm = new RooCachedReal(name.c_str(),name.c_str(),*normInt,*normParams) ;
00475 cachedNorm->setInterpolationOrder(_valueCacheIntOrder) ;
00476 cachedNorm->addOwnedComponents(*normInt) ;
00477 _norm = cachedNorm ;
00478 } else {
00479 _norm = normInt ;
00480 }
00481 delete normParams ;
00482 }
00483
00484
00485
00486
00487 cache = new CacheElem(*_norm) ;
00488 _normMgr.setObj(nset,cache) ;
00489
00490
00491
00492 delete depList ;
00493 return kTRUE ;
00494 }
00495
00496
00497
00498
00499 void RooAbsPdf::setNormValueCaching(Int_t minNumIntDim, Int_t ipOrder)
00500 {
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 _minDimNormValueCache = minNumIntDim ;
00521 _valueCacheIntOrder = ipOrder ;
00522 }
00523
00524
00525
00526
00527
00528 Bool_t RooAbsPdf::traceEvalHook(Double_t value) const
00529 {
00530
00531
00532
00533
00534
00535 Bool_t error= isnan(value) || (value < 0);
00536
00537
00538 if(!error && _traceCount <= 0) return error ;
00539
00540
00541 if(error && ++_errorCount <= 10) {
00542 cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
00543 if(_errorCount == 10) ccoutD(Tracing) << "(no more will be printed) ";
00544 }
00545 else if(_traceCount > 0) {
00546 ccoutD(Tracing) << '[' << _traceCount-- << "] ";
00547 }
00548 else {
00549 return error ;
00550 }
00551
00552 Print() ;
00553
00554 return error ;
00555 }
00556
00557
00558
00559
00560
00561 void RooAbsPdf::resetErrorCounters(Int_t resetValue)
00562 {
00563
00564
00565
00566 _errorCount = resetValue ;
00567 _negCount = resetValue ;
00568 }
00569
00570
00571
00572
00573 void RooAbsPdf::setTraceCounter(Int_t value, Bool_t allNodes)
00574 {
00575
00576
00577
00578 if (!allNodes) {
00579 _traceCount = value ;
00580 return ;
00581 } else {
00582 RooArgList branchList ;
00583 branchNodeServerList(&branchList) ;
00584 TIterator* iter = branchList.createIterator() ;
00585 RooAbsArg* arg ;
00586 while((arg=(RooAbsArg*)iter->Next())) {
00587 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
00588 if (pdf) pdf->setTraceCounter(value,kFALSE) ;
00589 }
00590 delete iter ;
00591 }
00592
00593 }
00594
00595
00596
00597
00598
00599 Double_t RooAbsPdf::getLogVal(const RooArgSet* nset) const
00600 {
00601
00602
00603
00604 Double_t prob = getVal(nset) ;
00605 if(prob < 0) {
00606
00607 logEvalError("getLogVal() top-level p.d.f evaluates to a negative number") ;
00608
00609 return 0;
00610 }
00611 if(prob == 0) {
00612
00613 logEvalError("getLogVal() top-level p.d.f evaluates to zero") ;
00614
00615 return log((double)0);
00616 }
00617 return log(prob);
00618 }
00619
00620
00621
00622
00623 Double_t RooAbsPdf::extendedTerm(UInt_t observed, const RooArgSet* nset) const
00624 {
00625
00626
00627
00628
00629
00630
00631
00632
00633 if(!canBeExtended()) {
00634 coutE(InputArguments) << fName << ": this PDF does not support extended maximum likelihood"
00635 << endl;
00636 return 0;
00637 }
00638
00639 Double_t expected= expectedEvents(nset);
00640 if(expected < 0) {
00641 coutE(InputArguments) << fName << ": calculated negative expected events: " << expected
00642 << endl;
00643 return 0;
00644 }
00645
00646
00647
00648 Double_t extra= expected - observed*log(expected);
00649
00650
00651
00652 Bool_t trace(kFALSE) ;
00653 if(trace) {
00654 cxcoutD(Tracing) << fName << "::extendedTerm: expected " << expected << " events, got "
00655 << observed << " events. extendedTerm = " << extra << endl;
00656 }
00657 return extra;
00658 }
00659
00660
00661
00662
00663 RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
00664 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
00665 {
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 RooLinkedList l ;
00690 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
00691 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
00692 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
00693 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
00694 return createNLL(data,l) ;
00695 }
00696
00697
00698
00699
00700
00701 RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooLinkedList& cmdList)
00702 {
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 RooCmdConfig pc(Form("RooAbsPdf::createNLL(%s)",GetName())) ;
00714
00715 pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
00716 pc.defineString("addCoefRange","SumCoefRange",0,"") ;
00717 pc.defineDouble("rangeLo","Range",0,-999.) ;
00718 pc.defineDouble("rangeHi","Range",1,-999.) ;
00719 pc.defineInt("splitRange","SplitRange",0,0) ;
00720 pc.defineInt("ext","Extended",0,2) ;
00721 pc.defineInt("numcpu","NumCPU",0,1) ;
00722 pc.defineInt("verbose","Verbose",0,0) ;
00723 pc.defineInt("optConst","Optimize",0,0) ;
00724 pc.defineInt("cloneData","CloneData",2,0) ;
00725 pc.defineSet("projDepSet","ProjectedObservables",0,0) ;
00726 pc.defineSet("cPars","Constrain",0,0) ;
00727 pc.defineInt("constrAll","Constrained",0,0) ;
00728 pc.defineSet("extCons","ExternalConstraints",0,0) ;
00729 pc.defineMutex("Range","RangeWithName") ;
00730 pc.defineMutex("Constrain","Constrained") ;
00731
00732
00733 pc.process(cmdList) ;
00734 if (!pc.ok(kTRUE)) {
00735 return 0 ;
00736 }
00737
00738
00739 const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
00740 const char* addCoefRangeName = pc.getString("addCoefRange",0,kTRUE) ;
00741 Int_t ext = pc.getInt("ext") ;
00742 Int_t numcpu = pc.getInt("numcpu") ;
00743 Int_t splitr = pc.getInt("splitRange") ;
00744 Bool_t verbose = pc.getInt("verbose") ;
00745 Int_t optConst = pc.getInt("optConst") ;
00746 Int_t cloneData = pc.getInt("cloneData") ;
00747
00748
00749 if (cloneData==2) {
00750 cloneData = optConst ;
00751 }
00752 RooArgSet* cPars = pc.getSet("cPars") ;
00753 Bool_t doStripDisconnected=kFALSE ;
00754
00755
00756
00757
00758 if (!cPars) {
00759 cPars = getParameters(data,kFALSE) ;
00760 doStripDisconnected=kTRUE ;
00761 }
00762 const RooArgSet* extCons = pc.getSet("extCons") ;
00763
00764
00765 if (ext==2) {
00766 ext = ((extendMode()==CanBeExtended || extendMode()==MustBeExtended)) ? 1 : 0 ;
00767 if (ext) {
00768 coutI(Minimization) << "p.d.f. provides expected number of events, including extended term in likelihood." << endl ;
00769 }
00770 }
00771
00772 if (pc.hasProcessed("Range")) {
00773 Double_t rangeLo = pc.getDouble("rangeLo") ;
00774 Double_t rangeHi = pc.getDouble("rangeHi") ;
00775
00776
00777 RooArgSet* obs = getObservables(&data) ;
00778 TIterator* iter = obs->createIterator() ;
00779 RooAbsArg* arg ;
00780 while((arg=(RooAbsArg*)iter->Next())) {
00781 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
00782 if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ;
00783 }
00784
00785 rangeName = "fit" ;
00786 }
00787
00788 RooArgSet projDeps ;
00789 RooArgSet* tmp = pc.getSet("projDepSet") ;
00790 if (tmp) {
00791 projDeps.add(*tmp) ;
00792 }
00793
00794
00795 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::CollectErrors) ;
00796 RooAbsReal* nll ;
00797 string baseName = Form("nll_%s_%s",GetName(),data.GetName()) ;
00798 if (!rangeName || strchr(rangeName,',')==0) {
00799
00800
00801
00802 nll = new RooNLLVar(baseName.c_str(),"-log(likelihood)",*this,data,projDeps,ext,rangeName,addCoefRangeName,numcpu,kFALSE,verbose,splitr,cloneData) ;
00803
00804 } else {
00805
00806 RooArgList nllList ;
00807 char* buf = new char[strlen(rangeName)+1] ;
00808 strlcpy(buf,rangeName,strlen(rangeName)+1) ;
00809 char* token = strtok(buf,",") ;
00810 while(token) {
00811 RooAbsReal* nllComp = new RooNLLVar(Form("%s_%s",baseName.c_str(),token),"-log(likelihood)",*this,data,projDeps,ext,token,addCoefRangeName,numcpu,kFALSE,verbose,splitr,cloneData) ;
00812 nllList.add(*nllComp) ;
00813 token = strtok(0,",") ;
00814 }
00815 delete[] buf ;
00816 nll = new RooAddition(baseName.c_str(),"-log(likelihood)",nllList,kTRUE) ;
00817 }
00818 RooAbsReal::setEvalErrorLoggingMode(RooAbsReal::PrintErrors) ;
00819
00820
00821 RooArgSet allConstraints ;
00822 if (cPars && cPars->getSize()>0) {
00823 RooArgSet* constraints = getAllConstraints(*data.get(),*cPars,doStripDisconnected) ;
00824 allConstraints.add(*constraints) ;
00825 delete constraints ;
00826
00827 }
00828 if (extCons) {
00829 allConstraints.add(*extCons) ;
00830 }
00831
00832
00833 RooAbsReal* nllCons(0) ;
00834 if (allConstraints.getSize()>0 && cPars) {
00835
00836 coutI(Minimization) << " Including the following contraint terms in minimization: " << allConstraints << endl ;
00837
00838 nllCons = new RooConstraintSum(Form("%s_constr",baseName.c_str()),"nllCons",allConstraints,*cPars) ;
00839 RooAbsReal* orignll = nll ;
00840
00841 nll = new RooAddition(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*nll,*nllCons)) ;
00842 nll->addOwnedComponents(RooArgSet(*orignll,*nllCons)) ;
00843 }
00844
00845 if (optConst) {
00846
00847 nll->constOptimizeTestStatistic(RooAbsArg::Activate) ;
00848 }
00849
00850 if (doStripDisconnected) {
00851 delete cPars ;
00852 }
00853 return nll ;
00854 }
00855
00856
00857
00858
00859
00860
00861
00862 RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
00863 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
00864 {
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 RooLinkedList l ;
00931 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
00932 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
00933 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
00934 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
00935 return fitTo(data,l) ;
00936 }
00937
00938
00939
00940
00941 RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooLinkedList& cmdList)
00942 {
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
00955
00956 RooLinkedList fitCmdList(cmdList) ;
00957 RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,CloneData") ;
00958
00959 pc.defineString("fitOpt","FitOptions",0,"") ;
00960 pc.defineInt("optConst","Optimize",0,1) ;
00961 pc.defineInt("verbose","Verbose",0,0) ;
00962 pc.defineInt("doSave","Save",0,0) ;
00963 pc.defineInt("doTimer","Timer",0,0) ;
00964 pc.defineInt("plevel","PrintLevel",0,1) ;
00965 pc.defineInt("strat","Strategy",0,1) ;
00966 pc.defineInt("initHesse","InitialHesse",0,0) ;
00967 pc.defineInt("hesse","Hesse",0,1) ;
00968 pc.defineInt("minos","Minos",0,0) ;
00969 pc.defineInt("ext","Extended",0,2) ;
00970 pc.defineInt("numcpu","NumCPU",0,1) ;
00971 pc.defineInt("numee","PrintEvalErrors",0,10) ;
00972 pc.defineInt("doEEWall","EvalErrorWall",0,1) ;
00973 pc.defineInt("doWarn","Warnings",0,1) ;
00974 pc.defineInt("doSumW2","SumW2Error",0,-1) ;
00975 pc.defineString("mintype","Minimizer",0,"") ;
00976 pc.defineString("minalg","Minimizer",1,"") ;
00977 pc.defineObject("minosSet","Minos",0,0) ;
00978 pc.defineSet("cPars","Constrain",0,0) ;
00979 pc.defineSet("extCons","ExternalConstraints",0,0) ;
00980 pc.defineMutex("FitOptions","Verbose") ;
00981 pc.defineMutex("FitOptions","Save") ;
00982 pc.defineMutex("FitOptions","Timer") ;
00983 pc.defineMutex("FitOptions","Strategy") ;
00984 pc.defineMutex("FitOptions","InitialHesse") ;
00985 pc.defineMutex("FitOptions","Hesse") ;
00986 pc.defineMutex("FitOptions","Minos") ;
00987 pc.defineMutex("Range","RangeWithName") ;
00988 pc.defineMutex("InitialHesse","Minimizer") ;
00989
00990
00991 pc.process(fitCmdList) ;
00992 if (!pc.ok(kTRUE)) {
00993 return 0 ;
00994 }
00995
00996
00997 const char* fitOpt = pc.getString("fitOpt",0,kTRUE) ;
00998 Int_t optConst = pc.getInt("optConst") ;
00999 Int_t verbose = pc.getInt("verbose") ;
01000 Int_t doSave = pc.getInt("doSave") ;
01001 Int_t doTimer = pc.getInt("doTimer") ;
01002 Int_t plevel = pc.getInt("plevel") ;
01003 Int_t strat = pc.getInt("strat") ;
01004 Int_t initHesse= pc.getInt("initHesse") ;
01005 Int_t hesse = pc.getInt("hesse") ;
01006 Int_t minos = pc.getInt("minos") ;
01007 Int_t numee = pc.getInt("numee") ;
01008 Int_t doEEWall = pc.getInt("doEEWall") ;
01009 Int_t doWarn = pc.getInt("doWarn") ;
01010 Int_t doSumW2 = pc.getInt("doSumW2") ;
01011 const RooArgSet* minosSet = static_cast<RooArgSet*>(pc.getObject("minosSet")) ;
01012 #ifdef __ROOFIT_NOROOMINIMIZER
01013 const char* minType =0 ;
01014 #else
01015 const char* minType = pc.getString("mintype","",kTRUE) ;
01016 const char* minAlg = pc.getString("minalg","",kTRUE) ;
01017 #endif
01018
01019
01020 Bool_t weightedData = data.isNonPoissonWeighted() ;
01021
01022
01023 if (weightedData && doSumW2==-1) {
01024 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: a likelihood fit is request of what appears to be weighted data. " << endl
01025 << " While the estimated values of the parameters will always be calculated taking the weights into account, " << endl
01026 << " there are multiple ways to estimate the errors on these parameter values. You are advised to make an " << endl
01027 << " explicit choice on the error calculation: " << endl
01028 << " - Either provide SumW2Error(kTRUE), to calculate a sum-of-weights corrected HESSE error matrix " << endl
01029 << " (error will be proportional to the number of events)" << endl
01030 << " - Or provide SumW2Error(kFALSE), to return errors from original HESSE error matrix" << endl
01031 << " (which will be proportional to the sum of the weights)" << endl
01032 << " If you want the errors to reflect the information contained in the provided dataset, choose kTRUE. " << endl
01033 << " If you want the errors to reflect the precision you would be able to obtain with an unweighted dataset " << endl
01034 << " with 'sum-of-weights' events, choose kFALSE." << endl ;
01035 }
01036
01037
01038
01039 if (doSumW2==1 && minos) {
01040 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: sum-of-weights correction does not apply to MINOS errors" << endl ;
01041 }
01042
01043 RooAbsReal* nll = createNLL(data,nllCmdList) ;
01044
01045 RooFitResult *ret = 0 ;
01046
01047
01048
01049 if (minType) {
01050
01051 #ifndef __ROOFIT_NOROOMINIMIZER
01052 RooMinimizer m(*nll) ;
01053
01054 m.setMinimizerType(minType) ;
01055
01056 m.setEvalErrorWall(doEEWall) ;
01057 if (doWarn==0) {
01058
01059 }
01060
01061 m.setPrintEvalErrors(numee) ;
01062 if (plevel!=1) {
01063 m.setPrintLevel(plevel) ;
01064 }
01065
01066 if (optConst) {
01067
01068 m.optimizeConst(1) ;
01069 }
01070
01071 if (fitOpt) {
01072
01073
01074 ret = m.fit(fitOpt) ;
01075
01076 } else {
01077
01078 if (verbose) {
01079
01080 m.setVerbose(1) ;
01081 }
01082 if (doTimer) {
01083
01084 m.setProfile(1) ;
01085 }
01086
01087 if (strat!=1) {
01088
01089 m.setStrategy(strat) ;
01090 }
01091
01092 if (initHesse) {
01093
01094 m.hesse() ;
01095 }
01096
01097
01098 m.minimize(minType,minAlg) ;
01099
01100 if (hesse) {
01101
01102 m.hesse() ;
01103 }
01104
01105 if (doSumW2==1) {
01106
01107
01108 list<RooNLLVar*> nllComponents ;
01109 RooArgSet* comps = nll->getComponents() ;
01110 RooAbsArg* arg ;
01111 TIterator* citer = comps->createIterator() ;
01112 while((arg=(RooAbsArg*)citer->Next())) {
01113 RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg) ;
01114 if (nllComp) {
01115 nllComponents.push_back(nllComp) ;
01116 }
01117 }
01118 delete citer ;
01119 delete comps ;
01120
01121
01122 RooFitResult* rw = m.save() ;
01123 for (list<RooNLLVar*>::iterator iter1=nllComponents.begin() ; iter1!=nllComponents.end() ; iter1++) {
01124 (*iter1)->applyWeightSquared(kTRUE) ;
01125 }
01126 coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
01127 m.hesse() ;
01128 RooFitResult* rw2 = m.save() ;
01129 for (list<RooNLLVar*>::iterator iter2=nllComponents.begin() ; iter2!=nllComponents.end() ; iter2++) {
01130 (*iter2)->applyWeightSquared(kFALSE) ;
01131 }
01132
01133
01134 const TMatrixDSym& V = rw->covarianceMatrix() ;
01135 TMatrixDSym C = rw2->covarianceMatrix() ;
01136
01137
01138 Double_t det(0) ;
01139 C.Invert(&det) ;
01140 if (det==0) {
01141 coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
01142 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
01143 } else {
01144
01145
01146 TMatrixD VCV(V,TMatrixD::kMult,TMatrixD(C,TMatrixD::kMult,V)) ;
01147
01148
01149 Int_t n = VCV.GetNrows() ;
01150 TMatrixDSym VCVsym(n) ;
01151 for (Int_t i=0 ; i<n ; i++) {
01152 for (Int_t j=i ; j<n ; j++) {
01153 if (i==j) {
01154 VCVsym(i,j) = VCV(i,j) ;
01155 }
01156 if (i!=j) {
01157 Double_t deltaRel = (VCV(i,j)-VCV(j,i))/sqrt(VCV(i,i)*VCV(j,j)) ;
01158 if (fabs(deltaRel)>1e-3) {
01159 coutW(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: Corrected covariance matrix is not (completely) symmetric: V[" << i << "," << j << "] = "
01160 << VCV(i,j) << " V[" << j << "," << i << "] = " << VCV(j,i) << " explicitly restoring symmetry by inserting average value" << endl ;
01161 }
01162 VCVsym(i,j) = (VCV(i,j)+VCV(j,i))/2 ;
01163 }
01164 }
01165 }
01166
01167
01168 m.applyCovarianceMatrix(VCVsym) ;
01169 }
01170
01171 delete rw ;
01172 delete rw2 ;
01173 }
01174
01175 if (minos) {
01176
01177 if (minosSet) {
01178 m.minos(*minosSet) ;
01179 } else {
01180 m.minos() ;
01181 }
01182 }
01183
01184
01185 if (doSave) {
01186 string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
01187 string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
01188 ret = m.save(name.c_str(),title.c_str()) ;
01189 }
01190
01191 }
01192 if (optConst) {
01193 m.optimizeConst(0) ;
01194 }
01195
01196 #endif
01197
01198 } else {
01199
01200 RooMinuit m(*nll) ;
01201
01202 m.setEvalErrorWall(doEEWall) ;
01203 if (doWarn==0) {
01204 m.setNoWarn() ;
01205 }
01206
01207 m.setPrintEvalErrors(numee) ;
01208 if (plevel!=1) {
01209 m.setPrintLevel(plevel) ;
01210 }
01211
01212 if (optConst) {
01213
01214 m.optimizeConst(1) ;
01215 }
01216
01217 if (fitOpt) {
01218
01219
01220 ret = m.fit(fitOpt) ;
01221
01222 } else {
01223
01224 if (verbose) {
01225
01226 m.setVerbose(1) ;
01227 }
01228 if (doTimer) {
01229
01230 m.setProfile(1) ;
01231 }
01232
01233 if (strat!=1) {
01234
01235 m.setStrategy(strat) ;
01236 }
01237
01238 if (initHesse) {
01239
01240 m.hesse() ;
01241 }
01242
01243
01244 m.migrad() ;
01245
01246 if (hesse) {
01247
01248 m.hesse() ;
01249 }
01250
01251 if (doSumW2==1) {
01252
01253
01254 list<RooNLLVar*> nllComponents ;
01255 RooArgSet* comps = nll->getComponents() ;
01256 RooAbsArg* arg ;
01257 TIterator* citer = comps->createIterator() ;
01258 while((arg=(RooAbsArg*)citer->Next())) {
01259 RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg) ;
01260 if (nllComp) {
01261 nllComponents.push_back(nllComp) ;
01262 }
01263 }
01264 delete citer ;
01265 delete comps ;
01266
01267
01268 RooFitResult* rw = m.save() ;
01269 for (list<RooNLLVar*>::iterator iter1=nllComponents.begin() ; iter1!=nllComponents.end() ; iter1++) {
01270 (*iter1)->applyWeightSquared(kTRUE) ;
01271 }
01272 coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
01273 m.hesse() ;
01274 RooFitResult* rw2 = m.save() ;
01275 for (list<RooNLLVar*>::iterator iter2=nllComponents.begin() ; iter2!=nllComponents.end() ; iter2++) {
01276 (*iter2)->applyWeightSquared(kFALSE) ;
01277 }
01278
01279
01280 const TMatrixDSym& V = rw->covarianceMatrix() ;
01281 TMatrixDSym C = rw2->covarianceMatrix() ;
01282
01283
01284 Double_t det(0) ;
01285 C.Invert(&det) ;
01286 if (det==0) {
01287 coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
01288 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
01289 } else {
01290
01291
01292 TMatrixD VCV(V,TMatrixD::kMult,TMatrixD(C,TMatrixD::kMult,V)) ;
01293
01294
01295 Int_t n = VCV.GetNrows() ;
01296 TMatrixDSym VCVsym(n) ;
01297 for (Int_t i=0 ; i<n ; i++) {
01298 for (Int_t j=i ; j<n ; j++) {
01299 if (i==j) {
01300 VCVsym(i,j) = VCV(i,j) ;
01301 }
01302 if (i!=j) {
01303 Double_t deltaRel = (VCV(i,j)-VCV(j,i))/sqrt(VCV(i,i)*VCV(j,j)) ;
01304 if (fabs(deltaRel)>1e-3) {
01305 coutW(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: Corrected covariance matrix is not (completely) symmetric: V[" << i << "," << j << "] = "
01306 << VCV(i,j) << " V[" << j << "," << i << "] = " << VCV(j,i) << " explicitly restoring symmetry by inserting average value" << endl ;
01307 }
01308 VCVsym(i,j) = (VCV(i,j)+VCV(j,i))/2 ;
01309 }
01310 }
01311 }
01312
01313
01314 m.applyCovarianceMatrix(VCVsym) ;
01315 }
01316
01317 delete rw ;
01318 delete rw2 ;
01319 }
01320
01321 if (minos) {
01322
01323 if (minosSet) {
01324 m.minos(*minosSet) ;
01325 } else {
01326 m.minos() ;
01327 }
01328 }
01329
01330
01331 if (doSave) {
01332 string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
01333 string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
01334 ret = m.save(name.c_str(),title.c_str()) ;
01335 }
01336
01337 }
01338
01339 if (optConst) {
01340 m.optimizeConst(0) ;
01341 }
01342
01343 }
01344
01345
01346
01347
01348 delete nll ;
01349 return ret ;
01350 }
01351
01352
01353
01354
01355 RooFitResult* RooAbsPdf::chi2FitTo(RooDataHist& data, const RooLinkedList& cmdList)
01356 {
01357
01358
01359
01360 RooCmdConfig pc(Form("RooAbsPdf::chi2FitTo(%s)",GetName())) ;
01361
01362
01363 RooLinkedList fitCmdList(cmdList) ;
01364 RooLinkedList chi2CmdList = pc.filterCmdList(fitCmdList,"Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,AddCoefRange,SplitRange") ;
01365
01366 RooAbsReal* chi2 = createChi2(data,chi2CmdList) ;
01367 RooFitResult* ret = chi2FitDriver(*chi2,fitCmdList) ;
01368
01369
01370 delete chi2 ;
01371 return ret ;
01372 }
01373
01374
01375
01376
01377
01378 RooAbsReal* RooAbsPdf::createChi2(RooDataHist& data, const RooCmdArg& arg1, const RooCmdArg& arg2,
01379 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
01380 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
01381 {
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
01397
01398 return new RooChi2Var(name.c_str(),name.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01399 }
01400
01401
01402
01403
01404
01405 RooAbsReal* RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList)
01406 {
01407
01408
01409
01410 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
01411
01412 pc.defineInt("integrate","Integrate",0,0) ;
01413 pc.defineObject("yvar","YVar",0,0) ;
01414
01415
01416 pc.process(cmdList) ;
01417 if (!pc.ok(kTRUE)) {
01418 return 0 ;
01419 }
01420
01421
01422 Bool_t integrate = pc.getInt("integrate") ;
01423 RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;
01424
01425 string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
01426
01427 if (yvar) {
01428 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
01429 } else {
01430 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,integrate) ;
01431 }
01432 }
01433
01434
01435
01436
01437
01438 void RooAbsPdf::printValue(ostream& os) const
01439 {
01440
01441
01442 getVal() ;
01443
01444 if (_norm) {
01445 os << evaluate() << "/" << _norm->getVal() ;
01446 } else {
01447 os << evaluate() ;
01448 }
01449 }
01450
01451
01452
01453
01454 void RooAbsPdf::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
01455 {
01456
01457
01458 RooAbsReal::printMultiline(os,contents,verbose,indent);
01459 os << indent << "--- RooAbsPdf ---" << endl;
01460 os << indent << "Cached value = " << _value << endl ;
01461 if (_norm) {
01462 os << indent << " Normalization integral: " << endl ;
01463 TString moreIndent(indent) ; moreIndent.Append(" ") ;
01464 _norm->printStream(os,kName|kAddress|kTitle|kValue|kArgs,kSingleLine,moreIndent.Data()) ;
01465 }
01466 }
01467
01468
01469
01470
01471 RooAbsGenContext* RooAbsPdf::genContext(const RooArgSet &vars, const RooDataSet *prototype,
01472 const RooArgSet* auxProto, Bool_t verbose) const
01473 {
01474
01475
01476 return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
01477 }
01478
01479
01480
01481
01482 RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, Int_t nEvents, const RooCmdArg& arg1,
01483 const RooCmdArg& arg2, const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5)
01484 {
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 return generate(whatVars,RooFit::NumEvents(nEvents),arg1,arg2,arg3,arg4,arg5) ;
01511 }
01512
01513
01514
01515
01516 RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
01517 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
01518 {
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
01551 pc.defineObject("proto","PrototypeData",0,0) ;
01552 pc.defineString("dsetName","Name",0,"") ;
01553 pc.defineInt("randProto","PrototypeData",0,0) ;
01554 pc.defineInt("resampleProto","PrototypeData",1,0) ;
01555 pc.defineInt("verbose","Verbose",0,0) ;
01556 pc.defineInt("extended","Extended",0,0) ;
01557 pc.defineInt("nEvents","NumEvents",0,0) ;
01558
01559
01560
01561 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
01562 if (!pc.ok(kTRUE)) {
01563 return 0 ;
01564 }
01565
01566
01567 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
01568 const char* dsetName = pc.getString("dsetName") ;
01569 Int_t nEvents = pc.getInt("nEvents") ;
01570 Bool_t verbose = pc.getInt("verbose") ;
01571 Bool_t randProto = pc.getInt("randProto") ;
01572 Bool_t resampleProto = pc.getInt("resampleProto") ;
01573 Bool_t extended = pc.getInt("extended") ;
01574
01575 if (extended) {
01576 nEvents = RooRandom::randomGenerator()->Poisson(nEvents==0?expectedEvents(&whatVars):nEvents) ;
01577 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
01578 << GetName() << "::expectedEvents() = " << nEvents << endl ;
01579
01580 if (nEvents==0) {
01581 return new RooDataSet("emptyData","emptyData",whatVars) ;
01582 }
01583 } else if (nEvents==0) {
01584 cxcoutI(Generation) << "No number of events specified , number of events generated is "
01585 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
01586 }
01587
01588 if (extended && protoData && !randProto) {
01589 cxcoutI(Generation) << "WARNING Using generator option Extended() (Poisson distribution of #events) together "
01590 << "with a prototype dataset implies incomplete sampling or oversampling of proto data. "
01591 << "Set randomize flag in ProtoData() option to randomize prototype dataset order and thus "
01592 << "to randomize the set of over/undersampled prototype events for each generation cycle." << endl ;
01593 }
01594
01595
01596
01597 RooDataSet* data ;
01598 if (protoData) {
01599 data = generate(whatVars,*protoData,nEvents,verbose,randProto,resampleProto) ;
01600 } else {
01601 data = generate(whatVars,nEvents,verbose) ;
01602 }
01603
01604
01605 if (dsetName && strlen(dsetName)>0) {
01606 data->SetName(dsetName) ;
01607 }
01608
01609 return data ;
01610 }
01611
01612
01613
01614
01615
01616
01617 RooAbsPdf::GenSpec* RooAbsPdf::prepareMultiGen(const RooArgSet &whatVars,
01618 const RooCmdArg& arg1,const RooCmdArg& arg2,
01619 const RooCmdArg& arg3,const RooCmdArg& arg4,
01620 const RooCmdArg& arg5,const RooCmdArg& arg6)
01621 {
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
01656 pc.defineObject("proto","PrototypeData",0,0) ;
01657 pc.defineString("dsetName","Name",0,"") ;
01658 pc.defineInt("randProto","PrototypeData",0,0) ;
01659 pc.defineInt("resampleProto","PrototypeData",1,0) ;
01660 pc.defineInt("verbose","Verbose",0,0) ;
01661 pc.defineInt("extended","Extended",0,0) ;
01662 pc.defineInt("nEvents","NumEvents",0,0) ;
01663
01664
01665
01666 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
01667 if (!pc.ok(kTRUE)) {
01668 return 0 ;
01669 }
01670
01671
01672 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
01673 const char* dsetName = pc.getString("dsetName") ;
01674 Int_t nEvents = pc.getInt("nEvents") ;
01675 Bool_t verbose = pc.getInt("verbose") ;
01676 Bool_t randProto = pc.getInt("randProto") ;
01677 Bool_t resampleProto = pc.getInt("resampleProto") ;
01678 Bool_t extended = pc.getInt("extended") ;
01679
01680 return new GenSpec(genContext(whatVars,protoData,0,verbose),whatVars,protoData,nEvents,extended,randProto,resampleProto,dsetName) ;
01681 }
01682
01683
01684
01685 RooDataSet *RooAbsPdf::generate(RooAbsPdf::GenSpec& spec) const
01686 {
01687
01688
01689
01690
01691
01692
01693 Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen) : spec._nGen ;
01694
01695 return generate(*spec._genContext,spec._whatVars,spec._protoData,
01696 nEvt,kFALSE,spec._randProto,spec._resampleProto) ;
01697 }
01698
01699
01700
01701
01702
01703
01704 RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, Int_t nEvents, Bool_t verbose) const
01705 {
01706
01707
01708
01709
01710
01711
01712
01713
01714 if (nEvents==0 && extendMode()==CanNotBeExtended) {
01715 return new RooDataSet("emptyData","emptyData",whatVars) ;
01716 }
01717
01718 RooDataSet *generated = 0;
01719 RooAbsGenContext *context= genContext(whatVars,0,0,verbose);
01720 if(0 != context && context->isValid()) {
01721 generated= context->generate(nEvents);
01722 }
01723 else {
01724 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") cannot create a valid context" << endl;
01725 }
01726 if(0 != context) delete context;
01727 return generated;
01728 }
01729
01730
01731
01732
01733
01734 RooDataSet *RooAbsPdf::generate(RooAbsGenContext& context, const RooArgSet &whatVars, const RooDataSet *prototype,
01735 Int_t nEvents, Bool_t , Bool_t randProtoOrder, Bool_t resampleProto) const
01736 {
01737
01738 if (nEvents==0 && (prototype==0 || prototype->numEntries()==0)) {
01739 return new RooDataSet("emptyData","emptyData",whatVars) ;
01740 }
01741
01742
01743 RooDataSet *generated = 0;
01744
01745
01746 if (resampleProto) {
01747 randProtoOrder=kTRUE ;
01748 }
01749
01750 if (randProtoOrder && prototype && prototype->numEntries()!=nEvents) {
01751 coutI(Generation) << "RooAbsPdf::generate (Re)randomizing event order in prototype dataset (Nevt=" << nEvents << ")" << endl ;
01752 Int_t* newOrder = randomizeProtoOrder(prototype->numEntries(),nEvents,resampleProto) ;
01753 context.setProtoDataOrder(newOrder) ;
01754 delete[] newOrder ;
01755 }
01756
01757 if(context.isValid()) {
01758 generated= context.generate(nEvents);
01759 }
01760 else {
01761 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") do not have a valid generator context" << endl;
01762 }
01763 return generated;
01764 }
01765
01766
01767
01768
01769
01770 RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, const RooDataSet& prototype,
01771 Int_t nEvents, Bool_t verbose, Bool_t randProtoOrder, Bool_t resampleProto) const
01772 {
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786 RooAbsGenContext *context= genContext(whatVars,&prototype,0,verbose);
01787 if (context) {
01788 RooDataSet* data = generate(*context,whatVars,&prototype,nEvents,verbose,randProtoOrder,resampleProto) ;
01789 delete context ;
01790 return data ;
01791 } else {
01792 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") ERROR creating generator context" << endl ;
01793 return 0 ;
01794 }
01795 }
01796
01797
01798
01799
01800 Int_t* RooAbsPdf::randomizeProtoOrder(Int_t nProto, Int_t, Bool_t resampleProto) const
01801 {
01802
01803
01804
01805
01806
01807 RooLinkedList l ;
01808 Int_t i ;
01809 for (i=0 ; i<nProto ; i++) {
01810 l.Add(new RooInt(i)) ;
01811 }
01812
01813
01814 Int_t* lut = new Int_t[nProto] ;
01815
01816
01817 if (!resampleProto) {
01818
01819 for (i=0 ; i<nProto ; i++) {
01820 Int_t iran = RooRandom::integer(nProto-i) ;
01821 RooInt* sample = (RooInt*) l.At(iran) ;
01822 lut[i] = *sample ;
01823 l.Remove(sample) ;
01824 delete sample ;
01825 }
01826 } else {
01827
01828 for (i=0 ; i<nProto ; i++) {
01829 lut[i] = RooRandom::integer(nProto);
01830 }
01831 }
01832
01833
01834 return lut ;
01835 }
01836
01837
01838
01839
01840 Int_t RooAbsPdf::getGenerator(const RooArgSet &, RooArgSet &, Bool_t ) const
01841 {
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851 return 0 ;
01852 }
01853
01854
01855
01856
01857 void RooAbsPdf::initGenerator(Int_t )
01858 {
01859
01860 }
01861
01862
01863
01864
01865 void RooAbsPdf::generateEvent(Int_t )
01866 {
01867
01868
01869
01870
01871 }
01872
01873
01874
01875
01876 Bool_t RooAbsPdf::isDirectGenSafe(const RooAbsArg& arg) const
01877 {
01878
01879
01880
01881
01882
01883
01884
01885 if (!findServer(arg.GetName())) return kFALSE ;
01886
01887
01888 TIterator* sIter = serverIterator() ;
01889 const RooAbsArg *server = 0;
01890 while((server=(const RooAbsArg*)sIter->Next())) {
01891 if(server == &arg) continue;
01892 if(server->dependsOn(arg)) {
01893 delete sIter ;
01894 return kFALSE ;
01895 }
01896 }
01897 delete sIter ;
01898 return kTRUE ;
01899 }
01900
01901
01902
01903
01904
01905 RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, Double_t nEvents, const RooCmdArg& arg1,
01906 const RooCmdArg& arg2, const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5)
01907 {
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918
01919
01920
01921
01922
01923 return generateBinned(whatVars,RooFit::NumEvents(nEvents),arg1,arg2,arg3,arg4,arg5) ;
01924 }
01925
01926
01927
01928
01929 RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
01930 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
01931 {
01932
01933
01934
01935
01936
01937
01938
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
01952 pc.defineString("dsetName","Name",0,"") ;
01953 pc.defineInt("verbose","Verbose",0,0) ;
01954 pc.defineInt("extended","Extended",0,0) ;
01955 pc.defineInt("nEvents","NumEvents",0,0) ;
01956 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
01957 pc.defineInt("expectedData","ExpectedData",0,0) ;
01958
01959
01960 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
01961 if (!pc.ok(kTRUE)) {
01962 return 0 ;
01963 }
01964
01965
01966 Double_t nEvents = pc.getDouble("nEventsD") ;
01967 if (nEvents<0) {
01968 nEvents = pc.getInt("nEvents") ;
01969 }
01970
01971 Bool_t extended = pc.getInt("extended") ;
01972 Bool_t expectedData = pc.getInt("expectedData") ;
01973 const char* dsetName = pc.getString("dsetName") ;
01974
01975 if (extended) {
01976 nEvents = (nEvents==0?Int_t(expectedEvents(&whatVars)+0.5):nEvents) ;
01977 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
01978 << GetName() << "::expectedEvents() = " << nEvents << endl ;
01979
01980 if (nEvents==0) {
01981 return 0 ;
01982 }
01983 } else if (nEvents==0) {
01984 cxcoutI(Generation) << "No number of events specified , number of events generated is "
01985 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
01986 }
01987
01988
01989 RooDataHist* data = generateBinned(whatVars,nEvents,expectedData,extended) ;
01990
01991
01992 if (dsetName && strlen(dsetName)>0) {
01993 data->SetName(dsetName) ;
01994 }
01995
01996 return data ;
01997 }
01998
01999
02000
02001
02002
02003 RooDataHist *RooAbsPdf::generateBinned(const RooArgSet &whatVars, Double_t nEvents, Bool_t expectedData, Bool_t extended) const
02004 {
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018 RooDataHist* hist = new RooDataHist("genData","genData",whatVars) ;
02019
02020
02021 if (nEvents<=0) {
02022 if (!canBeExtended()) {
02023 coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName() << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
02024 delete hist ;
02025 return 0 ;
02026 } else {
02027
02028 if (expectedData) {
02029 nEvents = expectedEvents(&whatVars) ;
02030 } else {
02031 nEvents = Int_t(expectedEvents(&whatVars)+0.5) ;
02032 }
02033 }
02034 }
02035
02036
02037 fillDataHist(hist,&whatVars,1,kTRUE) ;
02038
02039 vector<int> histOut(hist->numEntries()) ;
02040 Double_t histMax(-1) ;
02041 Int_t histOutSum(0) ;
02042 for (int i=0 ; i<hist->numEntries() ; i++) {
02043 hist->get(i) ;
02044 if (expectedData) {
02045
02046
02047 Double_t w=hist->weight()*nEvents ;
02048 hist->set(w,sqrt(w)) ;
02049
02050 } else if (extended) {
02051
02052
02053 Double_t w = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
02054 hist->set(w,sqrt(w)) ;
02055
02056 } else {
02057
02058
02059
02060 if (hist->weight()>histMax) {
02061 histMax = hist->weight() ;
02062 }
02063 histOut[i] = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
02064 histOutSum += histOut[i] ;
02065 }
02066 }
02067
02068
02069 if (!expectedData && !extended) {
02070
02071
02072
02073
02074 Int_t nEvtExtra = abs(Int_t(nEvents)-histOutSum) ;
02075 Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
02076
02077
02078 while(nEvtExtra>0) {
02079
02080 Int_t ibinRand = RooRandom::randomGenerator()->Integer(hist->numEntries()) ;
02081 hist->get(ibinRand) ;
02082 Double_t ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
02083
02084 if (ranY<hist->weight()) {
02085 if (wgt==1) {
02086 histOut[ibinRand]++ ;
02087 } else {
02088
02089 if (histOut[ibinRand]>0) {
02090 histOut[ibinRand]-- ;
02091 } else {
02092 continue ;
02093 }
02094 }
02095 nEvtExtra-- ;
02096 }
02097 }
02098
02099
02100 for (int i=0 ; i<hist->numEntries() ; i++) {
02101 hist->get(i) ;
02102 hist->set(histOut[i],sqrt(1.0*histOut[i])) ;
02103 }
02104
02105 } else if (expectedData) {
02106
02107
02108
02109
02110 Double_t corr = nEvents/hist->sumEntries() ;
02111 for (int i=0 ; i<hist->numEntries() ; i++) {
02112 hist->get(i) ;
02113 hist->set(hist->weight()*corr,sqrt(hist->weight()*corr)) ;
02114 }
02115
02116 }
02117
02118 return hist;
02119 }
02120
02121
02122
02123
02124 RooPlot* RooAbsPdf::plotOn(RooPlot* frame, RooLinkedList& cmdList) const
02125 {
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187 RooCmdArg* plotRange(0) ;
02188 RooCmdArg* normRange2(0) ;
02189 if (getStringAttribute("fitrange") && !cmdList.FindObject("Range") &&
02190 !cmdList.FindObject("RangeWithName")) {
02191 plotRange = (RooCmdArg*) RooFit::Range(getStringAttribute("fitrange")).Clone() ;
02192 cmdList.Add(plotRange) ;
02193 }
02194
02195 if (getStringAttribute("fitrange") && !cmdList.FindObject("NormRange")) {
02196 normRange2 = (RooCmdArg*) RooFit::NormRange(getStringAttribute("fitrange")).Clone() ;
02197 cmdList.Add(normRange2) ;
02198 }
02199
02200 if (plotRange || normRange2) {
02201 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f was fitted in range and no explicit "
02202 << (plotRange?"plot":"") << ((plotRange&&normRange2)?",":"")
02203 << (normRange2?"norm":"") << " range was specified, using fit range as default" << endl ;
02204 }
02205
02206
02207 if (plotSanityChecks(frame)) return frame ;
02208
02209
02210 RooCmdConfig pc(Form("RooAbsPdf::plotOn(%s)",GetName())) ;
02211 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
02212 pc.defineInt("scaleType","Normalization",0,Relative) ;
02213 pc.defineObject("compSet","SelectCompSet",0) ;
02214 pc.defineString("compSpec","SelectCompSpec",0) ;
02215 pc.defineObject("asymCat","Asymmetry",0) ;
02216 pc.defineDouble("rangeLo","Range",0,-999.) ;
02217 pc.defineDouble("rangeHi","Range",1,-999.) ;
02218 pc.defineString("rangeName","RangeWithName",0,"") ;
02219 pc.defineString("normRangeName","NormRange",0,"") ;
02220 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
02221 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
02222 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
02223 pc.defineMutex("Range","RangeWithName") ;
02224 pc.allowUndefined() ;
02225
02226
02227 pc.process(cmdList) ;
02228 if (!pc.ok(kTRUE)) {
02229 return frame ;
02230 }
02231
02232
02233 ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
02234 Double_t scaleFactor = pc.getDouble("scaleFactor") ;
02235 const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
02236 const char* compSpec = pc.getString("compSpec") ;
02237 const RooArgSet* compSet = (const RooArgSet*) pc.getObject("compSet") ;
02238 Bool_t haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
02239
02240
02241 TString nameSuffix ;
02242 if (compSpec && strlen(compSpec)>0) {
02243 nameSuffix.Append("_Comp[") ;
02244 nameSuffix.Append(compSpec) ;
02245 nameSuffix.Append("]") ;
02246 } else if (compSet) {
02247 nameSuffix.Append("_Comp[") ;
02248 nameSuffix.Append(compSet->contentsString().c_str()) ;
02249 nameSuffix.Append("]") ;
02250 }
02251
02252
02253 pc.stripCmdList(cmdList,"SelectCompSet,SelectCompSpec") ;
02254
02255
02256 if (asymCat) {
02257 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
02258 cmdList.Add(&cnsuffix);
02259 return RooAbsReal::plotOn(frame,cmdList) ;
02260 }
02261
02262
02263 Double_t nExpected(1) ;
02264 if (stype==RelativeExpected) {
02265 if (!canBeExtended()) {
02266 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
02267 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
02268 return frame ;
02269 }
02270 nExpected = expectedEvents(frame->getNormVars()) ;
02271 }
02272
02273 if (stype != Raw) {
02274
02275 if (frame->getFitRangeNEvt() && stype==Relative) {
02276
02277 Bool_t hasCustomRange(kFALSE), adjustNorm(kFALSE) ;
02278
02279 list<pair<Double_t,Double_t> > rangeLim ;
02280
02281
02282 if (pc.hasProcessed("Range")) {
02283
02284 Double_t rangeLo = pc.getDouble("rangeLo") ;
02285 Double_t rangeHi = pc.getDouble("rangeHi") ;
02286 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
02287 adjustNorm = pc.getInt("rangeAdjustNorm") ;
02288 hasCustomRange = kTRUE ;
02289
02290 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range ["
02291 << rangeLo << "," << rangeHi << "]" ;
02292 if (!pc.hasProcessed("NormRange")) {
02293 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " given range" << endl ;
02294 } else {
02295 ccoutI(Plotting) << endl ;
02296 }
02297
02298 nameSuffix.Append(Form("_Range[%f_%f]",rangeLo,rangeHi)) ;
02299
02300 } else if (pc.hasProcessed("RangeWithName")) {
02301
02302 char tmp[1024] ;
02303 strlcpy(tmp,pc.getString("rangeName",0,kTRUE),1024) ;
02304 char* rangeNameToken = strtok(tmp,",") ;
02305 while(rangeNameToken) {
02306 Double_t rangeLo = frame->getPlotVar()->getMin(rangeNameToken) ;
02307 Double_t rangeHi = frame->getPlotVar()->getMax(rangeNameToken) ;
02308 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
02309 rangeNameToken = strtok(0,",") ;
02310 }
02311 adjustNorm = pc.getInt("rangeWNAdjustNorm") ;
02312 hasCustomRange = kTRUE ;
02313
02314 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range '" << pc.getString("rangeName",0,kTRUE) << "'" ;
02315 if (!pc.hasProcessed("NormRange")) {
02316 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " given range" << endl ;
02317 } else {
02318 ccoutI(Plotting) << endl ;
02319 }
02320
02321 nameSuffix.Append(Form("_Range[%s]",pc.getString("rangeName"))) ;
02322 }
02323
02324 if (pc.hasProcessed("NormRange")) {
02325 char tmp[1024] ;
02326 strlcpy(tmp,pc.getString("normRangeName",0,kTRUE),1024) ;
02327 char* rangeNameToken = strtok(tmp,",") ;
02328 rangeLim.clear() ;
02329 while(rangeNameToken) {
02330 Double_t rangeLo = frame->getPlotVar()->getMin(rangeNameToken) ;
02331 Double_t rangeHi = frame->getPlotVar()->getMax(rangeNameToken) ;
02332 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
02333 rangeNameToken = strtok(0,",") ;
02334 }
02335 adjustNorm = kTRUE ;
02336 hasCustomRange = kTRUE ;
02337 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f. curve is normalized using explicit choice of ranges '" << pc.getString("normRangeName",0,kTRUE) << "'" << endl ;
02338
02339 nameSuffix.Append(Form("_NormRange[%s]",pc.getString("rangeName"))) ;
02340
02341 }
02342
02343 if (hasCustomRange && adjustNorm) {
02344
02345 Double_t rangeNevt(0) ;
02346 list<pair<Double_t,Double_t> >::iterator riter = rangeLim.begin() ;
02347 for (;riter!=rangeLim.end() ; ++riter) {
02348 Double_t nevt= frame->getFitRangeNEvt(riter->first,riter->second) ;
02349 rangeNevt += nevt ;
02350 }
02351 scaleFactor *= rangeNevt/nExpected ;
02352
02353 } else {
02354 scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
02355 }
02356 } else if (stype==RelativeExpected) {
02357 scaleFactor *= nExpected ;
02358 } else if (stype==NumEvent) {
02359 scaleFactor /= nExpected ;
02360 }
02361 scaleFactor *= frame->getFitRangeBinW() ;
02362 }
02363 frame->updateNormVars(*frame->getPlotVar()) ;
02364
02365
02366 RooCmdArg tmp = RooFit::Normalization(scaleFactor,Raw) ;
02367 cmdList.Add(&tmp) ;
02368
02369
02370 if (haveCompSel) {
02371
02372
02373 RooArgSet branchNodeSet ;
02374 branchNodeServerList(&branchNodeSet) ;
02375
02376
02377 TIterator* iter = branchNodeSet.createIterator() ;
02378 RooAbsArg* arg ;
02379 while((arg=(RooAbsArg*)iter->Next())) {
02380 if (!dynamic_cast<RooAbsReal*>(arg)) {
02381 branchNodeSet.remove(*arg) ;
02382 }
02383 }
02384 delete iter ;
02385
02386
02387 RooArgSet* dirSelNodes ;
02388 if (compSet) {
02389 dirSelNodes = (RooArgSet*) branchNodeSet.selectCommon(*compSet) ;
02390 } else {
02391 dirSelNodes = (RooArgSet*) branchNodeSet.selectByName(compSpec) ;
02392 }
02393 if (dirSelNodes->getSize()>0) {
02394 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << endl ;
02395
02396
02397 plotOnCompSelect(dirSelNodes) ;
02398 } else {
02399 if (compSet) {
02400 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << endl ;
02401 } else {
02402 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << endl ;
02403 }
02404 return 0 ;
02405 }
02406
02407 delete dirSelNodes ;
02408 }
02409
02410
02411 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
02412 cmdList.Add(&cnsuffix);
02413
02414 RooPlot* ret = RooAbsReal::plotOn(frame,cmdList) ;
02415
02416
02417 if (haveCompSel) plotOnCompSelect(0) ;
02418
02419 if (plotRange) {
02420 delete plotRange ;
02421 }
02422 if (normRange2) {
02423 delete normRange2 ;
02424 }
02425
02426 return ret ;
02427 }
02428
02429
02430
02431
02432 void RooAbsPdf::plotOnCompSelect(RooArgSet* selNodes) const
02433 {
02434
02435
02436
02437
02438
02439
02440
02441 RooArgSet branchNodeSet ;
02442 branchNodeServerList(&branchNodeSet) ;
02443
02444
02445 TIterator* iter = branchNodeSet.createIterator() ;
02446 RooAbsArg* arg ;
02447 while((arg=(RooAbsArg*)iter->Next())) {
02448 if (!dynamic_cast<RooAbsReal*>(arg)) {
02449 branchNodeSet.remove(*arg) ;
02450 }
02451 }
02452
02453
02454 if (!selNodes) {
02455
02456 iter->Reset() ;
02457 while((arg=(RooAbsArg*)iter->Next())) {
02458 ((RooAbsReal*)arg)->selectComp(kTRUE) ;
02459 }
02460 delete iter ;
02461 return ;
02462 }
02463
02464
02465
02466 iter->Reset() ;
02467 TIterator* sIter = selNodes->createIterator() ;
02468 RooArgSet tmp ;
02469 while((arg=(RooAbsArg*)iter->Next())) {
02470 sIter->Reset() ;
02471 RooAbsArg* selNode ;
02472 while((selNode=(RooAbsArg*)sIter->Next())) {
02473 if (selNode->dependsOn(*arg)) {
02474 tmp.add(*arg,kTRUE) ;
02475 }
02476 }
02477 }
02478 delete sIter ;
02479
02480
02481 iter->Reset() ;
02482 while((arg=(RooAbsArg*)iter->Next())) {
02483 if (arg->dependsOn(*selNodes)) {
02484 tmp.add(*arg,kTRUE) ;
02485 }
02486 }
02487
02488 tmp.remove(*selNodes,kTRUE) ;
02489 tmp.remove(*this) ;
02490 selNodes->add(tmp) ;
02491 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") indirectly selected PDF components: " << tmp << endl ;
02492
02493
02494 iter->Reset() ;
02495 while((arg=(RooAbsArg*)iter->Next())) {
02496 Bool_t select = selNodes->find(arg->GetName()) ? kTRUE : kFALSE ;
02497 ((RooAbsReal*)arg)->selectComp(select) ;
02498 }
02499
02500 delete iter ;
02501 }
02502
02503
02504
02505
02506
02507
02508 RooPlot* RooAbsPdf::plotOn(RooPlot *frame, PlotOpt o) const
02509 {
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521
02522 if (plotSanityChecks(frame)) return frame ;
02523
02524
02525 Double_t nExpected(1) ;
02526 if (o.stype==RelativeExpected) {
02527 if (!canBeExtended()) {
02528 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
02529 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
02530 return frame ;
02531 }
02532 nExpected = expectedEvents(frame->getNormVars()) ;
02533 }
02534
02535
02536 if (o.stype != Raw) {
02537
02538 if (frame->getFitRangeNEvt() && o.stype==Relative) {
02539
02540 o.scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
02541 } else if (o.stype==RelativeExpected) {
02542 o.scaleFactor *= nExpected ;
02543 } else if (o.stype==NumEvent) {
02544 o.scaleFactor /= nExpected ;
02545 }
02546 o.scaleFactor *= frame->getFitRangeBinW() ;
02547 }
02548 frame->updateNormVars(*frame->getPlotVar()) ;
02549
02550 return RooAbsReal::plotOn(frame,o) ;
02551 }
02552
02553
02554
02555
02556
02557 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
02558 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
02559 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
02560 {
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587 RooLinkedList cmdList;
02588 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
02589 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
02590 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
02591 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
02592
02593
02594 RooCmdConfig pc(Form("RooAbsPdf::paramOn(%s)",GetName())) ;
02595 pc.defineString("label","Label",0,"") ;
02596 pc.defineDouble("xmin","Layout",0,0.50) ;
02597 pc.defineDouble("xmax","Layout",1,0.99) ;
02598 pc.defineInt("ymaxi","Layout",0,Int_t(0.95*10000)) ;
02599 pc.defineInt("showc","ShowConstants",0,0) ;
02600 pc.defineObject("params","Parameters",0,0) ;
02601 pc.defineString("formatStr","Format",0,"NELU") ;
02602 pc.defineInt("sigDigit","Format",0,2) ;
02603 pc.defineInt("dummy","FormatArgs",0,0) ;
02604 pc.defineMutex("Format","FormatArgs") ;
02605
02606
02607 pc.process(cmdList) ;
02608 if (!pc.ok(kTRUE)) {
02609 return frame ;
02610 }
02611
02612 const char* label = pc.getString("label") ;
02613 Double_t xmin = pc.getDouble("xmin") ;
02614 Double_t xmax = pc.getDouble("xmax") ;
02615 Double_t ymax = pc.getInt("ymaxi") / 10000. ;
02616 Int_t showc = pc.getInt("showc") ;
02617
02618
02619 const char* formatStr = pc.getString("formatStr") ;
02620 Int_t sigDigit = pc.getInt("sigDigit") ;
02621
02622
02623 RooArgSet* params = static_cast<RooArgSet*>(pc.getObject("params")) ;
02624 if (!params) {
02625 params = getParameters(frame->getNormVars()) ;
02626 if (pc.hasProcessed("FormatArgs")) {
02627 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
02628 paramOn(frame,*params,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
02629 } else {
02630 paramOn(frame,*params,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
02631 }
02632 delete params ;
02633 } else {
02634 RooArgSet* pdfParams = getParameters(frame->getNormVars()) ;
02635 RooArgSet* selParams = static_cast<RooArgSet*>(pdfParams->selectCommon(*params)) ;
02636 if (pc.hasProcessed("FormatArgs")) {
02637 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
02638 paramOn(frame,*selParams,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
02639 } else {
02640 paramOn(frame,*selParams,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
02641 }
02642 delete selParams ;
02643 delete pdfParams ;
02644 }
02645
02646 return frame ;
02647 }
02648
02649
02650
02651
02652
02653 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooAbsData* data, const char *label,
02654 Int_t sigDigits, Option_t *options, Double_t xmin,
02655 Double_t xmax ,Double_t ymax)
02656 {
02657
02658
02659 RooArgSet* params = getParameters(data) ;
02660 TString opts(options) ;
02661 paramOn(frame,*params,opts.Contains("c"),label,sigDigits,options,xmin,xmax,ymax) ;
02662 delete params ;
02663 return frame ;
02664 }
02665
02666
02667
02668
02669 RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooArgSet& params, Bool_t showConstants, const char *label,
02670 Int_t sigDigits, Option_t *options, Double_t xmin,
02671 Double_t xmax ,Double_t ymax, const RooCmdArg* formatCmd)
02672 {
02673
02674
02675
02676
02677
02678
02679
02680
02681
02682 TString opts = options;
02683 opts.ToLower();
02684 Bool_t showLabel= (label != 0 && strlen(label) > 0);
02685
02686
02687 TIterator* pIter = params.createIterator() ;
02688
02689 Int_t nPar= params.getSize();
02690 Double_t ymin(ymax), dy(0.06);
02691 Int_t index(nPar);
02692 RooRealVar *var = 0;
02693 while((var=(RooRealVar*)pIter->Next())) {
02694 if(showConstants || !var->isConstant()) ymin-= dy;
02695 }
02696
02697 if(showLabel) ymin-= dy;
02698
02699
02700 TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
02701 if(!box) return 0;
02702 box->SetName(Form("%s_paramBox",GetName())) ;
02703 box->SetFillColor(0);
02704 box->SetBorderSize(1);
02705 box->SetTextAlign(12);
02706 box->SetTextSize(0.04F);
02707 box->SetFillStyle(1001);
02708 box->SetFillColor(0);
02709
02710 index= nPar;
02711 pIter->Reset() ;
02712 while((var=(RooRealVar*)pIter->Next())) {
02713 if(var->isConstant() && !showConstants) continue;
02714
02715 TString *formatted= options ? var->format(sigDigits, options) : var->format(*formatCmd) ;
02716 box->AddText(formatted->Data());
02717 delete formatted;
02718 }
02719
02720 if(showLabel) box->AddText(label);
02721
02722
02723 frame->addObject(box) ;
02724
02725 delete pIter ;
02726 return frame ;
02727 }
02728
02729
02730
02731
02732
02733 Double_t RooAbsPdf::expectedEvents(const RooArgSet*) const
02734 {
02735
02736
02737 return 0 ;
02738 }
02739
02740
02741
02742
02743 void RooAbsPdf::verboseEval(Int_t stat)
02744 {
02745
02746
02747 _verboseEval = stat ;
02748 }
02749
02750
02751
02752
02753 Int_t RooAbsPdf::verboseEval()
02754 {
02755
02756
02757 return _verboseEval ;
02758 }
02759
02760
02761
02762
02763 void RooAbsPdf::CacheElem::operModeHook(RooAbsArg::OperMode)
02764 {
02765
02766 }
02767
02768
02769
02770
02771 RooAbsPdf::CacheElem::~CacheElem()
02772 {
02773
02774
02775
02776
02777
02778 if (_owner) {
02779 RooAbsPdf* pdfOwner = static_cast<RooAbsPdf*>(_owner) ;
02780 if (pdfOwner->_norm == _norm) {
02781 pdfOwner->_norm = 0 ;
02782 }
02783 }
02784
02785 delete _norm ;
02786 }
02787
02788
02789
02790
02791 RooAbsPdf* RooAbsPdf::createProjection(const RooArgSet& iset)
02792 {
02793
02794
02795
02796 TString name(GetName()) ;
02797 name.Append("_Proj[") ;
02798 if (iset.getSize()>0) {
02799 TIterator* iter = iset.createIterator() ;
02800 RooAbsArg* arg ;
02801 Bool_t first(kTRUE) ;
02802 while((arg=(RooAbsArg*)iter->Next())) {
02803 if (first) {
02804 first=kFALSE ;
02805 } else {
02806 name.Append(",") ;
02807 }
02808 name.Append(arg->GetName()) ;
02809 }
02810 delete iter ;
02811 }
02812 name.Append("]") ;
02813
02814
02815 return new RooProjectedPdf(name.Data(),name.Data(),*this,iset) ;
02816 }
02817
02818
02819
02820
02821 RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooArgSet& nset)
02822 {
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833 return createCdf(iset,RooFit::SupNormSet(nset)) ;
02834 }
02835
02836
02837
02838
02839 RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2,
02840 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
02841 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
02842 {
02843
02844
02845
02846
02847
02848
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858
02859 RooCmdConfig pc(Form("RooAbsReal::createCdf(%s)",GetName())) ;
02860 pc.defineObject("supNormSet","SupNormSet",0,0) ;
02861 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
02862 pc.defineInt("intOrder","ScanParameters",1,2) ;
02863 pc.defineInt("doScanNum","ScanNumCdf",0,1) ;
02864 pc.defineInt("doScanAll","ScanAllCdf",0,0) ;
02865 pc.defineInt("doScanNon","ScanNoCdf",0,0) ;
02866 pc.defineMutex("ScanNumCdf","ScanAllCdf","ScanNoCdf") ;
02867
02868
02869 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
02870 if (!pc.ok(kTRUE)) {
02871 return 0 ;
02872 }
02873
02874
02875 const RooArgSet* snset = static_cast<const RooArgSet*>(pc.getObject("supNormSet",0)) ;
02876 RooArgSet nset ;
02877 if (snset) {
02878 nset.add(*snset) ;
02879 }
02880 Int_t numScanBins = pc.getInt("numScanBins") ;
02881 Int_t intOrder = pc.getInt("intOrder") ;
02882 Int_t doScanNum = pc.getInt("doScanNum") ;
02883 Int_t doScanAll = pc.getInt("doScanAll") ;
02884 Int_t doScanNon = pc.getInt("doScanNon") ;
02885
02886
02887 if (doScanNon) {
02888 return createIntRI(iset,nset) ;
02889 }
02890 if (doScanAll) {
02891 return createScanCdf(iset,nset,numScanBins,intOrder) ;
02892 }
02893 if (doScanNum) {
02894 RooRealIntegral* tmp = (RooRealIntegral*) createIntegral(iset) ;
02895 Int_t isNum= (tmp->numIntRealVars().getSize()>0) ;
02896 delete tmp ;
02897
02898 if (isNum) {
02899 coutI(NumIntegration) << "RooAbsPdf::createCdf(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << endl
02900 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
02901 << intOrder << " interpolation on integrated histogram." << endl
02902 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << endl ;
02903 }
02904
02905 return isNum ? createScanCdf(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
02906 }
02907 return 0 ;
02908 }
02909
02910 RooAbsReal* RooAbsPdf::createScanCdf(const RooArgSet& iset, const RooArgSet& nset, Int_t numScanBins, Int_t intOrder)
02911 {
02912 string name = string(GetName()) + "_NUMCDF_" + integralNameSuffix(iset,&nset).Data() ;
02913 RooRealVar* ivar = (RooRealVar*) iset.first() ;
02914 ivar->setBins(numScanBins,"numcdf") ;
02915 RooNumCdf* ret = new RooNumCdf(name.c_str(),name.c_str(),*this,*ivar,"numcdf") ;
02916 ret->setInterpolationOrder(intOrder) ;
02917 return ret ;
02918 }
02919
02920
02921
02922
02923
02924 RooArgSet* RooAbsPdf::getAllConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, Bool_t stripDisconnected) const
02925 {
02926
02927
02928
02929 RooArgSet* ret = new RooArgSet("AllConstraints") ;
02930
02931 RooArgSet* comps = getComponents() ;
02932 TIterator* iter = comps->createIterator() ;
02933 RooAbsArg *arg ;
02934 while((arg=(RooAbsArg*)iter->Next())) {
02935 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
02936 if (pdf && !ret->find(pdf->GetName())) {
02937 RooArgSet* compRet = pdf->getConstraints(observables,constrainedParams,stripDisconnected) ;
02938 if (compRet) {
02939 ret->add(*compRet,kFALSE) ;
02940 delete compRet ;
02941 }
02942 }
02943 }
02944 delete iter ;
02945 delete comps ;
02946
02947 return ret ;
02948 }
02949
02950
02951
02952 void RooAbsPdf::clearEvalError()
02953 {
02954
02955 _evalError = kFALSE ;
02956 }
02957
02958
02959
02960
02961 Bool_t RooAbsPdf::evalError()
02962 {
02963
02964 return _evalError ;
02965 }
02966
02967
02968
02969
02970 void RooAbsPdf::raiseEvalError()
02971 {
02972
02973 _evalError = kTRUE ;
02974 }
02975
02976
02977
02978
02979 RooNumGenConfig* RooAbsPdf::defaultGeneratorConfig()
02980 {
02981
02982 return &RooNumGenConfig::defaultConfig() ;
02983 }
02984
02985
02986
02987 RooNumGenConfig* RooAbsPdf::specialGeneratorConfig() const
02988 {
02989
02990
02991 return _specGeneratorConfig ;
02992 }
02993
02994
02995
02996
02997 RooNumGenConfig* RooAbsPdf::specialGeneratorConfig(Bool_t createOnTheFly)
02998 {
02999
03000
03001
03002
03003
03004 if (!_specGeneratorConfig && createOnTheFly) {
03005 _specGeneratorConfig = new RooNumGenConfig(*defaultGeneratorConfig()) ;
03006 }
03007 return _specGeneratorConfig ;
03008 }
03009
03010
03011
03012
03013 const RooNumGenConfig* RooAbsPdf::getGeneratorConfig() const
03014 {
03015
03016
03017
03018
03019 const RooNumGenConfig* config = specialGeneratorConfig() ;
03020 if (config) return config ;
03021 return defaultGeneratorConfig() ;
03022 }
03023
03024
03025
03026
03027 void RooAbsPdf::setGeneratorConfig(const RooNumGenConfig& config)
03028 {
03029
03030
03031 if (_specGeneratorConfig) {
03032 delete _specGeneratorConfig ;
03033 }
03034 _specGeneratorConfig = new RooNumGenConfig(config) ;
03035 }
03036
03037
03038
03039
03040 void RooAbsPdf::setGeneratorConfig()
03041 {
03042
03043
03044 if (_specGeneratorConfig) {
03045 delete _specGeneratorConfig ;
03046 }
03047 _specGeneratorConfig = 0 ;
03048 }
03049
03050
03051
03052
03053 RooAbsPdf::GenSpec::~GenSpec()
03054 {
03055 delete _genContext ;
03056 }
03057
03058
03059
03060 RooAbsPdf::GenSpec::GenSpec(RooAbsGenContext* context, const RooArgSet& whatVars, RooDataSet* protoData, Int_t nGen,
03061 Bool_t extended, Bool_t randProto, Bool_t resampleProto, TString dsetName) :
03062 _genContext(context), _whatVars(whatVars), _protoData(protoData), _nGen(nGen), _extended(extended),
03063 _randProto(randProto), _resampleProto(resampleProto), _dsetName(dsetName)
03064 {
03065 }
03066
03067
03068
03069
03070 void RooAbsPdf::setNormRange(const char* rangeName)
03071 {
03072 if (rangeName) {
03073 _normRange = rangeName ;
03074 } else {
03075 _normRange.Clear() ;
03076 }
03077
03078 if (_norm) {
03079 _normMgr.sterilize() ;
03080 _norm = 0 ;
03081 }
03082 }
03083
03084
03085
03086 void RooAbsPdf::setNormRangeOverride(const char* rangeName)
03087 {
03088 if (rangeName) {
03089 _normRangeOverride = rangeName ;
03090 } else {
03091 _normRangeOverride.Clear() ;
03092 }
03093
03094 if (_norm) {
03095 _normMgr.sterilize() ;
03096 _norm = 0 ;
03097 }
03098 }