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
22A RooProduct represents the product of a given set of RooAbsReal objects.
23
24**/
25
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
37using namespace std ;
38
40;
41
42class RooProduct::ProdMap : public std::vector<std::pair<RooArgSet*,RooArgList*> > {} ;
43
44// Namespace with helper functions that have STL stuff that we don't want to expose to CINT
45namespace {
46 typedef RooProduct::ProdMap::iterator RPPMIter ;
47 std::pair<RPPMIter,RPPMIter> findOverlap2nd(RPPMIter i, RPPMIter end) ;
48 void dump_map(ostream& os, RPPMIter i, RPPMIter end) ;
49}
50
51
52
53////////////////////////////////////////////////////////////////////////////////
54/// Default constructor
55
56RooProduct::RooProduct() : _cacheMgr(this,10)
57{
59}
60
61
62
63////////////////////////////////////////////////////////////////////////////////
64/// Destructor
65
67{
69}
70
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Construct function representing the product of functions in prodSet
75
76RooProduct::RooProduct(const char* name, const char* title, const RooArgList& prodSet) :
77 RooAbsReal(name, title),
78 _compRSet("!compRSet","Set of real product components",this),
79 _compCSet("!compCSet","Set of category product components",this),
80 _cacheMgr(this,10)
81{
82 for (auto comp : prodSet) {
83 addTerm(comp);
84 }
86}
87
88
89
90////////////////////////////////////////////////////////////////////////////////
91/// Copy constructor
92
93RooProduct::RooProduct(const RooProduct& other, const char* name) :
94 RooAbsReal(other, name),
95 _compRSet("!compRSet",this,other._compRSet),
96 _compCSet("!compCSet",this,other._compCSet),
97 _cacheMgr(other._cacheMgr,this)
98{
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Add a term to this product.
106 if (dynamic_cast<RooAbsReal*>(term)) {
107 _compRSet.add(*term) ;
108 } else if (dynamic_cast<RooAbsCategory*>(term)) {
109 _compCSet.add(*term) ;
110 } else {
111 coutE(InputArguments) << "RooProduct::addTerm(" << GetName() << ") ERROR: component " << term->GetName()
112 << " is not of type RooAbsReal or RooAbsCategory" << endl ;
113 throw std::invalid_argument("RooProduct can only handle terms deriving from RooAbsReal or RooAbsCategory.");
114 }
115}
116
117////////////////////////////////////////////////////////////////////////////////
118/// Force internal handling of integration of given observable if any
119/// of the product terms depend on it.
120
122{
123 // Force internal handling of integration of given observable if any
124 // of the product terms depend on it.
125
126 RooFIter compRIter = _compRSet.fwdIterator() ;
127 RooAbsReal* rcomp ;
128 Bool_t depends(kFALSE);
129 while((rcomp=(RooAbsReal*)compRIter.next())&&!depends) {
130 depends = rcomp->dependsOn(dep);
131 }
132 return depends ;
133}
134
135
136
137////////////////////////////////////////////////////////////////////////////////
138/// Group observables into subsets in which the product factorizes
139/// and that can thus be integrated separately
140
142{
143 ProdMap* map = new ProdMap ;
144
145 // Do we have any terms which do not depend on the
146 // on the variables we integrate over?
147 RooAbsReal* rcomp ;
148 RooFIter compRIter = _compRSet.fwdIterator() ;
149 RooArgList *indep = new RooArgList();
150 while((rcomp=(RooAbsReal*) compRIter.next())) {
151 if( !rcomp->dependsOn(allVars) ) indep->add(*rcomp);
152 }
153 if (indep->getSize()!=0) {
154 map->push_back( std::make_pair(new RooArgSet(),indep) );
155 } else {
156 delete indep;
157 }
158
159 // Map observables -> functions ; start with individual observables
160 RooFIter allVarsIter = allVars.fwdIterator() ;
161 RooAbsReal* var ;
162 while((var=(RooAbsReal*)allVarsIter.next())) {
163 RooArgSet *vars = new RooArgSet(); vars->add(*var);
164 RooArgList *comps = new RooArgList();
165 RooAbsReal* rcomp2 ;
166
167 compRIter = _compRSet.fwdIterator() ;
168 while((rcomp2=(RooAbsReal*) compRIter.next())) {
169 if( rcomp2->dependsOn(*var) ) comps->add(*rcomp2);
170 }
171 map->push_back( std::make_pair(vars,comps) );
172 }
173
174 // Merge groups with overlapping dependents
175 Bool_t overlap;
176 do {
177 std::pair<ProdMap::iterator,ProdMap::iterator> i = findOverlap2nd(map->begin(),map->end());
178 overlap = (i.first!=i.second);
179 if (overlap) {
180 i.first->first->add(*i.second->first);
181
182 // In the merging step, make sure not to duplicate
183 RooFIter it = i.second->second->fwdIterator() ;
184 RooAbsArg* targ ;
185 while ((targ = it.next())) {
186 if (!i.first->second->find(*targ)) {
187 i.first->second->add(*targ) ;
188 }
189 }
190 //i.first->second->add(*i.second->second);
191
192 delete i.second->first;
193 delete i.second->second;
194 map->erase(i.second);
195 }
196 } while (overlap);
197
198#ifndef NDEBUG
199 // check that we have all variables to be integrated over on the LHS
200 // of the map, and all terms in the product do appear on the RHS
201 int nVar=0; int nFunc=0;
202 for (ProdMap::iterator i = map->begin();i!=map->end();++i) {
203 nVar+=i->first->getSize();
204 nFunc+=i->second->getSize();
205 }
206 assert(nVar==allVars.getSize());
207 assert(nFunc==_compRSet.getSize());
208#endif
209 return map;
210}
211
212
213
214////////////////////////////////////////////////////////////////////////////////
215/// Return list of (partial) integrals whose product defines the integral of this
216/// RooProduct over the observables in iset in range isetRange. If no such list
217/// exists, create it now and store it in the cache for future use.
218
219Int_t RooProduct::getPartIntList(const RooArgSet* iset, const char *isetRange) const
220{
221
222 // check if we already have integrals for this combination of factors
223 Int_t sterileIndex(-1);
224 CacheElem* cache = (CacheElem*) _cacheMgr.getObj(iset,iset,&sterileIndex,RooNameReg::ptr(isetRange));
225 if (cache!=0) {
226 Int_t code = _cacheMgr.lastIndex();
227 return code;
228 }
229
230 ProdMap* map = groupProductTerms(*iset);
231
232 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") groupProductTerms returned map" ;
233 if (dologD(Integration)) {
234 dump_map(ccoutD(Integration),map->begin(),map->end());
235 ccoutD(Integration) << endl;
236 }
237
238 // did we find any factorizable terms?
239 if (map->size()<2) {
240
241 for (ProdMap::iterator iter = map->begin() ; iter != map->end() ; ++iter) {
242 delete iter->first ;
243 delete iter->second ;
244 }
245
246 delete map ;
247 return -1; // RRI caller will zero analVars if return code = 0....
248 }
249 cache = new CacheElem();
250
251 for (ProdMap::const_iterator i = map->begin();i!=map->end();++i) {
252 RooAbsReal *term(0);
253 if (i->second->getSize()>1) { // create a RooProd for this subexpression
254 const char *name = makeFPName("SUBPROD_",*i->second);
255 term = new RooProduct(name,name,*i->second);
256 cache->_ownedList.addOwned(*term);
257 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") created subexpression " << term->GetName() << endl;
258 } else {
259 assert(i->second->getSize()==1);
260 RooFIter j = i->second->fwdIterator();
261 term = (RooAbsReal*)j.next();
262 }
263 assert(term!=0);
264 if (i->first->getSize()==0) { // check whether we need to integrate over this term or not...
265 cache->_prodList.add(*term);
266 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") adding simple factor " << term->GetName() << endl;
267 } else {
268 RooAbsReal *integral = term->createIntegral(*i->first,isetRange);
269 cache->_prodList.add(*integral);
270 cache->_ownedList.addOwned(*integral);
271 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") adding integral for " << term->GetName() << " : " << integral->GetName() << endl;
272 }
273 }
274 // add current set-up to cache, and return index..
275 Int_t code = _cacheMgr.setObj(iset,iset,(RooAbsCacheElement*)cache,RooNameReg::ptr(isetRange));
276
277 cxcoutD(Integration) << "RooProduct::getPartIntList(" << GetName() << ") created list " << cache->_prodList << " with code " << code+1 << endl
278 << " for iset=" << *iset << " @" << iset << " range: " << (isetRange?isetRange:"<none>") << endl ;
279
280 for (ProdMap::iterator iter = map->begin() ; iter != map->end() ; ++iter) {
281 delete iter->first ;
282 delete iter->second ;
283 }
284 delete map ;
285 return code;
286}
287
288
289////////////////////////////////////////////////////////////////////////////////
290/// Declare that we handle all integrations internally
291
293 const RooArgSet* /*normSet*/,
294 const char* rangeName) const
295{
296 if (_forceNumInt) return 0 ;
297
298 // Declare that we can analytically integrate all requested observables
299 // (basically, we will take care of the problem, and delegate where required)
300 //assert(normSet==0);
301 assert(analVars.getSize()==0);
302 analVars.add(allVars) ;
303 Int_t code = getPartIntList(&analVars,rangeName)+1;
304 return code ;
305}
306
307
308////////////////////////////////////////////////////////////////////////////////
309/// Calculate integral internally from appropriate partial integral cache
310
311Double_t RooProduct::analyticalIntegral(Int_t code, const char* rangeName) const
312{
313 // note: rangeName implicit encoded in code: see _cacheMgr.setObj in getPartIntList...
314 CacheElem *cache = (CacheElem*) _cacheMgr.getObjByIndex(code-1);
315 if (cache==0) {
316 // cache got sterilized, trigger repopulation of this slot, then try again...
317 std::unique_ptr<RooArgSet> vars( getParameters(RooArgSet()) );
318 RooArgSet iset = _cacheMgr.selectFromSet2(*vars, code-1);
319 Int_t code2 = getPartIntList(&iset,rangeName)+1;
320 assert(code==code2); // must have revived the right (sterilized) slot...
321 return analyticalIntegral(code2,rangeName);
322 }
323 assert(cache!=0);
324
325 return calculate(cache->_prodList);
326}
327
328
329////////////////////////////////////////////////////////////////////////////////
330/// Calculate and return product of partial terms in partIntList
331
333{
334 Double_t val=1;
335 for (const auto arg : partIntList) {
336 const auto term = static_cast<const RooAbsReal*>(arg);
337 double x = term->getVal();
338 val*= x;
339 }
340 return val;
341}
342
343
344////////////////////////////////////////////////////////////////////////////////
345/// Construct automatic name for internal product terms
346
347const char* RooProduct::makeFPName(const char *pfx,const RooArgSet& terms) const
348{
349 static TString pname;
350 pname = pfx;
351 RooFIter i = terms.fwdIterator();
352 RooAbsArg *arg;
354 while((arg=(RooAbsArg*)i.next())) {
355 if (first) { first=kFALSE;}
356 else pname.Append("_X_");
357 pname.Append(arg->GetName());
358 }
359 return pname.Data();
360}
361
362
363
364////////////////////////////////////////////////////////////////////////////////
365/// Evaluate product of input functions
366
368{
369 Double_t prod(1) ;
370
371 const RooArgSet* nset = _compRSet.nset() ;
372 for (const auto item : _compRSet) {
373 auto rcomp = static_cast<const RooAbsReal*>(item);
374
375 prod *= rcomp->getVal(nset) ;
376 }
377
378 for (const auto item : _compCSet) {
379 auto ccomp = static_cast<const RooAbsCategory*>(item);
380
381 prod *= ccomp->getCurrentIndex() ;
382 }
383
384 return prod ;
385}
386
387
388void RooProduct::computeBatch(cudaStream_t* /*stream*/, double* output, size_t nEvents, RooFit::Detail::DataMap const& dataMap) const
389{
390 for (unsigned int i = 0; i < nEvents; ++i) {
391 output[i] = 1.;
392 }
393
394 for (const auto item : _compRSet) {
395 auto rcomp = static_cast<const RooAbsReal*>(item);
396 auto componentValues = dataMap.at(rcomp);
397
398 for (unsigned int i = 0; i < nEvents; ++i) {
399 output[i] *= componentValues.size() == 1 ? componentValues[0] : componentValues[i];
400 }
401 }
402
403 for (const auto item : _compCSet) {
404 auto ccomp = static_cast<const RooAbsCategory*>(item);
405 const int catIndex = ccomp->getCurrentIndex();
406
407 for (unsigned int i = 0; i < nEvents; ++i) {
408 output[i] *= catIndex;
409 }
410 }
411}
412
413
414////////////////////////////////////////////////////////////////////////////////
415/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
416
417std::list<Double_t>* RooProduct::binBoundaries(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
418{
419 for (const auto item : _compRSet) {
420 auto func = static_cast<const RooAbsReal*>(item);
421
422 list<Double_t>* binb = func->binBoundaries(obs,xlo,xhi) ;
423 if (binb) {
424 return binb ;
425 }
426 }
427
428 return 0 ;
429}
430
431
432//_____________________________________________________________________________B
434{
435 // If all components that depend on obs are binned that so is the product
436
437 for (const auto item : _compRSet) {
438 auto func = static_cast<const RooAbsReal*>(item);
439
440 if (func->dependsOn(obs) && !func->isBinnedDistribution(obs)) {
441 return kFALSE ;
442 }
443 }
444
445 return kTRUE ;
446}
447
448
449
450////////////////////////////////////////////////////////////////////////////////
451/// Forward the plot sampling hint from the p.d.f. that defines the observable obs
452
453std::list<Double_t>* RooProduct::plotSamplingHint(RooAbsRealLValue& obs, Double_t xlo, Double_t xhi) const
454{
455 for (const auto item : _compRSet) {
456 auto func = static_cast<const RooAbsReal*>(item);
457
458 list<Double_t>* hint = func->plotSamplingHint(obs,xlo,xhi) ;
459 if (hint) {
460 return hint ;
461 }
462 }
463
464 return 0 ;
465}
466
467
468
469////////////////////////////////////////////////////////////////////////////////
470/// Destructor
471
473{
474}
475
476
477////////////////////////////////////////////////////////////////////////////////
478/// Return list of all RooAbsArgs in cache element
479
481{
482 RooArgList ret(_ownedList) ;
483 return ret ;
484}
485
486
487
488
489////////////////////////////////////////////////////////////////////////////////
490/// Label OK'ed components of a RooProduct with cache-and-track
491
493{
494 RooArgSet comp(components()) ;
495 for (const auto parg : comp) {
496 if (parg->isDerived()) {
497 if (parg->canNodeBeCached()==Always) {
498 trackNodes.add(*parg) ;
499 //cout << "tracking node RooProduct component " << parg->IsA()->GetName() << "::" << parg->GetName() << endl ;
500 }
501 }
502 }
503}
504
505
506
507
508
509////////////////////////////////////////////////////////////////////////////////
510/// Customized printing of arguments of a RooProduct to more intuitively reflect the contents of the
511/// product operator construction
512
513void RooProduct::printMetaArgs(ostream& os) const
514{
516
517 for (const auto rcomp : _compRSet) {
518 if (!first) { os << " * " ; } else { first = kFALSE ; }
519 os << rcomp->GetName() ;
520 }
521
522 for (const auto item : _compCSet) {
523 auto ccomp = static_cast<const RooAbsCategory*>(item);
524
525 if (!first) { os << " * " ; } else { first = kFALSE ; }
526 os << ccomp->GetName() ;
527 }
528
529 os << " " ;
530}
531
532
533
534
535
536namespace {
537
538std::pair<RPPMIter,RPPMIter> findOverlap2nd(RPPMIter i, RPPMIter end)
539{
540 // Utility function finding pairs of overlapping input functions
541 for (; i!=end; ++i) for ( RPPMIter j(i+1); j!=end; ++j) {
542 if (i->second->overlaps(*j->second)) {
543 return std::make_pair(i,j);
544 }
545 }
546 return std::make_pair(end,end);
547}
548
549
550void dump_map(ostream& os, RPPMIter i, RPPMIter end)
551{
552 // Utility dump function for debugging
554 os << " [ " ;
555 for(; i!=end;++i) {
556 if (first) { first=kFALSE; }
557 else { os << " , " ; }
558 os << *(i->first) << " -> " << *(i->second) ;
559 }
560 os << " ] " ;
561}
562
563}
564
565
566
567
#define cxcoutD(a)
#define dologD(a)
#define coutE(a)
#define ccoutD(a)
#define TRACE_DESTROY
Definition RooTrace.h:24
#define TRACE_CREATE
Definition RooTrace.h:23
const Bool_t kFALSE
Definition RtypesCore.h:101
bool Bool_t
Definition RtypesCore.h:63
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
char name[80]
Definition TGX11.cxx:110
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition RooAbsArg.h:69
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.
friend class RooArgSet
Definition RooAbsArg.h:642
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...
RooAbsCacheElement is the abstract base class for objects to be stored in RooAbsCache cache manager o...
RooAbsCategory is the base class for objects that represent a discrete value with a finite number of ...
virtual value_type getCurrentIndex() const
Return index number of current state.
Int_t getSize() const
RooFIter fwdIterator() const
One-time forward iterator.
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
virtual Bool_t addOwned(RooAbsArg &var, Bool_t silent=kFALSE)
Add an argument and transfer the ownership to the collection.
RooAbsArg * first() const
const RooArgSet * nset() const
Definition RooAbsProxy.h:45
RooAbsRealLValue is the common abstract base class for objects that represent a real value that may a...
RooAbsReal is the common abstract base class for objects that represent a real value and implements f...
Definition RooAbsReal.h:64
Bool_t _forceNumInt
Definition RooAbsReal.h:487
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 ...
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Retrieve bin boundaries if this distribution is binned in obs.
Double_t getVal(const RooArgSet *normalisationSet=nullptr) const
Evaluate object.
Definition RooAbsReal.h:94
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &obs, Double_t xlo, Double_t xhi) const
Interface for returning an optional hint for initial sampling points when constructing a curve projec...
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:35
T * getObj(const RooArgSet *nset, Int_t *sterileIndex=0, const TNamed *isetRangeName=0)
T * getObjByIndex(Int_t index) const
Retrieve payload object by slot index.
RooArgSet selectFromSet2(RooArgSet const &argSet, int index) const
Create RooArgSet contatining the objects that are both in the cached set 2.
Int_t lastIndex() const
Int_t setObj(const RooArgSet *nset, T *obj, const TNamed *isetRangeName=0)
A one-time forward iterator working on RooLinkedList or RooAbsCollection.
RooAbsArg * next()
Return next element or nullptr if at end.
auto & at(RooAbsArg const *arg, RooAbsArg const *=nullptr)
Definition DataMap.h:88
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE) override
Reimplementation of standard RooArgList::add()
static const TNamed * ptr(const char *stringPtr)
Return a unique TNamed pointer for given C++ string.
virtual ~CacheElem()
Destructor.
RooArgList _ownedList
Definition RooProduct.h:72
virtual RooArgList containedArgs(Action)
Return list of all RooAbsArgs in cache element.
A RooProduct represents the product of a given set of RooAbsReal objects.
Definition RooProduct.h:29
void printMetaArgs(std::ostream &os) const
Customized printing of arguments of a RooProduct to more intuitively reflect the contents of the prod...
virtual std::list< Double_t > * plotSamplingHint(RooAbsRealLValue &, Double_t, Double_t) const
Forward the plot sampling hint from the p.d.f. that defines the observable obs
void computeBatch(cudaStream_t *, double *output, size_t nEvents, RooFit::Detail::DataMap const &) const
Base function for computing multiple values of a RooAbsReal.
RooListProxy _compRSet
Definition RooProduct.h:64
void addTerm(RooAbsArg *term)
Add a term to this product.
virtual ~RooProduct()
Destructor.
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.
double evaluate() const
Evaluate product of input functions.
virtual Int_t getAnalyticalIntegralWN(RooArgSet &allVars, RooArgSet &analVars, const RooArgSet *normSet, const char *rangeName=0) const
Declare that we handle all integrations internally.
virtual std::list< Double_t > * binBoundaries(RooAbsRealLValue &, Double_t, Double_t) const
Forward the plot sampling hint from the p.d.f. that defines the observable obs
const char * makeFPName(const char *pfx, const RooArgSet &terms) const
Construct automatic name for internal product terms.
virtual Bool_t forceAnalyticalInt(const RooAbsArg &dep) const
Force internal handling of integration of given observable if any of the product terms depend on it.
virtual Double_t analyticalIntegral(Int_t code, const char *rangeName=0) const
Calculate integral internally from appropriate partial integral cache.
RooProduct()
Default constructor.
RooObjCacheManager _cacheMgr
Definition RooProduct.h:75
Int_t getPartIntList(const RooArgSet *iset, const char *rangeName=0) const
Return list of (partial) integrals whose product defines the integral of this RooProduct over the obs...
virtual void setCacheAndTrackHints(RooArgSet &)
Label OK'ed components of a RooProduct with cache-and-track.
RooListProxy _compCSet
Definition RooProduct.h:65
virtual Bool_t isBinnedDistribution(const RooArgSet &obs) const
Tests if the distribution is binned. Unless overridden by derived classes, this always returns false.
RooArgList components()
Definition RooProduct.h:47
virtual const char * GetName() const
Returns name of object.
Definition TNamed.h:47
Basic string class.
Definition TString.h:136
const char * Data() const
Definition TString.h:369
TString & Append(const char *cs)
Definition TString.h:564
Double_t x[n]
Definition legend1.C:17
Definition first.py:1
static void output(int code)
Definition gifencode.c:226