RooWorkspace* makeInvertedANFit(TTree* tree, float forceSigma=-1, bool constrainMu=false, float forceMu=-1) {
  RooWorkspace *ws = new RooWorkspace("ws","");

  std::vector< TString (*)(TString, RooRealVar&, RooWorkspace&) > bkgPdfList;
  bkgPdfList.push_back(makeSingleExp);
  bkgPdfList.push_back(makeDoubleExp);
#if DEBUG==0
  //bkgPdfList.push_back(makeTripleExp);
  bkgPdfList.push_back(makeModExp);
  bkgPdfList.push_back(makeSinglePow);
  bkgPdfList.push_back(makeDoublePow);
  bkgPdfList.push_back(makePoly2);
  bkgPdfList.push_back(makePoly3);
#endif



  RooRealVar mgg("mgg","m_{#gamma#gamma}",103,160,"GeV");
  mgg.setBins(38);

  mgg.setRange("sideband_low", 103,120);
  mgg.setRange("sideband_high",131,160);
  mgg.setRange("signal",120,131);

  RooRealVar MR("MR","",0,3000,"GeV");
  MR.setBins(60);
  
  RooRealVar Rsq("t1Rsq","",0,1,"GeV");
  Rsq.setBins(20);

  RooRealVar hem1_M("hem1_M","",-1,2000,"GeV");
  hem1_M.setBins(40);

  RooRealVar hem2_M("hem2_M","",-1,2000,"GeV");
  hem2_M.setBins(40);

  RooRealVar ptgg("ptgg","p_{T}^{#gamma#gamma}",0,500,"GeV");
  ptgg.setBins(50);

  RooDataSet data("data","",tree,RooArgSet(mgg,MR,Rsq,hem1_M,hem2_M,ptgg));

  RooDataSet* blind_data = (RooDataSet*)data.reduce("mgg<121 || mgg>130");

  std::vector<TString> tags;
  //fit many different background models
  for(auto func = bkgPdfList.begin(); func != bkgPdfList.end(); func++) {
    TString tag = (*func)("bonly",mgg,*ws);
    tags.push_back(tag);
    ws->pdf("bonly_"+tag+"_ext")->fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
    RooFitResult* bres = ws->pdf("bonly_"+tag+"_ext")->fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
    bres->SetName(tag+"_bonly_fitres");
    ws->import(*bres);

    //make blinded fit
    RooPlot *fmgg_b = mgg.frame();
    blind_data->plotOn(fmgg_b,RooFit::Range("sideband_low,sideband_high"));
    TBox blindBox(121,fmgg_b->GetMinimum()-(fmgg_b->GetMaximum()-fmgg_b->GetMinimum())*0.015,130,fmgg_b->GetMaximum());
    blindBox.SetFillColor(kGray);
    fmgg_b->addObject(&blindBox);
    ws->pdf("bonly_"+tag+"_ext")->plotOn(fmgg_b,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("sideband_low,sideband_high"));
    fmgg_b->SetName(tag+"_blinded_frame");
    ws->import(*fmgg_b);
    delete fmgg_b;
    

    //set all the parameters constant
    RooArgSet* vars = ws->pdf("bonly_"+tag)->getVariables();
    RooFIter iter = vars->fwdIterator();
    RooAbsArg* a;
    while( (a = iter.next()) ){
      if(string(a->GetName()).compare("mgg")==0) continue;
      static_cast<RooRealVar*>(a)->setConstant(kTRUE);
    }

    //make the background portion of the s+b fit
    (*func)("b",mgg,*ws);

    RooRealVar sigma(tag+"_s_sigma","",5,0,100);
    if(forceSigma!=-1) {
      sigma.setVal(forceSigma);
      sigma.setConstant(true);
    }
    RooRealVar mu(tag+"_s_mu","",126,120,132);
    if(forceMu!=-1) {
      mu.setVal(forceMu);
      mu.setConstant(true);
    }
    RooGaussian sig(tag+"_sig_model","",mgg,mu,sigma);
    RooRealVar Nsig(tag+"_sb_Ns","",5,0,100);
    RooRealVar Nbkg(tag+"_sb_Nb","",100,0,100000);
    

    RooRealVar HiggsMass("HiggsMass","",125.1);
    RooRealVar HiggsMassError("HiggsMassError","",0.24);
    RooGaussian HiggsMassConstraint("HiggsMassConstraint","",mu,HiggsMass,HiggsMassError);


    RooAddPdf fitModel(tag+"_sb_model","",RooArgList( *ws->pdf("b_"+tag), sig ),RooArgList(Nbkg,Nsig));

    RooFitResult* sbres;
    RooAbsReal* nll;
    if(constrainMu) {
      fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
      sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
      nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    } else {
      fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE));
      sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE));
      nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE));
    }
    sbres->SetName(tag+"_sb_fitres");
    ws->import(*sbres);
    ws->import(fitModel);

    RooPlot *fmgg = mgg.frame();
    data.plotOn(fmgg);
    fitModel.plotOn(fmgg);
    ws->pdf("b_"+tag+"_ext")->plotOn(fmgg,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("Full"));
    fmgg->SetName(tag+"_frame");
    ws->import(*fmgg);
    delete fmgg;


    RooMinuit(*nll).migrad();

    RooPlot *fNs = Nsig.frame(0,25);
    fNs->SetName(tag+"_Nsig_pll");
    RooAbsReal *pll = nll->createProfile(Nsig);
    //nll->plotOn(fNs,RooFit::ShiftToZero(),RooFit::LineColor(kRed));
    pll->plotOn(fNs);
    ws->import(*fNs);

    delete fNs;

    RooPlot *fmu = mu.frame(125,132);
    fmu->SetName(tag+"_mu_pll");
    RooAbsReal *pll_mu = nll->createProfile(mu);
    pll_mu->plotOn(fmu);
    ws->import(*fmu);

    delete fmu;

  }

  RooArgSet weights("weights");
  RooArgSet pdfs_bonly("pdfs_bonly");
  RooArgSet pdfs_b("pdfs_b");

  RooRealVar minAIC("minAIC","",1E10);
  //compute AIC stuff
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooAbsPdf *p_bonly = ws->pdf("bonly_"+*t);
    RooAbsPdf *p_b = ws->pdf("b_"+*t);
    RooFitResult *sb = (RooFitResult*)ws->obj(*t+"_bonly_fitres");
    RooRealVar k(*t+"_b_k","",p_bonly->getParameters(RooArgSet(mgg))->getSize());
    RooRealVar nll(*t+"_b_minNll","",sb->minNll());
    RooRealVar Npts(*t+"_b_N","",blind_data->sumEntries());
    RooFormulaVar AIC(*t+"_b_AIC","2*@0+2*@1+2*@1*(@1+1)/(@2-@1-1)",RooArgSet(nll,k,Npts));
    ws->import(AIC);
    if(AIC.getVal() < minAIC.getVal()) {
      minAIC.setVal(AIC.getVal());
    }
    //aicExpSum+=TMath::Exp(-0.5*AIC.getVal()); //we will need this precomputed  for the next step
    pdfs_bonly.add(*p_bonly);
    pdfs_b.add(*p_b);
  }
  ws->import(minAIC);
  //compute the AIC weight
  float aicExpSum=0;
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    aicExpSum+=TMath::Exp(-0.5*(AIC->getVal()-minAIC.getVal())); //we will need this precomputed  for the next step    
  }
  std::cout << "aicExpSum: " << aicExpSum << std::endl;

  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    RooRealVar *AICw = new RooRealVar(*t+"_b_AICWeight","",TMath::Exp(-0.5*(AIC->getVal()-minAIC.getVal()))/aicExpSum);
    if( TMath::IsNaN(AICw->getVal()) ) {AICw->setVal(0);}
    ws->import(*AICw);
    std::cout << *t << ":  " << AIC->getVal()-minAIC.getVal() << "    " << AICw->getVal() << std::endl;
    weights.add(*AICw);
  }
  RooAddPdf bonly_AIC("bonly_AIC","",pdfs_bonly,weights);
  RooAddPdf b_AIC("b_AIC","",pdfs_b,weights);

  //b_AIC.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
  //RooFitResult* bres = b_AIC.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::Range("sideband_low,sideband_high"));
  //bres->SetName("AIC_b_fitres");
  //ws->import(*bres);

  //make blinded fit
  RooPlot *fmgg_b = mgg.frame(RooFit::Range("sideband_low,sideband_high"));
  blind_data->plotOn(fmgg_b,RooFit::Range("sideband_low,sideband_high"));
  TBox blindBox(121,fmgg_b->GetMinimum()-(fmgg_b->GetMaximum()-fmgg_b->GetMinimum())*0.015,130,fmgg_b->GetMaximum());
  blindBox.SetFillColor(kGray);
  fmgg_b->addObject(&blindBox);
  bonly_AIC.plotOn(fmgg_b,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("sideband_low,sideband_high"));
  fmgg_b->SetName("AIC_blinded_frame");
  ws->import(*fmgg_b);
  delete fmgg_b;
    
#if 1

  RooRealVar sigma("AIC_s_sigma","",5,0,100);
  if(forceSigma!=-1) {
    sigma.setVal(forceSigma);
    sigma.setConstant(true);
  }
  RooRealVar mu("AIC_s_mu","",126,120,132);
  if(forceMu!=-1) {
    mu.setVal(forceMu);
    mu.setConstant(true);
  }
  RooGaussian sig("AIC_sig_model","",mgg,mu,sigma);
  RooRealVar Nsig("AIC_sb_Ns","",5,0,100);
  RooRealVar Nbkg("AIC_sb_Nb","",100,0,100000);
  
  
  RooRealVar HiggsMass("HiggsMass","",125.1);
  RooRealVar HiggsMassError("HiggsMassError","",0.24);
  RooGaussian HiggsMassConstraint("HiggsMassConstraint","",mu,HiggsMass,HiggsMassError);
  
  
  RooAddPdf fitModel("AIC_sb_model","",RooArgList( b_AIC, sig ),RooArgList(Nbkg,Nsig));

  RooFitResult* sbres;
  RooAbsReal *nll;

  if(constrainMu) {
    fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
    nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE),RooFit::ExternalConstraints(RooArgSet(HiggsMassConstraint)));
  } else {
    fitModel.fitTo(data,RooFit::Strategy(0),RooFit::Extended(kTRUE));
    sbres = fitModel.fitTo(data,RooFit::Strategy(2),RooFit::Save(kTRUE),RooFit::Extended(kTRUE));
    nll = fitModel.createNLL(data,RooFit::NumCPU(4),RooFit::Extended(kTRUE));
  }

  assert(nll!=0);
  
  sbres->SetName("AIC_sb_fitres");
  ws->import(*sbres);
  ws->import(fitModel);
  
  RooPlot *fmgg = mgg.frame();
  data.plotOn(fmgg);
  fitModel.plotOn(fmgg);
  ws->pdf("b_AIC")->plotOn(fmgg,RooFit::LineColor(kRed),RooFit::Range("Full"),RooFit::NormRange("Full"));
  fmgg->SetName("AIC_frame");
  ws->import(*fmgg);
  delete fmgg;

  RooMinuit(*nll).migrad();
  
  RooPlot *fNs = Nsig.frame(0,25);
  fNs->SetName("AIC_Nsig_pll");
  RooAbsReal *pll = nll->createProfile(Nsig);
  //nll->plotOn(fNs,RooFit::ShiftToZero(),RooFit::LineColor(kRed));
  pll->plotOn(fNs);
  ws->import(*fNs);
  delete fNs;


  RooPlot *fmu = mu.frame(125,132);
  fmu->SetName("AIC_mu_pll");
  RooAbsReal *pll_mu = nll->createProfile(mu);
  pll_mu->plotOn(fmu);
  ws->import(*fmu);

  delete fmu;

  std::cout << "min AIC: " << minAIC.getVal() << std::endl;
  for(auto t = tags.begin(); t!=tags.end(); t++) {
    RooFormulaVar *AIC = (RooFormulaVar*)ws->obj(*t+"_b_AIC");
    RooRealVar *AICw = ws->var(*t+"_b_AICWeight");
    RooRealVar* k = ws->var(*t+"_b_k");
    printf("%s & %0.0f & %0.2f & %0.2f \\\\\n",t->Data(),k->getVal(),AIC->getVal()-minAIC.getVal(),AICw->getVal());
    //std::cout << k->getVal() << " " << AIC->getVal()-minAIC.getVal() << " " << AICw->getVal() << std::endl;
  }
#endif
  return ws;
}
void performFit(string inputDir, string inputParameterFile, string label,
                string PassInputDataFilename, string FailInputDataFilename, 
                string PassSignalTemplateHistName, string FailSignalTemplateHistName)
{

  gBenchmark->Start("fitZCat");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================
  
  const Double_t mlow  = 60;
  const Double_t mhigh = 120;
  const Int_t    nbins = 24;

  TString effType = inputDir;

  // The fit variable - lepton invariant mass
  RooRealVar* rooMass_ = new RooRealVar("Mass","m_{ee}",mlow, mhigh, "GeV/c^{2}");
  RooRealVar Mass = *rooMass_;
  Mass.setBins(nbins);

  // Make the category variable that defines the two fits,
  // namely whether the probe passes or fails the eff criteria.
  RooCategory sample("sample","") ;
  sample.defineType("Pass", 1) ;
  sample.defineType("Fail", 2) ; 


  RooDataSet *dataPass  = RooDataSet::read((inputDir+PassInputDataFilename).c_str(),RooArgList(Mass));
  RooDataSet *dataFail  = RooDataSet::read((inputDir+FailInputDataFilename).c_str(),RooArgList(Mass));

  RooDataSet *dataCombined = new RooDataSet("dataCombined","dataCombined", RooArgList(Mass), RooFit::Index(sample), 
                                            RooFit::Import("Pass",*dataPass),
                                            RooFit::Import("Fail",*dataFail));



  //*********************************************************************************************
  //Define Free Parameters
  //*********************************************************************************************
  RooRealVar* ParNumSignal =  LoadParameters(inputParameterFile, label,"ParNumSignal");
  RooRealVar* ParNumBkgPass =  LoadParameters(inputParameterFile, label,"ParNumBkgPass");
  RooRealVar* ParNumBkgFail =  LoadParameters(inputParameterFile, label, "ParNumBkgFail");
  RooRealVar* ParEfficiency  = LoadParameters(inputParameterFile, label, "ParEfficiency");
  RooRealVar* ParPassBackgroundExpCoefficient = LoadParameters(inputParameterFile, label, "ParPassBackgroundExpCoefficient");
  RooRealVar* ParFailBackgroundExpCoefficient = LoadParameters(inputParameterFile, label, "ParFailBackgroundExpCoefficient");
  RooRealVar* ParPassSignalMassShift = LoadParameters(inputParameterFile, label, "ParPassSignalMassShift");
  RooRealVar* ParFailSignalMassShift = LoadParameters(inputParameterFile, label, "ParFailSignalMassShift");
  RooRealVar* ParPassSignalResolution = LoadParameters(inputParameterFile, label, "ParPassSignalResolution");
  RooRealVar* ParFailSignalResolution = LoadParameters(inputParameterFile, label, "ParFailSignalResolution");



// new RooRealVar  ("ParPassSignalMassShift","ParPassSignalMassShift",-2.6079e-02,-10.0, 10.0);   //ParPassSignalMassShift->setConstant(kTRUE);  
//   RooRealVar* ParFailSignalMassShift = new RooRealVar  ("ParFailSignalMassShift","ParFailSignalMassShift",7.2230e-01,-10.0, 10.0);   //ParFailSignalMassShift->setConstant(kTRUE);  
//   RooRealVar* ParPassSignalResolution = new RooRealVar ("ParPassSignalResolution","ParPassSignalResolution",6.9723e-01,0.0, 10.0);     ParPassSignalResolution->setConstant(kTRUE);  
//   RooRealVar* ParFailSignalResolution = new RooRealVar ("ParFailSignalResolution","ParFailSignalResolution",1.6412e+00,0.0, 10.0);     ParFailSignalResolution->setConstant(kTRUE);  

  //*********************************************************************************************
  //
  //Load Signal PDFs
  //
  //*********************************************************************************************

  TFile *Zeelineshape_file =  new TFile("res/photonEfffromZee.dflag1.eT1.2.gT40.mt15.root", "READ");
  TH1* histTemplatePass = (TH1D*) Zeelineshape_file->Get(PassSignalTemplateHistName.c_str());
  TH1* histTemplateFail = (TH1D*) Zeelineshape_file->Get(FailSignalTemplateHistName.c_str());

  //Introduce mass shift coordinate transformation 
//   RooFormulaVar PassShiftedMass("PassShiftedMass","@0-@1",RooArgList(Mass,*ParPassSignalMassShift));
//   RooFormulaVar FailShiftedMass("FailShiftedMass","@0-@1",RooArgList(Mass,*ParFailSignalMassShift));

  RooGaussian  *PassSignalResolutionFunction =  new RooGaussian("PassSignalResolutionFunction","PassSignalResolutionFunction",Mass,*ParPassSignalMassShift,*ParPassSignalResolution);
  RooGaussian  *FailSignalResolutionFunction =  new RooGaussian("FailSignalResolutionFunction","FailSignalResolutionFunction",Mass,*ParFailSignalMassShift,*ParFailSignalResolution);


  RooDataHist* dataHistPass = new RooDataHist("dataHistPass","dataHistPass", RooArgSet(Mass), histTemplatePass);
  RooDataHist* dataHistFail = new RooDataHist("dataHistFail","dataHistFail", RooArgSet(Mass), histTemplateFail);
  RooHistPdf* signalShapePassTemplatePdf = new RooHistPdf("signalShapePassTemplatePdf", "signalShapePassTemplatePdf", Mass, *dataHistPass, 1);
  RooHistPdf* signalShapeFailTemplatePdf = new RooHistPdf("signalShapeFailTemplatePdf", "signalShapeFailTemplatePdf", Mass, *dataHistFail, 1);

  RooFFTConvPdf* signalShapePassPdf = new RooFFTConvPdf("signalShapePassPdf","signalShapePassPdf"  , Mass, *signalShapePassTemplatePdf,*PassSignalResolutionFunction,2);
  RooFFTConvPdf* signalShapeFailPdf = new RooFFTConvPdf("signalShapeFailPdf","signalShapeFailPdf"  , Mass, *signalShapeFailTemplatePdf,*FailSignalResolutionFunction,2);


  // Now define some efficiency/yield variables  
  RooFormulaVar* NumSignalPass = new RooFormulaVar("NumSignalPass", "ParEfficiency*ParNumSignal", RooArgList(*ParEfficiency,*ParNumSignal));
  RooFormulaVar* NumSignalFail = new RooFormulaVar("NumSignalFail", "(1.0-ParEfficiency)*ParNumSignal", RooArgList(*ParEfficiency,*ParNumSignal));


  //*********************************************************************************************
  //
  // Create Background PDFs
  //
  //*********************************************************************************************
  RooExponential* bkgPassPdf = new RooExponential("bkgPassPdf","bkgPassPdf",Mass, *ParPassBackgroundExpCoefficient);
  RooExponential* bkgFailPdf = new RooExponential("bkgFailPdf","bkgFailPdf",Mass, *ParFailBackgroundExpCoefficient);


 //*********************************************************************************************
  //
  // Create Total PDFs
  //
  //*********************************************************************************************
  RooAddPdf pdfPass("pdfPass","pdfPass",RooArgList(*signalShapePassPdf,*bkgPassPdf), RooArgList(*NumSignalPass,*ParNumBkgPass));
  RooAddPdf pdfFail("pdfFail","pdfFail",RooArgList(*signalShapeFailPdf,*bkgFailPdf), RooArgList(*NumSignalFail,*ParNumBkgFail));

  // PDF for simultaneous fit
   RooSimultaneous totalPdf("totalPdf","totalPdf", sample);
   totalPdf.addPdf(pdfPass,"Pass");
//    totalPdf.Print();
   totalPdf.addPdf(pdfFail,"Fail");
   totalPdf.Print();


   //*********************************************************************************************
  //
  // Perform Fit
  //
  //*********************************************************************************************
   RooFitResult *fitResult = 0;

  // ********* Fix with Migrad first ********** //  
   fitResult = totalPdf.fitTo(*dataCombined, RooFit::Save(true), 
                              RooFit::Extended(true), RooFit::PrintLevel(-1));
   fitResult->Print("v");


//   // ********* Fit With Minos ********** //  
//    fitResult = totalPdf.fitTo(*dataCombined, RooFit::Save(true), 
//                               RooFit::Extended(true), RooFit::PrintLevel(-1), RooFit::Minos());
//    fitResult->Print("v");




//   // ********* Fix Mass Shift and Fit For Resolution ********** //  
//    ParPassSignalMassShift->setConstant(kTRUE); 
//    ParFailSignalMassShift->setConstant(kTRUE); 
//    ParPassSignalResolution->setConstant(kFALSE); 
//    ParFailSignalResolution->setConstant(kFALSE); 
//    fitResult = totalPdf.fitTo(*dataCombined, RooFit::Save(true), 
//    RooFit::Extended(true), RooFit::PrintLevel(-1));
//    fitResult->Print("v");


//   // ********* Do Final Fit ********** //  
//    ParPassSignalMassShift->setConstant(kFALSE); 
//    ParFailSignalMassShift->setConstant(kFALSE); 
//    ParPassSignalResolution->setConstant(kTRUE); 
//    ParFailSignalResolution->setConstant(kTRUE); 
//    fitResult = totalPdf.fitTo(*dataCombined, RooFit::Save(true), 
//                                             RooFit::Extended(true), RooFit::PrintLevel(-1));
//    fitResult->Print("v");





  double nSignalPass = NumSignalPass->getVal();
  double nSignalFail    = NumSignalFail->getVal();
  double denominator = nSignalPass + nSignalFail;

  printf("\nFit results:\n");
  if( fitResult->status() != 0 ){
    std::cout<<"ERROR: BAD FIT STATUS"<<std::endl;
  }

  printf("    Efficiency = %.4f +- %.4f\n", 
	 ParEfficiency->getVal(), ParEfficiency->getPropagatedError(*fitResult));  
  cout << "Signal Pass: "******"Signal Fail: " << nSignalFail << endl;

  cout << "*********************************************************************\n";
  cout << "Final Parameters\n";
  cout << "*********************************************************************\n";
  PrintParameter(ParNumSignal, label,"ParNumSignal");
  PrintParameter(ParNumBkgPass, label,"ParNumBkgPass");
  PrintParameter(ParNumBkgFail, label, "ParNumBkgFail");
  PrintParameter(ParEfficiency  , label, "ParEfficiency");
  PrintParameter(ParPassBackgroundExpCoefficient , label, "ParPassBackgroundExpCoefficient");
  PrintParameter(ParFailBackgroundExpCoefficient , label, "ParFailBackgroundExpCoefficient");
  PrintParameter(ParPassSignalMassShift , label, "ParPassSignalMassShift");
  PrintParameter(ParFailSignalMassShift , label, "ParFailSignalMassShift");
  PrintParameter(ParPassSignalResolution , label, "ParPassSignalResolution");
  PrintParameter(ParFailSignalResolution , label, "ParFailSignalResolution");
  cout << endl << endl;


  //--------------------------------------------------------------------------------------------------------------
  // Make plots 
  //==============================================================================================================  
  TFile *canvasFile = new TFile("Efficiency_FitResults.root", "UPDATE");


  RooAbsData::ErrorType errorType = RooAbsData::Poisson;

  Mass.setBins(NBINSPASS);
  TString cname = TString((label+"_Pass").c_str());
  TCanvas *c = new TCanvas(cname,cname,800,600);
  RooPlot* frame1 = Mass.frame();
  frame1->SetMinimum(0);
  dataPass->plotOn(frame1,RooFit::DataError(errorType));
  pdfPass.plotOn(frame1,RooFit::ProjWData(*dataPass), 
  RooFit::Components(*bkgPassPdf),RooFit::LineColor(kRed));
  pdfPass.plotOn(frame1,RooFit::ProjWData(*dataPass));
  frame1->Draw("e0");
  
  TPaveText *plotlabel = new TPaveText(0.23,0.87,0.43,0.92,"NDC");
   plotlabel->SetTextColor(kBlack);
   plotlabel->SetFillColor(kWhite);
   plotlabel->SetBorderSize(0);
   plotlabel->SetTextAlign(12);
   plotlabel->SetTextSize(0.03);
   plotlabel->AddText("CMS Preliminary 2010");
  TPaveText *plotlabel2 = new TPaveText(0.23,0.82,0.43,0.87,"NDC");
   plotlabel2->SetTextColor(kBlack);
   plotlabel2->SetFillColor(kWhite);
   plotlabel2->SetBorderSize(0);
   plotlabel2->SetTextAlign(12);
   plotlabel2->SetTextSize(0.03);
   plotlabel2->AddText("#sqrt{s} = 7 TeV");
  TPaveText *plotlabel3 = new TPaveText(0.23,0.75,0.43,0.80,"NDC");
   plotlabel3->SetTextColor(kBlack);
   plotlabel3->SetFillColor(kWhite);
   plotlabel3->SetBorderSize(0);
   plotlabel3->SetTextAlign(12);
   plotlabel3->SetTextSize(0.03);
  char temp[100];
  sprintf(temp, "%.4f", LUMINOSITY);
  plotlabel3->AddText((string("#int#font[12]{L}dt = ") + 
  temp + string(" pb^{ -1}")).c_str());
  TPaveText *plotlabel4 = new TPaveText(0.6,0.82,0.8,0.87,"NDC");
   plotlabel4->SetTextColor(kBlack);
   plotlabel4->SetFillColor(kWhite);
   plotlabel4->SetBorderSize(0);
   plotlabel4->SetTextAlign(12);
   plotlabel4->SetTextSize(0.03);
   double nsig = ParNumSignal->getVal();
   double nErr = ParNumSignal->getError();
   double e = ParEfficiency->getVal();
   double eErr = ParEfficiency->getError();
   double corr = fitResult->correlation(*ParEfficiency, *ParNumSignal);
   double err = ErrorInProduct(nsig, nErr, e, eErr, corr);
   sprintf(temp, "Signal = %.2f #pm %.2f", NumSignalPass->getVal(), err);
   plotlabel4->AddText(temp);
   TPaveText *plotlabel5 = new TPaveText(0.6,0.77,0.8,0.82,"NDC");
   plotlabel5->SetTextColor(kBlack);
   plotlabel5->SetFillColor(kWhite);
   plotlabel5->SetBorderSize(0);
   plotlabel5->SetTextAlign(12);
   plotlabel5->SetTextSize(0.03);
   sprintf(temp, "Bkg = %.2f #pm %.2f", ParNumBkgPass->getVal(), ParNumBkgPass->getError());
   plotlabel5->AddText(temp);
   TPaveText *plotlabel6 = new TPaveText(0.6,0.87,0.8,0.92,"NDC");
   plotlabel6->SetTextColor(kBlack);
   plotlabel6->SetFillColor(kWhite);
   plotlabel6->SetBorderSize(0);
   plotlabel6->SetTextAlign(12);
   plotlabel6->SetTextSize(0.03);
   plotlabel6->AddText("Passing probes");
   TPaveText *plotlabel7 = new TPaveText(0.6,0.72,0.8,0.77,"NDC");
   plotlabel7->SetTextColor(kBlack);
   plotlabel7->SetFillColor(kWhite);
   plotlabel7->SetBorderSize(0);
   plotlabel7->SetTextAlign(12);
   plotlabel7->SetTextSize(0.03); 
   sprintf(temp, "Eff = %.3f #pm %.3f", ParEfficiency->getVal(), ParEfficiency->getErrorHi());
   plotlabel7->AddText(temp);
   TPaveText *plotlabel8 = new TPaveText(0.6,0.72,0.8,0.66,"NDC");
   plotlabel8->SetTextColor(kBlack);
   plotlabel8->SetFillColor(kWhite);
   plotlabel8->SetBorderSize(0);
   plotlabel8->SetTextAlign(12);
   plotlabel8->SetTextSize(0.03);
   sprintf(temp, "#chi^{2}/DOF = %.3f", frame1->chiSquare());
   plotlabel8->AddText(temp);

  plotlabel4->Draw();
  plotlabel5->Draw();
  plotlabel6->Draw();
  plotlabel7->Draw();
  plotlabel8->Draw();

//   c->SaveAs( cname + TString(".eps"));
  c->SaveAs( cname + TString(".gif"));
  canvasFile->WriteTObject(c, c->GetName(), "WriteDelete");

 
  Mass.setBins(NBINSFAIL);
  cname = TString((label+"_Fail").c_str());
  TCanvas* c2 = new TCanvas(cname,cname,800,600);
  RooPlot* frame2 = Mass.frame();
  frame2->SetMinimum(0);
  dataFail->plotOn(frame2,RooFit::DataError(errorType));
  pdfFail.plotOn(frame2,RooFit::ProjWData(*dataFail), 
  RooFit::Components(*bkgFailPdf),RooFit::LineColor(kRed));
  pdfFail.plotOn(frame2,RooFit::ProjWData(*dataFail));
  frame2->Draw("e0");

  plotlabel = new TPaveText(0.23,0.87,0.43,0.92,"NDC");
   plotlabel->SetTextColor(kBlack);
   plotlabel->SetFillColor(kWhite);
   plotlabel->SetBorderSize(0);
   plotlabel->SetTextAlign(12);
   plotlabel->SetTextSize(0.03);
   plotlabel->AddText("CMS Preliminary 2010");
 plotlabel2 = new TPaveText(0.23,0.82,0.43,0.87,"NDC");
   plotlabel2->SetTextColor(kBlack);
   plotlabel2->SetFillColor(kWhite);
   plotlabel2->SetBorderSize(0);
   plotlabel2->SetTextAlign(12);
   plotlabel2->SetTextSize(0.03);
   plotlabel2->AddText("#sqrt{s} = 7 TeV");
  plotlabel3 = new TPaveText(0.23,0.75,0.43,0.80,"NDC");
   plotlabel3->SetTextColor(kBlack);
   plotlabel3->SetFillColor(kWhite);
   plotlabel3->SetBorderSize(0);
   plotlabel3->SetTextAlign(12);
   plotlabel3->SetTextSize(0.03);
   sprintf(temp, "%.4f", LUMINOSITY);
   plotlabel3->AddText((string("#int#font[12]{L}dt = ") + 
                        temp + string(" pb^{ -1}")).c_str());
   plotlabel4 = new TPaveText(0.6,0.82,0.8,0.87,"NDC");
   plotlabel4->SetTextColor(kBlack);
   plotlabel4->SetFillColor(kWhite);
   plotlabel4->SetBorderSize(0);
   plotlabel4->SetTextAlign(12);
   plotlabel4->SetTextSize(0.03);
   err = ErrorInProduct(nsig, nErr, 1.0-e, eErr, corr);
   sprintf(temp, "Signal = %.2f #pm %.2f", NumSignalFail->getVal(), err);
   plotlabel4->AddText(temp);
   plotlabel5 = new TPaveText(0.6,0.77,0.8,0.82,"NDC");
   plotlabel5->SetTextColor(kBlack);
   plotlabel5->SetFillColor(kWhite);
   plotlabel5->SetBorderSize(0);
   plotlabel5->SetTextAlign(12);
   plotlabel5->SetTextSize(0.03);
   sprintf(temp, "Bkg = %.2f #pm %.2f", ParNumBkgFail->getVal(), ParNumBkgFail->getError());
   plotlabel5->AddText(temp);
   plotlabel6 = new TPaveText(0.6,0.87,0.8,0.92,"NDC");
   plotlabel6->SetTextColor(kBlack);
   plotlabel6->SetFillColor(kWhite);
   plotlabel6->SetBorderSize(0);
   plotlabel6->SetTextAlign(12);
   plotlabel6->SetTextSize(0.03);
   plotlabel6->AddText("Failing probes");
   plotlabel7 = new TPaveText(0.6,0.72,0.8,0.77,"NDC");
   plotlabel7->SetTextColor(kBlack);
   plotlabel7->SetFillColor(kWhite);
   plotlabel7->SetBorderSize(0);
   plotlabel7->SetTextAlign(12);
   plotlabel7->SetTextSize(0.03);
   sprintf(temp, "Eff = %.3f #pm %.3f", ParEfficiency->getVal(), ParEfficiency->getErrorHi(), ParEfficiency->getErrorLo());
   plotlabel7->AddText(temp);
   plotlabel8 = new TPaveText(0.6,0.72,0.8,0.66,"NDC");
   plotlabel8->SetTextColor(kBlack);
   plotlabel8->SetFillColor(kWhite);
   plotlabel8->SetBorderSize(0);
   plotlabel8->SetTextAlign(12);
   plotlabel8->SetTextSize(0.03);
   sprintf(temp, "#chi^{2}/DOF = %.3f", frame2->chiSquare());
   plotlabel8->AddText(temp);

//   plotlabel->Draw();
//   plotlabel2->Draw();
//   plotlabel3->Draw();
  plotlabel4->Draw();
  plotlabel5->Draw();
  plotlabel6->Draw();
  plotlabel7->Draw();
  plotlabel8->Draw();

  c2->SaveAs( cname + TString(".gif"));
//   c2->SaveAs( cname + TString(".eps"));
//   c2->SaveAs( cname + TString(".root"));
  canvasFile->WriteTObject(c2, c2->GetName(), "WriteDelete");

  canvasFile->Close();

  
  effTextFile.width(40);
  effTextFile << label;
  effTextFile.width(20);
  effTextFile  << setiosflags(ios::fixed) << setprecision(4) << left << ParEfficiency->getVal() ;
  effTextFile.width(20);
  effTextFile  << left << ParEfficiency->getErrorHi();
  effTextFile.width(20);
  effTextFile  << left << ParEfficiency->getErrorLo();
  effTextFile.width(14);
  effTextFile  << setiosflags(ios::fixed) << setprecision(2) << left << nSignalPass ;
  effTextFile.width(14);
  effTextFile << left << nSignalFail << endl;

} 
Example #3
0
///v1 using unbinnned fit
//input data text file
void FitTagAndProbev1(char *datafile_pass, char *datafile_fail, char *mcRootFile, char *mcPassHist, char *mcFailHist, float xminFit, float xmaxFit, bool SetPassBkgZero,bool SetFailBkgZero){


  gROOT->cd();
  gROOT->Reset();

  gSystem->Load("libRooFit") ;
  gSystem->Load("libRooFitCore") ;



  RooRealVar* rooMass_ = new RooRealVar("Mass","m_{#mu#mu}",xminFit, xmaxFit, "GeV/c^{2}");
  RooRealVar Mass = *rooMass_;


  // Make the category variable that defines the two fits,
  // namely whether the probe passes or fails the eff criteria.
  RooCategory sample("sample","") ;
  sample.defineType("Pass", 1) ;
  sample.defineType("Fail", 2) ;

  ///////// convert Histograms into RooDataHists
  //RooDataHist* data_pass = new RooDataHist("data_pass","data_pass",
  //RooArgList(Mass), hist_pass);

  RooDataSet *data_pass = RooDataSet::read(datafile_pass,RooArgSet(Mass));
  //RooDataHist* data_fail = new RooDataHist("data_fail","data_fail",
  //RooArgList(Mass), hist_fail);
  RooDataSet *data_fail = RooDataSet::read(datafile_fail,RooArgSet(Mass));

  cout<<data_pass->sumEntries()<<" " <<data_fail->sumEntries()<<endl;



  //  RooDataHist* data = new RooDataHist( "fitData","fitData",
  //				       RooArgList(Mass),RooFit::Index(sample),
  //				       RooFit::Import("Pass",*hist_pass), RooFit::Import("Fail",*hist_fail) );

  RooDataSet* data = new RooDataSet( "fitData","fitData",RooArgList(Mass),RooFit::Index(sample),RooFit::Import("Pass",*data_pass),RooFit::Import("Fail",*data_fail) );


  // Signal pdf

  //TFile *Zeelineshape_file =  new TFile("res/testTagProbe.dm2.dflag2.mT1.root","read");

  //  TFile *Zeelineshape_file =  new TFile("res/testTagProbe.dm2.dflag2.mT1.cha1.mt30.root","read");
  //res/testTagProbe.dm2.dflag2.mT1.cha1.mt30.root

  //TFile *Zeelineshape_file =  new TFile("res/testTagProbe.dm2.dflag3.mT1.cha0.mt-1.pu1.root","read");




    TFile *Zeelineshape_file =  new TFile(mcRootFile,"read");

  TH1F *th1 = (TH1F*)Zeelineshape_file->Get(mcPassHist);

 //  ///int nbins = th1->GetNbinsX();
//   int nbins = int( (xmaxFit - xminFit+0.1) / th1->GetBinWidth(1));
//   int rebin = 2;
//   nbins = nbins/ rebin;

//   cout<<"nbins: "<< nbins <<endl;


//   th1->Rebin(rebin);

  int nbins = 60;



  RooDataHist* rdh = new RooDataHist("rdh","", Mass, th1);
  TH1 *th1f = (TH1F*)Zeelineshape_file->Get(mcFailHist);
  RooDataHist* rdhf = new RooDataHist("rdh","", Mass, th1f);



  const char *passHistName = th1->GetName();
  const char *failHistName = th1f->GetName();

  const char *passHistTitle = th1->GetTitle();
  const char *failHistTitle = th1->GetTitle();

  float xlowMC = th1->GetXaxis()->GetXmin();
  float xmaxMC = th1->GetXaxis()->GetXmax();
  if( xminFit < xlowMC  || xmaxFit > xmaxMC ){
    cout<<"FitRangeNotMC "<< xlowMC <<"to"<< xmaxMC <<" MC "<<endl;
    return;
  }
  int startbin = int((xminFit-xlowMC+0.001)/th1->GetBinWidth(1)) + 1;
  int endbin = int((xmaxFit-xlowMC+0.001)/th1->GetBinWidth(1));
  float passMC = th1->Integral(startbin,endbin);
  float allMC = th1->Integral(startbin,endbin) +  th1f->Integral(startbin,endbin);
  float effTP_MC =  passMC / allMC;
  float effTP_MCerr = sqrt( effTP_MC * (1- effTP_MC)/ allMC);
  //  float effTP_MC =  th1->Integral() / ( th1->Integral() + th1f->Integral());




  //RooRealVar* rooMass1_ = new RooRealVar("Mass","m_{#mu#mu}",xminFit, xmaxFit, "GeV/c^{2}");
  //RooRealVar Mass1 = *rooMass1_;

  // RooRealVar* massShift = new RooRealVar("massShift","massShift",0.,-2,2);
  //RooFormulaVar* rooMass1_ = new RooFormulaVar("Mass1", "(1-massShift)*Mass", RooArgList(*massShift,Mass));
  //RooFormulaVar Mass1 = *rooMass1_;

  RooHistPdf* signalShapePdfPass = new RooHistPdf("signalShapePdf", "",
						  RooArgSet(Mass), *rdh,1);

  RooHistPdf* signalShapePdfFail = new RooHistPdf("signalShapePdf", "",
						  RooArgSet(Mass), *rdhf,1);


  RooRealVar  cbBias ("#Deltam_{CB}", "CB Bias", 0.05, -2, 2,"GeV/c^{2}");
  RooRealVar  cbSigma("#sigma_{CB}","CB Width", 1.38, 0.01, 10.0,"GeV/c^{2}");
  RooRealVar  cbCut  ("a_{CB}","CB Cut", 1.5, 0.1, 2.0);
  RooRealVar  cbPower("n_{CB}","CB Power", 1.3, 0.1, 20.0);
  RooRealVar bwMean("m_{Z}","BW Mean", 91.1876, "GeV/c^{2}");
  RooRealVar bwWidth("#Gamma_{Z}", "BW Width", 2.4952, "GeV/c^{2}");
  RooBreitWigner bw("bw", "bw", Mass, bwMean, bwWidth);
  RooCBShape     cball("cball", "A  Crystal Ball Lineshape", Mass, cbBias, cbSigma, cbCut, cbPower);
  RooFFTConvPdf BWxCB("BWxCB","bw (X) crystall ball", Mass, bw, cball);




  // Background pass PDF

  RooRealVar* bkgShape = new RooRealVar("bkgShape","bkgShape",-0.2,-10.,0.);

  if(SetPassBkgZero){
    bkgShape = new RooRealVar("bkgShape","bkgShape",0.,0.,0.);
  }

  RooExponential* bkgShapePdf = new RooExponential("bkgShapePdf","bkgShapePdf",Mass, *bkgShape);

  // Background fail PDF
  RooRealVar* bkgShapef = new RooRealVar("bkgShapef","bkgShape",-0.2,-10.,0.);
  if(SetFailBkgZero){
    bkgShapef = new RooRealVar("bkgShapef","bkgShape",0.,0.,0.);
  }

  RooExponential* bkgShapePdff = new RooExponential("bkgShapePdff","bkgShapePdff",Mass, *bkgShapef);
  //RooGenericPdf* bkgShapePdff = new RooGenericPdf("bkgShapePdff","bkgShapePdff","pow(Mass,bkgShapef)",RooArgSet(Mass, *bkgShapef));

  // Now define some efficiency/yield variables


  RooRealVar* numSignal = new RooRealVar("numSignal","numSignal", 100, 0.0, 1000000.0);
  RooRealVar* eff = new RooRealVar("eff","eff", 0.9, 0.2, 1.0);
  RooFormulaVar* nSigPass = new RooFormulaVar("nSigPass", "eff*numSignal", RooArgList(*eff,*numSignal));
  RooFormulaVar* nSigFail = new RooFormulaVar("nSigFail", "(1.0-eff)*numSignal", RooArgList(*eff,*numSignal));

  RooRealVar* nBkgPass = new RooRealVar("nBkgPass","nBkgPass", 100, 0.0, 10000000);
  if(SetPassBkgZero){
    nBkgPass = new RooRealVar("nBkgPass","nBkgPass", 0., 0., 0.);
  }


  RooRealVar* nBkgFail = new RooRealVar("nBkgFail","nBkgFail", 100, 0.0, 10000000);
  if(SetFailBkgZero){
    nBkgFail = new RooRealVar("nBkgFail","nBkgFail", 0.,0.,0.);
  }



  RooArgList componentsPass(*signalShapePdfPass,*bkgShapePdf);
  RooArgList yieldsPass(*nSigPass, *nBkgPass);

  RooArgList componentsFail(*signalShapePdfFail,*bkgShapePdff);
  // RooArgList componentsFail(BWxCB,*bkgShapePdff);


  RooArgList yieldsFail(*nSigFail, *nBkgFail);


   RooAddPdf pdfPass("pdfPass","extended sum pdf", componentsPass, yieldsPass);
   RooAddPdf pdfFail("pdfFail","extended sum pdf", componentsFail, yieldsFail);


   // The total simultaneous fit ...
   RooSimultaneous totalPdf("totalPdf","totalPdf", sample);
   totalPdf.addPdf(pdfPass,"Pass");
   totalPdf.Print();
   totalPdf.addPdf(pdfFail,"Fail");
   totalPdf.Print();


   ifstream readinfail(datafile_fail,ios::in);
   float mm;
   int ndataFailPeak = 0;
   while(readinfail.good()){
    if( readinfail.eof()) break;
    readinfail>>mm;

    if( mm> 80 && mm <100){
      ndataFailPeak ++;
    }

   }


   // ********* Do the Actual Fit ********** //

   RooFitResult *fitResult = totalPdf.fitTo(*data,RooFit::Save(true),
					    RooFit::Extended(true), RooFit::PrintLevel(-1));

   fitResult->Print("v");


  double numerator = nSigPass->getVal();
  double nfails    = nSigFail->getVal();
  double denominator = numerator + nfails;

  cout<<"num/den: "<< numerator <<" "<< denominator <<endl;

   RooAbsData::ErrorType errorType = RooAbsData::Poisson;

   TCanvas *can0 = new TCanvas("can0","c000",200,10,550,500);
   setTCanvasNicev1(can0);

   //RooPlot* frame1 = Mass.frame();
   RooPlot* frame1 = Mass.frame(Range(xminFit,xmaxFit),Bins(nbins));

   frame1->SetMinimum(0);
   data_pass->plotOn(frame1,RooFit::DataError(errorType));
   pdfPass.plotOn(frame1,RooFit::ProjWData(*data_pass),
		  RooFit::Components(*bkgShapePdf),RooFit::LineColor(kRed));
   pdfPass.plotOn(frame1,RooFit::ProjWData(*data_pass));
   frame1->Draw("e0");

   char *filename = new char[1000];
   sprintf(filename,"Probe Pass %s",passHistTitle);
   TLatex l;
   l.SetNDC();
   l.SetTextSize(0.04);
   l.SetTextColor(1);
   l.DrawLatex(0.2,0.9,filename);
   double nsig = numSignal->getVal();
   double nErr = numSignal->getError();
   double e = eff->getVal();
   double eErr = eff->getError();
   double corr = fitResult->correlation(*eff, *numSignal);
   double err = ErrorInProduct(nsig, nErr, e, eErr, corr);
   sprintf(filename, "N_{s} = %.2f #pm %.2f", nSigPass->getVal(), err);
   l.DrawLatex(0.62,0.8,filename);
   sprintf(filename, "N_{b} = %.2f #pm %.2f", nBkgPass->getVal(), nBkgPass->getError());
   l.DrawLatex(0.62,0.75,filename);
   sprintf(filename, "#epsilon^{Data}_{s} = %4.3f #pm %4.3f", eff->getVal(), eff->getError());
   l.DrawLatex(0.62,0.7,filename);
   sprintf(filename, "#epsilon^{MC}_{s} = %4.3f", effTP_MC);
   l.DrawLatex(0.62,0.65,filename);


   sprintf(filename,"resTP/hhu_probepass_%s.gif",passHistName);
   can0->Print(filename);
   sprintf(filename,"resTP/hhu_probepass_%s.pdf",passHistName);
   can0->Print(filename);


   //probel fail

   TCanvas *can1 = new TCanvas("can1","c001",200,10,550,500);
   setTCanvasNicev1(can1);
   //RooPlot* frame1f = Mass.frame();
   //RooPlot* frame1f = Mass.frame(Range(xminFit,xmaxFit),Bins(nbins));
   RooPlot* frame1f = Mass.frame(Range(xminFit,xmaxFit),Bins(30));
   frame1f->SetMinimum(0);
   data_fail->plotOn(frame1f,RooFit::DataError(errorType));
   pdfFail.plotOn(frame1f,RooFit::ProjWData(*data_fail),
		  RooFit::Components(*bkgShapePdff),RooFit::LineColor(kRed));
   pdfFail.plotOn(frame1f,RooFit::ProjWData(*data_fail));
   frame1f->Draw("e0");

   sprintf(filename,"Probe Fail %s", failHistTitle);
   l.DrawLatex(0.2,0.9,filename);
   nsig = numSignal->getVal();
   nErr = numSignal->getError();
   e = 1-eff->getVal();
   eErr = eff->getError();
   corr = fitResult->correlation(*eff, *numSignal);
   err = ErrorInProduct(nsig, nErr, e, eErr, corr);
   sprintf(filename, "N_{s} = %.2f #pm %.2f", nSigFail->getVal(), err);
   l.DrawLatex(0.6,0.8,filename);
   sprintf(filename, "N_{b} = %.2f #pm %.2f", nBkgFail->getVal(), nBkgFail->getError());
   l.DrawLatex(0.6,0.75,filename);
   sprintf(filename, "#epsilon^{Data}_{s} = %3.3f #pm %3.3f", eff->getVal(), eff->getError());
   //l.DrawLatex(0.65,0.6,filename);
   sprintf(filename, "#epsilon^{MC}_{s} = %3.3f", effTP_MC);
   //l.DrawLatex(0.6,0.5,filename);

   sprintf(filename,"resTP/hhu_probefail_%s.pdf",failHistName);
   can1->Print(filename);
   sprintf(filename,"resTP/hhu_probefail_%s.gif",failHistName);
   can1->Print(filename);


   cout<<"effMC: "<< effTP_MC <<" +/- " <<effTP_MCerr <<endl;
   cout<<"eff: "<< eff->getVal() <<" +/- " << eff->getError() <<endl;

   cout<<"ndataPeakFail " << ndataFailPeak <<endl;

}
//-------------------------------------------------------------
//Main macro for generating data and fitting
//=============================================================  
void FitMassTwoD(const string workspaceFile = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/FitWorkspace_asdf.root", const string outputTree = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/MassFitResults/MassFitTwoD_asdf.root", Int_t plotOption = 0, Int_t storeOption = 1, Int_t constBkg = 1, Int_t NToys = 5000) {

  TRandom3 *randomnumber = new TRandom3(1200);
  TFile *wsFile = new TFile (workspaceFile.c_str(), "READ");
  RooWorkspace *ws = (RooWorkspace*)wsFile->Get("MassFitWorkspace");
  
  //Import variables from workspace
  RooAbsPdf *model2Dpdf = ws->pdf("model2Dpdf");
  RooRealVar *massBjet = ws->var("massBjet");
  RooRealVar *massPho = ws->var("massPho");
  RooRealVar *HHHCoupling = ws->var("HHHCoupling"); RooRealVar constHHHCoupling(*HHHCoupling);
  RooRealVar *nres = ws->var("N (ResBkg)"); RooRealVar constNres(*nres);
  RooRealVar *nnonres = ws->var("N (NonResBkg)"); RooRealVar constNnonres(*nnonres);
  RooRealVar *expRateBjet = ws->var("expRateBjet"); RooRealVar constexpBjet(*expRateBjet);
  RooRealVar *expRatePho = ws->var("expRatePho"); RooRealVar constexpPho(*expRatePho);
  RooFormulaVar *nsig = (RooFormulaVar*)ws->function("nsig"); 

  if (constBkg == 0) { 
    expRateBjet->setConstant(false);
    expRatePho->setConstant(false);
  } else {
    expRateBjet->setConstant(true);
    expRatePho->setConstant(true);
  }

  //Variables to set constant
  RooRealVar *sigMeanBjet = ws->var("sigMeanBjet"); sigMeanBjet->setConstant();
  RooRealVar *sigSigmaBjet = ws->var("sigSigmaBjet"); sigSigmaBjet->setConstant();
  RooRealVar *sigAlpha = ws->var("sigAlpha"); sigAlpha->setConstant();
  RooRealVar *sigPower = ws->var("sigPower"); sigPower->setConstant();
  RooRealVar *resMeanBjet = ws->var("resMeanBjet"); resMeanBjet->setConstant();
  RooRealVar *resSigmaBjet = ws->var("resSigmaBjet"); resSigmaBjet->setConstant();
  RooRealVar *resAlpha = ws->var("resAlpha"); resAlpha->setConstant();
  RooRealVar *resPower = ws->var("resPower"); resPower->setConstant();
  RooRealVar *resExpo = ws->var("resExpo"); resExpo->setConstant();
  RooRealVar *nbbH = ws->var("nbbH"); nbbH->setConstant();
  RooRealVar *nOthers = ws->var("nOthers"); nOthers->setConstant();
  
  //Create TTree to store the resulting yield data
  TFile *f = new TFile(outputTree.c_str(), "RECREATE");
  TTree *resultTree = new TTree("resultTree", "Parameter results from fitting");
  Float_t nsigOut, nresOut, nnonresOut;
  Float_t nsigStd, nresStd, nnonresStd;
  Float_t HHHCouplingOut, HHHCouplingStd;
  
  resultTree->Branch("nsigOut",&nsigOut, "nsigOut/F");
  resultTree->Branch("nresOut",&nresOut, "nresOut/F");
  resultTree->Branch("nnonresOut",&nnonresOut, "nnonresOut/F");
  resultTree->Branch("nsigStd",&nsigStd, "nsigStd/F");
  resultTree->Branch("nresStd",&nresStd, "nresStd/F");
  resultTree->Branch("nnonresStd",&nnonresStd, "nnonresStd/F");
  resultTree->Branch("HHHCouplingOut",&HHHCouplingOut, "HHHCouplingOut/F");
  resultTree->Branch("HHHCouplingStd",&HHHCouplingStd, "HHHCouplingStd/F");
  
  //Generate Toy MC experiment data and fits
  for(UInt_t t=0; t < NToys; ++t) {
    cout << "Toy #" << t << endl;
    HHHCoupling->setVal(constHHHCoupling.getVal()); nres->setVal(constNres.getVal()); nnonres->setVal(constNnonres.getVal());
    expRateBjet->setVal(constexpBjet.getVal()); expRatePho->setVal(constexpPho.getVal());

    Float_t ran = randomnumber->Poisson(325.);
    RooDataSet *pseudoData2D = model2Dpdf->generate(RooArgList(*massBjet,*massPho), ran);
    RooFitResult *fitResult2D = model2Dpdf->fitTo(*pseudoData2D, RooFit::Save(), RooFit::Extended(kTRUE), RooFit::Strategy(2));

//     if (t == 1763) {
//     	ws->import(*pseudoData2D, kTRUE);
//     	ws->import(*pseudoData2D, Rename("pseudoData2D"));
//     }
//     if (plotOption == 1) MakePlots(ws, fitResult2D);
    

//     cout << "DEBUG: " << constexpBjet.getVal() << " , " << constexpPho.getVal() << " | " << expRateBjet->getVal() << " " << expRatePho->getVal() << "\n";
    cout << "DEBUG: " << HHHCoupling->getVal() << " " << HHHCoupling->getPropagatedError(*fitResult2D) << "\n";


    //Store fit parameters into ROOT file
    if (storeOption == 1) {
      //Save variables into separate branches of root tree
      
      nsigOut = nsig->getVal();
      nresOut = nres->getVal();
      nnonresOut = nnonres->getVal();
      nsigStd = nsig->getPropagatedError(*fitResult2D);
      nresStd = nres->getPropagatedError(*fitResult2D);
      nnonresStd = nnonres->getPropagatedError(*fitResult2D);
      HHHCouplingOut = HHHCoupling->getVal();
      HHHCouplingStd = HHHCoupling->getPropagatedError(*fitResult2D);

      //cout << "\n\n\n\n\n\n" << nsigOut << " | " << nresOut << " | " << nnonresOut << " | " << ran  << "\n\n\n\n\n" << endl;
      resultTree->Fill();
    }
  }
  
  //Write to the TTree and close it
  resultTree->Write();
  f->Close();
}