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 "RooAbsGenContext.h"
31#include "RooRandom.h"
32#include "RooAbsPdf.h"
33#include "RooDataSet.h"
34#include "RooMsgService.h"
35#include "RooGlobalFunc.h"
36
37#include "Riostream.h"
38
39
40using namespace std;
41
43;
44
45
46////////////////////////////////////////////////////////////////////////////////
47/// Constructor
48
50 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
51 TNamed(model),
52 _prototype(prototype),
53 _isValid(true),
54 _verbose(verbose),
55 _genData(0)
56{
57 // Check PDF dependents
58 if (model.recursiveCheckObservables(&vars)) {
59 coutE(Generation) << "RooAbsGenContext::ctor: Error in PDF dependents" << endl ;
60 _isValid = false ;
61 return ;
62 }
63
64 // Make a snapshot of the generated variables that we can overwrite.
65 vars.snapshot(_theEvent, false);
66
67 // Analyze the prototype dataset, if one is specified
69 if(0 != _prototype) {
70 for (RooAbsArg const* proto : *_prototype->get()) {
71 // is this variable being generated or taken from the prototype?
72 if(!_theEvent.contains(*proto)) {
75 }
76 }
77 }
78
79 // Add auxiliary protovars to _protoVars, if provided
80 if (auxProto) {
81 _protoVars.add(*auxProto) ;
82 _theEvent.addClone(*auxProto);
83 }
84
85 // Remember the default number of events to generate when no prototype dataset is provided.
86 _extendMode = model.extendMode() ;
87 if (model.canBeExtended()) {
89 } else {
91 }
92
93 // Save normalization range
94 if (model.normRange()) {
95 _normRange = model.normRange() ;
96 }
97}
98
99
100
101////////////////////////////////////////////////////////////////////////////////
102/// Interface to attach given parameters to object in this context
103
104void RooAbsGenContext::attach(const RooArgSet& /*params*/)
105{
106}
107
108
109
110////////////////////////////////////////////////////////////////////////////////
111/// Create an empty dataset to hold the events that will be generated
112
113RooDataSet* RooAbsGenContext::createDataSet(const char* name, const char* title, const RooArgSet& obs)
114{
115 RooDataSet* ret = new RooDataSet(name, title, obs);
116 ret->setDirtyProp(false) ;
117 return ret ;
118}
119
120
121////////////////////////////////////////////////////////////////////////////////
122/// Generate the specified number of events with nEvents>0 and
123/// and return a dataset containing the generated events. With nEvents<=0,
124/// generate the number of events in the prototype dataset, if available,
125/// or else the expected number of events, if non-zero.
126/// If extendedMode = true generate according to a Poisson(nEvents)
127/// The returned dataset belongs to the caller. Return zero in case of an error.
128/// Generation of individual events is delegated to a virtual generateEvent()
129/// method. A virtual initGenerator() method is also called just before the
130/// first call to generateEvent().
131
132RooDataSet *RooAbsGenContext::generate(double nEvents, bool skipInit, bool extendedMode)
133{
134 if(!isValid()) {
135 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
136 return 0;
137 }
138
139 // Calculate the expected number of events if necessary
140 if(nEvents <= 0) {
141 if(_prototype) {
142 nEvents= (Int_t)_prototype->numEntries();
143 }
144 else {
146 coutE(Generation) << ClassName() << "::" << GetName()
147 << ":generate: PDF not extendable: cannot calculate expected number of events" << endl;
148 return 0;
149 }
150 nEvents= _expectedEvents;
151 }
152 if(nEvents <= 0) {
153 coutE(Generation) << ClassName() << "::" << GetName()
154 << ":generate: cannot calculate expected number of events" << endl;
155 return 0;
156 }
157 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
158 << nEvents << " events" << endl;
159
160 }
161
162 if (extendedMode) {
163 double nExpEvents = nEvents;
164 nEvents = RooRandom::randomGenerator()->Poisson(nEvents) ;
165 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
166 << GetName() << "::expectedEvents() = " << nExpEvents << endl ;
167 }
168
169 // check that any prototype dataset still defines the variables we need
170 // (this is necessary since we never make a private clone, for efficiency)
171 if(_prototype) {
172 const RooArgSet *vars= _prototype->get();
173 bool ok(true);
174 for (RooAbsArg * arg : _protoVars) {
175 if(vars->contains(*arg)) continue;
176 coutE(InputArguments) << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
177 << arg->GetName() << "\"" << endl;
178
179 // WVE disable this for the moment
180 // ok= false;
181 }
182 // coverity[DEADCODE]
183 if(!ok) return 0;
184 }
185
186 if (_verbose) Print("v") ;
187
188 // create a new dataset
189 TString name(GetName()),title(GetTitle());
190 name.Append("Data");
191 title.Prepend("Generated From ");
192
193 // WVE need specialization here for simultaneous pdfs
194 _genData = createDataSet(name.Data(), title.Data(), _theEvent);
195
196 // Perform any subclass implementation-specific initialization
197 // Can be skipped if this is a rerun with an identical configuration
198 if (!skipInit) {
200 }
201
202 // Loop over the events to generate
203 Int_t evt(0) ;
204 while(_genData->numEntries()<nEvents) {
205
206 // first, load values from the prototype dataset, if one was provided
207 if(0 != _prototype) {
209
210 Int_t actualProtoIdx = !_protoOrder.empty() ? _protoOrder[_nextProtoIndex] : _nextProtoIndex ;
211
212 const RooArgSet *subEvent= _prototype->get(actualProtoIdx);
214 if(0 != subEvent) {
215 _theEvent.assign(*subEvent);
216 }
217 else {
218 coutE(Generation) << ClassName() << "::" << GetName() << ":generate: cannot load event "
219 << actualProtoIdx << " from prototype dataset" << endl;
220 return 0;
221 }
222 }
223
224 // delegate the generation of the rest of this event to our subclass implementation
226
227
228 // WVE add check that event is in normRange
230 continue ;
231 }
232
234 evt++ ;
235 }
236
238 _genData = 0 ;
239 output->setDirtyProp(true) ;
240
241 return output;
242}
243
244
245
246////////////////////////////////////////////////////////////////////////////////
247/// Interface function to initialize context for generation for given
248/// set of observables
249
251{
252}
253
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// Print name of context
258
259void RooAbsGenContext::printName(ostream& os) const
260{
261 os << GetName() ;
262}
263
264
265
266////////////////////////////////////////////////////////////////////////////////
267/// Print title of context
268
269void RooAbsGenContext::printTitle(ostream& os) const
270{
271 os << GetTitle() ;
272}
273
274
275
276////////////////////////////////////////////////////////////////////////////////
277/// Print class name of context
278
279void RooAbsGenContext::printClassName(ostream& os) const
280{
281 os << ClassName() ;
282}
283
284
285
286////////////////////////////////////////////////////////////////////////////////
287/// Print arguments of context, i.e. the observables being generated in this context
288
289void RooAbsGenContext::printArgs(ostream& os) const
290{
291 os << "[ " ;
292 bool first(true) ;
293 for (RooAbsArg * arg : _theEvent) {
294 if (first) {
295 first=false ;
296 } else {
297 os << "," ;
298 }
299 os << arg->GetName() ;
300 }
301 os << "]" ;
302}
303
304
305
306////////////////////////////////////////////////////////////////////////////////
307/// Interface for multi-line printing
308
309void RooAbsGenContext::printMultiline(ostream &/*os*/, Int_t /*contents*/, bool /*verbose*/, TString /*indent*/) const
310{
311}
312
313
314
315
316////////////////////////////////////////////////////////////////////////////////
317/// Set the traversal order of prototype data to that in the lookup tables
318/// passed as argument. The LUT must be an array of integers with the same
319/// size as the number of entries in the prototype dataset and must contain
320/// integer values in the range [0,Nevt-1]
321
323{
324 // Copy new lookup table if provided and needed
325 if (lut && _prototype) {
327 _protoOrder.resize(n);
328 Int_t i ;
329 for (i=0 ; i<n ; i++) {
330 _protoOrder[i] = lut[i] ;
331 }
332 }
333}
334
335
336
337
338////////////////////////////////////////////////////////////////////////////////
339/// Rescale existing output buffer with given ratio
340
342{
343
344 Int_t nOrig = _genData->numEntries() ;
345 Int_t nTarg = Int_t(nOrig*ratio+0.5) ;
346 RooDataSet* trimmedData = (RooDataSet*) _genData->reduce(RooFit::EventRange(0,nTarg)) ;
347
348 cxcoutD(Generation) << "RooGenContext::resampleData*( existing production trimmed from " << nOrig << " to " << trimmedData->numEntries() << " events" << endl ;
349
350 delete _genData ;
351 _genData = trimmedData ;
352
353 if (_prototype) {
354 // Push back proto index by trimmed amount to force recycling of the
355 // proto entries that were trimmed away
356 _nextProtoIndex -= (nOrig-nTarg) ;
357 while (_nextProtoIndex<0) {
359 }
360 }
361
362}
363
364
365
366
367////////////////////////////////////////////////////////////////////////////////
368/// Define default contents when printing
369
371{
372 return kName|kClassName|kValue ;
373}
374
375
376
377////////////////////////////////////////////////////////////////////////////////
378/// Define default print style
379
381{
382 if (opt && TString(opt).Contains("v")) {
383 return kVerbose ;
384 }
385 return kStandard ;
386}
#define coutI(a)
Definition: RooMsgService.h:34
#define cxcoutI(a)
Definition: RooMsgService.h:89
#define cxcoutD(a)
Definition: RooMsgService.h:85
#define coutE(a)
Definition: RooMsgService.h:37
int Int_t
Definition: RtypesCore.h:45
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:17502
RooAbsArg is the common abstract base class for objects that represent a value and a "shape" in RooFi...
Definition: RooAbsArg.h:71
bool recursiveCheckObservables(const RooArgSet *nset) const
Recursively call checkObservables on all nodes in the expression tree.
Definition: RooAbsArg.cxx:781
bool contains(const RooAbsArg &var) const
Check if collection contains an argument with the same name as var.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add 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...
virtual RooAbsArg * addClone(const RooAbsArg &var, bool silent=false)
Add a clone of the specified argument to list.
void setDirtyProp(bool flag)
Control propagation of dirty flags from observables in dataset.
Definition: RooAbsData.cxx:433
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
Definition: RooAbsData.cxx:378
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:453
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.
std::vector< Int_t > _protoOrder
LUT with traversal order of prototype data.
RooAbsPdf::ExtendMode _extendMode
Extended mode capabilities of p.d.f.
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
virtual RooDataSet * generate(double nEvents=0, bool skipInit=false, bool extendedMode=false)
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
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.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for multi-line printing.
const RooDataSet * _prototype
Pointer to prototype dataset.
RooAbsGenContext(const RooAbsPdf &model, const RooArgSet &vars, const RooDataSet *prototype=0, const RooArgSet *auxProto=nullptr, bool _verbose=false)
Constructor.
TString _normRange
Normalization range of pdf.
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.
RooArgSet _protoVars
Prototype observables.
void printTitle(std::ostream &os) const override
Print title of context.
virtual void generateEvent(RooArgSet &theEvent, Int_t remaining)=0
bool _verbose
Verbose messaging?
bool _isValid
Is context in valid state?
bool isValid() const
virtual void setProtoDataOrder(Int_t *lut)
Set the traversal order of prototype data to that in the lookup tables passed as argument.
void resampleData(double &ratio)
Rescale existing output buffer with given ratio.
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
Definition: RooAbsPdf.cxx:3195
bool 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:293
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:56
bool isInRange(const char *rangeSpec)
Definition: RooArgSet.cxx:619
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition: RooArgSet.h:179
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 weight=1.0, double weightError=0.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
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()