//-------------------------------------------------------------
//Main macro for generating data and fitting
//=============================================================  
void FitMassPhotonResolutionSystematics(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 SystematicsUpOrDown = 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 *nsig = ws->var("N (Sig)"); RooRealVar constNsig(*nsig);
  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);

  //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 *sigmaPho = ws->var("sigmaPho"); sigmaPho->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();
  
  double inputSigmaPho = sigmaPho->getVal();

  //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;
  
  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");
  
  //Generate Toy MC experiment data and fits
  for(UInt_t t=0; t < NToys; ++t) {
    cout << "Toy #" << t << endl;
    nsig->setVal(constNsig.getVal()); nres->setVal(constNres.getVal()); nnonres->setVal(constNnonres.getVal());
    expRateBjet->setVal(constexpBjet.getVal()); expRatePho->setVal(constexpPho.getVal());
   
    //set jet energy resolutions to nominal
    sigmaPho->setVal(inputSigmaPho);

    cout << "Before: " << sigmaPho->getVal() << " | ";

    Float_t ran = randomnumber->Poisson(325.);
    RooDataSet *pseudoData2D = model2Dpdf->generate(RooArgList(*massBjet,*massPho), ran);

    //move jet energy resolution up/down
    if (SystematicsUpOrDown == 1) {
      sigmaPho->setVal(inputSigmaPho*1.15);
    } else if (SystematicsUpOrDown == -1) {
      sigmaPho->setVal(inputSigmaPho/1.15);
    }

    cout << "After: " << sigmaPho->getVal() << " \n";

    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";


    //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);
  		//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();
}
void FitScenariosTwoD_RequiredPerformance_card(const string inputfilePho = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/HHToBBGG_SignalBkgd_AfterCuts_diphotonMass.root", const string inputfileBjet = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/HHToBBGG_SignalBkgd_AfterCuts_dibjetMass.root", const string inputfileTwoD = "/afs/cern.ch/work/d/daan/public/releases/CMSSW_5_3_9_patch3/src/CMSAna/HHToBBGG/data/HHToBBGG_SignalBkgd_AfterCuts_twoDMass.root", const string scanOption = "lum", Int_t NToys = 500, Int_t s = 5) {
	
  

  TRandom3 *randomNumber = new TRandom3(1200);
  TFile *file = new TFile(Form("HHToBBGGWorkspace_%s_%d.root",scanOption.c_str(),s),"RECREATE");
  RooWorkspace* ws = new RooWorkspace("CMSAna/HHToBBGG/fits/Workspace");
  AddModels(ws, inputfilePho, inputfileBjet, inputfileTwoD, scanOption, s);

  //Import variables from workspace
  RooAbsPdf *model2Dpdf = ws->pdf("model2Dpdf");
  RooAbsPdf *model2Dpdf_cat0 = ws->pdf("model2Dpdf_cat0");
  RooAbsPdf *model2Dpdf_cat1 = ws->pdf("model2Dpdf_cat1");
  RooRealVar *massBjet = ws->var("massBjet");
  RooRealVar *massPho = ws->var("massPho");
  RooCategory *sampleCategory = ws->cat("sampleCategory");

  RooRealVar *nsig = ws->var("nsig"); RooRealVar constNsig(*nsig);
  RooRealVar *nres_cat0 = ws->var("nres_cat0"); RooRealVar constNres_cat0(*nres_cat0);
  RooRealVar *nnonres_cat0 = ws->var("nnonres_cat0"); RooRealVar constNnonres_cat0(*nnonres_cat0);
  RooRealVar *nres_cat1 = ws->var("nres_cat1"); RooRealVar constNres_cat1(*nres_cat1);
  RooRealVar *nnonres_cat1 = ws->var("nnonres_cat1"); RooRealVar constNnonres_cat1(*nnonres_cat1);
  
  //Create TTree to store the resulting yield data
  TFile *f = new TFile(Form(("CMSAna/HHToBBGG/data/MassFitResults/ResolutionAnalysis/OptionB_Categories/tmp/"+scanOption+"FitScenario%d.root").c_str(), s), "RECREATE");
  TTree *resultTree = new TTree("resultTree", "Parameter results from fitting");
  Float_t nsigOut, nresOut, nnonresOut;
  Float_t nsigStd, nresStd, nnonresStd;
  
  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");
  
  //-------------------------------------------------------------
  //Yield Information
  //=============================================================     
  double myPhoEffRatio = 1.00;
  double myBtagEffRatio = 1.00;
  double myEndcapPhotonFakerateRatio = 1.0;
  if (scanOption == "phoEff") {
    myPhoEffRatio = phoEffRatio[s];
    myBtagEffRatio = 1.25;
  }
  if (scanOption == "btagEff") {
    myBtagEffRatio = btagEffRatio[s];
    myPhoEffRatio = 1.25;
  }
  if (scanOption == "endcapPhotonFakerate") myEndcapPhotonFakerateRatio = endcapPhotonFakerate[s];
  
  double totalYield = 
    6.11*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +
    7.88*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +      
    31.1*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 26.4*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 48.7*myBtagEffRatio*myBtagEffRatio*myPhoEffRatio
    + 1.8*myBtagEffRatio*myBtagEffRatio
    +
    2.41*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +
    17.4*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 17.2*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 206.0*myBtagEffRatio*myBtagEffRatio*myPhoEffRatio*myEndcapPhotonFakerateRatio
    + 1.7*myBtagEffRatio*myBtagEffRatio
    ;
  double cat0Yield = 6.11*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +
    7.88*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +      
    31.1*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 26.4*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 48.7*myBtagEffRatio*myBtagEffRatio*myPhoEffRatio
    + 1.8*myBtagEffRatio*myBtagEffRatio;
  double cat1Yield = 2.41*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio +
    17.4*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 17.2*myPhoEffRatio*myPhoEffRatio*myBtagEffRatio*myBtagEffRatio
    + 206.0*myBtagEffRatio*myBtagEffRatio*myPhoEffRatio*myEndcapPhotonFakerateRatio
    + 1.7*myBtagEffRatio*myBtagEffRatio;
  double cat0Fraction = cat0Yield / totalYield;
  double cat1Fraction = cat1Yield / totalYield;

  //-------------------------------------------------------------
  //Generate Toy MC experiment data and fit
  //=============================================================     
  for(UInt_t t=0; t < NToys; ++t) {
    cout << t << "|" << s << endl;
    nsig->setVal(constNsig.getVal());
    nres_cat0->setVal(constNres_cat0.getVal());
    nnonres_cat0->setVal(constNnonres_cat0.getVal());
    nres_cat1->setVal(constNres_cat1.getVal());
    nnonres_cat1->setVal(constNnonres_cat1.getVal());
    Float_t ran;

    //if (scanOption == "lum") ran = randomNumber->Poisson(totalYield*luminosity[s]);
    //else ran = randomNumber->Poisson(totalYield);

    if (scanOption == "lum") ran = totalYield*luminosity[s];
    else ran = totalYield;


    RooDataSet *pseudoData2D = model2Dpdf->generate(RooArgList(*massBjet,*massPho, *sampleCategory), ran);
    RooFitResult *fitResult2D = model2Dpdf->fitTo(*pseudoData2D, RooFit::Save(), RooFit::Extended(kTRUE), RooFit::Strategy(2));
    ws->import(*pseudoData2D, kTRUE);
    ws->import(*pseudoData2D, Rename("pseudoData2D"));

    RooDataSet *pseudoData2D_cat0 = model2Dpdf_cat0->generate(RooArgList(*massBjet,*massPho), ran*cat0Fraction);
    RooDataSet *pseudoData2D_cat1 = model2Dpdf_cat1->generate(RooArgList(*massBjet,*massPho), ran*cat1Fraction);
    ws->import(*pseudoData2D_cat0, kTRUE);
    ws->import(*pseudoData2D_cat0, Rename("pseudoData2D_cat0"));
    ws->import(*pseudoData2D_cat1, kTRUE);
    ws->import(*pseudoData2D_cat1, Rename("pseudoData2D_cat1"));
    
    //Save variables into separate branches of root tree
    nsigOut = nsig->getVal();
    nresOut = nres_cat0->getVal();
    nnonresOut = nnonres_cat0->getVal();
    nsigStd = nsig->getPropagatedError(*fitResult2D);
    nresStd = nres_cat0->getPropagatedError(*fitResult2D);
    nnonresStd = nnonres_cat0->getPropagatedError(*fitResult2D);
    
    resultTree->Fill();      
  }
  
  //Write to the TTree and close it
  resultTree->Write();

  file->WriteTObject(ws, Form("HHToBBGGWorkspace",scanOption.c_str(),s), "WriteDelete");
  file->Close();
  delete file;




}
//-------------------------------------------------------------
//Plot the model fitting function for signal+background
//=============================================================
void MakePlots(RooWorkspace *ws, RooFitResult *fitResult2D) {
  
  RooPlot* framex = 0;
  RooPlot* framey = 0;
  
  //Import yield variables
  RooRealVar *nsig = ws->var("N (Sig)");
  RooRealVar *nres = ws->var("N (ResBkg)");
  RooRealVar *nnonres = ws->var("N (NonResBkg)");
  //Select and plot only one experiment
  if (! (nsig->getVal() >= 15.6 && nsig->getVal() <= 17.0
  				&& nres->getVal() >= 27.9 && nres->getVal() <= 28.0
  				&& nnonres->getVal() <= 287.))
  	return;
  if (alreadyPlotted) return;  
  alreadyPlotted = 1;
  
  //Import the PDF's
  RooAbsPdf *model2Dpdf = ws->pdf("model2Dpdf");
  RooAbsPdf *sigPDFPho = ws->pdf("sigPDFPho");
  RooAbsPdf *resPDFPho = ws->pdf("resPDFPho");
  RooAbsPdf *nonresPDFPho = ws->pdf("nonresPDFPho");
  RooAbsPdf *sigPDFBjet = ws->pdf("sigPDFBjet");
  RooAbsPdf *sigPDFBjetCut = ws->pdf("sigPDFBjetCut");
  RooAbsPdf *resPDFBjet = ws->pdf("resPDFBjet");
  RooAbsPdf *resPDFBjetExt = ws->pdf("resPDFBjetExt");
  RooAbsPdf *nonresPDFBjet = ws->pdf("nonresPDFBjet");
  //x-axis variables
  RooRealVar *massPho = ws->var("massPho");
  RooRealVar *massBjet = ws->var("massBjet");
  RooRealVar *massBjetExt = ws->var("massBjetExt");
  RooRealVar *massBjetCut = ws->var("massBjetCut");
  //sig variables
  RooRealVar *sigMeanBjet = ws->var("sigMeanBjet");
  RooRealVar *sigSigmaBjet = ws->var("sigSigmaBjet");
  RooRealVar *sigAlpha = ws->var("sigAlpha");
  RooRealVar *sigPower = ws->var("sigPower");
  //res bkg variables
  RooRealVar *resMeanBjet = ws->var("resMeanBjet");
  RooRealVar *resSigmaBjet = ws->var("resSigmaBjet");
  RooRealVar *resAlpha = ws->var("resAlpha");
  RooRealVar *resPower = ws->var("resPower");
  RooRealVar *resExpo = ws->var("resExpo");
  RooRealVar *nbbH = ws->var("nbbH");
  RooRealVar *nOthers = ws->var("nOthers");
  //simulated data
  RooDataHist *sigBjetData = (RooDataHist *)ws->data("sigBjetData");
  RooDataHist *resBjetDataExt = (RooDataHist *)ws->data("resBjetDataExt");
  RooDataSet *pseudoData2D = (RooDataSet *)ws->data("pseudoData2D");
  
  //Plot of 2D generated data and fits
  TH1 *data2d = pseudoData2D->createHistogram("2D Data", *massBjet,Binning(25), YVar(*massPho,Binning(25)));
  data2d->SetStats(0);
  TH1 *fit2d = model2Dpdf->createHistogram("2D Fit", *massBjet, YVar(*massPho));
  fit2d->SetStats(0);
  
  cv = new TCanvas("cv","cv",1600,600);
  cv->Divide(2);
  cv->cd(1); gPad->SetLeftMargin(0.15); data2d->Draw("LEGO2");
  data2d->SetTitle("");
  data2d->GetXaxis()->SetTitleOffset(2); data2d->GetXaxis()->SetTitle("M_{bb} [GeV/c^{2}]");
  data2d->GetYaxis()->SetTitleOffset(2.2); data2d->GetYaxis()->SetTitle("M_{#gamma#gamma} [GeV/c^{2}]");
  data2d->GetZaxis()->SetTitleOffset(1.75);
  
  cv->cd(2); gPad->SetLeftMargin(0.15); fit2d->Draw("SURF1");
  fit2d->SetTitle("");
  fit2d->GetXaxis()->SetTitleOffset(2); data2d->GetXaxis()->SetTitle("M_{bb} [GeV/c^{2}]");
  fit2d->GetYaxis()->SetTitleOffset(2.2); data2d->GetYaxis()->SetTitle("M_{#gamma#gamma} [GeV/c^{2}]");
  fit2d->GetZaxis()->SetTitleOffset(1.75);
  cv->SaveAs(Form("Plots/AllSignalBkgd/Fits/Toys/twoDimensionalFits_%d.gif",1));
  
  //Plot of massBjet and massPho projections from 2D fit
  massPho->setRange("PhoWindow",120,130);
  framex = massBjet->frame(Bins(50)); 
  framex->SetTitle(""); framex->SetXTitle("M_{bb} [GeV/c^{2}]");  framex->SetYTitle("Number of Events");
  pseudoData2D->plotOn(framex, CutRange("PhoWindow"));
  model2Dpdf->plotOn(framex, ProjectionRange("PhoWindow"), VisualizeError(*fitResult2D), FillStyle(3001));
  model2Dpdf->plotOn(framex, ProjectionRange("PhoWindow"));
  model2Dpdf->plotOn(framex, ProjectionRange("PhoWindow"), Components("sigPDFBjet"), LineStyle(kDashed), LineColor(kRed));
  model2Dpdf->plotOn(framex, ProjectionRange("PhoWindow"), Components("resPDFBjet"), LineStyle(kDashed), LineColor(kOrange));
  model2Dpdf->plotOn(framex, ProjectionRange("PhoWindow"), Components("nonresPDFBjet"), LineStyle(kDashed), LineColor(kGreen));
  
  framey = massPho->frame(Bins(50)); 
  framey->SetTitle(""); framey->SetXTitle("M_{#gamma#gamma} [GeV/c^{2}]");  framey->SetYTitle("Number of Events");
  pseudoData2D->plotOn(framey);
  model2Dpdf->plotOn(framey, VisualizeError(*fitResult2D), FillStyle(3001));
  model2Dpdf->plotOn(framey);
  model2Dpdf->plotOn(framey,Components("sigPDFPho"), LineStyle(kDashed), LineColor(kRed));
  model2Dpdf->plotOn(framey,Components("resPDFPho"), LineStyle(kDashed), LineColor(kOrange));
  model2Dpdf->plotOn(framey,Components("nonresPDFPho"), LineStyle(kDashed), LineColor(kGreen));
  
  cv = new TCanvas("cv","cv",1600,600);
  cv->Divide(2);
  cv->cd(1); framex->Draw();
  tex = new TLatex();
  tex->SetNDC();
  tex->SetTextSize(0.042);
  tex->SetTextFont(42);
  tex->DrawLatex(0.52, 0.84, Form("N_{Sig} = %.2f +/- %.2f", nsig->getVal(), nsig->getPropagatedError(*fitResult2D)));
  tex->DrawLatex(0.52, 0.79, Form("N_{ResBkg} = %.2f +/- %.2f", nres->getVal(), nres->getPropagatedError(*fitResult2D)));
  tex->DrawLatex(0.52, 0.74, Form("N_{NonResBkg} = %.2f +/- %.2f", nnonres->getVal(), nnonres->getPropagatedError(*fitResult2D)));
  tex->Draw();
  cv->Update();
  cv->cd(2); framey->Draw();
  tex->DrawLatex(0.52, 0.84, Form("N_{Sig} = %.2f +/- %.2f", nsig->getVal(), nsig->getPropagatedError(*fitResult2D)));
  tex->DrawLatex(0.52, 0.79, Form("N_{ResBkg} = %.2f +/- %.2f", nres->getVal(), nres->getPropagatedError(*fitResult2D)));
  tex->DrawLatex(0.52, 0.74, Form("N_{NonResBkg} = %.2f +/- %.2f", nnonres->getVal(), nnonres->getPropagatedError(*fitResult2D)));
  tex->Draw();
  cv->Update();
  cv->SaveAs(Form("Plots/AllSignalBkgd/Fits/Toys/projectionFits_%d.gif",1));
}
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;

}