Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
22Abstract 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 <ostream>
38
39using std::ostream;
40
41
42
43////////////////////////////////////////////////////////////////////////////////
44/// Constructor
45
47 const RooDataSet *prototype, const RooArgSet* auxProto, bool verbose) :
48 TNamed(model),
49 _prototype(prototype),
50 _isValid(true),
51 _verbose(verbose)
52{
53 // Check PDF dependents
54 if (model.recursiveCheckObservables(&vars)) {
55 coutE(Generation) << "RooAbsGenContext::ctor: Error in PDF dependents" << std::endl ;
56 _isValid = false ;
57 return ;
58 }
59
60 // Make a snapshot of the generated variables that we can overwrite.
61 vars.snapshot(_theEvent, false);
62
63 // Analyze the prototype dataset, if one is specified
65 if(nullptr != _prototype) {
66 for (RooAbsArg const* proto : *_prototype->get()) {
67 // is this variable being generated or taken from the prototype?
68 if(!_theEvent.contains(*proto)) {
71 }
72 }
73 }
74
75 // Add auxiliary protovars to _protoVars, if provided
76 if (auxProto) {
79 }
80
81 // Remember the default number of events to generate when no prototype dataset is provided.
82 _extendMode = model.extendMode() ;
83 if (model.canBeExtended()) {
84 _expectedEvents= (Int_t)(model.expectedEvents(&_theEvent) + 0.5);
85 } else {
87 }
88
89 // Save normalization range
90 if (model.normRange()) {
91 _normRange = model.normRange() ;
92 }
93}
94
95
96
97////////////////////////////////////////////////////////////////////////////////
98/// Interface to attach given parameters to object in this context
99
100void RooAbsGenContext::attach(const RooArgSet& /*params*/)
101{
102}
103
104
105
106////////////////////////////////////////////////////////////////////////////////
107/// Create an empty dataset to hold the events that will be generated
108
109RooDataSet* RooAbsGenContext::createDataSet(const char* name, const char* title, const RooArgSet& obs)
110{
111 RooDataSet* ret = new RooDataSet(name, title, obs);
112 ret->setDirtyProp(false) ;
113 return ret ;
114}
115
116
117////////////////////////////////////////////////////////////////////////////////
118/// Generate the specified number of events with nEvents>0 and
119/// and return a dataset containing the generated events. With nEvents<=0,
120/// generate the number of events in the prototype dataset, if available,
121/// or else the expected number of events, if non-zero.
122/// If extendedMode = true generate according to a Poisson(nEvents)
123/// The returned dataset belongs to the caller. Return zero in case of an error.
124/// Generation of individual events is delegated to a virtual generateEvent()
125/// method. A virtual initGenerator() method is also called just before the
126/// first call to generateEvent().
127
129{
130 if(!isValid()) {
131 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << std::endl;
132 return nullptr;
133 }
134
135 // Calculate the expected number of events if necessary
136 if(nEvents <= 0) {
137 if(_prototype) {
138 nEvents= (Int_t)_prototype->numEntries();
139 }
140 else {
142 coutE(Generation) << ClassName() << "::" << GetName()
143 << ":generate: PDF not extendable: cannot calculate expected number of events" << std::endl;
144 return nullptr;
145 }
146 nEvents= _expectedEvents;
147 }
148 if(nEvents <= 0) {
149 coutE(Generation) << ClassName() << "::" << GetName()
150 << ":generate: cannot calculate expected number of events" << std::endl;
151 return nullptr;
152 }
153 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
154 << nEvents << " events" << std::endl;
155
156 }
157
158 if (extendedMode) {
159 double nExpEvents = nEvents;
160 nEvents = RooRandom::randomGenerator()->Poisson(nEvents) ;
161 cxcoutI(Generation) << " Extended mode active, number of events generated (" << nEvents << ") is Poisson fluctuation on "
162 << GetName() << "::expectedEvents() = " << nExpEvents << std::endl ;
163 }
164
165 // check that any prototype dataset still defines the variables we need
166 // (this is necessary since we never make a private clone, for efficiency)
167 if(_prototype) {
168 const RooArgSet *vars= _prototype->get();
169 bool ok(true);
170 for (RooAbsArg * arg : _protoVars) {
171 if(vars->contains(*arg)) continue;
172 coutE(InputArguments) << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
173 << arg->GetName() << "\"" << std::endl;
174
175 // WVE disable this for the moment
176 // ok= false;
177 }
178 // coverity[DEADCODE]
179 if(!ok) return nullptr;
180 }
181
182 if (_verbose) Print("v") ;
183
184 // create a new dataset
186 TString title(GetTitle());
187 name.Append("Data");
188 title.Prepend("Generated From ");
189
190 // WVE need specialization here for simultaneous pdfs
191 _genData = createDataSet(name.Data(), title.Data(), _theEvent);
192
193 // Perform any subclass implementation-specific initialization
194 // Can be skipped if this is a rerun with an identical configuration
195 if (!skipInit) {
197 }
198
199 // Loop over the events to generate
200 while(_genData->numEntries()<nEvents) {
201
202 // first, load values from the prototype dataset, if one was provided
203 if(nullptr != _prototype) {
204 if(_nextProtoIndex >= _prototype->numEntries()) _nextProtoIndex= 0;
205
207
210 if(nullptr != subEvent) {
212 }
213 else {
214 coutE(Generation) << ClassName() << "::" << GetName() << ":generate: cannot load event "
215 << actualProtoIdx << " from prototype dataset" << std::endl;
216 return nullptr;
217 }
218 }
219
220 // delegate the generation of the rest of this event to our subclass implementation
222
223
224 // WVE add check that event is in normRange
226 continue ;
227 }
228
230 }
231
232 RooDataSet* output = _genData ;
233 _genData = nullptr ;
234 output->setDirtyProp(true) ;
235
236 return output;
237}
238
239
240
241////////////////////////////////////////////////////////////////////////////////
242/// Interface function to initialize context for generation for given
243/// set of observables
244
248
249
250
251////////////////////////////////////////////////////////////////////////////////
252/// Print name of context
253
254void RooAbsGenContext::printName(ostream& os) const
255{
256 os << GetName() ;
257}
258
259
260
261////////////////////////////////////////////////////////////////////////////////
262/// Print title of context
263
264void RooAbsGenContext::printTitle(ostream& os) const
265{
266 os << GetTitle() ;
267}
268
269
270
271////////////////////////////////////////////////////////////////////////////////
272/// Print class name of context
273
274void RooAbsGenContext::printClassName(ostream& os) const
275{
276 os << ClassName() ;
277}
278
279
280
281////////////////////////////////////////////////////////////////////////////////
282/// Print arguments of context, i.e. the observables being generated in this context
283
284void RooAbsGenContext::printArgs(ostream& os) const
285{
286 os << "[ " ;
287 bool first(true) ;
288 for (RooAbsArg * arg : _theEvent) {
289 if (first) {
290 first=false ;
291 } else {
292 os << "," ;
293 }
294 os << arg->GetName() ;
295 }
296 os << "]" ;
297}
298
299
300
301////////////////////////////////////////////////////////////////////////////////
302/// Interface for multi-line printing
303
304void RooAbsGenContext::printMultiline(ostream &/*os*/, Int_t /*contents*/, bool /*verbose*/, TString /*indent*/) const
305{
306}
307
308
309
310
311////////////////////////////////////////////////////////////////////////////////
312/// Set the traversal order of prototype data to that in the lookup tables
313/// passed as argument. The LUT must be an array of integers with the same
314/// size as the number of entries in the prototype dataset and must contain
315/// integer values in the range [0,Nevt-1]
316
318{
319 // Copy new lookup table if provided and needed
320 if (lut && _prototype) {
321 Int_t n = _prototype->numEntries() ;
322 _protoOrder.resize(n);
323 Int_t i ;
324 for (i=0 ; i<n ; i++) {
325 _protoOrder[i] = lut[i] ;
326 }
327 }
328}
329
330
331
332
333////////////////////////////////////////////////////////////////////////////////
334/// Rescale existing output buffer with given ratio
335
337{
338
340 Int_t nTarg = Int_t(nOrig*ratio+0.5) ;
341 std::unique_ptr<RooAbsData> trimmedData{_genData->reduce(RooFit::EventRange(0,nTarg))};
342
343 cxcoutD(Generation) << "RooGenContext::resampleData*( existing production trimmed from " << nOrig << " to " << trimmedData->numEntries() << " events" << std::endl ;
344
345 delete _genData ;
346 _genData = static_cast<RooDataSet*>(trimmedData.release());
347
348 if (_prototype) {
349 // Push back proto index by trimmed amount to force recycling of the
350 // proto entries that were trimmed away
352 while (_nextProtoIndex<0) {
353 _nextProtoIndex += _prototype->numEntries() ;
354 }
355 }
356
357}
358
359
360
361
362////////////////////////////////////////////////////////////////////////////////
363/// Define default contents when printing
364
369
370
371
372////////////////////////////////////////////////////////////////////////////////
373/// Define default print style
374
376{
377 if (opt && TString(opt).Contains("v")) {
378 return kVerbose ;
379 }
380 return kStandard ;
381}
#define coutI(a)
#define cxcoutI(a)
#define cxcoutD(a)
#define coutE(a)
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
const char Option_t
Option string (const char)
Definition RtypesCore.h:81
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
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:76
bool contains(const char *name) const
Check if collection contains an argument with a specific name.
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.
RooFit::OwningPtr< RooAbsData > reduce(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 a reduced copy of this dataset.
virtual Int_t numEntries() const
Return number of entries in dataset, i.e., count unweighted entries.
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.
RooAbsGenContext(const RooAbsPdf &model, const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool _verbose=false)
Constructor.
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.
void Print(Option_t *options=nullptr) const override
This method must be overridden when a class wants to print itself.
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.
Abstract interface for all probability density functions.
Definition RooAbsPdf.h:32
@ CanNotBeExtended
Definition RooAbsPdf.h:208
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:24
bool isInRange(const char *rangeSpec)
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:159
Container class to hold unbinned data.
Definition RooDataSet.h:32
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:47
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:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:225
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
const char * Data() const
Definition TString.h:385
TString & Prepend(const char *cs)
Definition TString.h:683
RooCmdArg EventRange(Int_t nStart, Int_t nStop)
const Int_t n
Definition legend1.C:16