void addNuisanceWithToys(std::string iFileName,std::string iChannel,std::string iBkg,std::string iEnergy,std::string iName,std::string iDir,bool iRebin=true,bool iVarBin=false,int iFitModel=1,int iFitModel1=1,double iFirst=150,double iLast=1500,std::string iSigMass="800",double iSigScale=0.1,int iNToys=1000) { 
  std::cout << "======> " << iDir << "/" << iBkg << " -- " << iFileName << std::endl;  
  if(iVarBin) std::cout << "option not implemented yet!";
  if(iVarBin) return;
  //double lFirst = 200;
  //double lLast  = 1500;
  double lFirst = iFirst;
  double lLast  = iLast;

  std::cout << "===================================================================================================================================================" <<std::endl;
  std::cout << "Using Initial fit model: " << iFitModel << ", fitting range: " << iFirst << "-" << iLast << " , using alternative fit model: " << iFitModel1 << std::endl; 
  std::cout << "===================================================================================================================================================" <<std::endl;

  TFile *lFile = new TFile(iFileName.c_str());
  TH1F  *lH0   = (TH1F*) lFile->Get((iDir+"/"+iBkg).c_str());
  TH1F  *lData = (TH1F*) lFile->Get((iDir+"/data_obs").c_str());
  TH1F  *lSig = 0;

  // for now, use bbH signal for testing in b-tag and ggH in no-btag
  if(iDir.find("_btag") != std::string::npos) lSig = (TH1F*)lFile->Get((iDir+"/bbH"+iSigMass+"_fine_binning").c_str());
  else lSig = (TH1F*)lFile->Get((iDir+"/ggH"+iSigMass+"_fine_binning").c_str());

  TH1F *lH0Clone = (TH1F*)lH0->Clone("lH0Clone");     // binning too fine as of now? start by rebinning
  TH1F *lDataClone = (TH1F*)lData->Clone("lDataClone");   
  TH1F *lSigClone = (TH1F*)lSig->Clone("lSigClone");  
 // lH0Clone->Rebin(2);
 // lDataClone->Rebin(2);
 // lSigClone->Rebin(2);

  lSig->Rebin(10);  

  //Define the fit function
  RooRealVar lM("m","m" ,0,5000);
  lM.setRange(lFirst,lLast);
  RooRealVar lA("a","a" ,50,  0.1,200);
  RooRealVar lB("b","b" ,0.0 , -10.5,10.5);
  RooRealVar lA1("a1","a1" ,50,  0.1,1000);
  RooRealVar lB1("b1","b1" ,0.0 , -10.5,10.5);

  RooDataHist *pH0  =  new RooDataHist("Data","Data" ,RooArgList(lM),lH0);
  double lNB0 = lH0->Integral(lH0->FindBin(lFirst),lH0->FindBin(lLast));
  double lNSig0 = lSig->Integral(lSig->FindBin(lFirst),lSig->FindBin(lLast));
 //lNB0=500;
// lNSig0=500;
 lSig->Scale(iSigScale*lNB0/lNSig0);                                         // scale signal to iSigScale*(Background yield), could try other options
 lNSig0 = lSig->Integral(lSig->FindBin(lFirst),lSig->FindBin(lLast));        // readjust norm of signal hist   
  
  //Generate the "default" fit model 

  RooGenericPdf *lFit  = 0; lFit = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB));
  if(iFitModel == 1) lFit = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB));
  if(iFitModel == 1) {lA.setVal(0.3); lB.setVal(0.5);}
  if(iFitModel == 2) lFit = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB));
  if(iFitModel == 2) {lA.setVal(0.01); lA.setRange(0,10); }
  if(iFitModel == 3) lFit = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB));
 
  // Generate the alternative model
  
  RooGenericPdf *lFit1  = 0; lFit1 = new RooGenericPdf("genPdf","exp(-m/(a1+b1*m))",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 1) lFit1 = new RooGenericPdf("genPdf","exp(-a1*pow(m,b1))",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 1) {lA1.setVal(0.3); lB1.setVal(0.5);}
  if(iFitModel1 == 2) lFit1 = new RooGenericPdf("genPdf","a1*exp(b1*m)",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 2) {lA1.setVal(0.01); lA1.setRange(0,10); }
  if(iFitModel1 == 3) lFit1 = new RooGenericPdf("genPdf","a1/pow(m,b1)",RooArgList(lM,lA1,lB1));
  
  //=============================================================================================================================================
  //Perform the tail fit and generate the shift up and down histograms
  //=============================================================================================================================================

  RooFitResult  *lRFit = 0;
  lRFit = lFit->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast),RooFit::Strategy(0)); 
  TMatrixDSym lCovMatrix   = lRFit->covarianceMatrix(); 
  TMatrixD  lEigVecs(2,2);    lEigVecs = TMatrixDSymEigen(lCovMatrix).GetEigenVectors();
  TVectorD  lEigVals(2);      lEigVals = TMatrixDSymEigen(lCovMatrix).GetEigenValues();
  cout << " Ve---> " << lEigVecs(0,0) << " -- " << lEigVecs(1,0) << " -- " << lEigVecs(0,1) << " -- " << lEigVecs(1,1) << endl;
  cout << " Co---> " << lCovMatrix(0,0) << " -- " << lCovMatrix(1,0) << " -- " << lCovMatrix(0,1) << " -- " << lCovMatrix(1,1) << endl;
  double lACentral = lA.getVal();
  double lBCentral = lB.getVal();
  lEigVals(0) = sqrt(lEigVals(0));
  lEigVals(1) = sqrt(lEigVals(1));
  cout << "===> " << lEigVals(0) << " -- " << lEigVals(1) << endl;
  
  TH1F* lH     = (TH1F*) lFit->createHistogram("fit" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  lA.setVal(lACentral + lEigVals(0)*lEigVecs(0,0));
  lB.setVal(lBCentral + lEigVals(0)*lEigVecs(1,0));
  TH1F* lHUp   = (TH1F*) lFit->createHistogram("Up"  ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  lA.setVal(lACentral - lEigVals(0)*lEigVecs(0,0));
  lB.setVal(lBCentral - lEigVals(0)*lEigVecs(1,0));
  TH1F* lHDown = (TH1F*) lFit->createHistogram("Down",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  lA.setVal(lACentral + lEigVals(1)*lEigVecs(0,1));
  lB.setVal(lBCentral + lEigVals(1)*lEigVecs(1,1));
  TH1F* lHUp1   = (TH1F*) lFit->createHistogram("Up1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  lA.setVal(lACentral - lEigVals(1)*lEigVecs(0,1));
  lB.setVal(lBCentral - lEigVals(1)*lEigVecs(1,1));
  TH1F* lHDown1 = (TH1F*) lFit->createHistogram("Down1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  std::string lNuisance1 =  iBkg+"_"+"CMS_"+iName+"1_" + iChannel + "_" + iEnergy;
  std::string lNuisance2 =  iBkg+"_"+"CMS_"+iName+"2_" + iChannel + "_" + iEnergy;
  lHUp    = merge(lNuisance1 + "Up"   ,lFirst,lH0,lHUp);
  lHDown  = merge(lNuisance1 + "Down" ,lFirst,lH0,lHDown);
  lHUp1   = merge(lNuisance2 + "Up"   ,lFirst,lH0,lHUp1);
  lHDown1 = merge(lNuisance2 + "Down" ,lFirst,lH0,lHDown1);
  lH      = merge(lH0->GetName()      ,lFirst,lH0,lH);

  //=============================================================================================================================================
  //=============================================================================================================================================
  
  //Set the variables A and B to the final central values from the tail fit

  lA.setVal(lACentral);
  lB.setVal(lBCentral);
 // lA.removeRange();
 // lB.removeRange();
 
  //Generate the background pdf corresponding to the final result of the tail fit
 
 RooGenericPdf *lFitFinal  = 0; lFitFinal = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB));
  if(iFitModel == 1) lFitFinal = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB));
  if(iFitModel == 2) lFitFinal = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB));
  if(iFitModel == 3) lFitFinal = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB));



  //=============================================================================================================================================
  //Perform the tail fit with the alternative fit function (once initially, before allowing tail fit to float in toy fit).
  //=============================================================================================================================================

  RooFitResult  *lRFit1 = 0;
 //lRFit1=lFit1->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(iFirst,iLast),RooFit::Strategy(0));  
 lRFit1=lFit1->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(200,1500),RooFit::Strategy(0));  
  
  //Generate the background pdf corresponding to the result of the alternative tail fit

  RooGenericPdf *lFit1Final  = 0; lFit1Final = new RooGenericPdf("genPdf","exp(-m/(a1+b1*m))",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 1) lFit1Final = new RooGenericPdf("genPdf","exp(-a1*pow(m,b1))",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 2) lFit1Final = new RooGenericPdf("genPdf","a1*exp(b1*m)",RooArgList(lM,lA1,lB1));
  if(iFitModel1 == 3) lFit1Final = new RooGenericPdf("genPdf","a1/pow(m,b1)",RooArgList(lM,lA1,lB1));

 // lA1.removeRange();
 // lB1.removeRange();
  
  //=============================================================================================================================================

  //Define RooRealVar for the normalization of the signal and background, starting from the initial integral of the input histograms

  lM.setRange(300,1500);  

  RooRealVar lNB("nb","nb",lNB0,0,10000);
  RooRealVar lNSig("nsig","nsig",lNSig0,-1000,1000);

  //Define a PDF for the signal histogram lSig
  
  RooDataHist  *pS      = new RooDataHist("sigH","sigH",RooArgList(lM),lSig);
  RooHistPdf   *lSPdf   = new RooHistPdf ("sigPdf","sigPdf",lM,*pS);
 
  //Define generator and fit functions for the RooMCStudy

  RooAddPdf    *lGenMod = new RooAddPdf  ("genmod","genmod",RooArgList(*lFitFinal ,*lSPdf),RooArgList(lNB,lNSig));
  RooAddPdf    *lFitMod = new RooAddPdf  ("fitmod","fitmod",RooArgList(*lFit1Final,*lSPdf),RooArgList(lNB,lNSig));

  //Generate plot of the signal and background models going into the toy generation   

  RooPlot* plot=lM.frame();
  lGenMod->plotOn(plot);
  lGenMod->plotOn(plot,RooFit::Components(*lSPdf),RooFit::LineColor(2));
  TCanvas* lC11 = new TCanvas("pdf","pdf",600,600) ;
  lC11->cd();
  plot->Draw();
  lC11->SaveAs(("SBModel_"+iBkg+"_" + iDir + "_" + iEnergy+".pdf").c_str());

  std::cout << "===================================================================================================================================================" <<std::endl;
  std::cout << "FIT PARAMETERS BEFORE ROOMCSTUDY: lA: " << lA.getVal() << " lB: " << lB.getVal() << " lA1: " << lA1.getVal() << " lB1: " << lB1.getVal() << std::endl;  
  std::cout << "===================================================================================================================================================" <<std::endl;


  RooMCStudy   *lToy    = new RooMCStudy(*lGenMod,lM,RooFit::FitModel(*lFitMod),RooFit::Binned(kTRUE),RooFit::Silence(),RooFit::Extended(kTRUE),RooFit::Verbose(kTRUE),RooFit::FitOptions(RooFit::Save(kTRUE),RooFit::Strategy(0)));

  // Generate and fit iNToys toy samples
  
  std::cout << "Number of background events: " << lNB0 << " Number of signal events: " << lNSig0 << " Sum: " << lNB0+lNSig0 << std::endl;
  
  //=============================================================================================================================================
  // Generate and fit toys
  //============================================================================================================================================= 
    
  lToy->generateAndFit(iNToys,lNB0+lNSig0,kTRUE);
 
  std::cout << "===================================================================================================================================================" <<std::endl;
  std::cout << "FIT PARAMETERS AFTER ROOMCSTUDY: lA: " << lA.getVal() << " lB: " << lB.getVal() << " lA1: " << lA1.getVal() << " lB1: " << lB1.getVal() << std::endl;  
  std::cout << "===================================================================================================================================================" <<std::endl;
  

  //=============================================================================================================================================
  // Generate plots relevant to the toy fit
  //=============================================================================================================================================

  RooPlot* lFrame1 = lToy->plotPull(lNSig,-5,5,100,kTRUE);
  lFrame1->SetTitle("distribution of pulls on signal yield from toys");
  lFrame1->SetXTitle("N_{sig} pull");
  
  TCanvas* lC00 = new TCanvas("pulls","pulls",600,600) ;
  lC00->cd();
  lFrame1->GetYaxis()->SetTitleOffset(1.2); 
  lFrame1->GetXaxis()->SetTitleOffset(1.0); 
  lFrame1->Draw() ;
  lC00->SaveAs(("sig_pulls_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());

  RooPlot* lFrame2 = lToy->plotParam(lA1);
  lFrame2->SetTitle("distribution of values of parameter 1 (a) after toy fit");
  lFrame2->SetXTitle("Parameter 1 (a)");
  TCanvas* lC01 = new TCanvas("valA","valA",600,600) ;
  lFrame2->Draw() ;
  lC01->SaveAs(("valA_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());

  RooPlot* lFrame3 = lToy->plotParam(lB1);
  lFrame3->SetTitle("distribution of values of parameter 2 (b) after toy fit");
  lFrame3->SetXTitle("Parameter 2 (b)");
  TCanvas* lC02 = new TCanvas("valB","valB",600,600) ;
  lFrame3->Draw() ;
  lC02->SaveAs(("valB_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());
  
  RooPlot* lFrame6 = lToy->plotNLL(0,1000,100);
  lFrame6->SetTitle("-log(L)");
  lFrame6->SetXTitle("-log(L)");
  TCanvas* lC05 = new TCanvas("logl","logl",600,600) ;
  lFrame6->Draw() ;
  lC05->SaveAs(("logL_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());

  RooPlot* lFrame7 = lToy->plotParam(lNSig);
  lFrame7->SetTitle("distribution of values of N_{sig} after toy fit");
  lFrame7->SetXTitle("N_{sig}");
  TCanvas* lC06 = new TCanvas("Nsig","Nsig",600,600) ;
  lFrame7->Draw() ;
  lC06->SaveAs(("NSig_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());
  
  RooPlot* lFrame8 = lToy->plotParam(lNB);
  lFrame8->SetTitle("distribution of values of N_{bkg} after toy fit");
  lFrame8->SetXTitle("N_{bkg}");
  TCanvas* lC07 = new TCanvas("Nbkg","Nbkg",600,600) ;
  lFrame8->Draw() ;
  lC07->SaveAs(("Nbkg_toyfits_"+iBkg+"_" + iDir + "_" + iEnergy+".png").c_str());
 

  if(iRebin) { 
    const int lNBins = lData->GetNbinsX();
    double *lAxis    = getAxis(lData);
    lH0     = rebin(lH0    ,lNBins,lAxis);
    lH      = rebin(lH     ,lNBins,lAxis);
    lHUp    = rebin(lHUp   ,lNBins,lAxis);
    lHDown  = rebin(lHDown ,lNBins,lAxis);
    lHUp1   = rebin(lHUp1  ,lNBins,lAxis);
    lHDown1 = rebin(lHDown1,lNBins,lAxis);
  }

  // we dont need this bin errors since we do not use them (fit tails replaces bin-by-bin error!), therefore i set all errors to 0, this also saves us from modifying the add_bbb_error.py script in which I otherwise would have to include a option for adding bbb only in specific ranges
  int lMergeBin = lH->GetXaxis()->FindBin(iFirst);
  for(int i0 = lMergeBin; i0 < lH->GetNbinsX()+1; i0++){
    lH->SetBinError  (i0,0);
    lHUp->SetBinError  (i0,0);
    lHDown->SetBinError  (i0,0);
    lHUp1->SetBinError  (i0,0);
    lHDown1->SetBinError  (i0,0);
  }


  TFile *lOutFile =new TFile("Output.root","RECREATE");
  cloneFile(lOutFile,lFile,iDir+"/"+iBkg);
  lOutFile->cd(iDir.c_str());
  lH     ->Write();
  lHUp   ->Write(); 
  lHDown ->Write(); 
  lHUp1  ->Write(); 
  lHDown1->Write(); 

  // Debug Plots
  lH0->SetStats(0);
  lH->SetStats(0);
  lHUp->SetStats(0);
  lHDown->SetStats(0);
  lHUp1->SetStats(0);
  lHDown1->SetStats(0);
  lH0    ->SetLineWidth(1); lH0->SetMarkerStyle(kFullCircle);
  lH     ->SetLineColor(kGreen);
  lHUp   ->SetLineColor(kRed);
  lHDown ->SetLineColor(kRed);
  lHUp1  ->SetLineColor(kBlue);
  lHDown1->SetLineColor(kBlue);
  TCanvas *lC0 = new TCanvas("Can","Can",800,600);
  lC0->Divide(1,2); lC0->cd();  lC0->cd(1)->SetPad(0,0.2,1.0,1.0); gPad->SetLeftMargin(0.2) ; 
  lH0->Draw();
  lH     ->Draw("hist sames");
  lHUp   ->Draw("hist sames");
  lHDown ->Draw("hist sames");
  lHUp1  ->Draw("hist sames");
  lHDown1->Draw("hist sames");
  gPad->SetLogy();
  
  TLegend* leg1;
  /// setup the CMS Preliminary
  leg1 = new TLegend(0.7, 0.80, 1, 1); 
  leg1->SetBorderSize( 0 );
  leg1->SetFillStyle ( 1001 );
  leg1->SetFillColor (kWhite);
  leg1->AddEntry( lH0 , "orignal",  "PL" );
  leg1->AddEntry( lH , "cental fit",  "L" );
  leg1->AddEntry( lHUp , "shift1 up",  "L" );
  leg1->AddEntry( lHDown , "shift1 down",  "L" );
  leg1->AddEntry( lHUp1 , "shift2 up",  "L" );
  leg1->AddEntry( lHDown1 , "shift2 down",  "L" );
  leg1->Draw("same");


  lC0->cd(2)->SetPad(0,0,1.0,0.2); gPad->SetLeftMargin(0.2) ;
  drawDifference(lH0,lH,lHUp,lHDown,lHUp1,lHDown1);
  lH0->SetStats(0);
  lC0->Update();
  lC0->SaveAs((iBkg+"_"+"CMS_"+iName+"1_" + iDir + "_" + iEnergy+".png").c_str());
  //lFile->Close();
  return;
}
Exemple #2
0
double* fitHist(TCanvas *iC, bool iDoMu,int iPlot, std::string iName,TH1D *iData,TH1D *iW,TH1D *iEWK,TH1D *iAntiData,TH1D *iAntiW,TH1D *iAntiEWK,const Double_t METMAX,const Int_t NBINS,const Double_t lumi,const Int_t Ecm,int iAltQCD) {
    //
    // Declare fit parameters for signal and background yields
    // Note: W signal and EWK+top PDFs are constrained to the ratio described in MC
    //
    RooRealVar nSig(("nSig"+iName).c_str(),("nSig"+iName).c_str(),0.7*(iData->Integral()),0,iData->Integral());
    RooRealVar nQCD(("nQCD"+iName).c_str(),("nQCD"+iName).c_str(),0.3*(iData->Integral()),0,iData->Integral());
    RooRealVar cewk(("cewk"+iName).c_str(),("cewk"+iName).c_str(),0.1,0,5) ;
    cewk.setVal(iEWK->Integral()/iW->Integral());
    cewk.setConstant(kTRUE);
    RooFormulaVar nEWK(("nEWK"+iName).c_str(),("nEWK"+iName).c_str(),("cewk"+iName+"*nSig"+iName).c_str(),RooArgList(nSig,cewk));

    RooRealVar nAntiSig(("nAntiSig"+iName).c_str(),("nAntiSig"+iName).c_str(),0.05*(iAntiData->Integral()),0,iAntiData->Integral());
    RooRealVar nAntiQCD(("nAntiQCD"+iName).c_str(),("nAntiQCD"+iName).c_str(),0.9 *(iAntiData->Integral()),0,iAntiData->Integral());
    RooRealVar dewk    (("dewk"    +iName).c_str(),("dewk"    +iName).c_str(),0.1,0,5) ;
    dewk.setVal(iAntiEWK->Integral()/iAntiW->Integral());
    dewk.setConstant(kTRUE);
    RooFormulaVar nAntiEWK(("nAntiEWK"+iName).c_str(),("nAntiEWK"+iName).c_str(),("dewk"+iName+"*nAntiSig"+iName).c_str(),RooArgList(nAntiSig,dewk));

    //
    // Construct PDFs for fitting
    //
    RooRealVar pfmet(("pfmet"+iName).c_str(),("pfmet"+iName).c_str(),0,METMAX);
    pfmet.setBins(NBINS);

    // Signal PDFs
    RooDataHist wMet  (("wMET" +iName).c_str(), ("wMET" +iName).c_str(),     RooArgSet(pfmet),iW);
    RooHistPdf  pdfW(( "w"+iName).c_str(), ( "w"+iName).c_str(), pfmet, wMet, 1);
    RooDataHist awMet (("awMET"+iName).c_str(), ("awMET"+iName).c_str(),     RooArgSet(pfmet),iAntiW);
    RooHistPdf apdfW(("aw"+iName).c_str(), ("aw"+iName).c_str(), pfmet,awMet, 1);

    // EWK+top PDFs
    RooDataHist ewkMet (("ewkMET" +iName).c_str(),( "ewkMET"+iName).c_str(), RooArgSet(pfmet),iEWK);
    RooHistPdf  pdfEWK (( "ewk"+iName).c_str(),( "ewk"+iName).c_str(), pfmet,ewkMet, 1);
    RooDataHist aewkMet(("aewkMET"+iName).c_str(),("aewkMET"+iName).c_str(), RooArgSet(pfmet),iAntiEWK);
    RooHistPdf apdfEWK (("aewk"+iName).c_str(),("aewk"+iName).c_str(), pfmet,aewkMet, 1);

    // QCD Pdfs
    CPepeModel0 qcd0 (("qcd0" +iName).c_str(),pfmet);
    CPepeModel1 qcd1 (("qcd1" +iName).c_str(),pfmet);
    CPepeModel2 qcd2 (("qcd2" +iName).c_str(),pfmet);
    CPepeModel0 aqcd0(("aqcd0"+iName).c_str(),pfmet);
    CPepeModel1 aqcd1(("aqcd1"+iName).c_str(),pfmet,qcd1.sigma);
    CPepeModel2 aqcd2(("aqcd2"+iName).c_str(),pfmet);
    RooGenericPdf *lQCD  =  qcd0.model;
    RooGenericPdf *lAQCD = aqcd0.model;
    if(iDoMu) lQCD  = qcd1.model;
    if(iDoMu) lAQCD = aqcd1.model;
    if(iAltQCD == 0) lQCD = qcd0.model;
    if(iAltQCD == 1) lQCD = qcd1.model;
    if(iAltQCD == 2) lQCD = qcd2.model;
    if(iAltQCD == 0) lAQCD = aqcd0.model;
    if(iAltQCD == 1) lAQCD = aqcd1.model;
    if(iAltQCD == 2) lAQCD = aqcd2.model;

    // Signal + Background PDFs
    RooAddPdf pdfMet (("pdfMet"+iName).c_str(), ("pdfMet" +iName).c_str(), RooArgList(pdfW ,pdfEWK ,*lQCD), RooArgList(nSig,nEWK,nQCD));
    RooAddPdf apdfMet(("apdfMet"+iName).c_str(),("apdfMet"+iName).c_str(), RooArgList(apdfW,apdfEWK,*lAQCD), RooArgList(nAntiSig,nAntiEWK,nAntiQCD));

    // PDF for simultaneous fit
    RooCategory rooCat("rooCat","rooCat");
    rooCat.defineType("Select");
    rooCat.defineType("Anti");

    RooSimultaneous pdfTotal("pdfTotal","pdfTotal",rooCat);
    pdfTotal.addPdf(pdfMet, "Select");
    if(iDoMu) pdfTotal.addPdf(apdfMet,"Anti");

    // Perform fits
    RooDataHist dataMet  (("dataMet"+iName).c_str(),("dataMet"+iName).c_str(), RooArgSet(pfmet),iData);
    RooDataHist antiMet  (("antiMet"+iName).c_str(),("antiMet"+iName).c_str(), RooArgSet(pfmet),iAntiData);
    RooDataHist dataTotal(("data"   +iName).c_str(),("data"   +iName).c_str(), RooArgList(pfmet), Index(rooCat),
                          Import("Select", dataMet),
                          Import("Anti",   antiMet));

    RooFitResult *fitRes = 0;
    bool runMinos = kTRUE;
    if(iPlot == 0 || iPlot == 3) runMinos = kFALSE; //Remove Minos when running toys (too damn slow)
    if(!iDoMu) fitRes = pdfMet  .fitTo(dataMet  ,Extended(),Minos(runMinos),Save(kTRUE));
    if( iDoMu) fitRes = pdfTotal.fitTo(dataTotal,Extended(),Minos(runMinos),Save(kTRUE));

    double *lResults = new double[16];
    lResults[0]  = nSig.getVal();
    lResults[1]  = nEWK.getVal();
    lResults[2]  = nQCD.getVal();
    lResults[3]  = nAntiSig.getVal();
    lResults[4]  = nAntiEWK.getVal();
    lResults[5]  = nAntiQCD.getVal();
    if(!iDoMu) lResults[6]  = double(qcd0.sigma->getVal());
    if( iDoMu) lResults[6]  = double(qcd1.sigma->getVal());

    lResults[7]  = 0.;
    if(!iDoMu) lResults[7]  = qcd1.a1->getVal();
    lResults[8]   = nSig    .getPropagatedError(*fitRes);
    lResults[9]   = nEWK    .getPropagatedError(*fitRes);
    lResults[10]  = nQCD    .getPropagatedError(*fitRes);
    lResults[11]  = nAntiSig.getPropagatedError(*fitRes);
    lResults[12]  = nAntiEWK.getPropagatedError(*fitRes);
    lResults[13]  = nAntiQCD.getPropagatedError(*fitRes);
    if( iDoMu) lResults[14]  = qcd0.sigma->getError();
    if(!iDoMu) lResults[14]  = qcd1.sigma->getError();
    if( iDoMu) lResults[15]  = 0;
    if(!iDoMu) lResults[15]  = qcd1.a1   ->getError();
    if(iPlot == 0 ) return lResults;
    //
    // Use histogram version of fitted PDFs to make ratio plots
    // (Will also use PDF histograms later for Chi^2 and KS tests)
    //
    TH1D *hPdfMet = (TH1D*)(pdfMet.createHistogram(("hPdfMet"+iName).c_str(), pfmet));
    hPdfMet->Scale((nSig.getVal()+nEWK.getVal()+nQCD.getVal())/hPdfMet->Integral());
    TH1D *hMetDiff = makeDiffHist(iData,hPdfMet,"hMetDiff"+iName);
    hMetDiff->SetMarkerStyle(kFullCircle);
    hMetDiff->SetMarkerSize(0.9);

    TH1D *hPdfAntiMet = (TH1D*)(apdfMet.createHistogram(("hPdfAntiMet"+iName).c_str(), pfmet));
    hPdfAntiMet->Scale((nAntiSig.getVal()+nAntiEWK.getVal()+nAntiQCD.getVal())/hPdfAntiMet->Integral());
    TH1D *hAntiMetDiff = makeDiffHist(iAntiData,hPdfAntiMet,"hAntiMetDiff"+iName);
    hAntiMetDiff->SetMarkerStyle(kFullCircle);
    hAntiMetDiff->SetMarkerSize(0.9);
    if(iPlot == 3 ) {
        //Build best fit QCD with default W and EWK Shap
        TH1D *hPdfMetQCD  = (TH1D*)(lQCD ->createHistogram(("hPdfMetQCD"    +iName).c_str(), pfmet));
        TH1D *hPdfAMetQCD = (TH1D*)(lAQCD->createHistogram(("hPdfAntiMetQCD"+iName).c_str(), pfmet));
        hPdfMetQCD ->Scale(nQCD    .getVal()/hPdfMetQCD ->Integral());
        hPdfAMetQCD->Scale(nAntiQCD.getVal()/hPdfAMetQCD->Integral());

        TH1D *pW    = (TH1D*) iW      ->Clone("WForToys");
        pW   ->Scale(nSig    .getVal()/pW   ->Integral());
        TH1D *pEWK  = (TH1D*) iEWK    ->Clone("EWKForToys");
        pEWK ->Scale(nEWK    .getVal()/pEWK ->Integral());
        TH1D *pAW   = (TH1D*) iAntiW  ->Clone("AWForToys");
        pAW  ->Scale(nAntiSig.getVal()/pAW  ->Integral());
        TH1D *pAEWK = (TH1D*) iAntiEWK->Clone("AEWKForToys");
        pAEWK->Scale(nAntiEWK.getVal()/pAEWK->Integral());
        hPdfMetQCD ->Add(pW);
        hPdfMetQCD ->Add(pEWK);
        hPdfAMetQCD->Add(pAW);
        hPdfAMetQCD->Add(pAEWK);
        fBestFit     = hPdfMetQCD;
        fAntiBestFit = hPdfAMetQCD;
        return lResults;
    }

    //--------------------------------------------------------------------------------------------------------------
    // Make plots
    //==============================================================================================================
    char ylabel[100];  // string buffer for y-axis label

    // file format for output plots
    const TString format("png");

    // label for lumi
    char lumitext[100];
    if(lumi<0.1) sprintf(lumitext,"%.1f pb^{-1}  at  #sqrt{s} = %i TeV",lumi*1000.,Ecm);
    else         sprintf(lumitext,"%.2f fb^{-1}  at  #sqrt{s} = %i TeV",lumi      ,Ecm);

    // plot colors
    Int_t linecolorW   = kOrange-3;
    Int_t fillcolorW   = kOrange-2;
    Int_t linecolorEWK = kOrange+10;
    Int_t fillcolorEWK = kOrange+7;
    Int_t linecolorQCD = kViolet+2;
    Int_t fillcolorQCD = kViolet-5;
    Int_t ratioColor   = kGray+2;

    //
    // Dummy histograms for TLegend
    // (Nobody can figure out how to properly pass RooFit objects...)
    //
    TH1D *hDummyData = new TH1D("hDummyData","",0,0,10);
    hDummyData->SetMarkerStyle(kFullCircle);
    hDummyData->SetMarkerSize(0.9);

    TH1D *hDummyW = new TH1D("hDummyW","",0,0,10);
    hDummyW->SetLineColor(linecolorW);
    hDummyW->SetFillColor(fillcolorW);
    hDummyW->SetFillStyle(1001);

    TH1D *hDummyEWK = new TH1D("hDummyEWK","",0,0,10);
    hDummyEWK->SetLineColor(linecolorEWK);
    hDummyEWK->SetFillColor(fillcolorEWK);
    hDummyEWK->SetFillStyle(1001);

    TH1D *hDummyQCD = new TH1D("hDummyQCD","",0,0,10);
    hDummyQCD->SetLineColor(linecolorQCD);
    hDummyQCD->SetFillColor(fillcolorQCD);
    hDummyQCD->SetFillStyle(1001);

    //
    // W MET plot
    //
    RooPlot *wmframe = pfmet.frame(Bins(NBINS));
    dataMet.plotOn(wmframe,MarkerStyle(kFullCircle),MarkerSize(0.9),DrawOption("ZP"));
    pdfMet.plotOn(wmframe,FillColor(fillcolorW),DrawOption("F"));
    pdfMet.plotOn(wmframe,LineColor(linecolorW));
    pdfMet.plotOn(wmframe,Components(RooArgSet(pdfEWK,*lQCD)),FillColor(fillcolorEWK),DrawOption("F"));
    pdfMet.plotOn(wmframe,Components(RooArgSet(pdfEWK,*lQCD)),LineColor(linecolorEWK));
    pdfMet.plotOn(wmframe,Components(RooArgSet(*lQCD)),FillColor(fillcolorQCD),DrawOption("F"));
    pdfMet.plotOn(wmframe,Components(RooArgSet(*lQCD)),LineColor(linecolorQCD));
    pdfMet.plotOn(wmframe,Components(RooArgSet(pdfW)),LineColor(linecolorW),LineStyle(2));
    dataMet.plotOn(wmframe,MarkerStyle(kFullCircle),MarkerSize(0.9),DrawOption("ZP"));

    sprintf(ylabel,"Events / %.1f GeV",iData->GetBinWidth(1));
    CPlot plotMet(("fitmet"+iName).c_str(),wmframe,"","",ylabel);
    plotMet.SetLegend(0.68,0.57,0.93,0.77);
    plotMet.GetLegend()->AddEntry(hDummyData,"data","PL");
    plotMet.GetLegend()->AddEntry(hDummyW,"W#rightarrow#mu#nu","F");
    plotMet.GetLegend()->AddEntry(hDummyEWK,"EWK+t#bar{t}","F");
    plotMet.GetLegend()->AddEntry(hDummyQCD,"QCD","F");
    plotMet.AddTextBox(lumitext,0.55,0.80,0.90,0.86,0);
    plotMet.AddTextBox("CMS Preliminary",0.63,0.92,0.95,0.99,0);
    plotMet.SetYRange(0.1,1.1*(iData->GetMaximum()));
    plotMet.Draw(iC,kFALSE,format,1);

    CPlot plotMetDiff(("fitmet"+iName).c_str(),"","#slash{E}_{T} [GeV]","#chi");
    plotMetDiff.AddHist1D(hMetDiff,"EX0",ratioColor);
    plotMetDiff.SetYRange(-8,8);
    plotMetDiff.AddLine(0, 0,METMAX, 0,kBlack,1);
    plotMetDiff.AddLine(0, 5,METMAX, 5,kBlack,3);
    plotMetDiff.AddLine(0,-5,METMAX,-5,kBlack,3);
    plotMetDiff.Draw(iC,kTRUE,format,2);
    plotMet.Draw(iC,kTRUE,format,1);

    plotMet.SetName(("fitmetlog"+iName).c_str());
    plotMet.SetLogy();
    plotMet.SetYRange(1e-3*(iData->GetMaximum()),10*(iData->GetMaximum()));
    plotMet.Draw(iC,kTRUE,format,1);

    if(iDoMu) {
        RooPlot *awmframe = pfmet.frame(Bins(NBINS));
        antiMet.plotOn(awmframe,MarkerStyle(kFullCircle),MarkerSize(0.9),DrawOption("ZP"));
        apdfMet.plotOn(awmframe,FillColor(fillcolorW),DrawOption("F"));
        apdfMet.plotOn(awmframe,LineColor(linecolorW));
        apdfMet.plotOn(awmframe,Components(RooArgSet(apdfEWK,*lQCD)),FillColor(fillcolorEWK),DrawOption("F"));
        apdfMet.plotOn(awmframe,Components(RooArgSet(apdfEWK,*lQCD)),LineColor(linecolorEWK));
        apdfMet.plotOn(awmframe,Components(RooArgSet(*lQCD)),FillColor(fillcolorQCD),DrawOption("F"));
        apdfMet.plotOn(awmframe,Components(RooArgSet(*lQCD)),LineColor(linecolorQCD));
        apdfMet.plotOn(awmframe,Components(RooArgSet(apdfW)),LineColor(linecolorW),LineStyle(2));
        antiMet.plotOn(awmframe,MarkerStyle(kFullCircle),MarkerSize(0.9),DrawOption("ZP"));

        sprintf(ylabel,"Events / %.1f GeV",iAntiData->GetBinWidth(1));
        CPlot plotAntiMet(("fitantimet"+iName).c_str(),awmframe,"","",ylabel);
        plotAntiMet.SetLegend(0.68,0.57,0.93,0.77);
        plotAntiMet.GetLegend()->AddEntry(hDummyData,"data","PL");
        plotAntiMet.GetLegend()->AddEntry(hDummyW,"W#rightarrow#mu#nu","F");
        plotAntiMet.GetLegend()->AddEntry(hDummyEWK,"EWK+t#bar{t}","F");
        plotAntiMet.GetLegend()->AddEntry(hDummyQCD,"QCD","F");
        plotAntiMet.AddTextBox(lumitext,0.55,0.80,0.90,0.86,0);
        plotAntiMet.AddTextBox("CMS Preliminary",0.63,0.92,0.95,0.99,0);
        plotAntiMet.SetYRange(0.1,1.1*(iAntiData->GetMaximum()));
        plotAntiMet.Draw(iC,kFALSE,format,1);

        CPlot plotAntiMetDiff(("fitantimet"+iName).c_str(),"","#slash{E}_{T} [GeV]","#chi");
        plotAntiMetDiff.AddHist1D(hMetDiff,"EX0",ratioColor);
        plotAntiMetDiff.SetYRange(-8,8);
        plotAntiMetDiff.AddLine(0, 0,METMAX, 0,kBlack,1);
        plotAntiMetDiff.AddLine(0, 5,METMAX, 5,kBlack,3);
        plotAntiMetDiff.AddLine(0,-5,METMAX,-5,kBlack,3);
        plotAntiMetDiff.Draw(iC,kTRUE,format,2);

        plotAntiMet.SetName(("fitantimetlog"+iName).c_str());
        plotAntiMet.SetLogy();
        plotAntiMet.SetYRange(1e-3*(iAntiData->GetMaximum()),10*(iAntiData->GetMaximum()));
        plotAntiMet.Draw(iC,kTRUE,format,1);
    }
    if(iPlot == 1) return lResults;

    ofstream txtfile;
    std::string txtfName = "fitres"+iName;
    if( iDoMu) txtfName + "Mu.txt";
    if(!iDoMu) txtfName + "Mu.txt";
    ios_base::fmtflags flags;
    cout << " --- test " << iData->Integral() << " -- " << hPdfMet->Integral() << endl;
    Double_t chi2prob = iData->Chi2Test(hPdfMet,"PUW");
    Double_t chi2ndf  = iData->Chi2Test(hPdfMet,"CHI2/NDFUW");
    Double_t ksprob   = iData->KolmogorovTest(hPdfMet);
    Double_t ksprobpe = 1;//iData->KolmogorovTest(hPdfMet,"DX");
    txtfile.open(txtfName.c_str());
    assert(txtfile.is_open());

    flags = txtfile.flags();
    txtfile << setprecision(10);
    txtfile << " *** Yields *** " << endl;
    txtfile << "Selected: " << iData->Integral() << endl;
    txtfile << "  Signal: " << nSig.getVal() << " +/- " << nSig.getPropagatedError(*fitRes) << endl;
    txtfile << "     QCD: " << nQCD.getVal() << " +/- " << nQCD.getPropagatedError(*fitRes) << endl;
    txtfile << "   Other: " << nEWK.getVal() << " +/- " << nEWK.getPropagatedError(*fitRes) << endl;
    txtfile << endl;
    txtfile.flags(flags);

    fitRes->printStream(txtfile,RooPrintable::kValue,RooPrintable::kVerbose);
    txtfile << endl;
    printCorrelations(txtfile, fitRes);
    txtfile << endl;
    printChi2AndKSResults(txtfile, chi2prob, chi2ndf, ksprob, ksprobpe);
    txtfile.close();
    return lResults;
}
void addNuisance(std::string iFileName,std::string iChannel,std::string iBkg,std::string iEnergy,std::string iName,std::string iDir,bool iRebin=true,bool iVarBin=false,int iFitModel=1,double iFirst=150,double iLast=1500) { 
  std::cout << "======> " << iDir << "/" << iBkg << " -- " << iFileName << std::endl;  
  if(iVarBin) addVarBinNuisance(iFileName,iChannel,iBkg,iEnergy,iName,iDir,iRebin,iFitModel,iFirst,iLast);
  if(iVarBin) return;

  TFile *lFile = new TFile(iFileName.c_str());
  TH1F  *lH0   = (TH1F*) lFile->Get((iDir+"/"+iBkg).c_str());
  TH1F  *lData = (TH1F*) lFile->Get((iDir+"/data_obs").c_str());

  //Define the fit function
  RooRealVar lM("m","m" ,0,5000);   //lM.setBinning(lBinning);
  RooRealVar lA("a","a" ,50,  0.1,100);
  RooRealVar lB("b","b" ,0.0 , -10.5,10.5); //lB.setConstant(kTRUE);
  RooDataHist *pH0  =  new RooDataHist("Data","Data" ,RooArgList(lM),lH0);
  RooGenericPdf *lFit  = 0; lFit = new RooGenericPdf("genPdf","exp(-m/(a+b*m))",RooArgList(lM,lA,lB));
  if(iFitModel == 1) lFit = new RooGenericPdf("genPdf","exp(-a*pow(m,b))",RooArgList(lM,lA,lB));
  if(iFitModel == 1) {lA.setVal(0.3); lB.setVal(0.5);}
  if(iFitModel == 2) lFit = new RooGenericPdf("genPdf","a*exp(b*m)",RooArgList(lM,lA,lB));
  if(iFitModel == 3) lFit = new RooGenericPdf("genPdf","a/pow(m,b)",RooArgList(lM,lA,lB));
  RooFitResult  *lRFit = 0;
  double lFirst = iFirst;
  double lLast  = iLast;
  //lRFit = lFit->chi2FitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast));
  lRFit = lFit->fitTo(*pH0,RooFit::Save(kTRUE),RooFit::Range(lFirst,lLast),RooFit::Strategy(0)); 
  TMatrixDSym lCovMatrix   = lRFit->covarianceMatrix(); 
  TMatrixD  lEigVecs(2,2);    lEigVecs = TMatrixDSymEigen(lCovMatrix).GetEigenVectors();
  TVectorD  lEigVals(2);      lEigVals = TMatrixDSymEigen(lCovMatrix).GetEigenValues();
  cout << " Ve---> " << lEigVecs(0,0) << " -- " << lEigVecs(1,0) << " -- " << lEigVecs(0,1) << " -- " << lEigVecs(1,1) << endl;
  cout << " Co---> " << lCovMatrix(0,0) << " -- " << lCovMatrix(1,0) << " -- " << lCovMatrix(0,1) << " -- " << lCovMatrix(1,1) << endl;
  double lACentral = lA.getVal();
  double lBCentral = lB.getVal();
  lEigVals(0) = sqrt(lEigVals(0));
  lEigVals(1) = sqrt(lEigVals(1));
  cout << "===> " << lEigVals(0) << " -- " << lEigVals(1) << endl;
  
  TH1F* lH     = (TH1F*) lFit->createHistogram("fit" ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));
  lA.setVal(lACentral + lEigVals(0)*lEigVecs(0,0));
  lB.setVal(lBCentral + lEigVals(0)*lEigVecs(1,0));
  TH1F* lHUp   = (TH1F*) lFit->createHistogram("Up"  ,lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));
  lA.setVal(lACentral - lEigVals(0)*lEigVecs(0,0));
  lB.setVal(lBCentral - lEigVals(0)*lEigVecs(1,0));
  TH1F* lHDown = (TH1F*) lFit->createHistogram("Down",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  lA.setVal(lACentral + lEigVals(1)*lEigVecs(0,1));
  lB.setVal(lBCentral + lEigVals(1)*lEigVecs(1,1));
  TH1F* lHUp1   = (TH1F*) lFit->createHistogram("Up1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));
  lA.setVal(lACentral - lEigVals(1)*lEigVecs(0,1));
  lB.setVal(lBCentral - lEigVals(1)*lEigVecs(1,1));
  TH1F* lHDown1 = (TH1F*) lFit->createHistogram("Down1",lM,RooFit::Binning(lH0->GetNbinsX(),lH0->GetXaxis()->GetXmin(),lH0->GetXaxis()->GetXmax()));

  std::string lNuisance1 =  iBkg+"_"+"CMS_"+iName+"1_" + iChannel + "_" + iEnergy;
  std::string lNuisance2 =  iBkg+"_"+"CMS_"+iName+"2_" + iChannel + "_" + iEnergy;
  lHUp    = merge(lNuisance1 + "Up"   ,lFirst,lH0,lHUp);
  lHDown  = merge(lNuisance1 + "Down" ,lFirst,lH0,lHDown);
  lHUp1   = merge(lNuisance2 + "Up"   ,lFirst,lH0,lHUp1);
  lHDown1 = merge(lNuisance2 + "Down" ,lFirst,lH0,lHDown1);
  lH      = merge(lH0->GetName()      ,lFirst,lH0,lH);

  if(iRebin) { 
    const int lNBins = lData->GetNbinsX();
    double *lAxis    = getAxis(lData);
    lH0     = rebin(lH0    ,lNBins,lAxis);
    lH      = rebin(lH     ,lNBins,lAxis);
    lHUp    = rebin(lHUp   ,lNBins,lAxis);
    lHDown  = rebin(lHDown ,lNBins,lAxis);
    lHUp1   = rebin(lHUp1  ,lNBins,lAxis);
    lHDown1 = rebin(lHDown1,lNBins,lAxis);
  }

  // we dont need this bin errors since we do not use them (fit tails replaces bin-by-bin error!), therefore i set all errors to 0, this also saves us from modifying the add_bbb_error.py script in which I otherwise would have to include a option for adding bbb only in specific ranges
  int lMergeBin = lH->GetXaxis()->FindBin(iFirst);
  for(int i0 = lMergeBin; i0 < lH->GetNbinsX()+1; i0++){
    lH->SetBinError  (i0,0);
    lHUp->SetBinError  (i0,0);
    lHDown->SetBinError  (i0,0);
    lHUp1->SetBinError  (i0,0);
    lHDown1->SetBinError  (i0,0);
  }


  TFile *lOutFile =new TFile("Output.root","RECREATE");
  cloneFile(lOutFile,lFile,iDir+"/"+iBkg);
  lOutFile->cd(iDir.c_str());
  lH     ->Write();
  lHUp   ->Write(); 
  lHDown ->Write(); 
  lHUp1  ->Write(); 
  lHDown1->Write(); 

  // Debug Plots
  lH0->SetStats(0);
  lH->SetStats(0);
  lHUp->SetStats(0);
  lHDown->SetStats(0);
  lHUp1->SetStats(0);
  lHDown1->SetStats(0);
  lH0    ->SetLineWidth(1); lH0->SetMarkerStyle(kFullCircle);
  lH     ->SetLineColor(kGreen);
  lHUp   ->SetLineColor(kRed);
  lHDown ->SetLineColor(kRed);
  lHUp1  ->SetLineColor(kBlue);
  lHDown1->SetLineColor(kBlue);
  TCanvas *lC0 = new TCanvas("Can","Can",800,600);
  lC0->Divide(1,2); lC0->cd();  lC0->cd(1)->SetPad(0,0.2,1.0,1.0); gPad->SetLeftMargin(0.2) ; 
  lH0->Draw();
  lH     ->Draw("hist sames");
  lHUp   ->Draw("hist sames");
  lHDown ->Draw("hist sames");
  lHUp1  ->Draw("hist sames");
  lHDown1->Draw("hist sames");
  gPad->SetLogy();
  
  TLegend* leg1;
  /// setup the CMS Preliminary
  leg1 = new TLegend(0.7, 0.80, 1, 1); 
  leg1->SetBorderSize( 0 );
  leg1->SetFillStyle ( 1001 );
  leg1->SetFillColor (kWhite);
  leg1->AddEntry( lH0 , "orignal",  "PL" );
  leg1->AddEntry( lH , "cental fit",  "L" );
  leg1->AddEntry( lHUp , "shift1 up",  "L" );
  leg1->AddEntry( lHDown , "shift1 down",  "L" );
  leg1->AddEntry( lHUp1 , "shift2 up",  "L" );
  leg1->AddEntry( lHDown1 , "shift2 down",  "L" );
  leg1->Draw("same");


  lC0->cd(2)->SetPad(0,0,1.0,0.2); gPad->SetLeftMargin(0.2) ;
  drawDifference(lH0,lH,lHUp,lHDown,lHUp1,lHDown1);
  lH0->SetStats(0);
  lC0->Update();
  lC0->SaveAs((iBkg+"_"+"CMS_"+iName+"1_" + iDir + "_" + iEnergy+".png").c_str());
  //lFile->Close();
  return;
}