Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooBinnedGenContext.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 RooBinnedGenContext.cxx
19\class RooBinnedGenContext
20\ingroup Roofitcore
21
22RooBinnedGenContext is an efficient implementation of the
23generator context specific for binned pdfs.
24**/
25
26#include "Riostream.h"
27
28
29#include "RooMsgService.h"
30#include "RooBinnedGenContext.h"
31#include "RooAbsPdf.h"
32#include "RooRealVar.h"
33#include "RooDataHist.h"
34#include "RooDataSet.h"
35#include "RooRandom.h"
36
37using namespace std;
38
40;
41
42
43////////////////////////////////////////////////////////////////////////////////
44/// Constructor
45
47 const RooDataSet *prototype, const RooArgSet* auxProto,
48 bool verbose) :
49 RooAbsGenContext(model,vars,prototype,auxProto,verbose)
50{
51 cxcoutI(Generation) << "RooBinnedGenContext::ctor() setting up event special generator context for sum p.d.f. " << model.GetName()
52 << " for generation of observable(s) " << vars ;
53 if (prototype) ccxcoutI(Generation) << " with prototype data for " << *prototype->get() ;
54 if (auxProto && auxProto->getSize()>0) ccxcoutI(Generation) << " with auxiliary prototypes " << *auxProto ;
55 ccxcoutI(Generation) << endl ;
56
57 // Constructor. Build an array of generator contexts for each product component PDF
58 RooArgSet(model).snapshot(_pdfSet, true) ;
59 _pdf = (RooAbsPdf*) _pdfSet.find(model.GetName()) ;
61
62 // Fix normalization set of this RooAddPdf
63 if (prototype)
64 {
65 RooArgSet coefNSet(vars) ;
66 coefNSet.add(*prototype->get()) ;
67 _pdf->fixAddCoefNormalization(coefNSet) ;
68 }
69
71 _vars = std::unique_ptr<RooArgSet>{_pdf->getObservables(vars)};
72
73 // Create empty RooDataHist
74 _hist = std::make_unique<RooDataHist>("genData","genData",*_vars);
75
76 _expectedData = false ;
77}
78
79
81
82
83////////////////////////////////////////////////////////////////////////////////
84/// Attach given set of variables to internal p.d.f. clone
85
87{
89}
90
91
92
93////////////////////////////////////////////////////////////////////////////////
94/// One-time initialization of generator contex. Attach theEvent
95/// to internal p.d.f clone and forward initialization call to
96/// the component generators
97
99{
100 _pdf->recursiveRedirectServers(theEvent) ;
101
102}
103
104
105////////////////////////////////////////////////////////////////////////////////
106
108{
109 _expectedData = flag ;
110}
111
112
113////////////////////////////////////////////////////////////////////////////////
114
115RooDataSet *RooBinnedGenContext::generate(double nEvt, bool /*skipInit*/, bool extended)
116{
117 // Scale to number of events and introduce Poisson fluctuations
118 _hist->reset() ;
119
120 double nEvents = nEvt ;
121
122 if (nEvents<=0) {
123 if (!_pdf->canBeExtended()) {
124 coutE(InputArguments) << "RooAbsPdf::generateBinned(" << GetName()
125 << ") ERROR: No event count provided and p.d.f does not provide expected number of events" << endl ;
126 return 0 ;
127 } else {
128 // Don't round in expectedData mode
129 if (_expectedData || extended) {
130 nEvents = _pdf->expectedEvents(_vars.get());
131 } else {
132 nEvents = Int_t(_pdf->expectedEvents(_vars.get())+0.5) ;
133 }
134 }
135 }
136
137 // Sample p.d.f. distribution
138 _pdf->fillDataHist(_hist.get(),_vars.get(),1,true) ;
139
140 // Output container
141 RooDataSet* wudata = new RooDataSet("wu","wu",*_vars,RooFit::WeightVar()) ;
142
143 vector<int> histOut(_hist->numEntries()) ;
144 double histMax(-1) ;
145 Int_t histOutSum(0) ;
146 for (int i=0 ; i<_hist->numEntries() ; i++) {
147 _hist->get(i) ;
148 if (_expectedData) {
149
150 // Expected data, multiply p.d.f by nEvents
151 double w=_hist->weight()*nEvents ;
152 wudata->add(*_hist->get(),w) ;
153
154 } else if (extended) {
155
156 // Extended mode, set contents to Poisson(pdf*nEvents)
157 double w = RooRandom::randomGenerator()->Poisson(_hist->weight()*nEvents) ;
158 wudata->add(*_hist->get(),w) ;
159
160 } else {
161
162 // Regular mode, fill array of weights with Poisson(pdf*nEvents), but to not fill
163 // histogram yet.
164 if (_hist->weight()>histMax) {
165 histMax = _hist->weight() ;
166 }
167 histOut[i] = RooRandom::randomGenerator()->Poisson(_hist->weight()*nEvents) ;
168 histOutSum += histOut[i] ;
169 }
170 }
171
172
173 if (!_expectedData && !extended) {
174
175 // Second pass for regular mode - Trim/Extend dataset to exact number of entries
176
177 // Calculate difference between what is generated so far and what is requested
178 Int_t nEvtExtra = std::abs(Int_t(nEvents)-histOutSum) ;
179 Int_t wgt = (histOutSum>nEvents) ? -1 : 1 ;
180
181 // Perform simple binned accept/reject procedure to get to exact event count
182 while(nEvtExtra>0) {
183
184 Int_t ibinRand = RooRandom::randomGenerator()->Integer(_hist->numEntries()) ;
185 _hist->get(ibinRand) ;
186 double ranY = RooRandom::randomGenerator()->Uniform(histMax) ;
187
188 if (ranY<_hist->weight()) {
189 if (wgt==1) {
190 histOut[ibinRand]++ ;
191 } else {
192 // If weight is negative, prior bin content must be at least 1
193 if (histOut[ibinRand]>0) {
194 histOut[ibinRand]-- ;
195 } else {
196 continue ;
197 }
198 }
199 nEvtExtra-- ;
200 }
201 }
202
203 // Transfer working array to histogram
204 for (int i=0 ; i<_hist->numEntries() ; i++) {
205 _hist->get(i) ;
206 wudata->add(*_hist->get(),histOut[i]) ;
207 }
208
209 }
210
211 return wudata ;
212
213}
214
215
216
217////////////////////////////////////////////////////////////////////////////////
218/// this method is not implemented for this context
219
221{
222 assert(0) ;
223}
224
225
226
227////////////////////////////////////////////////////////////////////////////////
228/// Print the details of the context
229
230void RooBinnedGenContext::printMultiline(ostream &os, Int_t content, bool verbose, TString indent) const
231{
232 RooAbsGenContext::printMultiline(os,content,verbose,indent) ;
233 os << indent << "--- RooBinnedGenContext ---" << endl ;
234 os << indent << "Using PDF ";
236}
#define cxcoutI(a)
#define coutE(a)
#define ccxcoutI(a)
int Int_t
Definition RtypesCore.h:45
#define ClassImp(name)
Definition Rtypes.h:377
static void indent(ostringstream &buf, int indent_level)
bool recursiveRedirectServers(const RooAbsCollection &newServerList, bool mustReplaceAll=false, bool nameChange=false, bool recurseInNewSet=true)
Recursively replace all servers with the new servers in newSet.
void setOperMode(OperMode mode, bool recurseADirty=true)
Set the operation mode of this node.
RooFit::OwningPtr< RooArgSet > getObservables(const RooArgSet &set, bool valueOnly=true) const
Given a set of possible observables, return the observables that this PDF depends on.
Int_t getSize() const
Return the number of elements in the collection.
virtual bool add(const RooAbsArg &var, bool silent=false)
Add the specified argument to list.
RooAbsArg * find(const char *name) const
Find object with given name in list.
virtual void reset()
RooAbsGenContext is the abstract base class for generator contexts of RooAbsPdf objects.
RooArgSet _theEvent
Pointer to observable event being generated.
void printMultiline(std::ostream &os, Int_t contents, bool verbose=false, TString indent="") const override
Interface for multi-line printing.
virtual double expectedEvents(const RooArgSet *nset) const
Return expected number of events to be used in calculation of extended likelihood.
bool canBeExtended() const
If true, PDF can provide extended likelihood term.
Definition RooAbsPdf.h:278
RooDataHist * fillDataHist(RooDataHist *hist, const RooArgSet *nset, double scaleFactor, bool correctForBinVolume=false, bool showProgress=false) const
Fill a RooDataHist with values sampled from this function at the bin centers.
virtual void fixAddCoefNormalization(const RooArgSet &addNormSet=RooArgSet(), bool force=true)
Fix the interpretation of the coefficient of any RooAddPdf component in the expression tree headed by...
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooArgSet * snapshot(bool deepCopy=true) const
Use RooAbsCollection::snapshot(), but return as RooArgSet.
Definition RooArgSet.h:178
RooBinnedGenContext is an efficient implementation of the generator context specific for binned pdfs.
RooAbsPdf * _pdf
Pointer to cloned p.d.f.
~RooBinnedGenContext() override
void generateEvent(RooArgSet &theEvent, Int_t remaining) override
this method is not implemented for this context
std::unique_ptr< RooDataHist > _hist
Histogram.
void printMultiline(std::ostream &os, Int_t content, bool verbose=false, TString indent="") const override
Print the details of the context.
RooArgSet _pdfSet
Set owned all nodes of internal clone of p.d.f.
RooBinnedGenContext(const RooAbsPdf &model, const RooArgSet &vars, const RooDataSet *prototype=nullptr, const RooArgSet *auxProto=nullptr, bool _verbose=false)
Constructor.
void setExpectedData(bool) override
std::unique_ptr< RooArgSet > _vars
void initGenerator(const RooArgSet &theEvent) override
One-time initialization of generator contex.
RooDataSet * generate(double nEvents=0.0, bool skipInit=false, bool extendedMode=false) override
Generate the specified number of events with nEvents>0 and and return a dataset containing the genera...
void attach(const RooArgSet &params) override
Attach given set of variables to internal p.d.f. clone.
RooDataSet is a container class to hold unbinned data.
Definition RooDataSet.h:57
const RooArgSet * get(Int_t index) const override
Return RooArgSet with coordinates of event 'index'.
void add(const RooArgSet &row, double weight=1.0, double weightError=0.0) override
Add one ore more rows of data.
virtual void printStream(std::ostream &os, Int_t contents, StyleOption style, TString indent="") const
Print description of object on ostream, printing contents set by contents integer,...
static TRandom * randomGenerator()
Return a pointer to a singleton random-number generator implementation.
Definition RooRandom.cxx:51
const char * GetName() const override
Returns name of object.
Definition TNamed.h:47
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition TRandom.cxx:402
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition TRandom.cxx:672
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition TRandom.cxx:360
Basic string class.
Definition TString.h:139
RooCmdArg WeightVar(const char *name="weight", bool reinterpretAsWeight=false)