void testMVATrainerAnalysis()
{
	using namespace PhysicsTools;

	setStyle();

	MVAComputer mva("testMVAComputerEvaluate.mva");

	Variable::Value values[3];
	values[0].setName("x");
	values[1].setName("y");

	TH2F *f = new TH2F("discr", "Discriminator", 200, -10, 10, 200, -10, 10);
	f->SetXTitle("x");
	f->SetYTitle("y");

	TH2F *g = new TH2F("dx", "dD/dx", 200, -10, 10, 200, -10, 10);
	g->SetXTitle("x");
	g->SetYTitle("y");

	TH2F *h = new TH2F("dy", "dD/dy", 200, -10, 10, 200, -10, 10);
	h->SetXTitle("x");
	h->SetYTitle("y");

	for(double x = -10 + 0.05; x < 10; x += 0.1)  {
		for(double y = -10 + 0.05; y < 10; y += 0.1) {
			values[0].setValue(x);
			values[1].setValue(y);
			double v = mva.deriv(values, values + 2);
			f->SetBinContent(f->FindBin(x, y), v);
			g->SetBinContent(g->FindBin(x, y), values[0].getValue());
			h->SetBinContent(h->FindBin(x, y), values[1].getValue());
		}
	}

	TCanvas *c1 = new TCanvas("c1");
	c1->Divide(2, 2);
	c1->cd(1);
	f->SetStats(0);
	f->SetContour(511);
	f->Draw("colz");
	c1->cd(3);
	g->SetStats(0);
	g->SetContour(511);
	g->Draw("colz");
	c1->cd(4);
	h->SetStats(0);
	h->SetContour(511);
	h->Draw("colz");
}
float getSMSxs(float mlsp,float mglu) {
  TH2F *refh  =  new TH2F("ReferenceHisto","ReferenceHisto",(int)((mgluend-mglustart)/mglustep+1),mglustart-0.5*mglustep,mgluend+0.5*mglustep,int((mLSPend-mLSPstart)/mLSPstep+1),mLSPstart-0.5*mLSPstep,mLSPend+0.5*mLSPstep);
  refh->SetBinContent(refh->FindBin(mglu,mlsp),1);//only compute the cross section for our point
  TFile *xsecfile = new TFile((PlottingSetup::cbafbasedir+"/"+PlottingSetup::SMSReferenceXSFile).c_str());
  if(xsecfile->IsZombie()) {
      write_error(__FUNCTION__,"Cross section file is invalid!!!!");
      return -1;
  }
  xsecfile->Close();
  delete xsecfile;
  TH2F *xsec = adjust_histo(get_XS(PlottingSetup::cbafbasedir+"/"+PlottingSetup::SMSReferenceXSFile,"gluino",refh),refh);
  int GlobalBin = xsec->FindBin(mglu,mlsp);
  float refxs=xsec->GetBinContent(GlobalBin);
  delete refh;
  delete xsec;
  return refxs;
}
Exemple #3
0
//2d reweighting of rho and its sigma
void reweight_rhosigma(TH1F* weight_rho, TH1F* weight_rhoo,TH2F*weight_rhon,TH2F*weight_rho2o,TH2F* weight_rhonr, TH2F* weight_rho2,TH2F*weight_sigman,TH2F*weight_sigma2o,TH2F* weight_sigmanr, TH2F* weight_sigma2,RooDataSet **dset, RooDataSet *dsetdestination, bool deleteold){
  if (!(*dset)) return;
//  TH2F *hnum = new TH2F("hnum","hnum",n_rhobins_forreweighting,rhobins_forreweighting,n_sigmabins_forreweighting,sigmabins_forreweighting);
//  TH2F *hden = new TH2F("hden","hden",n_rhobins_forreweighting,rhobins_forreweighting,n_sigmabins_forreweighting,sigmabins_forreweighting);
  TH2F *hnum = new TH2F("hnum","hnum",100,0,100,20,0,20);
  TH2F *hden = new TH2F("hden","hden",100,0,100,20,0,20);
  hnum->Sumw2();
  hden->Sumw2();
  for (int i=0; i<(*dset)->numEntries(); i++){
    hden->Fill(fabs((*dset)->get(i)->getRealValue("roorho")),fabs((*dset)->get(i)->getRealValue("roosigma")),(*dset)->store()->weight(i));
  }
  for (int i=0; i<dsetdestination->numEntries(); i++){
    hnum->Fill(fabs(dsetdestination->get(i)->getRealValue("roorho")),fabs(dsetdestination->get(i)->getRealValue("roosigma")),dsetdestination->store()->weight(i));
  }

  hnum->Scale(1.0/hnum->Integral());
  hden->Scale(1.0/hden->Integral());
//data/MC
  hnum->Divide(hden);
  TH2F *h = hnum;

  RooDataSet *newdset = new RooDataSet(**dset,Form("%s_rhosigmarew",(*dset)->GetName()));
  newdset->reset();
  for (int i=0; i<(*dset)->numEntries(); i++){
    RooArgSet args = *((*dset)->get(i));
    float oldw = (*dset)->store()->weight(i);
    float rho = args.getRealValue("roorho");
    float sigma = args.getRealValue("roosigma");
    float neww = oldw*h->GetBinContent(h->FindBin(rho,sigma));
	if(debug){
		weight_rho->Fill(neww);
		weight_rhoo->Fill(oldw);
		weight_rho2o->Fill(h->GetXaxis()->FindBin(rho),oldw);	
		weight_rhon->Fill(h->GetXaxis()->FindBin(rho),neww);	
		if(oldw!=0)weight_rhonr->Fill(h->GetXaxis()->FindBin(rho),oldw/neww);
		else {weight_rhonr->Fill(-10,1);}//cout << "dipho weight old 0" << endl;}
		if(oldw!=0)weight_rho2->Fill(rho,oldw/neww);
		weight_sigma2o->Fill(h->GetYaxis()->FindBin(sigma),oldw);	
		weight_sigman->Fill(h->GetYaxis()->FindBin(sigma),neww);	
		if(oldw!=0)weight_sigmanr->Fill(h->GetYaxis()->FindBin(sigma),oldw/neww);
		else {weight_sigmanr->Fill(-10,1);}//cout << "dipho weight old 0" << endl;}
		if(oldw!=0)weight_sigma2->Fill(sigma,oldw/neww);
	}
		newdset->add(args,neww);
	  }
	  newdset->SetName((*dset)->GetName());
	  newdset->SetTitle((*dset)->GetTitle());
	  delete hnum; delete hden;
	  RooDataSet *old_dset = *dset;
	  *dset=newdset;
	  std::cout << "RhoSigma2D rew: norm from " << old_dset->sumEntries() << " to " << newdset->sumEntries() << std::endl;
	  if (deleteold) delete old_dset;
	};
Exemple #4
0
TH2F *plotEff2D(RooDataSet *a, TString b) {
    const RooArgSet *set = a->get();
    RooRealVar *yAx = (RooRealVar*)set->find("pt");
    RooRealVar *xAx = (RooRealVar*)set->find("eta");
    RooRealVar *eff = (RooRealVar*)set->find("efficiency");

//    const int xnbins = xAx->getBinning().numBins();
//    const int ynbins = yAx->getBinning().numBins();

    //double xbins[] = {-2.4, -1.6, -0.8, 0.0, 0.8, 1.6, 2.4};
    //double ybins[] = {0, 2, 3, 5, 8, 10, 20};

    const double *xvbins = xAx->getBinning().array();
    const double *yvbins = yAx->getBinning().array();

    TH2F* h = new TH2F(b, "", xAx->getBinning().numBins(), xvbins, yAx->getBinning().numBins(), yvbins);

    gStyle->SetPaintTextFormat("5.2f");
    gStyle->SetPadRightMargin(0.12);
    gStyle->SetPalette(1);
    h->SetOption("colztexte");
    h->GetZaxis()->SetRangeUser(-0.001,1.001);
    h->SetStats(kFALSE);
    h->GetYaxis()->SetTitle("p_{T} [GeV/c]");
    h->GetXaxis()->SetTitle("#eta");
    h->GetXaxis()->CenterTitle();
    h->GetYaxis()->CenterTitle();
    h->GetXaxis()->SetTitleSize(0.05);
    h->GetYaxis()->SetTitleSize(0.05);
    h->GetYaxis()->SetTitleOffset(0.8);
    h->GetXaxis()->SetTitleOffset(0.9);
    for(int i=0; i<a->numEntries(); i++) {
        a->get(i);
        h->SetBinContent(h->FindBin(xAx->getVal(), yAx->getVal()), eff->getVal());
        h->SetBinError(h->FindBin(xAx->getVal(), yAx->getVal()), (eff->getErrorHi()-eff->getErrorLo())/2.);
    }

    return h;

}
Exemple #5
0
void Plotcolz(){
  if(StopMass.size() == 0) GetAllMasses();
	TCanvas *c1 = new TCanvas("c1","c1",600,400);
	TH2F* hist = new TH2F("hist", "nEvents for the different mass points", 40, 12.5, 1000+12.5, 24, -12.5, 600-12.5);
	for(int k = 0; k < StopMass.size(); k++){
		hist->SetBinContent(hist->FindBin(StopMass[k], NeutralinoMass[k]), Events[k]);
	}
	hist -> SetStats(0);
  hist->GetXaxis()->SetTitle("Stop Mass [GeV]");
  hist->GetYaxis()->SetTitle("Neutralino Mass [GeV]");
  hist->GetXaxis()->SetNdivisions(40308);
  hist->GetYaxis()->SetNdivisions(40306);
  c1->SetGrid();
	hist->Draw("colz");
  c1 -> Print(outputdir + "MassPointsEvents.pdf", "pdf");
  c1 -> Print(outputdir + "MassPointsEvents.png", "png");

}
void Analyzer::Loop(TChain *t,int type){ //type|=4 : compute lmin,lmax; type|=1 data type |=2 mc

		
		treeVarInt["nvtx"] = -999; t->SetBranchAddress("nvtx",&treeVarInt["nvtx"]);
		treeVar["rho"] = -999; t->SetBranchAddress("rho",&treeVar["rho"]);
		Float_t jetPt[4]; t->SetBranchAddress("jetPt",&jetPt);
		Float_t jetEnergy[4]; t->SetBranchAddress("jetEnergy",&jetEnergy);
		Float_t jetBtag[4]; t->SetBranchAddress("jetBtag",&jetBtag);
		Float_t jetBeta[4]; t->SetBranchAddress("jetBeta",&jetBeta);
		Float_t jetEta[4]; t->SetBranchAddress("jetEta",&jetEta);
		Float_t jetPhi[4]; t->SetBranchAddress("jetPhi",&jetPhi);
		Float_t jetAxis_QC[2][4]; t->SetBranchAddress("jetAxis_QC",&jetAxis_QC);
		Float_t jetAxis[2][4]; t->SetBranchAddress("jetAxis",&jetAxis);
		Float_t jetPtD[4]; t->SetBranchAddress("jetPtD",&jetPtD);
		Float_t jetPtD_QC[4]; t->SetBranchAddress("jetPtD_QC",&jetPtD_QC);
		Int_t jetChgPart_ptcut[4]; t->SetBranchAddress("jetChgPart_ptcut",&jetChgPart_ptcut);
		Int_t jetChgPart_QC[4]; t->SetBranchAddress("jetChgPart_QC",&jetChgPart_QC);
		Int_t jetNeutralPart_ptcut[4]; t->SetBranchAddress("jetNeutralPart_ptcut",&jetNeutralPart_ptcut);
		vector<int> *partonId=0;if(type >1)t->SetBranchAddress("partonId",&partonId);
		vector<int> *partonSt=0;if(type >1)t->SetBranchAddress("partonSt",&partonSt);
		vector<float> *partonPt=0;if(type >1)t->SetBranchAddress("partonPt",&partonPt);
		vector<float> *partonEta=0;if(type >1)t->SetBranchAddress("partonEta",&partonEta);
		vector<float> *partonPhi=0;if(type >1)t->SetBranchAddress("partonPhi",&partonPhi);
		vector<float> *partonE=0;if(type >1)t->SetBranchAddress("partonE",&partonE);
		
		vector<bool> *triggerResult=0;if(type ==1)t->SetBranchAddress("triggerResult",&triggerResult);
		
		
		if(type&4) {lmin=1.0;lmax=0;} //reset lmin-lmax
		if(type&1) {delete h_data; CreateHisto(1);}
		if(type&10) {delete h_mc; CreateHisto(2);} //8+2
		if(type&32) {varAll.clear();} //reset varAll

		for(int i=0;i<t->GetEntries() ;i++)
			{
			t->GetEntry(i);
			treeVar["ptJet0"]=jetPt[0];
			treeVar["etaJet0"]=jetEta[0];
			treeVar["rhoPF"]=treeVar["rho"];
			
			//fprintf(stderr,"A: Pt: %f<%f<%f - Eta: %f<%f<%f: Rho: %f<%f<%f\n",PtMin,treeVar["ptJet0"],PtMax,EtaMin,treeVar["etaJet0"],EtaMax,RhoMin,treeVar["rhoPF"],RhoMax);
			if((treeVar["ptJet0"]<PtMin)||(treeVar["ptJet0"]>PtMax)||(fabs(treeVar["etaJet0"])<EtaMin)||(fabs(treeVar["etaJet0"])>EtaMax)|| (treeVar["rhoPF"]<RhoMin)||(treeVar["rhoPF"]>RhoMax))continue;
			//fprintf(stderr,"-B\n");
			//selection
			double muJet_dphi=deltaPhi(jetPhi[0],jetPhi[1]);
			if(fabs(muJet_dphi)<2.5) continue;
			//fprintf(stderr,"--C\n");
			if( ! (2.0 *jetPt[2]/ (jetPt[0]+jetPt[1])<.3) )continue; 
			//fprintf(stderr,"---D\n");
			if( jetBtag[0] >0.244)continue;
			//fprintf(stderr,"----E\n");
			//trigger --only on data
			if( type==1 && !( triggerResult != NULL && triggerResult->size()>1 && triggerResult->at(1) )) continue;
			
			//parton Matching
			double dR_min=999;
			int pos_min=999;
			//int part_min=5;
			
			//fprintf(stderr,"_______not NULL: %ld = %ld = %ld\n",partonPt,partonEta,partonPhi);
			if(type>1){ //only on MC
			for(int iPart=0;iPart<partonPt->size();iPart++)
				{
				double dR_ipart= deltaR(partonEta->at(iPart),partonPhi->at(iPart),jetEta[0],jetPhi[0]);
				if(dR_ipart< dR_min){dR_min=dR_ipart;pos_min=iPart;}
				}
			}
			if(dR_min<.3){
				//fprintf(stderr,"_______%f<%f\n",pos_min,partonId->size());
				treeVarInt["pdgIdPartJet0"]=partonId->at(pos_min);
				} else treeVarInt["pdgIdPartJet0"]=0;
			
			//fprintf(stderr,"_______E2:pos_min=%d dR=%f\n",pos_min,dR_min);
			map<TString,float> variables_MLP;	
			map<TString,float> variables_corr_MLP;	
			//map<TString,float> variables_QGL;	
			
//			variables_QGL["axis1"]= jetAxis_QC[0][0];
//			variables_QGL["axis2"]= jetAxis_QC[1][0];
//			variables_QGL["ptd"] = jetPtD_QC[0];
//			variables_QGL["mult"] = jetChgPart_QC[0]+jetNeutralPart_ptcut[0];
//			variables_QGL["pt"] = jetPt[0];
//			variables_QGL["eta"] = jetEta[0];
//			variables_QGL["rho"] = rho;
	
			//fprintf(stderr,"_______E3:nvtx: %d\n",treeVarInt["nvtx"]);
			if(fabs(jetEta[0])<2.5 && (jetBeta[0]<(1.0 -0.2*TMath::Log(treeVarInt["nvtx"]-0.67)))) continue;	
			//fprintf(stderr,"-----F\n");
			float sub_data=0.0;
			if(fabs(jetEta[0])>2.5 && type==1)sub_data=1.0;
			//Variables as general variables
			treeVar["mult"]=float(jetChgPart_QC[0]+jetNeutralPart_ptcut[0])-sub_data;
			treeVar["axis1"]=jetAxis_QC[0][0];
			treeVar["axis2"]=jetAxis_QC[1][0];
			treeVar["ptD"]=jetPtD_QC[0];
			//Discriminators - only if needed -  save time
			if(varName=="QGLHisto")treeVar["QGLHisto"] = qgl->computeQGLikelihood2012(jetPt[0],jetEta[0],treeVar["rho"],jetChgPart_QC[0]+jetNeutralPart_ptcut[0]-sub_data,jetPtD_QC[0],jetAxis_QC[1][0]);
			if(varName=="QGLMLP"){	
				variables_MLP["axis1"]=jetAxis_QC[0][0];
				variables_MLP["axis2"]=jetAxis_QC[1][0];
				variables_MLP["ptD"]=jetPtD_QC[0];
				variables_MLP["mult"]=jetChgPart_QC[0];
				
				variables_MLP["pt"]=jetPt[0];
				variables_MLP["eta"]=jetEta[0];
				variables_MLP["rho"]=treeVar["rho"];
				
				if(fabs(jetEta[0])>2.5){
					variables_MLP["axis1"]=jetAxis[0][0];
					variables_MLP["axis2"]=jetAxis[1][0];
					variables_MLP["ptD"]=jetPtD[0];
					variables_MLP["mult"]=jetChgPart_QC[0]+jetNeutralPart_ptcut[0]-sub_data;
					
					}
				
				variables_corr_MLP["axis1"] = variables_MLP["axis1"];
				variables_corr_MLP["axis2"] = variables_MLP["axis2"];
				variables_corr_MLP["ptD"] = variables_MLP["ptD"];
				variables_corr_MLP["mult"] = variables_MLP["mult"];
			
				//variables_corr_MLP=qgmlp->TEST(variables_MLP,variables_corr_MLP);
				
				treeVar["QGLMLP"]=qgmlp->QGvalue(variables_MLP);
			}
			//treeVar["pdgIdPartJet0"];
			//---------------------------
		
			//fprintf(stderr,"------G\n");
			if(type&1){
				//printf("passed selection - type 1 --> %.3f - %.3f\n",treeVar[varName],treeVar[varName+"Fwd"]);
				string var=varName;
			//	if(EtaMin>2.5)var+="Fwd"; //only in data fwd
				alpha=1; beta=0;
					//int bin=puw->FindBin(treeVar["rho"]);
					//int bin2=ptetaw->FindBin(jetPt[0],fabs(jetEta[0]) );
					//float weight=puw->GetBinContent(bin) *  ptetaw->GetBinContent(bin2);
					treeVar["eventWeight"]=1.; //data
					treeVar["PUReWeight"]=1;
				FillHisto(h_data,var);
				}	
			if(type&2){
				//mc
			//fprintf(stderr,"________notNull:%ld %ld %f\n",puw,ptetaw,treeVar["rho"]);
					int bin = puw->FindBin(treeVar["rho"]);
					int bin2 = ptetaw->FindBin(jetPt[0],fabs(jetEta[0]) );
					float weight=puw->GetBinContent(bin) *  ptetaw->GetBinContent(bin2);
			//fprintf(stderr,"________bin:%d,%d, w=%f\n",bin,bin2,weight);
					treeVar["eventWeight"]=weight;treeVar["PUReWeight"]=1;
				FillHisto(h_mc,varName);
				}
			if(type&4){
				string var=varName;
				if(lmin>treeVar[var]) lmin=treeVar[var];
				if(lmax<treeVar[var]) lmax=treeVar[var];
				}
			if(type&8){
				alpha=1;beta=0;
				if( treeVarInt["pdgIdPartJet0"] ==21) {alpha=a_g;beta=b_g;}
				if( fabs(treeVarInt["pdgIdPartJet0"]) < 5) {alpha=a_q;beta=b_q;}
				if( fabs(treeVarInt["pdgIdPartJet0"])== 0) {alpha=1;beta=0;}

				FillHisto(h_mc,varName);
				}
			if(type&16){
				for(int j=0;j<int(alphaFast.size());j++)
					{
					alpha=alphaFast[j];
					beta=betaFast[j];
					FillHisto(h_mcFast[j],varName);
					}
				}
			if(type&32){ 
					int bin=puw->FindBin(treeVar["rho"]);
					int bin2=ptetaw->FindBin(jetPt[0],fabs(jetEta[0]) );
					float weight=puw->GetBinContent(bin) *  ptetaw->GetBinContent(bin2);
					varAll.push_back(TRIO(treeVarInt["pdgIdPartJet0"],treeVar[varName],weight)); //w=-1 default
				}
			}
}
Exemple #7
0
void IsovsPt(){


  TFile *f1 = new TFile("../../CutTMVATrees_Barrel.root");
 
  float ppt,peta,Sie_ie,iso_P,iso_C,iso_N,to_e,weight;
  int nvtx;

  gStyle->SetOptStat(0);



  //Signal Tree
  t_S->SetBranchAddress("Sieie",&Sie_ie);
  t_S->SetBranchAddress("isoP",&iso_P);
  t_S->SetBranchAddress("isoC",&iso_C);
  t_S->SetBranchAddress("isoN",&iso_N);
  t_S->SetBranchAddress("ToE",&to_e);
  t_S->SetBranchAddress("weighT",&weight);
  t_S->SetBranchAddress("Nvtx",&nvtx);
  t_S->SetBranchAddress("Peta",&peta);
  t_S->SetBranchAddress("Ppt",&ppt);

  //Background Tree
  t_B->SetBranchAddress("Sieie",&Sie_ie);
  t_B->SetBranchAddress("isoP",&iso_P);
  t_B->SetBranchAddress("isoC",&iso_C);
  t_B->SetBranchAddress("isoN",&iso_N);
  t_B->SetBranchAddress("ToE",&to_e);
  t_B->SetBranchAddress("weighT",&weight);
  t_B->SetBranchAddress("Nvtx",&nvtx);
  t_B->SetBranchAddress("Peta",&peta);
  t_B->SetBranchAddress("Ppt",&ppt);



  TH2F *isoCptS = new TH2F("isoCptS","Iso Charge vs Pt",100,0,200,3000,0,30);
  TH2F *isoNptS = new TH2F("isoNptS","Iso Neutral vs Pt",100,0,200,3000,0,30);
  TH2F *isoPptS = new TH2F("isoPptS","Iso Photon vs Pt",100,0,200,3000,0,30);




  for(int i  = 0; i < t_S->GetEntries();i++){

    t_S->GetEntry(i);

 
    isoCptS->Fill(ppt,iso_C);
 
    if(to_e < 0.05){
      
      isoNptS->Fill(ppt,iso_N);

    }

    isoPptS->Fill(ppt,iso_P);
  }




  // Now that we have the Iso vs pt histograms lets see the efficiency in pt bins

  double BinCch [100][3000] = {0};
  double BinCph [100][3000] = {0};
  double BinCh  [100][3000] = {0};
 
  double ptX[100] ={0};

  

  cout<<"here"<<endl;

  for(int j  = 0 ; j < 100 ; j++){
  
    double ptx = 200.0*j/100 + 1.0; 
    ptX[j] = ptx; 

    for(int i  = 0; i < 3000 ; i++){
      double isocx = 30.0*i/3000 + 0.005; 
      double isopx = 30.0*i/3000 + 0.005; 
      double isonx = 30.0*i/3000 + 0.005; 
      
      int bin =  isoCptS->FindBin(ptx,isocx);    
      BinCch[j][i] = isoCptS->GetBinContent(bin);

      bin =  isoPptS->FindBin(ptx,isopx);    
      BinCph[j][i] = isoPptS->GetBinContent(bin);

      bin =  isoNptS->FindBin(ptx,isonx);    
      BinCh[j][i] = isoNptS->GetBinContent(bin);

    
    
    }

  } 




  double ch_95[100] = {0};
  double ch_90[100] = {0}; 
  double ch_80[100] = {0}; 
  double ch_70[100] = {0}; 
  
  

  double ph_95[100] = {0};
  double ph_90[100] = {0}; 
  double ph_80[100] = {0}; 
  double ph_70[100] = {0}; 
  
  double ne_95[100] = {0};
  double ne_90[100] = {0}; 
  double ne_80[100] = {0}; 
  double ne_70[100] = {0}; 
  
  double ch_95e[100] = {0};
  double ch_90e[100] = {0}; 
  double ch_80e[100] = {0}; 
  double ch_70e[100] = {0}; 
  
  double ph_95e[100] = {0}; 
  double ph_90e[100] = {0}; 
  double ph_80e[100] = {0}; 
  double ph_70e[100] = {0}; 
  
  double ne_95e[100] = {0};
  double ne_90e[100] = {0}; 
  double ne_80e[100] = {0}; 
  double ne_70e[100] = {0}; 



  
  for(int j = 0 ; j  < 100; j ++){
    
    double totC = 0;
    double totN = 0;
    double totP = 0;
    
    for(int i = 0; i < 3000; i++) totC = totC + BinCch[j][i];
    for(int i = 0; i < 3000; i++) totN = totN + BinCh[j][i]; 
    for(int i = 0; i < 3000; i++) totP = totP + BinCph[j][i]; 

    double entrC = 0;
    double entrP = 0;
    double entrN = 0;
    
    int passc95 = 0; 
    int passc9 = 0;
    int passc8 = 0;
    int passc7 = 0;

    int passp95 = 0; 
    int passp9 = 0;
    int passp8 = 0;
    int passp7 = 0;

    int passn95 = 0; 
    int passn9 = 0;
    int passn8 = 0;
    int passn7 = 0; 

    for(int i  = 0; i < 3000 ; i++){
      
      entrC = entrC + BinCch[j][i];
      entrP = entrP + BinCph[j][i];
      entrN = entrN + BinCh[j][i];

      //------- photon
      if(passp95 == 0 && entrP*1.0/totP  > 0.95){
	
	double num = sqrt(entrP);
	double den = sqrt(totP);

	ph_95e[j] = 0.95*sqrt(pow(num/totP,2) + pow(den/entrP,2) );



	ph_95[j] = i*0.01;
	passp95= 1; 
      }

      


      if(passp9 == 0 && entrP*1.0/totP  > 0.90){
	
	double num = sqrt(entrP);
	double den = sqrt(totP);

	ph_90e[j] = 0.9*sqrt(pow(num/totP,2) + pow(den/entrP,2) );



	ph_90[j] = i*0.01;
	passp9 = 1; 
      }
      if(passp8 == 0 && entrP*1.0/totP  > 0.80){

	
	double num = sqrt(entrP);
	double den = sqrt(totP);

	ph_80e[j] = 0.8*sqrt(pow(num/totP,2) + pow(den/entrP,2) );

	
	ph_80[j] = i*0.01;
	passp8 = 1; 
      }
      if(passp7 == 0 && entrP*1.0/totP  > 0.70){

	
	double num = sqrt(entrP);
	double den = sqrt(totP);

	ph_70e[j] = 0.7*sqrt(pow(num/totP,2) + pow(den/entrP,2) );



	ph_70[j] = i*0.01;
	passp7 = 1; 
      }


      //--------- charge
      if(passc95 == 0 && entrC*1.0/totC  > 0.95){
	
	double num = sqrt(entrC);
	double den = sqrt(totC);

	ch_95e[j] = 0.95*sqrt(pow(num/totC,2) + pow(den/entrC,2) );



	ch_95[j] = i*0.01;
	passc95= 1; 
      }
      

      if(passc9 == 0 && entrC*1.0/totC  > 0.90){

	double num = sqrt(entrC);
	double den = sqrt(totC);

	ch_90e[j] = 0.9*sqrt(pow(num/totC,2) + pow(den/entrC,2) );

	ch_90[j] = i*0.01;
	passc9 = 1; 
      }
      if(passc8 == 0 && entrC*1.0/totC  > 0.80){

	double num = sqrt(entrC);
	double den = sqrt(totC);

	ch_80e[j] = 0.8*sqrt(pow(num/totC,2) + pow(den/entrC,2) );

	ch_80[j] = i*0.01;
	passc8 = 1; 
      }
      if(passc7 == 0 && entrC*1.0/totC  > 0.70){
	
	double num = sqrt(entrC);
	double den = sqrt(totC);

	ch_70e[j] = 0.7*sqrt(pow(num/totC,2) + pow(den/entrC,2) );

	ch_70[j] = i*0.01;
	passc7 = 1; 
      }

      
      //--------- neutral
      if(passn95 == 0 && entrN*1.0/totN  > 0.95){
	
	double num = sqrt(entrN);
	double den = sqrt(totN);

	ne_95e[j] = 0.95*sqrt(pow(num/totN,2) + pow(den/entrN,2) );



	ne_95[j] = i*0.01;
	passn95= 1; 
      }
    






      if(passn9 == 0 && entrN*1.0/totN  > 0.90){

	
	double num = sqrt(entrN);
	double den = sqrt(totN);

	ne_90e[j] = 0.9*sqrt(pow(num/totN,2) + pow(den/entrN,2) );



	ne_90[j] = i*0.01;
	passn9 = 1; 
      }
      if(passn8 == 0 && entrN*1.0/totN  > 0.80){

	
	double num = sqrt(entrN);
	double den = sqrt(totN);

	ne_80e[j] = 0.8*sqrt(pow(num/totN,2) + pow(den/entrN,2) );


	ne_80[j] = i*0.01; 
	passn8 = 1; 
      }
      if(passn7 == 0 && entrN*1.0/totN  > 0.70){

	
	double num = sqrt(entrN);
	double den = sqrt(totN);

	ne_70e[j] = 0.7*sqrt(pow(num/totN,2) + pow(den/entrN,2) );


	ne_70[j] = i*0.01;
	passn7 = 1; 
      }


    }
    
  }
  

  double ptXe[100] = {2};
  
  TGraph *p95 = new TGraphErrors(100,ptX,ph_95,ptXe,ph_95e);
  TGraph *p9 = new TGraphErrors(100,ptX,ph_90,ptXe,ph_90e);
  TGraph *p8 = new TGraphErrors(100,ptX,ph_80,ptXe,ph_80e);
  TGraph *p7 = new TGraphErrors(100,ptX,ph_70,ptXe,ph_70e);

  p95->SetMarkerColor(kMagenta);
  p9->SetMarkerColor(kRed);
  p8->SetMarkerColor(kOrange);
  p7->SetMarkerColor(kYellow);
 

  p95->SetMarkerSize(kMagenta);
  p9->SetMarkerSize(1);
  p8->SetMarkerSize(1);
  p7->SetMarkerSize(1);

  
  p95->SetLineColor(kMagenta);
  p9->SetLineColor(kRed);
  p8->SetLineColor(kOrange);
  p7->SetLineColor(kYellow);






  TGraph *n95 = new TGraphErrors(100,ptX,ne_95,ptXe,ne_95e);
  TGraph *n9 = new TGraphErrors(100,ptX,ne_90,ptXe,ne_90e);
  TGraph *n8 = new TGraphErrors(100,ptX,ne_80,ptXe,ne_80e);
  TGraph *n7 = new TGraphErrors(100,ptX,ne_70,ptXe,ne_70e);

  n95->SetMarkerColor(kMagenta);
  n9->SetMarkerColor(kRed);
  n8->SetMarkerColor(kOrange);
  n7->SetMarkerColor(kYellow);

  n95->SetMarkerSize(kMagenta);
  n9->SetMarkerSize(1);
  n8->SetMarkerSize(1);
  n7->SetMarkerSize(1);

  n95->SetLineColor(kMagenta);
  n9->SetLineColor(kRed);
  n8->SetLineColor(kOrange);
  n7->SetLineColor(kYellow);




  TGraph *c95 = new TGraphErrors(100,ptX,ch_95,ptXe,ch_95e);
  TGraph *c9 = new TGraphErrors(100,ptX,ch_90,ptXe,ch_90e);
  TGraph *c8 = new TGraphErrors(100,ptX,ch_80,ptXe,ch_80e);
  TGraph *c7 = new TGraphErrors(100,ptX,ch_70,ptXe,ch_70e);

  c95->SetMarkerColor(kMagenta); 
  c9->SetMarkerColor(kRed);
  c8->SetMarkerColor(kOrange);
  c7->SetMarkerColor(kYellow);


  c95->SetLineColor(kMagenta); 
  c9->SetLineColor(kRed);
  c8->SetLineColor(kOrange);
  c7->SetLineColor(kYellow);



  c95->SetMarkerSize(1);
  c9->SetMarkerSize(1);
  c8->SetMarkerSize(1);
  c7->SetMarkerSize(1);




  TMultiGraph *PhoIso = new TMultiGraph();
  TMultiGraph *ChgIso = new TMultiGraph();
  TMultiGraph *NeuIso = new TMultiGraph();


  PhoIso->Add(p95,"p");
  PhoIso->Add(p9,"p");
  PhoIso->Add(p7,"p");
  PhoIso->Add(p8,"p");


  ChgIso->Add(c95,"p");
  ChgIso->Add(c9,"p");
  ChgIso->Add(c7,"p");
  ChgIso->Add(c8,"p");

  NeuIso->Add(n95,"p");
  NeuIso->Add(n9,"p");
  NeuIso->Add(n7,"p");
  NeuIso->Add(n8,"p");

  



  TCanvas *c1 = new TCanvas("c1","Iso P vs Pt",1000,500);
  c1->Divide(2,1); 

  c1->cd(1);
  PhoIso->Draw("AP");
  PhoIso->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  PhoIso->GetYaxis()->SetTitle("Isolation PF:gamma");
  

  
  c1->cd(2)->SetLogz();
  
  isoPptS->Draw("colz");  
  isoPptS->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  isoPptS->GetYaxis()->SetTitle("Isolation PF:gamma");

  c1->SaveAs("PhotonIso_95.png");


  TCanvas *c2 = new TCanvas("c2","Iso C vs Pt",1000,500);
  c2->Divide(2,1);
  c2->cd(1);
  ChgIso->Draw("AP");
  ChgIso->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  ChgIso->GetYaxis()->SetTitle("Isolation PF:ch hadrons");
  

  c2->cd(2)->SetLogz();
  
  isoCptS->Draw("colz");  
  isoCptS->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  isoCptS->GetYaxis()->SetTitle("Isolation PF:ch hadrons");


  c2->SaveAs("ChargeIso_95.png");
  
  TCanvas *c3 = new TCanvas("c3","Iso N vs Pt",1000,500);
  c3->Divide(2,1);
  c3->cd(1);
  NeuIso->Draw("AP");
  NeuIso->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  NeuIso->GetYaxis()->SetTitle("Isolation PF:h0");
  

  c3->cd(2)->SetLogz();
  
  isoNptS->Draw("colz");  
  isoNptS->GetXaxis()->SetTitle("Pt GeVc^{-1}");
  isoNptS->GetYaxis()->SetTitle("Isolation PF:h0");


  c3->SaveAs("NeutralIso_95_HoEcut.png");

  c1->Update();
  c2->Update();
  c3->Update();

}
Exemple #8
0
int looperCR2lep( analysis* myAnalysis, sample* mySample, int nEvents = -1, bool fast = true) {

	// Benchmark
	TBenchmark *bmark = new TBenchmark();
	bmark->Start("benchmark");

	// Setup
	TChain *chain = mySample->GetChain();
	TString sampleName = mySample->GetLabel();
	const int nSigRegs = myAnalysis->GetSigRegionsAll().size();
	const int nVariations = mySample->IsData() ? 0 : myAnalysis->GetSystematics(false).size();
	bool isFastsim = mySample->IsSignal();
	cout << "\nSample: " << sampleName.Data() << " (CR2L";
	if(      myContext.GetJesDir() == contextVars::kUp )   cout << ", JES up";
	else if( myContext.GetJesDir() == contextVars::kDown ) cout << ", JES down";
	cout << ")" << endl;

	myContext.SetUseRl( true );

	/////////////////////////////////////////////////////////
	// Histograms
	TDirectory *rootdir = gDirectory->GetDirectory("Rint:");  // Use TDirectories to assist in memory management
	TDirectory *histdir = new TDirectory( "histdir", "histdir", "", rootdir );
	TDirectory *systdir = new TDirectory( "systdir", "systdir", "", rootdir );
	TDirectory *zerodir = new TDirectory( "zerodir", "zerodir", "", rootdir );

	TH1::SetDefaultSumw2();

	TH1D* h_bkgtype_sum[nSigRegs][nVariations+1];
	TH1D* h_evttype_sum[nSigRegs][nVariations+1];
	TH2D* h_sigyields[nSigRegs][nVariations+1];

	TH1D* h_bkgtype[nSigRegs][nVariations+1]; // per-file versions for zeroing
	TH1D* h_evttype[nSigRegs][nVariations+1];

	TH1D *h_mt[nSigRegs];
	TH1D *h_met[nSigRegs];
	TH1D *h_mt2w[nSigRegs];
	TH1D *h_chi2[nSigRegs];
	TH1D *h_htratio[nSigRegs];
	TH1D *h_mindphi[nSigRegs];
	TH1D *h_ptb1[nSigRegs];
	TH1D *h_drlb1[nSigRegs];
	TH1D *h_ptlep[nSigRegs];
	TH1D *h_metht[nSigRegs];
	TH1D *h_dphilw[nSigRegs];
	TH1D *h_njets[nSigRegs];
	TH1D *h_nbtags[nSigRegs];
	TH1D *h_ptj1[nSigRegs];
	TH1D *h_j1btag[nSigRegs];
	TH1D *h_modtop[nSigRegs];
	TH1D *h_dphilmet[nSigRegs];
	TH1D *h_mlb[nSigRegs];

	vector<TString> regNames = myAnalysis->GetSigRegionLabelsAll();
	vector<sigRegion*> sigRegions = myAnalysis->GetSigRegionsAll();
	vector<systematic*> variations = myAnalysis->GetSystematics(false);

	for( int i=0; i<nSigRegs; i++ ) {

		TString plotLabel = sampleName + "_" + regNames.at(i);
		systdir->cd();

		for( int j=1; j<=nVariations; j++ ) {
			TString varName = variations.at(j-1)->GetNameLong();
			h_bkgtype_sum[i][j] = new TH1D( "bkgtype_" + plotLabel + "_" + varName, "Yield by background type",  5, 0.5, 5.5);
			h_evttype_sum[i][j] = new TH1D( "evttype_" + regNames.at(i) + "_" + varName, "Yield by event type",  6, 0.5, 6.5);
			h_sigyields[i][j] = new TH2D( "sigyields_" + regNames.at(i) + "_" + varName, "Signal yields by mass point", 37,99,1024, 19,-1,474 );
		}

		histdir->cd();

		h_bkgtype_sum[i][0] = new TH1D( "bkgtype_" + plotLabel, "Yield by background type",  5, 0.5, 5.5);
		h_evttype_sum[i][0] = new TH1D( "evttype_" + regNames.at(i), "Yield by event type",  6, 0.5, 6.5);
		h_sigyields[i][0] = new TH2D( "sigyields_" + regNames.at(i), "Signal yields by mass point", 37,99,1024, 19,-1,474 );

		h_mt[i]       = new TH1D(  "mt_"      + plotLabel, "Transverse mass",          80, 0, 800);
		h_met[i]      = new TH1D(  "met_"     + plotLabel, "MET",                      40, 0, 1000);
		h_mt2w[i]     = new TH1D(  "mt2w_"    + plotLabel, "MT2W",                     50, 0, 500);
		h_chi2[i]     = new TH1D(  "chi2_"    + plotLabel, "Hadronic #chi^{2}",        50, 0, 15);
		h_htratio[i]  = new TH1D(  "htratio_" + plotLabel, "H_{T} ratio",              50, 0, 1);
		h_mindphi[i]  = new TH1D(  "mindphi_" + plotLabel, "min #Delta#phi(j12,MET)",  63, 0, 3.15);
		h_ptb1[i]     = new TH1D(  "ptb1_"    + plotLabel, "p_{T} (b1)",               50, 0, 500);
		h_drlb1[i]    = new TH1D(  "drlb1_"   + plotLabel, "#DeltaR (lep, b1)",        50, 0, 5);
		h_ptlep[i]    = new TH1D(  "ptlep_"   + plotLabel, "p_{T} (lep)",              50, 0, 500);
		h_metht[i]    = new TH1D(  "metht_"   + plotLabel, "MET/sqrt(HT)",             50, 0, 100);
		h_dphilw[i]   = new TH1D(  "dphilw_"  + plotLabel, "#Delta#phi (lep,W)",       63, 0, 3.15);
		h_njets[i]    = new TH1D(  "njets_"   + plotLabel, "Number of jets",           16, -0.5, 15.5);
		h_nbtags[i]   = new TH1D(  "nbtags_"  + plotLabel, "Number of b-tags",          7, -0.5, 6.5);
		h_ptj1[i]     = new TH1D(  "ptj1_"    + plotLabel, "Leading jet p_{T}",        40, 0, 1000);
		h_j1btag[i]   = new TH1D(  "j1btag_"  + plotLabel, "Is leading jet b-tagged?",  2, -0.5, 1.5);
		h_modtop[i]   = new TH1D(  "modtop_"  + plotLabel, "Modified topness",         30, -15., 15.);
		h_dphilmet[i] = new TH1D(  "dphilmet_"+ plotLabel, "#Delta#phi (lep1, MET)",   63, 0., 3.15);
		h_mlb[i]      = new TH1D(  "mlb_"     + plotLabel, "M_{lb}",                   50, 0., 500.);


		for( int j=0; j<=nVariations; j++ ) {

			TAxis* axis = h_bkgtype_sum[i][j]->GetXaxis();
			axis->SetBinLabel( 1, "2+lep" );
			axis->SetBinLabel( 2, "1lepW" );
			axis->SetBinLabel( 3, "1lepTop" );
			axis->SetBinLabel( 4, "ZtoNuNu" );
			axis->SetBinLabel( 5, "Other" );

			axis = h_evttype_sum[i][j]->GetXaxis();
			axis->SetBinLabel( 1, "Data" );
			axis->SetBinLabel( 2, "Signals" );
			axis->SetBinLabel( 3, "2+lep" );
			axis->SetBinLabel( 4, "1lepW" );
			axis->SetBinLabel( 5, "1lepTop" );
			axis->SetBinLabel( 6, "ZtoNuNu" );
		}

	}

	TH1D *h_yields_sum = new TH1D( Form("srYields_%s", sampleName.Data()), "Yield by signal region", nSigRegs, 0.5, float(nSigRegs)+0.5);
	for( int i=0; i<nSigRegs; i++ ) h_yields_sum->GetXaxis()->SetBinLabel( i+1, regNames.at(i) );

	// Set up copies of histograms, in order to zero out negative yields
	zerodir->cd();
	TH1D* h_yields = (TH1D*)h_yields_sum->Clone( "tmp_" + TString(h_yields_sum->GetName()) );

	for( int i=0; i<nSigRegs; i++ ) {
		for( int j=0; j<=nVariations; j++ ) {
			h_bkgtype[i][j] = (TH1D*)h_bkgtype_sum[i][j]->Clone( "tmp_" + TString(h_bkgtype_sum[i][j]->GetName()) );
			h_evttype[i][j] = (TH1D*)h_evttype_sum[i][j]->Clone( "tmp_" + TString(h_evttype_sum[i][j]->GetName()) );
		}
	}

	// Set up cutflow variables
	double yield_total = 0;
	double yield_unique = 0;
	double yield_filter = 0;
	double yield_vtx = 0;
	double yield_1goodlep = 0;
	double yield_lepSel = 0;
	double yield_2lepveto = 0;
	double yield_trkVeto = 0;
	double yield_2lepCR = 0;
	double yield_tauVeto = 0;
	double yield_njets = 0;
	double yield_1bjet = 0;
	double yield_METcut = 0;
	double yield_MTcut = 0;
	double yield_dPhi = 0;
	double yield_chi2 = 0;

	int yGen_total = 0;
	int yGen_unique = 0;
	int yGen_filter = 0;
	int yGen_vtx = 0;
	int yGen_1goodlep = 0;
	int yGen_lepSel = 0;
	int yGen_2lepveto = 0;
	int yGen_trkVeto = 0;
	int yGen_tauVeto = 0;
	int yGen_2lepCR = 0;
	int yGen_njets = 0;
	int yGen_1bjet = 0;
	int yGen_METcut = 0;
	int yGen_MTcut = 0;
	int yGen_dPhi = 0;
	int yGen_chi2 = 0;

	////////////////////////////////////////////////////////////////////
	// Set up data-specific filters

	if( mySample->IsData() ) {
		set_goodrun_file_json( "reference-files/Cert_271036-284044_13TeV_23Sep2016ReReco_Collisions16_JSON.txt" );
		duplicate_removal::clear_list();
	}


	/////////////////////////////////////////////////////////////////////

	// Loop over events to Analyze
	unsigned int nEventsTotal = 0;
	unsigned int nEventsChain = chain->GetEntries();
	if( nEvents >= 0 ) nEventsChain = nEvents;
	TObjArray *listOfFiles = chain->GetListOfFiles();
	TIter fileIter(listOfFiles);
	TFile *currentFile = 0;

	// File Loop
	while ( (currentFile = (TFile*)fileIter.Next()) ) {

		// Get File Content
		TFile file( currentFile->GetTitle() );
		TString filename = file.GetName();
		TTree *tree = (TTree*)file.Get("t");
		if(fast) TTreeCache::SetLearnEntries(10);
		if(fast) tree->SetCacheSize(128*1024*1024);
		cms3.Init(tree);

		// Load event weight histograms
		TH2F* hNEvts = (TH2F*)file.Get("histNEvts");
		TH3D* hCounterSMS = (TH3D*)file.Get("h_counterSMS");
		TH1D* hCounter = (TH1D*)file.Get("h_counter");
		myHelper.Setup( isFastsim, hCounter, hNEvts, hCounterSMS );

		// Reset zeroing histograms
		for( int i=0; i<nSigRegs; i++ ) {
			for( int j=0; j<=nVariations; j++ ) {
				h_bkgtype[i][j]->Reset();
				h_evttype[i][j]->Reset();
			}
		}
		h_yields->Reset();

		// Loop over Events in current file
		if( nEventsTotal >= nEventsChain ) continue;
		unsigned int nEventsTree = tree->GetEntriesFast();
		for( unsigned int event = 0; event < nEventsTree; ++event) {

			// Get Event Content
			if( nEventsTotal >= nEventsChain ) continue;
			if(fast) tree->LoadTree(event);
			cms3.GetEntry(event);
			++nEventsTotal;

			// Progress
			CMS3::progress( nEventsTotal, nEventsChain );

			////////////////////////////////////////////////////////////////////////////////////////////////////////
			// Analysis Code
			// ---------------------------------------------------------------------------------------------------//


			///////////////////////////////////////////////////////////////
			// Special filters to more finely categorize background events
			if(      sampleName == "tt2l"  && gen_nfromtleps_() != 2 ) continue;  //Require 2 leps from top in "tt2l" events
			else if( sampleName == "tt1l"  && gen_nfromtleps_() != 1 ) continue;  //Require 1 lep from top in "tt1l" events

			// Stitch W+NJets samples together by removing the MET<200 events from the non-nupT samples
			if( sampleName.Contains("wjets") && filename.Contains("JetsToLNu_madgraph") && nupt()>=200. ) continue;

			//FastSim anomalous event filter
			if( isFastsim && !context::filt_fastsimjets() ) continue;

			if( !mySample->PassSelections() ) continue;


			/////////////////////////////////
			// Set event weight

			double evtWeight = 1.;

			// Data should have a weight of 1.0
			if( is_data() || mySample->IsData() ) evtWeight = 1.;
			else {

				// Weight background MC using scale1fb
				evtWeight = myAnalysis->GetLumi() * scale1fb();

				// Weight signal MC using xsec and nEvents
				if( mySample->IsSignal() ) {
					myHelper.PrepSignal();
					double nEvtsSample = hNEvts->GetBinContent( hNEvts->FindBin( mass_stop(), mass_lsp() ) );
					evtWeight = myAnalysis->GetLumi() * 1000. * xsec() / nEvtsSample;
				}

				// Apply scale factors to correct the shape of the MC
				evtWeight *= myHelper.TrigEff2l();
				evtWeight *= myHelper.LepSF();
				evtWeight *= myHelper.BtagSF();
				if(  isFastsim ) evtWeight *= myHelper.LepSFfastsim();
				if( !isFastsim ) evtWeight *= myHelper.PileupSF();
				if( mySample->GetLabel() == "tt2l" || filename.Contains("W_5f_powheg_pythia8") ) {
					evtWeight *= myHelper.MetResSF();
					// evtWeight *= myHelper.TopSystPtSF();
				}
				else if( mySample->GetLabel() == "tt1l" || mySample->GetLabel() == "wjets" ) evtWeight *= myHelper.MetResSF();
				if( mySample->GetLabel() == "tt2l" || mySample->GetLabel() == "tt1l" || mySample->IsSignal() ) evtWeight *= myHelper.ISRnJetsSF();

				// Correct event weight when samples are merged together
				if(      filename.Contains("ttbar_diLept_madgraph_pythia8_ext1_25ns") ) evtWeight *= 23198554./(23198554.+5689986.);
				else if( filename.Contains("ttbar_diLept_madgraph_pythia8_25ns") ) evtWeight *= 5689986./(23198554.+5689986.);
				else if( filename.Contains("t_tW_5f_powheg_pythia8_noHadDecays_25ns") ) evtWeight *= 4473156./(4473156.+3145334.);
				else if( filename.Contains("t_tW_5f_powheg_pythia8_noHadDecays_ext1_25ns") ) evtWeight *= 3145334./(4473156.+3145334.);
				else if( filename.Contains("t_tbarW_5f_powheg_pythia8_noHadDecays_25ns") ) evtWeight *= 5029568./(5029568.+3146940.);
				else if( filename.Contains("t_tbarW_5f_powheg_pythia8_noHadDecays_ext1_25ns") ) evtWeight *= 3146940./(5029568.+3146940.);
			}

			// Count the number of events processed
			yield_total += evtWeight;
			yGen_total++;

			// Remove duplicate events in data
			if( is_data() ) {
				duplicate_removal::DorkyEventIdentifier id( run(), evt(), ls() );
				if( is_duplicate(id) ) continue;
				yield_unique += evtWeight;
				yGen_unique++;
			}

			// MET filters, bad event filters, and triggers for data
			if( is_data() ) {
				if( !goodrun( run(), ls() ) ) continue;
				if( !filt_met() ) continue;
				if( !filt_badChargedCandidateFilter() ) continue;
				if( !filt_badMuonFilter() ) continue;
				if( !context::filt_jetWithBadMuon() ) continue;
				if( !filt_pfovercalomet() ) continue;
				if( !HLT_MET() && !HLT_MET110_MHT110() && !HLT_MET120_MHT120() ) {
					if( !(HLT_SingleEl() && (abs(lep1_pdgid())==11 || abs(lep2_pdgid())==11) ) &&
					    !(HLT_SingleMu() && (abs(lep1_pdgid())==13 || abs(lep2_pdgid())==13) ) ) continue;
				}
				yield_filter += evtWeight;
				yGen_filter++;
			}

			// First vertex must be good
			if( nvtxs() < 1 ) continue;
			yield_vtx += evtWeight;
			yGen_vtx++;

			// Must have at least 1 good lepton
			if( ngoodleps() < 1 ) continue;
			yield_1goodlep += evtWeight;
			yGen_1goodlep++;

			// Lep 1 must pass lepton selections
			// if( abs(lep1_pdgid())==11 ) {
			// 	if( lep1_p4().pt() < 20. ) continue;
			// 	if( fabs(lep1_p4().eta()) > 1.4442 ) continue;
			// 	if( !lep1_passMediumID() ) continue;
			// }
			// else if( abs(lep1_pdgid())==13 ) {
			// 	if( lep1_p4().pt() < 20. ) continue;
			// 	if( fabs(lep1_p4().eta()) > 2.4 ) continue;
			// 	if( !lep1_passTightID() ) continue;
			// }
			yield_lepSel += evtWeight;
			yGen_lepSel++;


			///////////////////
			// Make 2-lepton CR

			int countGoodLeps = 0;

			// Count the number of veto leptons
			if( nvetoleps() >= 2 && lep2_p4().pt() > 10. ) countGoodLeps += nvetoleps();

			if( countGoodLeps > 1 ) {
				yield_2lepveto += evtWeight;
				yGen_2lepveto++;
			}

			// If we fail the track veto, count another good lepton
			// if( !PassTrackVeto() ) {
			// 	countGoodLeps++;
			// 	yield_trkVeto += evtWeight;
			// 	yGen_trkVeto++;
			// }

			// If we fail the tau veto, count another good lepton
			// if( !PassTauVeto() ) {
			// 	countGoodLeps++;
			// 	yield_tauVeto += evtWeight;
			// 	yGen_tauVeto++;
			// }

			if( countGoodLeps < 2 ) continue;
			yield_2lepCR += evtWeight;
			yGen_2lepCR++;


			////////////////////
			////////////////////

			// N-jet requirement
			if( context::ngoodjets() < 2 ) continue;
			yield_njets += evtWeight;
			yGen_njets++;

			j1pt = context::ak4pfjets_p4().at(0).pt();

			// B-tag requirement
			if( context::ngoodbtags() < 1 ) continue;
			yield_1bjet += evtWeight;
			yGen_1bjet++;

			j1_isBtag = context::ak4pfjets_passMEDbtag().at(0);

			// Baseline MET cut (with 2nd lepton pT added to MET)
			if( context::Met() < 250. ) continue;
			yield_METcut += evtWeight;
			yGen_METcut++;

			// MT cut (with 2nd lepton pT added to MET)
			if( context::MT_met_lep() < 150. ) continue;
			yield_MTcut += evtWeight;
			yGen_MTcut++;

			// Min delta-phi between MET and j1/j2 (with 2nd lepton pT added to MET)
			if( context::Mindphi_met_j1_j2() < 0.5 ) continue;
			yield_dPhi += evtWeight;
			yGen_dPhi++;

			// Chi^2 cut
			// if( hadronic_top_chi2() >= 10. ) continue;
			yield_chi2 += evtWeight;
			yGen_chi2++;


			//////////////////////////////////////////////////////////
			// Classify event based on number of leptons / neutrinos
			// Order of evaluation matters, because some events fall into multiple categories

			int bkgType = -99;
			if( filename.Contains("ZZTo2L2Nu") && isZtoNuNu() ) bkgType = 1; // Force ZZto2L2Nu to be 2lep
			else if( isZtoNuNu() )     bkgType = 4;   // Z to nu nu
			else if( is2lep() )        bkgType = 1;   // 2 or more leptons
			else if( is1lepFromTop() ) bkgType = 3;   // 1 lepton from top quark
			else if( is1lepFromW() )   bkgType = 2;   // 1 lepton from a W not from top
			else                       bkgType = 5;   // Other

			int evtType = -99;
			if(      mySample->IsData()   ) evtType = 1;
			else if( mySample->IsSignal() ) evtType = 2;
			else                            evtType = 2+bkgType;

			// Quickly calculate some variables
			double metSqHT = context::Met() / sqrt( context::ak4_HT() );

			const TVector3 lepVec( lep1_p4().x(), lep1_p4().y(), lep1_p4().z() );
			const TVector3 metVec( context::Met()*cos(context::MetPhi()), context::Met()*sin(context::MetPhi()), 0 );
			const TVector3 wVec = lepVec + metVec;
			double dPhiLepW = fabs( lepVec.DeltaPhi(wVec) );

			double drLepLeadb = ROOT::Math::VectorUtil::DeltaR( lep1_p4(), context::ak4pfjets_leadMEDbjet_p4() );

			lep1pt = lep1_p4().Pt();

			myMlb = context::Mlb_closestb();

			///////////////////////////////////////////
			// Signal region cuts and histo filling

			// If the event passes the SR cuts, store which background type this event is, and fill histograms
			for( int i=0; i<nSigRegs; i++ ) {

				if( !sigRegions.at(i)->PassAllCuts() ) continue;

				// Make some corrections that depend on the signal region
				double fillWeight = evtWeight;
				bool is_corridor = sigRegions.at(i)->GetLabel().Contains("corr");
				myHelper.SetCorridor( is_corridor );
				if(      !is_data() &&  is_corridor ) fillWeight *= sfhelp::MetResCorrectionCorridor();
				else if( !is_data() && !is_corridor ) fillWeight *= sfhelp::BtagCorrectionTight();

				h_bkgtype[i][0]->Fill( bkgType,                            fillWeight );
				h_evttype[i][0]->Fill( evtType,                            fillWeight );
				if( mySample->IsSignal() ) h_sigyields[i][0]->Fill( mass_stop(), mass_lsp(), fillWeight );

				h_mt[i]->Fill(      context::MT_met_lep(),                 fillWeight );
				h_met[i]->Fill(     context::Met(),                        fillWeight );
				h_mt2w[i]->Fill(    context::MT2W(),                       fillWeight );
				h_chi2[i]->Fill(    hadronic_top_chi2(),                   fillWeight );
				h_htratio[i]->Fill( context::ak4_htratiom(),               fillWeight );
				h_mindphi[i]->Fill( context::Mindphi_met_j1_j2(),          fillWeight );
				h_ptb1[i]->Fill( context::ak4pfjets_leadMEDbjet_p4().pt(), fillWeight );
				h_drlb1[i]->Fill(   drLepLeadb,                            fillWeight );
				h_ptlep[i]->Fill(   lep1_p4().pt(),                        fillWeight );
				h_metht[i]->Fill(   metSqHT,                               fillWeight );
				h_dphilw[i]->Fill(  dPhiLepW,                              fillWeight );
				h_njets[i]->Fill(   context::ngoodjets(),                  fillWeight );
				h_nbtags[i]->Fill(  context::ngoodbtags(),                 fillWeight );
				h_ptj1[i]->Fill(    j1pt,                                  fillWeight );
				h_j1btag[i]->Fill(  j1_isBtag,                             fillWeight );
				h_modtop[i]->Fill(  context::TopnessMod(),                 fillWeight );
				h_dphilmet[i]->Fill( context::lep1_dphiMET(),              fillWeight );
				h_mlb[i]->Fill(     myMlb,                                 fillWeight );

				h_yields->Fill(     double(i+1),                           fillWeight );

				// Special systematic variation histograms
				for( int j=1; j<=nVariations; j++ ) {
					h_bkgtype[i][j]->Fill( bkgType,  fillWeight * variations.at(j-1)->GetWeight() );
					h_evttype[i][j]->Fill( evtType,  fillWeight * variations.at(j-1)->GetWeight() );
					if( mySample->IsSignal() ) h_sigyields[i][j]->Fill( mass_stop(), mass_lsp(), fillWeight * variations.at(j-1)->GetWeight() );
				}

			}

			// ---------------------------------------------------------------------------------------------------//
			////////////////////////////////////////////////////////////////////////////////////////////////////////
		} //End of loop over events in file

		// Clean Up
		delete tree;
		file.Close();

		// Zero negative values in each signal region
		for( int i=0; i<nSigRegs; i++ ) {
			for( int j=0; j<=nVariations; j++ ) {
				bool negsFound = false;

				// First zero any decay modes with negative yields
				for( int k=1; k<= h_bkgtype[i][j]->GetNbinsX(); k++ ) {
					if( h_bkgtype[i][j]->GetBinContent(k) < 0.0 ) {
						h_bkgtype[i][j]->SetBinContent(k, 0.);
						h_bkgtype[i][j]->SetBinError(k, 0.);
						negsFound = true;
					}
					if( h_evttype[i][j]->GetBinContent(k+2) < 0.0 ) {
						h_evttype[i][j]->SetBinContent(k+2, 0.);
						h_evttype[i][j]->SetBinError(k+2, 0.);
					}
				}
				// If any negative yields were found in any decay mode, recalculate the total yield
				if( j==0 && negsFound ) {
					double newYield, newErr;
					newYield = h_bkgtype[i][0]->IntegralAndError( 0, -1, newErr );
					h_yields->SetBinContent(i+1, newYield);
					h_yields->SetBinError(i+1, newErr);
				}
				// Add zeroed histograms to total histograms
				h_bkgtype_sum[i][j]->Add( h_bkgtype[i][j] );
				h_evttype_sum[i][j]->Add( h_evttype[i][j] );
			}
		}
		h_yields_sum->Add( h_yields );

	} // End loop over files in the chain

	cout << "Cutflow yields:                        (yield)  (gen evts)" << endl;

	printf("Total number of events:             %10.2f %9i\n",   yield_total    , yGen_total    );
	if( mySample->IsData() ) {
		printf("Events passing duplicate removal:   %10.2f %9i\n", yield_unique   , yGen_unique   );
		printf("Events passing filters and trigger: %10.2f %9i\n", yield_filter   , yGen_filter   );
	}
	printf("Events with 1st vertex good:        %10.2f %9i\n",   yield_vtx      , yGen_vtx      );
	printf("Events with at least 1 good lepton: %10.2f %9i\n",   yield_1goodlep , yGen_1goodlep );
	printf("Events passing lepton selection:    %10.2f %9i\n",   yield_lepSel   , yGen_lepSel   );

	printf("\nEvents passing 2-lep requirement:   %10.2f %9i\n", yield_2lepCR   , yGen_2lepCR   );
	printf("   Events with veto lepton:         %10.2f %9i\n",   yield_2lepveto , yGen_2lepveto );
	printf("   Events with isolated track:      %10.2f %9i\n",   yield_trkVeto  , yGen_trkVeto  );
	printf("   Events with identified tau:      %10.2f %9i\n\n", yield_tauVeto  , yGen_tauVeto  );

	printf("Events with at least 2 jets:        %10.2f %9i\n",   yield_njets    , yGen_njets    );
	printf("Events with at least 1 b-tag:       %10.2f %9i\n",   yield_1bjet    , yGen_1bjet    );
	printf("Events with MET > 250 GeV:          %10.2f %9i\n",   yield_METcut   , yGen_METcut   );
	printf("Events with MT > 150 GeV:           %10.2f %9i\n",   yield_MTcut    , yGen_MTcut    );
	printf("Events with min dPhi > 0.5:         %10.2f %9i\n",   yield_dPhi     , yGen_dPhi     );
	// printf("Events with chi2 < 10:              %10.2f %9i\n",   yield_chi2     , yGen_chi2     );
	printf("Yield after preselection:           %10.2f %9i\n",   yield_chi2     , yGen_chi2     );

	if ( nEventsChain != nEventsTotal ) {
		cout << Form( "ERROR: number of events from files (%d) is not equal to total number of events (%d)", nEventsChain, nEventsTotal ) << endl;
	}


	///////////////////////////////////////////////////////////////////////////////
	// Store histograms and clean them up
	TFile* plotfile = new TFile( myAnalysis->GetPlotFileName(), "READ");
	TFile* systfile = new TFile( myAnalysis->GetSystFileName(), "READ");
	TFile* sourcefile;

	// Certain histograms are cumulative across multiple samples. For those histograms, add what the
	// looper has just collected to the cumulative version stored in our output files
	for( int j=0; j<=nVariations; j++ ) {

		if( j==0 ) sourcefile = plotfile;
		else       sourcefile = systfile;

		for( int i=0; i<nSigRegs; i++ ) {

			// Build up cumulative histo of SUSY scan yields
			TH2D* hTemp2 = (TH2D*)sourcefile->Get( h_sigyields[i][j]->GetName() );
			if( hTemp2 != 0 ) h_sigyields[i][j]->Add( hTemp2 );

			// Build up cumulative histo of yields by signal/background type
			TH1D* hTemp = (TH1D*)sourcefile->Get( h_evttype_sum[i][j]->GetName() );
			if( hTemp != 0 ) h_evttype_sum[i][j]->Add( hTemp );
		}
	}
	delete plotfile;
	delete systfile;

	// Take all histograms in histdir and write them to plotfile
	plotfile = new TFile( myAnalysis->GetPlotFileName(), "UPDATE");
	plotfile->cd();
	histdir->GetList()->Write( "", TObject::kOverwrite );
	delete plotfile;

	// Take all histograms in systdir and write them to systfile
	systfile = new TFile( myAnalysis->GetSystFileName(), "UPDATE");
	systfile->cd();
	systdir->GetList()->Write( "", TObject::kOverwrite );
	delete systfile;

	// Cleanup
	zerodir->Close();
	histdir->Close();
	systdir->Close();

	// return
	bmark->Stop("benchmark");
	cout << endl;
	cout << nEventsTotal << " Events Processed" << endl;
	cout << "------------------------------" << endl;
	cout << "CPU  Time:	" << Form( "%.01f", bmark->GetCpuTime("benchmark")  ) << endl;
	cout << "Real Time:	" << Form( "%.01f", bmark->GetRealTime("benchmark") ) << endl;
	cout << endl;
	delete bmark;
	return 0;
}
int main (int argc, char *argv[])
{

  printBoxedMessage("Starting plot generation");

  // ####################
  // ##   Init tools   ##
  // ####################
 
     string signalCategory = "T2bw-025";

     // Create a sonic Screwdriver
      SonicScrewdriver screwdriver;

  // ##########################
  // ##   Create Variables   ##
  // ##########################

     screwdriver.AddVariable("METoverSqrtHT",  "MET / #sqrt{H_{T}}",      "",       32,0,32,         &(myEvent.METoverSqrtHT),       "");
     screwdriver.AddVariable("MET",            "MET",                     "GeV",    15,50,500,       &(myEvent.MET),                 "logY=true");
     screwdriver.AddVariable("MT",             "MT",                      "GeV",    20,0,400,        &(myEvent.MT),                  "logY=true");
     screwdriver.AddVariable("leadingBPt",     "p_{T}(leading b jet)",    "GeV",    20,0,200,        &(myEvent.leadingBPt),          "logY=true");
     
     screwdriver.AddVariable("mStop",          "m_{#tilde{t}}",           "GeV",    28,112.5,812.5,  &(myEvent.mStop),               "");
     screwdriver.AddVariable("mNeutralino",    "m_{#chi^{0}}",            "GeV",    16,-12.5,387.5,  &(myEvent.mNeutralino),         "noOverflowInLastBin");
     
     // #########################################################
     // ##   Create ProcessClasses (and associated datasets)   ##
     // #########################################################

     screwdriver.AddProcessClass("1ltop",                        "1l top", "background",kRed-7);
         #ifdef USING_TTBAR_POWHEG
             screwdriver.AddDataset("ttbar_powheg",              "1ltop",  0, 0);
         #endif
         #ifdef USING_TTBAR_MADGRAPH
             screwdriver.AddDataset("ttbar_madgraph_1l",         "1ltop",  0, 0);
         #endif
         screwdriver.AddDataset("singleTop_st",                  "1ltop",  0, 0);


     screwdriver.AddProcessClass("ttbar_2l", "t#bar{t} #rightarrow l^{+}l^{-}", "background",kCyan-3);
         #ifdef USING_TTBAR_MADGRAPH
             screwdriver.AddDataset("ttbar_madgraph_2l",   "ttbar_2l",  0, 0);
         #endif

     screwdriver.AddProcessClass("W+jets",         "W+jets",                    "background", kOrange-2);
             screwdriver.AddDataset("W+jets",      "W+jets", 0, 0);
                                                   
     screwdriver.AddProcessClass("rare",           "rare",                      "background", kMagenta-5);
             screwdriver.AddDataset("rare",        "rare", 0, 0);
                                                   
     screwdriver.AddProcessClass(signalCategory,    signalCategory,             "signal",     kViolet-1);
             screwdriver.AddDataset(signalCategory, signalCategory,   0, 0);

     screwdriver.AddProcessClass("signal_250_100",  signalCategory+" (250/100)",      "signal",COLORPLOT_BLUE   );
     screwdriver.AddProcessClass("signal_450_100",  signalCategory+" (450/100)",      "signal",COLORPLOT_GREEN2 ); 
     screwdriver.AddProcessClass("signal_400_175",  signalCategory+" (400/175)",      "signal",COLORPLOT_GREEN2 ); 
     screwdriver.AddProcessClass("signal_650_100",  signalCategory+" (650/100)",      "signal",COLORPLOT_GREEN  );

  // ##########################
  // ##    Create Regions    ##
  // ##########################

     screwdriver.AddRegion("presel",             "Preselection",                          &goesInPreselectionMTtail);
/*
     screwdriver.AddRegion("veryOffShell_loose", "Cut-and-count;Very off-shell (loose)",  &Selector_veryOffShell_loose);
     screwdriver.AddRegion("offShell_loose",     "Cut-and-count;Off-shell (loose)",       &Selector_offShell_loose );
     screwdriver.AddRegion("lowDeltaM_tight",    "Cut-and-count;Low #DeltaM (tight)",     &Selector_lowDeltaM_tight );
     screwdriver.AddRegion("highDeltaM",         "Cut-and-count;High #DeltaM",            &Selector_highDeltaM );
*/
     
     screwdriver.AddRegion("offshell",           "Cut-and-count;Off-shell",              &Selector_offShell);
     screwdriver.AddRegion("lowMasses",          "Cut-and-count;Low masses",             &Selector_lowMasses);
     screwdriver.AddRegion("highMasses",         "Cut-and-count;High masses",            &Selector_highMasses);
     

  // ##########################
  // ##   Create Channels    ##
  // ##########################
      
     screwdriver.AddChannel("singleLepton", "e/#mu-channels",  &goesInSingleLeptonChannel);

  // ########################################
  // ##       Create histograms and        ##
  // ##  schedule type of plots to produce ##
  // ########################################

     screwdriver.SetLumi(20000);

     // Create histograms
     screwdriver.Create1DHistos();
     screwdriver.Add2DHisto("mStop","mNeutralino");

     screwdriver.SetGlobalBoolOption  ("1DSuperimposed",   "includeSignal",                   true   );

     screwdriver.SetGlobalStringOption("1DStack",          "includeSignal",                   "stack");
     screwdriver.SetGlobalFloatOption ("1DStack",          "factorSignal",                    1.0    );

     screwdriver.SetGlobalStringOption("DataMCComparison", "includeSignal",                   "stack");
     screwdriver.SetGlobalFloatOption ("DataMCComparison", "factorSignal",                    1.0    );

     // Schedule plots
     screwdriver.SchedulePlots("1DSuperimposed");
     screwdriver.SchedulePlots("1DStack");
     screwdriver.SchedulePlots("2D");
     screwdriver.SchedulePlots("2DSuperimposed");

     // Config plots

     screwdriver.SetGlobalStringOption("Plot", "infoTopRight", "CMS Internal");
     screwdriver.SetGlobalStringOption("Plot", "infoTopLeft",  "#sqrt{s} = 8 TeV, L = 20 fb^{-1}");

     screwdriver.SetGlobalBoolOption("Plot", "exportPdf", true);
     screwdriver.SetGlobalBoolOption("Plot", "exportEps", false);
     screwdriver.SetGlobalBoolOption("Plot", "exportPng", false);

  // ########################################
  // ##       Run over the datasets        ##
  // ########################################

  vector<string> datasetsList;
  screwdriver.GetDatasetList(&datasetsList);

  cout << "   > Reading datasets... " << endl;
  cout << endl;

  for (unsigned int d = 0 ; d < datasetsList.size() ; d++)
  {
     string currentDataset = datasetsList[d];
     string currentProcessClass = screwdriver.GetProcessClass(currentDataset); 
     // Open the tree
     TFile f((string(FOLDER_BABYTUPLES)+currentDataset+".root").c_str());
     TTree* theTree = (TTree*) f.Get("babyTuple"); 

     intermediatePointers pointers;
     InitializeBranchesForReading(theTree,&myEvent,&pointers);

     sampleName = currentDataset;
     sampleType = screwdriver.GetProcessClassType(currentProcessClass);
    
     if (currentDataset == signalCategory)
     {
         theTree->SetBranchAddress("mStop",       &(myEvent.mStop));
         theTree->SetBranchAddress("mNeutralino", &(myEvent.mNeutralino));
     }
     else
     {
         myEvent.mStop       = -1;
         myEvent.mNeutralino = -1;
     }

  // ########################################
  // ##        Run over the events         ##
  // ########################################

      int nEntries = theTree->GetEntries();
      for (int i = 0 ; i < nEntries ; i++)
      //for (int i = 0 ; i < min(200000, (int) theTree->GetEntries()); i++)
      {
          if (i % (theTree->GetEntries() / 50) == 0) 
              printProgressBar(i,nEntries,currentDataset);

          // Get the i-th entry
          ReadEvent(theTree,i,&pointers,&myEvent);

          // Split 1-lepton ttbar and 2-lepton ttbar
          string currentProcessClass_ = currentProcessClass;
          if ((currentDataset == "ttbar_powheg") && (myEvent.numberOfGenLepton == 2)) 
              currentProcessClass_ = "ttbar_2l";

          screwdriver.AutoFillProcessClass(currentProcessClass_,getWeight());

          if ((myEvent.mStop == 250) && (myEvent.mNeutralino == 100))
              screwdriver.AutoFillProcessClass("signal_250_100",getWeight());
          if ((myEvent.mStop == 450) && (myEvent.mNeutralino == 100))
              screwdriver.AutoFillProcessClass("signal_450_100",getWeight());
          if ((myEvent.mStop == 400) && (myEvent.mNeutralino == 175))
              screwdriver.AutoFillProcessClass("signal_400_175",getWeight());
          if ((myEvent.mStop == 650) && (myEvent.mNeutralino == 100))
              screwdriver.AutoFillProcessClass("signal_650_100",getWeight());
      }

      printProgressBar(nEntries,nEntries,currentDataset);
      cout << endl;
      f.Close();

  }

  // ###################################
  // ##   Make plots and write them   ##
  // ###################################
 
  cout << endl;
  cout << "   > Making plots..." << endl;
  screwdriver.MakePlots();
  cout << "   > Saving plots..." << endl;
  screwdriver.WritePlots("../plots/cutAndCount_performances/"+signalCategory+"/");

  printBoxedMessage("Plot generation completed");

  // #############################
  // ##   Post-plotting tests   ##
  // #############################
  
  printBoxedMessage("Now computing misc tests ... ");
  
  /*
  vector<string> cutAndCountRegions =
  {
      "veryOffShell_loose",
      "offShell_loose",    
      "lowDeltaM_tight",   
      "highDeltaM"     
  };

  float SF_1ltop_and_Wjets = 2;
  float SF_allOthers       = 1.3;

  vector<float> globalBackgroundUncertainty =
  {
      0.2,
      0.2,
      0.2,
      0.4
  };
  */
  
  vector<string> cutAndCountRegions =
  {
    "presel",
    "offshell",
    "lowMasses",
    "highMasses"
  };

  float SF_1ltop_and_Wjets = 2;
  float SF_allOthers       = 1.3;

  vector<float> globalBackgroundUncertainty =
  {
      0.2,
      0.2,
      0.2
  };
  
  TableBackgroundSignal(&screwdriver,cutAndCountRegions,"singleLepton").Print();
  TableBackgroundSignal(&screwdriver,cutAndCountRegions,"singleLepton").PrintLatex();

  // ##########################
  // ##   Compute FOM maps   ##
  // ##########################

  vector<TH2F*> signalMaps;
  vector<TH2F*> FOMdiscoveryMaps;
  vector<TH2F*> FOMexclusionMaps;
  vector<TH2F*> efficiencies;

  int nBinsX = -1;
  int nBinsY = -1;

  TH2F* signalMapPresel  = screwdriver.get2DHistoClone("mStop","mNeutralino",signalCategory,"presel","singleLepton");
  TH2F* backgroundPresel = screwdriver.get2DCompositeHistoClone("mStop","mNeutralino","2DSumBackground","presel","singleLepton","");

  if (nBinsX == -1) nBinsX = signalMapPresel->GetNbinsX();
  if (nBinsY == -1) nBinsY = signalMapPresel->GetNbinsY();

  // Store background eff in (mStop,mLSP) = (200,300)
  int backgroundBin = signalMapPresel->FindBin(200,300);
  float backgroundYieldPresel = backgroundPresel->Integral(0,nBinsX+1,0,nBinsY+1);

  for (unsigned int i = 0 ; i < cutAndCountRegions.size() ; i++)
  {
      signalMaps.push_back(screwdriver.get2DHistoClone("mStop","mNeutralino",signalCategory,cutAndCountRegions[i],"singleLepton"));
      signalMaps[i]->SetName((string("signalMap_")+cutAndCountRegions[i]).c_str());

      float B =   screwdriver.GetYieldAndError("1ltop",    cutAndCountRegions[i],"singleLepton").value()  * SF_1ltop_and_Wjets
                + screwdriver.GetYieldAndError("ttbar_2l", cutAndCountRegions[i],"singleLepton").value()  * SF_allOthers
                + screwdriver.GetYieldAndError("W+jets",   cutAndCountRegions[i],"singleLepton").value()  * SF_1ltop_and_Wjets
                + screwdriver.GetYieldAndError("rare",     cutAndCountRegions[i],"singleLepton").value()  * SF_allOthers;

      // Apply scale factor from background prediction
      float f_B = globalBackgroundUncertainty[i];
      //float f_B = 0.15;

      if (B < 1.0) B = 1.0;
 
      efficiencies.push_back((TH2F*) signalMaps[i]->Clone());
      efficiencies[i]->SetName((string("eff_")+cutAndCountRegions[i]).c_str());
      efficiencies[i]->Divide(signalMapPresel);
      efficiencies[i]->SetBinContent(backgroundBin,B/backgroundYieldPresel);
      
      FOMdiscoveryMaps.push_back((TH2F*) signalMaps[i]->Clone());
      FOMdiscoveryMaps[i]->SetName((string("FOMdisco_")+cutAndCountRegions[i]).c_str());

      FOMexclusionMaps.push_back((TH2F*) signalMaps[i]->Clone());
      FOMexclusionMaps[i]->SetName((string("FOMexclu_")+cutAndCountRegions[i]).c_str());

      for (int x = 1 ; x <= nBinsX ; x++)
      for (int y = 1 ; y <= nBinsY ; y++)
      {
          float S = signalMaps[i]->GetBinContent(x,y);

          float FOMdiscovery = figureOfMerit(S,B,"discovery",false,f_B);
          FOMdiscoveryMaps[i]->SetBinContent(x,y,FOMdiscovery);
          
          float FOMexclusion = figureOfMerit(S,B,"exclusion",false,f_B);
          FOMexclusionMaps[i]->SetBinContent(x,y,FOMexclusion);
      }

  }

  // ################################
  // ##   Compute "best" FOM map   ##
  // ################################

  TH2F* bestDiscoFOMMap = (TH2F*) signalMaps[0]->Clone();  bestDiscoFOMMap->SetName("bestDiscoFOM");
  TH2F* bestDiscoSetMap = (TH2F*) signalMaps[0]->Clone();  bestDiscoSetMap->SetName("bestDiscoSet");
  TH2F* bestDiscoSigEff = (TH2F*) signalMaps[0]->Clone();  bestDiscoSigEff->SetName("bestDiscoSigEff");
  TH2F* bestDiscoBkgEff = (TH2F*) signalMaps[0]->Clone();  bestDiscoBkgEff->SetName("bestDiscoBkgEff");
  
  TH2F* bestExcluFOMMap = (TH2F*) signalMaps[0]->Clone();  bestExcluFOMMap->SetName("bestExcluFOM");
  TH2F* bestExcluSetMap = (TH2F*) signalMaps[0]->Clone();  bestExcluSetMap->SetName("bestExcluSet");
  TH2F* bestExcluSigEff = (TH2F*) signalMaps[0]->Clone();  bestExcluSigEff->SetName("bestExcluSigEff");
  TH2F* bestExcluBkgEff = (TH2F*) signalMaps[0]->Clone();  bestExcluBkgEff->SetName("bestExcluBkgEff");
  
  for (int x = 1 ; x <= nBinsX ; x++)
  for (int y = 1 ; y <= nBinsY ; y++)
  {
      float bestDiscoFOM = -1.0;
      int   bestDiscoSet = 0;
      float bestDiscoSigEff_ = -1.0;
      float bestDiscoBkgEff_ = -1.0;
      for (unsigned int i = 0 ; i < cutAndCountRegions.size() ; i++)
      {
          float DiscoFOM = FOMdiscoveryMaps[i]->GetBinContent(x,y);
          if (bestDiscoFOM < DiscoFOM)
          {
              bestDiscoFOM = DiscoFOM;
              if (bestDiscoFOM > 0) bestDiscoSet = i+1;
              bestDiscoSigEff_ = efficiencies[i]->GetBinContent(x,y);
              bestDiscoBkgEff_ = efficiencies[i]->GetBinContent(backgroundBin);
          }
      }
      bestDiscoFOMMap->SetBinContent(x,y,bestDiscoFOM);
      bestDiscoSetMap->SetBinContent(x,y,bestDiscoSet);
      bestDiscoSigEff->SetBinContent(x,y,bestDiscoSigEff_);
      bestDiscoBkgEff->SetBinContent(x,y,bestDiscoBkgEff_);

      float bestExcluFOM = -1.0;
      int   bestExcluSet = 0;
      float bestExcluSigEff_ = -1.0;
      float bestExcluBkgEff_ = -1.0;
      for (unsigned int i = 0 ; i < cutAndCountRegions.size() ; i++)
      {
          float ExcluFOM = FOMexclusionMaps[i]->GetBinContent(x,y);
          if (bestExcluFOM < ExcluFOM)
          {
              bestExcluFOM = ExcluFOM;
              if (bestExcluFOM > 0) bestExcluSet = i+1;
              bestExcluSigEff_ = efficiencies[i]->GetBinContent(x,y);
              bestExcluBkgEff_ = efficiencies[i]->GetBinContent(backgroundBin);
          }
      }
      bestExcluFOMMap->SetBinContent(x,y,bestExcluFOM);
      bestExcluSetMap->SetBinContent(x,y,bestExcluSet);
      bestExcluSigEff->SetBinContent(x,y,bestExcluSigEff_);
      bestExcluBkgEff->SetBinContent(x,y,bestExcluBkgEff_);

  }

  // #########################
  // ##   Save those maps   ##
  // #########################

  float lineOffset = 0.0;
  string label;
  if (signalCategory == "T2tt"    ) { lineOffset = 172; label = "T2tt;";            }
  if (signalCategory == "T2bw-025") { lineOffset = 320; label = "T2bw (x = 0.25);"; }
  if (signalCategory == "T2bw-050") { lineOffset = 160; label = "T2bw (x = 0.50);"; }
  if (signalCategory == "T2bw-075") { lineOffset = 105; label = "T2bw (x = 0.75);"; }

  TFile fOutput(("../plots/cutAndCount_performances/"+signalCategory+"/custom.root").c_str(),"RECREATE");
  string pathExport = "../plots/cutAndCount_performances/"+signalCategory+"/";
  gStyle->SetPaintTextFormat("4.0f");
  formatAndWriteMapPlot(&screwdriver,bestDiscoSetMap,bestDiscoSetMap->GetName(),label+"Best set of cuts;(for discovery)",pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestExcluSetMap,bestExcluSetMap->GetName(),label+"Best set of cuts;(for exclusion)",pathExport,lineOffset);
  gStyle->SetPaintTextFormat("4.1f");
  for (unsigned int i = 0 ; i < cutAndCountRegions.size() ; i++)
  {
      FOMdiscoveryMaps[i]->SetMaximum(5.0);
      formatAndWriteMapPlot(&screwdriver,FOMdiscoveryMaps[i],FOMdiscoveryMaps[i]->GetName(),string("Discovery FOM for ")+cutAndCountRegions[i], pathExport,lineOffset);
      formatAndWriteMapPlot(&screwdriver,    efficiencies[i],    efficiencies[i]->GetName(),string("Efficiencies for " )+cutAndCountRegions[i], pathExport,lineOffset);
  }
  bestDiscoFOMMap->SetMaximum(5.0);
  bestExcluFOMMap->SetMaximum(5.0);
  formatAndWriteMapPlot(&screwdriver,bestDiscoFOMMap,bestDiscoFOMMap->GetName(),label+"Best FOM;(for discovery)"              ,pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestDiscoSigEff,bestDiscoSigEff->GetName(),label+"Best signal efficiency;(for discovery)",pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestDiscoBkgEff,bestDiscoBkgEff->GetName(),label+"Best backgr efficiency;(for discovery)",pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestExcluFOMMap,bestExcluFOMMap->GetName(),label+"Best FOM;(for exclusion)"              ,pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestExcluSigEff,bestExcluSigEff->GetName(),label+"Best signal efficiency;(for exclusion)",pathExport,lineOffset);
  formatAndWriteMapPlot(&screwdriver,bestExcluBkgEff,bestExcluBkgEff->GetName(),label+"Best backgr efficiency;(for exclusion)",pathExport,lineOffset);
  fOutput.Close();

  printBoxedMessage("Program done.");
  return (0);
}
int ScanChain( TChain* chain, bool fast = true, int nEvents = -1, string skimFilePrefix = "test") {

  //load PUweights
  TFile *fPU = new TFile("puWeights.root","READ");
  TH1D *puWeight     = (TH1D*)fPU->Get("puWeight");
  TH1D *puWeightUp   = (TH1D*)fPU->Get("puWeightUp");
  TH1D *puWeightDown = (TH1D*)fPU->Get("puWeightDown");

  TFile *fxsec = new TFile("xsec_stop_13TeV.root","READ");
  TH1D *hxsec     = (TH1D*)fxsec->Get("stop");

  TFile *f_el_SF       = new TFile("lepsf/kinematicBinSFele.root", "read");
  TFile *f_mu_SF_id    = new TFile("lepsf/TnP_MuonID_NUM_MediumID_DENOM_generalTracks_VAR_map_pt_eta.root", "read");
  TFile *f_mu_SF_iso   = new TFile("lepsf/TnP_MuonID_NUM_MiniIsoTight_DENOM_LooseID_VAR_map_pt_eta.root");
  TFile *f_mu_SF_veto_id  = new TFile("lepsf/TnP_MuonID_NUM_LooseID_DENOM_generalTracks_VAR_map_pt_eta.root", "read");
  TFile *f_mu_SF_veto_iso = new TFile("lepsf/TnP_MuonID_NUM_MiniIsoTight_DENOM_LooseID_VAR_map_pt_eta.root");
  //TFile *f_mu_SF_veto_iso = new TFile("lepsf/TnP_MuonID_NUM_MiniIsoLoose_DENOM_LooseID_VAR_map_pt_eta.root");
  //TFile *f_vetoLep_eff = new TFile("lepsf/lepeff__ttbar_powheg_pythia8_25ns.root", "read");
  TFile *f_vetoLep_eff = new TFile("lepsf/lepeff__ttbar_powheg_pythia8_25ns__SRcuts.root", "read");  
  TH2D *h_el_SF_id_temp      = (TH2D*)f_el_SF->Get("CutBasedMedium");
  TH2D *h_el_SF_iso_temp     = (TH2D*)f_el_SF->Get("MiniIso0p1_vs_AbsEta");
  TH2D *h_el_SF_veto_id_temp  = (TH2D*)f_el_SF->Get("CutBasedVeto");
  TH2D *h_el_SF_veto_iso_temp = (TH2D*)f_el_SF->Get("MiniIso0p4_vs_AbsEta");
  TH2D *h_mu_SF_id_temp      = (TH2D*)f_mu_SF_id->Get("pt_abseta_PLOT_pair_probeMultiplicity_bin0_&_tag_combRelIsoPF04dBeta_bin0_&_tag_pt_bin0_&_tag_IsoMu20_pass");
  TH2D *h_mu_SF_iso_temp     = (TH2D*)f_mu_SF_iso->Get("pt_abseta_PLOT_pair_probeMultiplicity_bin0_&_tag_combRelIsoPF04dBeta_bin0_&_tag_pt_bin0_&_PF_pass_&_tag_IsoMu20_pass");
  TH2D *h_mu_SF_veto_id_temp  = (TH2D*)f_mu_SF_veto_id->Get("pt_abseta_PLOT_pair_probeMultiplicity_bin0_&_tag_combRelIsoPF04dBeta_bin0_&_tag_pt_bin0_&_tag_IsoMu20_pass");
  TH2D *h_mu_SF_veto_iso_temp = (TH2D*)f_mu_SF_veto_iso->Get("pt_abseta_PLOT_pair_probeMultiplicity_bin0_&_tag_combRelIsoPF04dBeta_bin0_&_tag_pt_bin0_&_PF_pass_&_tag_IsoMu20_pass");
  //TH2D *h_el_vetoLepEff_temp = (TH2D*)f_vetoLep_eff->Get("h2_lepEff_vetoSel_Eff_el");
  //TH2D *h_mu_vetoLepEff_temp = (TH2D*)f_vetoLep_eff->Get("h2_lepEff_vetoSel_Eff_mu");
  TH2D *h_el_vetoLepEff_temp = (TH2D*)f_vetoLep_eff->Get("h2_lepEff_vetoSel_rebin_Eff_el");
  TH2D *h_mu_vetoLepEff_temp = (TH2D*)f_vetoLep_eff->Get("h2_lepEff_vetoSel_rebin_Eff_mu");
  TH2D *h_el_SF_id  = (TH2D*)h_el_SF_id_temp->Clone("h_el_SF_id");
  TH2D *h_el_SF_iso = (TH2D*)h_el_SF_iso_temp->Clone("h_el_SF_iso");
  TH2D *h_mu_SF_id  = (TH2D*)h_mu_SF_id_temp->Clone("h_mu_SF_id");
  TH2D *h_mu_SF_iso = (TH2D*)h_mu_SF_iso_temp->Clone("h_mu_SF_iso");
  TH2D *h_el_SF_veto_id  = (TH2D*)h_el_SF_veto_id_temp->Clone("h_el_SF_veto_id");
  TH2D *h_el_SF_veto_iso = (TH2D*)h_el_SF_veto_iso_temp->Clone("h_el_SF_veto_iso");
  TH2D *h_mu_SF_veto_id  = (TH2D*)h_mu_SF_veto_id_temp->Clone("h_mu_SF_veto_id");
  TH2D *h_mu_SF_veto_iso = (TH2D*)h_mu_SF_veto_iso_temp->Clone("h_mu_SF_veto_iso");
  //This is are the important ones
  TH2D *h_el_vetoLepEff = (TH2D*)h_el_vetoLepEff_temp->Clone("h_el_vetoLepEff");
  TH2D *h_mu_vetoLepEff = (TH2D*)h_mu_vetoLepEff_temp->Clone("h_mu_vetoLepEff");
  TH2D *h_el_SF = (TH2D*)h_el_SF_id->Clone("h_el_SF");
  h_el_SF->Multiply(h_el_SF_iso);
  TH2D *h_el_SF_veto = (TH2D*)h_el_SF_veto_id->Clone("h_el_SF_veto");
  TH2D *h_mu_SF = (TH2D*)h_mu_SF_id->Clone("h_mu_SF");
  h_mu_SF->Multiply(h_mu_SF_iso);
  TH2D *h_mu_SF_veto = (TH2D*)h_mu_SF_veto_id->Clone("h_mu_SF_veto");
  h_mu_SF_veto->Multiply(h_mu_SF_veto_iso);
  TFile *f_el_FS_ID       = new TFile("lepsf/sf_el_mediumCB.root", "read");
  TFile *f_el_FS_Iso      = new TFile("lepsf/sf_el_mini01.root", "read");
  TFile *f_mu_FS_ID       = new TFile("lepsf/sf_mu_mediumID.root", "read");
  TFile *f_mu_FS_Iso      = new TFile("lepsf/sf_mu_mini02.root", "read");
  TH2D *h_el_FS_ID_temp  = (TH2D*)f_el_FS_ID ->Get("histo2D");
  //TH2D *h_el_FS_ID       = (TH2D*)h_el_FS_ID_temp ->Clone("h_el_FS_ID");
  TH2D *h_el_FS          = (TH2D*)h_el_FS_ID_temp ->Clone("h_el_FS");
  TH2D *h_el_FS_Iso_temp = (TH2D*)f_el_FS_Iso->Get("histo2D");
  //TH2D *h_el_FS_Iso      = (TH2D*)h_el_FS_Iso_temp->Clone("h_el_FS_Iso");
  h_el_FS->Multiply(h_el_FS_Iso_temp);
  TH2D *h_mu_FS_ID_temp  = (TH2D*)f_mu_FS_ID ->Get("histo2D");
  //TH2D *h_mu_FS_ID       = (TH2D*)h_mu_FS_ID_temp ->Clone("h_mu_FS_ID");
  TH2D *h_mu_FS          = (TH2D*)h_mu_FS_ID_temp ->Clone("h_mu_FS");
  TH2D *h_mu_FS_Iso_temp = (TH2D*)f_mu_FS_Iso->Get("histo2D");
  //TH2D *h_mu_FS_Iso      = (TH2D*)h_mu_FS_Iso_temp->Clone("h_mu_FS_ID");
  h_mu_FS->Multiply(h_mu_FS_Iso_temp);

  
  // Benchmark
  TBenchmark *bmark = new TBenchmark();
  bmark->Start("benchmark");

  // Example Histograms
  TDirectory *rootdir = gDirectory->GetDirectory("Rint:");


  map<string, TH3D*> histos;//use D histos as weights can vary a lot among the signal
  vector<string> histonames; histonames.clear();
  //  vector<int> hbins; hbins.clear();
  //  vector<float> hlow; hlow.clear();
  //  vector<float> hup; hup.clear();

  //lumi, trigger, stats done
  histonames.push_back("SRyield");
  histonames.push_back("SR_Bup_HF");//done
  histonames.push_back("SR_Bdown_HF");
  histonames.push_back("SR_Bup_LF");//done
  histonames.push_back("SR_Bdown_LF");
  histonames.push_back("SR_JESup");
  histonames.push_back("SR_JESdown");
  histonames.push_back("SR_muRFup");
  histonames.push_back("SR_muRFdown");
  //histonames.push_back("SR_PDFup");
  //histonames.push_back("SR_PDFdown");
  histonames.push_back("SR_ISRup");//done preliminary
  histonames.push_back("SR_ISRdown");
  histonames.push_back("SR_PUup");//done preliminary
  histonames.push_back("SR_PUdown");
  histonames.push_back("SR_LepEffup");//done - I guess we need no renormalization - no fastsim in, no vetoSF
  histonames.push_back("SR_LepEffdown");
  histonames.push_back("SR_LepEffFSup");//done - I guess we need no renormalization - no fastsim in, no vetoSF
  histonames.push_back("SR_LepEffFSdown");
  histonames.push_back("SR_Xsecup");//done
  histonames.push_back("SR_Xsecdown");
  histonames.push_back("CR1l_sigcontamination");//scaled to signalreg yield
  histonames.push_back("CR2l_sigcontamination");//scaled to signalreg yield
  /*
  histonames.push_back("eventsum");
  histonames.push_back("rawweightsum");
  histonames.push_back("totweightsum");
  histonames.push_back("ISRsum");
  histonames.push_back("BSFsum");
  histonames.push_back("PUweightsum");
  histonames.push_back("xsecsum");
  histonames.push_back("nevtsum");
  histonames.push_back("lepsum");
  histonames.push_back("lepSFsum");
  */
  for(unsigned int i = 0; i<histonames.size(); ++i){
    string mapname = histonames[i];
    if(histos.count(mapname) == 0 ) histos[mapname] = new TH3D(mapname.c_str(), "", 37,99,1024, 19,-1,474, 13, -0.5,12.5);
    //mStop 100-1000, mLSP 0-450, SR 1-12, 9200 bins, SR 0 is non-SR - in case it it needed!!
      histos[mapname]->Sumw2(); histos[mapname]->SetDirectory(rootdir);
    }

  
  
  // Loop over events to Analyze
  unsigned int nEventsTotal = 0;
  unsigned int nEventsChain = chain->GetEntries();
  if( nEvents >= 0 ) nEventsChain = nEvents;
  TObjArray *listOfFiles = chain->GetListOfFiles();
  TIter fileIter(listOfFiles);
  TFile *currentFile = 0;

  //get the reweighting histograms
  TIter fileIterFirst(listOfFiles);
  TFile *currentFileFirst = 0;
  TH3D* counterhistSig;
  TH2F* histNEvts;
  bool thisisfirst = true;
  // File Loop for adding correct histograms
  while ( (currentFileFirst = (TFile*)fileIterFirst.Next()) ) {
    TFile *file = new TFile( currentFileFirst->GetTitle() );
    file->cd();
    if(thisisfirst){
      counterhistSig = (TH3D*)file->Get("h_counterSMS");
      counterhistSig->SetDirectory(0); 
      histNEvts = (TH2F*)file->Get("histNEvts");
      histNEvts->SetDirectory(0);
      thisisfirst = false;
    } else {
      TH3D *tempcounterhistSig = (TH3D*)file->Get("h_counterSMS");
      tempcounterhistSig->SetDirectory(0); 
      TH2F *temphistNEvts = (TH2F*)file->Get("histNEvts");
      temphistNEvts->SetDirectory(0);
      counterhistSig->Add(tempcounterhistSig);
      histNEvts->Add(temphistNEvts);
      tempcounterhistSig->Delete();
      temphistNEvts->Delete();
    }
    file->Close();
    delete file;
  }

  // File Loop
  while ( (currentFile = (TFile*)fileIter.Next()) ) {

    // Get File Content
    TFile *file = new TFile( currentFile->GetTitle() );
    TTree *tree = (TTree*)file->Get("t");
    if(fast) TTreeCache::SetLearnEntries(10);
    if(fast) tree->SetCacheSize(128*1024*1024);
    cms3.Init(tree);
    
    // Loop over Events in current file
    if( nEventsTotal >= nEventsChain ) continue;
    unsigned int nEventsTree = tree->GetEntriesFast();
    for( unsigned int event = 0; event < nEventsTree; ++event) {
 
      // Get Event Content
      if( nEventsTotal >= nEventsChain ) continue;
      if(fast) tree->LoadTree(event);
      cms3.GetEntry(event);
      ++nEventsTotal;
    
      // Progress
      CMS3::progress( nEventsTotal, nEventsChain );

      // Analysis Code

      float mStop = mass_stop();
      float mLSP = mass_lsp();
      float mCharg = mass_chargino();
      //float xVal = mass_lsp();
      int Nevts = histNEvts->GetBinContent(histNEvts->FindBin(mStop,mLSP));
      double nevts = double(Nevts);
      //float weight = cms3.scale1fb()*2.11;
      double PUweight     = puWeight    ->GetBinContent(puWeight    ->FindBin(pu_ntrue() ) );
      double PUweightUp   = puWeightUp  ->GetBinContent(puWeightUp  ->FindBin(pu_ntrue() ) );
      double PUweightDown = puWeightDown->GetBinContent(puWeightDown->FindBin(pu_ntrue() ) );
      PUweightUp = 1; PUweightDown = PUweight; PUweight = 1; //now PU syst is applying vs not applying
     double ISRnorm = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,19));
      double ISRnormup = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,20));
      double ISRnormdown = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,21));
      double ISRweight = weight_ISR();
      double BSFnorm = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,14));
      double BSFnormHup = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,15));
      double BSFnormLup = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,16));
      double BSFnormHdown = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,17));
      double BSFnormLdown = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,18));
      double BSFweight = weight_btagsf();
      double muRFnorm = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,1));
      double muRFnormup = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,5));
      double muRFnormdown = counterhistSig->GetBinContent(counterhistSig->FindBin(mStop,mLSP,9));
      if(ISRnorm>0) ISRweight*=nevts/ISRnorm;
      if(ISRnorm<=0||ISRnormup<=0||ISRnormdown<=0){ ISRnormdown=1.; ISRnormup=1.; ISRnorm=1.;}
      if(ISRweight!=weight_ISR()) cout << "ISRw " << ISRweight << " wISR " << weight_ISR() << " nevts " << nevts << " ISRn " << ISRnorm << endl;
      if(BSFnorm>0) BSFweight *=nevts/BSFnorm;
      if(BSFnorm<=0||BSFnormHup<=0||BSFnormLup<=0||BSFnormHdown<=0||BSFnormLdown<=0){
	BSFnorm=1; BSFnormHup=1; BSFnormLup=1; BSFnormHdown=1; BSFnormLdown=1;
      }
      if(muRFnorm<=0||muRFnormup<=0||muRFnormdown<=0){ muRFnormdown=1; muRFnormup=1; muRFnorm=1; }
      //lepSF is done below
      double xsection = hxsec->GetBinContent(hxsec->FindBin(mStop));
      double xsectionerr = hxsec->GetBinError(hxsec->FindBin(mStop));
      //double rawweight = xsec()*2260./nevts;
      //double weight = xsec()*2260./nevts*PUweight*ISRweight*BSFweight;//xsec given in pb
      double rawweight = xsection*2260./nevts;
      double weight = xsection*2260./nevts*PUweight*ISRweight*BSFweight;//xsec given in pb
      //did put ISRweight which should be ==1
      if(ISRweight!=1) cout << "ISRw " << ISRweight << endl;
      if(event==0) cout << "weight " << weight << " nEvents " << nEventsTree << " filename " << currentFile->GetTitle() << endl;

      int NSLeps = 0;
      int NAddVetoLeps = 0;
      if(lep1_is_mu()){
	if(lep1_pt()>20&&fabs(lep1_eta())<2.4) {++NSLeps;}
      } else if (lep1_is_el()){
	if(lep1_pt()>20&&fabs(lep1_eta())<1.4442) {++NSLeps; }
      } if(lep2_is_mu()){
	if(lep2_pt()>20&&fabs(lep2_eta())<2.4) {++NSLeps;}
      } else if (lep2_is_el()){
	if(lep2_pt()>20&&fabs(lep2_eta())<1.4442) {++NSLeps; }
      }
      if(lep2_is_mu()){
	if(lep2_pt()>10&&fabs(lep2_eta())<2.4) {++NAddVetoLeps;}
      } else if (lep2_is_el()){
	if(lep2_pt()>10&&fabs(lep2_eta())<2.4) {++NAddVetoLeps; }
      }
      if(NSLeps<1) continue;//temp
      float lepSF_pt_cutoff = 100.0;
      float lepSF_pt_min    = 10.0;
      double lepSF    = 1.0;
      double lepSF_Up = 1.0;
      double lepSF_Dn = 1.0;
      float lepSF_FS_pt_cutoff = 200.0;
      double lepSF_FS    = 1.0;
      double lepSF_FS_Up = 1.0;
      double lepSF_FS_Dn = 1.0;	
      if(lep1_is_el()){
	int binX = h_el_SF->GetXaxis()->FindBin( std::min(lepSF_pt_cutoff, (float)lep1_p4().Pt()) );
	int binY = h_el_SF->GetYaxis()->FindBin( fabs(lep1_p4().Eta()) );
	lepSF    = h_el_SF->GetBinContent( binX, binY );
	lepSF_Up = lepSF + h_el_SF->GetBinError( binX, binY );
	lepSF_Dn = lepSF - h_el_SF->GetBinError( binX, binY );
	int bin = h_el_FS->FindBin(  std::min(lepSF_FS_pt_cutoff, (float)lep1_p4().Pt()), fabs(lep1_p4().Eta()) );
	lepSF_FS = h_el_FS->GetBinContent(bin);
	lepSF_FS_Up = lepSF_FS + h_el_FS->GetBinError(bin);
	lepSF_FS_Dn = lepSF_FS + h_el_FS->GetBinError(bin);
      }
      if(lep1_is_mu()){
	int binX = h_mu_SF->GetXaxis()->FindBin( std::min(lepSF_pt_cutoff, (float)lep1_p4().Pt()) );
	int binY = h_mu_SF->GetYaxis()->FindBin( fabs(lep1_p4().Eta()) );
	lepSF    = h_mu_SF->GetBinContent( binX, binY );
	lepSF_Up = lepSF + h_mu_SF->GetBinError( binX, binY );
	lepSF_Dn = lepSF - h_mu_SF->GetBinError( binX, binY );
	int bin = h_mu_FS->FindBin(  std::min(lepSF_FS_pt_cutoff, (float)lep1_p4().Pt()), fabs(lep1_p4().Eta()) );
	lepSF_FS = h_mu_FS->GetBinContent(bin);
	lepSF_FS_Up = lepSF_FS + h_mu_FS->GetBinError(bin);
	lepSF_FS_Dn = lepSF_FS + h_mu_FS->GetBinError(bin);
      }
      weight *= (lepSF*lepSF_FS);

      
      if(nvtxs()<0)               continue;
      if(ngoodleps()<1)           continue;//accomodate 2l-CR
      if(nvetoleps()<1)           continue;//accomodate 2l-CR
    //if(!PassTrackVeto_v3())     continue;//accomodate 2l-CR
    //if(!PassTauVeto())          continue;//accomodate 2l-CR
      if(ngoodjets()<2)           continue;
      if(ngoodbtags()<0)          continue;//accomodate 1l-CR
      if(pfmet()<250)             continue;
      if(mt_met_lep()<150)        continue;
      if(mindphi_met_j1_j2()<0.8) continue;


      int SR = -1;
      int compressedSR = -1;
      if(ngoodleps()==1&&nvetoleps()==1&&PassTrackVeto_v3()&&PassTauVeto()&&ngoodbtags()>=1){//basis for SR 1l, >=1b
	if(ngoodjets()>=4){
	  if(MT2W()<=200){
	    if(pfmet()>325) SR = 2;
	    else SR = 1;
	  } else { //high MT2W
	    if(pfmet()>450) SR = 5;
	    else if(pfmet()>350) SR = 4;
	    else SR = 3;
	  }
	} else if(ngoodjets()==3 && MT2W()>200 && pfmet()>350) {
	  SR = 6;
	} else if(MT2W()>200&&topnessMod()>(-3)) { //2 or 3 jets
	  if(ngoodbtags()==1){
	    if(pfmet()>400) SR = 8;
	    else SR = 7;
	  } else {//ge2 jets
	    if(pfmet()>400) SR = 10;
	    else SR = 9;
	  }
	}
	//compressed region (jets are sorted by pt
	if(ngoodjets()>=5&&ak4pfjets_passMEDbtag()[0]==false&&ak4pfjets_pt()[0]>200.){
	  if(MT2W()<=200) compressedSR = 11;
	  else compressedSR = 12;
	}
      }

      //CR-1l
      int CR1l = -1;
      if(ngoodleps()==1&&nvetoleps()==1&&PassTrackVeto_v3()&&PassTauVeto()&&ngoodbtags()==0&&ngoodjets()>=3&&MT2W()>200){
	if(ngoodjets()==3){
	  CR1l = 1;
	} else {
	  CR1l = 2;
	}
      }
      //CR1l  1 --> SR  6
      //CR1l  2 --> SR  3-5
      float CR1l_1_6 = 0.37*0.18;
      float CR1l_2_3 = 0.55*0.15;
      float CR1l_2_4 = 0.25*0.29;
      float CR1l_2_5 = 0.20*0.40;

      //CR2l = -1;
      int lepind = -1;
      if(ngoodleps()>=2&&NSLeps==2) lepind = 5;
      else if(ngoodleps()==2&&NSLeps==2) lepind = 4;//exactly two leptons,CR4
      else if(ngoodleps()==1&&NSLeps==1&&NAddVetoLeps>=1) lepind = 3;//one lepton, but more than 1 add. loose,1l,>2l
      //else if(ngoodleps()==1&&NSLeps==1&&nvetoleps()==2) lepind = 2;//one lepton + 1 add. loose,CR5
      else if(ngoodleps()==1&&NSLeps==1&&nvetoleps()==0&&(!PassTrackVeto_v3()||!PassTauVeto())) lepind = 1;//exactly one lepton, but do not pass track/tau veto - i.e. one additional track or tau, CR6
      int CR2l = -1;
      if((lepind==4||lepind==3||lepind==1)&&ngoodjets()>=3&&ngoodbtags()>=1){
	if(MT2W()<=200) CR2l = 1;
	else CR2l = 2;
      }
      float CR2l_1_1 = 0.61*0.48;
      float CR2l_1_2 = 0.61*0.19;
      float CR2l_2_3 = 0.44*0.39;
      float CR2l_2_4 = 0.44*0.11;
      float CR2l_2_5 = 0.44*0.07;
      float CR2l_2_6 = 0.44*0.11;

      if(SR==(-1)&&CR1l==(-1)&&CR2l==(-1)&&compressedSR==(-1)) continue;
      //implement some sanity checks
      if(CR1l!=(-1)&&CR2l!=(-1)) cout << "WTF CR1l " << CR1l << " CR2l " << CR2l << endl;
      if(SR!=(-1)&&CR1l!=(-1)) cout << "WTF SR " << SR << " CR1l " << CR1l << endl;
      if(SR!=(-1)&&CR2l!=(-1)) cout << "WTF SR " << SR << " CR2l " << CR2l << endl;

      //ISR reweighting, get stop pair using last copy:
      double ISRup = weight_ISRup()/weight_ISR()*ISRnorm/ISRnormup;
      double ISRdown = weight_ISRdown()/weight_ISR()*ISRnorm/ISRnormdown;
      //double XSup = (xsec()+xsec_uncert())/xsec();
      //double XSdown = (xsec()-xsec_uncert())/xsec();
      double XSup = (xsection+xsectionerr)/xsection;
      double XSdown = (xsection-xsectionerr)/xsection;
      double PUup = PUweightUp/PUweight;
      double PUdown = PUweightDown/PUweight;
      double lEffup = lepSF_Up/lepSF;
      double lEffdown = lepSF_Dn/lepSF;
      double lEffFSup = lepSF_FS_Up/lepSF_FS;
      double lEffFSdown = lepSF_FS_Dn/lepSF_FS;
      double BSFHup = weight_btagsf_heavy_UP()/weight_btagsf()*BSFnorm/BSFnormHup;
      double BSFLup = weight_btagsf_light_UP()/weight_btagsf()*BSFnorm/BSFnormHup;
      double BSFHdown = weight_btagsf_heavy_DN()/weight_btagsf()*BSFnorm/BSFnormHup;
      double BSFLdown = weight_btagsf_light_DN()/weight_btagsf()*BSFnorm/BSFnormHup;
      double muRFup = genweights().at(4)/genweights().at(0)*muRFnorm/muRFnormup;
      double muRFdown = genweights().at(8)/genweights().at(0)*muRFnorm/muRFnormdown;
      //cout << genweights().at(0) << " " << genweights().at(4) << " " << genweights().at(8) << " " << mStop << " " << mLSP << endl;

      if(CR1l>0){
	if(ngoodleps()!=1) cout << __LINE__ << " " << ngoodleps() << endl;
	if(NSLeps!=1) cout << __LINE__ << " " << NSLeps << endl;
	if(nvetoleps()!=1) cout << __LINE__ << " " << nvetoleps() << endl;
	if(ngoodbtags()>=1) cout << __LINE__ << " " << ngoodbtags() << endl;
	//signal contamination in 0b control region, do correlations later during datacard making
	if(CR1l==1){
	  histos["CR1l_sigcontamination"]->Fill(mStop,mLSP,6,weight*CR1l_1_6);
	} else if(CR1l==2){
	  histos["CR1l_sigcontamination"]->Fill(mStop,mLSP,3,weight*CR1l_2_3);
	  histos["CR1l_sigcontamination"]->Fill(mStop,mLSP,4,weight*CR1l_2_4);
	  histos["CR1l_sigcontamination"]->Fill(mStop,mLSP,5,weight*CR1l_2_5);
	}
      } else if(CR2l>0){
	if(nvetoleps()<=1||(nvetoleps()==1&&(!PassTrackVeto_v3()||!PassTauVeto()))) cout << __LINE__ << " " << nvetoleps() << " " << PassTrackVeto_v3() << " " << PassTauVeto() << endl;
	if(ngoodbtags()<1) cout << __LINE__ << " " << ngoodbtags() << endl;
	//signal contamination in 2l control region, do correlations later during datacard making
	if(CR2l==1){
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,1,weight*CR2l_1_1);
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,2,weight*CR2l_1_2);
	} else if(CR2l==2){
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,3,weight*CR2l_2_3);
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,4,weight*CR2l_2_4);
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,5,weight*CR2l_2_5);
	  histos["CR2l_sigcontamination"]->Fill(mStop,mLSP,6,weight*CR2l_2_6);

	}
      } else if(SR>0){
	if(ngoodleps()!=1) cout << __LINE__ << " " << ngoodleps() << endl;
	if(NSLeps!=1) cout << __LINE__ << " " << NSLeps << endl;
	if(nvetoleps()!=1) cout << __LINE__ << " " << nvetoleps() << endl;
	if(!PassTrackVeto_v3())  cout << __LINE__ << endl;
	if(!PassTauVeto())  cout << __LINE__ << endl;
	if(SR<=6&&ngoodjets()<3) cout << __LINE__ << " " << ngoodjets() << endl;
	if(ngoodbtags()<1) cout << __LINE__ << " " << ngoodbtags() << endl;
	/*
	histos["eventsum"]->Fill(mStop,mLSP,SR,1.);
	histos["rawweightsum"]->Fill(mStop,mLSP,SR,rawweight);
	histos["totweightsum"]->Fill(mStop,mLSP,SR,weight);
	histos["ISRsum"]->Fill(mStop,mLSP,SR,ISRweight);
	histos["BSFsum"]->Fill(mStop,mLSP,SR,BSFweight);
	histos["PUweightsum"]->Fill(mStop,mLSP,SR,PUweight);
	histos["xsecsum"]->Fill(mStop,mLSP,SR,xsection);
	histos["nevtsum"]->Fill(mStop,mLSP,SR,nevts);
	histos["lepsum"]->Fill(mStop,mLSP,SR,lepSF);
	histos["lepSFsum"]->Fill(mStop,mLSP,SR,lepSF_FS);
	*/
	//finally - do signal regions!
	histos["SRyield"]->Fill(mStop,mLSP,SR,weight);
	histos["SR_ISRup"]->Fill(mStop,mLSP,SR,weight*ISRup);
	histos["SR_ISRdown"]->Fill(mStop,mLSP,SR,weight*ISRdown);
	histos["SR_Xsecup"]->Fill(mStop,mLSP,SR,weight*XSup);
	histos["SR_Xsecdown"]->Fill(mStop,mLSP,SR,weight*XSdown);
	histos["SR_PUup"]->Fill(mStop,mLSP,SR,weight*PUup);
	histos["SR_PUdown"]->Fill(mStop,mLSP,SR,weight*PUdown);
	histos["SR_Bup_HF"]->Fill(mStop,mLSP,SR,weight*BSFHup);
	histos["SR_Bup_LF"]->Fill(mStop,mLSP,SR,weight*BSFLup);
	histos["SR_Bdown_HF"]->Fill(mStop,mLSP,SR,weight*BSFHdown);
	histos["SR_Bdown_LF"]->Fill(mStop,mLSP,SR,weight*BSFLdown);
	histos["SR_LepEffup"]->Fill(mStop,mLSP,SR,weight*lEffup);
	histos["SR_LepEffdown"]->Fill(mStop,mLSP,SR,weight*lEffdown);
	histos["SR_LepEffFSup"]->Fill(mStop,mLSP,SR,weight*lEffFSup);
	histos["SR_LepEffFSdown"]->Fill(mStop,mLSP,SR,weight*lEffFSdown);
	histos["SR_muRFup"]->Fill(mStop,mLSP,SR,weight*muRFup);
	histos["SR_muRFdown"]->Fill(mStop,mLSP,SR,weight*muRFdown);
      }
      if(compressedSR>0){
	if(compressedSR<=6) cout << __LINE__ << " " << compressedSR << endl;
	//compressedSR is defined to not overlap with SR - can use same histogram!
	histos["SRyield"]->Fill(mStop,mLSP,compressedSR,weight);
	histos["SR_ISRup"]->Fill(mStop,mLSP,compressedSR,weight*ISRup);
	histos["SR_ISRdown"]->Fill(mStop,mLSP,compressedSR,weight*ISRdown);
	histos["SR_Xsecup"]->Fill(mStop,mLSP,compressedSR,weight*XSup);
	histos["SR_Xsecdown"]->Fill(mStop,mLSP,compressedSR,weight*XSdown);
	histos["SR_PUup"]->Fill(mStop,mLSP,compressedSR,weight*PUup);
	histos["SR_PUdown"]->Fill(mStop,mLSP,compressedSR,weight*PUdown);
	histos["SR_Bup_HF"]->Fill(mStop,mLSP,compressedSR,weight*BSFHup);
	histos["SR_Bup_LF"]->Fill(mStop,mLSP,compressedSR,weight*BSFLup);
	histos["SR_Bdown_HF"]->Fill(mStop,mLSP,compressedSR,weight*BSFHdown);
	histos["SR_Bdown_LF"]->Fill(mStop,mLSP,compressedSR,weight*BSFLdown);
	histos["SR_LepEffup"]->Fill(mStop,mLSP,compressedSR,weight*lEffup);
	histos["SR_LepEffdown"]->Fill(mStop,mLSP,compressedSR,weight*lEffdown);
	histos["SR_LepEffFSup"]->Fill(mStop,mLSP,compressedSR,weight*lEffFSup);
	histos["SR_LepEffFSdown"]->Fill(mStop,mLSP,compressedSR,weight*lEffFSdown);
	histos["SR_muRFup"]->Fill(mStop,mLSP,compressedSR,weight*muRFup);
	histos["SR_muRFdown"]->Fill(mStop,mLSP,compressedSR,weight*muRFdown);
      }

    }//event loop
  
    // Clean Up
    delete tree;
    file->Close();
    delete file;
  }//file loop
  if ( nEventsChain != nEventsTotal ) {
    cout << Form( "ERROR: number of events from files (%d) is not equal to total number of events (%d)", nEventsChain, nEventsTotal ) << endl;
  }
  
  // Example Histograms
  // samplehisto->Draw();

  /*
  for(map<string,TH3D*>::iterator h=histos.begin(); h!=histos.end();++h){
    //add overflow
    //h->second->SetBinContent(h->second->GetNbinsX(), h->second->GetBinContent(h->second->GetNbinsX() )+ h->second->GetBinContent(h->second->GetNbinsX()+1) );
    //h->second->SetBinError(h->second->GetNbinsX(), sqrt(pow(h->second->GetBinError(h->second->GetNbinsX() ),2)+pow(h->second->GetBinError(h->second->GetNbinsX()+1),2) ) );
    //add underfloe
    //h->second->SetBinContent(1, h->second->GetBinContent(1)+ h->second->GetBinContent(0) );
    //h->second->SetBinError(1, sqrt(pow(h->second->GetBinError(1),2)+pow(h->second->GetBinError(0),2) ) );
  }
  */
  string filename = "rootfiles/signalyields/Histos_"+skimFilePrefix+".root";
  TFile *f = new TFile(filename.c_str(),"RECREATE");
  f->cd();
  for(map<string,TH3D*>::iterator h=    histos.begin(); h!=    histos.end();++h) h->second->Write();
  f->Close();
  cout << "Saved histos in " << f->GetName() << endl;

  f_el_SF->Close();
  f_mu_SF_id->Close();
  f_mu_SF_iso->Close();
  f_mu_SF_veto_id->Close();
  f_mu_SF_veto_iso->Close();
  f_vetoLep_eff->Close();
  f_el_FS_ID->Close();
  f_el_FS_Iso->Close();
  f_mu_FS_ID->Close();
  f_mu_FS_Iso->Close();
  // return
  bmark->Stop("benchmark");
  cout << endl;
  cout << nEventsTotal << " Events Processed" << endl;
  cout << "------------------------------" << endl;
  cout << "CPU  Time:	" << Form( "%.01f", bmark->GetCpuTime("benchmark")  ) << endl;
  cout << "Real Time:	" << Form( "%.01f", bmark->GetRealTime("benchmark") ) << endl;
  cout << endl;
  delete bmark;
  delete fPU;//delete PU file
  delete f_el_SF;
  delete f_mu_SF_id;
  delete f_mu_SF_iso;
  delete f_mu_SF_veto_id;
  delete f_mu_SF_veto_iso;
  delete f_vetoLep_eff;
  delete f_el_FS_ID;
  delete f_el_FS_Iso;
  delete f_mu_FS_ID;
  delete f_mu_FS_Iso;
  return 0;
}
Exemple #11
0
void trim(const char* treepath = "/media/Disk1/avartak/CMS/Data/Dileptons/DoubleMuon/tree*.root", const char* outfilename = "/media/Disk1/avartak/CMS/Data/Dileptons/DoubleMuon/trim.root", bool isMC = false) {

    TFile purwtfile("../data/purwt.root");
    TFile muoidfile("../data/muonIDIsoSF.root");

    TH1F* purwthist = (TH1F*)purwtfile.Get("puhist");

    TH2F* muidlhist = (TH2F*)muoidfile.Get("scalefactors_MuonMediumId_Muon");
    TH2F* muidmhist = (TH2F*)muoidfile.Get("scalefactors_MuonMediumId_Muon");
    TH2F* muidthist = (TH2F*)muoidfile.Get("scalefactors_TightId_Muon"     );

    TH2F* muislhist = (TH2F*)muoidfile.Get("scalefactors_Iso_MuonMediumId" );
    TH2F* muismhist = (TH2F*)muoidfile.Get("scalefactors_Iso_MuonMediumId" );
    TH2F* muisthist = (TH2F*)muoidfile.Get("scalefactors_Iso_MuonTightId"  );

    TFileCollection fc("fc");
    fc.Add(treepath);

    TChain* chain = new TChain("mmtree/tree");
    chain->AddFileInfoList(fc.GetList());

    TTreeReader reader(chain);

    TTreeReaderValue<double>                       xsec     (reader, "xsec"       );
    TTreeReaderValue<double>                       wgt      (reader, "wgt"        );
    TTreeReaderValue<unsigned>                     nvtx     (reader, "nvtx"       );
    TTreeReaderValue<std::vector<TLorentzVector> > dimuons  (reader, "dimuons"    );
    TTreeReaderValue<std::vector<unsigned> >       m1idx    (reader, "m1idx"      );
    TTreeReaderValue<std::vector<unsigned> >       m2idx    (reader, "m2idx"      );
    TTreeReaderValue<std::vector<double> >         masserr  (reader, "masserr"    );
    TTreeReaderValue<std::vector<TLorentzVector> > muons    (reader, "muons"      );
    TTreeReaderValue<std::vector<double> >         miso     (reader, "miso"       );
    TTreeReaderValue<std::vector<char> >           mid      (reader, "mid"        );
    TTreeReaderValue<unsigned char>                hlt2m    (reader, "hltdoublemu");
    TTreeReaderValue<unsigned char>                hlt1m    (reader, "hltsinglemu");

    TFile* outfile = new TFile(outfilename, "RECREATE");
    TTree* outtree = new TTree("tree", "tree");

    double wgtsum  = isMC ? sumwgt(treepath) : 1.0;
    double mcwgt   = 1.0;
    double puwgt   = 1.0;
    double lidw1   = 1.0;
    double lidw2   = 1.0;
    double midw1   = 1.0;
    double midw2   = 1.0;
    double tidw1   = 1.0;
    double tidw2   = 1.0;
    double m1pt    = 0.0;        
    double m1eta   = 0.0;        
    double m1phi   = 0.0;        
    double m1iso   = 0.0;        
    double m2pt    = 0.0;        
    double m2eta   = 0.0;        
    double m2phi   = 0.0;        
    double m2iso   = 0.0;        
    double mmpt    = 0.0;        
    double mmeta   = 0.0;        
    double mmphi   = 0.0;        
    double mass    = 0.0;        
    double merr    = 0.0;        

    char   m1id    = 0;
    char   m2id    = 0;
    char   trig1m  = 0;
    char   trig2m  = 0;

    outtree->Branch("mcwgt" , &mcwgt , "mcwgt/D" );
    outtree->Branch("puwgt" , &puwgt , "puwgt/D" );
    outtree->Branch("lidw1" , &lidw1 , "lidw1/D" );
    outtree->Branch("lidw2" , &lidw2 , "lidw2/D" );
    outtree->Branch("midw1" , &midw1 , "midw1/D" );
    outtree->Branch("midw2" , &midw2 , "midw2/D" );
    outtree->Branch("tidw1" , &tidw1 , "tidw1/D" );
    outtree->Branch("tidw2" , &tidw2 , "tidw2/D" );
    outtree->Branch("m1pt"  , &m1pt  , "m1pt/D"  );
    outtree->Branch("m1eta" , &m1eta , "m1eta/D" );
    outtree->Branch("m1eta" , &m1phi , "m1phi/D" );
    outtree->Branch("m1id"  , &m1id  , "m1id/B"  );
    outtree->Branch("m1iso" , &m1iso , "m1iso/D" );
    outtree->Branch("m2pt"  , &m2pt  , "m2pt/D"  );
    outtree->Branch("m2eta" , &m2eta , "m2eta/D" );
    outtree->Branch("m2eta" , &m2phi , "m2phi/D" );
    outtree->Branch("m2id"  , &m2id  , "m2id/B"  );
    outtree->Branch("m2iso" , &m2iso , "m2iso/D" );
    outtree->Branch("mmpt"  , &mmpt  , "mmpt/D"  );
    outtree->Branch("mmeta" , &mmeta , "mmeta/D" );
    outtree->Branch("mmeta" , &mmphi , "mmphi/D" );
    outtree->Branch("mass"  , &mass  , "mass/D"  );
    outtree->Branch("merr"  , &merr  , "merr/D"  );
    outtree->Branch("trig1m", &trig1m, "trig1m/b");
    outtree->Branch("trig2m", &trig2m, "trig2m/b");

    while(reader.Next()) {

        if (muons->size() != 2) continue;
        if (dimuons->size() != 1) continue;

        unsigned numvtx = *nvtx;
        if (numvtx > 40) numvtx = 40;

        double pt1  = muons->at((*m1idx)[0]).Pt();
        double pt2  = muons->at((*m2idx)[0]).Pt();

        double eta1 = fabs(muons->at((*m1idx)[0]).Eta());
        double eta2 = fabs(muons->at((*m2idx)[0]).Eta());

        if (pt1 >= 120.0) pt1 = 119.9;
        if (pt2 >= 120.0) pt2 = 119.9;

        if (pt1 <=  20.0) pt1 =  20.1;
        if (pt2 <=  20.0) pt2 =  20.1;

        if (isMC) {
            mcwgt = 35.9 * (*wgt) * (*xsec) / wgtsum;
            puwgt = purwthist->GetBinContent(purwthist->FindBin(numvtx));
            
            lidw1 = muidlhist->GetBinContent(muidlhist->FindBin(eta1, pt1));
            lidw1*= muislhist->GetBinContent(muislhist->FindBin(eta1, pt1));
            lidw2 = muidlhist->GetBinContent(muidlhist->FindBin(eta2, pt2));
            lidw2*= muislhist->GetBinContent(muislhist->FindBin(eta2, pt2));
            
            midw1 = muidmhist->GetBinContent(muidmhist->FindBin(eta1, pt1));
            midw1*= muismhist->GetBinContent(muismhist->FindBin(eta1, pt1));
            midw2 = muidmhist->GetBinContent(muidmhist->FindBin(eta2, pt2));
            midw2*= muismhist->GetBinContent(muismhist->FindBin(eta2, pt2));
            
            tidw1 = muidthist->GetBinContent(muidthist->FindBin(eta1, pt1));
            tidw1*= muisthist->GetBinContent(muisthist->FindBin(eta1, pt1));
            tidw2 = muidthist->GetBinContent(muidthist->FindBin(eta2, pt2));
            tidw2*= muisthist->GetBinContent(muisthist->FindBin(eta2, pt2));
        }

        m1pt   = muons->at((*m1idx)[0]).Pt();
        m1eta  = muons->at((*m1idx)[0]).Eta();
        m1phi  = muons->at((*m1idx)[0]).Phi();

        m2pt   = muons->at((*m2idx)[0]).Pt();
        m2eta  = muons->at((*m2idx)[0]).Eta();
        m2phi  = muons->at((*m2idx)[0]).Phi();

        mmpt   = (*dimuons)[0].Pt();
        mmeta  = (*dimuons)[0].Eta();
        mmphi  = (*dimuons)[0].Phi();
        mass   = (*dimuons)[0].M();

        merr   = (*masserr)[0];

        m1id   = mid->at((*m1idx)[0]);
        m2id   = mid->at((*m2idx)[0]);

        m1iso  = miso->at((*m1idx)[0]);
        m2iso  = miso->at((*m2idx)[0]);

        trig1m = (*hlt1m);
        trig2m = (*hlt2m);

        outtree->Fill();

    }

    outtree->Write();

    outfile->Close();
}