Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooProduct.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 * GR, Gerhard Raven, VU Amsterdan, graven@nikhef.nl *
8 * *
9 * Copyright (c) 2000-2007, 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\file RooProduct.cxx
19\class RooProduct
20\ingroup Roofitcore
21
22Represents the product of a given set of RooAbsReal objects.
23**/
24
25#include "RooConstVar.h"
26#include "RooProduct.h"
27
28#include "RooNameReg.h"
29#include "RooAbsReal.h"
30#include "RooAbsCategory.h"
31#include "RooMsgService.h"
32#include "RooTrace.h"
33
34#include <cmath>
35#include <memory>
36
38
39class RooProduct::ProdMap : public std::vector<std::pair<RooArgSet*,RooArgList*> > {} ;
40
41// Namespace with helper functions that have STL stuff that we don't want to expose to CINT
42namespace {
43 typedef RooProduct::ProdMap::iterator RPPMIter ;
44 std::pair<RPPMIter,RPPMIter> findOverlap2nd(RPPMIter i, RPPMIter end) ;
45 void dump_map(std::ostream& os, RPPMIter i, RPPMIter end) ;
46}
47
48
49////////////////////////////////////////////////////////////////////////////////
50/// Default constructor
51
52RooProduct::RooProduct() : _cacheMgr(this,10)
53{
55}
56
57
58////////////////////////////////////////////////////////////////////////////////
59/// Destructor
60
62{
64}
65
66
67
68////////////////////////////////////////////////////////////////////////////////
69/// Construct function representing the product of functions in prodSet
70
71RooProduct::RooProduct(const char* name, const char* title, const RooArgList& prodSet) :
72 RooAbsReal(name, title),
73 _compRSet("!compRSet","Set of real product components",this),
74 _compCSet("!compCSet","Set of category product components",this),
75 _cacheMgr(this,10)
76{
77 for (auto comp : prodSet) {
78 addTerm(comp);
79 }
81}
82
83
84RooProduct::RooProduct(const char *name, const char *title, RooAbsReal& real1, RooAbsReal& real2) :
85 RooProduct{name, title, {real1, real2}} {}
86
87
88////////////////////////////////////////////////////////////////////////////////
89/// Copy constructor
90
91RooProduct::RooProduct(const RooProduct& other, const char* name) :
92 RooAbsReal(other, name),
93 _compRSet("!compRSet",this,other._compRSet),
94 _compCSet("!compCSet",this,other._compCSet),
95 _cacheMgr(other._cacheMgr,this)
96{
98}
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Add a term to this product.
104 if (dynamic_cast<RooAbsReal*>(term)) {
105 _compRSet.add(*term) ;
106 } else if (dynamic_cast<RooAbsCategory*>(term)) {
107 _compCSet.add(*term) ;
108 } else {
109 coutE(InputArguments) << "RooProduct::addTerm(" << GetName() << ") ERROR: component " << term->GetName()
110 << " is not of type RooAbsReal or RooAbsCategory" << std::endl ;
111 throw std::invalid_argument("RooProduct can only handle terms deriving from RooAbsReal or RooAbsCategory.");
112 }
113}
114
115////////////////////////////////////////////////////////////////////////////////
116/// Force internal handling of integration of given observable if any
117/// of the product terms depend on it.
118
120{
121 // Force internal handling of integration of given observable if any
122 // of the product terms depend on it.
123
124 bool depends(false);
125 for (auto const* rcomp : static_range_cast<RooAbsReal*>(_compRSet)) {
126 if (depends) break;
127 depends = rcomp->dependsOn(dep);
128 }
129 return depends ;
130}
131
132
133
134////////////////////////////////////////////////////////////////////////////////
135/// Group observables into subsets in which the product factorizes
136/// and that can thus be integrated separately
137
139{
140 ProdMap* map = new ProdMap ;
141
142 // Do we have any terms which do not depend on the
143 // on the variables we integrate over?
144 RooArgList *indep = new RooArgList();
145 for (auto const* rcomp : static_range_cast<RooAbsReal*>(_compRSet)) {
146 if( !rcomp->dependsOn(allVars) ) indep->add(*rcomp);
147 }
148 if (!indep->empty()) {
149 map->push_back( std::make_pair(new RooArgSet(),indep) );
150 } else {
151 delete indep;
152 }
153
154 // Map observables -> functions ; start with individual observables
155 for (auto const* var : static_range_cast<RooAbsReal*>(allVars)) {
156 RooArgSet *vars = new RooArgSet(); vars->add(*var);
157 RooArgList *comps = new RooArgList();
158
159 for (auto const* rcomp2 : static_range_cast<RooAbsReal*>(_compRSet)) {
160 if( rcomp2->dependsOn(*var) ) comps->add(*rcomp2);
161 }
162 map->push_back( std::make_pair(vars,comps) );
163 }
164
165 // Merge groups with overlapping dependents
166 bool overlap;
167 do {
168 std::pair<ProdMap::iterator,ProdMap::iterator> i = findOverlap2nd(map->begin(),map->end());
169 overlap = (i.first!=i.second);
170 if (overlap) {
171 i.first->first->add(*i.second->first);
172
173 // In the merging step, make sure not to duplicate
174 for (auto const* targ : *(i.second->second)) {
175 if (!i.first->second->find(*targ)) {
176 i.first->second->add(*targ) ;
177 }
178 }
179 //i.first->second->add(*i.second->second);
180
181 delete i.second->first;
182 delete i.second->second;
183 map->erase(i.second);
184 }
185 } while (overlap);
186
187#ifndef NDEBUG
188 // check that we have all variables to be integrated over on the LHS
189 // of the map, and all terms in the product do appear on the RHS
190 std::size_t nVar=0;
191 std::size_t nFunc=0;
192 for (ProdMap::iterator i = map->begin();i!=map->end();++i) {
193 nVar+=i->first->size();
194 nFunc+=i->second->size();
195 }
196 assert(nVar==allVars.size());
197 assert(nFunc==_compRSet.size());
198#endif
199 return map;
200}
201
202
203
204////////////////////////////////////////////////////////////////////////////////
205/// Return list of (partial) integrals whose product defines the integral of this
206/// RooProduct over the observables in iset in range isetRange. If no such list
207/// exists, create it now and store it in the cache for future use.
208
209Int_t RooProduct::getPartIntList(const RooArgSet* iset, const char *isetRange) const
210{
211
212 // check if we already have integrals for this combination of factors
213 Int_t sterileIndex(-1);
214 CacheElem* cache = static_cast<CacheElem*>(_cacheMgr.getObj(iset,iset,&sterileIndex,RooNameReg::ptr(isetRange)));
215 if (cache!=nullptr) {
216 Int_t code = _cacheMgr.lastIndex();
217 return code;
218 }
219
220 std::unique_ptr<ProdMap> map{groupProductTerms(*iset)};
221
222 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") groupProductTerms returned map" ;
223 if (dologD(Integration)) {
224 dump_map(ccoutD(Integration),map->begin(),map->end());
225 ccoutD(Integration) << std::endl;
226 }
227
228 // did we find any factorizable terms?
229 if (map->size()<2) {
230
231 for (ProdMap::iterator iter = map->begin() ; iter != map->end() ; ++iter) {
232 delete iter->first ;
233 delete iter->second ;
234 }
235
236 return -1; // RRI caller will zero analVars if return code = 0....
237 }
238 cache = new CacheElem();
239
240 for (ProdMap::const_iterator i = map->begin();i!=map->end();++i) {
241 RooAbsReal *term(nullptr);
242 if (i->second->size()>1) { // create a RooProd for this subexpression
243 const char *name = makeFPName("SUBPROD_",*i->second);
244 auto ownedTerm = std::make_unique<RooProduct>(name,name,*i->second);
245 term = ownedTerm.get();
246 cache->_ownedList.addOwned(std::move(ownedTerm));
247 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") created subexpression " << term->GetName() << std::endl;
248 } else {
249 assert(i->second->size()==1);
250 term = static_cast<RooAbsReal*>(i->second->at(0));
251 }
252 assert(term!=nullptr);
253 if (i->first->empty()) { // check whether we need to integrate over this term or not...
254 cache->_prodList.add(*term);
255 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") adding simple factor " << term->GetName() << std::endl;
256 } else {
257 std::unique_ptr<RooAbsReal> integral{term->createIntegral(*i->first,isetRange)};
258 cache->_prodList.add(*integral);
259 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") adding integral for " << term->GetName() << " : " << integral->GetName() << std::endl;
260 cache->_ownedList.addOwned(std::move(integral));
261 }
262 }
263 // add current set-up to cache, and return index..
264 Int_t code = _cacheMgr.setObj(iset,iset,(RooAbsCacheElement*)cache,RooNameReg::ptr(isetRange));
265
266 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") created list " << cache->_prodList << " with code " << code+1 << std::endl
267 << " for iset=" << *iset << " @" << iset << " range: " << (isetRange?isetRange:"<none>") << std::endl ;
268
269 for (ProdMap::iterator iter = map->begin() ; iter != map->end() ; ++iter) {
270 delete iter->first ;
271 delete iter->second ;
272 }
273 return code;
274}
275
276
277////////////////////////////////////////////////////////////////////////////////
278/// Declare that we handle all integrations internally
279
281 const RooArgSet* /*normSet*/,
282 const char* rangeName) const
283{
284 if (_forceNumInt) return 0 ;
285
286 // Declare that we can analytically integrate all requested observables
287 // (basically, we will take care of the problem, and delegate where required)
288 //assert(normSet==0);
289 assert(analVars.empty());
290 analVars.add(allVars) ;
291 Int_t code = getPartIntList(&analVars,rangeName)+1;
292 return code ;
293}
294
295
296////////////////////////////////////////////////////////////////////////////////
297/// Calculate integral internally from appropriate partial integral cache
298
299double RooProduct::analyticalIntegral(Int_t code, const char* rangeName) const
300{
301 // note: rangeName implicit encoded in code: see _cacheMgr.setObj in getPartIntList...
302 CacheElem *cache = static_cast<CacheElem*>(_cacheMgr.getObjByIndex(code-1));
303 if (cache==nullptr) {
304 // cache got sterilized, trigger repopulation of this slot, then try again...
305 std::unique_ptr<RooArgSet> vars( getParameters(RooArgSet()) );
306 RooArgSet iset = _cacheMgr.selectFromSet2(*vars, code-1);
307 Int_t code2 = getPartIntList(&iset,rangeName)+1;
308 assert(code==code2); // must have revived the right (sterilized) slot...
309 return analyticalIntegral(code2,rangeName);
310 }
311 assert(cache!=nullptr);
312
313 return calculate(cache->_prodList);
314}
315
316
317////////////////////////////////////////////////////////////////////////////////
318/// Calculate and return product of partial terms in partIntList
319
320double RooProduct::calculate(const RooArgList& partIntList) const
321{
322 double val=1;
323 for (const auto arg : partIntList) {
324 const auto term = static_cast<const RooAbsReal*>(arg);
325 double x = term->getVal();
326 val*= x;
327 }
328 return val;
329}
330
331
332////////////////////////////////////////////////////////////////////////////////
333/// Construct automatic name for internal product terms
334
335const char* RooProduct::makeFPName(const char *pfx,const RooArgSet& terms) const
336{
337 static TString pname;
338 pname = pfx;
339 bool first(true);
340 for (auto const* arg : terms) {
341 if (first) { first=false;}
342 else pname.Append("_X_");
343 pname.Append(arg->GetName());
344 }
345 return pname.Data();
346}
347
348
349
350////////////////////////////////////////////////////////////////////////////////
351/// Evaluate product of input functions
352
354{
355 double prod(1) ;
356
357 const RooArgSet* nset = _compRSet.nset() ;
358 for (const auto item : _compRSet) {
359 auto rcomp = static_cast<const RooAbsReal*>(item);
360
361 prod *= rcomp->getVal(nset) ;
362 }
363
364 for (const auto item : _compCSet) {
365 auto ccomp = static_cast<const RooAbsCategory*>(item);
366
367 prod *= ccomp->getCurrentIndex() ;
368 }
369
370 return prod ;
371}
372
373
375{
376 std::span<double> output = ctx.output();
377 std::size_t nEvents = output.size();
378
379 for (unsigned int i = 0; i < nEvents; ++i) {
380 output[i] = 1.;
381 }
382
383 for (const auto item : _compRSet) {
384 auto rcomp = static_cast<const RooAbsReal*>(item);
385 auto componentValues = ctx.at(rcomp);
386
387 for (unsigned int i = 0; i < nEvents; ++i) {
388 output[i] *= componentValues.size() == 1 ? componentValues[0] : componentValues[i];
389 }
390 }
391
392 for (const auto item : _compCSet) {
393 auto ccomp = static_cast<const RooAbsCategory*>(item);
394 const int catIndex = ccomp->getCurrentIndex();
395
396 for (unsigned int i = 0; i < nEvents; ++i) {
397 output[i] *= catIndex;
398 }
399 }
400}
401
402
403////////////////////////////////////////////////////////////////////////////////
404/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
405
406std::list<double>* RooProduct::binBoundaries(RooAbsRealLValue& obs, double xlo, double xhi) const
407{
408 for (const auto item : _compRSet) {
409 auto func = static_cast<const RooAbsReal*>(item);
410
411 if (std::list<double>* binb = func->binBoundaries(obs,xlo,xhi)) {
412 return binb ;
413 }
414 }
415
416 return nullptr ;
417}
418
419
420//_____________________________________________________________________________B
422{
423 // If all components that depend on obs are binned that so is the product
424
425 for (const auto item : _compRSet) {
426 auto func = static_cast<const RooAbsReal*>(item);
427
428 if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) {
429 return false ;
430 }
431 }
432
433 return true ;
434}
435
436
437
438////////////////////////////////////////////////////////////////////////////////
439/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
440
441std::list<double>* RooProduct::plotSamplingHint(RooAbsRealLValue& obs, double xlo, double xhi) const
442{
443 for (const auto item : _compRSet) {
444 auto func = static_cast<const RooAbsReal*>(item);
445
446 if (std::list<double>* hint = func->plotSamplingHint(obs,xlo,xhi)) {
447 return hint ;
448 }
449 }
450
451 return nullptr ;
452}
453
454
455
456////////////////////////////////////////////////////////////////////////////////
457/// Destructor
458
460{
461}
462
463
464////////////////////////////////////////////////////////////////////////////////
465/// Return list of all RooAbsArgs in cache element
466
468{
469 RooArgList ret(_ownedList) ;
470 return ret ;
471}
472
473
474
475
476////////////////////////////////////////////////////////////////////////////////
477/// Label OK'ed components of a RooProduct with cache-and-track
478
480{
481 RooArgSet comp(components()) ;
482 for (const auto parg : comp) {
483 if (parg->isDerived()) {
484 if (parg->canNodeBeCached()==Always) {
485 trackNodes.add(*parg) ;
486 }
487 }
488 }
489}
490
491////////////////////////////////////////////////////////////////////////////////
492/// Customized printing of arguments of a RooProduct to more intuitively reflect the contents of the
493/// product operator construction
494
495void RooProduct::printMetaArgs(std::ostream& os) const
496{
497 bool first(true) ;
498
499 for (const auto rcomp : _compRSet) {
500 if (!first) { os << " * " ; } else { first = false ; }
501 os << rcomp->GetName() ;
502 }
503
504 for (const auto item : _compCSet) {
505 auto ccomp = static_cast<const RooAbsCategory*>(item);
506
507 if (!first) { os << " * " ; } else { first = false ; }
508 os << ccomp->GetName() ;
509 }
510
511 os << " " ;
512}
513
514
516 RooAbsReal::ioStreamerPass2(); // call the baseclass method
517
518 if(numProxies() < 2) {
519 throw std::runtime_error("RooProduct::ioStreamerPass2(): the number of proxies in the proxy list should be at least 2!");
520 }
521
522 // If the proxy data members are evolved by schema evolution, the proxy list
523 // that references them will contain null pointers because the evolved
524 // members are only created after the proxy list. That's why we have to set
525 // them manually in that case.
526 RooAbsProxy * p0 = getProxy(0);
527 if(p0 == nullptr) {
529 p0 = &_compRSet;
530 }
531 RooAbsProxy * p1 = getProxy(1);
532 if(p1 == nullptr) {
534 p1 = &_compCSet;
535 }
536
537 // If the proxies in the proxy list still don't correspond to _compRSet and
538 // _compCSet, it's time to print errors. And try to recover.
539 auto expectProxyIs = [this](std::size_t idx, RooAbsProxy * proxyInArg, RooListProxy * ourProxy, const char* memberName) {
540 if(proxyInArg != ourProxy) {
541 // From experience, it's rather the members of the RooProduct that is
542 // still correct in these inconsistent cases. That's why we try to
543 // recover by setting the proxy in the _proxyList to be equal to the
544 // member proxy. But that might be wrong, so it's important to warn the
545 // user anyway.
546 _proxyList.RemoveAt(idx);
547 _proxyList.AddAt(ourProxy, idx);
548 std::stringstream ss;
549 ss << "Problem when reading RooProduct instance \"" << GetName() << "\"!\n"
550 << " _proxyList[" << idx << "] was expected to be equal to " << memberName << ", but it's not.\n"
551 << " - proxyList[" << idx << "] : ";
552 proxyInArg->print(ss, true);
553 ss << "\n - " << memberName << " : " ;
554 ourProxy->print(ss, true);
555 ss << "\n RooFit will resolve this inconsistency by making _proxyList[" << idx << "] point to " << memberName
556 << ".";
557 coutW(LinkStateMgmt) << ss.str() << std::endl;
558 }
559 };
560
561 expectProxyIs(0, p0, &_compRSet, "_compRSet");
562 expectProxyIs(1, p1, &_compCSet, "_compCSet");
563}
564
565
566namespace {
567
568std::pair<RPPMIter,RPPMIter> findOverlap2nd(RPPMIter i, RPPMIter end)
569{
570 // Utility function finding pairs of overlapping input functions
571 for (; i != end; ++i) {
572 for (RPPMIter j(i + 1); j != end; ++j) {
573 if (i->second->overlaps(*j->second)) {
574 return std::make_pair(i, j);
575 }
576 }
577 }
578 return std::make_pair(end,end);
579}
580
581
582void dump_map(std::ostream& os, RPPMIter i, RPPMIter end)
583{
584 // Utility dump function for debugging
585 bool first(true);
586 os << " [ " ;
587 for(; i!=end;++i) {
588 if (first) { first=false; }
589 else { os << " , " ; }
590 os << *(i->first) << " -> " << *(i->second) ;
591 }
592 os << " ] " ;
593}
594
595}
#define cxcoutD(a)
#define coutW(a)
#define dologD(a)
#define coutE(a)
#define ccoutD(a)
#define TRACE_DESTROY
Definition RooTrace.h:24
#define TRACE_CREATE
Definition RooTrace.h:23
#define ClassImp(name)
Definition Rtypes.h:382
char name[80]
Definition TGX11.cxx:110
Common abstract base class for objects that represent a value and a "shape" in RooFit.
Definition RooAbsArg.h:77
RooRefArray _proxyList
Definition RooAbsArg.h:578
RooFit::OwningPtr< RooArgSet > getParameters(const RooAbsData *data, bool stripDisconnected=true) const
Create a list of leaf nodes in the arg tree starting with ourself as top node that don't match any of...
virtual void ioStreamerPass2()
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
Int_t numProxies() const
Return the number of registered proxies.
RooAbsProxy * getProxy(Int_t index) const
Return the nth proxy from the proxy list.
Abstract base class for objects to be stored in RooAbsCache cache manager objects.
A space to attach TBranches.
virtual value_type getCurrentIndex() const
Return index number of current state.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
Storage_t::size_type size() const
RooAbsArg * first() const
virtual bool addOwned(RooAbsArg &var, bool silent=false)
Add an argument and transfer the ownership to the collection.
Abstract interface for proxy classes.
Definition RooAbsProxy.h:37
const RooArgSet * nset() const
Definition RooAbsProxy.h:52
Abstract base class for objects that represent a real value that may appear on the left hand side of ...
Abstract base class for objects that represent a real value and implements functionality common to al...
Definition RooAbsReal.h:59
bool _forceNumInt
Force numerical integration if flag set.
Definition RooAbsReal.h:538
RooFit::OwningPtr< RooAbsReal > createIntegral(const RooArgSet &iset, const RooCmdArg &arg1, const RooCmdArg &arg2={}, const RooCmdArg &arg3={}, const RooCmdArg &arg4={}, const RooCmdArg &arg5={}, const RooCmdArg &arg6={}, const RooCmdArg &arg7={}, const RooCmdArg &arg8={}) const
Create an object that represents the integral of the function over one or more observables listed in ...
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition RooArgList.h:22
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=nullptr)
Setter function without integration set.
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
RooArgSet selectFromSet2(RooArgSet const &argSet, int index) const
Create RooArgSet containing the objects that are both in the cached set 2 with a given index and an i...
Int_t lastIndex() const
Return index of slot used in last get or set operation.
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=nullptr, const TNamed *isetRangeName=nullptr)
Getter function without integration set.
bool add(const RooAbsArg &var, bool valueServer, bool shapeServer, bool silent)
Overloaded RooCollection_t::add() method insert object into set and registers object as server to own...
std::span< const double > at(RooAbsArg const *arg, RooAbsArg const *caller=nullptr)
std::span< double > output()
static const TNamed * ptr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
RooArgList containedArgs(Action) override
Return list of all RooAbsArgs in cache element.
RooArgList _ownedList
Definition RooProduct.h:78
~CacheElem() override
Destructor.
Represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
std::list< double > * binBoundaries(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
void doEval(RooFit::EvalContext &) const override
Base function for computing multiple values of a RooAbsReal.
RooListProxy _compRSet
Definition RooProduct.h:70
double evaluate() const override
Evaluate product of input functions.
double analyticalIntegral(Int_t code, const char *rangeName=nullptr) const override
Calculate integral internally from appropriate partial integral cache.
void addTerm(RooAbsArg *term)
Add a term to this product.
std::list< double > * plotSamplingHint(RooAbsRealLValue &, double, double) const override
Forward the plot sampling hint from the p.d.f. that defines the observable obs.
ProdMap * groupProductTerms(const RooArgSet &) const
Group observables into subsets in which the product factorizes and that can thus be integrated separa...
double calculate(const RooArgList &partIntList) const
The cache manager.
bool forceAnalyticalInt(const RooAbsArg &dep) const override
Force internal handling of integration of given observable if any of the product terms depend on it.
void setCacheAndTrackHints(RooArgSet &) override
Label OK'ed components of a RooProduct with cache-and-track.
~RooProduct() override
Destructor.
bool isBinnedDistribution(const RooArgSet &obs) const override
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
void ioStreamerPass2() override
Method called by workspace container to finalize schema evolution issues that cannot be handled in a ...
Int_t getPartIntList(const RooArgSet *iset, const char *rangeName=nullptr) const
Return list of (partial) integrals whose product defines the integral of this RooProduct over the obs...
Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=nullptr) const override
Declare that we handle all integrations internally.
void printMetaArgs(std::ostream &os) const override
Customized printing of arguments of a RooProduct to more intuitively reflect the contents of the prod...
const char * makeFPName(const char *pfx, const RooArgSet &terms) const
Construct automatic name for internal product terms.
RooProduct()
Default constructor.
RooObjCacheManager _cacheMgr
Definition RooProduct.h:81
RooListProxy _compCSet
Definition RooProduct.h:71
RooArgList components()
Definition RooProduct.h:48
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
void AddAt(TObject *obj, Int_t idx) override
Add object at position ids.
TObject * RemoveAt(Int_t idx) override
Remove object at index idx.
Basic string class.
Definition TString.h:139
const char * Data() const
Definition TString.h:376
TString & Append(const char *cs)
Definition TString.h:572
Double_t x[n]
Definition legend1.C:17
static void output()