Logo ROOT   6.16/01
Reference Guide
RooAbsPdf.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17//////////////////////////////////////////////////////////////////////////////
18/** \class RooAbsPdf
19 \ingroup Roofitcore
20
21RooAbsPdf is the abstract interface for all probability density
22functions The class provides hybrid analytical/numerical
23normalization for its implementations, error tracing and a MC
24generator interface.
25
26A minimal implementation of a PDF class derived from RooAbsPdf
27should overload the evaluate() function. This functions should
28return PDFs value.
29
30
31### Normalization/Integration
32
33Although the normalization of a PDF is an integral part of a
34probability density function, normalization is treated separately
35in RooAbsPdf. The reason is that a RooAbsPdf object is more than a
36PDF: it can be a building block for a more complex, composite PDF
37if any of its variables are functions instead of variables. In
38such cases the normalization of the composite may not be simply the
39integral over the dependents of the top level PDF as these are
40functions with potentially non-trivial Jacobian terms themselves.
41Therefore
42
43**--> No explicit attempt should be made to normalize
44 the functions output in evaluate().**
45
46In addition, RooAbsPdf objects do not have a static concept of what
47variables are parameters and what variables are dependents (which
48need to be integrated over for a correct PDF normalization).
49Instead the choice of normalization is always specified each time a
50normalized values is requested from the PDF via the getVal()
51method.
52
53RooAbsPdf manages the entire normalization logic of each PDF with
54help of a RooRealIntegral object, which coordinates the integration
55of a given choice of normalization. By default, RooRealIntegral will
56perform a fully numeric integration of all dependents. However,
57PDFs can advertise one or more (partial) analytical integrals of
58their function, and these will be used by RooRealIntegral, if it
59determines that this is safe (i.e. no hidden Jacobian terms,
60multiplication with other PDFs that have one or more dependents in
61commen etc)
62
63To implement analytical integrals, two functions must be implemented. First,
64
65``Int_t getAnalyticalIntegral(const RooArgSet& integSet, RooArgSet& anaIntSet)``
66
67advertises the analytical integrals that are supported. 'integSet'
68is the set of dependents for which integration is requested. The
69function should copy the subset of dependents it can analytically
70integrate to anaIntSet and return a unique identification code for
71this integration configuration. If no integration can be
72performed, zero should be returned. Second,
73
74``Double_t analyticalIntegral(Int_t code)``
75
76Implements the actual analytical integral(s) advertised by
77getAnalyticalIntegral. This functions will only be called with
78codes returned by getAnalyticalIntegral, except code zero.
79
80The integration range for real each dependent to be integrated can
81be obtained from the dependents' proxy functions min() and
82max(). Never call these proxy functions for any proxy not known to
83be a dependent via the integration code. Doing so may be
84ill-defined, e.g. in case the proxy holds a function, and will
85trigger an assert. Integrated category dependents should always be
86summed over all of their states.
87
88
89
90### Direct generation of observables
91
92Any PDF dependent can be generated with the accept/reject method,
93but for certain PDFs more efficient methods may be implemented. To
94implement direct generation of one or more observables, two
95functions need to be implemented, similar to those for analytical
96integrals:
97
98``Int_t getGenerator(const RooArgSet& generateVars, RooArgSet& directVars)`` and
99``void generateEvent(Int_t code)``
100
101The first function advertises observables that can be generated,
102similar to the way analytical integrals are advertised. The second
103function implements the generator for the advertised observables
104
105The generated dependent values should be store in the proxy
106objects. For this the assignment operator can be used (i.e. xProxy
107= 3.0 ). Never call assign to any proxy not known to be a dependent
108via the generation code. Doing so may be ill-defined, e.g. in case
109the proxy holds a function, and will trigger an assert
110
111
112*/
113
114#include "RooFit.h"
115#include "RooMsgService.h"
116
117#include "TClass.h"
118#include "Riostream.h"
119#include "TMath.h"
120#include "TObjString.h"
121#include "TPaveText.h"
122#include "TList.h"
123#include "TH1.h"
124#include "TH2.h"
125#include "TMatrixD.h"
126#include "TMatrixDSym.h"
127#include "RooAbsPdf.h"
128#include "RooDataSet.h"
129#include "RooArgSet.h"
130#include "RooArgProxy.h"
131#include "RooRealProxy.h"
132#include "RooRealVar.h"
133#include "RooGenContext.h"
134#include "RooBinnedGenContext.h"
135#include "RooPlot.h"
136#include "RooCurve.h"
137#include "RooNLLVar.h"
138#include "RooMinuit.h"
139#include "RooCategory.h"
140#include "RooNameReg.h"
141#include "RooCmdConfig.h"
142#include "RooGlobalFunc.h"
143#include "RooAddition.h"
144#include "RooRandom.h"
145#include "RooNumIntConfig.h"
146#include "RooProjectedPdf.h"
147#include "RooInt.h"
148#include "RooCustomizer.h"
149#include "RooConstraintSum.h"
150#include "RooParamBinning.h"
151#include "RooNumCdf.h"
152#include "RooFitResult.h"
153#include "RooNumGenConfig.h"
154#include "RooCachedReal.h"
155#include "RooXYChi2Var.h"
156#include "RooChi2Var.h"
157#include "RooMinimizer.h"
158#include "RooRealIntegral.h"
159#include "RooWorkspace.h"
160#include "Math/CholeskyDecomp.h"
161#include <string>
162
163using namespace std;
164
166;
168;
169
173
174////////////////////////////////////////////////////////////////////////////////
175/// Default constructor
176
177RooAbsPdf::RooAbsPdf() : _norm(0), _normSet(0), _specGeneratorConfig(0)
178{
179 _errorCount = 0 ;
180 _negCount = 0 ;
181 _rawValue = 0 ;
183 _traceCount = 0 ;
184}
185
186
187
188////////////////////////////////////////////////////////////////////////////////
189/// Constructor with name and title only
190
191RooAbsPdf::RooAbsPdf(const char *name, const char *title) :
192 RooAbsReal(name,title), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
193{
195 setTraceCounter(0) ;
196}
197
198
199
200////////////////////////////////////////////////////////////////////////////////
201/// Constructor with name, title, and plot range
202
203RooAbsPdf::RooAbsPdf(const char *name, const char *title,
204 Double_t plotMin, Double_t plotMax) :
205 RooAbsReal(name,title,plotMin,plotMax), _norm(0), _normSet(0), _normMgr(this,10), _selectComp(kTRUE), _specGeneratorConfig(0)
206{
208 setTraceCounter(0) ;
209}
210
211
212
213////////////////////////////////////////////////////////////////////////////////
214/// Copy constructor
215
216RooAbsPdf::RooAbsPdf(const RooAbsPdf& other, const char* name) :
217 RooAbsReal(other,name), _norm(0), _normSet(0),
218 _normMgr(other._normMgr,this), _selectComp(other._selectComp), _normRange(other._normRange)
219{
222
223 if (other._specGeneratorConfig) {
225 } else {
227 }
228}
229
230
231
232////////////////////////////////////////////////////////////////////////////////
233/// Destructor
234
236{
238}
239
240
241
242////////////////////////////////////////////////////////////////////////////////
243/// Return current value, normalized by integrating over
244/// the observables in 'nset'. If 'nset' is 0, the unnormalized value
245/// is returned. All elements of 'nset' must be lvalues
246///
247/// Unnormalized values are not cached.
248/// Doing so would be complicated as _norm->getVal() could
249/// spoil the cache and interfere with returning the cached
250/// return value. Since unnormalized calls are typically
251/// done in integration calls, there is no performance hit.
252
254{
255 // Fast-track processing of clean-cache objects
256 // if (_operMode==AClean) {
257 // cout << "RooAbsPdf::getValV(" << this << "," << GetName() << ") CLEAN value = " << _value << endl ;
258 // return _value ;
259 // }
260
261 // Special handling of case without normalization set (used in numeric integration of pdfs)
262 if (!nset) {
263 RooArgSet* tmp = _normSet ;
264 _normSet = 0 ;
265 Double_t val = evaluate() ;
266 _normSet = tmp ;
267 Bool_t error = traceEvalPdf(val) ;
268
269 if (error) {
270// raiseEvalError() ;
271 return 0 ;
272 }
273 return val ;
274 }
275
276
277 // Process change in last data set used
278 Bool_t nsetChanged(kFALSE) ;
279 if (nset!=_normSet || _norm==0) {
280 nsetChanged = syncNormalization(nset) ;
281 }
282
283 // Return value of object. Calculated if dirty, otherwise cached value is returned.
284 if (isValueDirty() || nsetChanged || _norm->isValueDirty()) {
285
286 // Evaluate numerator
287 Double_t rawVal = evaluate() ;
288 Bool_t error = traceEvalPdf(rawVal) ; // Error checking and printing
290 // Evaluate denominator
291 Double_t normVal(_norm->getVal()) ;
292
293 if (normVal<=0.) {
294 error=kTRUE ;
295 logEvalError("p.d.f normalization integral is zero or negative") ;
296 }
297
298 // Raise global error flag if problems occur
299 if (error) {
300// raiseEvalError() ;
301 _value = 0 ;
302 } else {
303 _value = rawVal / normVal ;
304// cout << "RooAbsPdf::getValV(" << GetName() << ") writing _value = " << rawVal << "/" << normVal << " = " << _value << endl ;
305 }
306
307 clearValueAndShapeDirty() ; //setValueDirty(kFALSE) ;
308 }
309
310 return _value ;
311}
312
313
314
315////////////////////////////////////////////////////////////////////////////////
316/// Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further information)
317///
318/// This function applies the normalization specified by 'normSet' to the integral returned
319/// by RooAbsReal::analyticalIntegral(). The passthrough scenario (code=0) is also changed
320/// to return a normalized answer
321
322Double_t RooAbsPdf::analyticalIntegralWN(Int_t code, const RooArgSet* normSet, const char* rangeName) const
323{
324 cxcoutD(Eval) << "RooAbsPdf::analyticalIntegralWN(" << GetName() << ") code = " << code << " normset = " << (normSet?*normSet:RooArgSet()) << endl ;
325
326
327 if (code==0) return getVal(normSet) ;
328 if (normSet) {
329 return analyticalIntegral(code,rangeName) / getNorm(normSet) ;
330 } else {
331 return analyticalIntegral(code,rangeName) ;
332 }
333}
334
335
336
337////////////////////////////////////////////////////////////////////////////////
338/// Check that passed value is positive and not 'not-a-number'. If
339/// not, print an error, until the error counter reaches its set
340/// maximum.
341
343{
344 // check for a math error or negative value
345 Bool_t error(kFALSE) ;
346 if (TMath::IsNaN(value)) {
347 logEvalError(Form("p.d.f value is Not-a-Number (%f), forcing value to zero",value)) ;
348 error=kTRUE ;
349 }
350 if (value<0) {
351 logEvalError(Form("p.d.f value is less than zero (%f), forcing value to zero",value)) ;
352 error=kTRUE ;
353 }
354
355 // do nothing if we are no longer tracing evaluations and there was no error
356 if(!error) return error ;
357
358 // otherwise, print out this evaluations input values and result
359 if(++_errorCount <= 10) {
360 cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
361 if(_errorCount == 10) cxcoutD(Tracing) << "(no more will be printed) ";
362 }
363 else {
364 return error ;
365 }
366
367 Print() ;
368 return error ;
369}
370
371
372
373
374////////////////////////////////////////////////////////////////////////////////
375/// Return the integral of this PDF over all observables listed in 'nset'.
376
378{
379 if (!nset) return 1 ;
380
382 if (_verboseEval>1) cxcoutD(Tracing) << IsA()->GetName() << "::getNorm(" << GetName() << "): norm(" << _norm << ") = " << _norm->getVal() << endl ;
383
384 Double_t ret = _norm->getVal() ;
385 if (ret==0.) {
386 if(++_errorCount <= 10) {
387 coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ":: WARNING normalization is zero, nset = " ; nset->Print("1") ;
388 if(_errorCount == 10) coutW(Eval) << "RooAbsPdf::getNorm(" << GetName() << ") INFO: no more messages will be printed " << endl ;
389 }
390 }
391
392 return ret ;
393}
394
395
396
397////////////////////////////////////////////////////////////////////////////////
398/// Return pointer to RooAbsReal object that implements calculation of integral over observables iset in range
399/// rangeName, optionally taking the integrand normalized over observables nset
400
401const RooAbsReal* RooAbsPdf::getNormObj(const RooArgSet* nset, const RooArgSet* iset, const TNamed* rangeName) const
402{
403
404 // Check normalization is already stored
405 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset,iset,0,rangeName) ;
406 if (cache) {
407 return cache->_norm ;
408 }
409
410 // If not create it now
411 RooArgSet* depList = getObservables(iset) ;
412 RooAbsReal* norm = createIntegral(*depList,*nset, *getIntegratorConfig(), RooNameReg::str(rangeName)) ;
413 delete depList ;
414
415 // Store it in the cache
416 cache = new CacheElem(*norm) ;
417 _normMgr.setObj(nset,iset,cache,rangeName) ;
418
419 // And return the newly created integral
420 return norm ;
421}
422
423
424
425////////////////////////////////////////////////////////////////////////////////
426/// Verify that the normalization integral cached with this PDF
427/// is valid for given set of normalization observables
428///
429/// If not, the cached normalization integral (if any) is deleted
430/// and a new integral is constructed for use with 'nset'
431/// Elements in 'nset' can be discrete and real, but must be lvalues
432///
433/// For functions that declare to be self-normalized by overloading the
434/// selfNormalized() function, a unit normalization is always constructed
435
436Bool_t RooAbsPdf::syncNormalization(const RooArgSet* nset, Bool_t adjustProxies) const
437{
438
439// cout << IsA()->GetName() << "::syncNormalization(" << GetName() << ") nset = " << nset << " = " << (nset?*nset:RooArgSet()) << endl ;
440
441 _normSet = (RooArgSet*) nset ;
442
443 // Check if data sets are identical
444 CacheElem* cache = (CacheElem*) _normMgr.getObj(nset) ;
445 if (cache) {
446
447 Bool_t nsetChanged = (_norm!=cache->_norm) ;
448 _norm = cache->_norm ;
449
450
451// cout << "returning existing object " << _norm->GetName() << endl ;
452
453 if (nsetChanged && adjustProxies) {
454 // Update dataset pointers of proxies
455 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
456 }
457
458 return nsetChanged ;
459 }
460
461 // Update dataset pointers of proxies
462 if (adjustProxies) {
463 ((RooAbsPdf*) this)->setProxyNormSet(nset) ;
464 }
465
466 RooArgSet* depList = getObservables(nset) ;
467
468 if (_verboseEval>0) {
469 if (!selfNormalized()) {
470 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName()
471 << ") recreating normalization integral " << endl ;
472 if (depList) depList->printStream(ccoutD(Tracing),kName|kValue|kArgs,kSingleLine) ; else ccoutD(Tracing) << "<none>" << endl ;
473 } else {
474 cxcoutD(Tracing) << IsA()->GetName() << "::syncNormalization(" << GetName() << ") selfNormalized, creating unit norm" << endl;
475 }
476 }
477
478 // Destroy old normalization & create new
479 if (selfNormalized() || !dependsOn(*depList)) {
480 TString ntitle(GetTitle()) ; ntitle.Append(" Unit Normalization") ;
481 TString nname(GetName()) ; nname.Append("_UnitNorm") ;
482 _norm = new RooRealVar(nname.Data(),ntitle.Data(),1) ;
483 } else {
484 const char* nr = (_normRangeOverride.Length()>0 ? _normRangeOverride.Data() : (_normRange.Length()>0 ? _normRange.Data() : 0)) ;
485
486// cout << "RooAbsPdf::syncNormalization(" << GetName() << ") rangeName for normalization is " << (nr?nr:"<null>") << endl ;
487 RooAbsReal* normInt = createIntegral(*depList,*getIntegratorConfig(),nr) ;
488 normInt->getVal() ;
489// cout << "resulting normInt = " << normInt->GetName() << endl ;
490
491 const char* cacheParamsStr = getStringAttribute("CACHEPARAMINT") ;
492 if (cacheParamsStr && strlen(cacheParamsStr)) {
493
494 RooArgSet* intParams = normInt->getVariables() ;
495
496 RooNameSet cacheParamNames ;
497 cacheParamNames.setNameList(cacheParamsStr) ;
498 RooArgSet* cacheParams = cacheParamNames.select(*intParams) ;
499
500 if (cacheParams->getSize()>0) {
501 cxcoutD(Caching) << "RooAbsReal::createIntObj(" << GetName() << ") INFO: constructing " << cacheParams->getSize()
502 << "-dim value cache for integral over " << *depList << " as a function of " << *cacheParams << " in range " << (nr?nr:"<default>") << endl ;
503 string name = Form("%s_CACHE_[%s]",normInt->GetName(),cacheParams->contentsString().c_str()) ;
504 RooCachedReal* cachedIntegral = new RooCachedReal(name.c_str(),name.c_str(),*normInt,*cacheParams) ;
505 cachedIntegral->setInterpolationOrder(2) ;
506 cachedIntegral->addOwnedComponents(*normInt) ;
507 cachedIntegral->setCacheSource(kTRUE) ;
508 if (normInt->operMode()==ADirty) {
509 cachedIntegral->setOperMode(ADirty) ;
510 }
511 normInt= cachedIntegral ;
512 }
513
514 delete cacheParams ;
515 delete intParams ;
516 }
517 _norm = normInt ;
518 }
519
520 // Register new normalization with manager (takes ownership)
521 cache = new CacheElem(*_norm) ;
522 _normMgr.setObj(nset,cache) ;
523
524// cout << "making new object " << _norm->GetName() << endl ;
525
526 delete depList ;
527 return kTRUE ;
528}
529
530
531
532////////////////////////////////////////////////////////////////////////////////
533/// WVE 08/21/01 Probably obsolete now.
534
536{
537 // Floating point error checking and tracing for given float value
538
539 // check for a math error or negative value
540 Bool_t error= TMath::IsNaN(value) || (value < 0);
541
542 // do nothing if we are no longer tracing evaluations and there was no error
543 if(!error && _traceCount <= 0) return error ;
544
545 // otherwise, print out this evaluations input values and result
546 if(error && ++_errorCount <= 10) {
547 cxcoutD(Tracing) << "*** Evaluation Error " << _errorCount << " ";
548 if(_errorCount == 10) ccoutD(Tracing) << "(no more will be printed) ";
549 }
550 else if(_traceCount > 0) {
551 ccoutD(Tracing) << '[' << _traceCount-- << "] ";
552 }
553 else {
554 return error ;
555 }
556
557 Print() ;
558
559 return error ;
560}
561
562
563
564
565////////////////////////////////////////////////////////////////////////////////
566/// Reset error counter to given value, limiting the number
567/// of future error messages for this pdf to 'resetValue'
568
570{
571 _errorCount = resetValue ;
572 _negCount = resetValue ;
573}
574
575
576
577////////////////////////////////////////////////////////////////////////////////
578/// Reset trace counter to given value, limiting the
579/// number of future trace messages for this pdf to 'value'
580
582{
583 if (!allNodes) {
584 _traceCount = value ;
585 return ;
586 } else {
587 RooArgList branchList ;
588 branchNodeServerList(&branchList) ;
589 TIterator* iter = branchList.createIterator() ;
590 RooAbsArg* arg ;
591 while((arg=(RooAbsArg*)iter->Next())) {
592 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
593 if (pdf) pdf->setTraceCounter(value,kFALSE) ;
594 }
595 delete iter ;
596 }
597
598}
599
600
601
602
603////////////////////////////////////////////////////////////////////////////////
604/// Return the log of the current value with given normalization
605/// An error message is printed if the argument of the log is negative.
606
608{
609 Double_t prob = getVal(nset) ;
610
611 if (fabs(prob)>1e6) {
612 coutW(Eval) << "RooAbsPdf::getLogVal(" << GetName() << ") WARNING: large likelihood value: " << prob << endl ;
613 }
614
615 if(prob < 0) {
616
617 logEvalError("getLogVal() top-level p.d.f evaluates to a negative number") ;
618
619 return 0;
620 }
621 if(prob == 0) {
622
623 logEvalError("getLogVal() top-level p.d.f evaluates to zero") ;
624
625 return log((double)0);
626 }
627
628 if (TMath::IsNaN(prob)) {
629 logEvalError("getLogVal() top-level p.d.f evaluates to NaN") ;
630
631 return log((double)0);
632
633 }
634 return log(prob);
635}
636
637
638
639////////////////////////////////////////////////////////////////////////////////
640/// Returned the extended likelihood term (Nexpect - Nobserved*log(NExpected)
641/// of this PDF for the given number of observed events
642///
643/// For successfull operation the PDF implementation must indicate
644/// it is extendable by overloading canBeExtended() and must
645/// implemented the expectedEvents() function.
646
648{
649 // check if this PDF supports extended maximum likelihood fits
650 if(!canBeExtended()) {
651 coutE(InputArguments) << fName << ": this PDF does not support extended maximum likelihood"
652 << endl;
653 return 0;
654 }
655
656 Double_t expected= expectedEvents(nset);
657 if(expected < 0) {
658 coutE(InputArguments) << fName << ": calculated negative expected events: " << expected
659 << endl;
660 return 0;
661 }
662
663
664 // Explicitly handle case Nobs=Nexp=0
665 if (fabs(expected)<1e-10 && fabs(observed)<1e-10) {
666 return 0 ;
667 }
668
669 // Check for errors in Nexpected
670 if (expected<0 || TMath::IsNaN(expected)) {
671 logEvalError("extendedTerm #expected events is <0 or NaN") ;
672 return 0 ;
673 }
674
675 // calculate and return the negative log-likelihood of the Poisson
676 // factor for this dataset, dropping the constant log(observed!)
677 // Double_t extra=0;
678 // if(observed<1000000) {
679 // Double_t Delta1 = (expected-observed);
680 // Double_t Delta2 = observed*(log(expected)-log(observed+1));
681 // Double_t Const3 = 0.5*log(observed+1);
682 // extra= Delta1 - Delta2 + Const3;
683
684 // cout << " extra obs = " << observed << " exp = " << expected << endl ;
685 // cout << " extra orig = " << expected - observed*log(expected) << endl ;
686 // cout << " extra orig fix = " << expected - observed*log(expected) + log(TMath::Gamma(observed+1)) << endl ;
687 // cout << " extra new = " << extra << endl ;
688
689 // } else {
690 // Double_t sigma_square=expected;
691 // Double_t diff=observed-expected;
692 // extra=-log(sigma_square)/2 + (diff*diff)/(2*sigma_square);
693 // }
694
695 Double_t extra= expected - observed*log(expected);
696
697// cout << "RooAbsPdf::extendedTerm(" << GetName() << ") observed = " << observed << " expected = " << expected << endl ;
698
699 Bool_t trace(kFALSE) ;
700 if(trace) {
701 cxcoutD(Tracing) << fName << "::extendedTerm: expected " << expected << " events, got "
702 << observed << " events. extendedTerm = " << extra << endl;
703 }
704
705// cout << "RooAbsPdf::extendedTerm(" << GetName() << ") nExp = " << expected << " nObs = " << observed << endl ;
706 return extra;
707}
708
709
710
711////////////////////////////////////////////////////////////////////////////////
712/// Construct representation of -log(L) of PDF with given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
713/// is binned, a binned likelihood is constructed.
714///
715/// The following named arguments are supported
716///
717/// <table>
718/// <tr><th> Type of CmdArg <th> Effect on nll
719/// <tr><td> `ConditionalObservables(const RooArgSet& set)` <td> Do not normalize PDF over listed observables
720/// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
721/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
722/// <tr><td> `Range(Double_t lo, Double_t hi)` <td> Fit only data inside given range. A range named "fit" is created on the fly on all observables.
723/// Multiple comma separated range names can be specified.
724/// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
725/// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on num CPUs
726/// <table>
727/// <tr><th> Strategy <th> Effect
728/// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
729/// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
730/// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
731/// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
732/// and distribute components over processes. This approach can be benificial if normalization calculation time
733/// dominates the total computation time of a component (since the normalization calculation must be performed
734/// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
735/// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
736/// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
737/// do not share many parameters
738/// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
739/// 30 dataset entries, for which strategy 2 is followed.
740/// </table>
741/// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization (on by default)
742/// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed to
743/// by rangeName_{indexState} where indexState is the state of the master index category of the simultaneous fit
744/// <tr><td> `Constrain(const RooArgSet&pars)` <td> For p.d.f.s that contain internal parameter constraint terms, only apply constraints to
745/// given subset of parameters
746/// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood
747/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
748/// If none are specified the constrained parameters are used
749/// <tr><td> `GlobalObservablesTag(const char* tagName)` <td> Define the set of normalization observables to be used for the constraint terms by
750/// a string attribute associated with pdf observables that match the given tagName
751/// <tr><td> `Verbose(Bool_t flag)` <td> Controls RooFit informational messages in likelihood construction
752/// <tr><td> `CloneData(Bool flag)` <td> Use clone of dataset in NLL (default is true)
753/// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
754/// This can improve numeric stability in simultaneously fits with components with large likelihood values
755/// </table>
756///
757///
758
759RooAbsReal* RooAbsPdf::createNLL(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
760 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
761{
763 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
764 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
765 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
766 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
767 return createNLL(data,l) ;
768}
769
770
771
772
773////////////////////////////////////////////////////////////////////////////////
774/// Construct representation of -log(L) of PDFwith given dataset. If dataset is unbinned, an unbinned likelihood is constructed. If the dataset
775/// is binned, a binned likelihood is constructed.
776///
777/// See RooAbsPdf::createNLL(RooAbsData& data, RooCmdArg arg1, RooCmdArg arg2, RooCmdArg arg3, RooCmdArg arg4,
778/// RooCmdArg arg5, RooCmdArg arg6, RooCmdArg arg7, RooCmdArg arg8)
779/// for documentation of options
780
782{
783
784 // Select the pdf-specific commands
785 RooCmdConfig pc(Form("RooAbsPdf::createNLL(%s)",GetName())) ;
786
787 pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
788 pc.defineString("addCoefRange","SumCoefRange",0,"") ;
789 pc.defineString("globstag","GlobalObservablesTag",0,"") ;
790 pc.defineDouble("rangeLo","Range",0,-999.) ;
791 pc.defineDouble("rangeHi","Range",1,-999.) ;
792 pc.defineInt("splitRange","SplitRange",0,0) ;
793 pc.defineInt("ext","Extended",0,2) ;
794 pc.defineInt("numcpu","NumCPU",0,1) ;
795 pc.defineInt("interleave","NumCPU",1,0) ;
796 pc.defineInt("verbose","Verbose",0,0) ;
797 pc.defineInt("optConst","Optimize",0,0) ;
798 pc.defineInt("cloneData","CloneData",2,0) ;
799 pc.defineSet("projDepSet","ProjectedObservables",0,0) ;
800 pc.defineSet("cPars","Constrain",0,0) ;
801 pc.defineSet("glObs","GlobalObservables",0,0) ;
802 pc.defineInt("constrAll","Constrained",0,0) ;
803 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
804 pc.defineSet("extCons","ExternalConstraints",0,0) ;
805 pc.defineMutex("Range","RangeWithName") ;
806 pc.defineMutex("Constrain","Constrained") ;
807 pc.defineMutex("GlobalObservables","GlobalObservablesTag") ;
808
809 // Process and check varargs
810 pc.process(cmdList) ;
811 if (!pc.ok(kTRUE)) {
812 return 0 ;
813 }
814
815 // Decode command line arguments
816 const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
817 const char* addCoefRangeName = pc.getString("addCoefRange",0,kTRUE) ;
818 const char* globsTag = pc.getString("globstag",0,kTRUE) ;
819 Int_t ext = pc.getInt("ext") ;
820 Int_t numcpu = pc.getInt("numcpu") ;
821 RooFit::MPSplit interl = (RooFit::MPSplit) pc.getInt("interleave") ;
822
823 Int_t splitr = pc.getInt("splitRange") ;
824 Bool_t verbose = pc.getInt("verbose") ;
825 Int_t optConst = pc.getInt("optConst") ;
826 Int_t cloneData = pc.getInt("cloneData") ;
827 Int_t doOffset = pc.getInt("doOffset") ;
828
829 // If no explicit cloneData command is specified, cloneData is set to true if optimization is activated
830 if (cloneData==2) {
831 cloneData = optConst ;
832 }
833
834
835 RooArgSet* cPars = pc.getSet("cPars") ;
836 RooArgSet* glObs = pc.getSet("glObs") ;
837 if (pc.hasProcessed("GlobalObservablesTag")) {
838 if (glObs) delete glObs ;
839 RooArgSet* allVars = getVariables() ;
840 glObs = (RooArgSet*) allVars->selectByAttrib(globsTag,kTRUE) ;
841 coutI(Minimization) << "User-defined specification of global observables definition with tag named '" << globsTag << "'" << endl ;
842 delete allVars ;
843 } else if (!pc.hasProcessed("GlobalObservables")) {
844
845 // Neither GlobalObservables nor GlobalObservablesTag has been processed - try if a default tag is defined in the head node
846 // Check if head not specifies default global observable tag
847 const char* defGlobObsTag = getStringAttribute("DefaultGlobalObservablesTag") ;
848 if (defGlobObsTag) {
849 coutI(Minimization) << "p.d.f. provides built-in specification of global observables definition with tag named '" << defGlobObsTag << "'" << endl ;
850 if (glObs) delete glObs ;
851 RooArgSet* allVars = getVariables() ;
852 glObs = (RooArgSet*) allVars->selectByAttrib(defGlobObsTag,kTRUE) ;
853 }
854 }
855
856
857 Bool_t doStripDisconnected=kFALSE ;
858
859 // If no explicit list of parameters to be constrained is specified apply default algorithm
860 // All terms of RooProdPdfs that do not contain observables and share a parameters with one or more
861 // terms that do contain observables are added as constraints.
862 if (!cPars) {
863 cPars = getParameters(data,kFALSE) ;
864 doStripDisconnected=kTRUE ;
865 }
866 const RooArgSet* extCons = pc.getSet("extCons") ;
867
868 // Process automatic extended option
869 if (ext==2) {
870 ext = ((extendMode()==CanBeExtended || extendMode()==MustBeExtended)) ? 1 : 0 ;
871 if (ext) {
872 coutI(Minimization) << "p.d.f. provides expected number of events, including extended term in likelihood." << endl ;
873 }
874 }
875
876 if (pc.hasProcessed("Range")) {
877 Double_t rangeLo = pc.getDouble("rangeLo") ;
878 Double_t rangeHi = pc.getDouble("rangeHi") ;
879
880 // Create range with name 'fit' with above limits on all observables
881 RooArgSet* obs = getObservables(&data) ;
882 TIterator* iter = obs->createIterator() ;
883 RooAbsArg* arg ;
884 while((arg=(RooAbsArg*)iter->Next())) {
885 RooRealVar* rrv = dynamic_cast<RooRealVar*>(arg) ;
886 if (rrv) rrv->setRange("fit",rangeLo,rangeHi) ;
887 }
888 // Set range name to be fitted to "fit"
889 rangeName = "fit" ;
890 }
891
892 RooArgSet projDeps ;
893 RooArgSet* tmp = pc.getSet("projDepSet") ;
894 if (tmp) {
895 projDeps.add(*tmp) ;
896 }
897
898 // Construct NLL
900 RooAbsReal* nll ;
901 string baseName = Form("nll_%s_%s",GetName(),data.GetName()) ;
902 if (!rangeName || strchr(rangeName,',')==0) {
903 // Simple case: default range, or single restricted range
904 //cout<<"FK: Data test 1: "<<data.sumEntries()<<endl;
905
906 nll = new RooNLLVar(baseName.c_str(),"-log(likelihood)",*this,data,projDeps,ext,rangeName,addCoefRangeName,numcpu,interl,verbose,splitr,cloneData) ;
907
908 } else {
909 // Composite case: multiple ranges
910 RooArgList nllList ;
911 const size_t bufSize = strlen(rangeName)+1;
912 char* buf = new char[bufSize] ;
913 strlcpy(buf,rangeName,bufSize) ;
914 char* token = strtok(buf,",") ;
915 while(token) {
916 RooAbsReal* nllComp = new RooNLLVar(Form("%s_%s",baseName.c_str(),token),"-log(likelihood)",*this,data,projDeps,ext,token,addCoefRangeName,numcpu,interl,verbose,splitr,cloneData) ;
917 nllList.add(*nllComp) ;
918 token = strtok(0,",") ;
919 }
920 delete[] buf ;
921 nll = new RooAddition(baseName.c_str(),"-log(likelihood)",nllList,kTRUE) ;
922 }
924
925 // Collect internal and external constraint specifications
926 RooArgSet allConstraints ;
927
928 if (_myws && _myws->set(Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()))) {
929
930 // retrieve from cache
931 const RooArgSet *constr =
932 _myws->set(Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()));
933 coutI(Minimization) << "createNLL picked up cached consraints from workspace with " << constr->getSize()
934 << " entries" << endl;
935 allConstraints.add(*constr);
936
937 } else {
938
939 if (cPars && cPars->getSize() > 0) {
940 RooArgSet *constraints = getAllConstraints(*data.get(), *cPars, doStripDisconnected);
941 allConstraints.add(*constraints);
942 delete constraints;
943 }
944 if (extCons) {
945 allConstraints.add(*extCons);
946 }
947
948 // write to cache
949 if (_myws) {
950 // cout << "createNLL: creating cache for allconstraints=" << allConstraints << endl ;
951 coutI(Minimization) << "createNLL: caching constraint set under name "
952 << Form("CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content())
953 << " with " << allConstraints.getSize() << " entries" << endl;
955 Form("CACHE_CONSTR_OF_PDF_%s_FOR_OBS_%s", GetName(), RooNameSet(*data.get()).content()), allConstraints);
956 }
957 }
958
959 // Include constraints, if any, in likelihood
960 RooAbsReal* nllCons(0) ;
961 if (allConstraints.getSize()>0 && cPars) {
962
963 coutI(Minimization) << " Including the following contraint terms in minimization: " << allConstraints << endl ;
964 if (glObs) {
965 coutI(Minimization) << "The following global observables have been defined: " << *glObs << endl ;
966 }
967 nllCons = new RooConstraintSum(Form("%s_constr",baseName.c_str()),"nllCons",allConstraints,glObs ? *glObs : *cPars) ;
968 nllCons->setOperMode(ADirty) ;
969 RooAbsReal* orignll = nll ;
970
971 nll = new RooAddition(Form("%s_with_constr",baseName.c_str()),"nllWithCons",RooArgSet(*nll,*nllCons)) ;
972 nll->addOwnedComponents(RooArgSet(*orignll,*nllCons)) ;
973 }
974
975
976 if (optConst) {
978 }
979
980 if (doStripDisconnected) {
981 delete cPars ;
982 }
983
984 if (doOffset) {
985 nll->enableOffsetting(kTRUE) ;
986 }
987
988 return nll ;
989}
990
991
992
993
994
995
996////////////////////////////////////////////////////////////////////////////////
997/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
998/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
999/// commands MIGRAD, HESSE in succession.
1000/// \param[in] data Data to fit the PDF to
1001/// \param[in] arg1 One or more arguments to control the behaviour of the fit
1002/// \return RooFitResult * with the fit status if option Save() is used, 0 otherwise.
1003///
1004/// The following named arguments are supported
1005///
1006/// <table>
1007/// <tr><th> Type of CmdArg <th> Options to control construction of -log(L)
1008/// <tr><td> `ConditionalObservables(const RooArgSet& set)` <td> Do not normalize PDF over listed observables
1009/// <tr><td> `Extended(Bool_t flag)` <td> Add extended likelihood term, off by default
1010/// <tr><td> `Range(const char* name)` <td> Fit only data inside range with given name
1011/// <tr><td> `Range(Double_t lo, Double_t hi)` <td> Fit only data inside given range. A range named "fit" is created on the fly on all observables.
1012/// Multiple comma separated range names can be specified.
1013/// <tr><td> `SumCoefRange(const char* name)` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1014/// <tr><td> `NumCPU(int num, int strat)` <td> Parallelize NLL calculation on num CPUs
1015/// <table>
1016/// <tr><th> Strategy <th> Effect
1017/// <tr><td> 0 = RooFit::BulkPartition (Default) <td> Divide events in N equal chunks
1018/// <tr><td> 1 = RooFit::Interleave <td> Process event i%N in process N. Recommended for binned data with
1019/// a substantial number of zero-bins, which will be distributed across processes more equitably in this strategy
1020/// <tr><td> 2 = RooFit::SimComponents <td> Process each component likelihood of a RooSimultaneous fully in a single process
1021/// and distribute components over processes. This approach can be benificial if normalization calculation time
1022/// dominates the total computation time of a component (since the normalization calculation must be performed
1023/// in each process in strategies 0 and 1. However beware that if the RooSimultaneous components do not share many
1024/// parameters this strategy is inefficient: as most minuit-induced likelihood calculations involve changing
1025/// a single parameter, only 1 of the N processes will be active most of the time if RooSimultaneous components
1026/// do not share many parameters
1027/// <tr><td> 3 = RooFit::Hybrid <td> Follow strategy 0 for all RooSimultaneous components, except those with less than
1028/// 30 dataset entries, for which strategy 2 is followed.
1029/// </table>
1030/// <tr><td> `SplitRange(Bool_t flag)` <td> Use separate fit ranges in a simultaneous fit. Actual range name for each subsample is assumed
1031/// to by rangeName_{indexState} where indexState is the state of the master index category of the simultaneous fit
1032/// <tr><td> `Constrained()` <td> Apply all constrained contained in the p.d.f. in the likelihood
1033/// <tr><td> `Constrain(const RooArgSet&pars)` <td> Apply constraints to listed parameters in likelihood using internal constrains in p.d.f
1034/// <tr><td> `GlobalObservables(const RooArgSet&)` <td> Define the set of normalization observables to be used for the constraint terms.
1035/// If none are specified the constrained parameters are used
1036/// <tr><td> `ExternalConstraints(const RooArgSet& )` <td> Include given external constraints to likelihood
1037/// <tr><td> `Offset(Bool_t)` <td> Offset likelihood by initial value (so that starting value of FCN in minuit is zero).
1038/// This can improve numeric stability in simultaneously fits with components with large likelihood values
1039///
1040/// <tr><th><th> Options to control flow of fit procedure
1041/// <tr><td> `Minimizer(type,algo)` <td> Choose minimization package and algorithm to use. Default is MINUIT/MIGRAD through the RooMinimizer interface,
1042/// but others can be specified (through RooMinimizer interface). Select OldMinuit to use MINUIT through the old RooMinuit interface
1043/// <table>
1044/// <tr><th> Type <th> Algorithm
1045/// <tr><td> OldMinuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1046/// <tr><td> Minuit <td> migrad, simplex, minimize (=migrad+simplex), migradimproved (=migrad+improve)
1047/// <tr><td> Minuit2 <td> migrad, simplex, minimize, scan
1048/// <tr><td> GSLMultiMin <td> conjugatefr, conjugatepr, bfgs, bfgs2, steepestdescent
1049/// <tr><td> GSLSimAn <td> -
1050/// </table>
1051///
1052/// <tr><td> `InitialHesse(Bool_t flag)` <td> Flag controls if HESSE before MIGRAD as well, off by default
1053/// <tr><td> `Optimize(Bool_t flag)` <td> Activate constant term optimization of test statistic during minimization (on by default)
1054/// <tr><td> `Hesse(Bool_t flag)` <td> Flag controls if HESSE is run after MIGRAD, on by default
1055/// <tr><td> `Minos(Bool_t flag)` <td> Flag controls if MINOS is run after HESSE, off by default
1056/// <tr><td> `Minos(const RooArgSet& set)` <td> Only run MINOS on given subset of arguments
1057/// <tr><td> `Save(Bool_t flag)` <td> Flag controls if RooFitResult object is produced and returned, off by default
1058/// <tr><td> `Strategy(Int_t flag)` <td> Set Minuit strategy (0 to 2, default is 1)
1059/// <tr><td> `FitOptions(const char* optStr)` <td> \deprecated Steer fit with classic options string (for backward compatibility).
1060/// \attention Use of this option excludes use of any of the new style steering options.
1061///
1062/// <tr><td> `SumW2Error(Bool_t flag)` <td> Apply correction to errors and covariance matrix.
1063/// This uses sum-of-weights covariance matrix
1064/// to obtain correct error for weighted likelihood fits. If this option is activated the
1065/// corrected covariance matrix is calculated as \f$ V_\mathrm{corr} = V C^{-1} V \f$, where V is the original
1066/// covariance matrix and C is the inverse of the covariance matrix calculated using the
1067/// weights squared
1068///
1069/// <tr><th><th> Options to control informational output
1070/// <tr><td> `Verbose(Bool_t flag)` <td> Flag controls if verbose output is printed (NLL, parameter changes during fit
1071/// <tr><td> `Timer(Bool_t flag)` <td> Time CPU and wall clock consumption of fit steps, off by default
1072/// <tr><td> `PrintLevel(Int_t level)` <td> Set Minuit print level (-1 through 3, default is 1). At -1 all RooFit informational messages are suppressed as well.
1073/// See RooMinimizer::PrintLevel for the meaning of the levels.
1074/// <tr><td> `Warnings(Bool_t flag)` <td> Enable or disable MINUIT warnings (enabled by default)
1075/// <tr><td> `PrintEvalErrors(Int_t numErr)` <td> Control number of p.d.f evaluation errors printed per likelihood evaluation.
1076/// A negative value suppresses output completely, a zero value will only print the error count per p.d.f component,
1077/// a positive value will print details of each error up to numErr messages per p.d.f component.
1078/// </table>
1079///
1080
1081RooFitResult* RooAbsPdf::fitTo(RooAbsData& data, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4,
1082 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1083{
1085 l.Add((TObject*)&arg1) ; l.Add((TObject*)&arg2) ;
1086 l.Add((TObject*)&arg3) ; l.Add((TObject*)&arg4) ;
1087 l.Add((TObject*)&arg5) ; l.Add((TObject*)&arg6) ;
1088 l.Add((TObject*)&arg7) ; l.Add((TObject*)&arg8) ;
1089 return fitTo(data,l) ;
1090}
1091
1092
1093
1094////////////////////////////////////////////////////////////////////////////////
1095/// Fit PDF to given dataset. If dataset is unbinned, an unbinned maximum likelihood is performed. If the dataset
1096/// is binned, a binned maximum likelihood is performed. By default the fit is executed through the MINUIT
1097/// commands MIGRAD, HESSE and MINOS in succession.
1098///
1099/// See RooAbsPdf::fitTo(RooAbsData&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&,RooCmdArg&)
1100///
1101/// for documentation of options
1102
1104{
1105
1106 // Select the pdf-specific commands
1107 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
1108
1109 RooLinkedList fitCmdList(cmdList) ;
1110 RooLinkedList nllCmdList = pc.filterCmdList(fitCmdList,"ProjectedObservables,Extended,Range,RangeWithName,SumCoefRange,NumCPU,SplitRange,Constrained,Constrain,ExternalConstraints,CloneData,GlobalObservables,GlobalObservablesTag,OffsetLikelihood") ;
1111
1112 pc.defineString("fitOpt","FitOptions",0,"") ;
1113 pc.defineInt("optConst","Optimize",0,2) ;
1114 pc.defineInt("verbose","Verbose",0,0) ;
1115 pc.defineInt("doSave","Save",0,0) ;
1116 pc.defineInt("doTimer","Timer",0,0) ;
1117 pc.defineInt("plevel","PrintLevel",0,1) ;
1118 pc.defineInt("strat","Strategy",0,1) ;
1119 pc.defineInt("initHesse","InitialHesse",0,0) ;
1120 pc.defineInt("hesse","Hesse",0,1) ;
1121 pc.defineInt("minos","Minos",0,0) ;
1122 pc.defineInt("ext","Extended",0,2) ;
1123 pc.defineInt("numcpu","NumCPU",0,1) ;
1124 pc.defineInt("numee","PrintEvalErrors",0,10) ;
1125 pc.defineInt("doEEWall","EvalErrorWall",0,1) ;
1126 pc.defineInt("doWarn","Warnings",0,1) ;
1127 pc.defineInt("doSumW2","SumW2Error",0,-1) ;
1128 pc.defineInt("doOffset","OffsetLikelihood",0,0) ;
1129 pc.defineString("mintype","Minimizer",0,"Minuit") ;
1130 pc.defineString("minalg","Minimizer",1,"minuit") ;
1131 pc.defineObject("minosSet","Minos",0,0) ;
1132 pc.defineSet("cPars","Constrain",0,0) ;
1133 pc.defineSet("extCons","ExternalConstraints",0,0) ;
1134 pc.defineMutex("FitOptions","Verbose") ;
1135 pc.defineMutex("FitOptions","Save") ;
1136 pc.defineMutex("FitOptions","Timer") ;
1137 pc.defineMutex("FitOptions","Strategy") ;
1138 pc.defineMutex("FitOptions","InitialHesse") ;
1139 pc.defineMutex("FitOptions","Hesse") ;
1140 pc.defineMutex("FitOptions","Minos") ;
1141 pc.defineMutex("Range","RangeWithName") ;
1142 pc.defineMutex("InitialHesse","Minimizer") ;
1143
1144 // Process and check varargs
1145 pc.process(fitCmdList) ;
1146 if (!pc.ok(kTRUE)) {
1147 return 0 ;
1148 }
1149
1150 // Decode command line arguments
1151 const char* fitOpt = pc.getString("fitOpt",0,kTRUE) ;
1152 Int_t optConst = pc.getInt("optConst") ;
1153 Int_t verbose = pc.getInt("verbose") ;
1154 Int_t doSave = pc.getInt("doSave") ;
1155 Int_t doTimer = pc.getInt("doTimer") ;
1156 Int_t plevel = pc.getInt("plevel") ;
1157 Int_t strat = pc.getInt("strat") ;
1158 Int_t initHesse= pc.getInt("initHesse") ;
1159 Int_t hesse = pc.getInt("hesse") ;
1160 Int_t minos = pc.getInt("minos") ;
1161 Int_t numee = pc.getInt("numee") ;
1162 Int_t doEEWall = pc.getInt("doEEWall") ;
1163 Int_t doWarn = pc.getInt("doWarn") ;
1164 Int_t doSumW2 = pc.getInt("doSumW2") ;
1165 const RooArgSet* minosSet = static_cast<RooArgSet*>(pc.getObject("minosSet")) ;
1166#ifdef __ROOFIT_NOROOMINIMIZER
1167 const char* minType =0 ;
1168#else
1169 const char* minType = pc.getString("mintype","Minuit") ;
1170 const char* minAlg = pc.getString("minalg","minuit") ;
1171#endif
1172
1173 // Determine if the dataset has weights
1174 Bool_t weightedData = data.isNonPoissonWeighted() ;
1175
1176 // Warn user that a SumW2Error() argument should be provided if weighted data is offered
1177 if (weightedData && doSumW2==-1) {
1178 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: a likelihood fit is request of what appears to be weighted data. " << endl
1179 << " While the estimated values of the parameters will always be calculated taking the weights into account, " << endl
1180 << " there are multiple ways to estimate the errors on these parameter values. You are advised to make an " << endl
1181 << " explicit choice on the error calculation: " << endl
1182 << " - Either provide SumW2Error(kTRUE), to calculate a sum-of-weights corrected HESSE error matrix " << endl
1183 << " (error will be proportional to the number of events)" << endl
1184 << " - Or provide SumW2Error(kFALSE), to return errors from original HESSE error matrix" << endl
1185 << " (which will be proportional to the sum of the weights)" << endl
1186 << " If you want the errors to reflect the information contained in the provided dataset, choose kTRUE. " << endl
1187 << " If you want the errors to reflect the precision you would be able to obtain with an unweighted dataset " << endl
1188 << " with 'sum-of-weights' events, choose kFALSE." << endl ;
1189 }
1190
1191
1192 // Warn user that sum-of-weights correction does not apply to MINOS errrors
1193 if (doSumW2==1 && minos) {
1194 coutW(InputArguments) << "RooAbsPdf::fitTo(" << GetName() << ") WARNING: sum-of-weights correction does not apply to MINOS errors" << endl ;
1195 }
1196
1197 RooAbsReal* nll = createNLL(data,nllCmdList) ;
1198 RooFitResult *ret = 0 ;
1199
1200 // Instantiate MINUIT
1201
1202 if (string(minType)!="OldMinuit") {
1203
1204#ifndef __ROOFIT_NOROOMINIMIZER
1205 RooMinimizer m(*nll) ;
1206
1207 m.setMinimizerType(minType) ;
1208
1209 m.setEvalErrorWall(doEEWall) ;
1210 if (doWarn==0) {
1211 // m.setNoWarn() ; WVE FIX THIS
1212 }
1213
1214 m.setPrintEvalErrors(numee) ;
1215 if (plevel!=1) {
1216 m.setPrintLevel(plevel) ;
1217 }
1218
1219 if (optConst) {
1220 // Activate constant term optimization
1221 m.optimizeConst(optConst) ;
1222 }
1223
1224 if (fitOpt) {
1225
1226 // Play fit options as historically defined
1227 ret = m.fit(fitOpt) ;
1228
1229 } else {
1230
1231 if (verbose) {
1232 // Activate verbose options
1233 m.setVerbose(1) ;
1234 }
1235 if (doTimer) {
1236 // Activate timer options
1237 m.setProfile(1) ;
1238 }
1239
1240 if (strat!=1) {
1241 // Modify fit strategy
1242 m.setStrategy(strat) ;
1243 }
1244
1245 if (initHesse) {
1246 // Initialize errors with hesse
1247 m.hesse() ;
1248 }
1249
1250 // Minimize using chosen algorithm
1251 m.minimize(minType,minAlg) ;
1252
1253 if (hesse) {
1254 // Evaluate errors with Hesse
1255 m.hesse() ;
1256 }
1257
1258 if (doSumW2==1 && m.getNPar()>0) {
1259 // Make list of RooNLLVar components of FCN
1260 RooArgSet* comps = nll->getComponents();
1261 vector<RooNLLVar*> nllComponents;
1262 nllComponents.reserve(comps->getSize());
1263 TIterator* citer = comps->createIterator();
1264 RooAbsArg* arg;
1265 while ((arg=(RooAbsArg*)citer->Next())) {
1266 RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg);
1267 if (!nllComp) continue;
1268 nllComponents.push_back(nllComp);
1269 }
1270 delete citer;
1271 delete comps;
1272
1273 // Calculated corrected errors for weighted likelihood fits
1274 RooFitResult* rw = m.save();
1275 for (vector<RooNLLVar*>::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) {
1276 (*it)->applyWeightSquared(kTRUE);
1277 }
1278 coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
1279 m.hesse();
1280 RooFitResult* rw2 = m.save();
1281 for (vector<RooNLLVar*>::iterator it = nllComponents.begin(); nllComponents.end() != it; ++it) {
1282 (*it)->applyWeightSquared(kFALSE);
1283 }
1284
1285 // Apply correction matrix
1286 const TMatrixDSym& matV = rw->covarianceMatrix();
1287 TMatrixDSym matC = rw2->covarianceMatrix();
1289 CholeskyDecompGenDim<Double_t> decomp(matC.GetNrows(), matC);
1290 if (!decomp) {
1291 coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
1292 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
1293 } else {
1294 // replace C by its inverse
1295 decomp.Invert(matC);
1296 // the class lies about the matrix being symmetric, so fill in the
1297 // part above the diagonal
1298 for (int i = 0; i < matC.GetNrows(); ++i)
1299 for (int j = 0; j < i; ++j) matC(j, i) = matC(i, j);
1300 matC.Similarity(matV);
1301 // C now contiains V C^-1 V
1302 // Propagate corrected errors to parameters objects
1303 m.applyCovarianceMatrix(matC);
1304 }
1305
1306 delete rw;
1307 delete rw2;
1308 }
1309
1310 if (minos) {
1311 // Evaluate errs with Minos
1312 if (minosSet) {
1313 m.minos(*minosSet) ;
1314 } else {
1315 m.minos() ;
1316 }
1317 }
1318
1319 // Optionally return fit result
1320 if (doSave) {
1321 string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
1322 string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
1323 ret = m.save(name.c_str(),title.c_str()) ;
1324 }
1325
1326 }
1327 if (optConst) {
1328 m.optimizeConst(0) ;
1329 }
1330
1331#endif
1332
1333 } else {
1334
1335 RooMinuit m(*nll) ;
1336
1337 m.setEvalErrorWall(doEEWall) ;
1338 if (doWarn==0) {
1339 m.setNoWarn() ;
1340 }
1341
1342 m.setPrintEvalErrors(numee) ;
1343 if (plevel!=1) {
1344 m.setPrintLevel(plevel) ;
1345 }
1346
1347 if (optConst) {
1348 // Activate constant term optimization
1349 m.optimizeConst(optConst) ;
1350 }
1351
1352 if (fitOpt) {
1353
1354 // Play fit options as historically defined
1355 ret = m.fit(fitOpt) ;
1356
1357 } else {
1358
1359 if (verbose) {
1360 // Activate verbose options
1361 m.setVerbose(1) ;
1362 }
1363 if (doTimer) {
1364 // Activate timer options
1365 m.setProfile(1) ;
1366 }
1367
1368 if (strat!=1) {
1369 // Modify fit strategy
1370 m.setStrategy(strat) ;
1371 }
1372
1373 if (initHesse) {
1374 // Initialize errors with hesse
1375 m.hesse() ;
1376 }
1377
1378 // Minimize using migrad
1379 m.migrad() ;
1380
1381 if (hesse) {
1382 // Evaluate errors with Hesse
1383 m.hesse() ;
1384 }
1385
1386 if (doSumW2==1 && m.getNPar()>0) {
1387
1388 // Make list of RooNLLVar components of FCN
1389 list<RooNLLVar*> nllComponents ;
1390 RooArgSet* comps = nll->getComponents() ;
1391 RooAbsArg* arg ;
1392 TIterator* citer = comps->createIterator() ;
1393 while((arg=(RooAbsArg*)citer->Next())) {
1394 RooNLLVar* nllComp = dynamic_cast<RooNLLVar*>(arg) ;
1395 if (nllComp) {
1396 nllComponents.push_back(nllComp) ;
1397 }
1398 }
1399 delete citer ;
1400 delete comps ;
1401
1402 // Calculated corrected errors for weighted likelihood fits
1403 RooFitResult* rw = m.save() ;
1404 for (list<RooNLLVar*>::iterator iter1=nllComponents.begin() ; iter1!=nllComponents.end() ; ++iter1) {
1405 (*iter1)->applyWeightSquared(kTRUE) ;
1406 }
1407 coutI(Fitting) << "RooAbsPdf::fitTo(" << GetName() << ") Calculating sum-of-weights-squared correction matrix for covariance matrix" << endl ;
1408 m.hesse() ;
1409 RooFitResult* rw2 = m.save() ;
1410 for (list<RooNLLVar*>::iterator iter2=nllComponents.begin() ; iter2!=nllComponents.end() ; ++iter2) {
1411 (*iter2)->applyWeightSquared(kFALSE) ;
1412 }
1413
1414 // Apply correction matrix
1415 const TMatrixDSym& matV = rw->covarianceMatrix();
1416 TMatrixDSym matC = rw2->covarianceMatrix();
1418 CholeskyDecompGenDim<Double_t> decomp(matC.GetNrows(), matC);
1419 if (!decomp) {
1420 coutE(Fitting) << "RooAbsPdf::fitTo(" << GetName()
1421 << ") ERROR: Cannot apply sum-of-weights correction to covariance matrix: correction matrix calculated with weight-squared is singular" <<endl ;
1422 } else {
1423 // replace C by its inverse
1424 decomp.Invert(matC);
1425 // the class lies about the matrix being symmetric, so fill in the
1426 // part above the diagonal
1427 for (int i = 0; i < matC.GetNrows(); ++i)
1428 for (int j = 0; j < i; ++j) matC(j, i) = matC(i, j);
1429 matC.Similarity(matV);
1430 // C now contiains V C^-1 V
1431 // Propagate corrected errors to parameters objects
1432 m.applyCovarianceMatrix(matC);
1433 }
1434
1435 delete rw ;
1436 delete rw2 ;
1437 }
1438
1439 if (minos) {
1440 // Evaluate errs with Minos
1441 if (minosSet) {
1442 m.minos(*minosSet) ;
1443 } else {
1444 m.minos() ;
1445 }
1446 }
1447
1448 // Optionally return fit result
1449 if (doSave) {
1450 string name = Form("fitresult_%s_%s",GetName(),data.GetName()) ;
1451 string title = Form("Result of fit of p.d.f. %s to dataset %s",GetName(),data.GetName()) ;
1452 ret = m.save(name.c_str(),title.c_str()) ;
1453 }
1454
1455 }
1456
1457 if (optConst) {
1458 m.optimizeConst(0) ;
1459 }
1460
1461 }
1462
1463
1464
1465 // Cleanup
1466 delete nll ;
1467 return ret ;
1468}
1469
1470
1471
1472////////////////////////////////////////////////////////////////////////////////
1473/// Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
1474
1476{
1477 // Select the pdf-specific commands
1478 RooCmdConfig pc(Form("RooAbsPdf::chi2FitTo(%s)",GetName())) ;
1479
1480 // Pull arguments to be passed to chi2 construction from list
1481 RooLinkedList fitCmdList(cmdList) ;
1482 RooLinkedList chi2CmdList = pc.filterCmdList(fitCmdList,"Range,RangeWithName,NumCPU,Optimize,ProjectedObservables,AddCoefRange,SplitRange,DataError,Extended") ;
1483
1484 RooAbsReal* chi2 = createChi2(data,chi2CmdList) ;
1485 RooFitResult* ret = chi2FitDriver(*chi2,fitCmdList) ;
1486
1487 // Cleanup
1488 delete chi2 ;
1489 return ret ;
1490}
1491
1492
1493
1494
1495////////////////////////////////////////////////////////////////////////////////
1496/// Create a \f$ \chi^2 \f$ from a histogram and this function.
1497///
1498/// Options to control construction of the \f$ \chi^2 \f$
1499/// ------------------------------------------
1500/// <table>
1501/// <tr><th> Type of CmdArg <th> Effect on \f$ \chi^2 \f$
1502/// <tr><td> `Extended()` <td> Use expected number of events of an extended p.d.f as normalization
1503/// <tr><td> `DataError()` <td> Choose between:
1504/// - Expected error [RooAbsData::Expected]
1505/// - Observed error (e.g. Sum-of-weights) [RooAbsData::SumW2]
1506/// - Poisson interval [RooAbsData::Poisson]
1507/// - Default: Expected error for unweighted data, Sum-of-weights for weighted data [RooAbsData::Auto]
1508/// <tr><td> `NumCPU()` <td> Activate parallel processing feature
1509/// <tr><td> `Range()` <td> Fit only selected region
1510/// <tr><td> `SumCoefRange()` <td> Set the range in which to interpret the coefficients of RooAddPdf components
1511/// <tr><td> `SplitRange()` <td> Fit range is split by index catory of simultaneous PDF
1512/// <tr><td> `ConditionalObservables()` <td> Define projected observables
1513/// </table>
1514
1516 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
1517 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
1518{
1519 RooLinkedList cmdList ;
1520 cmdList.Add((TObject*)&arg1) ; cmdList.Add((TObject*)&arg2) ;
1521 cmdList.Add((TObject*)&arg3) ; cmdList.Add((TObject*)&arg4) ;
1522 cmdList.Add((TObject*)&arg5) ; cmdList.Add((TObject*)&arg6) ;
1523 cmdList.Add((TObject*)&arg7) ; cmdList.Add((TObject*)&arg8) ;
1524
1525 RooCmdConfig pc(Form("RooAbsPdf::createChi2(%s)",GetName())) ;
1526 pc.defineString("rangeName","RangeWithName",0,"",kTRUE) ;
1527 pc.allowUndefined(kTRUE) ;
1528 pc.process(cmdList) ;
1529 if (!pc.ok(kTRUE)) {
1530 return 0 ;
1531 }
1532 const char* rangeName = pc.getString("rangeName",0,kTRUE) ;
1533
1534 // Construct Chi2
1536 RooAbsReal* chi2 ;
1537 string baseName = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1538
1539 if (!rangeName || strchr(rangeName,',')==0) {
1540 // Simple case: default range, or single restricted range
1541
1542 chi2 = new RooChi2Var(baseName.c_str(),baseName.c_str(),*this,data,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
1543
1544 } else {
1545
1546 // Find which argument is RangeWithName
1547 const RooCmdArg* rarg(0) ;
1548 string rcmd = "RangeWithName" ;
1549 if (arg1.GetName()==rcmd) rarg = &arg1 ;
1550 if (arg2.GetName()==rcmd) rarg = &arg2 ;
1551 if (arg3.GetName()==rcmd) rarg = &arg3 ;
1552 if (arg4.GetName()==rcmd) rarg = &arg4 ;
1553 if (arg5.GetName()==rcmd) rarg = &arg5 ;
1554 if (arg6.GetName()==rcmd) rarg = &arg6 ;
1555 if (arg7.GetName()==rcmd) rarg = &arg7 ;
1556 if (arg8.GetName()==rcmd) rarg = &arg8 ;
1557
1558 // Composite case: multiple ranges
1559 RooArgList chi2List ;
1560 const size_t bufSize = strlen(rangeName)+1;
1561 char* buf = new char[bufSize] ;
1562 strlcpy(buf,rangeName,bufSize) ;
1563 char* token = strtok(buf,",") ;
1564 while(token) {
1565 RooCmdArg subRangeCmd = RooFit::Range(token) ;
1566 // Construct chi2 while substituting original RangeWithName argument with subrange argument created above
1567 RooAbsReal* chi2Comp = new RooChi2Var(Form("%s_%s",baseName.c_str(),token),"chi^2",*this,data,
1568 &arg1==rarg?subRangeCmd:arg1,&arg2==rarg?subRangeCmd:arg2,
1569 &arg3==rarg?subRangeCmd:arg3,&arg4==rarg?subRangeCmd:arg4,
1570 &arg5==rarg?subRangeCmd:arg5,&arg6==rarg?subRangeCmd:arg6,
1571 &arg7==rarg?subRangeCmd:arg7,&arg8==rarg?subRangeCmd:arg8) ;
1572 chi2List.add(*chi2Comp) ;
1573 token = strtok(0,",") ;
1574 }
1575 delete[] buf ;
1576 chi2 = new RooAddition(baseName.c_str(),"chi^2",chi2List,kTRUE) ;
1577 }
1579
1580
1581 return chi2 ;
1582}
1583
1584
1585
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// Argument-list version of RooAbsPdf::createChi2()
1589
1591{
1592 // Select the pdf-specific commands
1593 RooCmdConfig pc(Form("RooAbsPdf::fitTo(%s)",GetName())) ;
1594
1595 pc.defineInt("integrate","Integrate",0,0) ;
1596 pc.defineObject("yvar","YVar",0,0) ;
1597
1598 // Process and check varargs
1599 pc.process(cmdList) ;
1600 if (!pc.ok(kTRUE)) {
1601 return 0 ;
1602 }
1603
1604 // Decode command line arguments
1605 Bool_t integrate = pc.getInt("integrate") ;
1606 RooRealVar* yvar = (RooRealVar*) pc.getObject("yvar") ;
1607
1608 string name = Form("chi2_%s_%s",GetName(),data.GetName()) ;
1609
1610 if (yvar) {
1611 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,*yvar,integrate) ;
1612 } else {
1613 return new RooXYChi2Var(name.c_str(),name.c_str(),*this,data,integrate) ;
1614 }
1615}
1616
1617
1618
1619
1620////////////////////////////////////////////////////////////////////////////////
1621/// Print value of p.d.f, also print normalization integral that was last used, if any
1622
1623void RooAbsPdf::printValue(ostream& os) const
1624{
1625 getVal() ;
1626
1627 if (_norm) {
1628 os << evaluate() << "/" << _norm->getVal() ;
1629 } else {
1630 os << evaluate() ;
1631 }
1632}
1633
1634
1635
1636////////////////////////////////////////////////////////////////////////////////
1637/// Print multi line detailed information of this RooAbsPdf
1638
1639void RooAbsPdf::printMultiline(ostream& os, Int_t contents, Bool_t verbose, TString indent) const
1640{
1641 RooAbsReal::printMultiline(os,contents,verbose,indent);
1642 os << indent << "--- RooAbsPdf ---" << endl;
1643 os << indent << "Cached value = " << _value << endl ;
1644 if (_norm) {
1645 os << indent << " Normalization integral: " << endl ;
1646 TString moreIndent(indent) ; moreIndent.Append(" ") ;
1647 _norm->printStream(os,kName|kAddress|kTitle|kValue|kArgs,kSingleLine,moreIndent.Data()) ;
1648 }
1649}
1650
1651
1652
1653////////////////////////////////////////////////////////////////////////////////
1654/// Return a binned generator context
1655
1657{
1658 return new RooBinnedGenContext(*this,vars,0,0,verbose) ;
1659}
1660
1661
1662////////////////////////////////////////////////////////////////////////////////
1663/// Interface function to create a generator context from a p.d.f. This default
1664/// implementation returns a 'standard' context that works for any p.d.f
1665
1667 const RooArgSet* auxProto, Bool_t verbose) const
1668{
1669 return new RooGenContext(*this,vars,prototype,auxProto,verbose) ;
1670}
1671
1672
1673////////////////////////////////////////////////////////////////////////////////
1674
1675RooAbsGenContext* RooAbsPdf::autoGenContext(const RooArgSet &vars, const RooDataSet* prototype, const RooArgSet* auxProto,
1676 Bool_t verbose, Bool_t autoBinned, const char* binnedTag) const
1677{
1678 if (prototype || (auxProto && auxProto->getSize()>0)) {
1679 return genContext(vars,prototype,auxProto,verbose);
1680 }
1681
1682 RooAbsGenContext *context(0) ;
1683 if ( (autoBinned & isBinnedDistribution(vars)) || ( binnedTag && strlen(binnedTag) && (getAttribute(binnedTag)||string(binnedTag)=="*"))) {
1684 context = binnedGenContext(vars,verbose) ;
1685 } else {
1686 context= genContext(vars,0,0,verbose);
1687 }
1688 return context ;
1689}
1690
1691
1692
1693////////////////////////////////////////////////////////////////////////////////
1694/// Generate a new dataset containing the specified variables with events sampled from our distribution.
1695/// Generate the specified number of events or expectedEvents() if not specified.
1696/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
1697/// constant and not be used for event generation.
1698/// \param[in] argxx Optional RooCmdArg() to change behaviour of generate
1699/// \return RooDataSet *, owned by caller.
1700///
1701/// Any variables of this PDF that are not in whatVars will use their
1702/// current values and be treated as fixed parameters. Returns zero
1703/// in case of an error.
1704///
1705/// <table>
1706/// <tr><th> Type of CmdArg <th> Effect on generate
1707/// <tr><td> `Name(const char* name)` <td> Name of the output dataset
1708/// <tr><td> `Verbose(Bool_t flag)` <td> Print informational messages during event generation
1709/// <tr><td> `NumEvent(int nevt)` <td> Generate specified number of events
1710/// <tr><td> `Extended()` <td> The actual number of events generated will be sampled from a Poisson distribution with mu=nevt.
1711/// For use with extended maximum likelihood fits
1712/// <tr><td> `GenBinned(const char* tag)` <td> Use binned generation for all component pdfs that have 'setAttribute(tag)' set
1713/// <tr><td> `AutoBinned(Bool_t flag)` <td> Automatically deploy binned generation for binned distributions (e.g. RooHistPdf, sums and products of
1714/// RooHistPdfs etc)
1715/// \note Datasets that are generated in binned mode are returned as weighted unbinned datasets
1716///
1717/// <tr><td> `AllBinned()` <td> As above, but for all components.
1718/// \note The notion of components is only meaningful for simultaneous PDFs
1719/// as binned generation is always executed at the top-level node for a regular
1720/// PDF, so for those it only mattes that the top-level node is tagged.
1721///
1722/// <tr><td> ProtoData(const RooDataSet& data, Bool_t randOrder)
1723/// <td> Use specified dataset as prototype dataset. If randOrder in ProtoData() is set to true,
1724/// the order of the events in the dataset will be read in a random order if the requested
1725/// number of events to be generated does not match the number of events in the prototype dataset.
1726/// \note If ProtoData() is used, the specified existing dataset as a prototype: the new dataset will contain
1727/// the same number of events as the prototype (unless otherwise specified), and any prototype variables not in
1728/// whatVars will be copied into the new dataset for each generated event and also used to set our PDF parameters.
1729/// The user can specify a number of events to generate that will override the default. The result is a
1730/// copy of the prototype dataset with only variables in whatVars randomized. Variables in whatVars that
1731/// are not in the prototype will be added as new columns to the generated dataset.
1732///
1733/// </table>
1734///
1735
1736RooDataSet *RooAbsPdf::generate(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
1737 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
1738{
1739 // Select the pdf-specific commands
1740 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
1741 pc.defineObject("proto","PrototypeData",0,0) ;
1742 pc.defineString("dsetName","Name",0,"") ;
1743 pc.defineInt("randProto","PrototypeData",0,0) ;
1744 pc.defineInt("resampleProto","PrototypeData",1,0) ;
1745 pc.defineInt("verbose","Verbose",0,0) ;
1746 pc.defineInt("extended","Extended",0,0) ;
1747 pc.defineInt("nEvents","NumEvents",0,0) ;
1748 pc.defineInt("autoBinned","AutoBinned",0,1) ;
1749 pc.defineInt("expectedData","ExpectedData",0,0) ;
1750 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
1751 pc.defineString("binnedTag","GenBinned",0,"") ;
1752 pc.defineMutex("GenBinned","ProtoData") ;
1753
1754 // Process and check varargs
1755 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
1756 if (!pc.ok(kTRUE)) {
1757 return 0 ;
1758 }
1759
1760 // Decode command line arguments
1761 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
1762 const char* dsetName = pc.getString("dsetName") ;
1763 Bool_t verbose = pc.getInt("verbose") ;
1764 Bool_t randProto = pc.getInt("randProto") ;
1765 Bool_t resampleProto = pc.getInt("resampleProto") ;
1766 Bool_t extended = pc.getInt("extended") ;
1767 Bool_t autoBinned = pc.getInt("autoBinned") ;
1768 const char* binnedTag = pc.getString("binnedTag") ;
1769 Int_t nEventsI = pc.getInt("nEvents") ;
1770 Double_t nEventsD = pc.getInt("nEventsD") ;
1771 //Bool_t verbose = pc.getInt("verbose") ;
1772 Bool_t expectedData = pc.getInt("expectedData") ;
1773
1774 Double_t nEvents = (nEventsD>0) ? nEventsD : Double_t(nEventsI);
1775
1776 // Force binned mode for expected data mode
1777 if (expectedData) {
1778 binnedTag="*" ;
1779 }
1780
1781 if (extended) {
1782 if (nEvents == 0) nEvents = expectedEvents(&whatVars);
1783 // nEvents = RooRandom::randomGenerator()->Poisson(nEvents==0 ? expectedEvents(&whatVars) : nEvents ) ;
1784 // // If Poisson fluctuation results in zero events, stop here
1785 // if (nEvents==0) {
1786 // return new RooDataSet("emptyData","emptyData",whatVars) ;
1787 // }
1788 } else if (nEvents==0) {
1789 cxcoutI(Generation) << "No number of events specified , number of events generated is "
1790 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
1791 }
1792
1793 if (extended && protoData && !randProto) {
1794 cxcoutI(Generation) << "WARNING Using generator option Extended() (Poisson distribution of #events) together "
1795 << "with a prototype dataset implies incomplete sampling or oversampling of proto data. "
1796 << "Set randomize flag in ProtoData() option to randomize prototype dataset order and thus "
1797 << "to randomize the set of over/undersampled prototype events for each generation cycle." << endl ;
1798 }
1799
1800
1801 // Forward to appropriate implementation
1802 RooDataSet* data ;
1803 if (protoData) {
1804 data = generate(whatVars,*protoData,Int_t(nEvents),verbose,randProto,resampleProto) ;
1805 } else {
1806 data = generate(whatVars,nEvents,verbose,autoBinned,binnedTag,expectedData, extended) ;
1807 }
1808
1809 // Rename dataset to given name if supplied
1810 if (dsetName && strlen(dsetName)>0) {
1811 data->SetName(dsetName) ;
1812 }
1813
1814 return data ;
1815}
1816
1817
1818
1819
1820
1821
1822////////////////////////////////////////////////////////////////////////////////
1823/// \note This method does not perform any generation. To generate according to generations specification call RooAbsPdf::generate(RooAbsPdf::GenSpec&) const
1824///
1825/// Details copied from RooAbsPdf::generate():
1826/// --------------------------------------------
1827/// \copydetails RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&)
1828
1830 const RooCmdArg& arg1,const RooCmdArg& arg2,
1831 const RooCmdArg& arg3,const RooCmdArg& arg4,
1832 const RooCmdArg& arg5,const RooCmdArg& arg6)
1833{
1834
1835 // Select the pdf-specific commands
1836 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
1837 pc.defineObject("proto","PrototypeData",0,0) ;
1838 pc.defineString("dsetName","Name",0,"") ;
1839 pc.defineInt("randProto","PrototypeData",0,0) ;
1840 pc.defineInt("resampleProto","PrototypeData",1,0) ;
1841 pc.defineInt("verbose","Verbose",0,0) ;
1842 pc.defineInt("extended","Extended",0,0) ;
1843 pc.defineInt("nEvents","NumEvents",0,0) ;
1844 pc.defineInt("autoBinned","AutoBinned",0,1) ;
1845 pc.defineString("binnedTag","GenBinned",0,"") ;
1846 pc.defineMutex("GenBinned","ProtoData") ;
1847
1848
1849 // Process and check varargs
1850 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
1851 if (!pc.ok(kTRUE)) {
1852 return 0 ;
1853 }
1854
1855 // Decode command line arguments
1856 RooDataSet* protoData = static_cast<RooDataSet*>(pc.getObject("proto",0)) ;
1857 const char* dsetName = pc.getString("dsetName") ;
1858 Int_t nEvents = pc.getInt("nEvents") ;
1859 Bool_t verbose = pc.getInt("verbose") ;
1860 Bool_t randProto = pc.getInt("randProto") ;
1861 Bool_t resampleProto = pc.getInt("resampleProto") ;
1862 Bool_t extended = pc.getInt("extended") ;
1863 Bool_t autoBinned = pc.getInt("autoBinned") ;
1864 const char* binnedTag = pc.getString("binnedTag") ;
1865
1866 RooAbsGenContext* cx = autoGenContext(whatVars,protoData,0,verbose,autoBinned,binnedTag) ;
1867
1868 return new GenSpec(cx,whatVars,protoData,nEvents,extended,randProto,resampleProto,dsetName) ;
1869}
1870
1871
1872////////////////////////////////////////////////////////////////////////////////
1873/// If many identical generation requests
1874/// are needed, e.g. in toy MC studies, it is more efficient to use the prepareMultiGen()/generate()
1875/// combination than calling the standard generate() multiple times as
1876/// initialization overhead is only incurred once.
1877
1879{
1880 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen) : spec._nGen ;
1881 //Int_t nEvt = spec._extended ? RooRandom::randomGenerator()->Poisson(spec._nGen==0?expectedEvents(spec._whatVars):spec._nGen) : spec._nGen ;
1882 //Int_t nEvt = spec._nGen == 0 ? RooRandom::randomGenerator()->Poisson(expectedEvents(spec._whatVars)) : spec._nGen;
1883
1884 Double_t nEvt = spec._nGen == 0 ? expectedEvents(spec._whatVars) : spec._nGen;
1885
1886 RooDataSet* ret = generate(*spec._genContext,spec._whatVars,spec._protoData, nEvt,kFALSE,spec._randProto,spec._resampleProto,
1887 spec._init,spec._extended) ;
1888 spec._init = kTRUE ;
1889 return ret ;
1890}
1891
1892
1893
1894
1895
1896////////////////////////////////////////////////////////////////////////////////
1897/// Generate a new dataset containing the specified variables with
1898/// events sampled from our distribution. Generate the specified
1899/// number of events or else try to use expectedEvents() if nEvents <= 0.
1900/// Any variables of this PDF that are not in whatVars will use their
1901/// current values and be treated as fixed parameters. Returns zero
1902/// in case of an error. The caller takes ownership of the returned
1903/// dataset.
1904
1905RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, Double_t nEvents, Bool_t verbose, Bool_t autoBinned, const char* binnedTag, Bool_t expectedData, Bool_t extended) const
1906{
1907 if (nEvents==0 && extendMode()==CanNotBeExtended) {
1908 return new RooDataSet("emptyData","emptyData",whatVars) ;
1909 }
1910
1911 // Request for binned generation
1912 RooAbsGenContext *context = autoGenContext(whatVars,0,0,verbose,autoBinned,binnedTag) ;
1913 if (expectedData) {
1914 context->setExpectedData(kTRUE) ;
1915 }
1916
1917 RooDataSet *generated = 0;
1918 if(0 != context && context->isValid()) {
1919 generated= context->generate(nEvents, kFALSE, extended);
1920 }
1921 else {
1922 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") cannot create a valid context" << endl;
1923 }
1924 if(0 != context) delete context;
1925 return generated;
1926}
1927
1928
1929
1930
1931////////////////////////////////////////////////////////////////////////////////
1932/// Internal method
1933
1934RooDataSet *RooAbsPdf::generate(RooAbsGenContext& context, const RooArgSet &whatVars, const RooDataSet *prototype,
1935 Double_t nEvents, Bool_t /*verbose*/, Bool_t randProtoOrder, Bool_t resampleProto,
1936 Bool_t skipInit, Bool_t extended) const
1937{
1938 if (nEvents==0 && (prototype==0 || prototype->numEntries()==0)) {
1939 return new RooDataSet("emptyData","emptyData",whatVars) ;
1940 }
1941
1942 RooDataSet *generated = 0;
1943
1944 // Resampling implies reshuffling in the implementation
1945 if (resampleProto) {
1946 randProtoOrder=kTRUE ;
1947 }
1948
1949 if (randProtoOrder && prototype && prototype->numEntries()!=nEvents) {
1950 coutI(Generation) << "RooAbsPdf::generate (Re)randomizing event order in prototype dataset (Nevt=" << nEvents << ")" << endl ;
1951 Int_t* newOrder = randomizeProtoOrder(prototype->numEntries(),Int_t(nEvents),resampleProto) ;
1952 context.setProtoDataOrder(newOrder) ;
1953 delete[] newOrder ;
1954 }
1955
1956 if(context.isValid()) {
1957 generated= context.generate(nEvents,skipInit,extended);
1958 }
1959 else {
1960 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") do not have a valid generator context" << endl;
1961 }
1962 return generated;
1963}
1964
1965
1966
1967
1968////////////////////////////////////////////////////////////////////////////////
1969/// Generate a new dataset with values of the whatVars variables
1970/// sampled from our distribution. Use the specified existing dataset
1971/// as a prototype: the new dataset will contain the same number of
1972/// events as the prototype (by default), and any prototype variables not in
1973/// whatVars will be copied into the new dataset for each generated
1974/// event and also used to set our PDF parameters. The user can specify a
1975/// number of events to generate that will override the default. The result is a
1976/// copy of the prototype dataset with only variables in whatVars
1977/// randomized. Variables in whatVars that are not in the prototype
1978/// will be added as new columns to the generated dataset. Returns
1979/// zero in case of an error. The caller takes ownership of the
1980/// returned dataset.
1981
1982RooDataSet *RooAbsPdf::generate(const RooArgSet &whatVars, const RooDataSet& prototype,
1983 Int_t nEvents, Bool_t verbose, Bool_t randProtoOrder, Bool_t resampleProto) const
1984{
1985 RooAbsGenContext *context= genContext(whatVars,&prototype,0,verbose);
1986 if (context) {
1987 RooDataSet* data = generate(*context,whatVars,&prototype,nEvents,verbose,randProtoOrder,resampleProto) ;
1988 delete context ;
1989 return data ;
1990 } else {
1991 coutE(Generation) << "RooAbsPdf::generate(" << GetName() << ") ERROR creating generator context" << endl ;
1992 return 0 ;
1993 }
1994}
1995
1996
1997
1998////////////////////////////////////////////////////////////////////////////////
1999/// Return lookup table with randomized access order for prototype events,
2000/// given nProto prototype data events and nGen events that will actually
2001/// be accessed
2002
2004{
2005 // Make unsorted linked list of indeces
2007 Int_t i ;
2008 for (i=0 ; i<nProto ; i++) {
2009 l.Add(new RooInt(i)) ;
2010 }
2011
2012 // Make output list
2013 Int_t* lut = new Int_t[nProto] ;
2014
2015 // Randomly samply input list into output list
2016 if (!resampleProto) {
2017 // In this mode, randomization is a strict reshuffle of the order
2018 for (i=0 ; i<nProto ; i++) {
2019 Int_t iran = RooRandom::integer(nProto-i) ;
2020 RooInt* sample = (RooInt*) l.At(iran) ;
2021 lut[i] = *sample ;
2022 l.Remove(sample) ;
2023 delete sample ;
2024 }
2025 } else {
2026 // In this mode, we resample, i.e. events can be used more than once
2027 for (i=0 ; i<nProto ; i++) {
2028 lut[i] = RooRandom::integer(nProto);
2029 }
2030 }
2031
2032
2033 return lut ;
2034}
2035
2036
2037
2038////////////////////////////////////////////////////////////////////////////////
2039/// Load generatedVars with the subset of directVars that we can generate events for,
2040/// and return a code that specifies the generator algorithm we will use. A code of
2041/// zero indicates that we cannot generate any of the directVars (in this case, nothing
2042/// should be added to generatedVars). Any non-zero codes will be passed to our generateEvent()
2043/// implementation, but otherwise its value is arbitrary. The default implemetation of
2044/// this method returns zero. Subclasses will usually implement this method using the
2045/// matchArgs() methods to advertise the algorithms they provide.
2046
2047Int_t RooAbsPdf::getGenerator(const RooArgSet &/*directVars*/, RooArgSet &/*generatedVars*/, Bool_t /*staticInitOK*/) const
2048{
2049 return 0 ;
2050}
2051
2052
2053
2054////////////////////////////////////////////////////////////////////////////////
2055/// Interface for one-time initialization to setup the generator for the specified code.
2056
2058{
2059}
2060
2061
2062
2063////////////////////////////////////////////////////////////////////////////////
2064/// Interface for generation of anan event using the algorithm
2065/// corresponding to the specified code. The meaning of each code is
2066/// defined by the getGenerator() implementation. The default
2067/// implementation does nothing.
2068
2070{
2071}
2072
2073
2074
2075////////////////////////////////////////////////////////////////////////////////
2076/// Check if given observable can be safely generated using the
2077/// pdfs internal generator mechanism (if that existsP). Observables
2078/// on which a PDF depends via more than route are not safe
2079/// for use with internal generators because they introduce
2080/// correlations not known to the internal generator
2081
2083{
2084 // Arg must be direct server of self
2085 if (!findServer(arg.GetName())) return kFALSE ;
2086
2087 // There must be no other dependency routes
2088 TIterator* sIter = serverIterator() ;
2089 const RooAbsArg *server = 0;
2090 while((server=(const RooAbsArg*)sIter->Next())) {
2091 if(server == &arg) continue;
2092 if(server->dependsOn(arg)) {
2093 delete sIter ;
2094 return kFALSE ;
2095 }
2096 }
2097 delete sIter ;
2098 return kTRUE ;
2099}
2100
2101
2102////////////////////////////////////////////////////////////////////////////////
2103/// Generate a new dataset containing the specified variables with events sampled from our distribution.
2104/// \param[in] whatVars Choose variables in which to generate events. Variables not listed here will remain
2105/// constant and not be used for event generation
2106/// \param[in] arg1 Optional RooCmdArg to change behaviour of generateBinned()
2107/// \return RooDataHist *, to be managed by caller.
2108///
2109/// Generate the specified number of events or expectedEvents() if not specified.
2110///
2111/// Any variables of this PDF that are not in whatVars will use their
2112/// current values and be treated as fixed parameters. Returns zero
2113/// in case of an error. The caller takes ownership of the returned
2114/// dataset.
2115///
2116/// The following named arguments are supported
2117/// | Type of CmdArg | Effect on generation
2118/// |-------------------------|-----------------------
2119/// | `Name(const char* name)` | Name of the output dataset
2120/// | `Verbose(Bool_t flag)` | Print informational messages during event generation
2121/// | `NumEvent(int nevt)` | Generate specified number of events
2122/// | `Extended()` | The actual number of events generated will be sampled from a Poisson distribution with mu=nevt. For use with extended maximum likelihood fits
2123/// | `ExpectedData()` | Return a binned dataset _without_ statistical fluctuations (also aliased as Asimov())
2124///
2125
2126RooDataHist *RooAbsPdf::generateBinned(const RooArgSet& whatVars, const RooCmdArg& arg1,const RooCmdArg& arg2,
2127 const RooCmdArg& arg3,const RooCmdArg& arg4, const RooCmdArg& arg5,const RooCmdArg& arg6)
2128{
2129
2130 // Select the pdf-specific commands
2131 RooCmdConfig pc(Form("RooAbsPdf::generate(%s)",GetName())) ;
2132 pc.defineString("dsetName","Name",0,"") ;
2133 pc.defineInt("verbose","Verbose",0,0) ;
2134 pc.defineInt("extended","Extended",0,0) ;
2135 pc.defineInt("nEvents","NumEvents",0,0) ;
2136 pc.defineDouble("nEventsD","NumEventsD",0,-1.) ;
2137 pc.defineInt("expectedData","ExpectedData",0,0) ;
2138
2139 // Process and check varargs
2140 pc.process(arg1,arg2,arg3,arg4,arg5,arg6) ;
2141 if (!pc.ok(kTRUE)) {
2142 return 0 ;
2143 }
2144
2145 // Decode command line arguments
2146 Double_t nEvents = pc.getDouble("nEventsD") ;
2147 if (nEvents<0) {
2148 nEvents = pc.getInt("nEvents") ;
2149 }
2150 //Bool_t verbose = pc.getInt("verbose") ;
2151 Bool_t extended = pc.getInt("extended") ;
2152 Bool_t expectedData = pc.getInt("expectedData") ;
2153 const char* dsetName = pc.getString("dsetName") ;
2154
2155 if (extended) {
2156 //nEvents = (nEvents==0?Int_t(expectedEvents(&whatVars)+0.5):nEvents) ;
2157 nEvents = (nEvents==0 ? expectedEvents(&whatVars) :nEvents) ;
2158 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
2159 << GetName() << "::expectedEvents() = " << nEvents << endl ;
2160 // If Poisson fluctuation results in zero events, stop here
2161 if (nEvents==0) {
2162 return 0 ;
2163 }
2164 } else if (nEvents==0) {
2165 cxcoutI(Generation) << "No number of events specified , number of events generated is "
2166 << GetName() << "::expectedEvents() = " << expectedEvents(&whatVars)<< endl ;
2167 }
2168
2169 // Forward to appropriate implementation
2170 RooDataHist* data = generateBinned(whatVars,nEvents,expectedData,extended) ;
2171
2172 // Rename dataset to given name if supplied
2173 if (dsetName && strlen(dsetName)>0) {
2174 data->SetName(dsetName) ;
2175 }
2176
2177 return data ;
2178}
2179
2180
2181
2182
2183////////////////////////////////////////////////////////////////////////////////
2184/// Generate a new dataset containing the specified variables with
2185/// events sampled from our distribution. Generate the specified
2186/// number of events or else try to use expectedEvents() if nEvents <= 0.
2187///
2188/// If expectedData is kTRUE (it is kFALSE by default), the returned histogram returns the 'expected'
2189/// data sample, i.e. no statistical fluctuations are present.
2190///
2191/// Any variables of this PDF that are not in whatVars will use their
2192/// current values and be treated as fixed parameters. Returns zero
2193/// in case of an error. The caller takes ownership of the returned
2194/// dataset.
2195
2196RooDataHist *RooAbsPdf::generateBinned(const RooArgSet &whatVars, Double_t nEvents, Bool_t expectedData, Bool_t extended) const
2197{
2198 // Create empty RooDataHist
2199 RooDataHist* hist = new RooDataHist("genData","genData",whatVars) ;
2200
2201 // Scale to number of events and introduce Poisson fluctuations
2202 if (nEvents<=0) {
2203 if (!canBeExtended()) {
2204 coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName() << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
2205 delete hist ;
2206 return 0 ;
2207 } else {
2208
2209 // Don't round in expectedData or extended mode
2210 if (expectedData || extended) {
2211 nEvents = expectedEvents(&whatVars) ;
2212 } else {
2213 nEvents = Int_t(expectedEvents(&whatVars)+0.5) ;
2214 }
2215 }
2216 }
2217
2218 // Sample p.d.f. distribution
2219 fillDataHist(hist,&whatVars,1,kTRUE) ;
2220
2221 vector<int> histOut(hist->numEntries()) ;
2222 Double_t histMax(-1) ;
2223 Int_t histOutSum(0) ;
2224 for (int i=0 ; i<hist->numEntries() ; i++) {
2225 hist->get(i) ;
2226 if (expectedData) {
2227
2228 // Expected data, multiply p.d.f by nEvents
2229 Double_t w=hist->weight()*nEvents ;
2230 hist->set(w,sqrt(w)) ;
2231
2232 } else if (extended) {
2233
2234 // Extended mode, set contents to Poisson(pdf*nEvents)
2235 Double_t w = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2236 hist->set(w,sqrt(w)) ;
2237
2238 } else {
2239
2240 // Regular mode, fill array of weights with Poisson(pdf*nEvents), but to not fill
2241 // histogram yet.
2242 if (hist->weight()>histMax) {
2243 histMax = hist->weight() ;
2244 }
2245 histOut[i] = RooRandom::randomGenerator()->Poisson(hist->weight()*nEvents) ;
2246 histOutSum += histOut[i] ;
2247 }
2248 }
2249
2250
2251 if (!expectedData && !extended) {
2252
2253 // Second pass for regular mode - Trim/Extend dataset to exact number of entries
2254
2255 // Calculate difference between what is generated so far and what is requested
2256 Int_t nEvtExtra = abs(Int_t(nEvents)-histOutSum) ;
2257 Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
2258
2259 // Perform simple binned accept/reject procedure to get to exact event count
2260 while(nEvtExtra>0) {
2261
2262 Int_t ibinRand = RooRandom::randomGenerator()->Integer(hist->numEntries()) ;
2263 hist->get(ibinRand) ;
2264 Double_t ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
2265
2266 if (ranY<hist->weight()) {
2267 if (wgt==1) {
2268 histOut[ibinRand]++ ;
2269 } else {
2270 // If weight is negative, prior bin content must be at least 1
2271 if (histOut[ibinRand]>0) {
2272 histOut[ibinRand]-- ;
2273 } else {
2274 continue ;
2275 }
2276 }
2277 nEvtExtra-- ;
2278 }
2279 }
2280
2281 // Transfer working array to histogram
2282 for (int i=0 ; i<hist->numEntries() ; i++) {
2283 hist->get(i) ;
2284 hist->set(histOut[i],sqrt(1.0*histOut[i])) ;
2285 }
2286
2287 } else if (expectedData) {
2288
2289 // Second pass for expectedData mode -- Normalize to exact number of requested events
2290 // Minor difference may be present in first round due to difference between
2291 // bin average and bin integral in sampling bins
2292 Double_t corr = nEvents/hist->sumEntries() ;
2293 for (int i=0 ; i<hist->numEntries() ; i++) {
2294 hist->get(i) ;
2295 hist->set(hist->weight()*corr,sqrt(hist->weight()*corr)) ;
2296 }
2297
2298 }
2299
2300 return hist;
2301}
2302
2303
2304
2305////////////////////////////////////////////////////////////////////////////////
2306/// Special generator interface for generation of 'global observables' -- for RooStats tools
2307
2309{
2310 return generate(whatVars,nEvents) ;
2311}
2312
2313
2314
2315////////////////////////////////////////////////////////////////////////////////
2316/// Plot (project) PDF on specified frame. If a PDF is plotted in an empty frame, it
2317/// will show a unit normalized curve in the frame variable, taken at the present value
2318/// of other observables defined for this PDF.
2319///
2320/// If a PDF is plotted in a frame in which a dataset has already been plotted, it will
2321/// show a projected curve integrated over all variables that were present in the shown
2322/// dataset except for the one on the x-axis. The normalization of the curve will also
2323/// be adjusted to the event count of the plotted dataset. An informational message
2324/// will be printed for each projection step that is performed
2325///
2326/// This function takes the following named arguments
2327///
2328///
2329/// <table>
2330/// <tr><th> Type of CmdArg <th> Projection control
2331/// <tr><td> `Slice(const RooArgSet& set)` <td> Override default projection behaviour by omitting
2332/// observables listed in set from the projection, resulting a 'slice' plot. Slicing is usually
2333/// only sensible in discrete observables
2334/// <tr><td> `Project(const RooArgSet& set)` <td> Override default projection behaviour by projecting
2335/// over observables given in set and complete ignoring the default projection behavior. Advanced use only.
2336/// <tr><td> `ProjWData(const RooAbsData& d)` <td> Override default projection _technique_ (integration). For observables
2337/// present in given dataset projection of PDF is achieved by constructing an average over all observable
2338/// values in given set. Consult RooFit plotting tutorial for further explanation of meaning & use of this technique
2339/// <tr><td> `ProjWData(const RooArgSet& s, const RooAbsData& d)` <td> As above but only consider subset 's' of
2340/// observables in dataset 'd' for projection through data averaging
2341/// <tr><td> `ProjectionRange(const char* rn)` <td> Override default range of projection integrals to a different
2342/// range specified by given range name. This technique allows you to project a finite width slice in a real-valued observable
2343/// <tr><td> `NormRange(const char* name)` <td> Calculate curve normalization w.r.t. only in specified ranges.
2344/// \note A Range() by default implies a NormRange() on the same range, but this option allows
2345/// to override the default, or specify a normalization ranges when the full curve is to be drawn
2346///
2347///
2348/// <tr><th><th> Misc content control
2349/// <tr><td> `Normalization(Double_t scale, ScaleType code)` <td> Adjust normalization by given scale factor.
2350/// Interpretation of number depends on code: Relative: relative adjustment factor, NumEvent: scale to match given number of events.
2351/// <tr><td> `Name(const chat* name)` <td> Give curve specified name in frame. Useful if curve is to be referenced later
2352/// <tr><td> `Asymmetry(const RooCategory& c)` <td> Show the asymmetry of the PDF in given two-state category
2353/// \f$ \frac{F(+)-F(-)}{F(+)+F(-)} \f$ rather than the PDF projection. Category must have two
2354/// states with indices -1 and +1 or three states with indeces -1,0 and +1.
2355/// <tr><td> `ShiftToZero(Bool_t flag)` <td> Shift entire curve such that lowest visible point is at exactly zero.
2356/// Mostly useful when plotting -log(L) or \f$ \chi^2 \f$ distributions
2357/// <tr><td> `AddTo(const char* name, double_t wgtSelf, double_t wgtOther)` <td> Add constructed projection to
2358/// already existing curve with given name and relative weight factors
2359///
2360/// <tr><th><th> Plotting control
2361/// <tr><td> `LineStyle(Int_t style)` <td> Select line style by ROOT line style code, default is solid
2362/// <tr><td> `LineColor(Int_t color)` <td> Select line color by ROOT color code, default is blue
2363/// <tr><td> `LineWidth(Int_t width)` <td> Select line with in pixels, default is 3
2364/// <tr><td> `FillStyle(Int_t style)` <td> Select fill style, default is not filled. If a filled style is selected,
2365/// also use VLines() to add vertical downward lines at end of curve to ensure proper closure
2366/// <tr><td> `FillColor(Int_t color)` <td> Select fill color by ROOT color code
2367/// <tr><td> `Range(const char* name)` <td> Only draw curve in range defined by given name
2368/// <tr><td> `Range(double lo, double hi)` <td> Only draw curve in specified range
2369/// <tr><td> `VLines()` <td> Add vertical lines to y=0 at end points of curve
2370/// <tr><td> `Precision(Double_t eps)` <td> Control precision of drawn curve w.r.t to scale of plot, default is 1e-3. Higher precision will
2371/// result in more and more densely spaced curve points A negative precision value will disable
2372/// adaptive point spacing and restrict sampling to the grid point of points defined by the binning
2373/// of the plotted observabled (recommended for expensive functions such as profile likelihoods)
2374/// <tr><td> `Invisible(Bool_t flag)` <td> Add curve to frame, but do not display. Useful in combination AddTo()
2375/// </table>
2376
2378{
2379
2380 // Pre-processing if p.d.f. contains a fit range and there is no command specifying one,
2381 // add a fit range as default range
2382 RooCmdArg* plotRange(0) ;
2383 RooCmdArg* normRange2(0) ;
2384 if (getStringAttribute("fitrange") && !cmdList.FindObject("Range") &&
2385 !cmdList.FindObject("RangeWithName")) {
2386 plotRange = (RooCmdArg*) RooFit::Range(getStringAttribute("fitrange")).Clone() ;
2387 cmdList.Add(plotRange) ;
2388 }
2389
2390 if (getStringAttribute("fitrange") && !cmdList.FindObject("NormRange")) {
2391 normRange2 = (RooCmdArg*) RooFit::NormRange(getStringAttribute("fitrange")).Clone() ;
2392 cmdList.Add(normRange2) ;
2393 }
2394
2395 if (plotRange || normRange2) {
2396 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f was fitted in range and no explicit "
2397 << (plotRange?"plot":"") << ((plotRange&&normRange2)?",":"")
2398 << (normRange2?"norm":"") << " range was specified, using fit range as default" << endl ;
2399 }
2400
2401 // Sanity checks
2402 if (plotSanityChecks(frame)) return frame ;
2403
2404 // Select the pdf-specific commands
2405 RooCmdConfig pc(Form("RooAbsPdf::plotOn(%s)",GetName())) ;
2406 pc.defineDouble("scaleFactor","Normalization",0,1.0) ;
2407 pc.defineInt("scaleType","Normalization",0,Relative) ;
2408 pc.defineObject("compSet","SelectCompSet",0) ;
2409 pc.defineString("compSpec","SelectCompSpec",0) ;
2410 pc.defineObject("asymCat","Asymmetry",0) ;
2411 pc.defineDouble("rangeLo","Range",0,-999.) ;
2412 pc.defineDouble("rangeHi","Range",1,-999.) ;
2413 pc.defineString("rangeName","RangeWithName",0,"") ;
2414 pc.defineString("normRangeName","NormRange",0,"") ;
2415 pc.defineInt("rangeAdjustNorm","Range",0,0) ;
2416 pc.defineInt("rangeWNAdjustNorm","RangeWithName",0,0) ;
2417 pc.defineMutex("SelectCompSet","SelectCompSpec") ;
2418 pc.defineMutex("Range","RangeWithName") ;
2419 pc.allowUndefined() ; // unknowns may be handled by RooAbsReal
2420
2421 // Process and check varargs
2422 pc.process(cmdList) ;
2423 if (!pc.ok(kTRUE)) {
2424 return frame ;
2425 }
2426
2427 // Decode command line arguments
2428 ScaleType stype = (ScaleType) pc.getInt("scaleType") ;
2429 Double_t scaleFactor = pc.getDouble("scaleFactor") ;
2430 const RooAbsCategoryLValue* asymCat = (const RooAbsCategoryLValue*) pc.getObject("asymCat") ;
2431 const char* compSpec = pc.getString("compSpec") ;
2432 const RooArgSet* compSet = (const RooArgSet*) pc.getObject("compSet") ;
2433 Bool_t haveCompSel = ( (compSpec && strlen(compSpec)>0) || compSet) ;
2434
2435 // Suffix for curve name
2436 TString nameSuffix ;
2437 if (compSpec && strlen(compSpec)>0) {
2438 nameSuffix.Append("_Comp[") ;
2439 nameSuffix.Append(compSpec) ;
2440 nameSuffix.Append("]") ;
2441 } else if (compSet) {
2442 nameSuffix.Append("_Comp[") ;
2443 nameSuffix.Append(compSet->contentsString().c_str()) ;
2444 nameSuffix.Append("]") ;
2445 }
2446
2447 // Remove PDF-only commands from command list
2448 pc.stripCmdList(cmdList,"SelectCompSet,SelectCompSpec") ;
2449
2450 // Adjust normalization, if so requested
2451 if (asymCat) {
2452 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
2453 cmdList.Add(&cnsuffix);
2454 return RooAbsReal::plotOn(frame,cmdList) ;
2455 }
2456
2457 // More sanity checks
2458 Double_t nExpected(1) ;
2459 if (stype==RelativeExpected) {
2460 if (!canBeExtended()) {
2461 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2462 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2463 return frame ;
2464 }
2465 nExpected = expectedEvents(frame->getNormVars()) ;
2466 }
2467
2468 if (stype != Raw) {
2469
2470 if (frame->getFitRangeNEvt() && stype==Relative) {
2471
2472 Bool_t hasCustomRange(kFALSE), adjustNorm(kFALSE) ;
2473
2474 list<pair<Double_t,Double_t> > rangeLim ;
2475
2476 // Retrieve plot range to be able to adjust normalization to data
2477 if (pc.hasProcessed("Range")) {
2478
2479 Double_t rangeLo = pc.getDouble("rangeLo") ;
2480 Double_t rangeHi = pc.getDouble("rangeHi") ;
2481 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2482 adjustNorm = pc.getInt("rangeAdjustNorm") ;
2483 hasCustomRange = kTRUE ;
2484
2485 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range ["
2486 << rangeLo << "," << rangeHi << "]" ;
2487 if (!pc.hasProcessed("NormRange")) {
2488 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " given range" << endl ;
2489 } else {
2490 ccoutI(Plotting) << endl ;
2491 }
2492
2493 nameSuffix.Append(Form("_Range[%f_%f]",rangeLo,rangeHi)) ;
2494
2495 } else if (pc.hasProcessed("RangeWithName")) {
2496
2497 char tmp[1024] ;
2498 strlcpy(tmp,pc.getString("rangeName",0,kTRUE),1024) ;
2499 char* rangeNameToken = strtok(tmp,",") ;
2500 while(rangeNameToken) {
2501 Double_t rangeLo = frame->getPlotVar()->getMin(rangeNameToken) ;
2502 Double_t rangeHi = frame->getPlotVar()->getMax(rangeNameToken) ;
2503 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2504 rangeNameToken = strtok(0,",") ;
2505 }
2506 adjustNorm = pc.getInt("rangeWNAdjustNorm") ;
2507 hasCustomRange = kTRUE ;
2508
2509 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") only plotting range '" << pc.getString("rangeName",0,kTRUE) << "'" ;
2510 if (!pc.hasProcessed("NormRange")) {
2511 ccoutI(Plotting) << ", curve is normalized to data in " << (adjustNorm?"given":"full") << " given range" << endl ;
2512 } else {
2513 ccoutI(Plotting) << endl ;
2514 }
2515
2516 nameSuffix.Append(Form("_Range[%s]",pc.getString("rangeName"))) ;
2517 }
2518 // Specification of a normalization range override those in a regular ranage
2519 if (pc.hasProcessed("NormRange")) {
2520 char tmp[1024] ;
2521 strlcpy(tmp,pc.getString("normRangeName",0,kTRUE),1024) ;
2522 char* rangeNameToken = strtok(tmp,",") ;
2523 rangeLim.clear() ;
2524 while(rangeNameToken) {
2525 Double_t rangeLo = frame->getPlotVar()->getMin(rangeNameToken) ;
2526 Double_t rangeHi = frame->getPlotVar()->getMax(rangeNameToken) ;
2527 rangeLim.push_back(make_pair(rangeLo,rangeHi)) ;
2528 rangeNameToken = strtok(0,",") ;
2529 }
2530 adjustNorm = kTRUE ;
2531 hasCustomRange = kTRUE ;
2532 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") p.d.f. curve is normalized using explicit choice of ranges '" << pc.getString("normRangeName",0,kTRUE) << "'" << endl ;
2533
2534 nameSuffix.Append(Form("_NormRange[%s]",pc.getString("rangeName"))) ;
2535
2536 }
2537
2538 if (hasCustomRange && adjustNorm) {
2539
2540 Double_t rangeNevt(0) ;
2541 list<pair<Double_t,Double_t> >::iterator riter = rangeLim.begin() ;
2542 for (;riter!=rangeLim.end() ; ++riter) {
2543 Double_t nevt= frame->getFitRangeNEvt(riter->first,riter->second) ;
2544 rangeNevt += nevt ;
2545 }
2546 scaleFactor *= rangeNevt/nExpected ;
2547
2548 } else {
2549 scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
2550 }
2551 } else if (stype==RelativeExpected) {
2552 scaleFactor *= nExpected ;
2553 } else if (stype==NumEvent) {
2554 scaleFactor /= nExpected ;
2555 }
2556 scaleFactor *= frame->getFitRangeBinW() ;
2557 }
2558 frame->updateNormVars(*frame->getPlotVar()) ;
2559
2560 // Append overriding scale factor command at end of original command list
2561 RooCmdArg tmp = RooFit::Normalization(scaleFactor,Raw) ;
2562 tmp.setInt(1,1) ; // Flag this normalization command as created for internal use (so that VisualizeError can strip it)
2563 cmdList.Add(&tmp) ;
2564
2565 // Was a component selected requested
2566 if (haveCompSel) {
2567
2568 // Get complete set of tree branch nodes
2569 RooArgSet branchNodeSet ;
2570 branchNodeServerList(&branchNodeSet) ;
2571
2572 // Discard any non-RooAbsReal nodes
2573 TIterator* iter = branchNodeSet.createIterator() ;
2574 RooAbsArg* arg ;
2575 while((arg=(RooAbsArg*)iter->Next())) {
2576 if (!dynamic_cast<RooAbsReal*>(arg)) {
2577 branchNodeSet.remove(*arg) ;
2578 }
2579 }
2580 delete iter ;
2581
2582 // Obtain direct selection
2583 RooArgSet* dirSelNodes ;
2584 if (compSet) {
2585 dirSelNodes = (RooArgSet*) branchNodeSet.selectCommon(*compSet) ;
2586 } else {
2587 dirSelNodes = (RooArgSet*) branchNodeSet.selectByName(compSpec) ;
2588 }
2589 if (dirSelNodes->getSize()>0) {
2590 coutI(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") directly selected PDF components: " << *dirSelNodes << endl ;
2591
2592 // Do indirect selection and activate both
2593 plotOnCompSelect(dirSelNodes) ;
2594 } else {
2595 if (compSet) {
2596 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection set " << *compSet << " does not match any components of p.d.f." << endl ;
2597 } else {
2598 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName() << ") ERROR: component selection expression '" << compSpec << "' does not select any components of p.d.f." << endl ;
2599 }
2600 return 0 ;
2601 }
2602
2603 delete dirSelNodes ;
2604 }
2605
2606
2607 RooCmdArg cnsuffix("CurveNameSuffix",0,0,0,0,nameSuffix.Data(),0,0,0) ;
2608 cmdList.Add(&cnsuffix);
2609
2610 RooPlot* ret = RooAbsReal::plotOn(frame,cmdList) ;
2611
2612 // Restore selection status ;
2613 if (haveCompSel) plotOnCompSelect(0) ;
2614
2615 if (plotRange) {
2616 delete plotRange ;
2617 }
2618 if (normRange2) {
2619 delete normRange2 ;
2620 }
2621
2622 return ret ;
2623}
2624
2625
2626
2627
2628//_____________________________________________________________________________
2629// coverity[PASS_BY_VALUE]
2631{
2632 // Plot oneself on 'frame'. In addition to features detailed in RooAbsReal::plotOn(),
2633 // the scale factor for a PDF can be interpreted in three different ways. The interpretation
2634 // is controlled by ScaleType
2635 //
2636 // Relative - Scale factor is applied on top of PDF normalization scale factor
2637 // NumEvent - Scale factor is interpreted as a number of events. The surface area
2638 // under the PDF curve will match that of a histogram containing the specified
2639 // number of event
2640 // Raw - Scale factor is applied to the raw (projected) probability density.
2641 // Not too useful, option provided for completeness.
2642
2643 // Sanity checks
2644 if (plotSanityChecks(frame)) return frame ;
2645
2646 // More sanity checks
2647 Double_t nExpected(1) ;
2648 if (o.stype==RelativeExpected) {
2649 if (!canBeExtended()) {
2650 coutE(Plotting) << "RooAbsPdf::plotOn(" << GetName()
2651 << "): ERROR the 'Expected' scale option can only be used on extendable PDFs" << endl ;
2652 return frame ;
2653 }
2654 nExpected = expectedEvents(frame->getNormVars()) ;
2655 }
2656
2657 // Adjust normalization, if so requested
2658 if (o.stype != Raw) {
2659
2660 if (frame->getFitRangeNEvt() && o.stype==Relative) {
2661 // If non-default plotting range is specified, adjust number of events in fit range
2662 o.scaleFactor *= frame->getFitRangeNEvt()/nExpected ;
2663 } else if (o.stype==RelativeExpected) {
2664 o.scaleFactor *= nExpected ;
2665 } else if (o.stype==NumEvent) {
2666 o.scaleFactor /= nExpected ;
2667 }
2668 o.scaleFactor *= frame->getFitRangeBinW() ;
2669 }
2670 frame->updateNormVars(*frame->getPlotVar()) ;
2671
2672 return RooAbsReal::plotOn(frame,o) ;
2673}
2674
2675
2676
2677
2678////////////////////////////////////////////////////////////////////////////////
2679/// The following named arguments are supported
2680/// <table>
2681/// <tr><th> Type of CmdArg <th> Effect on parameter box
2682/// <tr><td> `Parameters(const RooArgSet& param)` <td> Only the specified subset of parameters will be shown. By default all non-constant parameters are shown.
2683/// <tr><td> `ShowConstants(Bool_t flag)` <td> Also display constant parameters
2684/// <tr><td> `Format(const char* optStr)` <td> \deprecated Classing parameter formatting options, provided for backward compatibility
2685///
2686/// <tr><td> `Format(const char* what,...)` <td> Parameter formatting options.
2687/// | Parameter | Format
2688/// | ---------------------- | --------------------------
2689/// | `const char* what` | Controls what is shown. "N" adds name, "E" adds error, "A" shows asymmetric error, "U" shows unit, "H" hides the value
2690/// | `FixedPrecision(int n)`| Controls precision, set fixed number of digits
2691/// | `AutoPrecision(int n)` | Controls precision. Number of shown digits is calculated from error + n specified additional digits (1 is sensible default)
2692/// <tr><td> `Label(const chat* label)` <td> Add header label to parameter box
2693/// <tr><td> `Layout(Double_t xmin, Double_t xmax, Double_t ymax)` <td> Specify relative position of left/right side of box and top of box.
2694/// Position of bottom of box is calculated automatically from number lines in box
2695/// </table>
2696///
2697///
2698/// Example use:
2699/// ```
2700/// pdf.paramOn(frame, Label("fit result"), Format("NEU",AutoPrecision(1)) ) ;
2701/// ```
2702///
2703
2704RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2,
2705 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
2706 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
2707{
2708 // Stuff all arguments in a list
2709 RooLinkedList cmdList;
2710 cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
2711 cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
2712 cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
2713 cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ; cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
2714
2715 // Select the pdf-specific commands
2716 RooCmdConfig pc(Form("RooAbsPdf::paramOn(%s)",GetName())) ;
2717 pc.defineString("label","Label",0,"") ;
2718 pc.defineDouble("xmin","Layout",0,0.50) ;
2719 pc.defineDouble("xmax","Layout",1,0.99) ;
2720 pc.defineInt("ymaxi","Layout",0,Int_t(0.95*10000)) ;
2721 pc.defineInt("showc","ShowConstants",0,0) ;
2722 pc.defineObject("params","Parameters",0,0) ;
2723 pc.defineString("formatStr","Format",0,"NELU") ;
2724 pc.defineInt("sigDigit","Format",0,2) ;
2725 pc.defineInt("dummy","FormatArgs",0,0) ;
2726 pc.defineMutex("Format","FormatArgs") ;
2727
2728 // Process and check varargs
2729 pc.process(cmdList) ;
2730 if (!pc.ok(kTRUE)) {
2731 return frame ;
2732 }
2733
2734 const char* label = pc.getString("label") ;
2735 Double_t xmin = pc.getDouble("xmin") ;
2736 Double_t xmax = pc.getDouble("xmax") ;
2737 Double_t ymax = pc.getInt("ymaxi") / 10000. ;
2738 Int_t showc = pc.getInt("showc") ;
2739
2740
2741 const char* formatStr = pc.getString("formatStr") ;
2742 Int_t sigDigit = pc.getInt("sigDigit") ;
2743
2744 // Decode command line arguments
2745 RooArgSet* params = static_cast<RooArgSet*>(pc.getObject("params")) ;
2746 if (!params) {
2747 params = getParameters(frame->getNormVars()) ;
2748 if (pc.hasProcessed("FormatArgs")) {
2749 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
2750 paramOn(frame,*params,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
2751 } else {
2752 paramOn(frame,*params,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
2753 }
2754 delete params ;
2755 } else {
2756 RooArgSet* pdfParams = getParameters(frame->getNormVars()) ;
2757 RooArgSet* selParams = static_cast<RooArgSet*>(pdfParams->selectCommon(*params)) ;
2758 if (pc.hasProcessed("FormatArgs")) {
2759 const RooCmdArg* formatCmd = static_cast<RooCmdArg*>(cmdList.FindObject("FormatArgs")) ;
2760 paramOn(frame,*selParams,showc,label,0,0,xmin,xmax,ymax,formatCmd) ;
2761 } else {
2762 paramOn(frame,*selParams,showc,label,sigDigit,formatStr,xmin,xmax,ymax) ;
2763 }
2764 delete selParams ;
2765 delete pdfParams ;
2766 }
2767
2768 return frame ;
2769}
2770
2771
2772
2773
2774////////////////////////////////////////////////////////////////////////////////
2775/// \deprecated Obsolete, provided for backward compatibility. Don't use.
2776
2777RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooAbsData* data, const char *label,
2778 Int_t sigDigits, Option_t *options, Double_t xmin,
2780{
2781 RooArgSet* params = getParameters(data) ;
2782 TString opts(options) ;
2783 paramOn(frame,*params,opts.Contains("c"),label,sigDigits,options,xmin,xmax,ymax) ;
2784 delete params ;
2785 return frame ;
2786}
2787
2788
2789
2790////////////////////////////////////////////////////////////////////////////////
2791/// Add a text box with the current parameter values and their errors to the frame.
2792/// Observables of this PDF appearing in the 'data' dataset will be omitted.
2793///
2794/// Optional label will be inserted as first line of the text box. Use 'sigDigits'
2795/// to modify the default number of significant digits printed. The 'xmin,xmax,ymax'
2796/// values specify the inital relative position of the text box in the plot frame
2797
2798RooPlot* RooAbsPdf::paramOn(RooPlot* frame, const RooArgSet& params, Bool_t showConstants, const char *label,
2799 Int_t sigDigits, Option_t *options, Double_t xmin,
2800 Double_t xmax ,Double_t ymax, const RooCmdArg* formatCmd)
2801{
2802
2803 // parse the options
2804 TString opts = options;
2805 opts.ToLower();
2806 Bool_t showLabel= (label != 0 && strlen(label) > 0);
2807
2808 // calculate the box's size, adjusting for constant parameters
2809 TIterator* pIter = params.createIterator() ;
2810
2811 Double_t ymin(ymax), dy(0.06);
2812 RooRealVar *var = 0;
2813 while((var=(RooRealVar*)pIter->Next())) {
2814 if(showConstants || !var->isConstant()) ymin-= dy;
2815 }
2816
2817 if(showLabel) ymin-= dy;
2818
2819 // create the box and set its options
2820 TPaveText *box= new TPaveText(xmin,ymax,xmax,ymin,"BRNDC");
2821 if(!box) return 0;
2822 box->SetName(Form("%s_paramBox",GetName())) ;
2823 box->SetFillColor(0);
2824 box->SetBorderSize(1);
2825 box->SetTextAlign(12);
2826 box->SetTextSize(0.04F);
2827 box->SetFillStyle(1001);
2828 box->SetFillColor(0);
2829 //char buffer[512];
2830 pIter->Reset() ;
2831 while((var=(RooRealVar*)pIter->Next())) {
2832 if(var->isConstant() && !showConstants) continue;
2833
2834 TString *formatted= options ? var->format(sigDigits, options) : var->format(*formatCmd) ;
2835 box->AddText(formatted->Data());
2836 delete formatted;
2837 }
2838 // add the optional label if specified
2839 if(showLabel) box->AddText(label);
2840
2841 // Add box to frame
2842 frame->addObject(box) ;
2843
2844 delete pIter ;
2845 return frame ;
2846}
2847
2848
2849
2850
2851////////////////////////////////////////////////////////////////////////////////
2852/// Return expected number of events from this p.d.f for use in extended
2853/// likelihood calculations. This default implementation returns zero
2854
2856{
2857 return 0 ;
2858}
2859
2860
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// Change global level of verbosity for p.d.f. evaluations
2864
2866{
2867 _verboseEval = stat ;
2868}
2869
2870
2871
2872////////////////////////////////////////////////////////////////////////////////
2873/// Return global level of verbosity for p.d.f. evaluations
2874
2876{
2877 return _verboseEval ;
2878}
2879
2880
2881
2882////////////////////////////////////////////////////////////////////////////////
2883/// Dummy implementation
2884
2886{
2887}
2888
2889
2890
2891////////////////////////////////////////////////////////////////////////////////
2892/// Destructor of normalization cache element. If this element
2893/// provides the 'current' normalization stored in RooAbsPdf::_norm
2894/// zero _norm pointer here before object pointed to is deleted here
2895
2897{
2898 // Zero _norm pointer in RooAbsPdf if it is points to our cache payload
2899 if (_owner) {
2900 RooAbsPdf* pdfOwner = static_cast<RooAbsPdf*>(_owner) ;
2901 if (pdfOwner->_norm == _norm) {
2902 pdfOwner->_norm = 0 ;
2903 }
2904 }
2905
2906 delete _norm ;
2907}
2908
2909
2910
2911////////////////////////////////////////////////////////////////////////////////
2912/// Return a p.d.f that represent a projection of this p.d.f integrated over given observables
2913
2915{
2916 // Construct name for new object
2917 TString name(GetName()) ;
2918 name.Append("_Proj[") ;
2919 if (iset.getSize()>0) {
2920 TIterator* iter = iset.createIterator() ;
2921 RooAbsArg* arg ;
2922 Bool_t first(kTRUE) ;
2923 while((arg=(RooAbsArg*)iter->Next())) {
2924 if (first) {
2925 first=kFALSE ;
2926 } else {
2927 name.Append(",") ;
2928 }
2929 name.Append(arg->GetName()) ;
2930 }
2931 delete iter ;
2932 }
2933 name.Append("]") ;
2934
2935 // Return projected p.d.f.
2936 return new RooProjectedPdf(name.Data(),name.Data(),*this,iset) ;
2937}
2938
2939
2940
2941////////////////////////////////////////////////////////////////////////////////
2942/// Create a cumulative distribution function of this p.d.f in terms
2943/// of the observables listed in iset. If no nset argument is given
2944/// the c.d.f normalization is constructed over the integrated
2945/// observables, so that its maximum value is precisely 1. It is also
2946/// possible to choose a different normalization for
2947/// multi-dimensional p.d.f.s: eg. for a pdf f(x,y,z) one can
2948/// construct a partial cdf c(x,y) that only when integrated itself
2949/// over z results in a maximum value of 1. To construct such a cdf pass
2950/// z as argument to the optional nset argument
2951
2953{
2954 return createCdf(iset,RooFit::SupNormSet(nset)) ;
2955}
2956
2957
2958
2959////////////////////////////////////////////////////////////////////////////////
2960/// Create an object that represents the integral of the function over one or more observables listed in iset
2961/// The actual integration calculation is only performed when the return object is evaluated. The name
2962/// of the integral object is automatically constructed from the name of the input function, the variables
2963/// it integrates and the range integrates over
2964///
2965/// The following named arguments are accepted
2966/// | Type of CmdArg | Effect on CDF
2967/// | ---------------------|-------------------
2968/// | SupNormSet(const RooArgSet&) | Observables over which should be normalized _in addition_ to the integration observables
2969/// | ScanNumCdf() | Apply scanning technique if cdf integral involves numeric integration [ default ]
2970/// | ScanAllCdf() | Always apply scanning technique
2971/// | ScanNoCdf() | Never apply scanning technique
2972/// | ScanParameters(Int_t nbins, Int_t intOrder) | Parameters for scanning technique of making CDF: number of sampled bins and order of interpolation applied on numeric cdf
2973
2974RooAbsReal* RooAbsPdf::createCdf(const RooArgSet& iset, const RooCmdArg& arg1, const RooCmdArg& arg2,
2975 const RooCmdArg& arg3, const RooCmdArg& arg4, const RooCmdArg& arg5,
2976 const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8)
2977{
2978 // Define configuration for this method
2979 RooCmdConfig pc(Form("RooAbsReal::createCdf(%s)",GetName())) ;
2980 pc.defineObject("supNormSet","SupNormSet",0,0) ;
2981 pc.defineInt("numScanBins","ScanParameters",0,1000) ;
2982 pc.defineInt("intOrder","ScanParameters",1,2) ;
2983 pc.defineInt("doScanNum","ScanNumCdf",0,1) ;
2984 pc.defineInt("doScanAll","ScanAllCdf",0,0) ;
2985 pc.defineInt("doScanNon","ScanNoCdf",0,0) ;
2986 pc.defineMutex("ScanNumCdf","ScanAllCdf","ScanNoCdf") ;
2987
2988 // Process & check varargs
2989 pc.process(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
2990 if (!pc.ok(kTRUE)) {
2991 return 0 ;
2992 }
2993
2994 // Extract values from named arguments
2995 const RooArgSet* snset = static_cast<const RooArgSet*>(pc.getObject("supNormSet",0)) ;
2996 RooArgSet nset ;
2997 if (snset) {
2998 nset.add(*snset) ;
2999 }
3000 Int_t numScanBins = pc.getInt("numScanBins") ;
3001 Int_t intOrder = pc.getInt("intOrder") ;
3002 Int_t doScanNum = pc.getInt("doScanNum") ;
3003 Int_t doScanAll = pc.getInt("doScanAll") ;
3004 Int_t doScanNon = pc.getInt("doScanNon") ;
3005
3006 // If scanning technique is not requested make integral-based cdf and return
3007 if (doScanNon) {
3008 return createIntRI(iset,nset) ;
3009 }
3010 if (doScanAll) {
3011 return createScanCdf(iset,nset,numScanBins,intOrder) ;
3012 }
3013 if (doScanNum) {
3015 Int_t isNum= (tmp->numIntRealVars().getSize()>0) ;
3016 delete tmp ;
3017
3018 if (isNum) {
3019 coutI(NumIntegration) << "RooAbsPdf::createCdf(" << GetName() << ") integration over observable(s) " << iset << " involves numeric integration," << endl
3020 << " constructing cdf though numeric integration of sampled pdf in " << numScanBins << " bins and applying order "
3021 << intOrder << " interpolation on integrated histogram." << endl
3022 << " To override this choice of technique use argument ScanNone(), to change scan parameters use ScanParameters(nbins,order) argument" << endl ;
3023 }
3024
3025 return isNum ? createScanCdf(iset,nset,numScanBins,intOrder) : createIntRI(iset,nset) ;
3026 }
3027 return 0 ;
3028}
3029
3030RooAbsReal* RooAbsPdf::createScanCdf(const RooArgSet& iset, const RooArgSet& nset, Int_t numScanBins, Int_t intOrder)
3031{
3032 string name = string(GetName()) + "_NUMCDF_" + integralNameSuffix(iset,&nset).Data() ;
3033 RooRealVar* ivar = (RooRealVar*) iset.first() ;
3034 ivar->setBins(numScanBins,"numcdf") ;
3035 RooNumCdf* ret = new RooNumCdf(name.c_str(),name.c_str(),*this,*ivar,"numcdf") ;
3036 ret->setInterpolationOrder(intOrder) ;
3037 return ret ;
3038}
3039
3040
3041
3042
3043////////////////////////////////////////////////////////////////////////////////
3044/// This helper function finds and collects all constraints terms of all coponent p.d.f.s
3045/// and returns a RooArgSet with all those terms
3046
3047RooArgSet* RooAbsPdf::getAllConstraints(const RooArgSet& observables, RooArgSet& constrainedParams, Bool_t stripDisconnected) const
3048{
3049 RooArgSet* ret = new RooArgSet("AllConstraints") ;
3050
3051 RooArgSet* comps = getComponents() ;
3052 TIterator* iter = comps->createIterator() ;
3053 RooAbsArg *arg ;
3054 while((arg=(RooAbsArg*)iter->Next())) {
3055 RooAbsPdf* pdf = dynamic_cast<RooAbsPdf*>(arg) ;
3056 if (pdf && !ret->find(pdf->GetName())) {
3057 RooArgSet* compRet = pdf->getConstraints(observables,constrainedParams,stripDisconnected) ;
3058 if (compRet) {
3059 ret->add(*compRet,kFALSE) ;
3060 delete compRet ;
3061 }
3062 }
3063 }
3064 delete iter ;
3065 delete comps ;
3066
3067 return ret ;
3068}
3069
3070
3071////////////////////////////////////////////////////////////////////////////////
3072/// Clear the evaluation error flag
3073
3075{
3076 _evalError = kFALSE ;
3077}
3078
3079
3080
3081////////////////////////////////////////////////////////////////////////////////
3082/// Return the evaluation error flag
3083
3085{
3086 return _evalError ;
3087}
3088
3089
3090
3091////////////////////////////////////////////////////////////////////////////////
3092/// Raise the evaluation error flag
3093
3095{
3096 _evalError = kTRUE ;
3097}
3098
3099
3100
3101////////////////////////////////////////////////////////////////////////////////
3102/// Returns the default numeric MC generator configuration for all RooAbsReals
3103
3105{
3107}
3108
3109
3110////////////////////////////////////////////////////////////////////////////////
3111/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3112/// If this object has no specialized configuration, a null pointer is returned
3113
3115{
3116 return _specGeneratorConfig ;
3117}
3118
3119
3120
3121////////////////////////////////////////////////////////////////////////////////
3122/// Returns the specialized integrator configuration for _this_ RooAbsReal.
3123/// If this object has no specialized configuration, a null pointer is returned,
3124/// unless createOnTheFly is kTRUE in which case a clone of the default integrator
3125/// configuration is created, installed as specialized configuration, and returned
3126
3128{
3129 if (!_specGeneratorConfig && createOnTheFly) {
3131 }
3132 return _specGeneratorConfig ;
3133}
3134
3135
3136
3137////////////////////////////////////////////////////////////////////////////////
3138/// Return the numeric MC generator configuration used for this object. If
3139/// a specialized configuration was associated with this object, that configuration
3140/// is returned, otherwise the default configuration for all RooAbsReals is returned
3141
3143{
3144 const RooNumGenConfig* config = specialGeneratorConfig() ;
3145 if (config) return config ;
3146 return defaultGeneratorConfig() ;
3147}
3148
3149
3150
3151////////////////////////////////////////////////////////////////////////////////
3152/// Set the given configuration as default numeric MC generator
3153/// configuration for this object
3154
3156{
3158 delete _specGeneratorConfig ;
3159 }
3160 _specGeneratorConfig = new RooNumGenConfig(config) ;
3161}
3162
3163
3164
3165////////////////////////////////////////////////////////////////////////////////
3166/// Remove the specialized numeric MC generator configuration associated
3167/// with this object
3168
3170{
3172 delete _specGeneratorConfig ;
3173 }
3175}
3176
3177
3178
3179////////////////////////////////////////////////////////////////////////////////
3180
3182{
3183 delete _genContext ;
3184}
3185
3186
3187////////////////////////////////////////////////////////////////////////////////
3188
3189RooAbsPdf::GenSpec::GenSpec(RooAbsGenContext* context, const RooArgSet& whatVars, RooDataSet* protoData, Int_t nGen,
3190 Bool_t extended, Bool_t randProto, Bool_t resampleProto, TString dsetName, Bool_t init) :
3191 _genContext(context), _whatVars(whatVars), _protoData(protoData), _nGen(nGen), _extended(extended),
3192 _randProto(randProto), _resampleProto(resampleProto), _dsetName(dsetName), _init(init)
3193{
3194}
3195
3196
3197
3198////////////////////////////////////////////////////////////////////////////////
3199
3200void RooAbsPdf::setNormRange(const char* rangeName)
3201{
3202 if (rangeName) {
3203 _normRange = rangeName ;
3204 } else {
3205 _normRange.Clear() ;
3206 }
3207
3208 if (_norm) {
3210 _norm = 0 ;
3211 }
3212}
3213
3214
3215////////////////////////////////////////////////////////////////////////////////
3216
3217void RooAbsPdf::setNormRangeOverride(const char* rangeName)
3218{
3219 if (rangeName) {
3220 _normRangeOverride = rangeName ;
3221 } else {
3222 _normRangeOverride.Clear() ;
3223 }
3224
3225 if (_norm) {
3227 _norm = 0 ;
3228 }
3229}
header file containing the templated implementation of matrix inversion routines for use with ROOT's ...
#define e(i)
Definition: RSha256.hxx:103
static Int_t init()
#define coutI(a)
Definition: RooMsgService.h:31
#define cxcoutI(a)
Definition: RooMsgService.h:83
#define cxcoutD(a)
Definition: RooMsgService.h:79
#define coutW(a)
Definition: RooMsgService.h:33
#define coutE(a)
Definition: RooMsgService.h:34
#define ccoutI(a)
Definition: RooMsgService.h:38
#define ccoutD(a)
Definition: RooMsgService.h:37
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
double Double_t
Definition: RtypesCore.h:55
const Bool_t kTRUE
Definition: RtypesCore.h:87
const char Option_t
Definition: RtypesCore.h:62
#define ClassImp(name)
Definition: Rtypes.h:363
float xmin
Definition: THbookFile.cxx:93
float ymin
Definition: THbookFile.cxx:93
float xmax
Definition: THbookFile.cxx:93
float ymax
Definition: THbookFile.cxx:93
double sqrt(double)
double log(double)
char * Form(const char *fmt,...)
class to compute the Cholesky decomposition of a matrix
RooAbsArg is the common abstract base class for objects that represent a value (of arbitrary type) an...
Definition: RooAbsArg.h:66
RooArgSet * getObservables(const RooArgSet &set, Bool_t valueOnly=kTRUE) const
Definition: RooAbsArg.h:194
void clearValueAndShapeDirty() const
Definition: RooAbsArg.h:444
friend class RooDataSet
Definition: RooAbsArg.h:539
RooWorkspace * _myws
Prevent 'AlwaysDirty' mode for this node.
Definition: RooAbsArg.h:593
Bool_t dependsOn(const RooAbsCollection &serverList, const RooAbsArg *ignoreArg=0, Bool_t valueOnly=kFALSE) const
Test whether we depend on (ie, are served by) any object in the specified collection.
Definition: RooAbsArg.cxx:736
virtual TObject * Clone(const char *newname=0) const
Make a clone of an object using the Streamer facility.
Definition: RooAbsArg.h:75
friend class RooArgSet
Definition: RooAbsArg.h:471
virtual void Print(Option_t *options=0) const
Print TNamed name and title.
Definition: RooAbsArg.h:227
const Text_t * getStringAttribute(const Text_t *key) const
Get string attribute mapped under key 'key'.
Definition: RooAbsArg.cxx:286
RooArgSet * getParameters(const RooAbsData *data, Bool_t stripDisconnected=kTRUE) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
Definition: RooAbsArg.cxx:533
Bool_t isValueDirty() const
Definition: RooAbsArg.h:336
RooArgSet * getVariables(Bool_t stripDisconnected=kTRUE) const
Return RooArgSet with all variables (tree leaf nodes of expresssion tree)
Definition: RooAbsArg.cxx:2074
virtual void constOptimizeTestStatistic(ConstOpCode opcode, Bool_t doAlsoTrackingOpt=kTRUE)
Interface function signaling a request to perform constant term optimization.
Definition: RooAbsArg.cxx:1731
void setOperMode(OperMode mode, Bool_t recurseADirty=kTRUE)
Change cache operation mode to given mode.
Definition: RooAbsArg.cxx:1746
Bool_t addOwnedComponents(const RooArgSet &comps)
Take ownership of the contents of 'comps'.
Definition: RooAbsArg.cxx:2274
Bool_t getAttribute(const Text_t *name) const
Check if a named attribute is set. By default, all attributes are unset.
Definition: RooAbsArg.cxx:264
void setProxyNormSet(const RooArgSet *nset)
Forward a change in the cached normalization argset to all the registered proxies.
Definition: RooAbsArg.cxx:1270
friend class RooProjectedPdf
Definition: RooAbsArg.h:427
RooArgSet * getComponents() const
Definition: RooAbsArg.cxx:680
Bool_t isConstant() const
Definition: RooAbsArg.h:266
void branchNodeServerList(RooAbsCollection *list, const RooAbsArg *arg=0, Bool_t recurseNonDerived=kFALSE) const
Fill supplied list with all branch nodes of the arg tree starting with ourself as top node.
Definition: RooAbsArg.cxx:477
TIterator * serverIterator() const
Definition: RooAbsArg.h:112
RooAbsArg * findServer(const char *name) const
Definition: RooAbsArg.h:122
OperMode operMode() const
Definition: RooAbsArg.h:399
void setInterpolationOrder(Int_t order)
Set interpolation order of RooHistFunct representing cache histogram.
RooAbsCategoryLValue is the common abstract base class for objects that represent a discrete value th...
RooAbsCollection * selectCommon(const RooAbsCollection &refColl) const
Create a subset of the current collection, consisting only of those elements that are contained as we...
Int_t getSize() const
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
RooAbsArg * first() const
RooAbsCollection * selectByName(const char *nameList, Bool_t verbose=kFALSE) const
Create a subset of the current collection, consisting only of those elements with names matching the ...
virtual void Print(Option_t *options=0) const
This method must be overridden when a class wants to print itself.
RooAbsCollection * selectByAttrib(const char *name, Bool_t value) const
Create a subset of the current collection, consisting only of those elements with the specified attri...
std::string contentsString() const
Return comma separated list of contained object names as STL string.
virtual Bool_t remove(const RooAbsArg &var, Bool_t silent=kFALSE, Bool_t matchByNameOnly=kFALSE)
Remove the specified argument from our list.
TIterator * createIterator(Bool_t dir=kIterForward) const
RooAbsArg * find(const char *name) const
Find object with given name in list.
RooAbsData is the common abstract base class for binned and unbinned datasets.
Definition: RooAbsData.h:37
virtual Int_t numEntries() const
Definition: RooAbsData.cxx:285
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
Bool_t isValid() const
virtual RooDataSet * generate(Double_t nEvents=0, Bool_t skipInit=kFALSE, Bool_t extendedMode=kFALSE)
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
virtual void setExpectedData(Bool_t)
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Normalization set with for above integral.
Definition: RooAbsPdf.h:318
virtual ~CacheElem()
Destructor of normalization cache element.
Definition: RooAbsPdf.cxx:2896
void operModeHook(RooAbsArg::OperMode)
Dummy implementation.
Definition: RooAbsPdf.cxx:2885
RooAbsReal * _norm
Definition: RooAbsPdf.h:324
RooArgSet _whatVars
Definition: RooAbsPdf.h:82
RooAbsGenContext * _genContext
Definition: RooAbsPdf.h:81
Bool_t _resampleProto
Definition: RooAbsPdf.h:87
RooDataSet * _protoData
Definition: RooAbsPdf.h:83
RooAbsPdf is the abstract interface for all probability density functions The class provides hybrid a...
Definition: RooAbsPdf.h:41
GenSpec * prepareMultiGen(const RooArgSet &whatVars, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none())
Prepare GenSpec configuration object for efficient generation of multiple datasets from identical spe...
Definition: RooAbsPdf.cxx:1829
RooObjCacheManager _normMgr
Definition: RooAbsPdf.h:326
Double_t getNorm(const RooArgSet &nset) const
Definition: RooAbsPdf.h:204
static Bool_t evalError()
Return the evaluation error flag.
Definition: RooAbsPdf.cxx:3084
friend class CacheElem
Definition: RooAbsPdf.h:328
virtual void generateEvent(Int_t code)
Interface for generation of anan event using the algorithm corresponding to the specified code.
Definition: RooAbsPdf.cxx:2069
virtual ~RooAbsPdf()
Destructor.
Definition: RooAbsPdf.cxx:235
void setGeneratorConfig()
Remove the specialized numeric MC generator configuration associated with this object.
Definition: RooAbsPdf.cxx:3169
virtual void resetErrorCounters(Int_t resetValue=10)
Reset error counter to given value, limiting the number of future error messages for this pdf to 'res...
Definition: RooAbsPdf.cxx:569
virtual RooAbsReal * createChi2(RooDataHist &data, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none())
Create a from a histogram and this function.
Definition: RooAbsPdf.cxx:1515
virtual RooFitResult * chi2FitTo(RooDataHist &data, const RooLinkedList &cmdList)
Calls RooAbsPdf::createChi2(RooDataSet& data, const RooLinkedList& cmdList) and returns fit result.
Definition: RooAbsPdf.cxx:1475
static int verboseEval()
Return global level of verbosity for p.d.f. evaluations.
Definition: RooAbsPdf.cxx:2875
Bool_t traceEvalPdf(Double_t value) const
Check that passed value is positive and not 'not-a-number'.
Definition: RooAbsPdf.cxx:342
virtual RooAbsReal * createNLL(RooAbsData &data, const RooLinkedList &cmdList)
Construct representation of -log(L) of PDFwith given dataset.
Definition: RooAbsPdf.cxx:781
virtual RooAbsGenContext * genContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE) const
Interface function to create a generator context from a p.d.f.
Definition: RooAbsPdf.cxx:1666
RooAbsReal * createScanCdf(const RooArgSet &iset, const RooArgSet &nset, Int_t numScanBins, Int_t intOrder)
Definition: RooAbsPdf.cxx:3030
TString _normRange
MC generator configuration specific for this object.
Definition: RooAbsPdf.h:353
void setNormRange(const char *rangeName)
Definition: RooAbsPdf.cxx:3200
virtual Int_t getGenerator(const RooArgSet &directVars, RooArgSet &generateVars, Bool_t staticInitOK=kTRUE) const
Load generatedVars with the subset of directVars that we can generate events for, and return a code t...
Definition: RooAbsPdf.cxx:2047
RooNumGenConfig * specialGeneratorConfig() const
Returns the specialized integrator configuration for this RooAbsReal.
Definition: RooAbsPdf.cxx:3114
Bool_t canBeExtended() const
Definition: RooAbsPdf.h:230
virtual Bool_t selfNormalized() const
Definition: RooAbsPdf.h:216
virtual Bool_t traceEvalHook(Double_t value) const
WVE 08/21/01 Probably obsolete now.
Definition: RooAbsPdf.cxx:535
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Print multi line detailed information of this RooAbsPdf.
Definition: RooAbsPdf.cxx:1639
Double_t analyticalIntegralWN(Int_t code, const RooArgSet *normSet, const char *rangeName=0) const
Analytical integral with normalization (see RooAbsReal::analyticalIntegralWN() for further informatio...
Definition: RooAbsPdf.cxx:322
RooDataSet * generate(const RooArgSet &whatVars, Int_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none())
See RooAbsPdf::generate(const RooArgSet&,const RooCmdArg&,const RooCmdArg&,const RooCmdArg&,...
Definition: RooAbsPdf.h:56
virtual RooAbsGenContext * autoGenContext(const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t verbose=kFALSE, Bool_t autoBinned=kTRUE, const char *binnedTag="") const
Definition: RooAbsPdf.cxx:1675
Int_t _traceCount
Definition: RooAbsPdf.h:342
RooAbsReal * _norm
Definition: RooAbsPdf.h:315
virtual Double_t extendedTerm(Double_t observedEvents, const RooArgSet *nset=0) const
Returned the extended likelihood term (Nexpect - Nobserved*log(NExpected) of this PDF for the given n...
Definition: RooAbsPdf.cxx:647
virtual void printValue(std::ostream &os) const
Print value of p.d.f, also print normalization integral that was last used, if any.
Definition: RooAbsPdf.cxx:1623
virtual RooArgSet * getAllConstraints(const RooArgSet &observables, RooArgSet &constrainedParams, Bool_t stripDisconnected=kTRUE) const
This helper function finds and collects all constraints terms of all coponent p.d....
Definition: RooAbsPdf.cxx:3047
virtual RooFitResult * fitTo(RooAbsData &data, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none())
Fit PDF to given dataset.
Definition: RooAbsPdf.cxx:1081
static void raiseEvalError()
Raise the evaluation error flag.
Definition: RooAbsPdf.cxx:3094
virtual Bool_t syncNormalization(const RooArgSet *dset, Bool_t adjustProxies=kTRUE) const
Verify that the normalization integral cached with this PDF is valid for given set of normalization o...
Definition: RooAbsPdf.cxx:436
virtual Double_t getValV(const RooArgSet *set=0) const
Return current value, normalized by integrating over the observables in 'nset'.
Definition: RooAbsPdf.cxx:253
Int_t _errorCount
Definition: RooAbsPdf.h:338
Bool_t _selectComp
Definition: RooAbsPdf.h:345
virtual RooArgSet * getConstraints(const RooArgSet &, RooArgSet &, Bool_t) const
Definition: RooAbsPdf.h:182
@ CanBeExtended
Definition: RooAbsPdf.h:223
@ MustBeExtended
Definition: RooAbsPdf.h:223
@ CanNotBeExtended
Definition: RooAbsPdf.h:223
virtual RooDataHist * generateBinned(const RooArgSet &whatVars, Double_t nEvents, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none())
As RooAbsPdf::generateBinned(const RooArgSet&, const RooCmdArg&,const RooCmdArg&, const RooCmdArg&,...
Definition: RooAbsPdf.h:105
virtual RooPlot * paramOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none())
Add a box with parameter values (and errors) to the specified frame.
Definition: RooAbsPdf.cxx:2704
void setTraceCounter(Int_t value, Bool_t allNodes=kFALSE)
Reset trace counter to given value, limiting the number of future trace messages for this pdf to 'val...
Definition: RooAbsPdf.cxx:581
RooAbsReal * createCdf(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Create a cumulative distribution function of this p.d.f in terms of the observables listed in iset.
Definition: RooAbsPdf.cxx:2952
virtual const RooAbsReal * getNormObj(const RooArgSet *set, const RooArgSet *iset, const TNamed *rangeName=0) const
Return pointer to RooAbsReal object that implements calculation of integral over observables iset in ...
Definition: RooAbsPdf.cxx:401
virtual Double_t getLogVal(const RooArgSet *set=0) const
Return the log of the current value with given normalization An error message is printed if the argum...
Definition: RooAbsPdf.cxx:607
Int_t * randomizeProtoOrder(Int_t nProto, Int_t nGen, Bool_t resample=kFALSE) const
Return lookup table with randomized access order for prototype events, given nProto prototype data ev...
Definition: RooAbsPdf.cxx:2003
static Bool_t _evalError
Definition: RooAbsPdf.h:349
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events from this p.d.f for use in extended likelihood calculations.
Definition: RooAbsPdf.cxx:2855
Int_t _negCount
Definition: RooAbsPdf.h:343
void setNormRangeOverride(const char *rangeName)
Definition: RooAbsPdf.cxx:3217
virtual RooDataSet * generateSimGlobal(const RooArgSet &whatVars, Int_t nEvents)
Special generator interface for generation of 'global observables' – for RooStats tools.
Definition: RooAbsPdf.cxx:2308
virtual Bool_t isDirectGenSafe(const RooAbsArg &arg) const
Check if given observable can be safely generated using the pdfs internal generator mechanism (if tha...
Definition: RooAbsPdf.cxx:2082
const RooNumGenConfig * getGeneratorConfig() const
Return the numeric MC generator configuration used for this object.
Definition: RooAbsPdf.cxx:3142
virtual void initGenerator(Int_t code)
Interface for one-time initialization to setup the generator for the specified code.
Definition: RooAbsPdf.cxx:2057
virtual ExtendMode extendMode() const
Definition: RooAbsPdf.h:224
RooAbsPdf()
Default constructor.
Definition: RooAbsPdf.cxx:177
virtual RooAbsGenContext * binnedGenContext(const RooArgSet &vars, Bool_t verbose=kFALSE) const
Return a binned generator context.
Definition: RooAbsPdf.cxx:1656
static RooNumGenConfig * defaultGeneratorConfig()
Returns the default numeric MC generator configuration for all RooAbsReals.
Definition: RooAbsPdf.cxx:3104
RooNumGenConfig * _specGeneratorConfig
Definition: RooAbsPdf.h:351
RooArgSet * _normSet
Normalization integral (owned by _normMgr)
Definition: RooAbsPdf.h:316
Double_t _rawValue
Definition: RooAbsPdf.h:314
static TString _normRangeOverride
Definition: RooAbsPdf.h:354
static Int_t _verboseEval
Definition: RooAbsPdf.h:309
static void clearEvalError()
Clear the evaluation error flag.
Definition: RooAbsPdf.cxx:3074
virtual RooAbsPdf * createProjection(const RooArgSet &iset)
Return a p.d.f that represent a projection of this p.d.f integrated over given observables.
Definition: RooAbsPdf.cxx:2914
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg::none(), const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none(), const RooCmdArg &arg9=RooCmdArg::none(), const RooCmdArg &arg10=RooCmdArg::none()) const
Helper calling plotOn(RooPlot*, RooLinkedList&) const.
Definition: RooAbsPdf.h:119
virtual Double_t getMax(const char *name=0) const
virtual Double_t getMin(const char *name=0) const
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition: RooAbsReal.h:53
void plotOnCompSelect(RooArgSet *selNodes) const
Helper function for plotting of composite p.d.fs.
@ RelativeExpected
Definition: RooAbsReal.h:218
virtual RooPlot * plotOn(RooPlot *frame, const RooCmdArg &arg1=RooCmdArg(), const RooCmdArg &arg2=RooCmdArg(), const RooCmdArg &arg3=RooCmdArg(), const RooCmdArg &arg4=RooCmdArg(), const RooCmdArg &arg5=RooCmdArg(), const RooCmdArg &arg6=RooCmdArg(), const RooCmdArg &arg7=RooCmdArg(), const RooCmdArg &arg8=RooCmdArg(), const RooCmdArg &arg9=RooCmdArg(), const RooCmdArg &arg10=RooCmdArg()) const
Plot (project) PDF on specified frame.
virtual Double_t evaluate() const =0
Evaluate this PDF / function / constant. Needs to be overridden by all derived classes.
TString integralNameSuffix(const RooArgSet &iset, const RooArgSet *nset=0, const char *rangeName=0, Bool_t omitEmpty=kFALSE) const
Construct string with unique suffix name to give to integral object that encodes integrated observabl...
Definition: RooAbsReal.cxx:756
RooAbsReal * createIntRI(const RooArgSet &iset, const RooArgSet &nset=RooArgSet())
Utility function for createRunningIntegral that construct an object implementing the standard (analyt...
RooFitResult * chi2FitDriver(RooAbsReal &fcn, RooLinkedList &cmdList)
Internal driver function for chi2 fits.
Double_t _value
Definition: RooAbsReal.h:391
virtual void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const
Structure printing.
Definition: RooAbsReal.cxx:423
virtual void enableOffsetting(Bool_t)
Definition: RooAbsReal.h:308
Double_t getVal(const RooArgSet *set=0) const
Evaluate object. Returns either cached value or triggers a recalculation.
Definition: RooAbsReal.h:64
RooAbsReal * createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2=RooCmdArg::none(), const RooCmdArg &arg3=RooCmdArg::none(), const RooCmdArg &arg4=RooCmdArg::none(), const RooCmdArg &arg5=RooCmdArg::none(), const RooCmdArg &arg6=RooCmdArg::none(), const RooCmdArg &arg7=RooCmdArg::none(), const RooCmdArg &arg8=RooCmdArg::none()) const
Create an object that represents the integral of the function over one or more observables listed in ...
Definition: RooAbsReal.cxx:502
Bool_t plotSanityChecks(RooPlot *frame) const
Utility function for plotOn(), perform general sanity check on frame to ensure safe plotting operatio...
static void setEvalErrorLoggingMode(ErrorLoggingMode m)
Set evaluation error logging mode.
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Implements the actual analytical integral(s) advertised by getAnalyticalIntegral.
Definition: RooAbsReal.cxx:362
const RooNumIntConfig * getIntegratorConfig() const
Return the numeric integration configuration used for this object.
virtual Bool_t isBinnedDistribution(const RooArgSet &) const
Definition: RooAbsReal.h:278
void logEvalError(const char *message, const char *serverValueString=0) const
Log evaluation error message.
RooDataHist * fillDataHist(RooDataHist *hist, const RooArgSet *nset, Double_t scaleFactor, Bool_t correctForBinVolume=kFALSE, Bool_t showProgress=kFALSE) const
Fill a RooDataHist with values sampled from this function at the bin centers.
RooAddition calculates the sum of a set of RooAbsReal terms, or when constructed with two sets,...
Definition: RooAddition.h:26
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
virtual Bool_t add(const RooAbsCollection &col, Bool_t silent=kFALSE)
Add a collection of arguments to this collection by calling add() for each element in the source coll...
Definition: RooArgSet.h:88
RooBinnedGenContext is an efficient implementation of the generator context specific for binned pdfs.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
RooCachedReal is an implementation of RooAbsCachedReal that can cache any external RooAbsReal input f...
Definition: RooCachedReal.h:20
void setCacheSource(Bool_t flag)
Definition: RooCachedReal.h:44
RooCmdArg is a named container for two doubles, two integers two object points and three string point...
Definition: RooCmdArg.h:27
void setInt(Int_t idx, Int_t value)
Definition: RooCmdArg.h:66
Class RooCmdConfig is a configurable parser for RooCmdArg named arguments.
Definition: RooCmdConfig.h:27
RooConstraintSum calculates the sum of the -(log) likelihoods of a set of RooAbsPfs that represent co...
RooDataSet is a container class to hold N-dimensional binned data.
Definition: RooDataHist.h:40
virtual Double_t weight() const
Definition: RooDataHist.h:96
void set(Double_t weight, Double_t wgtErr=-1)
Increment the weight of the bin enclosing the coordinates given by 'row' by the specified amount.
virtual Double_t sumEntries() const
virtual Int_t numEntries() const
Return the number of bins.
virtual const RooArgSet * get() const
Definition: RooDataHist.h:77
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
const TMatrixDSym & covarianceMatrix() const
Return covariance matrix.
Class RooGenContext implement a universal generator context for all RooAbsPdf classes that do not hav...
Definition: RooGenContext.h:30
RooInt is a minimal implementation of a TObject holding a Int_t value.
Definition: RooInt.h:22
RooLinkedList is an collection class for internal use, storing a collection of RooAbsArg pointers in ...
Definition: RooLinkedList.h:35
TObject * FindObject(const char *name) const
Return pointer to obejct with given name.
virtual void Add(TObject *arg)
Definition: RooLinkedList.h:62
RooMinimizer is a wrapper class around ROOT::Fit:Fitter that provides a seamless interface between th...
Definition: RooMinimizer.h:38
RooMinuit is a wrapper class around TFitter/TMinuit that provides a seamless interface between the MI...
Definition: RooMinuit.h:39
Class RooNLLVar implements a a -log(likelihood) calculation from a dataset and a PDF.
Definition: RooNLLVar.h:26
static const char * str(const TNamed *ptr)
Return C++ string corresponding to given TNamed pointer.
Definition: RooNameReg.cxx:135
RooNameSet is a utility class that stores the names the objects in a RooArget.
Definition: RooNameSet.h:24
RooArgSet * select(const RooArgSet &list) const
Construct a RooArgSet of objects in input 'list' whose names match to those in the internal name list...
Definition: RooNameSet.cxx:187
void setNameList(const char *givenList)
Definition: RooNameSet.cxx:144
const char * content() const
Definition: RooNameSet.h:50
Class RooNumCdf is an implementation of RooNumRunningInt specialized to calculate cumulative distribu...
Definition: RooNumCdf.h:17
RooNumGenConfig holds the configuration parameters of the various numeric integrators used by RooReal...
static RooNumGenConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
A RooPlot is a plot frame and a container for graphics objects within that frame.
Definition: RooPlot.h:41
void addObject(TObject *obj, Option_t *drawOptions="", Bool_t invisible=kFALSE)
Add a generic object to this plot.
Definition: RooPlot.cxx:391
Double_t getFitRangeNEvt() const
Return the number of events in the fit range.
Definition: RooPlot.h:134
Double_t getFitRangeBinW() const
Return the bin width that is being used to normalise the PDF.
Definition: RooPlot.h:137
const RooArgSet * getNormVars() const
Definition: RooPlot.h:141
RooAbsRealLValue * getPlotVar() const
Definition: RooPlot.h:132
void updateNormVars(const RooArgSet &vars)
Install the given set of observables are reference normalization variables for this frame.
Definition: RooPlot.cxx:349
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
static UInt_t integer(UInt_t max, TRandom *generator=randomGenerator())
Return an integer uniformly distributed from [0,n-1].
Definition: RooRandom.cxx:102
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:54
RooRealIntegral performs hybrid numerical/analytical integrals of RooAbsReal objects.
const RooArgSet & numIntRealVars() const
RooRealVar represents a fundamental (non-derived) real valued object.
Definition: RooRealVar.h:36
void setBins(Int_t nBins, const char *name=0)
Definition: RooRealVar.h:77
void setRange(const char *name, Double_t min, Double_t max)
Set range named 'name to [min,max].
Definition: RooRealVar.cxx:448
TString * format(const RooCmdArg &formatArg) const
Format contents of RooRealVar for pretty printing on RooPlot parameter boxes.
Definition: RooRealVar.cxx:779
Bool_t defineSetInternal(const char *name, const RooArgSet &aset)
const RooArgSet * set(const char *name)
Return pointer to previously defined named set with given nmame If no such set is found a null pointe...
Iterator abstract base class.
Definition: TIterator.h:30
virtual void Reset()=0
virtual TObject * Next()=0
Int_t GetNrows() const
Definition: TMatrixTBase.h:124
TMatrixTSym< Element > & Similarity(const TMatrixT< Element > &n)
Calculate B * (*this) * B^T , final matrix will be (nrowsb x nrowsb) This is a similarity transform w...
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
TString fName
Definition: TNamed.h:32
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:383
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:627
virtual UInt_t Integer(UInt_t imax)
Returns a random integer on [ 0, imax-1 ].
Definition: TRandom.cxx:341
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition: fillpatterns.C:1
VecExpr< UnaryOp< Fabs< T >, VecExpr< A, T, D >, T >, T, D > fabs(const VecExpr< A, T, D > &rhs)
RooCmdArg NormRange(const char *rangeNameList)
@ Minimization
Definition: RooGlobalFunc.h:57
@ Generation
Definition: RooGlobalFunc.h:57
@ NumIntegration
Definition: RooGlobalFunc.h:59
@ InputArguments
Definition: RooGlobalFunc.h:58
RooCmdArg SupNormSet(const RooArgSet &nset)
RooCmdArg Range(const char *rangeName, Bool_t adjustNorm=kTRUE)
RooCmdArg Normalization(Double_t scaleFactor)
static constexpr double pc
Bool_t IsNaN(Double_t x)
Definition: TMath.h:880
Definition: first.py:1
STL namespace.
Double_t scaleFactor
Definition: RooAbsReal.h:422
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4