55 ClassImp(RooAcceptReject);
62 void RooAcceptReject::registerSampler(RooNumGenFactory& fact)
64 RooRealVar nTrial0D(
"nTrial0D",
"Number of trial samples for cat-only generation",100,0,1e9) ;
65 RooRealVar nTrial1D(
"nTrial1D",
"Number of trial samples for 1-dim generation",1000,0,1e9) ;
66 RooRealVar nTrial2D(
"nTrial2D",
"Number of trial samples for 2-dim generation",100000,0,1e9) ;
67 RooRealVar nTrial3D(
"nTrial3D",
"Number of trial samples for N-dim generation",10000000,0,1e9) ;
69 RooAcceptReject* proto =
new RooAcceptReject ;
70 fact.storeProtoSampler(proto,RooArgSet(nTrial0D,nTrial1D,nTrial2D,nTrial3D)) ;
81 RooAcceptReject::RooAcceptReject(
const RooAbsReal &func,
const RooArgSet &genVars,
const RooNumGenConfig& config, Bool_t verbose,
const RooAbsReal* maxFuncVal) :
82 RooAbsNumGenerator(func,genVars,verbose,maxFuncVal), _nextCatVar(0), _nextRealVar(0)
84 _minTrialsArray[0] =
static_cast<Int_t
>(config.getConfigSection(
"RooAcceptReject").getRealValue(
"nTrial0D")) ;
85 _minTrialsArray[1] =
static_cast<Int_t
>(config.getConfigSection(
"RooAcceptReject").getRealValue(
"nTrial1D")) ;
86 _minTrialsArray[2] =
static_cast<Int_t
>(config.getConfigSection(
"RooAcceptReject").getRealValue(
"nTrial2D")) ;
87 _minTrialsArray[3] =
static_cast<Int_t
>(config.getConfigSection(
"RooAcceptReject").getRealValue(
"nTrial3D")) ;
89 _realSampleDim = _realVars.getSize() ;
90 TIterator* iter = _catVars.createIterator() ;
93 while((cat=(RooAbsCategory*)iter->Next())) {
94 _catSampleMult *= cat->numTypes() ;
102 if(_realSampleDim > 3) {
103 _minTrials= _minTrialsArray[3]*_catSampleMult;
104 coutW(Generation) << fName <<
"::" << ClassName() <<
": WARNING: generating " << _realSampleDim
105 <<
" variables with accept-reject may not be accurate" << endl;
108 _minTrials= _minTrialsArray[_realSampleDim]*_catSampleMult;
110 if (_realSampleDim > 1) {
111 coutW(Generation) <<
"RooAcceptReject::ctor(" << fName
112 <<
") WARNING: performing accept/reject sampling on a p.d.f in "
113 << _realSampleDim <<
" dimensions without prior knowledge on maximum value "
114 <<
"of p.d.f. Determining maximum value by taking " << _minTrials
115 <<
" trial samples. If p.d.f contains sharp peaks smaller than average "
116 <<
"distance between trial sampling points these may be missed and p.d.f. "
117 <<
"may be sampled incorrectly." << endl ;
125 if (_minTrials>10000) {
126 coutW(Generation) <<
"RooAcceptReject::ctor(" << fName <<
"): WARNING: " << _minTrials <<
" trial samples requested by p.d.f for "
127 << _realSampleDim <<
"-dimensional accept/reject sampling, this may take some time" << endl ;
132 coutI(Generation) << fName <<
"::" << ClassName() <<
":" << endl
133 <<
" Initializing accept-reject generator for" << endl <<
" ";
134 _funcClone->printStream(ccoutI(Generation),kName,kSingleLine);
136 ccoutI(Generation) <<
" Function maximum provided, no trial sampling performed" << endl ;
138 ccoutI(Generation) <<
" Real sampling dimension is " << _realSampleDim << endl;
139 ccoutI(Generation) <<
" Category sampling multiplier is " << _catSampleMult << endl ;
140 ccoutI(Generation) <<
" Min sampling trials is " << _minTrials << endl;
142 if (_catVars.getSize()>0) {
143 ccoutI(Generation) <<
" Will generate category vars "<< _catVars << endl ;
145 if (_realVars.getSize()>0) {
146 ccoutI(Generation) <<
" Will generate real vars " << _realVars << endl ;
150 _nextCatVar= _catVars.createIterator();
151 _nextRealVar= _realVars.createIterator();
152 assert(0 != _nextCatVar && 0 != _nextRealVar);
166 RooAcceptReject::~RooAcceptReject()
179 const RooArgSet *RooAcceptReject::generateEvent(UInt_t remaining, Double_t& resampleRatio)
182 const RooArgSet *
event= _cache->get();
183 if(event->getSize() == 1)
return event;
191 while(_totalEvents < _minTrials) {
195 if (_cache->numEntries()>1000000) {
196 coutI(Generation) <<
"RooAcceptReject::generateEvent: resetting event cache" << endl ;
203 Double_t oldMax2(_maxFuncVal);
206 if (_maxFuncVal>oldMax2) {
207 cxcoutD(Generation) <<
"RooAcceptReject::generateEvent maxFuncVal has changed, need to resample already accepted events by factor"
208 << oldMax2 <<
"/" << _maxFuncVal <<
"=" << oldMax2/_maxFuncVal << endl ;
209 resampleRatio=oldMax2/_maxFuncVal ;
211 event= nextAcceptedEvent();
219 if(_totalEvents*_maxFuncVal <= 0) {
220 coutE(Generation) <<
"RooAcceptReject::generateEvent: cannot estimate efficiency...giving up" << endl;
224 Double_t eff= _funcSum/(_totalEvents*_maxFuncVal);
225 Long64_t extra= 1 + (Long64_t)(1.05*remaining/eff);
226 cxcoutD(Generation) <<
"RooAcceptReject::generateEvent: adding " << extra <<
" events to the cache, eff = " << eff << endl;
227 Double_t oldMax(_maxFuncVal);
230 if((_maxFuncVal > oldMax)) {
231 cxcoutD(Generation) <<
"RooAcceptReject::generateEvent: estimated function maximum increased from "
232 << oldMax <<
" to " << _maxFuncVal << endl;
233 oldMax = _maxFuncVal ;
240 if (_eventsUsed>1000000) {
247 _maxFuncVal = _funcMaxVal->getVal() ;
253 event = nextAcceptedEvent() ;
269 const RooArgSet *RooAcceptReject::nextAcceptedEvent()
271 const RooArgSet *
event = 0;
272 while((event= _cache->get(_eventsUsed))) {
275 Double_t r= RooRandom::uniform();
276 if(r*_maxFuncVal > _funcValPtr->getVal()) {
282 if(_verbose && (_eventsUsed%1000==0)) {
283 cerr <<
"RooAcceptReject: accepted event (used " << _eventsUsed <<
" of "
284 << _cache->numEntries() <<
" so far)" << endl;
298 void RooAcceptReject::addEventToCache()
301 _nextCatVar->Reset();
302 RooCategory *cat = 0;
303 while((cat= (RooCategory*)_nextCatVar->Next())) cat->randomize();
306 _nextRealVar->Reset();
307 RooRealVar *real = 0;
308 while((real= (RooRealVar*)_nextRealVar->Next())) real->randomize();
311 Double_t val= _funcClone->getVal();
312 _funcValPtr->setVal(val);
317 if(val > _maxFuncVal) _maxFuncVal= 1.05*val;
324 if (_verbose &&_totalEvents%10000==0) {
325 cerr <<
"RooAcceptReject: generated " << _totalEvents <<
" events so far." << endl ;
330 Double_t RooAcceptReject::getFuncMax()
337 while(_totalEvents < _minTrials) {
341 if (_cache->numEntries()>1000000) {
342 coutI(Generation) <<
"RooAcceptReject::getFuncMax: resetting event cache" << endl ;