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