示例#1
0
文件: chain.C 项目: rebecacern/ZH3l
void chain(int cem = 8, int nsel = 0, double mh = 125, int mode = 0){

  char plotName[300];
  sprintf(plotName,"test");
  bool isBackground = true;
  bool isData = false;
		  
  if (nsel == 0)                	{sprintf(plotName,"Data");	isBackground = false;	isData = true;}
  else if (nsel == 1)   		{sprintf(plotName,"ZH");	isBackground = false;}
  else if (nsel == 2)   		{sprintf(plotName,"WZ");}
  else if (nsel == 3)   		{sprintf(plotName,"ZZ");}
  else if (nsel == 4)   		{sprintf(plotName,"VVV");}
  else if (nsel == 5)			{sprintf(plotName,"Wjets");}
  else if (nsel == 6) 			{sprintf(plotName, "all");}
  else if (nsel == 7) 			{sprintf(plotName, "ZH_SM");	isBackground = false;} //no fakes allowed
				  
  char myRootFile[300];
  if (cem != 7 && cem !=8) cem = 8;
  double lumi = lumi8;
 if (cem == 8){
    if (nsel == 0) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/data_3l.root");
    else if (nsel == 7) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/zhww125.root");
    else if (nsel == 1 && (mh == 125 || mh == 124 || mh == 126 || mh == 125.7)) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/zhww125.root");
    else if (nsel == 1 && (mh == 118 || mh == 122)) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/hww120.root");
    else if (nsel == 1 &&  mh == 128) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/hww130.root");
    else if (nsel == 1) sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/hww%g.root", mh);
    else sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/backgroundA_3l.root");
  } else {
    lumi = lumi7;
    if (nsel == 0) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/data_3l.root");
    else if (nsel == 7) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/zhww125.root");
    else if (nsel == 1 && (mh == 125 || mh == 125.7)) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/zhww125.root");
    else if (nsel == 1 && (mh == 110 || mh == 115)) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/vtthww118.root");
    else if (nsel == 1 && mh == 145) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/vtthww140.root");
    else if (nsel == 1) sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/vtthww%g.root", mh);
    else sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/backgroundA_3l.root");
  }
  
  cout << "[Info:] "<< cem <<  "TeV, " << plotName << ", Higgs mass " << mh << ","  ;
  if (mode == 1) cout << " eee channel" << endl ;
  else if (mode == 2) cout << " eem channel" << endl ; 
  else if (mode == 3) cout << " emm channel" << endl ; 
  else if (mode == 4) cout << " mmm channel" << endl ; 
  else cout << " all final states" << endl;
 								    
  //Load datasets
  SmurfTree sample;
  cout << myRootFile << endl;
  sample.LoadTree(myRootFile,-1);
  sample.InitTree(0);

  // Prepare output file
  char rootFile[300];
  if (mode == 1) sprintf(rootFile,"%g/zh3l2j_input_shape_eee_%dTeV.root", mh, cem);
  else if (mode == 2) sprintf(rootFile,"%g/zh3l2j_input_shape_eem_%dTeV.root", mh, cem);
  else if (mode == 3) sprintf(rootFile,"%g/zh3l2j_input_shape_emm_%dTeV.root", mh, cem);
  else if (mode == 4) sprintf(rootFile,"%g/zh3l2j_input_shape_mmm_%dTeV.root", mh, cem);
  else sprintf(rootFile,"%g/zh3l2j_input_shape_%dTeV.root", mh, cem);
  
  TFile f_root(rootFile, "UPDATE");
											      
  // Prepare histograms
  char title[300];
												    
  sprintf(title,"histo_%s",plotName);
  TH1F* histo = new TH1F( title, " ", nbins, nbinlow, nbinhigh);
  histo->Sumw2();

  //Prepare useful things
  double weight = 1;
  double eventsPass = 0;
														  
  int nSample=sample.tree_->GetEntries();
  for (int i=0; i<nSample; ++i) {
														           
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nSample);
    sample.tree_->GetEntry(i);
    
    if(nsel == 1 && sample.processId_ != 24) continue;
    if(nsel == 7 && sample.processId_ != 24) continue;

    //Modes, 0 = all, 1 = eee, 2 = eem, 3 = emm, 4 = mmm
    if (mode == 1 && (abs(sample.lid1_)!= 11 || abs(sample.lid2_) != 11 || abs(sample.lid3_) != 11)) continue;
    if (mode == 2 && 
       ((abs(sample.lid1_)!= abs(sample.lid2_) && abs(sample.lid1_) != abs(sample.lid3_) && abs(sample.lid1_) == 11) ||
        (abs(sample.lid2_)!= abs(sample.lid1_) && abs(sample.lid2_) != abs(sample.lid3_) && abs(sample.lid2_) == 11) ||
	(abs(sample.lid3_)!= abs(sample.lid1_) && abs(sample.lid3_) != abs(sample.lid2_) && abs(sample.lid3_) == 11) ||
	(abs(sample.lid1_) == abs(sample.lid2_) && abs(sample.lid1_) == abs(sample.lid3_)))) continue;
    if (mode == 3 && 
       ((abs(sample.lid1_)!= abs(sample.lid2_) && abs(sample.lid1_) != abs(sample.lid3_) && abs(sample.lid1_) == 13) ||
        (abs(sample.lid2_)!= abs(sample.lid1_) && abs(sample.lid2_) != abs(sample.lid3_) && abs(sample.lid2_) == 13) ||
	(abs(sample.lid3_)!= abs(sample.lid1_) && abs(sample.lid3_) != abs(sample.lid2_) && abs(sample.lid3_) == 13) ||
	(abs(sample.lid1_) == abs(sample.lid2_) && abs(sample.lid1_) == abs(sample.lid3_)))) continue;
    if (mode == 4 && (abs(sample.lid1_)!= 13 || abs(sample.lid2_) != 13 || abs(sample.lid3_) != 13)) continue;
   
    				     
    weight = 1;
    if (!isData && sample.dstype_ != SmurfTree::data) weight = lumi*sample.scale1fb_*sample.sfWeightPU_*sample.sfWeightEff_*sample.sfWeightTrig_;    
      
    if (cem == 8 && nsel == 1 && mh == 118) weight *= ((0.472400*0.11800000)/(0.448300*0.14300000));  
    if (cem == 8 && nsel == 1 && mh == 122) weight *= ((0.425700*0.17000000)/(0.448300*0.14300000));  
    if (cem == 8 && nsel == 1 && mh == 124) weight *= ((0.404400*0.200000)/(0.394300*0.216000));    
    if (cem == 8 && nsel == 1 && mh == 126) weight *= ((0.384300*0.233000)/(0.394300*0.216000));   
    if (cem == 8 && nsel == 1 && mh == 128) weight *= ((0.365200*0.26800000)/(0.347300*0.30500000));  
    if (cem == 8 && nsel == 1 && mh == 127.5) weight *= ((0.387300*0.226200)/(0.394300*0.216000)); 
    
    if (cem == 7 && nsel == 1 && mh == 110) weight *= (0.02251917/0.0443547);
    if (cem == 7 && nsel == 1 && mh == 115) weight *= (0.03532622/0.0443547);
    if (cem == 7 && nsel == 1 && mh == 145) weight *= ((0.193000*0.600000)/(0.217200*0.501000));
    if (cem == 7 && nsel == 1 && mh == 125.7) weight *= ((0.215000*0.315800)/(0.226200*0.310100));
    
   
   //Three real leptons MC level
    if (!isData){
      bool isRealLepton = false;
      if((TMath::Abs(sample.lep1McId_) == 11 || TMath::Abs(sample.lep1McId_) == 13) &&
	 (TMath::Abs(sample.lep2McId_) == 11 || TMath::Abs(sample.lep2McId_) == 13) &&
	 (TMath::Abs(sample.lep3McId_) == 11 || TMath::Abs(sample.lep3McId_) == 13)) isRealLepton = true; 
      if (!isRealLepton && !isBackground) continue; //signal
      if (!isRealLepton && sample.dstype_ != SmurfTree::data) continue; //background
    }
																									         
    int ntype = sample.dstype_;
    
    //Check for fakes
    int nFake = 0;
    if(((sample.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (sample.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (sample.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (sample.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if (nFake !=0 && !isBackground) continue; 
    if (nFake !=0){ 
      ntype = 61;
      weight*= sample.sfWeightFR_*factor;
      //if (sample.dstype_ != SmurfTree::data) weight *=-1;
    }
    
    
    //2 same flavor, oppposite sign leptons + extra one
    if (sample.lid3_ == sample.lid2_ && sample.lid3_ == sample.lid1_) continue;
    if (sample.lid3_ == sample.lid2_ && fabs(sample.lid3_) != fabs(sample.lid1_)) continue;
    if (sample.lid3_ == sample.lid1_ && fabs(sample.lid3_) != fabs(sample.lid2_)) continue;
    if (sample.lid2_ == sample.lid1_ && fabs(sample.lid2_) != fabs(sample.lid3_)) continue;
    
    // At least 2 jets 
    if (sample.njets_ < 2) continue; 
    if (tau && (sample.jet1McId_ == 100 || sample.jet2McId_ == 100 || sample.jet3McId_ == 100 || sample.jet4McId_ == 100)) continue;

    //Make z-compatible pairs
    double m[3] = {-1, -1, -1};
    LorentzVector pair1, pair2, pair3;
    if (fabs(sample.lid1_) == fabs(sample.lid2_) && sample.lq1_*sample.lq2_ < 0){
      pair1 = sample.lep1_ + sample.lep2_ ;
      m[0] = pair1.M();
      if (m[0] < 12) continue;
    }
    if (fabs(sample.lid2_) == fabs(sample.lid3_) && sample.lq2_*sample.lq3_ < 0){
      pair2 = sample.lep2_ + sample.lep3_ ;
      m[1] = pair2.M();
      if (m[1] < 12) continue;
    }
    if (fabs(sample.lid1_) == fabs(sample.lid3_) && sample.lq1_*sample.lq3_ < 0){
      pair3 = sample.lep1_ + sample.lep3_ ;
      m[2] = pair3.M();
      if (m[2] < 12) continue;
    }
    if ( (m[0] > 0 && m[0] < 12) || (m[1] > 0 && m[1] < 12) || (m[2] > 0 && m[2] < 12)) continue;
    
    LorentzVector trelep = sample.lep1_ + sample.lep2_ + sample.lep3_;
    if (fabs(trelep.M() - mz) < 10) continue; 
																																																	         
    //Get the closest to the Z mass
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
    
    //Select the different things: Z pair, extra lepton, Higgs system
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
    // double dR = 0; //dR = fabs(ROOT::Math::VectorUtil::DeltaR(sample.lep1_ ,sample.lep2_)) etc
    if (min == fabs(mz - m[0])) {  pair = pair1; mt =  sample.mt3_; tlepton = sample.lep3_;} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  sample.mt1_; tlepton = sample.lep1_;} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  sample.mt2_; tlepton = sample.lep2_;} 
    pairjet = sample.jet1_+ sample.jet2_;
    LorentzVector metvector(sample.met_*cos(sample.metPhi_), sample.met_*sin(sample.metPhi_), 0, 0);
    LorentzVector higgsSystem = tlepton + metvector + sample.jet1_+ sample.jet2_;
    LorentzVector lm = tlepton + metvector;
    
    
    double hp[5];
    hp[0] = tlepton.Px() + sample.jet1_.Px()+ sample.jet2_.Px()+ metvector.Px();
    hp[1] = tlepton.Py() + sample.jet1_.Py()+ sample.jet2_.Py()+ metvector.Py();
    hp[2] = tlepton.Pz() + sample.jet1_.Pz()+ sample.jet2_.Pz()+ metvector.Pz();
    
    //Calculate p of the neutrino using Maria's code
    double metp = 0;
    // double otherSol = 0;
    double alpha=(mw*mw-mmu*mmu)/2/tlepton.P()+(tlepton.Px()*sample.met_*cos(sample.metPhi_)+tlepton.Py()*sample.met_*sin(sample.metPhi_))/tlepton.P();
    double A=tlepton.Pz()*tlepton.Pz()/tlepton.P()/tlepton.P()-1;
    double B=2*alpha*tlepton.Pz()/tlepton.P();
    double C=alpha*alpha-(sample.met_*cos(sample.metPhi_)*sample.met_*cos(sample.metPhi_) + sample.met_*sin(sample.metPhi_)*sample.met_*sin(sample.metPhi_));
    // bool isComplex = false;
    double tmproot = B*B - 4.0*A*C;
    if (tmproot<0) { 
      //isComplex= true;
      metp = - B/(2*A); 
      //otherSol = metp;
    } else {
      // isComplex = false;
      double tmpsol1 = (-B + TMath::Sqrt(tmproot))/(2.0*A);
      double tmpsol2 = (-B - TMath::Sqrt(tmproot))/(2.0*A);
      if (TMath::Abs(tmpsol1)<TMath::Abs(tmpsol2) ) {
	metp = tmpsol1; 
	//otherSol = tmpsol2; 
      } else { 
	metp = tmpsol2; 
	//otherSol = tmpsol1; 
      }
    }
    
    
    // hp[3] = tlepton.P() + sample.jet1_.P()+ sample.jet2_.P()+ metvector.P(); //crappy solution
    hp[3] = tlepton.P() + sample.jet1_.P()+ sample.jet2_.P()+ metp;
    hp[4] = tlepton.Pt() + sample.jet1_.Pt()+ sample.jet2_.Pt()+ sample.met_;
    
    double recomh  = hp[3]*hp[3]-hp[0]*hp[0]-hp[1]*hp[1]-hp[2]*hp[2]; if(recomh  > 0) recomh  = sqrt(recomh);else recomh   = 0.0;
    double recomth = hp[4]*hp[4]-hp[0]*hp[0]-hp[1]*hp[1]; if(recomth > 0) recomth = sqrt(recomth); else recomth  = 0.0;
    
    
    //Kinematic cuts
    if (pair.M() < (mz - separation)|| pair.M() > (mz + separation)) continue; 
    if (sample.met_ < metcut) continue;
    if (mt > mtcut) continue;
    if (pairjet.M() < (mw - separationjj) || pairjet.M() > (mw + separationjj)) continue;
    
    //double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),tlepton.Phi()));
    double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),lm.Phi()));
    if (deltaPhi > phicut) continue;
    
    
    if (nsel == 2 && ntype != 49) continue; //WZ
    if (nsel == 3 && ntype != 50) continue; //ZZ
    if (nsel == 4 && ntype != 59) continue; //VVV
    if (nsel == 5 && ntype != 61) continue; //fakes
    if (nsel == 0 && ntype != 0)  continue; //data
    
    
    
      histo->Fill(recomth, weight);
    //histo->Fill(higgsSystem.M(), weight);
    // histo->Fill(1, weight);
    eventsPass+= weight;
    
    
  }    
  
  cout << "[Info:] (" << plotName << ") " <<  eventsPass << " events pass, check " << histo->GetBinContent(1) << endl;
  
  
  f_root.Write();
  f_root.Close();
  
}
示例#2
0
void Content() {
  
  bool signal = false;
  TString bgdInputFile    = "/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/backgroundA_3l.root";
  //TString bgdInputFile   =  "/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/zhww125.root";

  
  //Load datasets
  SmurfTree background;
  background.LoadTree(bgdInputFile,-1);
  background.InitTree(0);
  
  char output[200];
  sprintf(output,"rootfiles/composition_study.root");     
  TFile* outFileNjets = new TFile(output,"recreate");
 
 
  TH1D* bck_cuts = new TH1D("bck_cuts", "cuts", 10, 0, 10);
  
  bck_cuts->Sumw2();
   double eventsPassBck = 0;
   double weight = 1;
     //Backgrounds
  double bckType[62] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};

  double weiType[62] = {0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,
			0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.};
  
  TString bckName[62] = {"null","null","null","null","null","null","null","null","null","null","null","null","null","null","null",
                         "null","null","null","null","null","null","null","null","null","null","null","null","null","null","null",
                         "null","null","null","null","null","null","null","null","null","null","null","null","null","null","null",
                         "null","null","null","null","null","null","null","null","null","null","null","null","null","null","null", "null", "fakes"};
  
  bckName[0] = "data";
  bckName[1] = "qqww";
  bckName[2] = "ggww";
  bckName[43] = "ttbar";
  bckName[44] = "tw";
  bckName[46] = "dymm";
  bckName[49] = "wz";
  bckName[50] = "zz";
  bckName[51] = "wgamma";
  bckName[59] = "www";
  bckName[60] = "dyttdd";   
  int nBck=background.tree_->GetEntries();
  for (int i=0; i<nBck; ++i) {
    
    
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nBck);
    background.tree_->GetEntry(i);
 
 
    if(signal && background.processId_ != 24) continue;

    weight = 1;
    if (background.dstype_ != SmurfTree::data) weight = lumi*background.scale1fb_*background.sfWeightPU_*background.sfWeightEff_*background.sfWeightTrig_;    

    int nsel = background.dstype_;
  
    //Three real leptons MC level
    bool isRealLepton = false;
    if((TMath::Abs(background.lep1McId_) == 11 || TMath::Abs(background.lep1McId_) == 13) &&
       (TMath::Abs(background.lep2McId_) == 11 || TMath::Abs(background.lep2McId_) == 13) &&
       (TMath::Abs(background.lep3McId_) == 11 || TMath::Abs(background.lep3McId_) == 13)) isRealLepton = true; 
    if (!isRealLepton && background.dstype_ != SmurfTree::data) continue;
     
    //Check for fakes
    int nFake = 0;
    if(((background.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (background.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (background.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (background.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (background.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (background.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (background.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
   
    if (nFake){ 
      nsel = 61;
      double factor = 1;
      weight*= background.sfWeightFR_*factor;
      //if (background.dstype_ != SmurfTree::data) weight *=-1;
    }
    
    bck_cuts->Fill(0., weight);
    if (signal & nFake) continue;
    
    
    
    //2 same flavor, oppposite sign leptons + extra one
    if (background.lid3_ == background.lid2_ && background.lid3_ == background.lid1_) continue;
    if (background.lid3_ == background.lid2_ && fabs(background.lid3_) != fabs(background.lid1_)) continue;
    if (background.lid3_ == background.lid1_ && fabs(background.lid3_) != fabs(background.lid2_)) continue;
    if (background.lid2_ == background.lid1_ && fabs(background.lid2_) != fabs(background.lid3_)) continue;
    
    //Select the different things: Z pair, extra lepton, Higgs system
    int idcat = 20; // 0 = eee, 1 = eemu, 2 = mumue, 3 = mumumu
    if (fabs(background.lid1_) == 11 && fabs(background.lid2_) == 11 && fabs(background.lid3_) == 11) idcat = 0;
    else if ((fabs(background.lid1_) == 11 && fabs(background.lid2_) == 11 && fabs(background.lid3_) == 13) 
          || (fabs(background.lid1_) == 11 && fabs(background.lid2_) == 13 && fabs(background.lid3_) == 11) 
	  || (fabs(background.lid1_) == 13 && fabs(background.lid2_) == 11 && fabs(background.lid3_) == 11)) idcat = 1;
    else if ((fabs(background.lid1_) == 11 && fabs(background.lid2_) == 13 && fabs(background.lid3_) == 13) 
          || (fabs(background.lid1_) == 13 && fabs(background.lid2_) == 13 && fabs(background.lid3_) == 11) 
	  || (fabs(background.lid1_) == 13 && fabs(background.lid2_) == 11 && fabs(background.lid3_) == 13)) idcat = 2;
    else  if (fabs(background.lid1_) == 13 && fabs(background.lid2_) == 13 && fabs(background.lid3_) == 13)  idcat = 3;
    
   
       
     bck_cuts->Fill(1., weight);
    
    //At least 2 jets
    if (background.njets_ < 2 ) continue; 
    bck_cuts->Fill(2., weight);
   
    
    //Make z-compatible pairs
    double m[3] = {0, 0, 0};
    LorentzVector pair1, pair2, pair3, trilep;
    if (fabs(background.lid1_) == fabs(background.lid2_) && background.lq1_*background.lq2_ < 0){
      pair1 = background.lep1_ + background.lep2_ ;
      m[0] = pair1.M();
    }
    if (fabs(background.lid2_) == fabs(background.lid3_) && background.lq2_*background.lq3_ < 0){
      pair2 = background.lep2_ + background.lep3_ ;
      m[1] = pair2.M();
    }
    if (fabs(background.lid1_) == fabs(background.lid3_) && background.lq1_*background.lq3_ < 0){
      pair3 = background.lep1_ + background.lep3_ ;
      m[2] = pair3.M();
    }
    trilep = background.lep1_ + background.lep2_ + background.lep3_ ;

    
    //Get the closest to the Z mass
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
    
    //Select the different things: Z pair, extra lepton, Higgs system
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
    double dR = 0;
    if (min == fabs(mz - m[0])) {  pair = pair1; mt =  background.mt3_; tlepton = background.lep3_; dR = fabs(ROOT::Math::VectorUtil::DeltaR(background.lep1_ ,background.lep2_));} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  background.mt1_; tlepton = background.lep1_; dR = fabs(ROOT::Math::VectorUtil::DeltaR(background.lep2_ ,background.lep3_));} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  background.mt2_; tlepton = background.lep2_; dR = fabs(ROOT::Math::VectorUtil::DeltaR(background.lep1_ ,background.lep3_));} 
    pairjet = background.jet1_+ background.jet2_;
    LorentzVector metvector(background.met_*cos(background.metPhi_), background.met_*sin(background.metPhi_), 0, 0);
    LorentzVector higgsSystem = tlepton + metvector + background.jet1_+ background.jet2_;
    LorentzVector lm = tlepton + metvector;
   
      
    double hp[5];
    hp[0] = tlepton.Px() + background.jet1_.Px()+ background.jet2_.Px()+ metvector.Px();
    hp[1] = tlepton.Py() + background.jet1_.Py()+ background.jet2_.Py()+ metvector.Py();
    hp[2] = tlepton.Pz() + background.jet1_.Pz()+ background.jet2_.Pz()+ metvector.Pz();
    
    //Calculate p of the neutrino using Maria's code
    double metp = 0;
    double otherSol = 0;
    double alpha=(mw*mw-mmu*mmu)/2/tlepton.P()+(tlepton.Px()*background.met_*cos(background.metPhi_)+tlepton.Py()*background.met_*sin(background.metPhi_))/tlepton.P();
    double A=tlepton.Pz()*tlepton.Pz()/tlepton.P()/tlepton.P()-1;
    double B=2*alpha*tlepton.Pz()/tlepton.P();
    double C=alpha*alpha-(background.met_*cos(background.metPhi_)*background.met_*cos(background.metPhi_) + background.met_*sin(background.metPhi_)*background.met_*sin(background.metPhi_));
    bool isComplex = false;
    double tmproot = B*B - 4.0*A*C;
      if (tmproot<0) { 
        isComplex= true;
        metp = - B/(2*A); 
	otherSol = metp;
      } else {
        isComplex = false;
	double tmpsol1 = (-B + TMath::Sqrt(tmproot))/(2.0*A);
	double tmpsol2 = (-B - TMath::Sqrt(tmproot))/(2.0*A);
	if (TMath::Abs(tmpsol1)<TMath::Abs(tmpsol2) ) {
	  metp = tmpsol1; otherSol = tmpsol2; 
	} else { metp = tmpsol2; otherSol = tmpsol1; }
     }
   
    
   // hp[3] = tlepton.P() + background.jet1_.P()+ background.jet2_.P()+ metvector.P(); //crappy solution
    hp[3] = tlepton.P() + background.jet1_.P()+ background.jet2_.P()+ metp;
    hp[4] = tlepton.Pt() + background.jet1_.Pt()+ background.jet2_.Pt()+ background.met_;
    
    double recomh  = hp[3]*hp[3]-hp[0]*hp[0]-hp[1]*hp[1]-hp[2]*hp[2]; if(recomh  > 0) recomh  = sqrt(recomh);else recomh   = 0.0;
    double recomth = hp[4]*hp[4]-hp[0]*hp[0]-hp[1]*hp[1]; if(recomth > 0) recomth = sqrt(recomth); else recomth  = 0.0;
    
 
    //Kinematic cuts
    if (pair.M() < (mz - separation)|| pair.M() > (mz + separation)) continue; 
    bck_cuts->Fill(3., weight); 
       
    
    if (background.met_ < metcut) continue;
    bck_cuts->Fill(4., weight);
       
     
    
    if (mt > mtcut) continue;
    bck_cuts->Fill(5., weight);
    
    
    if (pairjet.M() < (mw - separationjj) || pairjet.M() > (mw + separationjj)) continue;
    bck_cuts->Fill(6., weight);
  
   //double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),tlepton.Phi()));
    double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),lm.Phi()));
    if (deltaPhi > phicut) continue;
    bck_cuts->Fill(7., weight);
  
    eventsPassBck += weight;
    
	     
    bckType[(int)nsel] += weight;
    weiType[(int)nsel] += weight*weight;	
   

  }
  
  cout << endl;
  cout << eventsPassBck << " background events in " << lumi << " fb" << endl; 
  cout << endl;


  
  if (verboseLevel){ 
    cout << "------------------------------------------" << endl;
    cout << "[Backgrounds (All mixed):] " << endl;
    cout << "------------------------------------------" << endl;  
    for (int i = 1; i < 9; i++){
      if (i == 1) cout << " 3 lep:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 2) cout << " OSSF:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 3) cout << " 2 jet:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 4) cout << " mll:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 5) cout << " met:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 6) cout << " mt:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 7) cout << " mjj:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
      if (i == 8) cout << " phi:\t\t" <<  bck_cuts->GetBinContent(i) << " +/-  " <<  bck_cuts->GetBinError(i)  << endl;
    }
    cout << endl;
    cout << "[Breakdown:] " << endl;
    for(int i=0; i<62; i++){
      if(bckType[i] != 0 )
	cout << i <<"\t" << bckName[i] << ":\t\t" << bckType[i] << "+-" << sqrt(weiType[i]) <<endl;
    }
    cout << "------------------------------------------" << endl; 
  }
  
  outFileNjets->Write();
  outFileNjets->Close();
  
}
示例#3
0
double Object::DeltaR( Object * other_object ) { 
  double deta = Eta() - other_object -> Eta();
  double dphi = DeltaPhi ( other_object );
  double dr = sqrt ( deta * deta + dphi * dphi );
  return dr;
}
示例#4
0
float Object::DeltaR( Object * other_object ) { 
  float deta = Eta() - other_object -> Eta();
  float dphi = DeltaPhi ( other_object );
  float dr = sqrt ( deta * deta + dphi * dphi );
  return dr;
}
示例#5
0
文件: doWZ.C 项目: rebecacern/ZH3l
void doWZ(int cem = 8, int mode = 0){

  char plotName[300];
  sprintf(plotName,"test");
  
  sprintf(plotName,"WZ");
  bool isBackground = true;
  bool isData = false;
  int nsel = 2;
  
  char myRootFile[300];
  if (cem != 7 && cem !=8) cem = 8;
  double lumi = lumi8;
  if (cem == 8){
    sprintf(myRootFile,"/data/smurf/data/Run2012_Summer12_SmurfV9_53X/mitf-alljets/backgroundA_3l.root");
  } else {
    lumi = lumi7;
    sprintf(myRootFile,"/data/smurf/data/Run2011_Fall11_SmurfV9_42X/mitf-alljets/backgroundA_3l.root");
  }
  //Load datasets
  SmurfTree sample;
  sample.LoadTree(myRootFile,-1);
  sample.InitTree(0);

  // Prepare putput file
  char rootFile[300];
  if (cem == 8) sprintf(rootFile,"WZ8TeV.root");
  else sprintf(rootFile,"WZ7TeV.root");

  TFile f_root(rootFile, "RECREATE");
  
  // Prepare histograms
  char title[300];
  
  sprintf(title,"histogram");
  TH1F* histo = new TH1F( title, " ", nbins, nbinlow, nbinhigh);
  histo->Sumw2();

  //Prepare useful things
  double weight = 1;
  double eventsPass = 0;
  
  int nSample=sample.tree_->GetEntries();
   for (int i=0; i<nSample; ++i) {
    
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nSample);
    sample.tree_->GetEntry(i);
    
      //Modes, 0 = all, 1 = eee, 2 = eem, 3 = emm, 4 = mmm
    if (mode == 1 && (abs(sample.lid1_)!= 11 || abs(sample.lid2_) != 11 || abs(sample.lid3_) != 11)) continue;
    if (mode == 2 && 
       ((abs(sample.lid1_)!= abs(sample.lid2_) && abs(sample.lid1_) != abs(sample.lid3_) && abs(sample.lid1_) == 11) ||
        (abs(sample.lid2_)!= abs(sample.lid1_) && abs(sample.lid2_) != abs(sample.lid3_) && abs(sample.lid2_) == 11) ||
	(abs(sample.lid3_)!= abs(sample.lid1_) && abs(sample.lid3_) != abs(sample.lid2_) && abs(sample.lid3_) == 11) ||
	(abs(sample.lid1_) == abs(sample.lid2_) && abs(sample.lid1_) == abs(sample.lid3_)))) continue;
    if (mode == 3 && 
       ((abs(sample.lid1_)!= abs(sample.lid2_) && abs(sample.lid1_) != abs(sample.lid3_) && abs(sample.lid1_) == 13) ||
        (abs(sample.lid2_)!= abs(sample.lid1_) && abs(sample.lid2_) != abs(sample.lid3_) && abs(sample.lid2_) == 13) ||
	(abs(sample.lid3_)!= abs(sample.lid1_) && abs(sample.lid3_) != abs(sample.lid2_) && abs(sample.lid3_) == 13) ||
	(abs(sample.lid1_) == abs(sample.lid2_) && abs(sample.lid1_) == abs(sample.lid3_)))) continue;
    if (mode == 4 && (abs(sample.lid1_)!= 13 || abs(sample.lid2_) != 13 || abs(sample.lid3_) != 13)) continue;
   

    
    weight = 1;
    if (!isData && sample.dstype_ != SmurfTree::data) weight = lumi*sample.scale1fb_*sample.sfWeightPU_*sample.sfWeightEff_*sample.sfWeightTrig_;    
   
   //Three real leptons MC level
    if (!isData){
      bool isRealLepton = false;
      if((TMath::Abs(sample.lep1McId_) == 11 || TMath::Abs(sample.lep1McId_) == 13) &&
         (TMath::Abs(sample.lep2McId_) == 11 || TMath::Abs(sample.lep2McId_) == 13) &&
         (TMath::Abs(sample.lep3McId_) == 11 || TMath::Abs(sample.lep3McId_) == 13)) isRealLepton = true; 
      if (!isRealLepton && !isBackground) continue; //signal
      if (!isRealLepton && sample.dstype_ != SmurfTree::data) continue; //background
    }
    
    int ntype = sample.dstype_;
    
     //Check for fakes
    int nFake = 0;
    if(((sample.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (sample.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (sample.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (sample.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((sample.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (sample.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if (nFake !=0 && !isBackground) continue; 
    if (nFake !=0){ 
      ntype = 61;
      weight*= sample.sfWeightFR_*factor;
      //if (sample.dstype_ != SmurfTree::data) weight *=-1;
    }
    
    if (nsel == 2 && ntype != 49) continue; //WZ
    
    //2 same flavor, oppposite sign leptons + extra one
    if (sample.lid3_ == sample.lid2_ && sample.lid3_ == sample.lid1_) continue;
    if (sample.lid3_ == sample.lid2_ && fabs(sample.lid3_) != fabs(sample.lid1_)) continue;
    if (sample.lid3_ == sample.lid1_ && fabs(sample.lid3_) != fabs(sample.lid2_)) continue;
    if (sample.lid2_ == sample.lid1_ && fabs(sample.lid2_) != fabs(sample.lid3_)) continue;
    
    // At least 2 jets 
    if (sample.njets_ < 2) continue; 
    if (tau && (sample.jet1McId_ == 100 || sample.jet2McId_ == 100 || sample.jet3McId_ == 100 || sample.jet4McId_ == 100)) continue;

       //Make z-compatible pairs
    double m[3] = {-1, -1, -1};
    LorentzVector pair1, pair2, pair3;
    if (fabs(sample.lid1_) == fabs(sample.lid2_) && sample.lq1_*sample.lq2_ < 0){
      pair1 = sample.lep1_ + sample.lep2_ ;
      m[0] = pair1.M();
      if (m[0] < 12) continue;
    }
    if (fabs(sample.lid2_) == fabs(sample.lid3_) && sample.lq2_*sample.lq3_ < 0){
      pair2 = sample.lep2_ + sample.lep3_ ;
      m[1] = pair2.M();
      if (m[1] < 12) continue;
    }
    if (fabs(sample.lid1_) == fabs(sample.lid3_) && sample.lq1_*sample.lq3_ < 0){
      pair3 = sample.lep1_ + sample.lep3_ ;
      m[2] = pair3.M();
      if (m[2] < 12) continue;
    }
    if ( (m[0] > 0 && m[0] < 12) || (m[1] > 0 && m[1] < 12) || (m[2] > 0 && m[2] < 12)) continue;
    				
   LorentzVector trelep = sample.lep1_ + sample.lep2_ + sample.lep3_;
   if (fabs(trelep.M() - mz) < 10) continue; 
						
    //Get the closest to the Z mass
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
   
    //Select the different things: Z pair, extra lepton, Higgs system
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
   // double dR = 0; //dR = fabs(ROOT::Math::VectorUtil::DeltaR(sample.lep1_ ,sample.lep2_)) etc
    if (min == fabs(mz - m[0])) {  pair = pair1; mt =  sample.mt3_; tlepton = sample.lep3_;} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  sample.mt1_; tlepton = sample.lep1_;} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  sample.mt2_; tlepton = sample.lep2_;} 
    pairjet = sample.jet1_+ sample.jet2_;
    LorentzVector metvector(sample.met_*cos(sample.metPhi_), sample.met_*sin(sample.metPhi_), 0, 0);
    LorentzVector higgsSystem = tlepton + metvector + sample.jet1_+ sample.jet2_;
    LorentzVector lm = tlepton + metvector;
   
      
    double hp[5];
    hp[0] = tlepton.Px() + sample.jet1_.Px()+ sample.jet2_.Px()+ metvector.Px();
    hp[1] = tlepton.Py() + sample.jet1_.Py()+ sample.jet2_.Py()+ metvector.Py();
    hp[2] = tlepton.Pz() + sample.jet1_.Pz()+ sample.jet2_.Pz()+ metvector.Pz();
    
    //Calculate p of the neutrino using Maria's code
    double metp = 0;
   // double otherSol = 0;
    double alpha=(mw*mw-mmu*mmu)/2/tlepton.P()+(tlepton.Px()*sample.met_*cos(sample.metPhi_)+tlepton.Py()*sample.met_*sin(sample.metPhi_))/tlepton.P();
    double A=tlepton.Pz()*tlepton.Pz()/tlepton.P()/tlepton.P()-1;
    double B=2*alpha*tlepton.Pz()/tlepton.P();
    double C=alpha*alpha-(sample.met_*cos(sample.metPhi_)*sample.met_*cos(sample.metPhi_) + sample.met_*sin(sample.metPhi_)*sample.met_*sin(sample.metPhi_));
   // bool isComplex = false;
    double tmproot = B*B - 4.0*A*C;
      if (tmproot<0) { 
        //isComplex= true;
        metp = - B/(2*A); 
	//otherSol = metp;
      } else {
       // isComplex = false;
	double tmpsol1 = (-B + TMath::Sqrt(tmproot))/(2.0*A);
	double tmpsol2 = (-B - TMath::Sqrt(tmproot))/(2.0*A);
	if (TMath::Abs(tmpsol1)<TMath::Abs(tmpsol2) ) {
	  metp = tmpsol1; 
	  //otherSol = tmpsol2; 
	} else { 
	  metp = tmpsol2; 
	  //otherSol = tmpsol1; 
	}
     }
   
    
   // hp[3] = tlepton.P() + sample.jet1_.P()+ sample.jet2_.P()+ metvector.P(); //crappy solution
    hp[3] = tlepton.P() + sample.jet1_.P()+ sample.jet2_.P()+ metp;
    hp[4] = tlepton.Pt() + sample.jet1_.Pt()+ sample.jet2_.Pt()+ sample.met_;
    
    double recomh  = hp[3]*hp[3]-hp[0]*hp[0]-hp[1]*hp[1]-hp[2]*hp[2]; if(recomh  > 0) recomh  = sqrt(recomh);else recomh   = 0.0;
    double recomth = hp[4]*hp[4]-hp[0]*hp[0]-hp[1]*hp[1]; if(recomth > 0) recomth = sqrt(recomth); else recomth  = 0.0;
    
   
    //Kinematic cuts
    if (pair.M() < (mz - separation)|| pair.M() > (mz + separation)) continue; 
    if (sample.met_ < metcut) continue;
    if (mt > mtcut) continue;
    if (pairjet.M() < (mw - separationjj) || pairjet.M() > (mw + separationjj)) continue;
    
   //double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),tlepton.Phi()));
    double deltaPhi = fabs(DeltaPhi(pairjet.Phi(),lm.Phi()));
    if (deltaPhi > phicut) continue;
   
    
    histo->Fill(recomth, weight);
    //histo->Fill(higgsSystem.M(), weight);
    eventsPass+= weight;
     
  
  }    
  
   cout << "[Info:] (" << plotName << ") " <<  eventsPass << " events pass " << endl;
  
  
    f_root.Write();
    f_root.Close();
 
}
void analysisClass::Loop()
{
  std::cout << "analysisClass::Loop() begins" <<std::endl; 

  if (fChain == 0) return;

  //////////book histos here


  int   Nbins_METSumET = 500;
  float Max_METSumET = 500;

  //calomet
  TH1F *h_calometPt   = new TH1F ("h_calometPt","h_calometPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_calometPxy   = new TH1F ("h_calometPxy","h_calometPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_caloSumet   = new TH1F ("h_caloSumet","h_caloSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_caloMetOSumet   = new TH1F ("h_caloMetOSumet","h_caloMetOSumet",50,0,1.);

  h_calometPt->Sumw2();
  h_calometPxy->Sumw2();
  h_caloSumet->Sumw2();
  h_caloMetOSumet->Sumw2();

  //calomet in dijets (loose)
  TH1F *h_dijetLoose_calometPt   = new TH1F ("h_dijetLoose_calometPt","h_dijetLoose_calometPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_calometPxy   = new TH1F ("h_dijetLoose_calometPxy","h_dijetLoose_calometPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_caloSumet   = new TH1F ("h_dijetLoose_caloSumet","h_dijetLoose_caloSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_caloMetOSumet   = new TH1F ("h_dijetLoose_caloMetOSumet","h_dijetLoose_caloMetOSumet",50,0,1.);

  h_dijetLoose_calometPt->Sumw2();
  h_dijetLoose_calometPxy->Sumw2();
  h_dijetLoose_caloSumet->Sumw2();
  h_dijetLoose_caloMetOSumet->Sumw2();

  //calomet in dijets (tight)
  TH1F *h_dijetTight_calometPt   = new TH1F ("h_dijetTight_calometPt","h_dijetTight_calometPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_calometPxy   = new TH1F ("h_dijetTight_calometPxy","h_dijetTight_calometPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_caloSumet   = new TH1F ("h_dijetTight_caloSumet","h_dijetTight_caloSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_caloMetOSumet   = new TH1F ("h_dijetTight_caloMetOSumet","h_dijetTight_caloMetOSumet",50,0,1.);

  h_dijetTight_calometPt->Sumw2();
  h_dijetTight_calometPxy->Sumw2();
  h_dijetTight_caloSumet->Sumw2();
  h_dijetTight_caloMetOSumet->Sumw2();

  //tcmet
  TH1F *h_tcmetPt   = new TH1F ("h_tcmetPt","h_tcmetPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_tcmetPxy   = new TH1F ("h_tcmetPxy","h_tcmetPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_tcSumet   = new TH1F ("h_tcSumet","h_tcSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_tcMetOSumet   = new TH1F ("h_tcMetOSumet","h_tcMetOSumet",50,0,1.);

  h_tcmetPt->Sumw2();
  h_tcmetPxy->Sumw2();
  h_tcSumet->Sumw2();
  h_tcMetOSumet->Sumw2();

  //tcmet in dijet (loose)
  TH1F *h_dijetLoose_tcmetPt   = new TH1F ("h_dijetLoose_tcmetPt","h_dijetLoose_tcmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_tcmetPxy   = new TH1F ("h_dijetLoose_tcmetPxy","h_dijetLoose_tcmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_tcSumet   = new TH1F ("h_dijetLoose_tcSumet","h_dijetLoose_tcSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_tcMetOSumet   = new TH1F ("h_dijetLoose_tcMetOSumet","h_dijetLoose_tcMetOSumet",50,0,1.);

  h_dijetLoose_tcmetPt->Sumw2();
  h_dijetLoose_tcmetPxy->Sumw2();
  h_dijetLoose_tcSumet->Sumw2();
  h_dijetLoose_tcMetOSumet->Sumw2();

  //tcmet in dijet (tight)
  TH1F *h_dijetTight_tcmetPt   = new TH1F ("h_dijetTight_tcmetPt","h_dijetTight_tcmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_tcmetPxy   = new TH1F ("h_dijetTight_tcmetPxy","h_dijetTight_tcmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_tcSumet   = new TH1F ("h_dijetTight_tcSumet","h_dijetTight_tcSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_tcMetOSumet   = new TH1F ("h_dijetTight_tcMetOSumet","h_dijetTight_tcMetOSumet",50,0,1.);

  h_dijetTight_tcmetPt->Sumw2();
  h_dijetTight_tcmetPxy->Sumw2();
  h_dijetTight_tcSumet->Sumw2();
  h_dijetTight_tcMetOSumet->Sumw2();

  //pfmet
  TH1F *h_pfmetPt   = new TH1F ("h_pfmetPt","h_pfmetPt",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_pfmetPxy   = new TH1F ("h_pfmetPxy","h_pfmetPxy",Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_pfSumet   = new TH1F ("h_pfSumet","h_pfSumet",Nbins_METSumET,0,Max_METSumET);
  TH1F *h_pfMetOSumet   = new TH1F ("h_pfMetOSumet","h_pfMetOSumet",50,0,1.);

  h_pfmetPt->Sumw2();
  h_pfmetPxy->Sumw2();
  h_pfSumet->Sumw2();
  h_pfMetOSumet->Sumw2();

  //pfmet in dijet (loose)
  TH1F *h_dijetLoose_pfmetPt   = new TH1F ("h_dijetLoose_pfmetPt","h_dijetLoose_pfmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_pfmetPxy   = new TH1F ("h_dijetLoose_pfmetPxy","h_dijetLoose_pfmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetLoose_pfSumet   = new TH1F ("h_dijetLoose_pfSumet","h_dijetLoose_pfSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetLoose_pfMetOSumet   = new TH1F ("h_dijetLoose_pfMetOSumet","h_dijetLoose_pfMetOSumet",50,0,1.);

  h_dijetLoose_pfmetPt->Sumw2();
  h_dijetLoose_pfmetPxy->Sumw2();
  h_dijetLoose_pfSumet->Sumw2();
  h_dijetLoose_pfMetOSumet->Sumw2();

  //pfmet in dijet (tight)
  TH1F *h_dijetTight_pfmetPt   = new TH1F ("h_dijetTight_pfmetPt","h_dijetTight_pfmetPt",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_pfmetPxy   = new TH1F ("h_dijetTight_pfmetPxy","h_dijetTight_pfmetPxy",0.5*Nbins_METSumET,-Max_METSumET/2,Max_METSumET/2);
  TH1F *h_dijetTight_pfSumet   = new TH1F ("h_dijetTight_pfSumet","h_dijetTight_pfSumet",0.5*Nbins_METSumET,0,Max_METSumET);
  TH1F *h_dijetTight_pfMetOSumet   = new TH1F ("h_dijetTight_pfMetOSumet","h_dijetTight_pfMetOSumet",50,0,1.);

  h_dijetTight_pfmetPt->Sumw2();
  h_dijetTight_pfmetPxy->Sumw2();
  h_dijetTight_pfSumet->Sumw2();
  h_dijetTight_pfMetOSumet->Sumw2();

  //Vertex
  TH1F *h_AllVertexZ    = new TH1F ("h_AllVertexZ","h_AllVertexZ",100,-100,100);
  TH1F *h_AllVertexChi2 = new TH1F ("h_AllVertexChi2","h_AllVertexChi",100,0,100);
  TH1F *h_AllVertexNDOF = new TH1F ("h_AllVertexNDOF","h_AllVertexNDOF",50,0,50);
  TH1F *h_AllVertexChi2_0_NDOF = new TH1F ("h_AllVertexChi2_0_NDOF","h_AllVertexChi2_0_NDOF",200,0,40);
  TH1F *h_AllVertexNtrk = new TH1F ("h_AllVertexNtrk","h_AllVertexNtrk",50,0,50);
  TH1F *h_AllNVertex    = new TH1F ("h_AllNVertex","h_AllNVertex",50,0,50);
  TH1F *h_VertexSumpt   = new TH1F ("h_VertexSumpt","h_VertexSumpt",200,0,200);
  TH1F *h_VertexSumptW5 = new TH1F ("h_VertexSumptW5","h_VertexSumptW5",200,0,200);

  h_AllVertexZ->Sumw2();
  h_AllVertexChi2->Sumw2(); 
  h_AllVertexNDOF->Sumw2(); 
  h_AllVertexChi2_0_NDOF->Sumw2();
  h_AllVertexNtrk->Sumw2(); 
  h_AllNVertex->Sumw2();
  h_VertexSumpt->Sumw2(); 
  h_VertexSumptW5->Sumw2(); 

  /////////initialize variables
  float HFEnergyCut = getPreCutValue1("HFEnergyCut");

  //////////////////////////////
  ///// Goood Run List  ////////
  //////////////////////////////
  int goodruns[] = {123596, 123615, 123732, 123815, 123818,
                    123908, 124008, 124009, 124020, 124022,
                    124023, 124024, 124025, 124027, 124030/*,
							    124120*/};
                   //124120 at 2360 GeV

   int goodLSmin[] = {2, 70, 62, 8, 2,
                      2, 1, 1, 12, 66,
                      38, 2, 5, 24, 2/*,
				       1*/};

   int goodLSmax[] = {9999, 9999, 109, 9999, 42,
                      12, 1, 68, 94, 179,
                      9999, 83, 13, 9999, 9999/*,
						9999*/};


  // For S9/S1 flagging
  double slopes[] = {0.0171519,0.0245339,0.0311146,0.0384983,0.0530911,0.0608012,0.0789118,0.084833,0.0998253,0.118896,0.0913756,0.0589927};

  Long64_t nentries = fChain->GetEntriesFast();
  std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl; 

  Long64_t nb = 0;

  for (Long64_t jentry=0; jentry<nentries;jentry++) 
    //for (Long64_t jentry=0; jentry<2000;jentry++) 
    {
      Long64_t ientry = LoadTree(jentry);
      if (ientry < 0) break;
      //       if(jentry>300000) break;
      nb = fChain->GetEntry(jentry); 
      
      if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl; 
      ////////////////////// User's code starts here ///////////////////////
      

      //## Check if the run is in the list of good runs
      int pass_GoodRunList = 0;
      if(isData==1)
        {
          for (int i = 0; i < sizeof(goodruns)/sizeof(int) ; i++) {
            if (goodruns[i] == run && ls >= goodLSmin[i] && ls <= goodLSmax[i]) {
              pass_GoodRunList = 1;
              break;
            }
          }
        }
      else if(isData == 0)
        {
          pass_GoodRunList = 1;
        }

      //#####################
      //## Trigger selection
      //#####################

      int pass_BPTX              = 0;
      int pass_BSC_MB            = 0;
      int pass_BSC_BeamHaloVeto  = 0;
      int pass_PhysicsBit        = 0;

      //## pass_BPTX - Two beams crossing at CMS (only Data)
      if(isData==1)
	{
	  if(l1techbits->at(0)==1)
	    pass_BPTX = 1;
	}
      else if(isData==0)
	pass_BPTX = 1;
      
      //## pass_BSC_MB - BSC MinBias triggers firing (both Data and MC)
      if( l1techbits->at(40)==1 || l1techbits->at(41)==1 ) 
	pass_BSC_MB = 1;
      
      //## pass_BSC_BeamHaloVeto - Veto on BSC Beam Halo Triggers firing
      if(isData==1)
	{
	  pass_BSC_BeamHaloVeto = 1;
	  if( l1techbits->at(36) == 1 || l1techbits->at(37) == 1 || l1techbits->at(38) == 1 || l1techbits->at(39) == 1 )
	    pass_BSC_BeamHaloVeto = 0;
	}
      else if(isData == 0)
	pass_BSC_BeamHaloVeto = 1;

      //## pass_PhysicsBit - HLT Physics Declared bit set 
      if(isData==1)
	{
	  if(hltbits->at(116)==1)
	    pass_PhysicsBit = 1;
	}
      else if(isData == 0)
	pass_PhysicsBit = 1;

      //#####################
      //## Reco-based filters
      //#####################

      //pass_HFEnergyCut
      int pass_HFEnergyCut = 0;
      int pass_HFEnergyCut_Plus = 0;
      int pass_HFEnergyCut_Minus = 0;
      
      for (int i = 0; i<int(CaloTowersEmEt->size()); i++)
	{

	  if( fabs(CaloTowersIeta->at(i)) > 29 ) //HF only
	    {
	 
	      TVector3 * towerL = new TVector3;
	      TVector3 * towerS = new TVector3;
	      towerL->SetPtEtaPhi(CaloTowersEmEt->at(i)+0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));
	      towerS->SetPtEtaPhi(0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));

	      // energy on plus side	    
	      if( CaloTowersIeta->at(i) > 0 && ( towerL->Mag() + towerS->Mag() ) > HFEnergyCut )
		{
		  pass_HFEnergyCut_Plus=1;		  
		  if( pass_HFEnergyCut_Plus == 1 && pass_HFEnergyCut_Minus == 1 )
		    {
		      pass_HFEnergyCut = 1;
		      break;
		    }
		}

	      // energy on minus side	    
	      if( CaloTowersIeta->at(i) < 0 && ( towerL->Mag() + towerS->Mag() ) > HFEnergyCut )
		{
		  pass_HFEnergyCut_Minus=1;
		  if( pass_HFEnergyCut_Plus == 1 && pass_HFEnergyCut_Minus == 1 )
		    {
		      pass_HFEnergyCut = 1;
		      break;
		    }
		}
			
	      delete towerL;
	      delete towerS;
	
	    }//end loop over calotowers in HF

	}//end loop over calotowers
      

      //pass_GoodVertex 
      //https://twiki.cern.ch/twiki/bin/viewauth/CMS/TRKPromptFeedBack#Event_and_track_selection_recipe
      int pass_GoodVertex = 0;

      if(vertexZ->size() == 0) pass_GoodVertex = 0;
      for (int ii=0; ii<vertexZ->size(); ii++)
	if( vertexChi2->at(ii) != 0. && vertexNDF->at(ii) != 0 && vertexNDF->at(ii) >= 5 && fabs(vertexZ->at(ii)) <= 15. )
	  {
	    pass_GoodVertex = 1;
	    break;
	  }
      
      //## pass_MonsterTRKEventVeto - "Monster Events" Tracker Filter
      //see https://twiki.cern.ch/twiki/bin/viewauth/CMS/TRKPromptFeedBack#Event_and_track_selection_recipe
      int pass_MonsterTRKEventVeto = 0;

      int num_good_tracks = 0;
      float fraction      = 0.;
      float thresh        = 0.25;
	 
      if(tracksPt->size()<=10)
	{
	  pass_MonsterTRKEventVeto = 1;
	}//<=10 tracks	    
      else if(tracksPt->size()>10)
	{
	  for (int ii=0; ii<tracksPt->size(); ii++)
	    {
	      int trackFlags = tracksQuality->at(ii);
	      int highPurityFlag = 3;
	      if( ( trackFlags & 1 << highPurityFlag) > 0)
		{
		  num_good_tracks++;		      
		  fraction = (float)num_good_tracks / (float)tracksPt->size();
		  
		  if( fraction > thresh ) 
		    pass_MonsterTRKEventVeto = 1;
		}
	    }
	}//>10 tracks	    

      //## pass_HFPMTHitVeto - Reject anomalous events in HF due to PMT hits - 
      int pass_HFPMTHitVeto_tcMET   = 1;

      //masked towers
      // HF(37,67,1): STATUS = 0x8040
      // HF(29,67,1): STATUS = 0x40
      // HF(35,67,1): STATUS = 0x8040
      // HF(29,67,2): STATUS = 0x40
      // HF(30,67,2): STATUS = 0x8040
      // HF(32,67,2): STATUS = 0x8040
      // HF(36,67,2): STATUS = 0x8040
      // HF(38,67,2): STATUS = 0x8040

      for (int i = 0; i<int(CaloTowersEmEt->size()); i++)
	{
	  if( fabs(CaloTowersIeta->at(i)) > 29 ) //HF only
	    {
	      TVector3 * towerL = new TVector3;
	      TVector3 * towerS = new TVector3;
	      towerL->SetPtEtaPhi(CaloTowersEmEt->at(i)+0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));
	      towerS->SetPtEtaPhi(0.5*CaloTowersHadEt->at(i), CaloTowersEta->at(i), CaloTowersPhi->at(i));

	      //tower masked
	      int isLongMasked=0;
	      int isShortMasked=0;
	      if( CaloTowersIeta->at(i) == 37 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;
	      if( CaloTowersIeta->at(i) == 29 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;
	      if( CaloTowersIeta->at(i) == 35 && CaloTowersIphi->at(i) == 67)
		isLongMasked = 1;

	      if( CaloTowersIeta->at(i) == 29 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 30 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 32 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 36 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;
	      if( CaloTowersIeta->at(i) == 38 && CaloTowersIphi->at(i) == 67)
		isShortMasked = 1;

	      //-- a la tcMET		
	      float ET_cut_tcMET      = 5; 
	      float Rplus_cut_tcMET   = 0.99; 
	      float Rminus_cut_tcMET  = 0.8; 
	      Float_t ratio_tcMET     = -1.5;	      
	      if(  ( CaloTowersEmEt->at(i) + CaloTowersHadEt->at(i) ) > ET_cut_tcMET 
		   && isShortMasked==0 && isLongMasked==0 )
		{		
		  ratio_tcMET = ( fabs(towerL->Mag()) - fabs(towerS->Mag()) ) 
		    / ( fabs(towerL->Mag()) + fabs(towerS->Mag()) );

		  if( ratio_tcMET < -Rminus_cut_tcMET || ratio_tcMET > Rplus_cut_tcMET )
		    pass_HFPMTHitVeto_tcMET = 0; 
		}
	      delete towerL;
	      delete towerS;
	    }
	}


 //## pass_HFPMTHitVeto from 2010 HCAL DPG studies - Reject anomalous events in HF due to PMT hits - 
      int pass_HFPMTHitVeto_S9S1   = 1;
      int pass_HFPMTHitVeto_PET   = 1;

      for (int i = 0; i<int(PMTnoiseRecHitET->size()); i++)
	{
	  
	  bool isPMThit = false;
	  double energy = PMTnoiseRecHitEnergy->at(i);
	  double ET = PMTnoiseRecHitET->at(i);
	  double partenergy = PMTnoiseRecHitPartEnergy->at(i);
	  double sum4Long = PMTnoiseRecHitSum4Long->at(i);
	  double sum4Short = PMTnoiseRecHitSum4Short->at(i);
	  int ieta = PMTnoiseRecHitIeta->at(i);
	  int iphi = PMTnoiseRecHitIphi->at(i);
	  double phi = ((2*3.14159)/72) * iphi;
	  if(abs(ieta)>39) phi = ((2*3.14159)/72) * (iphi+1);
	  int depth = PMTnoiseRecHitDepth->at(i);

	  //skip the RecHit if it's just a pedestal noise
	  if( (depth==1 && energy<1.2) || (depth==2 && energy<1.8) ) continue;
               
	  //--> NOTE : all crystals has been removed in 2010 --> check if there is some channel with black tape on the window
	  //masked towers
	  // HF(37,67,1): STATUS = 0x8040
	  // HF(29,67,1): STATUS = 0x40
	  // HF(35,67,1): STATUS = 0x8040
	  // HF(29,67,2): STATUS = 0x40
	  // HF(30,67,2): STATUS = 0x8040
	  // HF(32,67,2): STATUS = 0x8040
	  // HF(36,67,2): STATUS = 0x8040
	  // HF(38,67,2): STATUS = 0x8040

	  //tower masked
	  int isLongMasked=0;
	  int isShortMasked=0;
	  if( (ieta==37 || ieta==29 || ieta==35) && iphi==67)
	    isLongMasked = 1;

	  if( (ieta==29 || ieta==30 || ieta==32 || ieta==36 || ieta==38) && iphi==67)
	    isShortMasked = 1;
               
	  //skip the RecHit if it's in the tower with crystals mounted
	  if( isLongMasked==1 || isShortMasked==1 ) continue;
               
	  //R = L-S/L+S
	  double R = PMTnoiseRecHitRValue->at(i);
               
	  //S9/S1
	  double S9oS1 = ( partenergy + sum4Long + sum4Short ) / energy;
               
	  // For S9/S1 flagging
	  double slope = (0.3084-0.02577*abs(ieta)+0.0005351*ieta*ieta);
	  if( abs(ieta)>39 ) slope = slopes[abs(ieta)-30];
	  double intercept = -slope*log((162.4-10.19*abs(ieta)+0.21*ieta*ieta));
                
	  //## identify HF spikes

	  //long fibers
	  if( depth==1 ) 
	    {

	      //PET
	      if( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && R>0.98 ) 
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_PET = 0;
		}
	      
	      //S9/S1
	      if( abs(ieta)==29 && ( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && R>0.98 ) ) //special case (as PET)
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_S9S1 = 0;		  
		}
	      else if( abs(ieta)>29 && ( energy>(162.4-10.19*abs(ieta)+0.21*ieta*ieta) && S9oS1<(intercept+slope*log(energy)) ) )
		{ 
		  isPMThit = true;
		  pass_HFPMTHitVeto_S9S1 = 0;		  
		}
	      
	    }
	  //short fibers (same cut, PET-based, for both PET and S9/S1 flags)
	  else if( depth==2 && energy>(129.9-6.61*abs(ieta)+0.1153*ieta*ieta) && R<-0.98 ) 
	    {
	      isPMThit = true;
	      pass_HFPMTHitVeto_PET = 0;
	      pass_HFPMTHitVeto_S9S1 = 0;
	    }
	  
	}//end loop over HF rechits




      //ECAL spikes EB
      int pass_ECALSpikesVeto_tcMET = 1;

      for (int ii=0; ii<ECALnoiseECalEBSeedEnergy->size(); ii++)
	{

	  //-- seed crystal info --
	  float seedEnergy = ECALnoiseECalEBSeedEnergy->at(ii);
	  float seedet = ECALnoiseECalEBSeedEnergy->at(ii) / cosh(ECALnoiseECalEBSeedEta->at(ii));
	  float seedex = seedet * cos( ECALnoiseECalEBSeedPhi->at(ii) );
	  float seedey = seedet * sin( ECALnoiseECalEBSeedPhi->at(ii) );
	  float seedeta = ECALnoiseECalEBSeedEta->at(ii);
	  float seedphi = ECALnoiseECalEBSeedPhi->at(ii);

	  //S4/S1 vs ET (a la tcMET)
	  float S4_tcMET = 0.;
	  S4_tcMET = ECALnoiseECalEBSeedERight->at(ii) 
	    + ECALnoiseECalEBSeedELeft->at(ii)
	    + ECALnoiseECalEBSeedETop->at(ii)
	    + ECALnoiseECalEBSeedEBottom->at(ii);

	  float S4_tcMEToverS1 = S4_tcMET / seedEnergy;

	  if(seedet > 5. && S4_tcMEToverS1 < 0.05)
	    pass_ECALSpikesVeto_tcMET = 0;
	}

      //############################
      //## Calculate Reco Quantities 
      //############################

      //=================================================================

      // Set the evaluation of the cuts to false and clear the variable values and filled status
      resetCuts();

      // Set the value of the variableNames listed in the cutFile to their current value
      fillVariableWithValue("pass_GoodRunList", pass_GoodRunList);
      fillVariableWithValue("pass_BPTX", pass_BPTX);
      fillVariableWithValue("pass_BSC_MB", pass_BSC_MB);
      fillVariableWithValue("pass_BSC_BeamHaloVeto", pass_BSC_BeamHaloVeto);
      fillVariableWithValue("pass_PhysicsBit", pass_PhysicsBit);
      fillVariableWithValue("pass_GoodVertex", pass_GoodVertex);
      fillVariableWithValue("pass_MonsterTRKEventVeto", pass_MonsterTRKEventVeto);
      fillVariableWithValue("pass_HFEnergyCut", pass_HFEnergyCut);

      fillVariableWithValue("pass_ECALSpikesVeto_tcMET", pass_ECALSpikesVeto_tcMET);
      fillVariableWithValue("pass_HFPMTHitVeto_tcMET", pass_HFPMTHitVeto_tcMET);

      //HF cleaning - S9/S1 and PET - HCAL DPG 2010
      fillVariableWithValue("pass_HFPMTHitVeto_S9S1", pass_HFPMTHitVeto_S9S1);
      fillVariableWithValue("pass_HFPMTHitVeto_PET", pass_HFPMTHitVeto_PET);

      // Evaluate cuts (but do not apply them)
      evaluateCuts();

      //###########################
      //## Start filling histograms
      //###########################


      if( passedAllPreviousCuts("pass_GoodVertex") )
	{
	  //Vertex
	  h_AllNVertex->Fill(vertexZ->size());
	  for (int ii=0; ii<vertexZ->size(); ii++)
	    {
	      if(vertexNTracksW5->at(ii)==0)
		continue;

	      h_AllVertexZ->Fill(vertexZ->at(ii));
	      h_AllVertexChi2->Fill(vertexChi2->at(ii));
	      h_AllVertexNDOF->Fill(vertexNDF->at(ii));
	      h_AllVertexNtrk->Fill(vertexNTracks->at(ii));
	      if(vertexNDF->at(ii)!=0)
		h_AllVertexChi2_0_NDOF->Fill( vertexChi2->at(ii) / vertexNDF->at(ii) );
	      
	      h_VertexSumpt->Fill(vertexSumPt->at(ii));
	      h_VertexSumptW5->Fill(vertexSumPtW5->at(ii));
	    }
	}
      
      if( passedCut("0") && pass_HFPMTHitVeto_tcMET == 1 && pass_ECALSpikesVeto_tcMET == 1 )
	{
	  //#########################
	  //## inclusive MET
	  //#########################
	  h_calometPt->Fill( calometPt->at(0) );
	  h_calometPxy->Fill( calometPx->at(0) ); 
	  h_calometPxy->Fill( calometPy->at(0) ); 
	  h_caloSumet->Fill( calometSumEt->at(0) ); 
	  h_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

	  h_tcmetPt->Fill( tcmetPt->at(0) );
	  h_tcmetPxy->Fill( tcmetPx->at(0) ); 
	  h_tcmetPxy->Fill( tcmetPy->at(0) ); 
	  h_tcSumet->Fill( tcmetSumEt->at(0) ); 
	  h_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 

	  h_pfmetPt->Fill( pfmetPt->at(0) );
	  h_pfmetPxy->Fill( pfmetPx->at(0) ); 
	  h_pfmetPxy->Fill( pfmetPy->at(0) ); 
	  h_pfSumet->Fill( pfmetSumEt->at(0) ); 
	  h_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 

	  ///////////////////////////////////////
	  ///////// Print High MET events////////
	  ///////////////////////////////////////
	  if(isData==1)
	    if( calometPt->at(0) > 20 || tcmetPt->at(0) > 20 || pfmetPt->at(0) > 20. )
	      {
		cout << "event: " << event << " " 
		     << "ls: " << ls << " "
		     << "run: " << run << "  "
		     << "--  calometPt->at(0) : " <<  calometPt->at(0) << " "
		     << "--  tcmetPt->at(0) : "   <<  tcmetPt->at(0)   <<" "
		     << "--  pfmetPt->at(0) : "   <<  pfmetPt->at(0)   <<" "
		     << endl;
	      }

	  if(isData==1)
	    if( calometSumEt->at(0) > 50 || tcmetSumEt->at(0) > 100 || pfmetSumEt->at(0) > 100 )
	      {
		cout << "event: " << event << " " 
		     << "ls: " << ls << " "
		     << "run: " << run << "  "
		     << "--  calometSumEt->at(0) : " <<  calometSumEt->at(0) << " "
		     << "--  tcmetSumEt->at(0) : "   <<  tcmetSumEt->at(0) << " "
		     << "--  pfmetSumEt->at(0) : "   <<  pfmetSumEt->at(0) << " "
		     << endl;
	      }
	  
	  //##########################
	  //## MET in dijets (ak5)
	  //##########################
	  
	  bool makeJetCorr = true;

	  // cut values
	  double endcapeta =2.6;
	  double endcapeta_dijet =3.0;
	  double cut_CaloDiJetDeltaPhi_min = 2.10;

	  // minimum pt cuts (depending on jet corrections)
	  double ptMin;
	  double ptMinDijet;
	  if (makeJetCorr==true) 
	    {
	      ptMin=15.;
	      ptMinDijet=10.;
	    }
	  if (makeJetCorr==false) 
	    {
	      ptMin=7.;
	      ptMinDijet=5.;
	    }

	  int index_jet1 = -10;
	  int index_jet2 = -10;
	  double mypt1=-10;
	  double mypt2=-10;

	  std::vector<TLorentzVector> vPtEtaPhiE;
	  if(!vPtEtaPhiE.empty()){ vPtEtaPhiE.clear(); }
	  
	  // --------------------DiJets---------------------------------------------------------------------   
	  // JET CORRECTION
	  // --------------------
	  double jcScale0;
	  double jcScale1;

	  //dijet
	  if(int(ak5JetpT->size())>=2)
	    {
	      for (int j = 0; j<int(ak5JetpT->size()); j++)
		{
		  //check if jet is among hardest two
		  //as jets are ordered in uncorrected pT: needs to be done only for corrected jets
		  if(makeJetCorr == true) {
		    if((ak5JetscaleL2L3->at(j)*ak5JetpT->at(j))>mypt1){
		      mypt2=mypt1;
		      index_jet2=index_jet1;
		      mypt1=ak5JetscaleL2L3->at(j)*ak5JetpT->at(j);
		      index_jet1=j;
		    }else if((ak5JetscaleL2L3->at(j)*ak5JetpT->at(j))>mypt2){
		      mypt2=ak5JetscaleL2L3->at(j)*ak5JetpT->at(j);
		      index_jet2=j;
		    }
		  }
		}

	      if((index_jet2==-10)||(index_jet1==-10))
		{
		  cout<<"index should be set ERROR: "<<index_jet2<<"/"<<index_jet1<<endl;
		}
	      // both passed pT and eta cuts
	      if(makeJetCorr == true) 
		{
		  jcScale0 = ak5JetscaleL2L3->at(index_jet1);
		  jcScale1 = ak5JetscaleL2L3->at(index_jet2);
		}
	      else 
		{
		  index_jet1 =  0;
		  index_jet2 =  1;
		  jcScale0    = 1;
		  jcScale1    = 1;
		}
	      
	      if( fabs(ak5JetEta->at(index_jet1)) < endcapeta_dijet && 
		  ( ak5JetpT->at(index_jet1) * jcScale0 ) > ptMinDijet && 
		  fabs( ak5JetEta->at(index_jet2) ) < endcapeta_dijet && 
		  ( ak5JetpT->at(index_jet2) * jcScale1 ) > ptMinDijet )
		{ 
		  // dphi
		double dphi = DeltaPhi(ak5JetPhi->at(index_jet1), ak5JetPhi->at(index_jet2) );
		
		if ( dphi > cut_CaloDiJetDeltaPhi_min ) 
		  {
		    // both passed jet ID loose
		    if(
		       JetIdloose(ak5JetJIDresEMF->at(index_jet1),ak5JetJIDfHPD->at(index_jet1),ak5JetJIDn90Hits->at(index_jet1),ak5JetEta->at(index_jet1)) &&
		       JetIdloose(ak5JetJIDresEMF->at(index_jet2),ak5JetJIDfHPD->at(index_jet2),ak5JetJIDn90Hits->at(index_jet2),ak5JetEta->at(index_jet2)))
		      {
			h_dijetLoose_calometPt->Fill( calometPt->at(0) );
			h_dijetLoose_calometPxy->Fill( calometPx->at(0) ); 
			h_dijetLoose_calometPxy->Fill( calometPy->at(0) ); 
			h_dijetLoose_caloSumet->Fill( calometSumEt->at(0) ); 
			h_dijetLoose_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

			h_dijetLoose_tcmetPt->Fill( tcmetPt->at(0) );
			h_dijetLoose_tcmetPxy->Fill( tcmetPx->at(0) ); 
			h_dijetLoose_tcmetPxy->Fill( tcmetPy->at(0) ); 
			h_dijetLoose_tcSumet->Fill( tcmetSumEt->at(0) ); 
			h_dijetLoose_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 

			h_dijetLoose_pfmetPt->Fill( pfmetPt->at(0) );
			h_dijetLoose_pfmetPxy->Fill( pfmetPx->at(0) ); 
			h_dijetLoose_pfmetPxy->Fill( pfmetPy->at(0) ); 
			h_dijetLoose_pfSumet->Fill( pfmetSumEt->at(0) ); 
			h_dijetLoose_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 
			
			// both passed jet ID tight
			if(
			   JetIdtight(ak5JetJIDresEMF->at(index_jet1),ak5JetJIDfHPD->at(index_jet1),ak5JetJIDfRBX->at(index_jet1),ak5JetJIDn90Hits->at(index_jet1),ak5JetEta->at(index_jet1)) &&
			   JetIdtight(ak5JetJIDresEMF->at(index_jet2),ak5JetJIDfHPD->at(index_jet2),ak5JetJIDfRBX->at(index_jet2),ak5JetJIDn90Hits->at(index_jet2),ak5JetEta->at(index_jet2)))
			  {
			    h_dijetTight_calometPt->Fill( calometPt->at(0) );
			    h_dijetTight_calometPxy->Fill( calometPx->at(0) ); 
			    h_dijetTight_calometPxy->Fill( calometPy->at(0) ); 
			    h_dijetTight_caloSumet->Fill( calometSumEt->at(0) ); 
			    h_dijetTight_caloMetOSumet->Fill( calometPt->at(0) / calometSumEt->at(0) ); 

			    h_dijetTight_tcmetPt->Fill( tcmetPt->at(0) );
			    h_dijetTight_tcmetPxy->Fill( tcmetPx->at(0) ); 
			    h_dijetTight_tcmetPxy->Fill( tcmetPy->at(0) ); 
			    h_dijetTight_tcSumet->Fill( tcmetSumEt->at(0) ); 
			    h_dijetTight_tcMetOSumet->Fill( tcmetPt->at(0) / tcmetSumEt->at(0) ); 
			    
			    h_dijetTight_pfmetPt->Fill( pfmetPt->at(0) );
			    h_dijetTight_pfmetPxy->Fill( pfmetPx->at(0) ); 
			    h_dijetTight_pfmetPxy->Fill( pfmetPy->at(0) ); 
			    h_dijetTight_pfSumet->Fill( pfmetSumEt->at(0) ); 
			    h_dijetTight_pfMetOSumet->Fill( pfmetPt->at(0) / pfmetSumEt->at(0) ); 
			  }
		      }
		  }//dphi cut
		}//eta/pt cuts on dijets
	    }//di jets >= 2 jets
	  
	  //##########################
	}//-------------- passed cuts "0"
      
      ////////////////////// User's code ends here ///////////////////////
    } // End loop over events

  //////////write histos 

  //## 1D histograms

  //calomet
  h_calometPt->Write(); 
  h_calometPxy->Write(); 
  h_caloSumet->Write(); 
  h_caloMetOSumet->Write();
  
  //tcmet
  h_tcmetPt->Write(); 
  h_tcmetPxy->Write(); 
  h_tcSumet->Write(); 
  h_tcMetOSumet->Write();

  //pfmet
  h_pfmetPt->Write(); 
  h_pfmetPxy->Write(); 
  h_pfSumet->Write(); 
  h_pfMetOSumet->Write();

  //Dijets (loose)
  h_dijetLoose_calometPt->Write(); 
  h_dijetLoose_calometPxy->Write(); 
  h_dijetLoose_caloSumet->Write(); 
  h_dijetLoose_caloMetOSumet->Write(); 
 
  h_dijetLoose_tcmetPt->Write(); 
  h_dijetLoose_tcmetPxy->Write(); 
  h_dijetLoose_tcSumet->Write();
  h_dijetLoose_tcMetOSumet->Write(); 
		    
  h_dijetLoose_pfmetPt->Write(); 
  h_dijetLoose_pfmetPxy->Write(); 
  h_dijetLoose_pfSumet->Write(); 
  h_dijetLoose_pfMetOSumet->Write(); 

  //Dijets (tight)
  h_dijetTight_calometPt->Write(); 
  h_dijetTight_calometPxy->Write(); 
  h_dijetTight_caloSumet->Write(); 
  h_dijetTight_caloMetOSumet->Write(); 
  
  h_dijetTight_tcmetPt->Write(); 
  h_dijetTight_tcmetPxy->Write(); 
  h_dijetTight_tcSumet->Write(); 
  h_dijetTight_tcMetOSumet->Write(); 
		    
  h_dijetTight_pfmetPt->Write(); 
  h_dijetTight_pfmetPxy->Write(); 
  h_dijetTight_pfSumet->Write(); 
  h_dijetTight_pfMetOSumet->Write(); 

  //Vertex
  h_AllVertexZ->Write();
  h_AllVertexChi2->Write(); 
  h_AllVertexNDOF->Write(); 
  h_AllVertexChi2_0_NDOF->Write();
  h_AllVertexNtrk->Write(); 
  h_AllNVertex->Write();
  h_VertexSumpt->Write(); 
  h_VertexSumptW5->Write(); 

  //## 2D histograms

  std::cout << "analysisClass::Loop() ends" <<std::endl; 
}
// root -l -q -b makeNtupleLHE_WZ.C+'("/afs/cern.ch/work/c/ceballos/public/samples/wzlhe8tev_qcdewk/","wzgamma_qed_5_qcd_99_sm.lhe",1,1,1)'
// root -l -q -b makeNtupleLHE_WZ.C+'("/afs/cern.ch/work/c/ceballos/public/samples/wwsslhe8tev_qcdewk/","qed_4_qcd_99_sm.lhe",1,1,0)'
void makeNtupleLHE_WZ(TString pathDir="/afs/cern.ch/work/c/ceballos/public/samples/wzlhe8tev/",
	           TString infname="WZJetsTo3LNu_8TeV-madgraph_166134011.lhe",
		   double weightIni = 1.0, bool withTaus = kTRUE, bool is3L = kTRUE
	       )
{
  ifstream ifs(Form("%s/%s",pathDir.Data(),infname.Data()));
  assert(ifs.is_open());

  TString outNtuplename = Form("%s",infname.Data());
  outNtuplename.ReplaceAll(".lhe",".root");
  TFile *outtuple = TFile::Open(outNtuplename.Data(),"recreate");
  TNtuple *nt = new TNtuple("Events","Events","ptl1:ptl2:ptl3:ptn:njets:ptj1:ptj2:etaj1:etaj2:detajj:dphijj:mjj:wsign:drlj:weight");

  // some weighted distributions
  TH1D *hDVar[20];
  const unsigned int nHist = 15;
  hDVar[ 0] = new TH1D(Form("hDVar_0") ,";N_{jets};events",5,-0.5,4.5);
  hDVar[ 1] = new TH1D(Form("hDVar_1") ,";N_{jets} W+;events",5,-0.5,4.5);
  hDVar[ 2] = new TH1D(Form("hDVar_2") ,";N_{jets} W-;events",5,-0.5,4.5);
  hDVar[ 3] = new TH1D(Form("hDVar_3") ,";pt_{T}^{l1} [GeV];events",100,0.,400.);
  hDVar[ 4] = new TH1D(Form("hDVar_4") ,";pt_{T}^{l2} [GeV];events",100,0.,400.);
  hDVar[ 5] = new TH1D(Form("hDVar_5") ,";pt_{T}^{l3} [GeV];events",100,0.,400.);
  hDVar[ 6] = new TH1D(Form("hDVar_6") ,";pt_{T}^{neutrino} [GeV];events",100,0.,400.);
  hDVar[ 7] = new TH1D(Form("hDVar_7") ,";p_{T}^{j1} [GeV];events",100,0.,600.);
  hDVar[ 8] = new TH1D(Form("hDVar_8") ,";p_{T}^{j2} [GeV];events",100,0.,600.);
  hDVar[ 9] = new TH1D(Form("hDVar_9") ,";#eta_{jj};events",100,0.,10.);
  hDVar[10] = new TH1D(Form("hDVar_10"),";#Delta #phi_{jj};events",100,0.,TMath::Pi());
  hDVar[11] = new TH1D(Form("hDVar_11"),";m_{jj} [GeV];events",100,0.,4000.);
  hDVar[12] = new TH1D(Form("hDVar_12"),";#Delta R_{ll} ;events",100,0.,5.);
  hDVar[13] = new TH1D(Form("hDVar_13"),";pt_{T}^{H} [GeV];events",100,0.,400.);
  hDVar[14] = new TH1D(Form("hDVar_14"),";|#eta_{T}^{H}|;events",100,-5.0,+5.0);
  for(UInt_t j=0; j<nHist; j++) {hDVar[j]->Sumw2(); hDVar[j]->SetMinimum(0.0000001);} 

  int eventType[10] = {0,0,0,0,0,0,0,0,0,0};
  string line;
  // skip the intro up until <init>
  do {
    getline(ifs,line);
  } while (line.compare("</init>") != 0);

  getline(ifs,line);

  int nevents=0,npass[4]={0,0,0,0};
  // get the event info
  while(getline(ifs,line)) {
    if(line.compare("<event>")==0) {
      nevents++;
      if(nevents%10000 == 0) printf("--- reading event %7d\n",nevents);

      int idup, istup, mothup1, mothup2, icolup1, icolup2; 
      double  pupx, pupy, pupz, pupe, pupm, vtimup, spinup;

      TLorentzVector vl1,vl2,vl3,vn,vj1,vj2;
      vl1.SetPxPyPzE  (0,0,0,0);
      vl2.SetPxPyPzE  (0,0,0,0);
      vl3.SetPxPyPzE  (0,0,0,0);
      vn.SetPxPyPzE   (0,0,0,0);
      vj1.SetPxPyPzE  (0,0,0,0);
      vj2.SetPxPyPzE  (0,0,0,0);

      // loop over the rest of them, skip initial line
      getline(ifs,line);
      getline(ifs,line);
      int pass[4] = {0,0,0,0};int lType[3] = {0,0,0};int nJets = 0;
      double weight = weightIni;
      while(line.compare("</event>") != 0) {
	stringstream sstmp(line);
	TString Line = line;
	if(!Line.Contains("#") && line.compare("") != 0) { // avoid crappy lines
	  sstmp >> idup >> istup >> mothup1 >> mothup2 >> icolup1 >> icolup2 >> pupx >> pupy >> pupz >> pupe >> pupm >> vtimup >> spinup;

	  TLorentzVector vec;
	  vec.SetPxPyPzE(pupx,pupy,pupz,pupe);

	  if(idup==+24) {pass[0]++;}

	  if(idup==-24) {pass[1]++;}

	  if(idup==25) {hDVar[13]->Fill(TMath::Min(vec.Pt(),399.999));if(vec.Pt() > 0) hDVar[14]->Fill(TMath::Min(TMath::Max(vec.Eta(),-4.999),4.999));}

	  if(istup == 1){
	    // if(TMath::Abs(idup) ==  15) weight = weight*0.3524; // to consider leptonic tau decays only
            if(TMath::Abs(idup) ==  11 || TMath::Abs(idup) ==  13 || (TMath::Abs(idup) ==  15 && withTaus == kTRUE)) {
	      pass[2]++;
	      if     (vec.Pt() > vl1.Pt()){
		vl3.SetPxPyPzE(vl2.Px(),vl2.Py(),vl2.Pz(),vl2.E());
		vl2.SetPxPyPzE(vl1.Px(),vl1.Py(),vl1.Pz(),vl1.E());
		vl1.SetPxPyPzE(vec.Px(),vec.Py(),vec.Pz(),vec.E());
	      }
	      else if(vec.Pt() > vl2.Pt()){
		vl3.SetPxPyPzE(vl2.Px(),vl2.Py(),vl2.Pz(),vl2.E());
		vl2.SetPxPyPzE(vec.Px(),vec.Py(),vec.Pz(),vec.E());
	      }
	      else if(vec.Pt() > vl3.Pt()){
		vl3.SetPxPyPzE(vec.Px(),vec.Py(),vec.Pz(),vec.E());
	      }
            }
            if(TMath::Abs(idup) == 12 || TMath::Abs(idup) == 14 || TMath::Abs(idup) == 16) {vn.SetPxPyPzE(vn.Px()+vec.Px(),vn.Py()+vec.Py(),vn.Pz()+vec.Pz(),vn.E()+vec.E()); pass[3]++;}
	    if(TMath::Abs(idup) == 11) lType[0]++;
	    if(TMath::Abs(idup) == 13) lType[1]++;
	    if(TMath::Abs(idup) == 15) lType[2]++;

	    if((TMath::Abs(idup) == 1 || TMath::Abs(idup) == 2 || TMath::Abs(idup) == 3 || 
	        TMath::Abs(idup) == 4 || TMath::Abs(idup) == 5 || TMath::Abs(idup) == 6 ||
		TMath::Abs(idup) ==21) &&
		vec.Pt() > 0.0) {
	      nJets++;
	      if     (vec.Pt() > vj1.Pt()){
		vj2.SetPxPyPzE(vj1.Px(),vj1.Py(),vj1.Pz(),vj1.E());
		vj1.SetPxPyPzE(vec.Px(),vec.Py(),vec.Pz(),vec.E());
	      }
	      else if(vec.Pt() > vj2.Pt()){
		vj2.SetPxPyPzE(vec.Px(),vec.Py(),vec.Pz(),vec.E());
	      }
	    }
          }
	}
	getline(ifs,line);
      }
      
      if(is3L == kTRUE){
        if     (lType[0] == 3 && lType[1] == 0 && lType[2] == 0) eventType[0]++;
        else if(lType[0] == 2 && lType[1] == 1 && lType[2] == 0) eventType[1]++;
        else if(lType[0] == 2 && lType[1] == 0 && lType[2] == 1) eventType[2]++;
        else if(lType[0] == 1 && lType[1] == 2 && lType[2] == 0) eventType[3]++;
        else if(lType[0] == 1 && lType[1] == 0 && lType[2] == 2) eventType[4]++;
        else if(lType[0] == 1 && lType[1] == 1 && lType[2] == 1) eventType[5]++;
        else if(lType[0] == 0 && lType[1] == 3 && lType[2] == 0) eventType[6]++;
        else if(lType[0] == 0 && lType[1] == 0 && lType[2] == 3) eventType[7]++;
        else if(lType[0] == 0 && lType[1] == 2 && lType[2] == 1) eventType[8]++;
        else if(lType[0] == 0 && lType[1] == 1 && lType[2] == 2) eventType[9]++;
        else {
          printf("Impossible3L: %d %d %d\n",lType[0],lType[1],lType[2]); assert(0);
        }
      }
      else {
        if     (lType[0] == 2 && lType[1] == 0 && lType[2] == 0) eventType[0]++;
        else if(lType[0] == 1 && lType[1] == 1 && lType[2] == 0) eventType[1]++;
        else if(lType[0] == 1 && lType[1] == 0 && lType[2] == 1) eventType[2]++;
        else if(lType[0] == 0 && lType[1] == 2 && lType[2] == 0) eventType[3]++;
        else if(lType[0] == 0 && lType[1] == 0 && lType[2] == 2) eventType[4]++;
        else if(lType[0] == 0 && lType[1] == 1 && lType[2] == 1) eventType[5]++;
        //else {
        //  printf("Impossible2L: %d %d %d\n",lType[0],lType[1],lType[2]); assert(0);
        //}
      }

      double ptl1,ptl2,ptl3,ptn,njets,ptj1,ptj2,etaj1,etaj2,detajj,dphijj,mjj,wsign,drll,drlj;
      // leptons info
      if(vl1.P() > 0) ptl1 = vl1.Pt();
      else            ptl1 = 0.0;
      if(vl2.P() > 0) ptl2 = vl2.Pt();
      else            ptl2 = 0.0;
      if(vl3.P() > 0) ptl3 = vl3.Pt();
      else            ptl3 = 0.0;
      ptn    = vn.Pt();
      njets  = (double)nJets;
      ptj1   = vj1.Pt();
      ptj2   = vj2.Pt();
      if(ptj1>0) etaj1 = vj1.Eta();
      else       etaj1 = -9.;
      if(ptj2>0) etaj2 = vj2.Eta();
      else       etaj2 = -9.;
      if(ptj2>0) detajj = TMath::Abs(vj1.Eta()-vj2.Eta());
      else       detajj = 0;
      dphijj = DeltaPhi(vj1.Phi(),vj2.Phi());
      mjj    = (vj1+vj2).M();
      
      drll = 999.;
      if(ptl1 > 0 && ptl2 > 0) {
        drll = sqrt(TMath::Abs(vl1.Eta()-vl2.Eta())*TMath::Abs(vl1.Eta()-vl2.Eta())+DeltaPhi(vl1.Phi(),vl2.Phi())*DeltaPhi(vl1.Phi(),vl2.Phi()));
      }
      if(ptl3 > 0) {
        double dr = sqrt(TMath::Abs(vl1.Eta()-vl3.Eta())*TMath::Abs(vl1.Eta()-vl3.Eta())+DeltaPhi(vl1.Phi(),vl3.Phi())*DeltaPhi(vl1.Phi(),vl3.Phi()));
	if(dr < drll) drll = dr;
               dr = sqrt(TMath::Abs(vl2.Eta()-vl3.Eta())*TMath::Abs(vl2.Eta()-vl3.Eta())+DeltaPhi(vl2.Phi(),vl3.Phi())*DeltaPhi(vl2.Phi(),vl3.Phi()));
	if(dr < drll) drll = dr;
      }
      
      drlj = 999.;double dr;
      if(ptj1 > 0){
        if(ptl1 > 0) {
	  dr = sqrt(TMath::Abs(vj1.Eta()-vl1.Eta())*TMath::Abs(vj1.Eta()-vl1.Eta())+DeltaPhi(vj1.Phi(),vl1.Phi())*DeltaPhi(vj1.Phi(),vl1.Phi()));
	  if(dr < drlj) drlj = dr;
        }
        if(ptl2 > 0) {
          dr = sqrt(TMath::Abs(vj1.Eta()-vl2.Eta())*TMath::Abs(vj1.Eta()-vl2.Eta())+DeltaPhi(vj1.Phi(),vl2.Phi())*DeltaPhi(vj1.Phi(),vl2.Phi()));
	  if(dr < drlj) drlj = dr;
        }
	if(ptl3 > 0) {
	  dr = sqrt(TMath::Abs(vj1.Eta()-vl3.Eta())*TMath::Abs(vj1.Eta()-vl3.Eta())+DeltaPhi(vj1.Phi(),vl3.Phi())*DeltaPhi(vj1.Phi(),vl3.Phi()));
	  if(dr < drlj) drlj = dr;
	}
      }
      if(ptj2 > 0){
        if(ptl1 > 0) {
          dr = sqrt(TMath::Abs(vj2.Eta()-vl1.Eta())*TMath::Abs(vj2.Eta()-vl1.Eta())+DeltaPhi(vj2.Phi(),vl1.Phi())*DeltaPhi(vj2.Phi(),vl1.Phi()));
	  if(dr < drlj) drlj = dr;
        }
        if(ptl2 > 0) {
	  dr = sqrt(TMath::Abs(vj2.Eta()-vl2.Eta())*TMath::Abs(vj2.Eta()-vl2.Eta())+DeltaPhi(vj2.Phi(),vl2.Phi())*DeltaPhi(vj2.Phi(),vl2.Phi()));
	  if(dr < drlj) drlj = dr;
        }
	if(ptl3 > 0) {
	  dr = sqrt(TMath::Abs(vj2.Eta()-vl3.Eta())*TMath::Abs(vj2.Eta()-vl3.Eta())+DeltaPhi(vj2.Phi(),vl3.Phi())*DeltaPhi(vj2.Phi(),vl3.Phi()));
	  if(dr < drlj) drlj = dr;
	}
      }
      
      wsign = (double)(pass[0]-pass[1])/TMath::Abs(pass[0]-pass[1]);
      //if(TMath::Abs(wsign) != 1) {printf("total W charge should be +/- 1 (%d)\n",(int)wsign); assert(0);}

      if(pass[0] >= 1) npass[0]++;
      if(pass[1] >= 1) npass[1]++;
      if(pass[2] == 3) npass[2]++;
      if(pass[3] >= 1) npass[3]++;

      hDVar[0]->Fill(TMath::Min(njets,4.499),weight);
      if     (wsign == +1) hDVar[1]->Fill(TMath::Min(njets,4.499),weight);
      else if(wsign == -1) hDVar[2]->Fill(TMath::Min(njets,4.499),weight);

      if(njets >= 2 &&
         vl1.P() > 0 && vl2.P() > 0 &&
         TMath::Abs(vl1.Eta()) < 2.5 && TMath::Abs(vl2.Eta()) < 2.5 && 
	 (is3L == kFALSE || TMath::Abs(vl3.Eta()) < 2.5)){
        nt->Fill(ptl1,ptl2,ptl3,ptn,njets,ptj1,ptj2,etaj1,etaj2,detajj,dphijj,mjj,wsign,drlj,weight);
	hDVar[3] ->Fill(TMath::Min(ptl1,399.999),weight);
	hDVar[4] ->Fill(TMath::Min(ptl2,399.999),weight);
	hDVar[5] ->Fill(TMath::Min(ptl3,399.999),weight);
	hDVar[6] ->Fill(TMath::Min(ptn,399.999),weight);
	hDVar[7] ->Fill(TMath::Min(ptj1,599.999),weight);
        hDVar[8] ->Fill(TMath::Min(ptj2,599.999),weight);
	hDVar[9] ->Fill(TMath::Min(detajj,9.999),weight);
	hDVar[10]->Fill(dphijj,weight);
	hDVar[11]->Fill(TMath::Min(mjj,3999.999),weight);
	hDVar[12]->Fill(TMath::Min(drll,4.999),weight);
      }
    } else {
示例#8
0
void analysis_mg(){//main  

  gSystem->Load("/uscms/home/mengleis/work/SUSYAnalysis/lib/libAnaClasses.so");

  char outputname[50] = "resTree_mgsignal_2016DoubleEG.root";
  ofstream logfile;
  logfile.open("resTree_mgsignal_2016DoubleEG.log"); 

  logfile << "analysis_mg()" << std::endl;

  RunType datatype(MuonEG2016); 
  TChain* es = new TChain("ggNtuplizer/EventTree");
  es->Add("root://cmseos.fnal.gov//store/user/msun/2016ggNtuple/skim-DoubleEG_Run2016B_PRv2.root");
  logfile << "Add file: 2016ggNtuple/skim-DoubleEG_Run2016B_PRv2.root" << std::endl;
  es->Add("root://cmseos.fnal.gov//store/user/msun/2016ggNtuple/skim-DoubleEG_Run2016C_PRv2.root");
  logfile << "Add file: 2016ggNtuple/skim-DoubleEG_Run2016C_PRv2.root" << std::endl;
  es->Add("root://cmseos.fnal.gov//store/user/msun/2016ggNtuple/skim-DoubleEG_Run2016D_PRv2.root");
  logfile << "Add file: 2016ggNtuple/skim-DoubleEG_Run2016D_PRv2.root" << std::endl;

  const unsigned nEvts = es->GetEntries();
  logfile << "Total event: " << nEvts << std::endl;
  logfile << "Output file: " << outputname << std::endl;

  int nTotal(0),npassHLT(0), npassPho(0), npassMu(0), npassdR(0), npassZ(0), npassMETFilter(0);

  TFile *outputfile = TFile::Open(outputname,"RECREATE");
  outputfile->cd();

//************* MC Tree **************************//
  TTree *mctree = new TTree("MCTree","MCTree");
  int mcType = MCType::NOMC;
  if(datatype == MC && mcType == MCType::NOMC){std::cout << "wrong MC type" << std::endl; throw;} 
  logfile << "mcType" << mcType << std::endl;
  std::vector<int> mcPID;
  std::vector<float> mcEta;
  std::vector<float> mcPhi;
  std::vector<float> mcPt;
  std::vector<int> mcMomPID;
  mctree->Branch("mcType",          &mcType);
  mctree->Branch("mcPID",           &mcPID);
  mctree->Branch("mcEta",           &mcEta);
  mctree->Branch("mcPhi",           &mcPhi);
  mctree->Branch("mcPt",            &mcPt);
  mctree->Branch("mcMomPID",        &mcMomPID);
//************ Signal Tree **********************//
  TTree *sigtree = new TTree("signalTree","signalTree");
  float phoEt(0);
  float phoEta(0);
  float phoPhi(0);
  float lepPt(0);
  float lepEta(0);
  float lepPhi(0);
  float sigMT(0);
  float sigMET(0);
  float sigMETPhi(0);
  float dPhiLepMET(0);
  int   nVertex(0);
  float dRPhoLep(0);
  float HT(0);
  float nJet(0);
  
  sigtree->Branch("phoEt",     &phoEt);
  sigtree->Branch("phoEta",    &phoEta);
  sigtree->Branch("phoPhi",    &phoPhi);
  sigtree->Branch("lepPt",     &lepPt);
  sigtree->Branch("lepEta",    &lepEta);
  sigtree->Branch("lepPhi",    &lepPhi);
  sigtree->Branch("sigMT",     &sigMT);
  sigtree->Branch("sigMET",    &sigMET);
  sigtree->Branch("sigMETPhi", &sigMETPhi);
  sigtree->Branch("dPhiLepMET",&dPhiLepMET);
  sigtree->Branch("nVertex",   &nVertex);
  sigtree->Branch("dRPhoLep",  &dRPhoLep);
  sigtree->Branch("HT",        &HT);
  sigtree->Branch("nJet",      &nJet);


//************ Signal Tree **********************//
  TTree *proxytree = new TTree("proxyTree","proxyTree");
  float proxyphoEt(0);
  float proxyphoEta(0);
  float proxyphoPhi(0);
  float proxylepPt(0);
  float proxylepEta(0);
  float proxylepPhi(0);
  float proxysigMT(0);
  float proxysigMET(0);
  float proxysigMETPhi(0);
  float proxydPhiLepMET(0);
  int   proxynVertex(0);
  float proxydRPhoLep(0);
  float proxyHT(0);
  float proxynJet(0);
  
  proxytree->Branch("phoEt",     &proxyphoEt);
  proxytree->Branch("phoEta",    &proxyphoEta);
  proxytree->Branch("phoPhi",    &proxyphoPhi);
  proxytree->Branch("lepPt",     &proxylepPt);
  proxytree->Branch("lepEta",    &proxylepEta);
  proxytree->Branch("lepPhi",    &proxylepPhi);
  proxytree->Branch("sigMT",     &proxysigMT);
  proxytree->Branch("sigMET",    &proxysigMET);
  proxytree->Branch("sigMETPhi", &proxysigMETPhi);
  proxytree->Branch("dPhiLepMET",&proxydPhiLepMET);
  proxytree->Branch("nVertex",   &proxynVertex);
  proxytree->Branch("dRPhoLep",  &proxydRPhoLep);
  proxytree->Branch("HT",        &proxyHT);
  proxytree->Branch("nJet",      &proxynJet);

//************ Signal Tree **********************//
  TTree *jettree = new TTree("jetTree","jetTree");
  float jetphoEt(0);
  float jetphoEta(0);
  float jetphoPhi(0);
  float jetlepPt(0);
  float jetlepEta(0);
  float jetlepPhi(0);
  float jetsigMT(0);
  float jetsigMET(0);
  float jetsigMETPhi(0);
  float jetdPhiLepMET(0);
  int   jetnVertex(0);
  float jetdRPhoLep(0);
  float jetHT(0);
  float jetnJet(0);
  
  jettree->Branch("phoEt",     &jetphoEt);
  jettree->Branch("phoEta",    &jetphoEta);
  jettree->Branch("phoPhi",    &jetphoPhi);
  jettree->Branch("lepPt",     &jetlepPt);
  jettree->Branch("lepEta",    &jetlepEta);
  jettree->Branch("lepPhi",    &jetlepPhi);
  jettree->Branch("sigMT",     &jetsigMT);
  jettree->Branch("sigMET",    &jetsigMET);
  jettree->Branch("sigMETPhi", &jetsigMETPhi);
  jettree->Branch("dPhiLepMET",&jetdPhiLepMET);
  jettree->Branch("nVertex",   &jetnVertex);
  jettree->Branch("dRPhoLep",  &jetdRPhoLep);
  jettree->Branch("HT",        &jetHT);
  jettree->Branch("nJet",      &jetnJet);

  /// histo lest
  TH1F *p_photonEt = new TH1F("photonET","#gamma E_{T}; E_{T} (GeV)",500,0,1500);
  TH1F *p_photonEta = new TH1F("photonEta","#gamma #eta; #eta;",60,-3,3);
  TH1F *p_lepPt = new TH1F("lepET","#mu P_{T}; P_{T} (GeV)",500,0,1000);
  TH1F *p_lepEta = new TH1F("lepEta","#mu #eta; #eta;",60,-3,3);
  TH1F *p_Mt = new TH1F("Mt","M_{T}; M_{T} (GeV);",200,0,400); 
  TH1F *p_MET = new TH1F("MET","MET",100,0,100);
 
  TH1F *p_PhoLepDeltaR = new TH1F("p_PhoLepDeltaR","#DeltaR(e, #gamma); #DeltaR(e, #gamma);",100,0,10);
  TH1F *p_PhoLepMass = new TH1F("p_PhoLepMass","M_{e#gamma}; M_{e#gamma}(GeV);", 200,0,400);
  TH1F *p_eventcount = new TH1F("p_eventcount","p_eventcount",7,0,7);
  
  rawData raw(es, datatype);
  std::vector<mcData>  MCData;
  std::vector<recoPhoton> Photon;
  std::vector<recoMuon>   Muon;
  std::vector<recoEle>   Ele;
  float MET(0);
  float METPhi(0);
  int nVtx(0);
  int jetNumber(0);
  int METFilter(0);
  logfile << "RunType: " << datatype << std::endl;

  std::cout << "Total evetns : " << nEvts << std::endl;
    for (unsigned ievt(0); ievt<nEvts; ++ievt){//loop on entries
  
      if (ievt%100000==0) std::cout << " -- Processing event " << ievt << std::endl;

        raw.GetData(es, ievt);
        MCData.clear();
        Photon.clear();
        Muon.clear();
        Ele.clear();
        if(datatype == MC)for(int iMC(0); iMC < raw.nMC; iMC++){MCData.push_back(mcData(raw, iMC));}
        for(int iPho(0); iPho < raw.nPho; iPho++){Photon.push_back(recoPhoton(raw, iPho));}
        for(int iMu(0); iMu < raw.nMu; iMu++){Muon.push_back(recoMuon(raw, iMu));}
        for(int iEle(0); iEle < raw.nEle; iEle++){Ele.push_back(recoEle(raw, iEle));}
        MET = raw.pfMET;
        METPhi = raw.pfMETPhi;
        METFilter = raw.metFilters;
        nVtx = raw.nVtx;
        jetNumber = raw.nJet;

        nTotal+=1;
        if(!raw.passHLT())continue;
        npassHLT+=1;

        if(raw.nMu < 1 || raw.nPho <1)continue;

        bool hasPho(false);
        std::vector<recoPhoton>::iterator signalPho = Photon.begin();
        std::vector< std::vector<recoPhoton>::iterator >  proxyPhoCollection;
        proxyPhoCollection.clear();
        std::vector< std::vector<recoPhoton>::iterator >  jetPhoCollection;
        jetPhoCollection.clear();
        std::vector< std::vector<recoPhoton>::iterator >  mcmatchPhoCollection;
        mcmatchPhoCollection.clear();
       	for(std::vector<recoPhoton>::iterator itpho = Photon.begin() ; itpho != Photon.end(); ++itpho){
          if(itpho->getEt() > 35)mcmatchPhoCollection.push_back(itpho);
          if(!itpho->isEB())continue;
          if(!itpho->passHLTSelection())continue;
          bool passHoverE = itpho->passHoverE(1);
          bool passNeuIso = itpho->passNeuIso(1);
          bool passPhoIso = itpho->passPhoIso(1);
		  bool passSigma = itpho->passSigma(1);
		  bool passChIso = itpho->passChIso(1);
		  bool PixelVeto = itpho->PixelSeed()==0? true: false;
		  bool GSFveto(true);
		  bool FSRVeto(true);
		  for(std::vector<recoEle>::iterator ie = Ele.begin(); ie != Ele.end(); ie++){
			 if(DeltaR(itpho->getEta(), itpho->getPhi(), ie->getEta(), ie->getPhi()) < 0.02)GSFveto = false;
			 if(DeltaR(itpho->getEta(), itpho->getPhi(), ie->getEta(), ie->getPhi()) < 0.3 && DeltaR(itpho->getEta(), itpho->getPhi(), ie->getEta(), ie->getPhi()) > 0.02 && ie->getEt()>2.0)FSRVeto=false;
		  }
		  for(std::vector<recoMuon>::iterator im = Muon.begin(); im != Muon.end(); im++)
			 if(DeltaR(itpho->getEta(), itpho->getPhi(), im->getEta(), im->getPhi()) < 0.3 && im->getEt()>2.0)FSRVeto=false;
		  if(passHoverE && passNeuIso && passPhoIso && itpho->getChIso()<15 && itpho->getSigma()< 0.02){
            if(!passSigma || !passChIso){
			  if(GSFveto && PixelVeto && FSRVeto)jetPhoCollection.push_back(itpho);
            }
		  }
          if(!itpho->passSignalSelection())continue;
		  if(GSFveto && PixelVeto && FSRVeto){
            if(!hasPho){
			  hasPho=true;
			  npassPho +=1;
			  signalPho = itpho;
            }
		  }
          if(FSRVeto && (!PixelVeto || !GSFveto))proxyPhoCollection.push_back(itpho);
        }
        
        bool hasMu(false);
        std::vector<recoMuon>::iterator signalMu = Muon.begin();
        std::vector< std::vector<recoMuon>::iterator > proxyMuonCollection;
        proxyMuonCollection.clear();
		for(std::vector<recoMuon>::iterator itMu = Muon.begin(); itMu != Muon.end(); itMu++){
		  if(hasMu)break;
		  if(itMu->passSignalSelection()){
			proxyMuonCollection.push_back(itMu);
			if(!hasMu && hasPho){
			  hasMu=true; 
			  npassMu +=1;
			  signalMu = itMu;
			}
		  }
		}

        bool saveMC(false);

        if(hasPho && hasMu){
            double dRmg = DeltaR(signalPho->getEta(), signalPho->getPhi(), signalMu->getEta(), signalMu->getPhi());
            p_PhoLepDeltaR->Fill(dRmg);

            if(dRmg>0.8){
               npassdR+=1;
               p_PhoLepMass->Fill((signalPho->getCalibP4()+signalMu->getP4()).M());
               if(METFilter == 0){ 
				 npassMETFilter +=1;
                 if(fabs((signalPho->getCalibP4()+signalMu->getP4()).M() - 91.188) > 10.0)npassZ+=1;

				 float deltaPhi = DeltaPhi(signalMu->getPhi(), METPhi);
				 float MT = sqrt(2*MET*signalMu->getPt()*(1-std::cos(deltaPhi)));

				 phoEt = signalPho->getCalibEt();
				 phoEta= signalPho->getEta();
				 phoPhi= signalPho->getPhi();
				 lepPt = signalMu->getPt();
				 lepEta= signalMu->getEta();
				 lepPhi= signalMu->getPhi();
				 sigMT = MT;
				 sigMET= MET;
				 sigMETPhi = METPhi;
				 dPhiLepMET = deltaPhi;
				 nVertex = nVtx;
				 nJet = jetNumber;

				 p_photonEt->Fill(signalPho->getCalibEt());
				 p_photonEta->Fill(signalPho->getEta());
				 p_lepPt->Fill(signalMu->getPt());
				 p_lepEta->Fill(signalMu->getEta());
				 p_Mt->Fill(MT);
				 p_MET->Fill(MET);

				 sigtree->Fill();

				 if(datatype == MC)saveMC=true;
               }//MET Filter
             }//dR Filter
          }//Candidate Filter
       
		  for(unsigned ip(0); ip < proxyPhoCollection.size(); ip++){
			for(unsigned ie(0); ie < proxyMuonCollection.size(); ie++){
			  std::vector<recoPhoton>::iterator proxyPho = proxyPhoCollection[ip];
			  std::vector<recoMuon>::iterator proxyMuon = proxyMuonCollection[ie];
			  double dRmg = DeltaR(proxyPho->getEta(), proxyPho->getPhi(), proxyMuon->getEta(), proxyMuon->getPhi());
			  if(dRmg>0.8){
				if(METFilter == 0){

				  float proxy_deltaPhi = DeltaPhi(proxyMuon->getPhi(), METPhi);
				  float proxy_MT = sqrt(2*MET*proxyMuon->getPt()*(1-std::cos(proxy_deltaPhi)));
				  proxyphoEt = proxyPho->getCalibEt();
				  proxyphoEta= proxyPho->getEta();
				  proxyphoPhi= proxyPho->getPhi();
				  proxylepPt = proxyMuon->getPt();
				  proxylepEta= proxyMuon->getEta();
				  proxylepPhi= proxyMuon->getPhi();
				  proxysigMT = proxy_MT;
				  proxysigMET= MET;
				  proxysigMETPhi = METPhi;
				  proxydPhiLepMET = proxy_deltaPhi; 
				  proxynVertex = nVtx; 
				  proxydRPhoLep= dRmg;
				  proxynJet = jetNumber; 
				  proxytree->Fill();

				  if(datatype == MC)saveMC=true;
				}//MET Filter
			  }//dR filter
			}// loop on ele collection
		  } // loop on pho collection
   
		  for(unsigned ip(0); ip < jetPhoCollection.size(); ip++){
			for(unsigned ie(0); ie < proxyMuonCollection.size(); ie++){
			  std::vector<recoPhoton>::iterator jetPho = jetPhoCollection[ip];
			  std::vector<recoMuon>::iterator jetMuon = proxyMuonCollection[ie];
			  double dRmg = DeltaR(jetPho->getEta(), jetPho->getPhi(), jetMuon->getEta(), jetMuon->getPhi());
			  if(dRmg>0.8){
				if(METFilter == 0){

				  float jet_deltaPhi = DeltaPhi(jetMuon->getPhi(), METPhi);
				  float jet_MT = sqrt(2*MET*jetMuon->getPt()*(1-std::cos(jet_deltaPhi)));
				  jetphoEt = jetPho->getCalibEt();
				  jetphoEta= jetPho->getEta();
				  jetphoPhi= jetPho->getPhi();
				  jetlepPt = jetMuon->getPt();
				  jetlepEta= jetMuon->getEta();
				  jetlepPhi= jetMuon->getPhi();
				  jetsigMT = jet_MT;
				  jetsigMET= MET;
				  jetsigMETPhi = METPhi;
				  jetdPhiLepMET = jet_deltaPhi; 
				  jetnVertex = nVtx; 
				  jetdRPhoLep= dRmg;
				  jetnJet = jetNumber; 
                  jettree->Fill();

				  if(datatype == MC)saveMC=true;
				}//MET Filter
			  }//dR filter
			}// loop on ele collection
		  } // loop on pho collection


		  if(datatype == MC && saveMC==true){
			mcPID.clear();
			mcEta.clear();
			mcPhi.clear();
			mcPt.clear();
			mcMomPID.clear();
			for(std::vector<mcData>::iterator itMC = MCData.begin(); itMC!= MCData.end(); itMC++){
			  for(unsigned ip(0); ip < mcmatchPhoCollection.size(); ip++){
				std::vector<recoPhoton>::iterator itPho = mcmatchPhoCollection[ip];
				float mcdR = DeltaR(itPho->getEta(), itPho->getPhi(), itMC->getEta(), itMC->getPhi());
				if(mcdR < 0.3){
				  mcPID.push_back(itMC->getPID());
				  mcMomPID.push_back(itMC->getMomPID());
				  mcEta.push_back(itMC->getEta());      
				  mcPhi.push_back(itMC->getPhi());
				  mcPt.push_back(itMC->getEt());
				}
			  }
			}
			mctree->Fill();
		  }
 
	}//loop on  events

p_eventcount->Fill("Total",nTotal);
p_eventcount->Fill("passHLT",npassHLT);
p_eventcount->Fill("passPho",npassPho);
p_eventcount->Fill("passMuon",npassMu);
p_eventcount->Fill("passdR",npassdR);
p_eventcount->Fill("passMETFilter",npassMETFilter);
p_eventcount->Fill("passZ",npassZ);

outputfile->Write();
logfile.close();
}
示例#9
0
void Test() {
  
  TString bgdInputFile    = "samples/backgroundA_3l.root";
  TString dataInputFile   = "samples/data_3l.root";
  TString sigInputFile   =  "samples/hww125.root";
  
  SmurfTree background;
  background.LoadTree(bgdInputFile,-1);
  background.InitTree(0);
  
  SmurfTree data;
  data.LoadTree(dataInputFile,-1);
  data.InitTree(0);
  
  SmurfTree signal;
  signal.LoadTree(sigInputFile,-1);
  signal.InitTree(0);
  
  char output[200];
  sprintf(output,"histo_test.root");     
  TFile* outFileNjets = new TFile(output,"recreate");
  
  TH1F* types = new TH1F("types", "types", 80, -0.5 , 79.5);
  types->Sumw2();
  
  TH1D* bckg_met = new TH1D("bckg_met", "MET", 200, 0, 200);
  bckg_met->Sumw2();
  TH1D* bckg_mllz = new TH1D("bckg_mllz", "m_{ll}", 200, 0, 200);
  bckg_mllz->Sumw2();
  TH1D* bckg_mt = new TH1D("bckg_mt", "m_t", 200, 0, 200);
  bckg_mt->Sumw2();
  TH1D* bckg_ptjet = new TH1D("bckg_ptjet", "P_t of leading jet", 200, 0, 200);
  bckg_ptjet->Sumw2();
  TH1D* bckg_mH = new TH1D("bckg_mH", "m_H", 200, 0, 400);
  bckg_mH->Sumw2();
  TH1D* bckg_mjj = new TH1D("bckg_mjj", "m_jj", 200, 0, 400);
  bckg_mjj->Sumw2();
  TH1D* bckg_dphill = new TH1D("bckg_dphill", "#Delta#phi_{ll}", 200, 0, 3.5);
  bckg_dphill->Sumw2();
  
  TH2D* bckg_mll_mh  = new TH2D("bckg_mll_mh", " ", 100, 40, 120, 100, 0, 200);
  
  TH1D* sig_met = new TH1D("sig_met", "MET", 200, 0, 200);
  sig_met->Sumw2();
  TH1D* sig_mllz = new TH1D("sig_mllz", "m_{ll}", 200, 0, 200);
  sig_mllz->Sumw2();
  TH1D* sig_mt = new TH1D("sig_mt", "m_t", 200, 0, 200);
  sig_mt->Sumw2();
  TH1D* sig_ptjet = new TH1D("sig_ptjet", "P_t of leading jet", 200, 0, 200);
  sig_ptjet->Sumw2();
  TH1D* sig_mH = new TH1D("sig_mH", "m_H", 200, 0, 400);
  sig_mH->Sumw2();
  TH1D* sig_mjj = new TH1D("sig_mjj", "m_jj", 200, 0, 400);
  sig_mjj->Sumw2();
  TH1D* sig_dphill = new TH1D("sig_dphill", "#Delta#phi_{ll}", 200, 0, 3.5);
  sig_dphill->Sumw2();

  TH2D* sig_mll_mh  = new TH2D("sig_mll_mh", " ",100, 40, 120, 100, 0, 200);
  

  double lumi = 12.1;
  double weight = 1;
  double eventsPass = 0;
  int nBgd=background.tree_->GetEntries();
  for (int i=0; i<nBgd; ++i) {
    
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nBgd);
    background.tree_->GetEntry(i);
    if (background.njets_ <2 )continue;
    if (!((background.cuts_ & SmurfTree::Lep1FullSelection) == SmurfTree::Lep1FullSelection 
	  && (background.cuts_ & SmurfTree::Lep2FullSelection) == SmurfTree::Lep2FullSelection) ) continue;
  
    weight = 1;
    
    int nFake = 0;
    if(((background.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (background.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (background.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (background.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (background.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (background.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((background.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (background.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if (nFake !=0) continue; 
    
    if (nFake > 1) continue; 
    if (nFake == 1) weight = lumi*background.scale1fb_*background.sfWeightPU_*background.sfWeightEff_*background.sfWeightTrig_*background.sfWeightFR_ ;
    else weight = lumi*background.scale1fb_*background.sfWeightPU_*background.sfWeightEff_*background.sfWeightTrig_;
    //weight = lumi*background.scale1fb_*background.sfWeightPU_*background.sfWeightEff_*background.sfWeightTrig_;
  
    if (background.lid3_ == background.lid2_ && background.lid3_ == background.lid1_) continue;
    if (background.lid3_ == background.lid2_ && fabs(background.lid3_) != fabs(background.lid1_)) continue;
    if (background.lid3_ == background.lid1_ && fabs(background.lid3_) != fabs(background.lid2_)) continue;
    if (background.lid2_ == background.lid1_ && fabs(background.lid2_) != fabs(background.lid3_)) continue;
    
    
    double m[3] = {0, 0, 0};
    LorentzVector pair1, pair2, pair3;
    if (fabs(background.lid1_) == fabs(background.lid2_) && background.lq1_*background.lq2_ < 0){
      pair1 = background.lep1_ + background.lep2_ ;
      m[0] = pair1.M();
    }
    if (fabs(background.lid2_) == fabs(background.lid3_) && background.lq2_*background.lq3_ < 0){
      pair2 = background.lep2_ + background.lep3_ ;
      m[1] = pair2.M();
    }
    if (fabs(background.lid1_) == fabs(background.lid3_) && background.lq1_*background.lq3_ < 0){
      pair3 = background.lep1_ + background.lep3_ ;
      m[2] = pair3.M();
    }
    
    if ( (m[0] < 80 || m[0] > 100) &&  (m[1] < 80 || m[1] > 100) &&  (m[2] < 80 || m[2] > 100)) continue;
    //if ( (m[0] < 40 || m[0] > 120) &&  (m[1] < 40 || m[1] > 120) &&  (m[2] < 40 || m[2] > 120)) continue;
    
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
   
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
    if (min == fabs(mz - m[0])){  pair = pair1; mt =  background.mt3_; tlepton = background.lep3_;} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  background.mt1_; tlepton = background.lep1_;} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  background.mt2_; tlepton = background.lep2_;} 
    pairjet = background.jet1_+ background.jet2_;
    
    if (mt < 40 || background.met_ < 25) continue;
    //     if (mt < 40 ) continue;

    // if (pairjet.M() < 65 || pairjet.M() > 95) continue;
  
    types->Fill(background.dstype_);
    bckg_met->Fill(background.met_, weight);
    bckg_mllz->Fill(pair.M(), weight);
    bckg_mt->Fill(mt, weight);
    bckg_ptjet->Fill(background.jet1_.Pt(), weight);
    LorentzVector metvector(background.met_*cos(background.metPhi_), background.met_*sin(background.metPhi_), 0, 0);
    LorentzVector higgsSystem = tlepton + metvector + background.jet1_  + background.jet2_;
    bckg_mH->Fill(higgsSystem.M(), weight);
    bckg_mjj->Fill(pairjet.M(), weight);
    bckg_dphill->Fill(DeltaPhi(pairjet.Phi(),tlepton.Phi()), weight);
    bckg_mll_mh->Fill(pair.M(),higgsSystem.M(), weight); 
    eventsPass += weight;
 
  }
  cout << eventsPass << " background events in " << lumi << " fb" << endl; 
  
  
  int nSig=signal.tree_->GetEntries();
  int nTotal = 0;
  int nZH = 0;
  double eventsPassSig = 0;
  for (int i=0; i<nSig; ++i) {
    
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nSig);
    signal.tree_->GetEntry(i);
    
    nTotal++;
    if(signal.processId_==24)  nZH++;
    
    if (signal.njets_ < 2 )continue;

    if(!((signal.cuts_ & SmurfTree::Lep1FullSelection) == SmurfTree::Lep1FullSelection 
	 &&(signal.cuts_ & SmurfTree::Lep2FullSelection) == SmurfTree::Lep2FullSelection)) continue;
     
    
     
    weight = 1;
    
    int nFake = 0;
    if(((signal.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (signal.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((signal.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (signal.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((signal.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (signal.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((signal.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (signal.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((signal.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (signal.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((signal.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (signal.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;

    weight = lumi*signal.scale1fb_*signal.sfWeightPU_*signal.sfWeightEff_*signal.sfWeightTrig_;
    
    
    if (signal.lid3_ == signal.lid2_ && signal.lid3_ == signal.lid1_) continue;
    if (signal.lid3_ == signal.lid2_ && fabs(signal.lid3_) != fabs(signal.lid1_)) continue;
    if (signal.lid3_ == signal.lid1_ && fabs(signal.lid3_) != fabs(signal.lid2_)) continue;
    if (signal.lid2_ == signal.lid1_ && fabs(signal.lid2_) != fabs(signal.lid3_)) continue;
    
    double m[3] = {0, 0, 0};
    LorentzVector pair1, pair2, pair3;
    if (fabs(signal.lid1_) == fabs(signal.lid2_) && signal.lq1_*signal.lq2_ < 0){
      pair1 = signal.lep1_ + signal.lep2_ ;
      m[0] = pair1.M();
    }
    if (fabs(signal.lid2_) == fabs(signal.lid3_) && signal.lq2_*signal.lq3_ < 0){
      pair2 = signal.lep2_ + signal.lep3_ ;
      m[1] = pair2.M();
    }
    if (fabs(signal.lid1_) == fabs(signal.lid3_) && signal.lq1_*signal.lq3_ < 0){
      pair3 = signal.lep1_ + signal.lep3_ ;
      m[2] = pair3.M();
    }
    
    if ( (m[0] < 80 || m[0] > 100) &&  (m[1] < 80 || m[1] > 100) &&  (m[2] < 80 || m[2] > 100)) continue;
    //   if ( (m[0] < 40 || m[0] > 120) &&  (m[1] < 40 || m[1] > 120) &&  (m[2] < 40 || m[2] > 120)) continue;
        
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
    
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
    if (min == fabs(mz - m[0])){  pair = pair1; mt =  signal.mt3_; tlepton = signal.lep3_;} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  signal.mt1_; tlepton = signal.lep1_;} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  signal.mt2_; tlepton = signal.lep2_;} 
    pairjet = signal.jet1_+ signal.jet2_;
        
     
    if (mt < 40 || signal.met_ < 25) continue;
    // if (mt < 40 ) continue;
    //if (pairjet.M() < 65 || pairjet.M() > 95) continue;
    
    types->Fill(signal.dstype_);
    sig_met->Fill(signal.met_, weight);
    sig_mllz->Fill(pair.M(), weight);
    sig_mt->Fill(mt, weight);
    sig_ptjet->Fill(signal.jet1_.Pt(), weight);  
    LorentzVector metvector(signal.met_*cos(signal.metPhi_), signal.met_*sin(signal.metPhi_), 0, 0);
    LorentzVector higgsSystem = tlepton + metvector + signal.jet1_  + signal.jet2_;
    sig_mH->Fill(higgsSystem.M(), weight);
    sig_mjj->Fill(pairjet.M(), weight);
    sig_dphill->Fill(DeltaPhi(pairjet.Phi(),tlepton.Phi()), weight);
    sig_mll_mh->Fill(pair.M(),higgsSystem.M(), weight); 
    //    cout << signal.njets_ << " - " ;
    eventsPassSig += weight;
  }
  cout << endl;
  
  cout << eventsPassSig << " signal events in " << lumi << " fb" << endl; 
  cout << nTotal << "events, from which " << nZH << "are ZH" << endl;
  int nData=data.tree_->GetEntries();
  double eventsPassData = 0;
  for (int i=0; i<nData; ++i) {
    
    if (i%100000 == 0 && verboseLevel > 0)
      printf("--- reading event %5d of %5d\n",i,nData);
    data.tree_->GetEntry(i);
    if (data.njets_ < 2 )continue;

    if(!((data.cuts_ & SmurfTree::Lep1FullSelection) == SmurfTree::Lep1FullSelection 
	 && (data.cuts_ & SmurfTree::Lep2FullSelection) == SmurfTree::Lep2FullSelection)) continue;

    
    weight = 1;

    int nFake = 0;
    if(((data.cuts_ & SmurfTree::Lep1LooseMuV2)  == SmurfTree::Lep1LooseMuV2)  && (data.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((data.cuts_ & SmurfTree::Lep2LooseMuV2)  == SmurfTree::Lep2LooseMuV2)  && (data.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((data.cuts_ & SmurfTree::Lep3LooseMuV2)  == SmurfTree::Lep3LooseMuV2)  && (data.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if(((data.cuts_ & SmurfTree::Lep1LooseEleV4) == SmurfTree::Lep1LooseEleV4) && (data.cuts_ & SmurfTree::Lep1FullSelection) != SmurfTree::Lep1FullSelection) nFake++;
    if(((data.cuts_ & SmurfTree::Lep2LooseEleV4) == SmurfTree::Lep2LooseEleV4) && (data.cuts_ & SmurfTree::Lep2FullSelection) != SmurfTree::Lep2FullSelection) nFake++;
    if(((data.cuts_ & SmurfTree::Lep3LooseEleV4) == SmurfTree::Lep3LooseEleV4) && (data.cuts_ & SmurfTree::Lep3FullSelection) != SmurfTree::Lep3FullSelection) nFake++;
    if (nFake !=0) continue; 
 
    if (data.lid3_ == data.lid2_ && data.lid3_ == data.lid1_) continue;
    if (data.lid3_ == data.lid2_ && fabs(data.lid3_) != fabs(data.lid1_)) continue;
    if (data.lid3_ == data.lid1_ && fabs(data.lid3_) != fabs(data.lid2_)) continue;
    if (data.lid2_ == data.lid1_ && fabs(data.lid2_) != fabs(data.lid3_)) continue;
    
    double m[3] = {0, 0, 0};
    LorentzVector pair1, pair2, pair3;
    if (fabs(data.lid1_) == fabs(data.lid2_) && data.lq1_*data.lq2_ < 0){
      pair1 = data.lep1_ + data.lep2_ ;
      m[0] = pair1.M();
    }
    if (fabs(data.lid2_) == fabs(data.lid3_) && data.lq2_*data.lq3_ < 0){
      pair2 = data.lep2_ + data.lep3_ ;
      m[1] = pair2.M();
    }
    if (fabs(data.lid1_) == fabs(data.lid3_) && data.lq1_*data.lq3_ < 0){
      pair3 = data.lep1_ + data.lep3_ ;
      m[2] = pair3.M();
    }
    
    if ( (m[0] < 80 || m[0] > 100) &&  (m[1] < 80 || m[1] > 100) &&  (m[2] < 80 || m[2] > 100)) continue;
    //   if ( (m[0] < 40 || m[0] > 120) &&  (m[1] < 40 || m[1] > 120) &&  (m[2] < 40 || m[2] > 120)) continue;    
    double min = TMath::Min(TMath::Min(fabs(mz -m[0]), fabs(mz-m[1])), TMath::Min(fabs(mz -m[0]), fabs(mz-m[2])));
    
    LorentzVector pair, tlepton, pairjet;
    double mt = 0;
    if (min == fabs(mz - m[0])){  pair = pair1; mt =  data.mt3_; tlepton = data.lep3_;} 
    else if (min == fabs(mz - m[1])){  pair = pair2;  mt =  data.mt1_; tlepton = data.lep1_;} 
    else if (min == fabs(mz - m[2])){  pair = pair3;  mt =  data.mt2_; tlepton = data.lep2_;} 
    pairjet = data.jet1_+ data.jet2_;
        
    
    if (mt < 40 || data.met_ < 25) continue;
    //   if (mt < 40 ) continue;
    //  if (pairjet.M() < 65 || pairjet.M() > 95) continue;

    eventsPassData += weight;
  }
  
  cout << eventsPassData << " data events in " << lumi << " fb" << endl; 

  outFileNjets->Write();
  outFileNjets->Close();
  
  
}
示例#10
0
bool Electron::PassUserID_HEEPv6p1 (bool verbose){
  // See: https://twiki.cern.ch/twiki/bin/viewauth/CMS/HEEPElectronIdentificationRun2
  // apply cuts manually based on variables here
  // this is version 6.1

  //----------------------------------------------------------------------
  //  Bools that are the same whether barrel or endcap
  //----------------------------------------------------------------------
  
  bool pass_et            = bool ( PtHeep()              >  35.0 );
  bool pass_ecalDriven    = bool ( EcalSeed()        == 1    );
  bool pass_deltaPhi      = bool ( fabs (DeltaPhi()) <  0.06 ); // dPhiSCTrkAtVtx
  bool pass_missingHits   = bool ( MissingHits()     <= 1    );

  //----------------------------------------------------------------------
  // Bools that depend on barrel vs. endcap
  //----------------------------------------------------------------------
  
  bool pass_deltaEtaSeed  = false;
  bool pass_sigmaIEtaIEta = false;
  bool pass_shape         = false;
  bool pass_shape1        = false;
  bool pass_shape2        = false;
  bool pass_caloIsolation = false;
  bool pass_dxy           = false;
  bool pass_hoe           = false;
  bool pass_trkIsolation  = false;
  
  double caloIsolation = EcalIsoDR03() + HcalIsoD1DR03();
  
  //----------------------------------------------------------------------
  // Barrel electrons
  //----------------------------------------------------------------------
  
  if ( fabs(SCEta()) < 1.4442 ){
    pass_deltaEtaSeed      = bool ( fabs(DeltaEtaSeed() )     < 0.004 );
    pass_hoe               = bool ( HoE()            < 1/SCEnergy() + 0.05 );
    pass_sigmaIEtaIEta     = true;
    pass_shape1            = bool ( Full5x5E1x5OverE5x5()        > 0.83  );
    pass_shape2            = bool ( Full5x5E2x5OverE5x5()        > 0.94  );
    pass_shape             = bool ( pass_shape1 || pass_shape2    );
    pass_caloIsolation     = bool ( caloIsolation < ( 2.0 + ( 0.03 * PtHeep() ) + (0.28 * RhoForHEEP() ) ) );
    pass_dxy               = bool ( fabs(LeadVtxDistXY()) < 0.02  );
    pass_trkIsolation      = bool ( PtHeep() < 95 ? TrkIsoDR03() < 5 : TrkIsoDR03() < 5+1.5*RhoForHEEP());
  }
  
  //----------------------------------------------------------------------
  // Endcap electrons
  //----------------------------------------------------------------------
  
  else if ( fabs(SCEta()) > 1.566 && fabs(SCEta()) < 2.5 ){ 
    pass_deltaEtaSeed      = bool ( fabs (DeltaEtaSeed())     < 0.006 );
    pass_hoe               = bool ( HoE()            < 5/SCEnergy() + 0.05 );
    pass_sigmaIEtaIEta     = bool ( Full5x5SigmaIEtaIEta()       < 0.03  );
    pass_shape             = true;
    if   ( PtHeep()  < 50 ) {
      pass_caloIsolation = bool ( caloIsolation < ( 2.5 + 
						    ( 0.28 * RhoForHEEP() ) ) );
    }
    else                { 
      pass_caloIsolation = bool ( caloIsolation < ( 2.5 + 
						    ( 0.28 * RhoForHEEP() ) + 
						    ( 0.03 * (PtHeep() - 50.0 ) ) ) );
    }
    pass_dxy               = bool ( fabs(LeadVtxDistXY()) < 0.05  );
    pass_trkIsolation      = bool ( PtHeep() < 100 ? TrkIsoDR03() < 5 : TrkIsoDR03() < 5+0.5*RhoForHEEP());
  }

  bool decision = (pass_et            && 
		   pass_ecalDriven    && 
		   pass_deltaEtaSeed  && 
		   pass_deltaPhi      && 
		   pass_hoe           && 
		   pass_sigmaIEtaIEta && 
		   pass_shape         && 
		   pass_dxy           && 
		   pass_missingHits   && 
		   pass_trkIsolation  && 
		   pass_caloIsolation ); 

  if ( verbose ) {
    if ( decision ) std::cout << "Electron #" << m_raw_index << " PASS HEEPID" << std::endl;
    else { 
      std::cout << "Electron #" << m_raw_index << " FAIL HEEPID" << std::endl;
      if ( !pass_et            ) std::cout << "\tfail et            " << std::endl;
      if ( !pass_ecalDriven    ) std::cout << "\tfail ecalDriven    " << std::endl;
      if ( !pass_deltaEtaSeed  ) std::cout << "\tfail deltaEtaSeed  " << std::endl;
      if ( !pass_deltaPhi      ) std::cout << "\tfail deltaPhi      " << std::endl;
      if ( !pass_hoe           ) std::cout << "\tfail hoe           " << std::endl;
      if ( !pass_sigmaIEtaIEta ) std::cout << "\tfail sigmaIEtaIEta " << std::endl;
      if ( !pass_shape         ) std::cout << "\tfail shape         " << std::endl;
      if ( !pass_dxy           ) std::cout << "\tfail dxy           " << std::endl;
      if ( !pass_missingHits   ) std::cout << "\tfail missingHits   " << std::endl;
      if ( !pass_trkIsolation  ) std::cout << "\tfail trkIsolation  " << std::endl;
      if ( !pass_caloIsolation ) std::cout << "\tfail caloIsolation " << std::endl;
    }
  }
  
  return decision;
}
示例#11
0
bool Electron::PassUserID_EGamma ( ID id, bool verbose ){

  //----------------------------------------------------------------------
  // Barrel electron cut values
  //----------------------------------------------------------------------
  // See: https://twiki.cern.ch/twiki/bin/viewauth/CMS/CutBasedElectronIdentificationRun2
  double l_b_f5x5sieie   [4] = {0.011100, 0.010557, 0.010399, 0.010181 };
  double l_b_dEtaIn      [4] = {0.016315, 0.012442, 0.007641, 0.006574 };
  double l_b_dPhiIn      [4] = {0.252044, 0.072624, 0.032643, 0.022868 };
  double l_b_hoe         [4] = {0.345843, 0.121476, 0.060662, 0.037553 };
  double l_b_pfRelIso    [4] = {0.164369, 0.120026, 0.097213, 0.074355 };
  double l_b_ooemoop     [4] = {0.248070, 0.221803, 0.153897, 0.131191 };
  double l_b_d0          [4] = {0.060279, 0.022664, 0.011811, 0.009924 };
  double l_b_dZ          [4] = {0.800538, 0.173670, 0.070775, 0.015310 };
  int    l_b_missHits    [4] = {2,   1,   1,   1}; 

  //----------------------------------------------------------------------
  // Endcap electron cut values
  //----------------------------------------------------------------------
  double l_e_f5x5sieie   [4] = {0.033987,  0.032602,  0.029524,  0.028766 };
  double l_e_dEtaIn      [4] = {0.010671,  0.010654,  0.009285,  0.005681 };
  double l_e_dPhiIn      [4] = {0.245263,  0.145129,  0.042447,  0.032046 };
  double l_e_hoe         [4] = {0.134691,  0.131862,  0.104263,  0.081902 };
  double l_e_pfRelIso    [4] = {0.212604,  0.162914,  0.116708,  0.090185 };
  double l_e_ooemoop     [4] = {0.157160,  0.142283,  0.137468,  0.106055 };
  double l_e_d0          [4] = {0.273097,  0.097358,  0.051682,  0.027261 };
  double l_e_dZ          [4] = {0.885860,  0.198444,  0.180720,  0.147154 };
  int    l_e_missHits    [4] = {3,   1,   1,   1}; 
  
  
  //----------------------------------------------------------------------
  // Bools that depend on barrel vs. endcap
  //----------------------------------------------------------------------

  bool   pass_full5x5SigmaIetaIeta = false;
  bool   pass_deltaEta             = false;
  bool   pass_deltaPhi             = false;
  bool   pass_hoe                  = false;
  bool   pass_pfIsoWBetaOverPt     = false;
  bool   pass_ooEmooP              = false;
  bool   pass_vtxDistXY            = false; // aka d0
  bool   pass_vtxDistZ             = false;
  bool   pass_missingHits          = false;
  bool   pass_convVeto             = false;

  //----------------------------------------------------------------------
  // Define EGamma ep parameter
  //----------------------------------------------------------------------
  const float ecal_energy_inverse = 1.0/EcalEnergy();
  const float eSCoverP = ESuperClusterOverP();
  const float ooEmooP = std::abs(1.0 - eSCoverP)*ecal_energy_inverse;

  //----------------------------------------------------------------------
  // Define DeltaBeta PF Isolation
  //----------------------------------------------------------------------
  double ptCutoff = 20.0;
  double deltaBetaConstant = 0.5;
  bool relativeIso = true;
  //
  const float chad = PFChargedHadronIso03();
  const float nhad = PFNeutralHadronIso03();
  const float pho = PFPhotonIso03();
  const float puchad = PFPUIso03();
  float iso = chad + std::max(0.0, nhad + pho - deltaBetaConstant*puchad);
  if(relativeIso) iso /= Pt();
  
  //----------------------------------------------------------------------
  // Barrel electron test
  //----------------------------------------------------------------------

  if ( fabs(SCEta()) < 1.479 ){
    pass_full5x5SigmaIetaIeta = bool ( Full5x5SigmaIEtaIEta() < l_b_f5x5sieie [ id ] );
    pass_deltaEta             = bool ( fabs(DeltaEta())       < l_b_dEtaIn    [ id ] );
    pass_deltaPhi             = bool ( fabs(DeltaPhi())       < l_b_dPhiIn    [ id ] );
    pass_hoe                  = bool ( HoE()                  < l_b_hoe       [ id ] );
    pass_pfIsoWBetaOverPt     = bool ( ooEmooP                < l_b_ooemoop   [ id ] );
    pass_ooEmooP              = bool ( iso                    < l_b_pfRelIso  [ id ] );
    pass_vtxDistXY            = bool ( fabs(VtxDistXY())      < l_b_d0        [ id ] );
    pass_vtxDistZ             = bool ( fabs(VtxDistZ ())      < l_b_dZ        [ id ] );
    pass_missingHits          = bool ( MissingHits()          < l_b_missHits  [ id ] );
    pass_convVeto             = ! HasMatchedConvPhot();
  } 

  //----------------------------------------------------------------------
  // Endcap electron test
  //----------------------------------------------------------------------

  else if ( fabs(SCEta()) > 1.479 && fabs(SCEta()) < 2.5 ){ 
    pass_full5x5SigmaIetaIeta = bool ( Full5x5SigmaIEtaIEta() < l_e_f5x5sieie [ id ] );
    pass_deltaEta             = bool ( fabs(DeltaEta())       < l_e_dEtaIn    [ id ] );
    pass_deltaPhi             = bool ( fabs(DeltaPhi())       < l_e_dPhiIn    [ id ] );
    pass_hoe                  = bool ( HoE()                  < l_e_hoe       [ id ] );
    pass_pfIsoWBetaOverPt     = bool ( ooEmooP                < l_e_ooemoop   [ id ] );
    pass_ooEmooP              = bool ( iso                    < l_e_pfRelIso  [ id ] );
    pass_vtxDistXY            = bool ( fabs(VtxDistXY())      < l_e_d0        [ id ] );
    pass_vtxDistZ             = bool ( fabs(VtxDistZ ())      < l_e_dZ        [ id ] );
    pass_missingHits          = bool ( MissingHits()          < l_e_missHits  [ id ] );
    pass_convVeto             = ! HasMatchedConvPhot();
  }

  bool decision = ( 
    pass_full5x5SigmaIetaIeta && 
    pass_deltaEta             && 
    pass_deltaPhi             && 
    pass_hoe                  && 
    pass_pfIsoWBetaOverPt     && 
    pass_ooEmooP              && 
    pass_vtxDistXY            && 
    pass_vtxDistZ             && 
    pass_missingHits          && 
    pass_convVeto             );
  
  return decision;
  
}