RooMCStudy.cxx

Go to the documentation of this file.
00001 /*****************************************************************************
00002  * Project: RooFit                                                           *
00003  * Package: RooFitCore                                                       *
00004  * @(#)root/roofitcore:$Id: RooMCStudy.cxx 36274 2010-10-11 08:05:03Z wouter $
00005  * Authors:                                                                  *
00006  *   WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu       *
00007  *   DK, David Kirkby,    UC Irvine,         dkirkby@uci.edu                 *
00008  *                                                                           *
00009  * Copyright (c) 2000-2005, Regents of the University of California          *
00010  *                          and Stanford University. All rights reserved.    *
00011  *                                                                           *
00012  * Redistribution and use in source and binary forms,                        *
00013  * with or without modification, are permitted according to the terms        *
00014  * listed in LICENSE (http://roofit.sourceforge.net/license.txt)             *
00015  *****************************************************************************/
00016 
00017 //////////////////////////////////////////////////////////////////////////////
00018 //
00019 // BEGIN_HTML
00020 // RooMCStudy is a help class to facilitate Monte Carlo studies
00021 // such as 'goodness-of-fit' studies, that involve fitting a PDF 
00022 // to multiple toy Monte Carlo sets generated from the same PDF 
00023 // or another PDF.
00024 // <p>
00025 // Given a fit PDF and a generator PDF, RooMCStudy can produce
00026 // large numbers of toyMC samples and/or fit these samples
00027 // and acculumate the final parameters of each fit in a dataset.
00028 // <p>
00029 // Additional plotting routines simplify the task of plotting
00030 // the distribution of the minimized likelihood, each parameters fitted value, 
00031 // fitted error and pull distribution.
00032 // <p>
00033 // Class RooMCStudy provides the option to insert add-in modules
00034 // that modify the generate and fit cycle and allow to perform
00035 // extra steps in the cycle. Output of these modules can be stored
00036 // alongside the fit results in the aggregate results dataset.
00037 // These study modules should derive from classs RooAbsMCStudyModel
00038 //
00039 // END_HTML
00040 //
00041 
00042 
00043 
00044 #include "RooFit.h"
00045 #include "Riostream.h"
00046 
00047 #include "RooMCStudy.h"
00048 #include "RooAbsMCStudyModule.h"
00049 
00050 #include "RooGenContext.h"
00051 #include "RooAbsPdf.h"
00052 #include "RooDataSet.h"
00053 #include "RooDataHist.h"
00054 #include "RooRealVar.h"
00055 #include "RooFitResult.h"
00056 #include "RooErrorVar.h"
00057 #include "RooFormulaVar.h"
00058 #include "RooArgList.h"
00059 #include "RooPlot.h"
00060 #include "RooGenericPdf.h"
00061 #include "RooRandom.h"
00062 #include "RooCmdConfig.h"
00063 #include "RooGlobalFunc.h"
00064 #include "RooPullVar.h"
00065 #include "RooMsgService.h"
00066 #include "RooProdPdf.h"
00067 
00068 using namespace std ;
00069 
00070 ClassImp(RooMCStudy)
00071   ;
00072 
00073 
00074 //_____________________________________________________________________________
00075 RooMCStudy::RooMCStudy(const RooAbsPdf& model, const RooArgSet& observables,
00076                        const RooCmdArg& arg1, const RooCmdArg& arg2,
00077                        const RooCmdArg& arg3,const RooCmdArg& arg4,const RooCmdArg& arg5,
00078                        const RooCmdArg& arg6,const RooCmdArg& arg7,const RooCmdArg& arg8) : TNamed("mcstudy","mcstudy")
00079 
00080 {
00081   // Construct Monte Carlo Study Manager. This class automates generating data from a given PDF,
00082   // fitting the PDF to that data and accumulating the fit statistics.
00083   //
00084   // The constructor accepts the following arguments
00085   //
00086   // model       -- The PDF to be studied
00087   // observables -- The variables of the PDF to be considered the observables
00088   //
00089   // Silence()                         -- Suppress all RooFit messages during running below PROGRESS level
00090   // FitModel(const RooAbsPdf&)        -- The PDF for fitting, if it is different from the PDF for generating
00091   // ConditionalObservables
00092   //           (const RooArgSet& set)  -- The set of observables that the PDF should _not_ be normalized over
00093   // Binned(Bool_t flag)               -- Bin the dataset before fitting it. Speeds up fitting of large data samples
00094   // FitOptions(const char*)           -- Classic fit options, provided for backward compatibility
00095   // FitOptions(....)                  -- Options to be used for fitting. All named arguments inside FitOptions()
00096   //                                                   are passed to RooAbsPdf::fitTo();
00097   // Verbose(Bool_t flag)              -- Activate informational messages in event generation phase
00098   // Extended(Bool_t flag)             -- Determine number of events for each sample anew from a Poisson distribution
00099   // Constrain(const RooArgSet& pars)  -- Apply internal constraints on given parameters in fit and sample constrained parameter
00100   //                                      values from constraint p.d.f for each toy.
00101   // ExternalConstraints(const RooArgSet& ) -- Apply internal constraints on given parameters in fit and sample constrained parameter
00102   //                                      values from constraint p.d.f for each toy.
00103   // ProtoData(const RooDataSet&, 
00104   //                 Bool_t randOrder) -- Prototype data for the event generation. If the randOrder flag is
00105   //                                      set, the order of the dataset will be re-randomized for each generation
00106   //                                      cycle to protect against systematic biases if the number of generated
00107   //                                      events does not exactly match the number of events in the prototype dataset
00108   //                                      at the cost of reduced precision
00109   //                                      with mu equal to the specified number of events
00110 
00111   // Stuff all arguments in a list
00112   RooLinkedList cmdList;
00113   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
00114   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
00115   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
00116   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
00117 
00118   // Select the pdf-specific commands 
00119   RooCmdConfig pc(Form("RooMCStudy::RooMCStudy(%s)",model.GetName())) ;
00120   
00121   pc.defineObject("fitModel","FitModel",0,0) ;
00122   pc.defineObject("condObs","ProjectedDependents",0,0) ;
00123   pc.defineObject("protoData","PrototypeData",0,0) ;
00124   pc.defineSet("cPars","Constrain",0,0) ;
00125   pc.defineSet("extCons","ExternalConstraints",0,0) ;
00126   pc.defineInt("silence","Silence",0,0) ;
00127   pc.defineInt("randProtoData","PrototypeData",0,0) ;
00128   pc.defineInt("verboseGen","Verbose",0,0) ;
00129   pc.defineInt("extendedGen","Extended",0,0) ;
00130   pc.defineInt("binGenData","Binned",0,0) ;
00131   pc.defineString("fitOpts","FitOptions",0,"") ;
00132   pc.defineInt("dummy","FitOptArgs",0,0) ;
00133   pc.defineMutex("FitOptions","FitOptArgs") ; // can have either classic or new-style fit options
00134   pc.defineMutex("Constrain","FitOptions") ; // constraints only work with new-style fit options
00135   pc.defineMutex("ExternalConstraints","FitOptions") ; // constraints only work with new-style fit options
00136   
00137   // Process and check varargs 
00138   pc.process(cmdList) ;
00139   if (!pc.ok(kTRUE)) {
00140     // WVE do something here
00141     throw std::string("RooMCStudy::RooMCStudy() Error in parsing arguments passed to contructor") ;
00142     return ;
00143   }
00144 
00145   // Save fit command options
00146   if (pc.hasProcessed("FitOptArgs")) {
00147     RooCmdArg* fitOptArg = static_cast<RooCmdArg*>(cmdList.FindObject("FitOptArgs")) ;
00148     for (Int_t i=0 ; i<fitOptArg->subArgs().GetSize() ;i++) {
00149       _fitOptList.Add(new RooCmdArg(static_cast<RooCmdArg&>(*fitOptArg->subArgs().At(i)))) ;
00150     }
00151   }
00152 
00153   // Decode command line arguments
00154   _silence = pc.getInt("silence") ;
00155   _verboseGen = pc.getInt("verboseGen") ;
00156   _extendedGen = pc.getInt("extendedGen") ;
00157   _binGenData = pc.getInt("binGenData") ;
00158   _randProto = pc.getInt("randProtoData") ;
00159 
00160   // Process constraints specifications
00161   const RooArgSet* cParsTmp = pc.getSet("cPars") ;
00162   const RooArgSet* extCons = pc.getSet("extCons") ;
00163 
00164   RooArgSet* cPars = new RooArgSet ;
00165   if (cParsTmp) {
00166     cPars->add(*cParsTmp) ;
00167   }
00168   
00169   // If constraints are specified, add to fit options
00170   if (cPars) {
00171     _fitOptList.Add(RooFit::Constrain(*cPars).Clone()) ;
00172   }
00173   if (extCons) {
00174     _fitOptList.Add(RooFit::ExternalConstraints(*extCons).Clone()) ;
00175   }
00176 
00177   // Make list of all constraints
00178   RooArgSet allConstraints ;
00179   RooArgSet consPars ;
00180   if (cPars) {
00181     RooArgSet* constraints = model.getConstraints(observables,*cPars,kTRUE) ;
00182     if (constraints) {
00183       allConstraints.add(*constraints) ;
00184       delete constraints ;
00185     }
00186   }
00187   
00188   // Construct constraint p.d.f
00189   if (allConstraints.getSize()>0) {
00190     _constrPdf = new RooProdPdf("mcs_constr_prod","RooMCStudy constraints product",allConstraints) ;
00191 
00192     if (cPars) {
00193       consPars.add(*cPars) ;
00194     } else {
00195       RooArgSet* params = model.getParameters(observables) ;
00196       RooArgSet* cparams = _constrPdf->getObservables(*params) ;
00197       consPars.add(*cparams) ;
00198       delete params ;
00199       delete cparams ;
00200     }
00201     _constrGenContext = _constrPdf->genContext(consPars,0,0,_verboseGen) ;
00202 
00203     _perExptGenParams = kTRUE ;
00204 
00205     coutI(Generation) << "RooMCStudy::RooMCStudy: INFO have pdf with constraints, will generate paramaters from constraint pdf for each experiment" << endl ;
00206 
00207 
00208   } else {
00209     _constrPdf = 0 ;
00210     _constrGenContext=0 ;
00211 
00212     _perExptGenParams = kFALSE ;
00213   }
00214 
00215   
00216   // Extract generator and fit models
00217   _genModel = const_cast<RooAbsPdf*>(&model) ;
00218   _genSample = 0 ;
00219   RooAbsPdf* fitModel = static_cast<RooAbsPdf*>(pc.getObject("fitModel",0)) ;
00220   _fitModel = fitModel ? fitModel : _genModel ;
00221   
00222   // Extract conditional observables and prototype data
00223   _genProtoData = static_cast<RooDataSet*>(pc.getObject("protoData",0)) ;
00224   if (pc.getObject("condObs",0)) {
00225     _projDeps.add(static_cast<RooArgSet&>(*pc.getObject("condObs",0))) ;
00226   }
00227   
00228   _dependents.add(observables) ;
00229      
00230   _allDependents.add(_dependents) ;  
00231   _fitOptions = pc.getString("fitOpts") ;
00232   _canAddFitResults = kTRUE ;
00233   
00234   if (_extendedGen && _genProtoData && !_randProto) {
00235     oocoutW(_fitModel,Generation) << "RooMCStudy::RooMCStudy: WARNING Using generator option 'e' (Poisson distribution of #events) together " << endl
00236                                   << "                        with a prototype dataset implies incomplete sampling or oversampling of proto data." << endl
00237                                   << "                        Use option \"r\" to randomize prototype dataset order and thus to randomize" << endl
00238                                   << "                        the set of over/undersampled prototype events for each generation cycle." << endl ;
00239   }
00240   
00241   _genParams = _genModel->getParameters(&_dependents) ;
00242   if (!_binGenData) {
00243     _genContext = _genModel->genContext(_dependents,_genProtoData,0,_verboseGen) ;
00244     _genContext->attach(*_genParams) ;
00245   } else {
00246     _genContext = 0 ;
00247   }
00248 
00249   _genInitParams = (RooArgSet*) _genParams->snapshot(kFALSE) ;
00250 
00251   // Store list of parameters and save initial values separately
00252   _fitParams = _fitModel->getParameters(&_dependents) ;
00253   _fitInitParams = (RooArgSet*) _fitParams->snapshot(kTRUE) ;
00254   
00255   _nExpGen = _extendedGen ? _genModel->expectedEvents(&_dependents) : 0 ;
00256   
00257   // Place holder for NLL
00258   _nllVar = new RooRealVar("NLL","-log(Likelihood)",0) ;
00259 
00260   // Place holder for number of generated events
00261   _ngenVar = new RooRealVar("ngen","number of generated events",0) ;
00262   
00263   // Create data set containing parameter values, errors and pulls
00264   RooArgSet tmp2(*_fitParams) ;
00265   tmp2.add(*_nllVar) ;
00266   tmp2.add(*_ngenVar) ;
00267 
00268   // Mark all variable to store their errors in the dataset
00269   tmp2.setAttribAll("StoreError",kTRUE) ;
00270   tmp2.setAttribAll("StoreAsymError",kTRUE) ;
00271   TString fpdName ;
00272   if (_fitModel==_genModel) {
00273     fpdName = Form("fitParData_%s",_fitModel->GetName()) ;
00274   } else {
00275     fpdName= Form("fitParData_%s_%s",_fitModel->GetName(),_genModel->GetName()) ;
00276   }
00277 
00278   _fitParData = new RooDataSet(fpdName.Data(),"Fit Parameters DataSet",tmp2) ;
00279   tmp2.setAttribAll("StoreError",kFALSE) ;
00280   tmp2.setAttribAll("StoreAsymError",kFALSE) ;
00281 
00282   if (_perExptGenParams) {
00283     _genParData = new RooDataSet("genParData","Generated Parameters dataset",*_genParams) ;
00284   } else {
00285     _genParData = 0 ;
00286   }
00287   
00288   // Append proto variables to allDependents
00289   if (_genProtoData) {
00290     _allDependents.add(*_genProtoData->get(),kTRUE) ;
00291   }
00292 
00293   // Call module initializers
00294   list<RooAbsMCStudyModule*>::iterator iter ;
00295   for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
00296     Bool_t ok = (*iter)->doInitializeInstance(*this) ;
00297     if (!ok) {
00298       oocoutE(_fitModel,Generation) << "RooMCStudy::ctor: removing study module " << (*iter)->GetName() << " from analysis chain because initialization failed" << endl ;
00299       iter = _modList.erase(iter) ;
00300     }
00301   }
00302   
00303 }
00304 
00305 
00306 //_____________________________________________________________________________
00307 RooMCStudy::RooMCStudy(const RooAbsPdf& genModel, const RooAbsPdf& fitModel, 
00308                        const RooArgSet& dependents, const char* genOptions, 
00309                        const char* fitOptions, const RooDataSet* genProtoData, 
00310                        const RooArgSet& projDeps) :
00311   TNamed("mcstudy","mcstudy"),
00312   _genModel((RooAbsPdf*)&genModel), 
00313   _genProtoData(genProtoData),
00314   _projDeps(projDeps),
00315   _constrPdf(0),
00316   _constrGenContext(0),
00317   _dependents(dependents), 
00318   _allDependents(dependents), 
00319   _fitModel((RooAbsPdf*)&fitModel), 
00320   _nllVar(0),
00321   _ngenVar(0),
00322   _genParData(0),
00323   _fitOptions(fitOptions),
00324   _canAddFitResults(kTRUE),
00325   _perExptGenParams(0),
00326   _silence(kFALSE)
00327 {
00328   // OBSOLETE, RETAINED FOR BACKWARD COMPATIBILY. PLEASE
00329   // USE CONSTRUCTOR WITH NAMED ARGUMENTS
00330   //
00331   // Constructor with a generator and fit model. Both models may point
00332   // to the same object. The 'dependents' set of variables is generated 
00333   // in the generator phase. The optional prototype dataset is passed to
00334   // the generator
00335   //
00336   // Available generator options
00337   //  v  - Verbose
00338   //  e  - Extended: use Poisson distribution for Nevts generated
00339   //
00340   // Available fit options
00341   //  See RooAbsPdf::fitTo()
00342   //
00343   
00344   // Decode generator options
00345   TString genOpt(genOptions) ;
00346   genOpt.ToLower() ;
00347   _verboseGen = genOpt.Contains("v") ;
00348   _extendedGen = genOpt.Contains("e") ;
00349   _binGenData = genOpt.Contains("b") ;
00350   _randProto = genOpt.Contains("r") ;
00351   
00352   if (_extendedGen && genProtoData && !_randProto) {
00353     oocoutE(_fitModel,Generation) << "RooMCStudy::RooMCStudy: WARNING Using generator option 'e' (Poisson distribution of #events) together " << endl
00354                                   << "                        with a prototype dataset implies incomplete sampling or oversampling of proto data." << endl
00355                                   << "                        Use option \"r\" to randomize prototype dataset order and thus to randomize" << endl
00356                                   << "                        the set of over/undersampled prototype events for each generation cycle." << endl ;
00357   }
00358   
00359   if (!_binGenData) {
00360     _genContext = genModel.genContext(dependents,genProtoData,0,_verboseGen) ;
00361   } else {
00362     _genContext = 0 ;
00363   }
00364   _genParams = _genModel->getParameters(&_dependents) ;
00365   _genSample = 0 ;
00366   RooArgSet* tmp = genModel.getParameters(&dependents) ;
00367   _genInitParams = (RooArgSet*) tmp->snapshot(kFALSE) ;
00368   delete tmp ;
00369   
00370   // Store list of parameters and save initial values separately
00371   _fitParams = fitModel.getParameters(&dependents) ;
00372   _fitInitParams = (RooArgSet*) _fitParams->snapshot(kTRUE) ;
00373   
00374   _nExpGen = _extendedGen ? genModel.expectedEvents(&dependents) : 0 ;
00375   
00376   // Place holder for NLL
00377   _nllVar = new RooRealVar("NLL","-log(Likelihood)",0) ;
00378   
00379   // Place holder for number of generated events
00380   _ngenVar = new RooRealVar("ngen","number of generated events",0) ;
00381   
00382   // Create data set containing parameter values, errors and pulls
00383   RooArgSet tmp2(*_fitParams) ;
00384   tmp2.add(*_nllVar) ;
00385   tmp2.add(*_ngenVar) ;
00386   
00387   // Mark all variable to store their errors in the dataset
00388   tmp2.setAttribAll("StoreError",kTRUE) ;
00389   tmp2.setAttribAll("StoreAsymError",kTRUE) ;
00390   _fitParData = new RooDataSet("fitParData","Fit Parameters DataSet",tmp2) ;
00391   tmp2.setAttribAll("StoreError",kFALSE) ;
00392   tmp2.setAttribAll("StoreAsymError",kFALSE) ;
00393   
00394   // Append proto variables to allDependents
00395   if (genProtoData) {
00396     _allDependents.add(*genProtoData->get(),kTRUE) ;
00397   }
00398 
00399   // Call module initializers
00400   list<RooAbsMCStudyModule*>::iterator iter ;
00401   for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
00402     Bool_t ok = (*iter)->doInitializeInstance(*this) ;
00403     if (!ok) {
00404       oocoutE(_fitModel,Generation) << "RooMCStudy::ctor: removing study module " << (*iter)->GetName() << " from analysis chain because initialization failed" << endl ;
00405       iter = _modList.erase(iter) ;
00406     }
00407   }
00408   
00409 }
00410 
00411 
00412 
00413 //_____________________________________________________________________________
00414 RooMCStudy::~RooMCStudy() 
00415 {  
00416   // Destructor 
00417   
00418   _genDataList.Delete() ;
00419   _fitResList.Delete() ;
00420   _fitOptList.Delete() ;
00421   delete _ngenVar ;
00422   delete _fitParData ;
00423   delete _genParData ;
00424   delete _fitInitParams ;
00425   delete _fitParams ;
00426   delete _genInitParams ;
00427   delete _genParams ;
00428   delete _genContext ;
00429   delete _nllVar ;
00430   delete _constrPdf ;
00431   delete _constrGenContext ;
00432 }
00433 
00434 
00435 
00436 //_____________________________________________________________________________
00437 void RooMCStudy::addModule(RooAbsMCStudyModule& module) 
00438 {
00439   // Insert given RooMCStudy add-on module to the processing chain
00440   // of this MCStudy object
00441 
00442   module.doInitializeInstance(*this) ;
00443   _modList.push_back(&module) ;        
00444 }
00445 
00446 
00447 
00448 //_____________________________________________________________________________
00449 Bool_t RooMCStudy::run(Bool_t doGenerate, Bool_t DoFit, Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
00450 {
00451   // Run engine method. Generate and/or fit, according to flags, 'nSamples' samples of 'nEvtPerSample' events.
00452   // If keepGenData is set, all generated data sets will be kept in memory and can be accessed
00453   // later via genData().
00454   //
00455   // When generating, data sets will be written out in ascii form if the pattern string is supplied
00456   // The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
00457   // and should contain one integer field that encodes the sample serial number.
00458   //
00459   // When fitting only, data sets may optionally be read from ascii files, using the same file
00460   // pattern.
00461   //
00462 
00463   RooFit::MsgLevel oldLevel(RooFit::FATAL) ;
00464   if (_silence) {
00465     oldLevel = RooMsgService::instance().globalKillBelow() ;
00466     RooMsgService::instance().setGlobalKillBelow(RooFit::PROGRESS) ;
00467   }
00468 
00469   list<RooAbsMCStudyModule*>::iterator iter ;
00470   for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
00471     (*iter)->initializeRun(nSamples) ;
00472   }  
00473   
00474   Int_t prescale = nSamples>100 ? Int_t(nSamples/100) : 1 ;
00475 
00476   while(nSamples--) {
00477     
00478     if (nSamples%prescale==0) {
00479       oocoutP(_fitModel,Generation) << "RooMCStudy::run: " ;
00480       if (doGenerate) ooccoutI(_fitModel,Generation) << "Generating " ;
00481       if (doGenerate && DoFit) ooccoutI(_fitModel,Generation) << "and " ;
00482       if (DoFit) ooccoutI(_fitModel,Generation) << "fitting " ;
00483       ooccoutP(_fitModel,Generation) << "sample " << nSamples << endl ;
00484     }
00485 
00486     _genSample = 0;
00487     Bool_t existingData = kFALSE ;
00488     if (doGenerate) {
00489       // Generate sample
00490       Int_t nEvt(nEvtPerSample) ;
00491 
00492       // Reset generator parameters to initial values
00493       *_genParams = *_genInitParams ;
00494 
00495       // If constraints are present, sample generator values from constraints
00496       if (_constrPdf) {
00497         RooDataSet* tmp = _constrGenContext->generate(1) ;
00498         *_genParams = *tmp->get() ;
00499         delete tmp ;
00500       }
00501 
00502       // Save generated parameters if required
00503       if (_genParData) {
00504         _genParData->add(*_genParams) ;
00505       }
00506 
00507       // Call module before-generation hook
00508       list<RooAbsMCStudyModule*>::iterator iter2 ;
00509       for (iter2=_modList.begin() ; iter2!= _modList.end() ; ++iter2) {
00510         (*iter2)->processBeforeGen(nSamples) ;
00511       }  
00512 
00513       if (_binGenData) {
00514 
00515         // Calculate the number of (extended) events for this run
00516         if (_extendedGen) {
00517           _nExpGen = _genModel->expectedEvents(&_dependents) ;
00518           nEvt = RooRandom::randomGenerator()->Poisson(nEvtPerSample==0?_nExpGen:nEvtPerSample) ;
00519         }       
00520 
00521         // Binned generation
00522         _genSample = _genModel->generateBinned(_dependents,nEvt) ;
00523 
00524       } else {
00525 
00526         // Calculate the number of (extended) events for this run
00527         if (_extendedGen) {
00528           _nExpGen = _genModel->expectedEvents(&_dependents) ;
00529           nEvt = RooRandom::randomGenerator()->Poisson(nEvtPerSample==0?_nExpGen:nEvtPerSample) ;
00530         }
00531         
00532         // Optional randomization of protodata for this run
00533         if (_randProto && _genProtoData && _genProtoData->numEntries()!=nEvt) {
00534           oocoutI(_fitModel,Generation) << "RooMCStudy: (Re)randomizing event order in prototype dataset (Nevt=" << nEvt << ")" << endl ;
00535           Int_t* newOrder = _genModel->randomizeProtoOrder(_genProtoData->numEntries(),nEvt) ;
00536           _genContext->setProtoDataOrder(newOrder) ;
00537           delete[] newOrder ;
00538         }
00539         
00540         // Actual generation of events
00541         if (nEvt>0) {
00542           _genSample = _genContext->generate(nEvt) ;
00543         } else {
00544           // Make empty dataset
00545           _genSample = new RooDataSet("emptySample","emptySample",_dependents) ;
00546         }       
00547       } 
00548 
00549         
00550     //} else if (asciiFilePat && &asciiFilePat) { //warning: the address of 'asciiFilePat' will always evaluate as 'true'
00551     } else if (asciiFilePat) {
00552 
00553       // Load sample from ASCII file
00554       char asciiFile[1024] ;
00555       snprintf(asciiFile,1024,asciiFilePat,nSamples) ;
00556       RooArgList depList(_allDependents) ;
00557       _genSample = RooDataSet::read(asciiFile,depList,"q") ;      
00558       
00559     } else {
00560       
00561       // Load sample from internal list
00562       _genSample = (RooDataSet*) _genDataList.At(nSamples) ;
00563       existingData = kTRUE ;
00564       if (!_genSample) {
00565         oocoutW(_fitModel,Generation) << "RooMCStudy::run: WARNING: Sample #" << nSamples << " not loaded, skipping" << endl ;
00566         continue ;
00567       }
00568     }
00569 
00570     // Save number of generated events
00571     _ngenVar->setVal(_genSample->sumEntries()) ;
00572 
00573     // Call module between generation and fitting hook
00574     list<RooAbsMCStudyModule*>::iterator iter3 ;
00575     for (iter3=_modList.begin() ; iter3!= _modList.end() ; ++iter3) {
00576       (*iter3)->processBetweenGenAndFit(nSamples) ;
00577     }  
00578     
00579     if (DoFit) fitSample(_genSample) ;
00580 
00581     // Call module between generation and fitting hook
00582     for (iter3=_modList.begin() ; iter3!= _modList.end() ; ++iter3) {
00583       (*iter3)->processAfterFit(nSamples) ;
00584     }  
00585     
00586     // Optionally write to ascii file
00587     if (doGenerate && asciiFilePat && *asciiFilePat) {
00588       char asciiFile[1024] ;
00589       snprintf(asciiFile,1024,asciiFilePat,nSamples) ;
00590       RooDataSet* unbinnedData = dynamic_cast<RooDataSet*>(_genSample) ;
00591       if (unbinnedData) {
00592         unbinnedData->write(asciiFile) ;
00593       } else {
00594         coutE(InputArguments) << "RooMCStudy::run(" << GetName() << ") ERROR: ASCII writing of binned datasets is not supported" << endl ;
00595       }
00596     }
00597     
00598     // Add to list or delete
00599     if (!existingData) {
00600       if (keepGenData) {
00601         _genDataList.Add(_genSample) ;
00602       } else {
00603         delete _genSample ;
00604       }
00605     }
00606   }
00607 
00608   for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
00609     RooDataSet* auxData = (*iter)->finalizeRun() ;
00610     if (auxData) {
00611       _fitParData->merge(auxData) ;
00612     }
00613   }  
00614 
00615   _canAddFitResults = kFALSE ;
00616 
00617   if (_genParData) {
00618     const RooArgSet* genPars = _genParData->get() ;
00619     TIterator* iter2 = genPars->createIterator() ;
00620     RooAbsArg* arg ;
00621     while((arg=(RooAbsArg*)iter2->Next())) {
00622       _genParData->changeObservableName(arg->GetName(),Form("%s_gen",arg->GetName())) ;
00623     }
00624     delete iter2 ;
00625     
00626     _fitParData->merge(_genParData) ;
00627   }
00628 
00629   if (DoFit) calcPulls() ;
00630 
00631   if (_silence) {
00632     RooMsgService::instance().setGlobalKillBelow(oldLevel) ;
00633   }
00634 
00635   return kFALSE ;
00636 }
00637 
00638 
00639 
00640 
00641 
00642 
00643 //_____________________________________________________________________________
00644 Bool_t RooMCStudy::generateAndFit(Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
00645 {
00646   // Generate and fit 'nSamples' samples of 'nEvtPerSample' events.
00647   // If keepGenData is set, all generated data sets will be kept in memory and can be accessed
00648   // later via genData().
00649   //
00650   // Data sets will be written out is ascii form if the pattern string is supplied.
00651   // The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
00652   // and should contain one integer field that encodes the sample serial number.
00653   //
00654   
00655   // Clear any previous data in memory
00656   _fitResList.Delete() ;
00657   _genDataList.Delete() ;
00658   _fitParData->reset() ;
00659   
00660   return run(kTRUE,kTRUE,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
00661 }
00662 
00663 
00664 
00665 //_____________________________________________________________________________
00666 Bool_t RooMCStudy::generate(Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
00667 {
00668   // Generate 'nSamples' samples of 'nEvtPerSample' events.
00669   // If keepGenData is set, all generated data sets will be kept in memory 
00670   // and can be accessed later via genData().
00671   //
00672   // Data sets will be written out in ascii form if the pattern string is supplied.
00673   // The pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
00674   // and should contain one integer field that encodes the sample serial number.
00675   //
00676   
00677   // Clear any previous data in memory
00678   _genDataList.Delete() ;
00679   
00680   return run(kTRUE,kFALSE,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
00681 }
00682 
00683 
00684 
00685 //_____________________________________________________________________________
00686 Bool_t RooMCStudy::fit(Int_t nSamples, const char* asciiFilePat) 
00687 {
00688   // Fit 'nSamples' datasets, which are read from ASCII files.
00689   //
00690   // The ascii file pattern, which is a template for snprintf, should look something like "data/toymc_%04d.dat"
00691   // and should contain one integer field that encodes the sample serial number.
00692   //
00693   
00694   // Clear any previous data in memory
00695   _fitResList.Delete() ;
00696   _fitParData->reset() ;
00697   
00698   return run(kFALSE,kTRUE,nSamples,0,kFALSE,asciiFilePat) ;
00699 }
00700 
00701 
00702 
00703 //_____________________________________________________________________________
00704 Bool_t RooMCStudy::fit(Int_t nSamples, TList& dataSetList) 
00705 {
00706   // Fit 'nSamples' datasets, as supplied in 'dataSetList'
00707   // 
00708   
00709   // Clear any previous data in memory
00710   _fitResList.Delete() ;
00711   _genDataList.Delete() ;
00712   _fitParData->reset() ;
00713   
00714   // Load list of data sets
00715   TIterator* iter = dataSetList.MakeIterator() ;
00716   RooAbsData* gset ;
00717   while((gset=(RooAbsData*)iter->Next())) {
00718     _genDataList.Add(gset) ;
00719   }
00720   delete iter ;
00721   
00722   return run(kFALSE,kTRUE,nSamples,0,kTRUE,0) ;
00723 }
00724 
00725 
00726 
00727 //_____________________________________________________________________________
00728 void RooMCStudy::resetFitParams()
00729 {
00730   // Reset all fit parameters to the initial model
00731   // parameters at the time of the RooMCStudy constructor
00732 
00733   *_fitParams = *_fitInitParams ;
00734 }
00735 
00736 
00737 
00738 //_____________________________________________________________________________
00739 RooFitResult* RooMCStudy::doFit(RooAbsData* genSample)
00740 {
00741   // Internal function. Performs actual fit according to specifications
00742 
00743   // Fit model to data set
00744   TString fitOpt2(_fitOptions) ; fitOpt2.Append("r") ;
00745   if (_silence) {
00746     fitOpt2.Append("b") ;
00747   }
00748   
00749   // Optionally bin dataset before fitting
00750   RooAbsData* data ;
00751   if (_binGenData) {    
00752     RooArgSet* depList = _fitModel->getObservables(genSample) ;
00753     data = new RooDataHist(genSample->GetName(),genSample->GetTitle(),*depList,*genSample) ;
00754     delete depList ;
00755   } else {
00756     data = genSample ;
00757   }
00758   
00759   RooFitResult* fr ;
00760   if (_fitOptList.GetSize()==0) {
00761     if (_projDeps.getSize()>0) {
00762       fr = (RooFitResult*) _fitModel->fitTo(*data,RooFit::ConditionalObservables(_projDeps),RooFit::FitOptions(fitOpt2)) ;
00763     } else {
00764       fr = (RooFitResult*) _fitModel->fitTo(*data,RooFit::FitOptions(fitOpt2)) ;
00765     }
00766   } else {
00767     RooCmdArg save  = RooFit::Save() ;
00768     RooCmdArg condo = RooFit::ConditionalObservables(_projDeps) ;
00769     RooCmdArg plevel = RooFit::PrintLevel(-1) ;
00770     RooLinkedList fitOptList(_fitOptList) ;
00771     fitOptList.Add(&save) ;
00772     if (_projDeps.getSize()>0) {
00773       fitOptList.Add(&condo) ;
00774     }
00775     if (_silence) {
00776       fitOptList.Add(&plevel) ;
00777     }
00778     fr = (RooFitResult*) _fitModel->fitTo(*data,fitOptList) ;
00779   }
00780 
00781   if (_binGenData) delete data ;
00782 
00783   return fr ;
00784 }
00785 
00786 
00787 
00788 //_____________________________________________________________________________
00789 RooFitResult* RooMCStudy::refit(RooAbsData* genSample) 
00790 {
00791   // Redo fit on 'current' toy sample, or if genSample is not NULL
00792   // do fit on given sample instead
00793 
00794   if (!genSample) {
00795     genSample = _genSample ;
00796   }
00797 
00798   RooFitResult* fr(0) ;
00799   if (genSample->sumEntries()>0) {
00800     fr = doFit(genSample) ;
00801   }
00802 
00803   return fr ;
00804 }
00805 
00806 
00807 
00808 //_____________________________________________________________________________
00809 Bool_t RooMCStudy::fitSample(RooAbsData* genSample) 
00810 {  
00811   // Internal method. Fit given dataset with fit model. If fit
00812   // converges (TMinuit status code zero) The fit results are appended
00813   // to the fit results dataset
00814   //
00815   // If the fit option "r" is supplied, the RooFitResult
00816   // objects will always be saved, regardless of the
00817   // fit status. RooFitResults objects can be retrieved
00818   // later via fitResult().
00819   //  
00820   
00821   // Reset all fit parameters to their initial values  
00822   resetFitParams() ;
00823 
00824   // Perform actual fit
00825   Bool_t ok ;
00826   RooFitResult* fr(0) ;
00827   if (genSample->sumEntries()>0) {
00828     fr = doFit(genSample) ;
00829     ok = (fr->status()==0) ;
00830   } else {
00831     ok = kFALSE ;
00832   }
00833 
00834   // If fit converged, store parameters and NLL
00835   if (ok) {
00836     _nllVar->setVal(fr->minNll()) ;
00837     RooArgSet tmp(*_fitParams) ;
00838     tmp.add(*_nllVar) ;
00839     tmp.add(*_ngenVar) ;
00840     _fitParData->add(tmp) ;
00841   }
00842   
00843   // Store fit result if requested by user
00844   Bool_t userSaveRequest = kFALSE ;
00845   if (_fitOptList.GetSize()>0) {
00846     if (_fitOptList.FindObject("Save")) userSaveRequest = kTRUE ;
00847   } else {
00848     if (_fitOptions.Contains("r")) userSaveRequest = kTRUE ;
00849   }
00850 
00851   if (userSaveRequest) {
00852     _fitResList.Add(fr) ;
00853   } else {
00854     delete fr ;
00855   }
00856     
00857   return !ok ;
00858 }
00859 
00860 
00861 
00862 //_____________________________________________________________________________
00863 Bool_t RooMCStudy::addFitResult(const RooFitResult& fr) 
00864 {  
00865   // Utility function to add fit result from external fit to this RooMCStudy
00866   // and process its results through the standard RooMCStudy statistics gathering tools.
00867   // This function allows users to run the toy MC generation and/or fitting
00868   // in a distributed way and to collect and analyze the results in a RooMCStudy
00869   // as if they were run locally.
00870   //
00871   // This method is only functional if this RooMCStudy object is cleanm, i.e. it was not used
00872   // to generate and/or fit any samples.
00873 
00874   if (!_canAddFitResults) {
00875     oocoutE(_fitModel,InputArguments) << "RooMCStudy::addFitResult: ERROR cannot add fit results in current state" << endl ;
00876     return kTRUE ;
00877   }
00878   
00879   // Transfer contents of fit result to fitParams ;
00880   *_fitParams = RooArgSet(fr.floatParsFinal()) ;
00881   
00882   // If fit converged, store parameters and NLL
00883   Bool_t ok = (fr.status()==0) ;
00884   if (ok) {
00885     _nllVar->setVal(fr.minNll()) ;
00886     RooArgSet tmp(*_fitParams) ;
00887     tmp.add(*_nllVar) ;
00888     tmp.add(*_ngenVar) ;
00889     _fitParData->add(tmp) ;
00890   }
00891   
00892   // Store fit result if requested by user
00893   if (_fitOptions.Contains("r")) {
00894     _fitResList.Add((TObject*)&fr) ;
00895   }  
00896   
00897   return kFALSE ;
00898 }
00899 
00900 
00901 
00902 //_____________________________________________________________________________
00903 void RooMCStudy::calcPulls() 
00904 {
00905   // Calculate the pulls for all fit parameters in
00906   // the fit results data set, and add them to that dataset
00907   
00908   TIterator* iter = _fitParams->createIterator()  ;
00909   RooRealVar* par ;
00910   while((par=(RooRealVar*)iter->Next())) {
00911     
00912     RooErrorVar* err = par->errorVar() ;
00913     _fitParData->addColumn(*err) ;
00914     delete err ;
00915     
00916     TString name(par->GetName()), title(par->GetTitle()) ;
00917     name.Append("pull") ;
00918     title.Append(" Pull") ;    
00919 
00920     // First look in fitParDataset to see if per-experiment generated value has been stored
00921     RooAbsReal* genParOrig = (RooAbsReal*) _fitParData->get()->find(Form("%s_gen",par->GetName())) ;    
00922     if (genParOrig && _perExptGenParams) {
00923 
00924       RooPullVar pull(name,title,*par,*genParOrig) ;
00925       _fitParData->addColumn(pull,kFALSE) ;
00926 
00927     } else {
00928       // If not use fixed generator value
00929       genParOrig = (RooAbsReal*)_genInitParams->find(par->GetName()) ;
00930       
00931       if (genParOrig) {
00932         RooAbsReal* genPar = (RooAbsReal*) genParOrig->Clone("truth") ;
00933         RooPullVar pull(name,title,*par,*genPar) ;
00934         
00935         _fitParData->addColumn(pull,kFALSE) ;
00936         delete genPar ;
00937         
00938       }
00939 
00940     }
00941 
00942   }
00943   delete iter ;
00944   
00945 }
00946 
00947 
00948 
00949 
00950 //_____________________________________________________________________________
00951 const RooDataSet& RooMCStudy::fitParDataSet()
00952 {
00953   // Return a RooDataSet the resulting fit parameters of each toy cycle.
00954   // This dataset also contains any additional output that was generated
00955   // by study modules that were added to this RooMCStudy
00956 
00957   if (_canAddFitResults) {
00958     calcPulls() ;  
00959     _canAddFitResults = kFALSE ; 
00960   }
00961   
00962   return *_fitParData ;
00963 }
00964 
00965 
00966 
00967 //_____________________________________________________________________________
00968 const RooArgSet* RooMCStudy::fitParams(Int_t sampleNum) const 
00969 {
00970   // Return an argset with the fit parameters for the given sample number
00971   //
00972   // NB: The fit parameters are only stored for successfull fits,
00973   //     thus the maximum sampleNum can be less that the number
00974   //     of generated samples and if so, the indeces will
00975   //     be out of synch with genData() and fitResult()
00976   
00977   // Check if sampleNum is in range
00978   if (sampleNum<0 || sampleNum>=_fitParData->numEntries()) {
00979     oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitParams: ERROR, invalid sample number: " << sampleNum << endl ;    
00980     return 0 ;
00981   }
00982   
00983   return _fitParData->get(sampleNum) ;
00984 }
00985 
00986 
00987 
00988 //_____________________________________________________________________________
00989 const RooFitResult* RooMCStudy::fitResult(Int_t sampleNum) const
00990 {
00991   // Return the RooFitResult object of the fit to given sample 
00992   
00993   // Check if sampleNum is in range
00994   if (sampleNum<0 || sampleNum>=_fitResList.GetSize()) {
00995     oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitResult: ERROR, invalid sample number: " << sampleNum << endl ;    
00996     return 0 ;
00997   }
00998   
00999   // Retrieve fit result object
01000   const RooFitResult* fr = (RooFitResult*) _fitResList.At(sampleNum) ;
01001   if (fr) {
01002     return fr ;
01003   } else {
01004     oocoutE(_fitModel,InputArguments) << "RooMCStudy::fitResult: ERROR, no fit result saved for sample " 
01005                           << sampleNum << ", did you use the 'r; fit option?" << endl ;
01006   }
01007   return 0 ;
01008 }
01009 
01010 
01011 
01012 //_____________________________________________________________________________
01013 const RooDataSet* RooMCStudy::genData(Int_t sampleNum) const 
01014 {
01015   // Return the given generated dataset. This method will only return datasets
01016   // if during the run cycle it was indicated that generator data should be saved.
01017   
01018   // Check that generated data was saved
01019   if (_genDataList.GetSize()==0) {
01020     oocoutE(_fitModel,InputArguments) << "RooMCStudy::genData() ERROR, generated data was not saved" << endl ;
01021     return 0 ;
01022   }
01023   
01024   // Check if sampleNum is in range
01025   if (sampleNum<0 || sampleNum>=_genDataList.GetSize()) {
01026     oocoutE(_fitModel,InputArguments) << "RooMCStudy::genData() ERROR, invalid sample number: " << sampleNum << endl ;    
01027     return 0 ;
01028   }
01029   
01030   return (RooDataSet*) _genDataList.At(sampleNum) ;
01031 }
01032 
01033 
01034 
01035 //_____________________________________________________________________________
01036 RooPlot* RooMCStudy::plotParamOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
01037                                  const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
01038 {
01039   // Plot the distribution of fitted values of a parameter. The parameter shown is the one from which the RooPlot
01040   // was created, e.g.
01041   //
01042   // RooPlot* frame = param.frame(100,-10,10) ;
01043   // mcstudy.paramOn(frame,LineStyle(kDashed)) ;
01044   // 
01045   // Any named arguments passed to plotParamOn() are forwarded to the underlying plotOn() call
01046   
01047   _fitParData->plotOn(frame,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01048   return frame ;
01049 }
01050 
01051 
01052 
01053 //_____________________________________________________________________________
01054 RooPlot* RooMCStudy::plotParam(const char* paramName, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
01055                                const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
01056 {
01057   // Plot the distribution of the fitted value of the given parameter on a newly created frame.
01058   //
01059   // This function accepts the following optional arguments
01060   // FrameRange(double lo, double hi) -- Set range of frame to given specification
01061   // FrameBins(int bins)              -- Set default number of bins of frame to given number
01062   // Frame(...)                       -- Pass supplied named arguments to RooAbsRealLValue::frame() function. See frame() function
01063   //                                     for list of allowed arguments
01064   //
01065   // If no frame specifications are given, the AutoRange() feature will be used to set the range
01066   // Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
01067 
01068 
01069   // Find parameter in fitParDataSet
01070   RooRealVar* param = static_cast<RooRealVar*>(_fitParData->get()->find(paramName)) ;
01071   if (!param) {
01072     oocoutE(_fitModel,InputArguments) << "RooMCStudy::plotParam: ERROR: no parameter defined with name " << paramName << endl ;  
01073     return 0 ;
01074   }
01075 
01076   // Forward to implementation below
01077   return plotParam(*param,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01078 }
01079 
01080 
01081 
01082 //_____________________________________________________________________________
01083 RooPlot* RooMCStudy::plotParam(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
01084                                const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
01085 {
01086   // Plot the distribution of the fitted value of the given parameter on a newly created frame.
01087   //
01088   // This function accepts the following optional arguments
01089   // FrameRange(double lo, double hi) -- Set range of frame to given specification
01090   // FrameBins(int bins)              -- Set default number of bins of frame to given number
01091   // Frame(...)                       -- Pass supplied named arguments to RooAbsRealLValue::frame() function. See frame() function
01092   //                                     for list of allowed arguments
01093   //
01094   // If no frame specifications are given, the AutoRange() feature will be used to set the range
01095   // Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
01096 
01097   // Stuff all arguments in a list
01098   RooLinkedList cmdList;
01099   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
01100   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
01101   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
01102   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
01103   
01104   RooPlot* frame = makeFrameAndPlotCmd(param, cmdList) ;
01105   if (frame) {
01106     _fitParData->plotOn(frame, cmdList) ;
01107   }
01108 
01109   return frame ;
01110 }
01111 
01112 
01113 
01114 //_____________________________________________________________________________
01115 RooPlot* RooMCStudy::plotNLL(const RooCmdArg& arg1, const RooCmdArg& arg2,
01116                      const RooCmdArg& arg3, const RooCmdArg& arg4,
01117                      const RooCmdArg& arg5, const RooCmdArg& arg6,
01118                      const RooCmdArg& arg7, const RooCmdArg& arg8) 
01119 {
01120   // Plot the distribution of the -log(L) values on a newly created frame.
01121   //
01122   // This function accepts the following optional arguments
01123   // FrameRange(double lo, double hi) -- Set range of frame to given specification
01124   // FrameBins(int bins)              -- Set default number of bins of frame to given number
01125   // Frame(...)                       -- Pass supplied named arguments to RooAbsRealLValue::frame() function. See frame() function
01126   //                                     for list of allowed arguments
01127   //
01128   // If no frame specifications are given, the AutoRange() feature will be used to set the range
01129   // Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
01130 
01131   return plotParam(*_nllVar,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01132 }
01133 
01134 
01135 
01136 //_____________________________________________________________________________
01137 RooPlot* RooMCStudy::plotError(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2,
01138                      const RooCmdArg& arg3, const RooCmdArg& arg4,
01139                      const RooCmdArg& arg5, const RooCmdArg& arg6,
01140                      const RooCmdArg& arg7, const RooCmdArg& arg8) 
01141 {
01142   // Plot the distribution of the fit errors for the specified parameter on a newly created frame.
01143   //
01144   // This function accepts the following optional arguments
01145   // FrameRange(double lo, double hi) -- Set range of frame to given specification
01146   // FrameBins(int bins)              -- Set default number of bins of frame to given number
01147   // Frame(...)                       -- Pass supplied named arguments to RooAbsRealLValue::frame() function. See frame() function
01148   //                                     for list of allowed arguments
01149   //
01150   // If no frame specifications are given, the AutoRange() feature will be used to set the range
01151   // Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
01152 
01153   if (_canAddFitResults) {
01154     calcPulls() ;
01155     _canAddFitResults=kFALSE ;
01156   }
01157 
01158   RooErrorVar* evar = param.errorVar() ;
01159   RooRealVar* evar_rrv = static_cast<RooRealVar*>(evar->createFundamental()) ;
01160   RooPlot* frame = plotParam(*evar_rrv,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
01161   delete evar_rrv ;
01162   delete evar ;
01163   return frame ;
01164 }
01165 
01166 
01167 
01168 //_____________________________________________________________________________
01169 RooPlot* RooMCStudy::plotPull(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2,
01170                      const RooCmdArg& arg3, const RooCmdArg& arg4,
01171                      const RooCmdArg& arg5, const RooCmdArg& arg6,
01172                      const RooCmdArg& arg7, const RooCmdArg& arg8) 
01173 {
01174   // Plot the distribution of pull values for the specified parameter on a newly created frame. If asymmetric
01175   // errors are calculated in the fit (by MINOS) those will be used in the pull calculation
01176   //
01177   // This function accepts the following optional arguments
01178   // FrameRange(double lo, double hi) -- Set range of frame to given specification
01179   // FrameBins(int bins)              -- Set default number of bins of frame to given number
01180   // Frame(...)                       -- Pass supplied named arguments to RooAbsRealLValue::frame() function. See frame() function
01181   //                                     for list of allowed arguments
01182   // FitGauss(Bool_t flag)            -- Add a gaussian fit to the frame
01183   //
01184   // If no frame specifications are given, the AutoSymRange() feature will be used to set the range
01185   // Any other named argument is passed to the RooAbsData::plotOn() call. See that function for allowed options
01186 
01187   // Stuff all arguments in a list
01188   RooLinkedList cmdList;
01189   cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
01190   cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
01191   cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
01192   cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
01193 
01194   TString name(param.GetName()), title(param.GetTitle()) ;
01195   name.Append("pull") ; title.Append(" Pull") ;
01196   RooRealVar pvar(name,title,-100,100) ;
01197   pvar.setBins(100) ;
01198 
01199 
01200   RooPlot* frame = makeFrameAndPlotCmd(pvar, cmdList, kTRUE) ;
01201   if (frame) {
01202 
01203     // Pick up optonal FitGauss command from list
01204     RooCmdConfig pc(Form("RooMCStudy::plotPull(%s)",_genModel->GetName())) ;
01205     pc.defineInt("fitGauss","FitGauss",0,0) ;
01206     pc.allowUndefined() ;
01207     pc.process(cmdList) ;
01208     Bool_t fitGauss=pc.getInt("fitGauss") ;
01209 
01210     // Pass stripped command list to plotOn()
01211     pc.stripCmdList(cmdList,"FitGauss") ;
01212     _fitParData->plotOn(frame,cmdList) ;
01213 
01214     // Add Gaussian fit if requested
01215     if (fitGauss) {
01216       RooRealVar pullMean("pullMean","Mean of pull",0,-10,10) ;
01217       RooRealVar pullSigma("pullSigma","Width of pull",1,0.1,5) ;
01218       RooGenericPdf pullGauss("pullGauss","Gaussian of pull",
01219                               "exp(-0.5*(@0-@1)*(@0-@1)/(@2*@2))",
01220                               RooArgSet(pvar,pullMean,pullSigma)) ;
01221       pullGauss.fitTo(*_fitParData,RooFit::Minos(0),RooFit::PrintLevel(-1)) ;
01222       pullGauss.plotOn(frame) ;
01223       pullGauss.paramOn(frame,_fitParData) ;
01224     }
01225   }
01226   return frame ; ;
01227 }
01228 
01229 
01230 
01231 //_____________________________________________________________________________
01232 RooPlot* RooMCStudy::makeFrameAndPlotCmd(const RooRealVar& param, RooLinkedList& cmdList, Bool_t symRange) const 
01233 {
01234   // Internal function. Construct RooPlot from given parameter and modify the list of named
01235   // arguments 'cmdList' to only contain the plot arguments that should be forwarded to 
01236   // RooAbsData::plotOn()
01237 
01238   // Select the frame-specific commands 
01239   RooCmdConfig pc(Form("RooMCStudy::plotParam(%s)",_genModel->GetName())) ;
01240   pc.defineInt("nbins","Bins",0,0) ;
01241   pc.defineDouble("xlo","Range",0,0) ;
01242   pc.defineDouble("xhi","Range",1,0) ;
01243   pc.defineInt("dummy","FrameArgs",0,0) ;
01244   pc.defineMutex("Bins","FrameArgs") ;
01245   pc.defineMutex("Range","FrameArgs") ;
01246 
01247   // Process and check varargs 
01248   pc.allowUndefined() ;
01249   pc.process(cmdList) ;
01250   if (!pc.ok(kTRUE)) {
01251     return 0 ;
01252   }
01253   
01254   // Make frame according to specs
01255   Int_t nbins = pc.getInt("nbins") ;
01256   Double_t xlo = pc.getDouble("xlo") ;
01257   Double_t xhi = pc.getDouble("xhi") ;
01258   RooPlot* frame ; 
01259 
01260   if (pc.hasProcessed("FrameArgs")) {
01261     // Explicit frame arguments are given, pass them on
01262     RooCmdArg* frameArg = static_cast<RooCmdArg*>(cmdList.FindObject("FrameArgs")) ;
01263     frame = param.frame(frameArg->subArgs()) ;
01264   } else {
01265     // FrameBins, FrameRange or none are given, build custom frame command list
01266     RooCmdArg bins = RooFit::Bins(nbins) ;
01267     RooCmdArg range = RooFit::Range(xlo,xhi) ;
01268     RooCmdArg autor = symRange ? RooFit::AutoSymRange(*_fitParData,0.2) : RooFit::AutoRange(*_fitParData,0.2) ;
01269     RooLinkedList frameCmdList ;
01270 
01271     if (pc.hasProcessed("Bins")) frameCmdList.Add(&bins) ;
01272     if (pc.hasProcessed("Range")) {
01273       frameCmdList.Add(&range) ;
01274     } else {
01275       frameCmdList.Add(&autor) ;
01276     }
01277     frame = param.frame(frameCmdList) ;
01278   }
01279   
01280   // Filter frame command from list and pass on to plotOn() 
01281   pc.stripCmdList(cmdList,"FrameArgs,Bins,Range") ;
01282 
01283   return frame ;
01284 }
01285 
01286 
01287 
01288 //_____________________________________________________________________________
01289 RooPlot* RooMCStudy::plotNLL(Double_t lo, Double_t hi, Int_t nBins) 
01290 {
01291   // Create a RooPlot of the -log(L) distribution in the range lo-hi
01292   // with 'nBins' bins
01293 
01294   RooPlot* frame = _nllVar->frame(lo,hi,nBins) ;
01295   
01296   _fitParData->plotOn(frame) ;
01297   return frame ;
01298 }
01299 
01300 
01301 
01302 //_____________________________________________________________________________
01303 RooPlot* RooMCStudy::plotError(const RooRealVar& param, Double_t lo, Double_t hi, Int_t nbins) 
01304 {
01305   // Create a RooPlot of the distribution of the fitted errors of the given parameter. 
01306   // The frame is created with a range [lo,hi] and plotted data will be binned in 'nbins' bins
01307 
01308   if (_canAddFitResults) {
01309     calcPulls() ;
01310     _canAddFitResults=kFALSE ;
01311   }
01312 
01313   RooErrorVar* evar = param.errorVar() ;
01314   RooPlot* frame = evar->frame(lo,hi,nbins) ;
01315   _fitParData->plotOn(frame) ;
01316 
01317   delete evar ;
01318   return frame ;
01319 }
01320 
01321 
01322 
01323 //_____________________________________________________________________________
01324 RooPlot* RooMCStudy::plotPull(const RooRealVar& param, Double_t lo, Double_t hi, Int_t nbins, Bool_t fitGauss) 
01325 {
01326   // Create a RooPlot of the pull distribution for the given
01327   // parameter.  The range lo-hi is plotted in nbins.  If fitGauss is
01328   // set, an unbinned ML fit of the distribution to a Gaussian p.d.f
01329   // is performed. The fit result is overlaid on the returned RooPlot
01330   // and a box with the fitted mean and sigma is added.
01331 
01332   if (_canAddFitResults) {
01333     calcPulls() ;
01334     _canAddFitResults=kFALSE ;
01335   }
01336 
01337 
01338   TString name(param.GetName()), title(param.GetTitle()) ;
01339   name.Append("pull") ; title.Append(" Pull") ;
01340   RooRealVar pvar(name,title,lo,hi) ;
01341   pvar.setBins(nbins) ;
01342 
01343   RooPlot* frame = pvar.frame() ;
01344   _fitParData->plotOn(frame) ;
01345 
01346   if (fitGauss) {
01347     RooRealVar pullMean("pullMean","Mean of pull",0,lo,hi) ;
01348     RooRealVar pullSigma("pullSigma","Width of pull",1,0,5) ;
01349     RooGenericPdf pullGauss("pullGauss","Gaussian of pull",
01350                             "exp(-0.5*(@0-@1)*(@0-@1)/(@2*@2))",
01351                             RooArgSet(pvar,pullMean,pullSigma)) ;
01352     pullGauss.fitTo(*_fitParData,"mh") ;
01353     pullGauss.plotOn(frame) ;
01354     pullGauss.paramOn(frame,_fitParData) ;
01355   }
01356 
01357   return frame ;
01358 }
01359 
01360 
01361 

Generated on Tue Jul 5 15:06:49 2011 for ROOT_528-00b_version by  doxygen 1.5.1