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