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