Logo ROOT  
Reference Guide
RooAbsGenContext.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\file RooAbsGenContext.cxx
19\class RooAbsGenContext
20\ingroup Roofitcore
21
22RooAbsGenContext is the abstract base class for generator contexts of
23RooAbsPdf objects. A generator context is an object that controls
24the generation of events from a given p.d.f in one or more sessions.
25This class defines the common interface for all such contexts and organizes
26storage of common components, such as the observables definition, the
27prototype data etc..
28**/
29
30#include "TClass.h"
31
32#include "RooAbsGenContext.h"
33#include "RooRandom.h"
34#include "RooAbsPdf.h"
35#include "RooDataSet.h"
36#include "RooMsgService.h"
37#include "RooGlobalFunc.h"
38
39#include "Riostream.h"
40
41
42using namespace std;
43
45;
46
47
48////////////////////////////////////////////////////////////////////////////////
49/// Constructor
50
52 const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
53 TNamed(model),
54 _prototype(prototype),
55 _isValid(kTRUE),
56 _verbose(verbose),
57 _protoOrder(0),
58 _genData(0)
59{
60 // Check PDF dependents
61 if (model.recursiveCheckObservables(&vars)) {
62 coutE(Generation) << "RooAbsGenContext::ctor: Error in PDF dependents" << endl ;
64 return ;
65 }
66
67 // Make a snapshot of the generated variables that we can overwrite.
68 vars.snapshot(_theEvent, false);
69
70 // Analyze the prototype dataset, if one is specified
72 if(0 != _prototype) {
73 TIterator *protoIterator= _prototype->get()->createIterator();
74 const RooAbsArg *proto = 0;
75 while((proto= (const RooAbsArg*)protoIterator->Next())) {
76 // is this variable being generated or taken from the prototype?
77 if(!_theEvent.contains(*proto)) {
80 }
81 }
82 delete protoIterator;
83 }
84
85 // Add auxiliary protovars to _protoVars, if provided
86 if (auxProto) {
87 _protoVars.add(*auxProto) ;
88 _theEvent.addClone(*auxProto);
89 }
90
91 // Remember the default number of events to generate when no prototype dataset is provided.
92 _extendMode = model.extendMode() ;
93 if (model.canBeExtended()) {
95 } else {
97 }
98
99 // Save normalization range
100 if (model.normRange()) {
101 _normRange = model.normRange() ;
102 }
103}
104
105
106
107////////////////////////////////////////////////////////////////////////////////
108/// Destructor
109
111{
112 if (_protoOrder) delete[] _protoOrder ;
113}
114
115
116
117////////////////////////////////////////////////////////////////////////////////
118/// Interface to attach given parameters to object in this context
119
120void RooAbsGenContext::attach(const RooArgSet& /*params*/)
121{
122}
123
124
125
126////////////////////////////////////////////////////////////////////////////////
127/// Create an empty dataset to hold the events that will be generated
128
129RooDataSet* RooAbsGenContext::createDataSet(const char* name, const char* title, const RooArgSet& obs)
130{
131 RooDataSet* ret = new RooDataSet(name, title, obs);
132 ret->setDirtyProp(kFALSE) ;
133 return ret ;
134}
135
136
137////////////////////////////////////////////////////////////////////////////////
138/// Generate the specified number of events with nEvents>0 and
139/// and return a dataset containing the generated events. With nEvents<=0,
140/// generate the number of events in the prototype dataset, if available,
141/// or else the expected number of events, if non-zero.
142/// If extendedMode = true generate according to a Poisson(nEvents)
143/// The returned dataset belongs to the caller. Return zero in case of an error.
144/// Generation of individual events is delegated to a virtual generateEvent()
145/// method. A virtual initGenerator() method is also called just before the
146/// first call to generateEvent().
147
149{
150 if(!isValid()) {
151 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
152 return 0;
153 }
154
155 // Calculate the expected number of events if necessary
156 if(nEvents <= 0) {
157 if(_prototype) {
158 nEvents= (Int_t)_prototype->numEntries();
159 }
160 else {
162 coutE(Generation) << ClassName() << "::" << GetName()
163 << ":generate: PDF not extendable: cannot calculate expected number of events" << endl;
164 return 0;
165 }
166 nEvents= _expectedEvents;
167 }
168 if(nEvents <= 0) {
169 coutE(Generation) << ClassName() << "::" << GetName()
170 << ":generate: cannot calculate expected number of events" << endl;
171 return 0;
172 }
173 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
174 << nEvents << " events" << endl;
175
176 }
177
178 if (extendedMode) {
179 double nExpEvents = nEvents;
180 nEvents = RooRandom::randomGenerator()->Poisson(nEvents) ;
181 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
182 << GetName() << "::expectedEvents() = " << nExpEvents << endl ;
183 }
184
185 // check that any prototype dataset still defines the variables we need
186 // (this is necessary since we never make a private clone, for efficiency)
187 if(_prototype) {
188 const RooArgSet *vars= _prototype->get();
190 const RooAbsArg *arg = 0;
191 Bool_t ok(kTRUE);
192 while((arg= (const RooAbsArg*)iterator->Next())) {
193 if(vars->contains(*arg)) continue;
194 coutE(InputArguments) << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
195 << arg->GetName() << "\"" << endl;
196
197 // WVE disable this for the moment
198 // ok= kFALSE;
199 }
200 delete iterator;
201 // coverity[DEADCODE]
202 if(!ok) return 0;
203 }
204
205 if (_verbose) Print("v") ;
206
207 // create a new dataset
208 TString name(GetName()),title(GetTitle());
209 name.Append("Data");
210 title.Prepend("Generated From ");
211
212 // WVE need specialization here for simultaneous pdfs
213 _genData = createDataSet(name.Data(), title.Data(), _theEvent);
214
215 // Perform any subclass implementation-specific initialization
216 // Can be skipped if this is a rerun with an identical configuration
217 if (!skipInit) {
219 }
220
221 // Loop over the events to generate
222 Int_t evt(0) ;
223 while(_genData->numEntries()<nEvents) {
224
225 // first, load values from the prototype dataset, if one was provided
226 if(0 != _prototype) {
228
230
231 const RooArgSet *subEvent= _prototype->get(actualProtoIdx);
233 if(0 != subEvent) {
234 _theEvent.assign(*subEvent);
235 }
236 else {
237 coutE(Generation) << ClassName() << "::" << GetName() << ":generate: cannot load event "
238 << actualProtoIdx << " from prototype dataset" << endl;
239 return 0;
240 }
241 }
242
243 // delegate the generation of the rest of this event to our subclass implementation
245
246
247 // WVE add check that event is in normRange
249 continue ;
250 }
251
253 evt++ ;
254 }
255
257 _genData = 0 ;
258 output->setDirtyProp(kTRUE) ;
259
260 return output;
261}
262
263
264
265////////////////////////////////////////////////////////////////////////////////
266/// Interface function to initialize context for generation for given
267/// set of observables
268
270{
271}
272
273
274
275////////////////////////////////////////////////////////////////////////////////
276/// Print name of context
277
278void RooAbsGenContext::printName(ostream& os) const
279{
280 os << GetName() ;
281}
282
283
284
285////////////////////////////////////////////////////////////////////////////////
286/// Print title of context
287
288void RooAbsGenContext::printTitle(ostream& os) const
289{
290 os << GetTitle() ;
291}
292
293
294
295////////////////////////////////////////////////////////////////////////////////
296/// Print class name of context
297
298void RooAbsGenContext::printClassName(ostream& os) const
299{
300 os << IsA()->GetName() ;
301}
302
303
304
305////////////////////////////////////////////////////////////////////////////////
306/// Print arguments of context, i.e. the observables being generated in this context
307
308void RooAbsGenContext::printArgs(ostream& os) const
309{
310 os << "[ " ;
312 RooAbsArg* arg ;
314 while((arg=(RooAbsArg*)iter->Next())) {
315 if (first) {
316 first=kFALSE ;
317 } else {
318 os << "," ;
319 }
320 os << arg->GetName() ;
321 }
322 os << "]" ;
323 delete iter ;
324}
325
326
327
328////////////////////////////////////////////////////////////////////////////////
329/// Interface for multi-line printing
330
331void RooAbsGenContext::printMultiline(ostream &/*os*/, Int_t /*contents*/, Bool_t /*verbose*/, TString /*indent*/) const
332{
333}
334
335
336
337
338////////////////////////////////////////////////////////////////////////////////
339/// Set the traversal order of prototype data to that in the lookup tables
340/// passed as argument. The LUT must be an array of integers with the same
341/// size as the number of entries in the prototype dataset and must contain
342/// integer values in the range [0,Nevt-1]
343
345{
346 // Delete any previous lookup table
347 if (_protoOrder) {
348 delete[] _protoOrder ;
349 _protoOrder = 0 ;
350 }
351
352 // Copy new lookup table if provided and needed
353 if (lut && _prototype) {
355 _protoOrder = new Int_t[n] ;
356 Int_t i ;
357 for (i=0 ; i<n ; i++) {
358 _protoOrder[i] = lut[i] ;
359 }
360 }
361}
362
363
364
365
366////////////////////////////////////////////////////////////////////////////////
367/// Rescale existing output buffer with given ratio
368
370{
371
372 Int_t nOrig = _genData->numEntries() ;
373 Int_t nTarg = Int_t(nOrig*ratio+0.5) ;
374 RooDataSet* trimmedData = (RooDataSet*) _genData->reduce(RooFit::EventRange(0,nTarg)) ;
375
376 cxcoutD(Generation) << "RooGenContext::resampleData*( existing production trimmed from " << nOrig << " to " << trimmedData->numEntries() << " events" << endl ;
377
378 delete _genData ;
379 _genData = trimmedData ;
380
381 if (_prototype) {
382 // Push back proto index by trimmed amount to force recycling of the
383 // proto entries that were trimmed away
384 _nextProtoIndex -= (nOrig-nTarg) ;
385 while (_nextProtoIndex<0) {
387 }
388 }
389
390}
391
392
393
394
395////////////////////////////////////////////////////////////////////////////////
396/// Define default contents when printing
397
399{
400 return kName|kClassName|kValue ;
401}
402
403
404
405////////////////////////////////////////////////////////////////////////////////
406/// Define default print style
407
409{
410 if (opt && TString(opt).Contains("v")) {
411 return kVerbose ;
412 }
413 return kStandard ;
414}
#define coutI(a)
Definition: RooMsgService.h:30
#define cxcoutI(a)
Definition: RooMsgService.h:85
#define cxcoutD(a)
Definition: RooMsgService.h:81
#define coutE(a)
Definition: RooMsgService.h:33
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:375
char name[80]
Definition: TGX11.cxx:110
const char * proto
Definition: civetweb.c:17493
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:78
Bool_t recursiveCheckObservables(const RooArgSet *nset) const
Recursively call checkObservables on all nodes in the expression tree.
Definition: RooAbsArg.cxx:809
virtual Bool_t add(const RooAbsArg &var, Bool_t silent=kFALSE)
Add the specified argument to list.
Bool_t contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
virtual RooAbsArg * addClone(const RooAbsArg &var, Bool_t silent=kFALSE)
Add a clone of the specified argument to list.
void assign(const RooAbsCollection &other) const
Sets the value, cache and constant attribute of any argument in our set that also appears in the othe...
TIterator * createIterator(Bool_t dir=kIterForward) const
TIterator-style iteration over contained elements.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Definition: RooAbsData.cxx:381
RooAbsData * reduce(const RooCmdArg &arg1, 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())
Create a reduced copy of this dataset.
Definition: RooAbsData.cxx:456
void setDirtyProp(Bool_t flag)
Control propagation of dirty flags from observables in dataset.
Definition: RooAbsData.cxx:436
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
virtual RooDataSet * createDataSet(const char *name, const char *title, const RooArgSet &obs)
Create an empty dataset to hold the events that will be generated.
void printMultiline(std::ostream &os, Int_t contents, Bool_t verbose=kFALSE, TString indent="") const override
Interface for multi-line printing.
RooAbsPdf::ExtendMode _extendMode
Extended mode capabilities of p.d.f.
Bool_t isValid() const
StyleOption defaultPrintStyle(Option_t *opt) const override
Define default print style.
Int_t defaultPrintContents(Option_t *opt) const override
Define default contents when printing.
virtual void attach(const RooArgSet &params)
Interface to attach given parameters to object in this context.
RooDataSet * _genData
! Data being generated
void printClassName(std::ostream &os) const override
Print class name of context.
void printName(std::ostream &os) const override
Print name of context.
virtual void initGenerator(const RooArgSet &theEvent)
Interface function to initialize context for generation for given set of observables.
RooArgSet _theEvent
Pointer to observable event being generated.
void Print(Option_t *options=0) const override
Print TNamed name and title.
~RooAbsGenContext() override
Destructor.
const RooDataSet * _prototype
Pointer to prototype dataset.
Bool_t _isValid
Is context in valid state?
TClass * IsA() const override
Int_t * _protoOrder
LUT with traversal order of prototype data.
TString _normRange
Normalization range of pdf.
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...
void printArgs(std::ostream &os) const override
Print arguments of context, i.e. the observables being generated in this context.
UInt_t _expectedEvents
Number of expected events from extended p.d.f.
Int_t _nextProtoIndex
Next prototype event to load according to LUT.
RooAbsGenContext(const RooAbsPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=0, Bool_t _verbose=kFALSE)
Constructor.
void resampleData(Double_t &ratio)
Rescale existing output buffer with given ratio.
RooArgSet _protoVars
Prototype observables.
void printTitle(std::ostream &os) const override
Print title of context.
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)=0
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
Bool_t _verbose
Verbose messaging?
Bool_t canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition: RooAbsPdf.h:263
@ CanNotBeExtended
Definition: RooAbsPdf.h:257
const char * normRange() const
Definition: RooAbsPdf.h:292
virtual Double_t expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Definition: RooAbsPdf.cxx:3231
virtual ExtendMode extendMode() const
Returns ability of PDF to provide extended likelihood terms.
Definition: RooAbsPdf.h:261
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:180
Bool_t isInRange(const char *rangeSpec)
Definition: RooArgSet.cxx:623
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:55
const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
virtual void addFast(const RooArgSet &row, Double_t weight=1.0, Double_t weightError=0)
Add a data point, with its coordinates specified in the 'data' argset, to the data set.
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition: RooRandom.cxx:51
Iterator abstract base class.
Definition: TIterator.h:30
virtual TObject * Next()=0
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition: TNamed.h:47
const char * GetTitle() const override
Returns title of object.
Definition: TNamed.h:48
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition: TObject.cxx:130
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:402
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
const char * Data() const
Definition: TString.h:369
TString & Prepend(const char *cs)
Definition: TString.h:661
RooCmdArg EventRange(Int_t nStart, Int_t nStop)
const Int_t n
Definition: legend1.C:16
@ Generation
Definition: RooGlobalFunc.h:63
@ InputArguments
Definition: RooGlobalFunc.h:64
Definition: first.py:1
static void output()