void MakeIndividualPDFhists(const std::string name)
{
	const int nfiles = 6;
	
	TFile* f[nfiles];
	f[0] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst1.root");
	f[1] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst2.root");
	f[2] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst3.root");
	f[3] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst4.root");
	f[4] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst5.root");
	f[5] = new TFile("~/RESULTS/10222009_PDFsystFullMCDataset/10272009_Result3/PDFsyst6.root");


	assert (f[0] !=NULL && "FILE 1 NOT FOUND!");
	assert (f[1] !=NULL && "FILE 2 NOT FOUND!");
	assert (f[2] !=NULL && "FILE 3 NOT FOUND!");
	assert (f[3] !=NULL && "FILE 4 NOT FOUND!");
	assert (f[4] !=NULL && "FILE 5 NOT FOUND!");
	assert (f[5] !=NULL && "FILE 6 NOT FOUND!");

	TH1* h[41];
	
	float xmin = 0;
	float xpoint1 = 200;
	float xpoint2 = 250;
	float xpoint3 = 300;
	float xpoint4 = 650;
	float width1 = 10;
	float width2 = 10;
	float width3 = 50;
	float width4 = 250;
	
	//0th hist is the reference. other 40 are the variants.
	for (int i=0; i < 41; ++i)
	{
		std::stringstream hist;
		hist << "Ana/PhoJetsTemp/Hist/1Jet/PDFSyst/PDFSystPara"<< i << "_" << name;
		std::cout << "looking for hist " << hist.str() << std::endl;
		h[i] = dynamic_cast<TH1*> (f[0]->Get(hist.str().c_str()));
		assert (h[i] != NULL && "hist is null");
		//Sumw2() for these hists are called at creation
		
		//add the other 2 jobs resutls
		for (int nf=1;nf< nfiles;++nf)
		{
			TH1* temp = dynamic_cast<TH1*> (f[nf]->Get(hist.str().c_str()));
			assert (temp != NULL && "hist is null");
			h[i]->Add(temp);
		}
		

		h[i] = (TH1F*) MakeVariableBins (h[i], xmin, xpoint1, xpoint2, xpoint3, xpoint4, width1, width2, width3, width4, false);
		if (i>0)
		{
			h[i]->Scale(h[0]->Integral()/(1. * h[i]->Integral()));
			h[i]->Divide(h[0]);
			int marker = 22, color=2;
			if (i%2)
			{
				marker = 23;
				color = 4;
			}
				
			h[i]->SetMarkerColor(color);
			h[i]->SetLineColor(color);
			h[i]->SetMarkerStyle(marker);
			h[i]->SetMarkerSize(1);
		}
	}


			gStyle->SetOptStat(0);
		new TCanvas();
		gPad->SetGridx();
		gPad->SetGridy();
		gPad->SetTickx();
		gPad->SetTicky();



	//make a plot for each PDF parameter wrt to reference
	for (int ipdf = 1; ipdf <41; ipdf=ipdf+2)
	{
		//h[ipdf]->Scale(h[0]->Integral()/(1. * h[ipdf]->Integral()));
		//h[ipdf+1]->Scale(h[0]->Integral()/(1. * h[ipdf+1]->Integral()));
		std::string xtitle, ytitle;
		if (name == "PhoEt") xtitle = "E_{T}^{#gamma}";
		ytitle = "Ratio wrt base (Parameter 0)";
		
		std::stringstream title, le1,le2, file;
		int jpdf = ipdf+1;
		title << "PDF parameter " << ipdf << " & "<< jpdf << "(normalized to base and ratio wrt to base)"
				<< ";" << xtitle << ";" << ytitle;
		le1 << "Parameter " << ipdf;
		le2 << "Parameter " << jpdf;
		file << "PDFpara_"<< ipdf << "_" << jpdf << ".eps";

		
		//h[ipdf]->SetMinimum(0.9);
		//h[ipdf]->SetMaximum(1.1);
		//h[ipdf]->SetTitle(title.str().c_str());
		h[ipdf]->GetXaxis()->CenterTitle(1);
		h[ipdf]->GetYaxis()->CenterTitle(1);

		if (ipdf==1) 
		{
			h[ipdf]->Draw();
			h[ipdf+1]->Draw("SAME");
		} else 
		{
			h[ipdf]->Draw("SAME");
			h[ipdf+1]->Draw("SAME");
		}

		TLegend *leg = new TLegend (0.7,0.8,0.9,0.9);
		leg->SetTextFont(42);
		leg->SetTextSize(0.03);


		leg->AddEntry(h[ipdf],le1.str().c_str());
		leg->AddEntry(h[ipdf+1],le2.str().c_str());
		//leg->Draw();
		//gPad->Print(file.str().c_str());
		
	}



	return;

	
	for (int i=1; i < 40; ++i)
	{
		if (i==1)
		{
			h[i]->Draw("P");
			h[i]->SetTitle("PDF: 40 variants wrt to CTEQ6;E_{T}^{#gamma};Ratio");
			//h[i]->SetTitle("PDF: 40 variants wrt to CTEQ6;E_{T}^{jet};Ratio");
		}
		else h[i]->Draw("P same");
	}

	//no make a plot with max/min values
	//exclude the 0th hist which is the reference
	
	for (int bin=0; bin<= h[1]->GetNbinsX(); ++bin)
	{
		if (h[1]->GetBinContent(bin))
		{
			float max=1,min=1;
			float maxer=0,miner=0;
			for (int nh=2; nh<41; ++nh)
			{
				if (h[nh]->GetBinContent(bin) > max )
				{
					max = h[nh]->GetBinContent(bin);
					maxer = h[nh]->GetBinError(bin);
				}
				if (h[nh]->GetBinContent(bin) < min )
				{
					min = h[nh]->GetBinContent(bin);
					miner = h[nh]->GetBinError(bin);
				}
			}
			
			h[1]->SetBinContent(bin,max);
			h[1]->SetBinError(bin,maxer);
			h[2]->SetBinContent(bin,min);
			h[2]->SetBinError(bin,miner);
		}

	}

	new TCanvas();
	gPad->SetGridx();
	gPad->SetGridy();
	gPad->SetTickx(2);
	gPad->SetTicky(2);
	h[1]->SetTitle("Max/Min of 40 PDF variants");
	h[1]->Draw("PE1");
	h[2]->Draw("SAME PE1");
	
	

return;

	TH1* ph = dynamic_cast<TH1*> (f[0]->Get("Ana/PhoJetsTemp/Hist/1Jet/Photon/EtCorr"));
	assert (ph != NULL && " photon hist is null");
	for (int nf=1;nf< nfiles;++nf)
	{
		TH1* temp = dynamic_cast<TH1*> (f[nf]->Get("Ana/PhoJetsTemp/Hist/1Jet/Photon/EtCorr"));
		assert (temp != NULL && "photon jobs hist is null");
		temp->Sumw2();
		ph->Add(temp);
	}

	ph = (TH1F*) MakeVariableBins (ph, xmin, xpoint1, xpoint2, xpoint3, xpoint4, width1, width2, width3, width4, false);

	new TCanvas();
	ph->Draw();
	return;
	
	TH1* final = dynamic_cast<TH1*> (ph->Clone("copy"));
	assert (final != NULL && " photon hist is null");
	for (int bin =0; bin <= ph->GetNbinsX()+1; ++bin)
	{
		final->SetBinError(bin,0);
		final->SetBinContent(bin,0);
예제 #2
0
파일: plotXJ.C 프로젝트: bjet2015/dibjets
TGraphErrors *makesysplot(TH1F *h, float dmu, int color)
{

  auto h1 = (TH1F *)h->Clone("h1");
  auto h2 = (TH1F *)h->Clone("h2");

  //if (h->GetTitle()=="Data b-jets 12")
    h->SetTitle("Data b-jets");
  h1->SetTitle("variation up");
  h2->SetTitle("variation down");

  float mu = h->GetMean();

  int n = round(mu*10);
  float i1=h->Integral(1,n);
  float w1 = weightedsum(h,1,n);

  float t = (mu-w1)/(1-i1);
  float alpha1 = (mu-dmu-t)/(w1-t*i1)-1;
  float beta1 = (1-(1+alpha1)*i1)/(1-i1)-1;
  float alpha2 = (mu+dmu-t)/(w1-t*i1)-1;
  float beta2 = (1-(1+alpha2)*i1)/(1-i1)-1;

  auto hbar = (TH1F *)h->Clone("hbar");


  for (int i=1;i<=h->GetNbinsX();i++) {
    float p = i>n ? 1+alpha1 : 1+beta1;
    h1->SetBinContent(i,h->GetBinContent(i)*p);
    p = i>n ? 1+alpha2 : 1+beta2;
    h2->SetBinContent(i,h->GetBinContent(i)*p);
  }
  Normalize({h1,h2}); //in principle it is not needed
  for (int i=1;i<=h->GetNbinsX();i++)
    hbar->SetBinError(i,fabs(h2->GetBinContent(i)-h1->GetBinContent(i))/2);



  hbar->SetFillColor(color);
  
  plotlegendpos = TopLeft;
  // plotsecondline = Form("%.3f,%.3f",h1->GetMean()-mu,mu-h2->GetMean()); //check means
  // plotthirdline = Form("%.3f",dmu);

  TGraphErrors *sys = new TGraphErrors(hbar->GetNbinsX());
  sys->SetFillColor(color);
  for (int i=1;i<=hbar->GetNbinsX();i++) {
    sys->SetPoint(i,hbar->GetBinCenter(i),hbar->GetBinContent(i));
    sys->SetPointError(i,0.05,hbar->GetBinError(i));
  }


  //draw true value, variation1 and variation2
  plotytitle = "Event fractions";
  // Draw({h,h1,h2},{"E1","hist","hist","e1p"});


  // auto c2 = getc();
  // h->Draw("e1");
  // sys->Draw("e2");
  // h->Draw("e1,same");
  // SavePlot(c2,Form("%ssys2",h->GetName()));


  return sys;


  //draw cdf (for fun)
  // auto hint = h->GetIntegral();
  // auto h1int = h1->GetIntegral();
  // auto h2int = h2->GetIntegral();

  // vector<double> xaxis;
  // for (int i=1;i<=h->GetNbinsX()+1;i++) xaxis.push_back(h->GetBinLowEdge(i));

  // auto g = new TGraph(xaxis.size()+1,&xaxis[0],hint); g->SetLineColor(kRed);
  // auto g1 = new TGraph(xaxis.size()+1,&xaxis[0],h1int); g1->SetLineColor(kGreen);
  // auto g2 = new TGraph(xaxis.size()+1,&xaxis[0],h2int); g2->SetLineColor(kBlue);

  // auto c = getc();
  // g->SetMinimum(0);g->SetMaximum(1);
  // g->Draw();
  // g1->Draw("same");
  // g2->Draw("same");

  // g->GetXaxis()->SetTitle("x_{J}");
  // g->GetXaxis()->SetTitle("prob");

  // SavePlots(c,"cum");

}
예제 #3
0
void checkdatainc(TString datafilename, TString incfilename)
{
  TFile *f = new TFile(datafilename);
  nt = (TTree *)f->Get("nt");
  auto h = new TH1F("data_rawpt","data_rawpt",ptbins,ptmin,ptmax);
  nt->Project(h->GetName(),"rawpt","weight");
  auto h4 = new TH1F("data_jtpt","data_jtpt",ptbins,ptmin,ptmax);
  nt->Project(h4->GetName(),"jtpt","weight");
  auto h2 = new TH1F("data_jteta","data_jteta",30,-2.4,2.4);
  nt->Project(h2->GetName(),"jteta","weight*(jtpt>120)");
  auto h3 = new TH1F("data_jtphi","data_jtphi",30,-3.14,3.14);
  nt->Project(h3->GetName(),"jtphi","weight*(jtpt>120)");

  fout->cd();
  h->Write();
  h2->Write();
  h3->Write();
  h4->Write();
  f->Close();

  f = new TFile(incfilename);
  nt = (TTree *)f->Get("nt");
  auto hinc = geth("inc_pthat");
  nt->Project(hinc->GetName(),"pthat","weight");

  auto hraw = new TH1F("inc_rawpt","inc_rawpt",ptbins,ptmin,ptmax);
  nt->Project(hraw->GetName(),"rawpt","weight");

  auto hpt = new TH1F("inc_jtpt","inc_jtpt",ptbins,ptmin,ptmax);
  nt->Project(hpt->GetName(),"jtpt","weight");

  auto heta = new TH1F("inc_jteta","inc_jteta",30,-2.4,2.4);
  nt->Project(heta->GetName(),"jteta","weight*(jtpt>120)");

  auto hphi = new TH1F("inc_jtphi","inc_jtphi",30,-3.14,3.14);
  nt->Project(hphi->GetName(),"jtphi","weight*(jtpt>120)");

  auto hJES = new TProfile("inc_JES","inc_JES",ptbins,0,ptmax);//30,200);
  nt->Project(hJES->GetName(),"jtpt/refpt:refpt","weight*(jtpt>20 && refpt>30)","prof");

  //  auto hJER = new TProfile("inc_JER","inc_JER",ptbins,30,200);
  //  nt->Project(hJER->GetName(),"abs(jtpt-refpt)/refpt:refpt","weight","prof");

  auto hJER = new TH1F("inc_JER","inc_JER",ptbins,0,ptmax);
  auto htemp=new TProfile("htemp","htemp",ptbins,0,ptmax,"CHOPT='S'"); //easily calculates RMS
  nt->Project("htemp","jtpt/refpt:refpt","weight*(jtpt>20 && refpt>30)","prof");
  for (int i=1;i<ptbins;i++) {
    hJER->SetBinContent(i,htemp->GetBinError(i));
    hJER->SetBinError(i,htemp->GetBinError(i)/1000); //should be fixed
  }




  fout->cd();
  hinc->Write();
  hpt->Write();
  hraw->Write();
  heta->Write();
  hphi->Write();
  hJES->Write();
  hJER->Write();
  f->Close();


}
예제 #4
0
void checkclosure()
{
  vector<TH1F *>hsig(Nbins);
  vector<TH1F *>hasd(Nbins);
  vector<TH1F *>hbkg(Nbins);
  vector<TH1F *>hsub(Nbins);
  vector<TH1F *>hhyj(Nbins);
  vector<TH1F *>hshj(Nbins);
  vector<TH1F *>hsbn(Nbins);


  for (int i=0;i<Nbins;i++) {
    seth(10,0,1);
    hsig[i] = geth(Form("hsig%d",i),Form("Signal away-side %s;x_{J}",binnames[i].Data())) ;
    hasd[i] = geth(Form("hasd%d",i),Form("Measured away-side %s;x_{J}",binnames[i].Data()));
    hbkg[i] = geth(Form("hbkg%d",i),Form("Near-side %s;x_{J}",binnames[i].Data()));
    hhyj[i] = geth(Form("hhyj%d",i),Form("Near-side hydjet %s;x_{J}",binnames[i].Data()));
    hsub[i] = geth(Form("hsub%d",i),Form("Subtracted NS %s;x_{J}",binnames[i].Data()));
    hshj[i] = geth(Form("hshj%d",i),Form("Subtracted Hydjet %s;x_{J}",binnames[i].Data()));
    hsbn[i] = geth(Form("hsbn%d",i),Form("Subtracted Naive %s;x_{J}",binnames[i].Data()));
  }




  auto fmcPb = config.getfile_djt("mcPbbfa");

  Fill(fmcPb,{"pthat","weight","jtpt1","refpt1","bProdCode","jtptSL","refptSL","dphiSL1","refparton_flavorForB1","subidSL","bin","pairCodeSL1","discr_csvV1_1","jteta1","jtetaSL"},[&] (dict d) {
      if (d["pthat"]<pthatcut) return;
      
      if (d["jtpt1"]>pt1cut && d["refpt1"]>50 && abs(d["refparton_flavorForB1"])==5 && d["jtptSL"]>pt2cut) {
        int bin = getbinindex(d["bin"]);
        
        float xj = d["jtptSL"]/d["jtpt1"];
        float w = weight1SLPbPb(d);
        if (AwaySide(d)) hasd[bin]->Fill(xj, w);
        if (AwaySide(d) && IsSignal(d)) hsig[bin]->Fill(xj,w);

        if (NearSide(d)) hbkg[bin]->Fill(xj,w);
        if (NearSide(d) && !IsSignal(d)) hhyj[bin]->Fill(xj,w);
      }
        



      });



  for (int i=0;i<Nbins;i++) {
    hsub[i]->Add(hasd[i],hbkg[i],1,-1*bkgfractionInNearSide[i]);
    hsbn[i]->Add(hasd[i],hbkg[i],1,-1);
    hshj[i]->Add(hasd[i],hhyj[i],1,-1);
  }
//  for (int i=0;i<Nbins;i++) 
//    hincsub[i]->Add(hincasd[i],hincbkg[i],1,-1);

  seth(bins);//Nbins,0,100);
  auto hcentrSubSIG = geth("hcentrSubSIG","Signal;bin;#LTx_{J}#GT");
  auto hcentrSubASD = geth("hcentrSubASD","Unsubtracted;bin;#LTx_{J}#GT");

  auto hcentrSubBKS = geth("hcentrSubBKS","Subtracted w/o bkg scaling;bin;#LTx_{J}#GT");
  auto hcentrSubCLS = geth("hcentrSubCLS","Subtracted with bkg scaling;bin;#LTx_{J}#GT");
  auto hcentrSubHJS = geth("hcentrSubHJS","Subtracted Hydjet;bin;#LTx_{J}#GT");


  plotlegendpos = BottomRight;


  for (int i=0;i<Nbins;i++) {
    hcentrSubSIG->SetBinContent(i+1,hsig[i]->GetMean());hcentrSubSIG->SetBinError(i+1,hsig[i]->GetMeanError());
    hcentrSubASD->SetBinContent(i+1,hasd[i]->GetMean());hcentrSubASD->SetBinError(i+1,hasd[i]->GetMeanError());
    hcentrSubBKS->SetBinContent(i+1,hsbn[i]->GetMean());hcentrSubBKS->SetBinError(i+1,hsbn[i]->GetMeanError());

    hcentrSubCLS->SetBinContent(i+1,hsub[i]->GetMean());hcentrSubCLS->SetBinError(i+1,hsub[i]->GetMeanError());
    hcentrSubHJS->SetBinContent(i+1,hshj[i]->GetMean());hcentrSubHJS->SetBinError(i+1,hshj[i]->GetMeanError());

    Draw({hsig[i],hsub[i],hshj[i]});
  }


  plotymin = 0.55;//0.4;
  plotymax = 0.7;//0.8;
  plotlegendpos = BottomRight;
  aktstring = "";


  plotputmean = false;
  //hcentrSubHJS - hydjet only subtraction
  // SetMC({hcentrSubSIG, hcentrSubBKS, hcentrSubASD});
  // SetData({hcentrSubCLS});

  hcentrSubSIG->SetMarkerStyle(kOpenSquare);
  hcentrSubBKS->SetMarkerStyle(kOpenSquare);
  hcentrSubASD->SetMarkerStyle(kOpenSquare);
  hcentrSubCLS->SetMarkerStyle(kFullCircle);


  hcentrSubSIG->SetMarkerColor(TColor::GetColorDark(2)); hcentrSubSIG->SetLineColor(TColor::GetColorDark(2));
  hcentrSubBKS->SetMarkerColor(TColor::GetColorDark(3)); hcentrSubBKS->SetLineColor(TColor::GetColorDark(3));
  hcentrSubASD->SetMarkerColor(TColor::GetColorDark(4)); hcentrSubASD->SetLineColor(TColor::GetColorDark(4));
  hcentrSubCLS->SetMarkerColor(TColor::GetColorDark(3)); hcentrSubCLS->SetLineColor(TColor::GetColorDark(3));

  plotoverwritecolors = false;
  plotlegenddx = -0.15;

  Draw({hcentrSubSIG,hcentrSubASD, hcentrSubBKS, hcentrSubCLS});


  auto syst = (TH1F *)hcentrSubSIG->Clone("syst");
  syst->Add(hcentrSubCLS,-1);
  map<TString,float> m;
  for (unsigned i=0;i<bins.size()-1;i++) {
    float misclosure = syst->GetBinContent(i+1);
    float err = hcentrSubCLS->GetBinError(i+1);
    m[Form("closure%d%d",(int)bins[i],(int)bins[i+1])]=sqrt(misclosure*misclosure+err*err);
  }

  WriteToFile(plotfoldername+"/hydjetclosuresyst.root",m);


}
예제 #5
0
void dataDrivenFromCR(TFile* fdata, TFile* fmc, TFile* fout, TString ddtype, TString gentype) {
  // Additional hists to consider: dataStats, MCstats, impurity

  TList* listOfDirs = fmc->GetListOfKeys();
  for (auto k : *listOfDirs) {
    TString srname = k->GetName();
    if (!srname.Contains("sr")) continue;
    if (srname.Contains("base") || srname.Contains("incl") || srname.Contains("sb")) continue;
    if (ddtype == "cr0b" && (srname.EndsWith("2") || srname.EndsWith("3"))) continue;

    TString crname = srname;
    crname.ReplaceAll("sr", ddtype);

    TString hname_data_CR = crname + "/h_metbins";
    TString hname_MC_SR = srname + "/h_metbins" + gentype;
    TString hname_MC_CR = crname + "/h_metbins";

    auto outdir = (TDirectory*) fout->mkdir(srname);

    auto hist_data_CR = (TH1D*) fdata->Get(hname_data_CR);
    auto hist_MC_CR = (TH1D*) fmc->Get(hname_MC_CR);
    auto hist_MC_SR = (TH1D*) fmc->Get(hname_MC_SR);

    if (!fmc->Get(hname_MC_CR)) {
      cout << "Couldn't find yield hist for " << hist_MC_CR << " in " << fmc->GetName() << "!!" << endl;
      cout << "This should not happend! Can not use data driven on this region! Use MC yields directly use TF from other SR!" << endl;
      continue;  // <-- actions to be added
    }
    if (!fmc->Get(hname_MC_SR)) {
      cout << "Couldn't find yield hist for " << hist_MC_SR << " in " << fmc->GetName() << ". Cannot define TF!" << endl;
      continue;  // <-- actions to be added
    }
    if (!fdata->Get(hname_data_CR)) {
      cout << "Couldn't find yield hist for " << hist_data_CR << " in " << fdata->GetName() << ". Please use yield from MC!" << endl;
      continue;  // <-- actions to be added
    }

    int lastbin = hist_data_CR->GetNbinsX();
    int extr_start_bin = lastbin; // the bin to start extrapolation, if == lastbin means no MET extrapolation is needed

    auto combineYieldsInExtrBins = [&](TH1D* hist) {
      double err = 0;
      double ylds = hist->IntegralAndError(extr_start_bin, -1, err);
      for (int ibin = extr_start_bin; ibin <= lastbin; ++ibin) {
        hist->SetBinContent(ibin, ylds);
        hist->SetBinError(ibin, err);
      }
    };

    if (useMetExtrapolation) {
      double yldCR(0.0), err(0.0);
      for (; extr_start_bin > 1; --extr_start_bin) {
        yldCR = hist_MC_CR->IntegralAndError(extr_start_bin, -1, err);
        double TFval = hist_MC_SR->GetBinContent(extr_start_bin) / yldCR;
        if (yldCR > extr_threshold && (TFval < extr_TFcap)) break;
      }
      // if (gentype == "_2lep" && (srname == "srE2" || srname == "srG2")) extr_start_bin = lastbin; // temporary hack for 2016
      // if (gentype == "_2lep" && (srname == "srH")) extr_start_bin = 1; // temporary hack for 2016
      if (extr_start_bin != lastbin) {
        cout << "Doing MET extrapolation for  " << crname << "  from bin " << lastbin << " (last bin) to bin " << extr_start_bin << "!" << endl;
        hist_data_CR->Clone("h_datayields_CR_raw")->Write();
        combineYieldsInExtrBins(hist_data_CR);
      }
    }

    TH1D* centralHist;

    auto crdir = (TDirectoryFile*) fmc->Get(crname);
    for (auto h : *(crdir->GetListOfKeys())) {
      TString hname = h->GetName();
      if (!hname.BeginsWith("h_metbins")) continue;
      // hardcode genclass skipping for now
      if (hname.Contains("_2lep") || hname.Contains("_1lep") || hname.Contains("_Znunu") || hname.Contains("_unclass")) continue;

      TString hnameSR = hname;
      hnameSR.ReplaceAll("h_metbins", "h_metbins" + gentype);

      // Not using fraction
      auto hist_MC_CR = (TH1D*) crdir->Get(hname)->Clone(hname+"_cr");
      auto hist_MC_SR = (TH1D*) fmc->Get(srname + "/" + hnameSR);

      if (!hist_MC_SR) {
        if (!hnameSR.Contains("cr2lTriggerSF"))
          cout << "Couldn't find yield hist for " << (srname + "/" + hnameSR) << " in " << fmc->GetName() << ". Use centralHist!" << endl;
        hist_MC_SR = (TH1D*) fmc->Get(hname_MC_SR)->Clone(hnameSR);
      }

      auto alphaHist = (TH1D*) hist_MC_SR->Clone(hname+"_alpha");
      if (useMetExtrapolation && extr_start_bin != lastbin) {
        // To take the MET distribution from the CR
        double cerr_SR = 0;
        double cyld_SR = alphaHist->IntegralAndError(extr_start_bin, -1, cerr_SR);
        double cyld_CR = hist_MC_CR->Integral(extr_start_bin, -1);
        for (int ibin = extr_start_bin; ibin <= lastbin; ++ibin) {
          double metfrac = hist_MC_CR->GetBinContent(ibin) / cyld_CR;
          alphaHist->SetBinContent(ibin, metfrac * cyld_SR);
          alphaHist->SetBinError(ibin, metfrac * cerr_SR);
        }
        combineYieldsInExtrBins(hist_MC_CR);
      }
      alphaHist->Divide(hist_MC_CR);

      for (int i = 1; i <= alphaHist->GetNbinsX(); ++i) {
        // zero out negative yields
        if (alphaHist->GetBinContent(i) < 0) {
          alphaHist->SetBinContent(i, 0);
          alphaHist->SetBinError(i, 0);
        }
      }

      outdir->cd();
      TH1D* hout = (TH1D*) alphaHist->Clone(hname);
      hout->Multiply(hist_data_CR);
      hout->Write();

      if (yearSeparateSyst && (hname.EndsWith("Up") || hname.EndsWith("Dn"))) {
        for (int i = 1; i < 4; ++i) {

          auto hcen_MC_CR = (TH1D*) fbkgs[i]->Get(crname+"/h_metbins");
          auto hcen_MC_SR = (TH1D*) fbkgs[i]->Get(srname+"/h_metbins"+gentype);
          auto hsys_MC_CR = (TH1D*) fbkgs[i]->Get(crname+"/"+hname);
          auto hsys_MC_SR = (TH1D*) fbkgs[i]->Get(srname+"/"+hnameSR);

          if (!hist_MC_SR) {
            if (!hnameSR.Contains("cr2lTriggerSF"))
              cout << "Couldn't find yield hist for " << (srname + "/" + hnameSR) << " in " << fmc->GetName() << ". Use centralHist!" << endl;
            hist_MC_SR = (TH1D*) fmc->Get(hname_MC_SR)->Clone(hnameSR);
          }

          auto alphaHist_yi = (TH1D*) fmc->Get(hname_MC_SR)->Clone(TString(hname).Insert(hname.Length()-2, Form("%d", 15+i)));
          auto h_MC_CR_yi = (TH1D*) fmc->Get(hname_MC_CR)->Clone(Form("%s_den_%d", hname.Data(), 15+i));
          if (hcen_MC_SR) alphaHist_yi->Add(hcen_MC_SR, -1);
          if (hsys_MC_SR) alphaHist_yi->Add(hsys_MC_SR);
          if (hcen_MC_CR) h_MC_CR_yi->Add(hcen_MC_CR, -1);
          if (hsys_MC_CR) h_MC_CR_yi->Add(hsys_MC_CR);

          if (useMetExtrapolation && extr_start_bin != lastbin) {
            // To take the MET distribution from the CR
            double cerr_SR = 0;
            double cyld_SR = alphaHist_yi->IntegralAndError(extr_start_bin, -1, cerr_SR);
            double cyld_CR = h_MC_CR_yi->Integral(extr_start_bin, -1);
            for (int ibin = extr_start_bin; ibin <= lastbin; ++ibin) {
              double metfrac = h_MC_CR_yi->GetBinContent(ibin) / cyld_CR;
              alphaHist_yi->SetBinContent(ibin, metfrac * cyld_SR);
              alphaHist_yi->SetBinError(ibin, metfrac * cerr_SR);
            }
            combineYieldsInExtrBins(h_MC_CR_yi);
          }
          alphaHist_yi->Divide(h_MC_CR_yi);

          for (int i = 1; i <= alphaHist_yi->GetNbinsX(); ++i) {
            // zero out negative yields
            if (alphaHist_yi->GetBinContent(i) < 0) {
              alphaHist_yi->SetBinContent(i, 0);
              alphaHist_yi->SetBinError(i, 0);
            }
          }
          outdir->cd();
          alphaHist_yi->Multiply(hist_data_CR);
          alphaHist_yi->Write();
        }
      }

      if (hname.EndsWith("h_metbins")) {
        centralHist = hout;
        // Store the central alpha hist and extr_start_bin for signal contamination
        alphaHist->Write("h_alphaHist");
        if (useMetExtrapolation && extr_start_bin < lastbin) {
          TH1D* h_extrstart = new TH1D("h_extrstart", "MET extrapolation start bin", 1, 0, 1);
          h_extrstart->SetBinContent(1, extr_start_bin);
          h_extrstart->Write();
        }
        if (doCRPurityError) {
          auto hist_MC_CR_pure = (TH1D*) fmc->Get(hname_MC_CR + gentype);
          auto hout_purityUp = (TH1D*) hout->Clone(hname+"_CRpurityUp");
          auto hout_purityDn = (TH1D*) hout->Clone(hname+"_CRpurityDn");
          if (useMetExtrapolation && extr_start_bin < lastbin)
            combineYieldsInExtrBins(hist_MC_CR_pure);
          for (int ibin = 1; ibin <= lastbin; ++ibin) {
            double crpurityerr = 0.5 * (hist_MC_CR->GetBinContent(ibin) - hist_MC_CR_pure->GetBinContent(ibin)) / hist_MC_CR->GetBinContent(ibin);
            hout_purityUp->SetBinContent(ibin, hout->GetBinContent(ibin) / ( 1 - crpurityerr));
            hout_purityDn->SetBinContent(ibin, hout->GetBinContent(ibin) / ( 1 + crpurityerr));
          }
          hout_purityUp->Write();
          hout_purityDn->Write();

          auto purityHist = (TH1D*) hist_MC_CR_pure->Clone("h_CRpurity");
          purityHist->Divide(hist_MC_CR_pure, hist_MC_CR, 1, 1, "B");
          purityHist->Write();
        }
      }
    }

    // Create alphaHist for dataStats
    auto h_dataStats = (TH1D*) centralHist->Clone("h_metbins_dataStats");
    auto h_MCStats = (TH1D*) centralHist->Clone("h_metbins_MCStats");
    for (int ibin = 1; ibin <= extr_start_bin; ++ibin) {
      // If not doing met extrapolation, extr_start_bin will equal to lastbin
      double data_error_thisbin = (hist_data_CR->GetBinContent(ibin) < 0.01)? 0 : hist_data_CR->GetBinError(ibin) / hist_data_CR->GetBinContent(ibin);
      h_dataStats->SetBinError(ibin, data_error_thisbin * h_dataStats->GetBinContent(ibin));

      double MC_SR_error_thisbin = (hist_MC_SR->GetBinContent(ibin) < 1e-5)? 0 : hist_MC_SR->GetBinError(ibin) / hist_MC_SR->GetBinContent(ibin);
      double MC_CR_error_thisbin = (hist_MC_CR->GetBinContent(ibin) < 1e-5)? 0 : hist_MC_CR->GetBinError(ibin) / hist_MC_CR->GetBinContent(ibin);
      double MC_error_thisbin = sqrt(MC_SR_error_thisbin*MC_SR_error_thisbin + MC_CR_error_thisbin*MC_CR_error_thisbin);

      h_MCStats->SetBinError(ibin, MC_error_thisbin * h_MCStats->GetBinContent(ibin));
    }
    for (int ibin = extr_start_bin+1; ibin <= lastbin; ++ibin) {
      // If doing met extrapolation, the bins following extr_start_bin for data and MC CR will be set to have 0 stat error
      // TODO: verify that this is the right thing to do
      h_dataStats->SetBinError(ibin, 0);
      double MC_SR_error_thisbin = (hist_MC_SR->GetBinContent(ibin) < 1e-5)? 0 : hist_MC_SR->GetBinError(ibin) / hist_MC_SR->GetBinContent(ibin);
      h_MCStats->SetBinError(ibin, MC_SR_error_thisbin * h_MCStats->GetBinContent(ibin));
    }

    h_dataStats->Write();
    h_MCStats->Write();

    hist_data_CR->Clone("h_datayields_CR")->Write();
    hist_MC_CR->Clone("h_MCyields_CR")->Write();
    hist_MC_SR->Clone("h_MCyields_SR")->Write();
  }
}