00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "RooFit.h"
00031
00032 #include "TClass.h"
00033
00034 #include "RooAbsGenContext.h"
00035 #include "RooAbsGenContext.h"
00036 #include "RooAbsPdf.h"
00037 #include "RooDataSet.h"
00038 #include "RooMsgService.h"
00039 #include "RooGlobalFunc.h"
00040
00041 #include "Riostream.h"
00042
00043
00044 ClassImp(RooAbsGenContext)
00045 ;
00046
00047
00048
00049 RooAbsGenContext::RooAbsGenContext(const RooAbsPdf& model, const RooArgSet &vars,
00050 const RooDataSet *prototype, const RooArgSet* auxProto, Bool_t verbose) :
00051 TNamed(model),
00052 _prototype(prototype),
00053 _theEvent(0),
00054 _isValid(kTRUE),
00055 _verbose(verbose),
00056 _protoOrder(0),
00057 _genData(0)
00058 {
00059
00060
00061
00062 if (model.recursiveCheckObservables(&vars)) {
00063 coutE(Generation) << "RooAbsGenContext::ctor: Error in PDF dependents" << endl ;
00064 _isValid = kFALSE ;
00065 return ;
00066 }
00067
00068
00069 _theEvent= (RooArgSet*)vars.snapshot(kFALSE);
00070
00071
00072 _nextProtoIndex= 0;
00073 if(0 != _prototype) {
00074 TIterator *protoIterator= _prototype->get()->createIterator();
00075 const RooAbsArg *proto = 0;
00076 while((proto= (const RooAbsArg*)protoIterator->Next())) {
00077
00078 if(!_theEvent->contains(*proto)) {
00079 _protoVars.add(*proto);
00080 _theEvent->addClone(*proto);
00081 }
00082 }
00083 delete protoIterator;
00084 }
00085
00086
00087 if (auxProto) {
00088 _protoVars.add(*auxProto) ;
00089 _theEvent->addClone(*auxProto) ;
00090 }
00091
00092
00093 _extendMode = model.extendMode() ;
00094 if (model.canBeExtended()) {
00095 _expectedEvents= (Int_t)(model.expectedEvents(_theEvent) + 0.5);
00096 } else {
00097 _expectedEvents= 0 ;
00098 }
00099
00100
00101 if (model.normRange()) {
00102 _normRange = model.normRange() ;
00103 }
00104 }
00105
00106
00107
00108
00109 RooAbsGenContext::~RooAbsGenContext()
00110 {
00111
00112
00113 if(0 != _theEvent) delete _theEvent;
00114 if (_protoOrder) delete[] _protoOrder ;
00115 }
00116
00117
00118
00119
00120 void RooAbsGenContext::attach(const RooArgSet& )
00121 {
00122
00123 }
00124
00125
00126
00127
00128 RooDataSet *RooAbsGenContext::generate(Int_t nEvents)
00129 {
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 if(!isValid()) {
00140 coutE(Generation) << ClassName() << "::" << GetName() << ": context is not valid" << endl;
00141 return 0;
00142 }
00143
00144
00145 if(nEvents <= 0) {
00146 if(_prototype) {
00147 nEvents= (Int_t)_prototype->numEntries();
00148 }
00149 else {
00150 if (_extendMode == RooAbsPdf::CanNotBeExtended) {
00151 coutE(Generation) << ClassName() << "::" << GetName()
00152 << ":generate: PDF not extendable: cannot calculate expected number of events" << endl;
00153 return 0;
00154 }
00155 nEvents= _expectedEvents;
00156 }
00157 if(nEvents <= 0) {
00158 coutE(Generation) << ClassName() << "::" << GetName()
00159 << ":generate: cannot calculate expected number of events" << endl;
00160 return 0;
00161 }
00162 coutI(Generation) << ClassName() << "::" << GetName() << ":generate: will generate "
00163 << nEvents << " events" << endl;
00164 }
00165
00166
00167
00168 if(_prototype) {
00169 const RooArgSet *vars= _prototype->get();
00170 TIterator *iterator= _protoVars.createIterator();
00171 const RooAbsArg *arg = 0;
00172 Bool_t ok(kTRUE);
00173 while((arg= (const RooAbsArg*)iterator->Next())) {
00174 if(vars->contains(*arg)) continue;
00175 coutE(InputArguments) << ClassName() << "::" << GetName() << ":generate: prototype dataset is missing \""
00176 << arg->GetName() << "\"" << endl;
00177
00178
00179
00180 }
00181 delete iterator;
00182
00183 if(!ok) return 0;
00184 }
00185
00186 if (_verbose) Print("v") ;
00187
00188
00189 TString name(GetName()),title(GetTitle());
00190 name.Append("Data");
00191 title.Prepend("Generated From ");
00192
00193 _genData = new RooDataSet(name.Data(), title.Data(), *_theEvent);
00194
00195
00196 initGenerator(*_theEvent);
00197
00198
00199 Int_t evt(0) ;
00200 while(_genData->numEntries()<nEvents) {
00201
00202
00203 if(0 != _prototype) {
00204 if(_nextProtoIndex >= _prototype->numEntries()) _nextProtoIndex= 0;
00205
00206 Int_t actualProtoIdx = _protoOrder ? _protoOrder[_nextProtoIndex] : _nextProtoIndex ;
00207
00208 const RooArgSet *subEvent= _prototype->get(actualProtoIdx);
00209 _nextProtoIndex++;
00210 if(0 != subEvent) {
00211 *_theEvent= *subEvent;
00212 }
00213 else {
00214 coutE(Generation) << ClassName() << "::" << GetName() << ":generate: cannot load event "
00215 << actualProtoIdx << " from prototype dataset" << endl;
00216 return 0;
00217 }
00218 }
00219
00220
00221 generateEvent(*_theEvent, nEvents - _genData->numEntries());
00222
00223
00224
00225 if (_normRange.Length()>0 && !_theEvent->isInRange(_normRange.Data())) {
00226 continue ;
00227 }
00228
00229 _genData->addFast(*_theEvent);
00230 evt++ ;
00231 }
00232
00233 RooDataSet* output = _genData ;
00234 _genData = 0 ;
00235
00236 return output;
00237 }
00238
00239
00240
00241
00242 void RooAbsGenContext::initGenerator(const RooArgSet&)
00243 {
00244
00245
00246 }
00247
00248
00249
00250
00251 void RooAbsGenContext::printName(ostream& os) const
00252 {
00253
00254
00255 os << GetName() ;
00256 }
00257
00258
00259
00260
00261 void RooAbsGenContext::printTitle(ostream& os) const
00262 {
00263
00264
00265 os << GetTitle() ;
00266 }
00267
00268
00269
00270
00271 void RooAbsGenContext::printClassName(ostream& os) const
00272 {
00273
00274
00275 os << IsA()->GetName() ;
00276 }
00277
00278
00279
00280
00281 void RooAbsGenContext::printArgs(ostream& os) const
00282 {
00283
00284
00285 os << "[ " ;
00286 TIterator* iter = _theEvent->createIterator() ;
00287 RooAbsArg* arg ;
00288 Bool_t first(kTRUE) ;
00289 while((arg=(RooAbsArg*)iter->Next())) {
00290 if (first) {
00291 first=kFALSE ;
00292 } else {
00293 os << "," ;
00294 }
00295 os << arg->GetName() ;
00296 }
00297 os << "]" ;
00298 delete iter ;
00299 }
00300
00301
00302
00303
00304 void RooAbsGenContext::printMultiline(ostream &, Int_t , Bool_t , TString ) const
00305 {
00306
00307 }
00308
00309
00310
00311
00312
00313 void RooAbsGenContext::setProtoDataOrder(Int_t* lut)
00314 {
00315
00316
00317
00318
00319
00320
00321 if (_protoOrder) {
00322 delete[] _protoOrder ;
00323 _protoOrder = 0 ;
00324 }
00325
00326
00327 if (lut && _prototype) {
00328 Int_t n = _prototype->numEntries() ;
00329 _protoOrder = new Int_t[n] ;
00330 Int_t i ;
00331 for (i=0 ; i<n ; i++) {
00332 _protoOrder[i] = lut[i] ;
00333 }
00334 }
00335 }
00336
00337
00338
00339
00340
00341 void RooAbsGenContext::resampleData(Double_t& ratio)
00342 {
00343
00344
00345
00346 Int_t nOrig = _genData->numEntries() ;
00347 Int_t nTarg = Int_t(nOrig*ratio+0.5) ;
00348 RooDataSet* trimmedData = (RooDataSet*) _genData->reduce(RooFit::EventRange(0,nTarg)) ;
00349
00350 cxcoutD(Generation) << "RooGenContext::resampleData*( existing production trimmed from " << nOrig << " to " << trimmedData->numEntries() << " events" << endl ;
00351
00352 delete _genData ;
00353 _genData = trimmedData ;
00354
00355 if (_prototype) {
00356
00357
00358 _nextProtoIndex -= (nOrig-nTarg) ;
00359 while (_nextProtoIndex<0) {
00360 _nextProtoIndex += _prototype->numEntries() ;
00361 }
00362 }
00363
00364 }
00365
00366
00367
00368
00369
00370 Int_t RooAbsGenContext::defaultPrintContents(Option_t* ) const
00371 {
00372
00373 return kName|kClassName|kValue ;
00374 }
00375
00376
00377
00378
00379 RooPrintable::StyleOption RooAbsGenContext::defaultPrintStyle(Option_t* opt) const
00380 {
00381
00382 if (opt && TString(opt).Contains("v")) {
00383 return kVerbose ;
00384 }
00385 return kStandard ;
00386 }