#include "RooFit.h"
#include "RooMCStudy.h"
#include "RooAbsMCStudyModule.h"
#include "RooGenContext.h"
#include "RooAbsPdf.h"
#include "RooDataSet.h"
#include "RooDataHist.h"
#include "RooRealVar.h"
#include "RooFitResult.h"
#include "RooErrorVar.h"
#include "RooFormulaVar.h"
#include "RooArgList.h"
#include "RooPlot.h"
#include "RooGenericPdf.h"
#include "RooRandom.h"
#include "RooCmdConfig.h"
#include "RooGlobalFunc.h"
#include "RooPullVar.h"
ClassImp(RooMCStudy)
  ;
RooMCStudy::RooMCStudy(const RooAbsPdf& model, const RooArgSet& observables,
   		       RooCmdArg arg1, RooCmdArg arg2,
   		       RooCmdArg arg3,RooCmdArg arg4,RooCmdArg arg5,
   		       RooCmdArg arg6,RooCmdArg arg7,RooCmdArg arg8) 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
{
  
  RooLinkedList cmdList;
  cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
  
  RooCmdConfig pc(Form("RooMCStudy::RooMCStudy(%s)",model.GetName())) ;
  
  pc.defineObject("fitModel","FitModel",0,0) ;
  pc.defineObject("condObs","ProjectedDependents",0,0) ;
  pc.defineObject("protoData","PrototypeData",0,0) ;
  pc.defineInt("randProtoData","PrototypeData",0,0) ;
  pc.defineInt("verboseGen","Verbose",0,0) ;
  pc.defineInt("extendedGen","Extended",0,0) ;
  pc.defineInt("binGenData","Binned",0,0) ;
  pc.defineString("fitOpts","FitOptions",0,"") ;
  pc.defineInt("dummy","FitOptArgs",0,0) ;
  pc.defineMutex("FitOptions","FitOptArgs") ;
  
  
  pc.process(cmdList) ;
  if (!pc.ok(kTRUE)) {
    
    return ;
  }
  
  
  if (pc.hasProcessed("FitOptArgs")) {
    RooCmdArg* fitOptArg = static_cast<RooCmdArg*>(cmdList.FindObject("FitOptArgs")) ;
    for (Int_t i=0 ; i<fitOptArg->subArgs().GetSize() ;i++) {
      _fitOptList.Add(new RooCmdArg(static_cast<RooCmdArg&>(*fitOptArg->subArgs().At(i)))) ;
    }
  }
  
  _verboseGen = pc.getInt("verboseGen") ;
  _extendedGen = pc.getInt("extendedGen") ;
  _binGenData = pc.getInt("binGenData") ;
  _randProto = pc.getInt("randProtoData") ;
  
  _genModel = const_cast<RooAbsPdf*>(&model) ;
  RooAbsPdf* fitModel = static_cast<RooAbsPdf*>(pc.getObject("fitModel",0)) ;
  _fitModel = fitModel ? fitModel : _genModel ;
  
  _genProtoData = static_cast<RooDataSet*>(pc.getObject("protoData",0)) ;
  if (pc.getObject("condObs",0)) {
    _projDeps.add(static_cast<RooArgSet&>(*pc.getObject("condObs",0))) ;
  }
  
  _dependents.add(observables) ;
     
  _allDependents.add(_dependents) ;  
  _fitOptions = pc.getString("fitOpts") ;
  _canAddFitResults = kTRUE ;
  
  if (_extendedGen && _genProtoData && !_randProto) {
    cout << "RooMCStudy::RooMCStudy: WARNING Using generator option 'e' (Poisson distribution of #events) together " << endl
	 << "                        with a prototype dataset implies incomplete sampling or oversampling of proto data." << endl
	 << "                        Use option \"r\" to randomize prototype dataset order and thus to randomize" << endl
	 << "                        the set of over/undersampled prototype events for each generation cycle." << endl ;
  }
  
  _genContext = _genModel->genContext(_dependents,_genProtoData,0,_verboseGen) ;
  _genParams = _genModel->getParameters(&_dependents) ;
  _genInitParams = (RooArgSet*) _genParams->snapshot(kFALSE) ;
  
  
  _fitParams = _fitModel->getParameters(&_dependents) ;
  _fitInitParams = (RooArgSet*) _fitParams->snapshot(kTRUE) ;
  
  _nExpGen = _extendedGen ? _genModel->expectedEvents(&_dependents) : 0 ;
  
  
  _nllVar = new RooRealVar("NLL","-log(Likelihood)",0) ;
  
  
  RooArgSet tmp2(*_fitParams) ;
  tmp2.add(*_nllVar) ;
  
  
  tmp2.setAttribAll("StoreError",kTRUE) ;
  tmp2.setAttribAll("StoreAsymError",kTRUE) ;
  _fitParData = new RooDataSet("fitParData","Fit Parameters DataSet",tmp2) ;
  tmp2.setAttribAll("StoreError",kFALSE) ;
  tmp2.setAttribAll("StoreAsymError",kFALSE) ;
  
  
  if (_genProtoData) {
    _allDependents.add(*_genProtoData->get(),kTRUE) ;
  }
  
  list<RooAbsMCStudyModule*>::iterator iter ;
  for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
    Bool_t ok = (*iter)->doInitializeInstance(*this) ;
    if (!ok) {
      cout << "RooMCStudy::ctor: removing study module " << (*iter)->GetName() << " from analysis chain because initialization failed" << endl ;
      iter = _modList.erase(iter) ;
    }
  }
  
}
RooMCStudy::RooMCStudy(const RooAbsPdf& genModel, const RooAbsPdf& fitModel, 
   		       const RooArgSet& dependents, const char* genOptions, 
   		       const char* fitOptions, const RooDataSet* genProtoData, 
   		       const RooArgSet& projDeps) :
  _genModel((RooAbsPdf*)&genModel), 
  _genProtoData(genProtoData),
  _projDeps(projDeps),
  _dependents(dependents), 
  _allDependents(dependents), 
  _fitModel((RooAbsPdf*)&fitModel), 
  _fitOptions(fitOptions),
  _canAddFitResults(kTRUE)
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  TString genOpt(genOptions) ;
  genOpt.ToLower() ;
  _verboseGen = genOpt.Contains("v") ;
  _extendedGen = genOpt.Contains("e") ;
  _binGenData = genOpt.Contains("b") ;
  _randProto = genOpt.Contains("r") ;
  
  if (_extendedGen && genProtoData && !_randProto) {
    cout << "RooMCStudy::RooMCStudy: WARNING Using generator option 'e' (Poisson distribution of #events) together " << endl
   	 << "                        with a prototype dataset implies incomplete sampling or oversampling of proto data." << endl
   	 << "                        Use option \"r\" to randomize prototype dataset order and thus to randomize" << endl
	 << "                        the set of over/undersampled prototype events for each generation cycle." << endl ;
  }
  
  _genContext = genModel.genContext(dependents,genProtoData,0,_verboseGen) ;
  RooArgSet* tmp = genModel.getParameters(&dependents) ;
  _genInitParams = (RooArgSet*) tmp->snapshot(kFALSE) ;
  delete tmp ;
  
  
  _fitParams = fitModel.getParameters(&dependents) ;
  _fitInitParams = (RooArgSet*) _fitParams->snapshot(kTRUE) ;
  
  _nExpGen = _extendedGen ? genModel.expectedEvents(&dependents) : 0 ;
  
  
  _nllVar = new RooRealVar("NLL","-log(Likelihood)",0) ;
  
  
  RooArgSet tmp2(*_fitParams) ;
  tmp2.add(*_nllVar) ;
  
  
  tmp2.setAttribAll("StoreError",kTRUE) ;
  tmp2.setAttribAll("StoreAsymError",kTRUE) ;
  _fitParData = new RooDataSet("fitParData","Fit Parameters DataSet",tmp2) ;
  tmp2.setAttribAll("StoreError",kFALSE) ;
  tmp2.setAttribAll("StoreAsymError",kFALSE) ;
  
  
  if (genProtoData) {
    _allDependents.add(*genProtoData->get(),kTRUE) ;
  }
  
  list<RooAbsMCStudyModule*>::iterator iter ;
  for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
    Bool_t ok = (*iter)->doInitializeInstance(*this) ;
    if (!ok) {
      cout << "RooMCStudy::ctor: removing study module " << (*iter)->GetName() << " from analysis chain because initialization failed" << endl ;
      iter = _modList.erase(iter) ;
    }
  }
  
}
RooMCStudy::~RooMCStudy() 
{  
  
  
  _genDataList.Delete() ;
  _fitResList.Delete() ;
  _fitOptList.Delete() ;
  delete _fitParData ;
  delete _fitInitParams ;
  delete _fitParams ;
  delete _genInitParams ;
  delete _genParams ;
  delete _genContext ;
  delete _nllVar ;
}
void RooMCStudy::addModule(RooAbsMCStudyModule& module) 
{
  
  module.doInitializeInstance(*this) ;
  _modList.push_back(&module) ;        
}
Bool_t RooMCStudy::run(Bool_t generate, Bool_t fit, Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
{
  
  
  
  
  
  
  
  
  
  
  
  list<RooAbsMCStudyModule*>::iterator iter ;
  for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
    (*iter)->initializeRun(nSamples) ;
  }  
  while(nSamples--) {
    
    cout << "RooMCStudy::run: " ;
    if (generate) cout << "Generating " ;
    if (generate && fit) cout << "and " ;
    if (fit) cout << "fitting " ;
    cout << "sample " << nSamples << endl ;
    
    _genSample = 0;
    Bool_t existingData = kFALSE ;
    if (generate) {
      
      Int_t nEvt(nEvtPerSample) ;
      
      *_genParams = *_genInitParams ;
      
      list<RooAbsMCStudyModule*>::iterator iter ;
      for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
	(*iter)->processBeforeGen(nSamples) ;
      }  
      
      if (_extendedGen) {
	_nExpGen = _genModel->expectedEvents(&_dependents) ;
	nEvt = RooRandom::randomGenerator()->Poisson(nEvtPerSample==0?_nExpGen:nEvtPerSample) ;
      }
      
      
      if (_randProto && _genProtoData && _genProtoData->numEntries()!=nEvt) {
	cout << "RooMCStudy: (Re)randomizing event order in prototype dataset (Nevt=" << nEvt << ")" << endl ;
          Int_t* newOrder = _genModel->randomizeProtoOrder(_genProtoData->numEntries(),nEvt) ;
          _genContext->setProtoDataOrder(newOrder) ;
          delete[] newOrder ;
      }
      
      
      _genSample = _genContext->generate(nEvt) ;
      
    } else if (asciiFilePat && &asciiFilePat) {
      
      char asciiFile[1024] ;
      sprintf(asciiFile,asciiFilePat,nSamples) ;
      RooArgList depList(_allDependents) ;
      _genSample = RooDataSet::read(asciiFile,depList,"q") ;      
      
    } else {
      
      
      _genSample = (RooDataSet*) _genDataList.At(nSamples) ;
      existingData = kTRUE ;
      if (!_genSample) {
   	cout << "RooMCStudy::run: WARNING: Sample #" << nSamples << " not loaded, skipping" << endl ;
   	continue ;
      }
    }
    
    list<RooAbsMCStudyModule*>::iterator iter ;
    for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
      (*iter)->processBetweenGenAndFit(nSamples) ;
    }  
    
    if (fit) fitSample(_genSample) ;
    
    for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
      (*iter)->processAfterFit(nSamples) ;
    }  
    
    
    if (generate && asciiFilePat && *asciiFilePat) {
      char asciiFile[1024] ;
      sprintf(asciiFile,asciiFilePat,nSamples) ;
      _genSample->write(asciiFile) ;
    }
    
    
    if (!existingData) {
      if (keepGenData) {
	_genDataList.Add(_genSample) ;
      } else {
	delete _genSample ;
      }
    }
  }
  for (iter=_modList.begin() ; iter!= _modList.end() ; ++iter) {
    RooDataSet* auxData = (*iter)->finalizeRun() ;
    if (auxData) {
      _fitParData->merge(auxData) ;
    }
  }  
  _canAddFitResults = kFALSE ;
  if (fit) calcPulls() ;
  return kFALSE ;
}
Bool_t RooMCStudy::generateAndFit(Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
{
  
  
  
  
  
  
  
  
  
  
  _fitResList.Delete() ;
  _genDataList.Delete() ;
  _fitParData->reset() ;
  
  return run(kTRUE,kTRUE,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
}
Bool_t RooMCStudy::generate(Int_t nSamples, Int_t nEvtPerSample, Bool_t keepGenData, const char* asciiFilePat) 
{
  
  
  
  
  
  
  
  
  
  
  _genDataList.Delete() ;
  
  return run(kTRUE,kFALSE,nSamples,nEvtPerSample,keepGenData,asciiFilePat) ;
}
Bool_t RooMCStudy::fit(Int_t nSamples, const char* asciiFilePat) 
{
  
  
  
  
  
  
  
  _fitResList.Delete() ;
  _fitParData->reset() ;
  
  return run(kFALSE,kTRUE,nSamples,0,kFALSE,asciiFilePat) ;
}
Bool_t RooMCStudy::fit(Int_t nSamples, TList& dataSetList) 
{
  
  
  
  
  _fitResList.Delete() ;
  _genDataList.Delete() ;
  _fitParData->reset() ;
  
  
  TIterator* iter = dataSetList.MakeIterator() ;
  RooAbsData* gset ;
  while((gset=(RooAbsData*)iter->Next())) {
    _genDataList.Add(gset) ;
  }
  delete iter ;
  
  return run(kFALSE,kTRUE,nSamples,0,kTRUE,0) ;
}
void RooMCStudy::resetFitParams()
{
  *_fitParams = *_fitInitParams ;
}
RooFitResult* RooMCStudy::doFit(RooAbsData* genSample)
{
  
  
  TString fitOpt2(_fitOptions) ; fitOpt2.Append("r") ;
  
  
  RooAbsData* data ;
  if (_binGenData) {    
    RooArgSet* depList = _fitModel->getObservables(genSample) ;
    data = new RooDataHist(genSample->GetName(),genSample->GetTitle(),*depList,*genSample) ;
    delete depList ;
  } else {
    data = genSample ;
  }
  
  RooFitResult* fr ;
  if (_fitOptList.GetSize()==0) {
    if (_projDeps.getSize()>0) {
      fr = (RooFitResult*) _fitModel->fitTo(*data,_projDeps,fitOpt2) ;
    } else {
      fr = (RooFitResult*) _fitModel->fitTo(*data,fitOpt2) ;
    }
  } else {
    RooCmdArg save  = RooFit::Save() ;
    RooCmdArg condo = RooFit::ConditionalObservables(_projDeps) ;
    RooLinkedList fitOptList(_fitOptList) ;
    fitOptList.Add(&save) ;
    if (_projDeps.getSize()>0) {
      fitOptList.Add(&condo) ;
    }
    fr = (RooFitResult*) _fitModel->fitTo(*data,fitOptList) ;
  }
  if (_binGenData) delete data ;
  return fr ;
}
RooFitResult* RooMCStudy::refit(RooAbsData* genSample) 
{
  if (!genSample) {
    genSample = _genSample ;
  }
  RooFitResult* fr = doFit(genSample) ;
    
  return fr ;
}
Bool_t RooMCStudy::fitSample(RooAbsData* genSample) 
{  
  
  
  
  
  
  
  
  
  
  
  
  
  resetFitParams() ;
  
  RooFitResult* fr = doFit(genSample) ;
  
  Bool_t ok = (fr->status()==0) ;
  if (ok) {
    _nllVar->setVal(fr->minNll()) ;
    RooArgSet tmp(*_fitParams) ;
    tmp.add(*_nllVar) ;
    _fitParData->add(tmp) ;
  }
  
  
  Bool_t userSaveRequest = kFALSE ;
  if (_fitOptList.GetSize()>0) {
    if (_fitOptList.FindObject("Save")) userSaveRequest = kTRUE ;
  } else {
    if (_fitOptions.Contains("r")) userSaveRequest = kTRUE ;
  }
  if (userSaveRequest) {
    _fitResList.Add(fr) ;
  } else {
    delete fr ;
  }
    
  return !ok ;
}
Bool_t RooMCStudy::addFitResult(const RooFitResult& fr) 
{  
  if (!_canAddFitResults) {
    cout << "RooMCStudy::addFitResult: ERROR cannot add fit results in current state" << endl ;
    return kTRUE ;
  }
  
  
  *_fitParams = RooArgSet(fr.floatParsFinal()) ;
  
  
  Bool_t ok = (fr.status()==0) ;
  if (ok) {
    _nllVar->setVal(fr.minNll()) ;
    RooArgSet tmp(*_fitParams) ;
    tmp.add(*_nllVar) ;
    _fitParData->add(tmp) ;
  }
  
  
  if (_fitOptions.Contains("r")) {
    _fitResList.Add((TObject*)&fr) ;
  }  
  
  return kFALSE ;
}
void RooMCStudy::calcPulls() 
{
  
  
  
  TIterator* iter = _fitParams->createIterator()  ;
  RooRealVar* par ;
  while((par=(RooRealVar*)iter->Next())) {
    
    RooErrorVar* err = par->errorVar() ;
    _fitParData->addColumn(*err) ;
    
    TString name(par->GetName()), title(par->GetTitle()) ;
    name.Append("pull") ;
    title.Append(" Pull") ;
    RooAbsReal* genParOrig = (RooAbsReal*)_genInitParams->find(par->GetName()) ;
    if (genParOrig) {
      RooAbsReal* genPar = (RooAbsReal*) genParOrig->Clone("truth") ;
      RooPullVar pull(name,title,*par,*genPar) ;
      
      _fitParData->addColumn(pull) ;
      delete genPar ;
    }    
  }
  delete iter ;
  
}
const RooDataSet& RooMCStudy::fitParDataSet()
{
  
  if (_canAddFitResults) {
    calcPulls() ;  
    _canAddFitResults = kFALSE ; 
  }
  
  return *_fitParData ;
}
const RooArgSet* RooMCStudy::fitParams(Int_t sampleNum) const 
{
  
  
  
  
  
  
  
  if (sampleNum<0 || sampleNum>=_fitParData->numEntries()) {
    cout << "RooMCStudy::fitParams: ERROR, invalid sample number: " << sampleNum << endl ;    
    return 0 ;
  }
  
  return _fitParData->get(sampleNum) ;
}
const RooFitResult* RooMCStudy::fitResult(Int_t sampleNum) const
{
  
  
  
  if (sampleNum<0 || sampleNum>=_fitResList.GetSize()) {
    cout << "RooMCStudy::fitResult: ERROR, invalid sample number: " << sampleNum << endl ;    
    return 0 ;
  }
  
  
  const RooFitResult* fr = (RooFitResult*) _fitResList.At(sampleNum) ;
  if (fr) {
    return fr ;
  } else {
    cout << "RooMCStudy::fitResult: ERROR, no fit result saved for sample " 
   	 << sampleNum << ", did you use the 'r; fit option?" << endl ;
  }
  return 0 ;
}
const RooDataSet* RooMCStudy::genData(Int_t sampleNum) const 
{
  
  
  
  if (_genDataList.GetSize()==0) {
    cout << "RooMCStudy::genData() ERROR, generated data was not saved" << endl ;
    return 0 ;
  }
  
  
  if (sampleNum<0 || sampleNum>=_genDataList.GetSize()) {
    cout << "RooMCStudy::genData() ERROR, invalid sample number: " << sampleNum << endl ;    
    return 0 ;
  }
  
  return (RooDataSet*) _genDataList.At(sampleNum) ;
}
RooPlot* RooMCStudy::plotParamOn(RooPlot* frame, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
   				 const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  _fitParData->plotOn(frame,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
  return frame ;
}
RooPlot* RooMCStudy::plotParam(const char* paramName, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
   			       const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  
  
  
  
  
  
  
  
  RooRealVar* param = static_cast<RooRealVar*>(_fitParData->get()->find(paramName)) ;
  if (!param) {
    cout << "RooMCStudy::plotParam: ERROR: no parameter defined with name " << paramName << endl ;  
    return 0 ;
  }
  
  return plotParam(*param,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
}
RooPlot* RooMCStudy::plotParam(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2, const RooCmdArg& arg3, const RooCmdArg& arg4, 
   			       const RooCmdArg& arg5, const RooCmdArg& arg6, const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  
  
  
  
  
  
  
  
  RooLinkedList cmdList;
  cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
  
  RooPlot* frame = makeFrameAndPlotCmd(param, cmdList) ;
  if (frame) {
    _fitParData->plotOn(frame, cmdList) ;
  }
  return frame ;
}
RooPlot* RooMCStudy::plotNLL(const RooCmdArg& arg1, const RooCmdArg& arg2,
                     const RooCmdArg& arg3, const RooCmdArg& arg4,
                     const RooCmdArg& arg5, const RooCmdArg& arg6,
                     const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  
  
  
  
  
  
  
  return plotParam(*_nllVar,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
}
RooPlot* RooMCStudy::plotError(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2,
                     const RooCmdArg& arg3, const RooCmdArg& arg4,
                     const RooCmdArg& arg5, const RooCmdArg& arg6,
                     const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  
  
  
  
  
  
  
  if (_canAddFitResults) {
    calcPulls() ;
    _canAddFitResults=kFALSE ;
  }
  RooErrorVar* evar = param.errorVar() ;
  RooRealVar* evar_rrv = static_cast<RooRealVar*>(evar->createFundamental()) ;
  RooPlot* frame = plotParam(*evar_rrv,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8) ;
  delete evar_rrv ;
  delete evar ;
  return frame ;
}
RooPlot* RooMCStudy::plotPull(const RooRealVar& param, const RooCmdArg& arg1, const RooCmdArg& arg2,
                     const RooCmdArg& arg3, const RooCmdArg& arg4,
                     const RooCmdArg& arg5, const RooCmdArg& arg6,
                     const RooCmdArg& arg7, const RooCmdArg& arg8) 
{
  
  
  
  
  
  
  
  
  
  
  
  
  
  RooLinkedList cmdList;
  cmdList.Add(const_cast<RooCmdArg*>(&arg1)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg2)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg3)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg4)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg5)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg6)) ;
  cmdList.Add(const_cast<RooCmdArg*>(&arg7)) ;  cmdList.Add(const_cast<RooCmdArg*>(&arg8)) ;
  TString name(param.GetName()), title(param.GetTitle()) ;
  name.Append("pull") ; title.Append(" Pull") ;
  RooRealVar pvar(name,title,-100,100) ;
  pvar.setBins(100) ;
  RooPlot* frame = makeFrameAndPlotCmd(pvar, cmdList, kTRUE) ;
  if (frame) {
    
    RooCmdConfig pc(Form("RooMCStudy::plotPull(%s)",_genModel->GetName())) ;
    pc.defineInt("fitGauss","FitGauss",0,0) ;
    pc.allowUndefined() ;
    pc.process(cmdList) ;
    Bool_t fitGauss=pc.getInt("fitGauss") ;
    
    pc.stripCmdList(cmdList,"FitGauss") ;
    _fitParData->plotOn(frame,cmdList) ;
    
    if (fitGauss) {
      RooRealVar pullMean("pullMean","Mean of pull",0,-100,100) ;
      RooRealVar pullSigma("pullSigma","Width of pull",1,0,5) ;
      RooGenericPdf pullGauss("pullGauss","Gaussian of pull",
			      "exp(-0.5*(@0-@1)*(@0-@1)/(@2*@2))",
			      RooArgSet(pvar,pullMean,pullSigma)) ;
      pullGauss.fitTo(*_fitParData,RooFit::Minos(0),RooFit::PrintLevel(-1)) ;
      pullGauss.plotOn(frame) ;
      pullGauss.paramOn(frame,_fitParData) ;
    }
  }
  return frame ; ;
}
RooPlot* RooMCStudy::makeFrameAndPlotCmd(const RooRealVar& param, RooLinkedList& cmdList, Bool_t symRange) const 
{
  
  RooCmdConfig pc(Form("RooMCStudy::plotParam(%s)",_genModel->GetName())) ;
  pc.defineInt("nbins","FrameBins",0,0) ;
  pc.defineDouble("xlo","FrameRange",0,0) ;
  pc.defineDouble("xhi","FrameRange",1,0) ;
  pc.defineInt("dummy","FrameArgs",0,0) ;
  pc.defineMutex("FrameBins","FrameArgs") ;
  pc.defineMutex("FrameRange","FrameArgs") ;
  
  pc.allowUndefined() ;
  pc.process(cmdList) ;
  if (!pc.ok(kTRUE)) {
    return 0 ;
  }
  
  
  Int_t nbins = pc.getInt("nbins") ;
  Double_t xlo = pc.getDouble("xlo") ;
  Double_t xhi = pc.getDouble("xhi") ;
  RooPlot* frame ; 
  if (pc.hasProcessed("FrameArgs")) {
    
    RooCmdArg* frameArg = static_cast<RooCmdArg*>(cmdList.FindObject("FrameArgs")) ;
    frame = param.frame(frameArg->subArgs()) ;
  } else {
    
    RooCmdArg bins = RooFit::Bins(nbins) ;
    RooCmdArg range = RooFit::Range(xlo,xhi) ;
    RooCmdArg autor = symRange ? RooFit::AutoSymRange(*_fitParData,0.2) : RooFit::AutoRange(*_fitParData,0.2) ;
    RooLinkedList frameCmdList ;
    if (pc.hasProcessed("FrameBins")) frameCmdList.Add(&bins) ;
    if (pc.hasProcessed("FrameRange")) {
      frameCmdList.Add(&range) ;
    } else {
      frameCmdList.Add(&autor) ;
    }
    frame = param.frame(frameCmdList) ;
  }
  
  
  pc.stripCmdList(cmdList,"FrameBins,FrameRange,FrameArgs") ;
  return frame ;
}
RooPlot* RooMCStudy::plotNLL(Double_t lo, Double_t hi, Int_t nBins) 
{
  
  
  RooPlot* frame = _nllVar->frame(lo,hi,nBins) ;
  
  _fitParData->plotOn(frame) ;
  return frame ;
}
RooPlot* RooMCStudy::plotError(const RooRealVar& param, Double_t lo, Double_t hi, Int_t nbins) 
{
  
  
  if (_canAddFitResults) {
    calcPulls() ;
    _canAddFitResults=kFALSE ;
  }
  RooErrorVar* evar = param.errorVar() ;
  RooPlot* frame = evar->frame(lo,hi,nbins) ;
  _fitParData->plotOn(frame) ;
  delete evar ;
  return frame ;
}
RooPlot* RooMCStudy::plotPull(const RooRealVar& param, Double_t lo, Double_t hi, Int_t nbins, Bool_t fitGauss) 
{
  
  
  
  
  
  if (_canAddFitResults) {
    calcPulls() ;
    _canAddFitResults=kFALSE ;
  }
  TString name(param.GetName()), title(param.GetTitle()) ;
  name.Append("pull") ; title.Append(" Pull") ;
  RooRealVar pvar(name,title,lo,hi) ;
  pvar.setBins(nbins) ;
  RooPlot* frame = pvar.frame() ;
  _fitParData->plotOn(frame) ;
  if (fitGauss) {
    RooRealVar pullMean("pullMean","Mean of pull",0,lo,hi) ;
    RooRealVar pullSigma("pullSigma","Width of pull",1,0,5) ;
    RooGenericPdf pullGauss("pullGauss","Gaussian of pull",
			    "exp(-0.5*(@0-@1)*(@0-@1)/(@2*@2))",
			    RooArgSet(pvar,pullMean,pullSigma)) ;
    pullGauss.fitTo(*_fitParData,"mh") ;
    pullGauss.plotOn(frame) ;
    pullGauss.paramOn(frame,_fitParData) ;
  }
  return frame ;
}
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.