Example #1
0
Mass JetInfo::TrackMass() const
{
    DEBUG0;
    LorentzVector<Momentum> jet;
    for (auto const &constituent : Constituents()) if (constituent.DetectorPart() == DetectorPart::track) jet += constituent.Momentum();
    return jet.Mass();
}
Example #2
0
float deltaR(LorentzVector jet1, LorentzVector jet2){
  // From cmssw reco::deltaPhi()
  float dphi = jet1.Phi() - jet2.Phi();
  while( dphi >   TMath::Pi() ) dphi -= TMath::TwoPi();
  while( dphi <= -TMath::Pi() ) dphi += TMath::TwoPi();
  return TMath::Sqrt(TMath::Power(dphi,2)+TMath::Power(jet1.Eta()-jet2.Eta(),2));
}
Example #3
0
double ComputeMT(LorentzVector p1, float met, float metphi) {
    double dPhi = deltaPhi(p1.Phi(), metphi);
    // 43.61 of pdg.lbl.gov/2013/reviews/rpp2012-rev-kinematics.pdf
    return sqrt( 2.0 * p1.Pt() * met * (1.0-cos(dPhi)) );
}
Example #4
0
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();
 
}
Example #5
0
float dRbetweenVectors(LorentzVector& vec1,LorentzVector& vec2 ){                                                                                                              
  float dphi = std::min(::fabs(vec1.Phi() - vec2.Phi()), 2 * M_PI - fabs(vec1.Phi() - vec2.Phi()));
  float deta = vec1.Eta() - vec2.Eta();

  return sqrt(dphi*dphi + deta*deta);
}
Example #6
0
int ScanChain( TChain* chain, bool fast = true, int nEvents = -1, string skimFilePrefix = "test") {

  int currentrun = -1;
  bool DCSonly = false;//KEEP THIS FALSE
  // Benchmark
  TBenchmark *bmark = new TBenchmark();
  bmark->Start("benchmark");

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

  map<string, TH1F*> histos;
  vector<string> histonames; histonames.clear();
  vector<int> hbins; hbins.clear();
  vector<float> hlow; hlow.clear();
  vector<float> hup; hup.clear();
  histonames.push_back("Mll");                       hbins.push_back(75); hlow.push_back(  15.); hup.push_back(390);
  histonames.push_back("Mud0");                      hbins.push_back(40); hlow.push_back( -0.4); hup.push_back(0.4);
  histonames.push_back("MudZ");                      hbins.push_back(40); hlow.push_back(  -1.); hup.push_back(1. );
  histonames.push_back("MuIP3d");                    hbins.push_back(40); hlow.push_back( -0.5); hup.push_back(0.5);
  histonames.push_back("MuRelIso03");                hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso03EA");              hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso03DB");              hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuMiniIsoEA");               hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuMiniIsoDB");               hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso04");                hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuAnnulus04");               hbins.push_back(25); hlow.push_back(   0.); hup.push_back(1. );
  histonames.push_back("MuRelIso03_MT30");           hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso03EA_MT30");         hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso03DB_MT30");         hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuMiniIsoEA_MT30");          hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuMiniIsoDB_MT30");          hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuRelIso04_MT30");           hbins.push_back(50); hlow.push_back(   0.); hup.push_back(2. );
  histonames.push_back("MuAnnulus04_MT30");          hbins.push_back(25); hlow.push_back(   0.); hup.push_back(1. );
  histonames.push_back("MuID");                      hbins.push_back( 7); hlow.push_back(  -1.); hup.push_back(6. );
  histonames.push_back("MuvalidFraction");           hbins.push_back(25); hlow.push_back(   0.); hup.push_back(1. );
  histonames.push_back("MuisPF");                    hbins.push_back( 5); hlow.push_back(  -1.); hup.push_back(4. );
  histonames.push_back("Mugfit_normchi2");           hbins.push_back(40); hlow.push_back(   0.); hup.push_back(20.);
  histonames.push_back("Mugfit_validSTAHits");       hbins.push_back(10); hlow.push_back(   0.); hup.push_back(10.);
  histonames.push_back("MunumberOfMatchedStations"); hbins.push_back(10); hlow.push_back(   0.); hup.push_back(10.);
  histonames.push_back("Munlayers");                 hbins.push_back(20); hlow.push_back(   0.); hup.push_back(20.);
  histonames.push_back("Muchi2LocalPosition");       hbins.push_back(40); hlow.push_back(   0.); hup.push_back(40.);
  histonames.push_back("MutrkKink");                 hbins.push_back(50); hlow.push_back(   0.); hup.push_back(50.);
  histonames.push_back("MusegmCompatibility");       hbins.push_back(35); hlow.push_back(   0.); hup.push_back(1.4);
  histonames.push_back("MuvalidPixelHits");          hbins.push_back( 5); hlow.push_back(   0.); hup.push_back(5. );
  histonames.push_back("MuPt");                      hbins.push_back(30); hlow.push_back(   0.); hup.push_back(600);
  histonames.push_back("MuEta");                     hbins.push_back(60); hlow.push_back(   3.); hup.push_back(3. );
  histonames.push_back("MuPhi");                     hbins.push_back(32); hlow.push_back( -3.2); hup.push_back(3.2);
  histonames.push_back("MuCharge");                  hbins.push_back( 6); hlow.push_back(  -2.); hup.push_back(4. );
  histonames.push_back("MT");                        hbins.push_back(45); hlow.push_back(   0.); hup.push_back(450);
  histonames.push_back("ZPt");                       hbins.push_back(30); hlow.push_back(   0.); hup.push_back(600);
  histonames.push_back("Z_Pt");                      hbins.push_back(30); hlow.push_back(   0.); hup.push_back(600);
  histonames.push_back("ZEta");                      hbins.push_back(50); hlow.push_back(  -5.); hup.push_back(5. );
  histonames.push_back("ZPhi");                      hbins.push_back(32); hlow.push_back( -3.2); hup.push_back(3.2);
  histonames.push_back("DPhill");                    hbins.push_back(32); hlow.push_back(   0.); hup.push_back(3.2);
  histonames.push_back("DEtall");                    hbins.push_back(50); hlow.push_back(   0.); hup.push_back(5. );
  histonames.push_back("DRll");                      hbins.push_back(32); hlow.push_back(   0.); hup.push_back(6.4);
  histonames.push_back("MyMuPt");                      hbins.push_back(30); hlow.push_back(   0.); hup.push_back(600);
  histonames.push_back("MyMuEta");                     hbins.push_back(60); hlow.push_back(   3.); hup.push_back(3. );
  histonames.push_back("MyMuPhi");                     hbins.push_back(32); hlow.push_back( -3.2); hup.push_back(3.2);
  histonames.push_back("MyMuCharge");                  hbins.push_back( 6); hlow.push_back(  -2.); hup.push_back(4. );
  histonames.push_back("MET");                      hbins.push_back(40); hlow.push_back(   0.); hup.push_back(200);
  histonames.push_back("HT");                      hbins.push_back(40); hlow.push_back(   0.); hup.push_back(400);
  histonames.push_back("NJets");                      hbins.push_back(10); hlow.push_back(   0.); hup.push_back(10);
  histonames.push_back("NBJets");                      hbins.push_back(5); hlow.push_back(   0.); hup.push_back(5);
	      
  for(unsigned int i = 0; i<histonames.size(); ++i){
    int nbins = hbins[i];
    string mapname;
    for(unsigned int j = 0; j<11; ++j){
      string prefix = "";
      if(j==1) prefix = "NJ0_";
      else if(j==2) prefix = "NJ1_";
      else if(j==3) prefix = "NJ2_";
      else if(j==4) prefix = "NJge3_";
      else if(j==5) prefix = "NB0_";
      else if(j==6) prefix = "NBge1_";
      else if(j==7) prefix = "HTge100_";
      else if(j==8) prefix = "METge50_";
      else if(j==9) prefix = "METge25_";
      else if(j==10) prefix = "HTge150_";
      mapname = prefix + histonames[i]+"_"+skimFilePrefix;
      //cout << mapname << endl;
      if(histos.count(mapname) == 0 ) histos[mapname] = new TH1F(mapname.c_str(), "", nbins, hlow[i], hup[i]);
      histos[mapname]->Sumw2(); histos[mapname]->SetDirectory(rootdir);
    }
  }

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

  //load json file
  const char* json_fileDCS = "myjsons/json_DCSONLY_Run2015B_snt.txt";
  const char* json_file = "myjsons/json_Golden_246908-251883_snt.txt";
  if(DCSonly) set_goodrun_file(json_fileDCS);
  else        set_goodrun_file(json_file);

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

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

    int nleps = 1;
    myevt p;//previous event
    myevt c;//current event
    resetEvent(p);
    resetEvent(c);
    vector<myevt> mu; mu.clear();

    // Loop over Events in current file
    if( nEventsTotal >= nEventsChain ) continue;
    unsigned int nEventsTree = tree->GetEntriesFast();
    for( unsigned int event = 0; event < nEventsTree; ++event) {
    
      // Get Event Content
      if( nEventsTotal >= nEventsChain ) continue;
      if(fast) tree->LoadTree(event);
      cms3.GetEntry(event);
      ++nEventsTotal;
    
      // Progress
      CMS3::progress(nEventsTotal, nEventsChain );
      if(evt_isRealData()&& !goodrun(evt_run(), evt_lumiBlock()) ) continue;

      //load my struct
      c.evt_pfmet   = evt_pfmet();
      c.evt_pfmetPhi   = evt_pfmetPhi();
      c.evt_trackmet   = evt_trackmet();
      c.evt_trackmetPhi   = evt_trackmetPhi();
      c.evt_pfsumet   = evt_pfsumet();
      c.evt_pfmetSig   = evt_pfmetSig();
      c.evt_event   = evt_event();
      c.evt_lumiBlock   = evt_lumiBlock();
      c.evt_run   = evt_run();
      c.filt_csc   = filt_csc();
      c.filt_hbhe   = filt_hbhe();
      c.filt_hcallaser   = filt_hcallaser();
      c.filt_ecaltp   = filt_ecaltp();
      c.filt_trkfail   = filt_trkfail();
      c.filt_eebadsc   = filt_eebadsc();
      c.evt_isRealData   = evt_isRealData(); 
      c.scale1fb   = scale1fb();
      c.evt_xsec_incl   = evt_xsec_incl();
      c.evt_kfactor   = evt_kfactor();
      c.gen_met   = gen_met();
      c.gen_metPhi   = gen_metPhi();
      c.njets   = njets();
      c.ht   = ht();
      c.jets  = jets();
      c.jets_disc  = jets_disc();
      c.sample  = sample();
      c.nvtx   = nvtx();
      c.HLT_Mu8_TrkIsoVVL   = HLT_Mu8_TrkIsoVVL();
      c.HLT_Mu17_TrkIsoVVL   = HLT_Mu17_TrkIsoVVL();
      c.HLT_Mu24_TrkIsoVVL   = HLT_Mu24_TrkIsoVVL();
      c.HLT_Mu34_TrkIsoVVL   = HLT_Mu34_TrkIsoVVL();
      c.HLT_Mu8   = HLT_Mu8();
      c.HLT_Mu17   = HLT_Mu17();
      c.HLT_Mu24   = HLT_Mu24();
      c.HLT_Mu34   = HLT_Mu34();
      c.HLT_Mu10_CentralPFJet30_BTagCSV0p5PF   = HLT_Mu10_CentralPFJet30_BTagCSV0p5PF();
      c.HLT_IsoMu24_eta2p1   = HLT_IsoMu24_eta2p1();
      c.HLT_IsoTkMu24_eta2p1   = HLT_IsoTkMu24_eta2p1(); 
      c.HLT_IsoMu27   = HLT_IsoMu27();
      c.HLT_IsoTkMu27   = HLT_IsoTkMu27(); 
      c.HLT_Mu45_eta2p1   = HLT_Mu45_eta2p1(); 
      c.HLT_Mu50   = HLT_Mu50();
      c.HLT_Ele8_CaloIdM_TrackIdM_PFJet30   = HLT_Ele8_CaloIdM_TrackIdM_PFJet30();
      c.HLT_Ele12_CaloIdM_TrackIdM_PFJet30   = HLT_Ele12_CaloIdM_TrackIdM_PFJet30();
      c.HLT_Ele18_CaloIdM_TrackIdM_PFJet30   = HLT_Ele18_CaloIdM_TrackIdM_PFJet30();
      c.HLT_Ele23_CaloIdM_TrackIdM_PFJet30   = HLT_Ele23_CaloIdM_TrackIdM_PFJet30();
      c.HLT_Ele33_CaloIdM_TrackIdM_PFJet30   = HLT_Ele33_CaloIdM_TrackIdM_PFJet30();
      c.HLT_Ele12_CaloIdL_TrackIdL_IsoVL_PFJet30   = HLT_Ele12_CaloIdL_TrackIdL_IsoVL_PFJet30();
      c.HLT_Ele18_CaloIdL_TrackIdL_IsoVL_PFJet30   = HLT_Ele18_CaloIdL_TrackIdL_IsoVL_PFJet30();
      c.HLT_Ele23_CaloIdL_TrackIdL_IsoVL_PFJet30   = HLT_Ele23_CaloIdL_TrackIdL_IsoVL_PFJet30();
      c.HLT_Ele33_CaloIdL_TrackIdL_IsoVL_PFJet30   = HLT_Ele33_CaloIdL_TrackIdL_IsoVL_PFJet30();
      c.HLT_Ele10_CaloIdM_TrackIdM_CentralPFJet30_BTagCSV0p5PF   = HLT_Ele10_CaloIdM_TrackIdM_CentralPFJet30_BTagCSV0p5PF();
      c.HLT_Ele27_eta2p1_WP75_Gsf   = HLT_Ele27_eta2p1_WP75_Gsf();
      c.HLT_Ele27_WP85_Gsf   = HLT_Ele27_WP85_Gsf();
      c.HLT_Ele27_eta2p1_WPLoose_Gsf   = HLT_Ele27_eta2p1_WPLoose_Gsf();
      c.HLT_Ele27_eta2p1_WPTight_Gsf   = HLT_Ele27_eta2p1_WPTight_Gsf();
      c.HLT_Ele32_eta2p1_WP75_Gsf   = HLT_Ele32_eta2p1_WP75_Gsf();
      c.HLT_Ele32_eta2p1_WPLoose_Gsf   = HLT_Ele32_eta2p1_WPLoose_Gsf();
      c.HLT_Ele32_eta2p1_WPTight_Gsf   = HLT_Ele32_eta2p1_WPTight_Gsf();
      c.HLT_Mu8_Ele8_CaloIdM_TrackIdM_Mass8_PFHT300   = HLT_Mu8_Ele8_CaloIdM_TrackIdM_Mass8_PFHT300();
      c.HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL   = HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL();
      c.HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL   = HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL();
      c.HLT_DoubleMu8_Mass8_PFHT300   = HLT_DoubleMu8_Mass8_PFHT300();
      c.HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL   = HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL();
      c.HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL   = HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL(); 
      c.HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ   = HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ();
      c.HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ   = HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ(); 
      c.HLT_DoubleEle8_CaloIdM_TrackIdM_Mass8_PFHT300   = HLT_DoubleEle8_CaloIdM_TrackIdM_Mass8_PFHT300();
      c.HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ   = HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ();
      c.pid_PFMuon   = pid_PFMuon();
      c.gfit_chi2   = gfit_chi2();
      c.gfit_ndof   = gfit_ndof();
      c.gfit_validSTAHits   = gfit_validSTAHits();
      c.numberOfMatchedStations   = numberOfMatchedStations();
      c.validPixelHits   = validPixelHits();
      c.nlayers   = nlayers();
      c.chi2LocalPosition   = chi2LocalPosition();
      c.trkKink   = trkKink();
      c.validHits   = validHits(); 
      c.lostHits   = lostHits();
      c.exp_outerlayers   = exp_outerlayers();
      c.segmCompatibility   = segmCompatibility();
      c.exp_innerlayers   = exp_innerlayers();
      c.passes_POG_vetoID   = passes_POG_vetoID();
      c.passes_POG_looseID   = passes_POG_looseID();
      c.passes_POG_mediumID   = passes_POG_mediumID();
      c.passes_POG_tightID   = passes_POG_tightID();
      c.ip3d   = ip3d();
      c.ip3derr   = ip3derr(); 
      c.type   = type();
      c.mt   = mt();
      c.ptrelv0   = ptrelv0();
      c.ptrelv1   = ptrelv1();
      c.miniiso   = miniiso();
      c.miniisoDB   = miniisoDB(); 
      c.reliso04   = reliso04();
      c.annulus04   = annulus04();
      c.p4  = p4();
      c.tag_p4  = tag_p4();
      c.dilep_p4  = dilep_p4();
      c.mc_p4  = mc_p4();
      c.mc_motherp4  = mc_motherp4();
      c.id   = id();
      c.idx   = idx();
      c.dxyPV   = dxyPV();
      c.dZ   = dZ();
      c.dxyPV_err   = dxyPV_err();
      c.motherID   = motherID();
      c.mc_id   = mc_id();
      c.RelIso03   = RelIso03();
      c.RelIso03EA   = RelIso03EA();
      c.RelIso03DB   = RelIso03DB();
      c.dilep_mass   = dilep_mass();
      c.dilep_p4   = dilep_p4();
      c.passes_SS_tight_noiso_v3 = passes_SS_tight_noiso_v3();
      c.passes_SS_fo_noiso_v3 = passes_SS_fo_noiso_v3();
      c.passes_POG_looseID = passLooseID(c);
      c.passes_POG_mediumID = passMediumID(c);
      c.passes_POG_tightID = passTightID(c);
     

      float weight = p.scale1fb*0.0403;
      if(skimFilePrefix=="DY_M10_50ns") weight *= 1.11;
      if(p.evt_isRealData) weight = 1.;
      if((skimFilePrefix=="SingleMuon"||skimFilePrefix=="DoubleMuon")&&fabs(weight-1.)>=0.001) cout <<__LINE__<< endl;
      // Analysis Code

      if(sameEvent(p,c)) { ++nleps; }


      if(((!sameEvent(p,c))||(nEventsChain==nEventsTotal)) && mu.size()>0) {

	int nbs = 0;
	int njs = 0;
	float HT = 0;
	double muovind[mu.size()];
	for(unsigned int i = 0; i<mu.size();++i){
	  muovind[i] = -1;
	  float minDR = 9999;
	  if(mu[i].jets.size()!=p.jets.size()) cout << "ERROR " << mu[i].jets.size() << " " << p.jets.size() << endl;
	  for(unsigned int j = 0; j<p.jets.size();++j){
	    float myDR = deltaR(mu[i].p4,p.jets[j]);
	    if(myDR<0.4 && myDR<minDR){
	      minDR = myDR;
	      muovind[i] = j;
	    }
	  }
	}
	for(unsigned int i = 0; i<p.jets.size();++i){
	  bool isoverlap = false;
	  for(unsigned int j = 0; j<mu.size();++j){
	    if(muovind[j]==i){
	      isoverlap = true;
	      break;
	    }
	  }
	  if(isoverlap) continue;
	  if(p.jets[i].Pt()<30) continue;
	  if(fabs(p.jets[i].Eta()>2.4)) continue;
	  ++njs;
	  HT += p.jets[i].Pt();
	  if(p.jets_disc[i]>0.890) ++nbs;
	}
      
	bool triggerbool2mu = false;
	bool triggerbool1mu = false;
	//now I reached full event!
	if(mu.size()>1) mu = sortbypt(mu);
	for(unsigned int i = 0; i<mu.size();++i){
	  if(mu[i].evt_isRealData) triggerbool2mu = triggerbool2mu || mu[i].HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ || mu[i].HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ;
	  if(mu[i].evt_isRealData) triggerbool1mu = triggerbool1mu || mu[i].HLT_IsoMu24_eta2p1 || mu[i].HLT_IsoTkMu24_eta2p1 || mu[i].HLT_IsoMu27 || mu[i].HLT_IsoTkMu27 || mu[i].HLT_IsoMu20 || mu[i].HLT_IsoMu20;
	}
	if(!p.evt_isRealData){ triggerbool2mu = true; triggerbool1mu = true;}
	if(mu.size()==2){
	  triggerbool2mu = triggerbool2mu&&mu[0].p4.Pt()>20.&&fabs(mu[0].p4.Eta())<2.1&&mu[0].p4.Pt()>20.&&fabs(mu[0].p4.Eta())<2.1;//two muons passing nominal trigger w/o iso and dZ
	  triggerbool1mu = triggerbool1mu&&((mu[0].p4.Pt()>30.&&fabs(mu[0].p4.Eta())<2.1)||(mu[1].p4.Pt()>30.&&fabs(mu[1].p4.Eta())<2.1));//one muon passing nominal trigger w/o iso
	  LorentzVector Z = (mu[0].p4+mu[1].p4);
	  if((triggerbool1mu||triggerbool2mu)&& mu[0].passes_POG_tightID&&mu[1].passes_POG_tightID&&mu[0].miniisoDB<0.2&&mu[1].miniisoDB<0.2&&
	      fabs(mu[0].dZ)<0.1&&fabs(mu[1].dZ)<0.1&&fabs(mu[0].dxyPV)<0.02&&fabs(mu[1].dxyPV)<0.02){
	    //cout << "have a dilepton event: Z pt " << Z.Pt() << " and mass " << Z.M() << endl;
	    histos["Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(njs==0) histos["NJ0_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    else if(njs==1) histos["NJ1_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    else if(njs==2) histos["NJ2_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    else histos["NJge3_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(nbs==0)  histos["NB0_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    else  histos["NBge1_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(HT>100.) histos["HTge100_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(HT>150.) histos["HTge150_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(p.evt_pfmet>50.) histos["METge50_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(p.evt_pfmet>25.) histos["METge25_Mll_"+skimFilePrefix]->Fill(Z.M(),weight);
	    if(Z.M()>75.&&Z.M()<105){
	      histos["ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
	      histos["ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
	      histos["ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
	      histos["DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
	      histos["DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
	      histos["DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      histos["MET_"+skimFilePrefix]->Fill(p.evt_pfmet,weight);
	      histos["HT_"+skimFilePrefix]->Fill(HT,weight);
	      histos["NJets_"+skimFilePrefix]->Fill(njs,weight);
	      histos["NBJets_"+skimFilePrefix]->Fill(nbs,weight);
	      if(njs==0){
		histos["NJ0_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NJ0_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NJ0_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NJ0_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NJ0_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NJ0_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } else if(njs==1){
		histos["NJ1_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NJ1_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NJ1_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NJ1_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NJ1_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NJ1_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } else if(njs==2){
		histos["NJ2_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NJ2_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NJ2_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NJ2_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NJ2_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NJ2_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } else {
		histos["NJge3_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NJge3_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NJge3_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NJge3_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NJge3_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NJge3_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } if(nbs==0){
		histos["NB0_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NB0_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NB0_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NB0_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NB0_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NB0_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } else {
		histos["NBge1_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["NBge1_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["NBge1_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["NBge1_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["NBge1_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["NBge1_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } if(HT>100.){
		histos["HTge100_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["HTge100_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["HTge100_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["HTge100_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["HTge100_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["HTge100_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } if(HT>150.){
		histos["HTge150_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["HTge150_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["HTge150_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["HTge150_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["HTge150_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["HTge150_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } if(p.evt_pfmet>50.){
		histos["METge50_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["METge50_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["METge50_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["METge50_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["METge50_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["METge50_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);
	      } if(p.evt_pfmet>25.){
		histos["METge25_ZPt_"+skimFilePrefix]->Fill(Z.Pt(),weight);
		histos["METge25_ZEta_"+skimFilePrefix]->Fill(Z.Eta(),weight);
		histos["METge25_ZPhi_"+skimFilePrefix]->Fill(Z.Phi(),weight);
		histos["METge25_DPhill_"+skimFilePrefix]->Fill(getdphi(mu[0].p4.Phi(),mu[1].p4.Phi()),weight);
		histos["METge25_DEtall_"+skimFilePrefix]->Fill(fabs(mu[0].p4.Eta()-mu[1].p4.Eta()),weight);
		histos["METge25_DRll_"+skimFilePrefix]->Fill(dRbetweenVectors(mu[0].p4,mu[1].p4),weight);	
	      }
	      for(unsigned int i = 0; i<mu.size(); ++i){
		float mucharge = 0; if(mu[i].id==13) mucharge = -1; else if(mu[i].id==-13) mucharge = +1; 
		histos["MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		histos["MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		histos["MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		histos["MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		if(njs==0){
		  histos["NJ0_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NJ0_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NJ0_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NJ0_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} else if(njs==1){
		  histos["NJ1_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NJ1_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NJ1_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NJ1_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} else if(njs==2){
		  histos["NJ2_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NJ2_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NJ2_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NJ2_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} else {
		  histos["NJge3_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NJge3_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NJge3_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NJge3_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} if(nbs==0){
		  histos["NB0_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NB0_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NB0_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NB0_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} else {
		  histos["NBge1_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["NBge1_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["NBge1_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["NBge1_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} if(HT>100.){
		  histos["HTge100_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["HTge100_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["HTge100_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["HTge100_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} if(HT>150.){
		  histos["HTge150_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["HTge150_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["HTge150_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["HTge150_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} if(p.evt_pfmet>50.){
		  histos["METge50_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["METge50_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["METge50_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["METge50_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		} if(p.evt_pfmet>25.){
		  histos["METge25_MuPt_"+skimFilePrefix]->Fill(mu[i].p4.Pt(),weight);
		  histos["METge25_MuEta_"+skimFilePrefix]->Fill(mu[i].p4.Eta(),weight);
		  histos["METge25_MuPhi_"+skimFilePrefix]->Fill(mu[i].p4.Phi(),weight);
		  histos["METge25_MuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
		}
	      }
	    }
	  }
	  if((triggerbool1mu||triggerbool2mu)&& mu[0].passes_POG_tightID&&mu[1].passes_POG_tightID&&fabs(mu[0].dZ)<0.1&&fabs(mu[1].dZ)<0.1&&fabs(mu[0].dxyPV)<0.02&&fabs(mu[1].dxyPV)<0.02){
	    if(Z.M()>75.&&Z.M()<105){
	      for(unsigned int i = 0; i<mu.size(); ++i){
		histos["MuRelIso03_"+skimFilePrefix]->Fill(mu[i].RelIso03,weight);
		histos["MuRelIso03EA_"+skimFilePrefix]->Fill(mu[i].RelIso03EA,weight);
		histos["MuRelIso03DB_"+skimFilePrefix]->Fill(mu[i].RelIso03DB,weight);
		histos["MuMiniIsoEA_"+skimFilePrefix]->Fill(mu[i].miniiso,weight);
		histos["MuMiniIsoDB_"+skimFilePrefix]->Fill(mu[i].miniisoDB,weight);
		histos["MuRelIso04_"+skimFilePrefix]->Fill(mu[i].reliso04,weight);
		histos["MuAnnulus04_"+skimFilePrefix]->Fill(mu[i].annulus04,weight);
		if(mu[0].mt>30&&mu[0].mt>30){
		  histos["MuRelIso03_MT30_"+skimFilePrefix]->Fill(mu[i].RelIso03,weight);
		  histos["MuRelIso03EA_MT30_"+skimFilePrefix]->Fill(mu[i].RelIso03EA,weight);
		  histos["MuRelIso03DB_MT30_"+skimFilePrefix]->Fill(mu[i].RelIso03DB,weight);
		  histos["MuMiniIsoEA_MT30_"+skimFilePrefix]->Fill(mu[i].miniiso,weight);
		  histos["MuMiniIsoDB_MT30_"+skimFilePrefix]->Fill(mu[i].miniisoDB,weight);
		  histos["MuRelIso04_MT30_"+skimFilePrefix]->Fill(mu[i].reliso04,weight);
		  histos["MuAnnulus04_MT30_"+skimFilePrefix]->Fill(mu[i].annulus04,weight);
		}
	      }
	    }
	  }
	  if((triggerbool1mu||triggerbool2mu)&& mu[0].passes_POG_tightID&&mu[1].passes_POG_tightID&&mu[0].miniisoDB<0.2&&mu[1].miniisoDB<0.2){
	    if(Z.M()>75.&&Z.M()<105){
	      for(unsigned int i = 0; i<mu.size(); ++i){
		histos["Mud0_"+skimFilePrefix]->Fill(mu[i].dxyPV,weight);
		histos["MudZ_"+skimFilePrefix]->Fill(mu[i].dZ,weight);
		histos["MuIP3d_"+skimFilePrefix]->Fill(mu[i].ip3d,weight);
	      }
	    }
	  }
	  if((triggerbool1mu||triggerbool2mu)&& mu[0].passes_POG_looseID&&mu[1].passes_POG_looseID&&mu[0].miniisoDB<0.2&&mu[1].miniisoDB<0.2&&
	      fabs(mu[0].dZ)<0.1&&fabs(mu[1].dZ)<0.1&&fabs(mu[0].dxyPV)<0.02&&fabs(mu[1].dxyPV)<0.02){
	    if(Z.M()>75.&&Z.M()<105){
	      for(unsigned int i = 0; i<mu.size(); ++i){
		if(mu[i].passes_POG_tightID) histos["MuID_"+skimFilePrefix]->Fill(3.,weight);
		else if(mu[i].passes_POG_mediumID) histos["MuID_"+skimFilePrefix]->Fill(2.,weight);
		else if(mu[i].passes_POG_looseID) histos["MuID_"+skimFilePrefix]->Fill(1.,weight);
		histos["MuvalidFraction_"+skimFilePrefix]->Fill((float)mu[i].validHits/((float)(mu[i].validHits+mu[i].lostHits+mu[i].exp_innerlayers+mu[i].exp_outerlayers)),weight);
		if(mu[i].gfit_ndof>0) histos["Mugfit_normchi2_"+skimFilePrefix]->Fill(mu[i].gfit_chi2/mu[i].gfit_ndof, weight);
		histos["Mugfit_validSTAHits_"+skimFilePrefix]->Fill(mu[i].gfit_validSTAHits,weight);
		histos["MunumberOfMatchedStations_"+skimFilePrefix]->Fill(mu[i].numberOfMatchedStations,weight);
		histos["MuvalidPixelHits_"+skimFilePrefix]->Fill(mu[i].validPixelHits,weight);
		histos["Munlayers_"+skimFilePrefix]->Fill(mu[i].nlayers,weight);
		histos["Muchi2LocalPosition_"+skimFilePrefix]->Fill(mu[i].chi2LocalPosition,weight);
		histos["MutrkKink_"+skimFilePrefix]->Fill(mu[i].trkKink,weight);
		histos["MusegmCompatibility_"+skimFilePrefix]->Fill(mu[i].segmCompatibility,weight);
	      }
	    }
	  }
	}//2 muons
	else if(mu.size()==1){
	  triggerbool1mu = triggerbool1mu&&((mu[0].p4.Pt()>30.&&fabs(mu[0].p4.Eta())<2.1));//one muon passing nominal trigger w/o iso
	  if(triggerbool1mu&&mu[0].passes_POG_tightID&&mu[0].miniisoDB<0.2&&fabs(mu[0].dZ)<0.1&&fabs(mu[0].dxyPV)<0.02&&mu[0].mt>40){//1 mu events.
	    float mucharge = 0; if(mu[0].id==13) mucharge = -1; else if(mu[0].id==-13) mucharge = +1; 
	    histos["MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	    histos["MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	    histos["MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	    histos["MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	    histos["MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
	    if(njs==0){
	      histos["NJ0_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NJ0_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NJ0_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NJ0_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NJ0_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);
	    } else if(njs==1){
	      histos["NJ1_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NJ1_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NJ1_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NJ1_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NJ1_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } else if(njs==2){
	      histos["NJ2_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NJ2_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NJ2_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NJ2_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NJ2_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } else {
	      histos["NJge3_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NJge3_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NJge3_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NJge3_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NJge3_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } if(nbs==0){
	      histos["NB0_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NB0_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NB0_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NB0_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NB0_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } else {
	      histos["NBge1_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["NBge1_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["NBge1_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["NBge1_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["NBge1_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } if(HT>100.){
	      histos["HTge100_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["HTge100_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["HTge100_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["HTge100_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["HTge100_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } if(HT>150.){
	      histos["HTge150_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["HTge150_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["HTge150_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["HTge150_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["HTge150_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } if(p.evt_pfmet>50.){
	      histos["METge50_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["METge50_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["METge50_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["METge50_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["METge50_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    } if(p.evt_pfmet>25.){
	      histos["METge25_MT_"+skimFilePrefix]->Fill(mu[0].mt,weight);
	      histos["METge25_MyMuPt_"+skimFilePrefix]->Fill(mu[0].p4.Pt(),weight);
	      histos["METge25_MyMuEta_"+skimFilePrefix]->Fill(mu[0].p4.Eta(),weight);
	      histos["METge25_MyMuPhi_"+skimFilePrefix]->Fill(mu[0].p4.Phi(),weight);
	      histos["METge25_MyMuCharge_"+skimFilePrefix]->Fill(mucharge,weight);	      
	    }
	  }
	}
      }
      if(!sameEvent(p,c)){
	//finally start new event.
	if(abs(p.id)==13&&p.passes_POG_tightID&&p.miniisoDB<0.2&&fabs(p.dZ)<0.1&&fabs(p.dxyPV)<0.02&&p.dilep_mass>75.&&p.dilep_mass<105&&p.p4.Pt()>20&&fabs(p.p4.Eta())<2.1) {
	  if((p.evt_isRealData&&(p.HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ || p.HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ || p.HLT_IsoMu24_eta2p1 || p.HLT_IsoTkMu24_eta2p1 || p.HLT_IsoMu27 || p.HLT_IsoTkMu27 || p.HLT_IsoMu20 || p.HLT_IsoMu20))||(!p.evt_isRealData)){
	    histos["Z_Pt_"+skimFilePrefix]->Fill(p.dilep_p4.Pt(),weight);
	  }
	}
	mu.clear();
	nleps = 1;
      }
      if(currentrun!=c.evt_run) { cout << "This is run " << c.evt_run << endl; currentrun = c.evt_run; }
      bool skip = false;
      //if(c.evt_run!=251244&&c.evt_run!=251251&&c.evt_run!=251252) skip = true;
      if(abs(c.id)!=13) skip = true;
      else if(c.p4.Pt()<20.) skip = true;
      else if(fabs(c.p4.Eta())>2.1) skip = true;
      else if(!c.passes_POG_looseID) skip = true;
      //else if(fabs(c.dZ)>0.5) skip = true;
      //else if(fabs(c.dxyPV)>0.2) skip = true;
      //else if(c.miniisoDB>0.5) skip = true;
      if(!skip) { mu.push_back(c); }
      p = c;
      resetEvent(c);
    }
  
    // Clean Up
    delete tree;
    file->Close();
    delete file;
  }
  if ( nEventsChain != nEventsTotal ) {
    cout << Form( "ERROR: number of events from files (%d) is not equal to total number of events (%d)", nEventsChain, nEventsTotal ) << endl;
  }
  
  // Example Histograms
  for(map<string,TH1F*>::iterator h=histos.begin(); h!=histos.end();++h){
    h->second->SetBinContent(h->second->GetNbinsX(), h->second->GetBinContent(h->second->GetNbinsX() )+ h->second->GetBinContent(h->second->GetNbinsX()+1) );
    h->second->SetBinError(h->second->GetNbinsX(), sqrt(pow(h->second->GetBinError(h->second->GetNbinsX() ),2)+pow(h->second->GetBinError(h->second->GetNbinsX()+1),2) ) );
  }
  for(map<string,TH1F*>::iterator h=histos.begin(); h!=histos.end();++h){
    h->second->SetBinContent(1, h->second->GetBinContent(1 )+ h->second->GetBinContent(0) );
    h->second->SetBinError(1, sqrt(pow(h->second->GetBinError(1 ),2)+pow(h->second->GetBinError(0),2) ) );
  }
  //string filename = "rootfiles/test/Histos_"+skimFilePrefix+".root";
  string filename = "rootfiles/first_20150727/Histos3_"+skimFilePrefix+".root";
  if(DCSonly) filename = "rootfiles/first_20150727/Histos3DCS_"+skimFilePrefix+".root";
  TFile *f = new TFile(filename.c_str(),"RECREATE");
  f->cd();
  for(map<string,TH1F*>::iterator h=    histos.begin(); h!=    histos.end();++h) h->second->Write();
  f->Close();
  cout << "Saved histos in " << f->GetName() << endl;  
  // return
  bmark->Stop("benchmark");
  cout << endl;
  cout << nEventsTotal << " Events Processed" << endl;
  cout << "------------------------------" << endl;
  cout << "CPU  Time:	" << Form( "%.01f", bmark->GetCpuTime("benchmark")  ) << endl;
  cout << "Real Time:	" << Form( "%.01f", bmark->GetRealTime("benchmark") ) << endl;
  cout << endl;
  delete bmark;
  return 0;
}
Example #7
0
void selectZee(const TString conf,        // input file
               const TString outputDir,   // output directory
	       const Bool_t  doScaleCorr  // apply energy scale corrections?
) {
  gBenchmark->Start("selectZee");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t MASS_LOW  = 40;
  const Double_t MASS_HIGH = 200;
  const Double_t PT_CUT    = 20;
  const Double_t ETA_CUT   = 2.5;
  const Double_t ELE_MASS  = 0.000511;
  
  const Double_t ECAL_GAP_LOW  = 1.4442;
  const Double_t ECAL_GAP_HIGH = 1.566;
  
  const Double_t escaleNbins  = 6;
  const Double_t escaleEta[]  = { 0.4,     0.8,     1.2,     1.4442,  2,        2.5 };
  const Double_t escaleCorr[] = { 1.00284, 1.00479, 1.00734, 1.00851, 1.00001,  0.982898 };


  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  enum { eEleEle2HLT=1, eEleEle1HLT, eEleEleNoSel, eEleSC };  // event category enum
  
  vector<TString>  snamev;      // sample name (for output files)  
  vector<CSample*> samplev;     // data/MC samples

  //
  // parse .conf file
  //
  confParse(conf, snamev, samplev);
  const Bool_t hasData = (samplev[0]->fnamev.size()>0);

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  const TString ntupDir = outputDir + TString("/ntuples");
  gSystem->mkdir(ntupDir,kTRUE);
  
  //
  // Declare output ntuple variables
  //
  UInt_t  runNum, lumiSec, evtNum;
  UInt_t  matchGen;
  UInt_t  category;
  UInt_t  npv, npu;
  Float_t genVPt, genVPhi, genVy, genVMass;
  Float_t scale1fb;
  Float_t met, metPhi, sumEt, u1, u2;
  Int_t   q1, q2;
  LorentzVector *dilep=0, *lep1=0, *lep2=0;
  ///// electron specific /////
  Float_t trkIso1, emIso1, hadIso1, trkIso2, emIso2, hadIso2;
  Float_t pfChIso1, pfGamIso1, pfNeuIso1, pfCombIso1, pfChIso2, pfGamIso2, pfNeuIso2, pfCombIso2;
  Float_t sigieie1, hovere1, eoverp1, fbrem1, ecalE1, sigieie2, hovere2, eoverp2, fbrem2, ecalE2;
  Float_t dphi1, deta1, dphi2, deta2;
  Float_t d01, dz1, d02, dz2;
  UInt_t  isConv1, nexphits1, typeBits1, isConv2, nexphits2, typeBits2; 
  LorentzVector *sc1=0, *sc2=0;
  
  // Data structures to store info from TTrees
  mithep::TEventInfo *info  = new mithep::TEventInfo();
  mithep::TGenInfo   *gen   = new mithep::TGenInfo();
  TClonesArray *electronArr = new TClonesArray("mithep::TElectron");
  TClonesArray *scArr       = new TClonesArray("mithep::TPhoton");
  TClonesArray *pvArr       = new TClonesArray("mithep::TVertex");
  
  TFile *infile=0;
  TTree *eventTree=0;
  
  //
  // loop over samples
  //  
  for(UInt_t isam=0; isam<samplev.size(); isam++) {
    
    // Assume data sample is first sample in .conf file
    // If sample is empty (i.e. contains no ntuple files), skip to next sample
    if(isam==0 && !hasData) continue;
    
    // Assume signal sample is given name "zee"
    // If it's the signal sample, toggle flag to store GEN W kinematics
    Bool_t isSignal = (snamev[isam].CompareTo("zee",TString::kIgnoreCase)==0);  
    
    CSample* samp = samplev[isam];
  
    //
    // Set up output ntuple
    //
    TString outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.root");
    if(isam==0 && !doScaleCorr) outfilename = ntupDir + TString("/") + snamev[isam] + TString("_select.raw.root");
    TFile *outFile = new TFile(outfilename,"RECREATE"); 
    TTree *outTree = new TTree("Events","Events");

    outTree->Branch("runNum",   &runNum,   "runNum/i");     // event run number
    outTree->Branch("lumiSec",  &lumiSec,  "lumiSec/i");    // event lumi section
    outTree->Branch("evtNum",   &evtNum,   "evtNum/i");     // event number
    outTree->Branch("matchGen", &matchGen, "matchGen/i");   // event has both leptons matched to MC Z->ll
    outTree->Branch("category", &category, "category/i");   // dilepton category
    outTree->Branch("npv",      &npv,      "npv/i");        // number of primary vertices
    outTree->Branch("npu",      &npu,      "npu/i");        // number of in-time PU events (MC)
    outTree->Branch("genVPt",   &genVPt,   "genVPt/F");     // GEN boson pT (signal MC)
    outTree->Branch("genVPhi",  &genVPhi,  "genVPhi/F");    // GEN boson phi (signal MC)
    outTree->Branch("genVy",    &genVy,    "genVy/F");      // GEN boson rapidity (signal MC)
    outTree->Branch("genVMass", &genVMass, "genVMass/F");   // GEN boson mass (signal MC)
    outTree->Branch("scale1fb", &scale1fb, "scale1fb/F");   // event weight per 1/fb (MC)
    outTree->Branch("met",      &met,      "met/F");        // MET
    outTree->Branch("metPhi",   &metPhi,   "metPhi/F");     // phi(MET)
    outTree->Branch("sumEt",    &sumEt,    "sumEt/F");      // Sum ET
    outTree->Branch("u1",       &u1,       "u1/F");         // parallel component of recoil
    outTree->Branch("u2",       &u2,       "u2/F");         // perpendicular component of recoil
    outTree->Branch("q1",       &q1,       "q1/I");         // charge of tag lepton
    outTree->Branch("q2",       &q2,       "q2/I");         // charge of probe lepton
    outTree->Branch("dilep", "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &dilep);  // dilepton 4-vector
    outTree->Branch("lep1",  "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep1);   // tag lepton 4-vector
    outTree->Branch("lep2",  "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &lep2);   // probe lepton 4-vector
    ///// electron specific /////
    outTree->Branch("trkIso1",    &trkIso1,    "trkIso1/F");     // track isolation of tag lepton
    outTree->Branch("trkIso2",    &trkIso2,    "trkIso2/F");     // track isolation of probe lepton
    outTree->Branch("emIso1",     &emIso1,     "emIso1/F");      // ECAL isolation of tag lepton
    outTree->Branch("emIso2",     &emIso2,     "emIso2/F");      // ECAL isolation of probe lepton
    outTree->Branch("hadIso1",    &hadIso1,    "hadIso1/F");     // HCAL isolation of tag lepton
    outTree->Branch("hadIso2",    &hadIso2,    "hadIso2/F");     // HCAL isolation of probe lepton
    outTree->Branch("pfChIso1",   &pfChIso1,   "pfChIso1/F");    // PF charged hadron isolation of tag lepton
    outTree->Branch("pfChIso2",   &pfChIso2,   "pfChIso2/F");    // PF charged hadron isolation of probe lepton
    outTree->Branch("pfGamIso1",  &pfGamIso1,  "pfGamIso1/F");   // PF photon isolation of tag lepton
    outTree->Branch("pfGamIso2",  &pfGamIso2,  "pfGamIso2/F");   // PF photon isolation of probe lepton
    outTree->Branch("pfNeuIso1",  &pfNeuIso1,  "pfNeuIso1/F");   // PF neutral hadron isolation of tag lepton
    outTree->Branch("pfNeuIso2",  &pfNeuIso2,  "pfNeuIso2/F");   // PF neutral hadron isolation of probe lepton
    outTree->Branch("pfCombIso1", &pfCombIso1, "pfCombIso1/F");  // PF combine isolation of tag lepton
    outTree->Branch("pfCombIso2", &pfCombIso2, "pfCombIso2/F");  // PF combined isolation of probe lepton    
    outTree->Branch("sigieie1",   &sigieie1,   "sigieie1/F");    // sigma-ieta-ieta of tag
    outTree->Branch("sigieie2",   &sigieie2,   "sigieie2/F");    // sigma-ieta-ieta of probe
    outTree->Branch("hovere1",    &hovere1,    "hovere1/F");     // H/E of tag
    outTree->Branch("hovere2",    &hovere2,    "hovere2/F");     // H/E of probe
    outTree->Branch("eoverp1",    &eoverp1,    "eoverp1/F");     // E/p of tag
    outTree->Branch("eoverp2",    &eoverp2,    "eoverp2/F");     // E/p of probe	 
    outTree->Branch("fbrem1",     &fbrem1,     "fbrem1/F");      // brem fraction of tag
    outTree->Branch("fbrem2",     &fbrem2,     "fbrem2/F");      // brem fraction of probe
    outTree->Branch("dphi1",      &dphi1,      "dphi1/F");       // GSF track - ECAL dphi of tag
    outTree->Branch("dphi2",      &dphi2,      "dphi2/F");       // GSF track - ECAL dphi of probe 	
    outTree->Branch("deta1",      &deta1,      "deta1/F");       // GSF track - ECAL deta of tag
    outTree->Branch("deta2",      &deta2,      "deta2/F");       // GSF track - ECAL deta of probe
    outTree->Branch("ecalE1",     &ecalE1,     "ecalE1/F");      // ECAL energy of tag
    outTree->Branch("ecalE2",     &ecalE2,     "ecalE2/F");      // ECAL energy of probe
    outTree->Branch("d01",        &d01,        "d01/F");	 // transverse impact parameter of tag
    outTree->Branch("d02",        &d02,        "d02/F");	 // transverse impact parameter of probe	  
    outTree->Branch("dz1",        &dz1,        "dz1/F");	 // longitudinal impact parameter of tag
    outTree->Branch("dz2",        &dz2,        "dz2/F");	 // longitudinal impact parameter of probe
    outTree->Branch("isConv1",    &isConv1,    "isConv1/i");     // conversion filter flag of tag lepton
    outTree->Branch("isConv2",    &isConv2,    "isConv2/i");     // conversion filter flag of probe lepton
    outTree->Branch("nexphits1",  &nexphits1,  "nexphits1/i");   // number of missing expected inner hits of tag lepton
    outTree->Branch("nexphits2",  &nexphits2,  "nexphits2/i");   // number of missing expected inner hits of probe lepton
    outTree->Branch("typeBits1",  &typeBits1,  "typeBits1/i");   // electron type of tag lepton
    outTree->Branch("typeBits2",  &typeBits2,  "typeBits2/i");   // electron type of probe lepton
    outTree->Branch("sc1",  "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc1);   // tag Supercluster 4-vector
    outTree->Branch("sc2",  "ROOT::Math::LorentzVector<ROOT::Math::PtEtaPhiM4D<double> >", &sc2);   // probe Supercluster 4-vector 
    
    //
    // loop through files
    //
    const UInt_t nfiles = samp->fnamev.size();
    for(UInt_t ifile=0; ifile<nfiles; ifile++) {  

      // Read input file and get the TTrees
      cout << "Processing " << samp->fnamev[ifile] << " [xsec = " << samp->xsecv[ifile] << " pb] ... "; cout.flush();
      infile = new TFile(samp->fnamev[ifile]); 
      assert(infile);

      Bool_t hasJSON = kFALSE;
      mithep::RunLumiRangeMap rlrm;
      if(samp->jsonv[ifile].CompareTo("NONE")!=0) { 
        hasJSON = kTRUE;
        rlrm.AddJSONFile(samp->jsonv[ifile].Data()); 
      }
  
      eventTree = (TTree*)infile->Get("Events");
      assert(eventTree);  
      eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
      eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");
      eventTree->SetBranchAddress("Photon",   &scArr);       TBranch *scBr       = eventTree->GetBranch("Photon");
      eventTree->SetBranchAddress("PV",       &pvArr);       TBranch *pvBr       = eventTree->GetBranch("PV");
      Bool_t hasGen = eventTree->GetBranchStatus("Gen");
      TBranch *genBr=0;
      if(hasGen) {
        eventTree->SetBranchAddress("Gen", &gen);
	genBr = eventTree->GetBranch("Gen");
      }
      
      // Compute MC event weight per 1/fb
      Double_t weight = 1;
      const Double_t xsec = samp->xsecv[ifile];
      if(xsec>0) weight = 1000.*xsec/(Double_t)eventTree->GetEntries();     

      //
      // loop over events
      //
      Double_t nsel=0, nselvar=0;
      for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
        infoBr->GetEntry(ientry);
	
	if(genBr) genBr->GetEntry(ientry);
     
        // check for certified lumi (if applicable)
        mithep::RunLumiRangeMap::RunLumiPairType rl(info->runNum, info->lumiSec);      
        if(hasJSON && !rlrm.HasRunLumi(rl)) continue;  

        // trigger requirement               
        ULong64_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL;
	ULong64_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj;  
        if(!(info->triggerBits & trigger)) continue;      
      
        // good vertex requirement
        if(!(info->hasGoodPV)) continue;
        pvArr->Clear();
        pvBr->GetEntry(ientry);
      
        //
	// SELECTION PROCEDURE:
	//  (1) Find a good electron matched to trigger -> this will be the "tag"
	//  (2) Pair the tag with Supercluster probes which form a tag+probe mass inside 
	//      the Z window and divide candidates into exclusive categories as follows:
	//      (a) if probe SC is part of a good electron matched to trigger     -> EleEle2HLT category
	//      (b) if probe SC is part of a good electron not matched to trigger -> EleEle1HLT category
	//      (c) if probe SC is part of an electron failing selection cuts     -> EleEleNoSel category
	//      (d) if probe SC is not part of an ECAL driven electron            -> EleSC category
	//	
	electronArr->Clear();
        electronBr->GetEntry(ientry);
	scArr->Clear();
	scBr->GetEntry(ientry);
        for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) {
          const mithep::TElectron *tag = (mithep::TElectron*)((*electronArr)[i1]);
	  
	  // check ECAL gap
	  if(fabs(tag->scEta)>=ECAL_GAP_LOW && fabs(tag->scEta)<=ECAL_GAP_HIGH) continue;
	  
	  Double_t escale1=1;
	  if(doScaleCorr && isam==0) {
	    for(UInt_t ieta=0; ieta<escaleNbins; ieta++) {
	      if(fabs(tag->scEta)<escaleEta[ieta]) {
	        escale1 = escaleCorr[ieta];
		break;
	      }
	    }
	  }
	  
	  if(escale1*(tag->scEt) < PT_CUT)    continue;  // lepton pT cut
	  if(fabs(tag->scEta)    > ETA_CUT)   continue;  // lepton |eta| cut
	  if(!passEleID(tag,info->rhoLowEta)) continue;  // lepton selection
	  if(!(tag->hltMatchBits & trigObj))  continue;  // check trigger matching
	  
	  LorentzVector vTag(escale1*(tag->pt), tag->eta, tag->phi, ELE_MASS);
	  LorentzVector vTagSC(escale1*(tag->scEt), tag->scEta, tag->scPhi, ELE_MASS);
	
	  for(Int_t j=0; j<scArr->GetEntriesFast(); j++) {
	    const mithep::TPhoton *scProbe = (mithep::TPhoton*)((*scArr)[j]);
	    if(scProbe->scID == tag->scID) continue;
	    
	    // check ECAL gap
	    if(fabs(scProbe->scEta)>=ECAL_GAP_LOW && fabs(scProbe->scEta)<=ECAL_GAP_HIGH) continue;
	    
	   Double_t escale2=1;
	    if(doScaleCorr && isam==0) {
	      for(UInt_t ieta=0; ieta<escaleNbins; ieta++) {
	        if(fabs(scProbe->scEta)<escaleEta[ieta]) {
	          escale2 = escaleCorr[ieta];
		  break;
	        }
	      }
	    }
	    
	    if(escale2*(scProbe->pt) < PT_CUT)  continue;  // Supercluster ET cut ("pt" = corrected by PV position)
	    if(fabs(scProbe->scEta)  > ETA_CUT) continue;  // Supercluster |eta| cuts
	    
	    const mithep::TElectron *eleProbe=0;
	    Int_t iprobe=-1;
	    for(Int_t i2=0; i2<electronArr->GetEntriesFast(); i2++) {
	      if(i1==i2) continue;
	      const mithep::TElectron *ele = (mithep::TElectron*)((*electronArr)[i2]);
	      if(!(ele->typeBits & kEcalDriven)) continue;
	      if(scProbe->scID==ele->scID) { 
	        eleProbe = ele; 
		iprobe   = i2;
		break; 
	      }
            }
	    
	    LorentzVector vProbe((eleProbe) ? escale2*(eleProbe->pt) : escale2*(scProbe->pt), 
	                         (eleProbe) ? eleProbe->eta : scProbe->eta, 
				 (eleProbe) ? eleProbe->phi : scProbe->phi, 
				 ELE_MASS);
	    LorentzVector vProbeSC((eleProbe) ? escale2*(eleProbe->scEt) : escale2*(scProbe->pt), 
	                           scProbe->scEta, scProbe->scPhi, ELE_MASS);
	    
	    // mass window
	    LorentzVector vDilep = vTag + vProbe;
	    if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;
	    
	    // determine event category
	    UInt_t icat=0;
	    if(eleProbe) {
	      if(passEleID(eleProbe,info->rhoLowEta)) {
	        if(eleProbe->hltMatchBits & trigObj) {
		  if(i1>iprobe) continue;  // make sure we don't double count EleEle2HLT category
		  icat=eEleEle2HLT;
		
		} else {
		  icat=eEleEle1HLT;
		}	      
	      } else { 
	        icat=eEleEleNoSel;
	      } 
	    } else { 
	      icat=eEleSC;
	    }
	    if(icat==0) continue;
	    
	    
	    /******** We have a Z candidate! HURRAY! ********/
	    
	    nsel+=weight;
            nselvar+=weight*weight;
	    
	    // Perform matching of dileptons to GEN leptons from Z decay
	    Bool_t hasGenMatch = kFALSE;
	    if(isSignal) {
	      Bool_t match1 = ( (abs(gen->id_1)==EGenType::kElectron) && ((toolbox::deltaR(tag->eta, tag->phi, gen->eta_1, gen->phi_1) < 0.5)) )
	                      || ( (abs(gen->id_2)==EGenType::kElectron) && ((toolbox::deltaR(tag->eta, tag->phi, gen->eta_2, gen->phi_2) < 0.5)) );
	      Bool_t match2 = ( (abs(gen->id_1)==EGenType::kElectron) && ((toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), gen->eta_1, gen->phi_1) < 0.5)) )
	                      || ( (abs(gen->id_2)==EGenType::kElectron) && ((toolbox::deltaR(vProbe.Eta(), vProbe.Phi(), gen->eta_2, gen->phi_2) < 0.5)) );
	      if(match1 && match2) hasGenMatch = kTRUE;
	    };
	    
	    //
	    // Fill tree
	    //
	    runNum   = info->runNum;
	    lumiSec  = info->lumiSec;
	    evtNum   = info->evtNum;
	    matchGen = hasGenMatch ? 1 : 0;
	    category = icat;
	    npv      = pvArr->GetEntriesFast();
	    npu      = info->nPU;
	    genVPt   = (hasGen) ? gen->vpt   : 0;
	    genVPhi  = (hasGen) ? gen->vphi  : 0;
	    genVy    = (hasGen) ? gen->vy    : 0;
	    genVMass = (hasGen) ? gen->vmass : 0;
	    scale1fb = weight;
	    met      = info->pfMET;
	    metPhi   = info->pfMETphi;
	    sumEt    = info->pfSumET;
	    
	    lep1 = &vTag;
	    q1   = tag->q;
	    
	    lep2 = &vProbe;
	    q2   = (eleProbe) ? eleProbe->q : -(tag->q);
	    
	    dilep = &vDilep;
	    
	    TVector2 vZPt((vDilep.Pt())*cos(vDilep.Phi()),(vDilep.Pt())*sin(vDilep.Phi()));        
            TVector2 vMet((info->pfMET)*cos(info->pfMETphi), (info->pfMET)*sin(info->pfMETphi));        
            TVector2 vU = -1.0*(vMet+vZPt);
            u1 = ((vDilep.Px())*(vU.Px()) + (vDilep.Py())*(vU.Py()))/(vDilep.Pt());  // u1 = (pT . u)/|pT|
            u2 = ((vDilep.Px())*(vU.Py()) - (vDilep.Py())*(vU.Px()))/(vDilep.Pt());  // u2 = (pT x u)/|pT|
	  
	    ///// electron specific /////
	    sc1        = &vTagSC;
	    trkIso1    = tag->trkIso03;
	    emIso1     = tag->emIso03;
	    hadIso1    = tag->hadIso03;
	    pfChIso1   = tag->pfChIso03;
	    pfGamIso1  = tag->pfGamIso03;	    
	    pfNeuIso1  = tag->pfNeuIso03;
	    pfCombIso1 = tag->pfChIso03 + TMath::Max(tag->pfNeuIso03 + tag->pfGamIso03 - (info->rhoLowEta)*getEffArea(tag->scEta), 0.);
	    sigieie1   = tag->sigiEtaiEta;
	    hovere1    = tag->HoverE;
	    eoverp1    = tag->EoverP;
	    fbrem1     = tag->fBrem;
	    dphi1      = tag->deltaPhiIn;
	    deta1      = tag->deltaEtaIn;
	    ecalE1     = tag->ecalE;
	    d01        = tag->d0;
	    dz1        = tag->dz;
	    isConv1    = tag->isConv;
	    nexphits1  = tag->nExpHitsInner;
	    typeBits1  = tag->typeBits;
	    
	    sc2        = &vProbeSC;
	    trkIso2    = (eleProbe) ? eleProbe->trkIso03      : -1;
	    emIso2     = (eleProbe) ? eleProbe->emIso03       : -1;
	    hadIso2    = (eleProbe) ? eleProbe->hadIso03      : -1;
	    pfChIso2   = (eleProbe) ? eleProbe->pfChIso03     : -1;
	    pfGamIso2  = (eleProbe) ? eleProbe->pfGamIso03    : -1;
	    pfNeuIso2  = (eleProbe) ? eleProbe->pfNeuIso03    : -1;
	    
	    pfCombIso2 = (eleProbe) ? 
	                 eleProbe->pfChIso03 + TMath::Max(eleProbe->pfNeuIso03 + eleProbe->pfGamIso03 - (info->rhoLowEta)*getEffArea(eleProbe->scEta), 0.) : 
			 -1;
	    
	    sigieie2   = (eleProbe) ? eleProbe->sigiEtaiEta   : scProbe->sigiEtaiEta;
	    hovere2    = (eleProbe) ? eleProbe->HoverE        : scProbe->HoverE;
	    eoverp2    = (eleProbe) ? eleProbe->EoverP        : -1;
	    fbrem2     = (eleProbe) ? eleProbe->fBrem         : -1;
	    dphi2      = (eleProbe) ? eleProbe->deltaPhiIn    : -999;
	    deta2      = (eleProbe) ? eleProbe->deltaEtaIn    : -999;
	    ecalE2     = (eleProbe) ? eleProbe->ecalE         : -999;
	    d02        = (eleProbe) ? eleProbe->d0            : -999;
	    dz2        = (eleProbe) ? eleProbe->dz            : -999;
	    isConv2    = (eleProbe) ? eleProbe->isConv        : 0;
	    nexphits2  = (eleProbe) ? eleProbe->nExpHitsInner : 0;
	    typeBits2  = (eleProbe) ? eleProbe->typeBits      : 0; 
	    
	    outTree->Fill();
	  }
        }
      }
      delete infile;
      infile=0, eventTree=0;    

      cout << nsel  << " +/- " << sqrt(nselvar);
      if(isam!=0) cout << " per 1/fb";
      cout << endl;
    }
    outFile->Write();
    outFile->Close(); 
  }
  delete info;
  delete gen;
  delete electronArr;
  delete scArr;
  delete pvArr;
  
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " Z -> e e" << endl;
  cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  if(doScaleCorr)
    cout << "  *** Scale corrections applied ***" << endl;
  cout << endl;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectZee"); 
}
Example #8
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();
  
}
void computeAccSelZeeBinned(const TString conf,            // input file
                            const TString outputDir        // output directory
) {
  gBenchmark->Start("computeAccSelZeeBinned");

  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //============================================================================================================== 

  const Double_t MASS_LOW   = 60;
  const Double_t MASS_HIGH  = 120;
  const Double_t PT_CUT     = 25;
  const Double_t ETA_CUT    = 2.5;
  const Double_t ELE_MASS   = 0.000511;
  const Double_t ETA_BARREL = 1.4442;
  const Double_t ETA_ENDCAP = 1.566;
  
  // efficiency files
  const TString dataHLTEffName     = "../Efficiency/May23_EleHLTEff/analysis/eff.root";
  const TString dataHLTEffName_pos = "../Efficiency/May23_EleHLTEff_pos/analysis/eff.root";
  const TString dataHLTEffName_neg = "../Efficiency/May23_EleHLTEff_neg/analysis/eff.root";
  const TString zeeHLTEffName      = "../Efficiency/Zee_EleHLTEff/analysis/eff.root";
  const TString zeeHLTEffName_pos  = "../Efficiency/Zee_EleHLTEff_pos/analysis/eff.root";
  const TString zeeHLTEffName_neg  = "../Efficiency/Zee_EleHLTEff_neg/analysis/eff.root";
  
  const TString dataGsfSelEffName     = "../Efficiency/May23_EleGsfSelEff/analysis/eff.root";
  const TString dataGsfSelEffName_pos = "../Efficiency/May23_EleGsfSelEff_pos/analysis/eff.root";
  const TString dataGsfSelEffName_neg = "../Efficiency/May23_EleGsfSelEff_neg/analysis/eff.root";
  const TString zeeGsfSelEffName      = "../Efficiency/Zee_EleGsfSelEff/analysis/eff.root";
  const TString zeeGsfSelEffName_pos  = "../Efficiency/Zee_EleGsfSelEff_pos/analysis/eff.root";
  const TString zeeGsfSelEffName_neg  = "../Efficiency/Zee_EleGsfSelEff_neg/analysis/eff.root";
    

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  

  vector<TString> fnamev;  // file name per input file
  vector<TString> labelv;  // TLegend label per input file
  vector<Int_t>   colorv;  // plot color per input file
  vector<Int_t>   linev;   // plot line style per input file

  //
  // parse .conf file
  //
  ifstream ifs;
  ifs.open(conf.Data());
  assert(ifs.is_open());
  string line;
  while(getline(ifs,line)) {
    if(line[0]=='#') continue;
    
    string fname;
    Int_t color, linesty;
    stringstream ss(line);
    ss >> fname >> color >> linesty;
    string label = line.substr(line.find('@')+1);
    fnamev.push_back(fname);
    labelv.push_back(label);
    colorv.push_back(color);
    linev.push_back(linesty);
  }
  ifs.close();

  // Create output directory
  gSystem->mkdir(outputDir,kTRUE);
  
  TH2D *h=0;
  
  //
  // HLT efficiency
  //
  cout << "Loading trigger efficiencies..." << endl;

  TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos);
  CEffUser2D dataHLTEff_pos;
  dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg);
  CEffUser2D dataHLTEff_neg;
  dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt"));
  
  TFile *zeeHLTEffFile_pos = new TFile(zeeHLTEffName_pos);
  CEffUser2D zeeHLTEff_pos;
  zeeHLTEff_pos.loadEff((TH2D*)zeeHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *zeeHLTEffFile_neg = new TFile(zeeHLTEffName_neg);
  CEffUser2D zeeHLTEff_neg;
  zeeHLTEff_neg.loadEff((TH2D*)zeeHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeHLTEffFile_neg->Get("hErrhEtaPt"));
  
  h =(TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt");
  TH2D *hHLTErr_pos = new TH2D("hHLTErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                 h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hHLTErr_neg = new TH2D("hHLTErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                 h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  
  //
  // Selection efficiency
  //
  cout << "Loading GSF+selection efficiencies..." << endl;
  
  TFile *dataGsfSelEffFile_pos = new TFile(dataGsfSelEffName_pos);
  CEffUser2D dataGsfSelEff_pos;
  dataGsfSelEff_pos.loadEff((TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_pos->Get("hErrhEtaPt"));
  
  TFile *dataGsfSelEffFile_neg = new TFile(dataGsfSelEffName_neg);
  CEffUser2D dataGsfSelEff_neg;
  dataGsfSelEff_neg.loadEff((TH2D*)dataGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataGsfSelEffFile_neg->Get("hErrhEtaPt"));

  TFile *zeeGsfSelEffFile_pos = new TFile(zeeGsfSelEffName_pos);
  CEffUser2D zeeGsfSelEff_pos;
  zeeGsfSelEff_pos.loadEff((TH2D*)zeeGsfSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_pos->Get("hErrhEtaPt"));

  TFile *zeeGsfSelEffFile_neg = new TFile(zeeGsfSelEffName_neg);
  CEffUser2D zeeGsfSelEff_neg;
  zeeGsfSelEff_neg.loadEff((TH2D*)zeeGsfSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zeeGsfSelEffFile_neg->Get("hErrhEtaPt"));
 
  h =(TH2D*)dataGsfSelEffFile_pos->Get("hEffEtaPt");
  TH2D *hGsfSelErr_pos = new TH2D("hGsfSelErr_pos", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  TH2D *hGsfSelErr_neg = new TH2D("hGsfSelErr_neg", "",h->GetNbinsX(),h->GetXaxis()->GetXmin(),h->GetXaxis()->GetXmax(),
                                                       h->GetNbinsY(),h->GetYaxis()->GetXmin(),h->GetYaxis()->GetXmax());
  
  // Data structures to store info from TTrees
  mithep::TEventInfo *info  = new mithep::TEventInfo();
  mithep::TGenInfo   *gen   = new mithep::TGenInfo();
  TClonesArray *electronArr = new TClonesArray("mithep::TElectron");
  
  TFile *infile=0;
  TTree *eventTree=0;
  
  // Variables to store acceptances and uncertainties (per input file)
  vector<Double_t> nEvtsv, nSelv, nSelCorrv;
  vector<Double_t> statErr2v, effErr2v;
  vector<Double_t> accv, accCorrv;
  vector<Double_t> accErrv, accCorrErrv;
    
  //
  // loop through files
  //
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {  

    // Read input file and get the TTrees
    cout << "Processing " << fnamev[ifile] << " ..." << endl;
    infile = new TFile(fnamev[ifile]); 
    assert(infile);
  
    eventTree = (TTree*)infile->Get("Events"); assert(eventTree);  
    eventTree->SetBranchAddress("Info",     &info);        TBranch *infoBr     = eventTree->GetBranch("Info");
    eventTree->SetBranchAddress("Gen",      &gen);         TBranch *genBr      = eventTree->GetBranch("Gen");
    eventTree->SetBranchAddress("Electron", &electronArr); TBranch *electronBr = eventTree->GetBranch("Electron");

    nEvtsv.push_back(0);
    nSelv.push_back(0);
    nSelCorrv.push_back(0);
    statErr2v.push_back(0);
    
    //
    // loop over events
    //
    for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
      genBr->GetEntry(ientry);
      if(gen->vmass<MASS_LOW || gen->vmass>MASS_HIGH) continue;

      infoBr->GetEntry(ientry);     
    
      Double_t weight=1;
      nEvtsv[ifile]+=weight;
    
      // trigger requirement               
      ULong_t trigger = kHLT_Ele22_CaloIdL_CaloIsoVL;
      ULong_t trigObj = kHLT_Ele22_CaloIdL_CaloIsoVL_EleObj;   
      if(!(info->triggerBits & trigger)) continue;
      
      // good vertex requirement
      if(!(info->hasGoodPV)) continue;
    
      electronArr->Clear();
      electronBr->GetEntry(ientry);
      for(Int_t i1=0; i1<electronArr->GetEntriesFast(); i1++) {
  	const mithep::TElectron *ele1 = (mithep::TElectron*)((*electronArr)[i1]);
	
	// check ECAL gap
	if(fabs(ele1->scEta)>=ETA_BARREL && fabs(ele1->scEta)<=ETA_ENDCAP) continue;
        
	if(ele1->scEt	     < PT_CUT)	     continue;  // lepton pT cut
        if(fabs(ele1->scEta) > ETA_CUT)	     continue;  // lepton |eta| cut
        if(!passEleID(ele1,info->rhoLowEta)) continue;  // lepton selection

        LorentzVector vEle1(ele1->pt, ele1->eta, ele1->phi, ELE_MASS);
	Bool_t isB1 = (fabs(ele1->scEta)<ETA_BARREL) ? kTRUE : kFALSE;

        for(Int_t i2=i1+1; i2<electronArr->GetEntriesFast(); i2++) {          
	  const mithep::TElectron *ele2 = (mithep::TElectron*)((*electronArr)[i2]);
	  
	  // check ECAL gap
	  if(fabs(ele2->scEta)>=ETA_BARREL && fabs(ele2->scEta)<=ETA_ENDCAP) continue;
        
          if(ele2->scEt        < PT_CUT)       continue;  // lepton pT cut
          if(fabs(ele2->scEta) > ETA_CUT)      continue;  // lepton |eta| cut
	  if(!passEleID(ele2,info->rhoLowEta)) continue;  // lepton selection

          LorentzVector vEle2(ele2->pt, ele2->eta, ele2->phi, ELE_MASS);  
          Bool_t isB2 = (fabs(ele2->scEta)<ETA_BARREL) ? kTRUE : kFALSE;

          // trigger match
	  if(!(ele1->hltMatchBits & trigObj) && !(ele2->hltMatchBits & trigObj)) continue;
	  
	  // mass window
          LorentzVector vDilep = vEle1 + vEle2;
          if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;
          
          
          /******** We have a Z candidate! HURRAY! ********/
       
          Double_t effdata, effmc;
          Double_t sceta1 = (fabs(ele1->scEta)<2.5) ? ele1->scEta : 0.99*(ele1->scEta);
          Double_t sceta2 = (fabs(ele2->scEta)<2.5) ? ele2->scEta : 0.99*(ele2->scEta);
    
          Double_t corr=1;
	  
	  effdata=1; effmc=1;
          if(ele1->q>0) { 
            effdata *= (1.-dataHLTEff_pos.getEff(sceta1, ele1->scEt)); 
            effmc   *= (1.-zeeHLTEff_pos.getEff(sceta1, ele1->scEt)); 
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(sceta1, ele1->scEt)); 
            effmc   *= (1.-zeeHLTEff_neg.getEff(sceta1, ele1->scEt)); 
          }
          if(ele2->q>0) {
            effdata *= (1.-dataHLTEff_pos.getEff(sceta2, ele2->scEt)); 
            effmc   *= (1.-zeeHLTEff_pos.getEff(sceta2, ele2->scEt));
          } else {
            effdata *= (1.-dataHLTEff_neg.getEff(sceta2, ele2->scEt)); 
            effmc   *= (1.-zeeHLTEff_neg.getEff(sceta2, ele2->scEt));
          }
          effdata = 1.-effdata;
          effmc   = 1.-effmc;
          corr *= effdata/effmc;
    
          effdata=1; effmc=1;
          if(ele1->q>0) { 
            effdata *= dataGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); 
            effmc   *= zeeGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); 
          } else {
            effdata *= dataGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); 
            effmc   *= zeeGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); 
          }
          if(ele2->q>0) {
            effdata *= dataGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); 
            effmc   *= zeeGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt);
          } else {
            effdata *= dataGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); 
            effmc   *= zeeGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt);
          }
          corr *= effdata/effmc;
	  
	  nSelv[ifile]+=weight;
	  nSelCorrv[ifile]+=weight*corr;
	  statErr2v[ifile]+=weight*weight*corr*corr;
	  
	  // scale factor uncertainties
//	  Double_t dataerr=0, mcerr=0;
//	  if(ele1->q>0) {	    
//	    effdata = dataGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt);
//	    errdata = TMath::Max(dataGsfSelEff_pos.getErrl(fabs(sceta1), ele1->scEt), dataGsfSelEff_pos.getErrh(fabs(sceta1), ele1->scEt));
//            effmc   = zeeGsfSelEff_pos.getEff(fabs(sceta1), ele1->scEt); 
//	    errmc   = TMath::Max(zeeGsfSelEff_pos.getErrl(fabs(sceta1), ele1->scEt), zeeGsfSelEff_pos.getErrh(fabs(sceta1), ele1->scEt));
//	    Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
//	    hGsfSelErr_pos->Fill(fabs(sceta1), ele1->scEt, errGsfSel);
//
//	  } else {
//	    effdata = dataGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt);
//	    errdata = TMath::Max(dataGsfSelEff_neg.getErrl(fabs(sceta1), ele1->scEt), dataGsfSelEff_neg.getErrh(fabs(sceta1), ele1->scEt));
//            effmc   = zeeGsfSelEff_neg.getEff(fabs(sceta1), ele1->scEt); 
//	    errmc   = TMath::Max(zeeGsfSelEff_neg.getErrl(fabs(sceta1), ele1->scEt), zeeGsfSelEff_neg.getErrh(fabs(sceta1), ele1->scEt));
//	    Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
//	    hGsfSelErr_neg->Fill(fabs(sceta1), ele1->scEt, errGsfSel);
//	  }
//	  if(ele2->q>0) {	    
//	    effdata = dataGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt);
//	    errdata = TMath::Max(dataGsfSelEff_pos.getErrl(fabs(sceta2), ele2->scEt), dataGsfSelEff_pos.getErrh(fabs(sceta2), ele2->scEt));
//            effmc   = zeeGsfSelEff_pos.getEff(fabs(sceta2), ele2->scEt); 
//	    errmc   = TMath::Max(zeeGsfSelEff_pos.getErrl(fabs(sceta2), ele2->scEt), zeeGsfSelEff_pos.getErrh(fabs(sceta2), ele2->scEt));
//	    Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
//	    hGsfSelErr_pos->Fill(fabs(sceta2), ele2->scEt, errGsfSel);
//
//	  } else {
//	    effdata = dataGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt);
//	    errdata = TMath::Max(dataGsfSelEff_neg.getErrl(fabs(sceta2), ele2->scEt), dataGsfSelEff_neg.getErrh(fabs(sceta2), ele2->scEt));
//            effmc   = zeeGsfSelEff_neg.getEff(fabs(sceta2), ele2->scEt); 
//	    errmc   = TMath::Max(zeeGsfSelEff_neg.getErrl(fabs(sceta2), ele2->scEt), zeeGsfSelEff_neg.getErrh(fabs(sceta2), ele2->scEt));
//	    Double_t errGsfSel = weight*corr*sqrt(errdata*errdata/effdata/effdata + errmc*errmc/effmc/effmc);
//	    hGsfSelErr_neg->Fill(fabs(sceta2), ele2->scEt, errGsfSel);
//	  }
        }
      }      
    }
    
//    Double_t err2=0;
//    for(Int_t iy=0; iy<=hGsfSelErr_pos->GetNbinsY(); iy++) {
//      for(Int_t ix=0; ix<=hGsfSelErr_pos->GetNbinsX(); ix++) {
//	err=hSelErr_pos->GetBinContent(ix,iy);
//	err2+=err*err;
//      }
//    }
//    for(Int_t iy=0; iy<=hGsfSelErr_neg->GetNbinsY(); iy++) {
//      for(Int_t ix=0; ix<=hGsfSelErr_neg->GetNbinsX(); ix++) {
//	err=hSelErr_neg->GetBinContent(ix,iy);
//	err2+=err*err;
//      }
//    }
//    effErr2v.push_back(err2);
    
    // compute acceptances
    accv.push_back(nSelv[ifile]/nEvtsv[ifile]);         accErrv.push_back(sqrt(accv[ifile]*(1.-accv[ifile])/nEvtsv[ifile]));
    accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]); accCorrErrv.push_back(sqrt(accCorrv[ifile]*(1.-accCorrv[ifile])/nEvtsv[ifile]));
    
    delete infile;
    infile=0, eventTree=0;  
  }  
  delete info;
  delete gen;
  delete electronArr;
  
    
  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << " Z -> e e" << endl;
  cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  cout << "  pT > " << PT_CUT << endl;
  cout << "  |eta| < " << ETA_CUT << endl;
  cout << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    cout << "   ================================================" << endl;
    cout << "    Label: " << labelv[ifile] << endl;
    cout << "     File: " << fnamev[ifile] << endl;
    cout << endl;
    cout << "    *** Acceptance ***" << endl;
    cout << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    cout << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
    cout << endl;
  }
  
  char txtfname[100];
  sprintf(txtfname,"%s/binned.txt",outputDir.Data());
  ofstream txtfile;
  txtfile.open(txtfname);
  txtfile << "*" << endl;
  txtfile << "* SUMMARY" << endl;
  txtfile << "*--------------------------------------------------" << endl;
  txtfile << " Z -> e e" << endl;
  txtfile << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
  txtfile << "  pT > " << PT_CUT << endl;
  txtfile << "  |eta| < " << ETA_CUT << endl;
  txtfile << endl;
  
  for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
    txtfile << "   ================================================" << endl;
    txtfile << "    Label: " << labelv[ifile] << endl;
    txtfile << "     File: " << fnamev[ifile] << endl;
    txtfile << endl;
    txtfile << "    *** Acceptance ***" << endl;
    txtfile << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
    txtfile << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
    txtfile << endl;
  }
  txtfile.close();
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("computeAccSelZeeBinned"); 
}
int ScanChain( TChain* chain, bool fast = true, int nEvents = -1, string skimFilePrefix = "test") {

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

  // Example Histograms
  TDirectory *rootdir = gDirectory->GetDirectory("Rint:");
  /*
   // This loads the library
   TMVA::Tools::Instance();

   // to get access to the GUI and all tmva macros
   TString thisdir = gSystem->DirName(gInterpreter->GetCurrentMacroName());
   gROOT->SetMacroPath(thisdir + ":" + gROOT->GetMacroPath());
   gROOT->ProcessLine(".L TMVAGui.C");
*/

  map<string, TH1F*> histos; //massive
  vector<string> histonames; histonames.clear();
  vector<string> histonameshelp; histonameshelp.clear();
  vector<int> histobinn; histobinn.clear();
  vector<double> histobinl; histobinl.clear();
  vector<double> histobinu; histobinu.clear();
  map<string, float> value;

  histonames.push_back("MT2W");               histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(500.);
  //histonames.push_back("MT2_b_b");            histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("MT2_lb_b");           histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("MT2_lb_bq");          histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("MT2_lb_bqq");         histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(1000.);
  //histonames.push_back("MT2_l_q");            histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(300.);
  histonames.push_back("MT2_lb_b_mless");     histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("MT2_lb_bq_mless");    histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("MT2_lb_bqq_mless");   histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("MT2_l_qq_mless");     histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("Mlb");                histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("Mlbb");               histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(1000.);
  histonames.push_back("M3b");                histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(1000.);
  histonames.push_back("MTb");                histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("MTq");                histobinn.push_back(20); histobinl.push_back(0.); histobinu.push_back(500.);
  histonames.push_back("MTqmax");             histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(1500.);
  //histonames.push_back("MTq_boostmax");       histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(1500.);
  //histonames.push_back("MTq_boost300");       histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(1500.);
  histonames.push_back("MTq_boostLeadJet");   histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(1500.);
  //histonames.push_back("MTqq");               histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("Topness");            histobinn.push_back(30); histobinl.push_back(-15.); histobinu.push_back(15.);
  histonames.push_back("MT");                 histobinn.push_back(40); histobinl.push_back(0.); histobinu.push_back(400.);
  histonames.push_back("MET");                histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("HT");                 histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(1000.);
  histonames.push_back("METoverSqrtHT");      histobinn.push_back(20); histobinl.push_back(0.); histobinu.push_back(40.);
  histonames.push_back("HTratio");            histobinn.push_back(20); histobinl.push_back(0.); histobinu.push_back(1.);
  histonames.push_back("dRLepBJet");          histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(10.);
  histonames.push_back("dRbb");               histobinn.push_back(25); histobinl.push_back(0.); histobinu.push_back(10.);
  histonames.push_back("chi2");               histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(30.);
  histonames.push_back("NBJets");             histobinn.push_back( 5); histobinl.push_back(0.); histobinu.push_back(5.);
  histonames.push_back("NJets");              histobinn.push_back(10); histobinl.push_back(0.); histobinu.push_back(10.);
  //histonames.push_back("minDPhi");            histobinn.push_back(32); histobinl.push_back(0.); histobinu.push_back(3.2);
  histonames.push_back("minDPhiJ3");          histobinn.push_back(32); histobinl.push_back(0.); histobinu.push_back(3.2);
  //histonames.push_back("minDPhiB");           histobinn.push_back(32); histobinl.push_back(0.); histobinu.push_back(3.2);
  //histonames.push_back("pTlb");               histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(600.);
  histonames.push_back("pTlbb");              histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(600.);
  histonames.push_back("pTl");                histobinn.push_back(27); histobinl.push_back(0.); histobinu.push_back(405.);
  histonames.push_back("pTleadj");            histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("pTleadb");            histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("pTtrailb");           histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  //histonames.push_back("sumak8prunedmass");   histobinn.push_back(30); histobinl.push_back(0.); histobinu.push_back(750.);
  histonames.push_back("DeltaPhiWl");         histobinn.push_back(32); histobinl.push_back(0.); histobinu.push_back(3.2);

  TFile *outfile[3];
  TTree *outtree[3];
  for(unsigned int b = 0; b<histonames.size(); ++b){
    value[histonames[b] ] = -99;
    histonameshelp.push_back(histonames[b]+(string)"/F");
  }
  for(unsigned int b = 0; b<3; ++b){
    string samplename = skimFilePrefix;
    if(skimFilePrefix!="TTbar"&&b>0) continue;
    if(skimFilePrefix=="TTbar"&&b==0) samplename = "TTbar1l";
    if(skimFilePrefix=="TTbar"&&b==1) samplename = "TTbar2l";
    if(skimFilePrefix=="TTbar"&&b==2) samplename = "TTbarH";
    TString fileName = "rootfiles/TestmysmallBDTvartree_"+samplename+".root";
    outfile[b] = new TFile(fileName,"RECREATE");
    outtree[b] = new TTree(samplename.c_str(),"");
    for(unsigned int a = 0; a<histonames.size(); ++a){
      outtree[b]->Branch(histonames[a].c_str(), &value[histonames[a] ], histonameshelp[a].c_str() );
    }
  }



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

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

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

      int sampleid = 0;
      string samplename = skimFilePrefix;
      if(skimFilePrefix=="TTbar"){
	if(cms3.gen_nfromtmus_() + cms3.gen_nfromtels_() + cms3.gen_nfromttaus_() ==2) { samplename = "TTbar2l"; sampleid=1; }
	else if(cms3.gen_nfromtmus_() + cms3.gen_nfromtels_() + cms3.gen_nfromttaus_() ==1) { samplename = "TTbar1l"; sampleid=0; }
	else { samplename = "TTbarH"; sampleid=2; }
      }
      // Analysis Code
      float weight = cms3.scale1fb()*10.;
      int NLeps = cms3.ngoodlep();
      string ds = cms3.dataset();
      float MET = cms3.pfmet();
      float METPhi = cms3.pfmet_phi();
      float METx = MET*TMath::Cos(METPhi);
      float METy = MET*TMath::Sin(METPhi);
      float MT2W = cms3.MT2W_lep1();
      float MT = cms3.MT_MET_lep1();
      float dRLepBJet = cms3.dR_lep1_leadb();
      float chi2 = cms3.chi2();
      //float genmet = cms3.genmet();
      //int NJets = cms3.ak4GoodPFJets();
      //int NBJets = cms3.ak4_nBTags_Med();
      float HT = cms3.ak4_HT();
      float HTratio = cms3.ak4_htratiom();
      int nvtxs = cms3.nvtxs();
      float minDPhi = cms3.mindphi_met_j1_j2();
      vector<ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > > jetslv = cms3.ak4pfjets_p4();
      vector<float> jetsbtag = cms3.ak4pfjets_btag_disc();
      vector<bool> jetsID = cms3.ak4pfjets_loose_pfid();
      ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > lep1lv = cms3.lep1_p4();
      float lep1pt = cms3.lep1_pt();
      float lep1eta = cms3.lep1_eta();
      //float lep1dr03isoDB = cms3.lep1_relIso03DB();
      bool lep1eIDl = cms3.lep1_is_eleid_loose();
      bool lep1eIDm = cms3.lep1_is_eleid_medium();
      bool lep1mIDt = cms3.lep1_is_muoid_tight();
      bool lep1ismu = cms3.lep1_is_mu();
      bool lep1isel = cms3.lep1_is_el();
      ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > lep2lv = cms3.lep1_p4();
      float lep2pt = cms3.lep2_pt();
      float lep2eta = cms3.lep2_eta();
      //float lep2dr03isoDB = cms3.lep2_relIso03DB();
      bool lep2eIDl = cms3.lep2_is_eleid_loose();
      bool lep2eIDm = cms3.lep2_is_eleid_medium();
      bool lep2mIDt = cms3.lep2_is_muoid_tight();
      bool lep2ismu = cms3.lep2_is_mu();
      bool lep2isel = cms3.lep2_is_el();
      
      bool trackveto = cms3.PassTrackVeto();
      bool tauveto = cms3.PassTauVeto();

      int NGLeps = 0;
      int NSLeps = 0;
      int NGJets = 0;
      int NGBJets = 0;

      int l1=-1;
      if(lep1ismu){
	//if(lep1pt>20&&fabs(lep1eta)<99&&lep1mIDt) ++NGLeps;
	//if(lep1pt>25&&fabs(lep1eta)<2.1&&lep1mIDt&&lep1dr03isoDB*lep1pt<TMath::Min(5.,0.15*lep1pt)) {++NSLeps; l1 = 1;}
	if(lep1pt>30&&fabs(lep1eta)<2.1&&fabs(cms3.lep1_d0())<0.02&&fabs(cms3.lep1_dz())<0.1&&cms3.lep1_miniRelIsoDB()<0.1) {++NSLeps; l1 = 1; }
      } else if (lep1isel){
	//if(lep1pt>20&&fabs(lep1eta)<99&&lep1eIDl) ++NGLeps;
	//if(lep1pt>30&&fabs(lep1eta)<1.442&&lep1eIDm&&lep1dr03isoDB*lep1pt<TMath::Min(5.,0.15*lep1pt)) {++NSLeps; l1 = 1;}
	if(lep1pt>40&&fabs(lep1eta)<2.1&&cms3.lep1_is_phys14_medium_noIso()&&cms3.lep1_miniRelIsoDB()<0.1) {++NSLeps; l1 = 1; }
      }
      if(lep2ismu){
	//if(lep2pt>20&&fabs(lep2eta)<99&&lep2mIDt) ++NGLeps;
	//if(lep2pt>25&&fabs(lep2eta)<2.1&&lep2mIDt&&lep2dr03isoDB*lep2pt<TMath::Min(5.,0.15*lep2pt)) {++NSLeps; if(l1!=1) l1 = 2; else l1=-2;}
	if(lep2pt>30&&fabs(lep2eta)<2.1&&fabs(cms3.lep2_d0())<0.02&&fabs(cms3.lep2_dz())<0.1&&cms3.lep2_miniRelIsoDB()<0.1) {++NSLeps; l1 = 1; if(l1!=1) l1 = 2; else l1=-2; }
      } else if (lep2isel){
	//if(lep2pt>20&&fabs(lep2eta)<99&&lep2eIDl) ++NGLeps;
	//if(lep2pt>30&&fabs(lep2eta)<1.442&&lep2eIDm&&lep2dr03isoDB*lep2pt<TMath::Min(5.,0.15*lep2pt)) {++NSLeps; if(l1!=1) l1 = 2; else l1=-2;}
	if(lep2pt>40&&fabs(lep2eta)<2.1&&cms3.lep2_is_phys14_medium_noIso()&&cms3.lep2_miniRelIsoDB()<0.1) {++NSLeps; if(l1!=1) l1 = 2; else l1=-2;}
      }
      NGLeps = NLeps;

      ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > leplv;
      if(l1==1) leplv = lep1lv;
      else if(l1==2) leplv = lep2lv;

      ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > metlv;
      metlv.SetPxPyPzE(METx,METy,0.,MET);

      //if(NGLeps != NLeps) cout << "NGLeps = " << NGLeps << " NLeps = " << NLeps << endl;
      //NGLeps = NLeps;
      vector<int> jind;
      vector<int> bind;
      ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > jsumlv;
      vector<ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > > jetlv;
      vector<ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > > boostjetlv;
      vector<ROOT::Math::LorentzVector<ROOT::Math::PxPyPzE4D<float> > > bjetlv;
      vector<float> btag;
      int jj1(-1), jj2(-1), jj3(-1);// j1(-1), j2(-1), jm(-1);
      float jj1d(-1), jj2d(-1), jj3d(-1);// jjmm(-1);
      for(unsigned int nj = 0; nj<jetsbtag.size(); ++nj){
	if(jetslv[nj].Pt()<30) continue;
	if(fabs(jetslv[nj].Eta())>2.4) continue;
	if(jetsID[nj]==false) continue;
	jind.push_back(nj);
	jetlv.push_back(jetslv[nj]);
	if(jetslv[nj].Pt()>250) boostjetlv.push_back(jetslv[nj]);
	btag.push_back(jetsbtag[nj]);
	++NGJets;
	if(jetsbtag[nj]>0.814) {++NGBJets; bind.push_back(nj); bjetlv.push_back(jetslv[nj]);}
	if(jetslv[nj].Pt()>jj1d){
	  jj3d = jj2d; jj2d = jj1d; jj1d = jetslv[nj].Pt();
	  jj3 = jj2; jj2 = jj1; jj1 = nj;
	} else if(jetslv[nj].Pt()>jj2d){
	  jj3d = jj2d; jj2d = jetslv[nj].Pt();
	  jj3 = jj2; jj2 = nj;
	} else if(jetslv[nj].Pt()>jj3d){
	  jj3d = jetslv[nj].Pt();
	  jj3 = nj;
	}
      }

      if(nvtxs<0) continue; 
      if(NGLeps!=1) continue; 
      if(NSLeps!=1) continue; 
      if(!trackveto) continue; 
      if(!tauveto) continue; 
      if(NGJets<4) continue;
      //if(NGBJets<1) continue; 
      if(MET<30) continue; 
      //if(MT>80) continue;

      for(unsigned int i = 0; i<histonames.size(); ++i){
	value[histonames[i] ] = -99;//reset values
      }
      //vector<LorentzVector > btaggedjets = JetUtil::BJetSelector(jetlv,btag,0.814,2,3,1);
      vector<LorentzVector > btaggedjets = JetUtil::BJetSelector(jetlv,btag,0.814,2,2,2);

      vector<LorentzVector > dummybjets;dummybjets.clear();
      LorentzVector dummybjet; dummybjet.SetPxPyPzE(0.,0.,0.,0.); dummybjets.push_back(dummybjet);dummybjets.push_back(dummybjet);
      
      //value["MT2W"]                  = CalculateMT2W_(btaggedjets,leplv,MET,METPhi,true);
      value["MT2W"] = MT2W;
      value["Topness"]               = Gettopness_(MET,METPhi,leplv,btaggedjets,1);
      value["MT2_b_b"]               = MT2_b_b_(MET,METPhi,btaggedjets,true, 0);
      value["MT2_lb_b_mless"]        = MT2_lb_b_(MET,METPhi,leplv,btaggedjets,false,0);
      value["MT2_lb_b"]              = MT2_lb_b_(MET,METPhi,leplv,btaggedjets,true ,0);
      value["MT2_lb_bq_mless"]       = MT2_lb_bq_( MET,METPhi,leplv,btaggedjets,jetlv,false,0);
      value["MT2_lb_bq"]             = MT2_lb_bq_( MET,METPhi,leplv,btaggedjets,jetlv,true ,0);
      value["MT2_lb_bqq_mless"]      = MT2_lb_bqq_(MET,METPhi,leplv,btaggedjets,jetlv,false,0);
      value["MT2_lb_bqq"]            = MT2_lb_bqq_(MET,METPhi,leplv,btaggedjets,jetlv,true ,0);
      value["MT2_l_q"]               = MT2_lb_bq_( MET,METPhi,leplv,dummybjets,jetlv,true ,0);
      value["MT2_l_qq_mless"]        = MT2_lb_bqq_(MET,METPhi,leplv,dummybjets,jetlv,true ,0);

      int leadb(-1), trailb(-1);
      for(unsigned int n = 0; n<btaggedjets.size();++n){
	if(leadb<0) leadb = n;
	else if(trailb<0) trailb = n;
	else if(btaggedjets[n].Pt() > btaggedjets[leadb].Pt()){ trailb = leadb; leadb = n; }
	else if(btaggedjets[n].Pt() > btaggedjets[trailb].Pt()){ trailb = n; }
	LorentzVector temp = btaggedjets[n]+leplv;
	if(temp.M()<value["Mlb"]) value["Mlb"] = temp.M();  else if(value["Mlb"]<0) value["Mlb"] = temp.M();
	if(temp.Pt()<value["pTlb"]) value["pTlb"] = temp.Pt();  else if(value["pTlb"]<0) value["pTlb"] = temp.Pt();
	float tmp = getMT(btaggedjets[n],metlv);
	if(tmp<value["MTb"]) value["MTb"] = tmp;  else if(value["MTb"]<0) value["MTb"] = tmp;
	tmp = JetUtil::deltaR(btaggedjets[n],leplv);
	tmp = JetUtil::deltaPhi(btaggedjets[n],metlv);
	if(tmp<value["minDPhiB"]) value["minDPhiB"] = tmp;  else if(value["minDPhiB"]<0) value["minDPhiB"] = tmp;
	for(unsigned int m = n+1; m<btaggedjets.size();++m){
	  temp = btaggedjets[n]+btaggedjets[m]+leplv;
	  if(temp.M()<value["Mlbb"]) value["Mlbb"] = temp.M();  else if(value["Mlbb"]<0) value["Mlbb"] = temp.M();
	  if(temp.Pt()<value["pTlbb"]) value["pTlbb"] = temp.Pt();  else if(value["pTlbb"]<0) value["pTlbb"] = temp.Pt();
	  tmp = JetUtil::deltaR(btaggedjets[n],btaggedjets[m]);
	  if(tmp<value["dRbb"]) value["dRbb"] = tmp;  else if(value["dRbb"]<0) value["dRbb"] = tmp;
	}
      }
      float myleadjpt = -1.;
      int bj1(-1), bj2(-1),bj3(-1);
      for(unsigned int n = 0; n<jetlv.size();++n){
	float tmp = getMT(jetlv[n],metlv);
  	if(tmp<value["MTq"]) value["MTq"] = tmp;  else if(value["MTq"]<0) value["MTq"] = tmp;
  	if(tmp>value["MTqmax"]) value["MTqmax"] = tmp;  else if(value["MTqmax"]<0) value["MTqmax"] = tmp;
	if(jetlv[n].Pt()>250.){ if(tmp>value["MTq_boostmax"]) value["MTq_boostmax"] = tmp;  else if(value["MTq_boostmax"]<0) value["MTq_boostmax"] = tmp; }
	if(jetlv[n].Pt()>300.){ if(tmp<value["MTq_boost300"]) value["MTq_boost300"] = tmp;  else if(value["MTq_boost300"]<0) value["MTq_boost300"] = tmp; }
	if(jetlv[n].Pt()>myleadjpt){ value["MTq_boostLeadJet"] = tmp; myleadjpt = jetlv[n].Pt(); }// else if(value["MTq_boostLeadJet"]<0) value["MTq_boostLeadJet"] = tmp;
	for(unsigned int m = n+1; m<jetlv.size();++m){
	  tmp = getMT(jetlv[n]+jetlv[m],metlv);
	  if(tmp<value["MTqq"]) value["MTqq"] = tmp;  else if(value["MTqq"]<0) value["MTqq"] = tmp;
	}
	if(n<3){
	  tmp = JetUtil::deltaPhi(jetlv[n],metlv);
	  if(tmp<value["minDPhiJ3"]) value["minDPhiJ3"] = tmp;  else if(value["minDPhiJ3"]<0) value["minDPhiJ3"] = tmp;
	}
	float dP1l(-1), dP2l(-1), dP3l(-1);
	if(bj1>0) dP1l = JetUtil::deltaPhi(jetlv[bj1],leplv);
	if(bj2>0) dP2l = JetUtil::deltaPhi(jetlv[bj2],leplv);
	if(bj3>0) dP3l = JetUtil::deltaPhi(jetlv[bj3],leplv);
	if(JetUtil::deltaPhi(jetlv[n],leplv)>dP1l){ bj3 = bj2; bj2 = bj1; bj1 = n;}
	else if(JetUtil::deltaPhi(jetlv[n],leplv)>dP2l){ bj3 = bj2; bj2 = n;}
	else if(JetUtil::deltaPhi(jetlv[n],leplv)>dP3l){ bj3 = n;}
      }

      LorentzVector bjsumlep = jetlv[bj1] + jetlv[bj2] + jetlv[bj3];
      value["M3b"] = bjsumlep.M();

      float prune=0.;
      for(unsigned int n = 0; n<cms3.ak8pfjets_pruned_mass().size();++n) prune += cms3.ak8pfjets_pruned_mass()[n];
      
      //cout << __LINE__<<endl;
      value["sumak8prunedmass"]   = prune;
      value["MT"] = MT;
      value["MET"] = MET;
      value["HT"] = HT;
      if(HT>0) {
	value["METoverSqrtHT"] = MET/TMath::Sqrt(HT);
      }
      value["HTratio"] = HTratio;
      value["dRLepBJet"] = dRLepBJet;
      value["chi2"] = chi2;
      value["NBJets"] = NGBJets;
      value["NJets"] = NGJets;
      value["minDPhi"] = minDPhi;
      value["pTl"] = leplv.Pt();
      value["pTleadj"] = myleadjpt;
      value["pTleadb"] = btaggedjets[leadb].Pt();
      value["pTtrailb"] = btaggedjets[trailb].Pt();
      value["DeltaPhiWl"] = JetUtil::deltaPhi(leplv,metlv+leplv);

      outtree[sampleid]->Fill();


      for(unsigned int i = 0; i<histonames.size(); ++i){
	value[histonames[i] ] = -99;//reset values
      }
    }
  
    // Clean Up
    delete tree;
    file->Close();
    delete file;
  }
  if ( nEventsChain != nEventsTotal ) {
    cout << Form( "ERROR: number of events from files (%d) is not equal to total number of events (%d)", nEventsChain, nEventsTotal ) << endl;
  }

  for(unsigned int b = 0; b<3; ++b){
    if(skimFilePrefix!="TTbar"&&b>0) continue;
    outfile[b]->cd();
    outtree[b]->Write();
    outfile[b]->Close();
    cout << "Tree for making BDT saved in " << outfile[b]->GetName() << endl;
  }

  // return
  bmark->Stop("benchmark");
  cout << endl;
  cout << nEventsTotal << " Events Processed" << endl;
  cout << "------------------------------" << endl;
  cout << "CPU  Time:	" << Form( "%.01f", bmark->GetCpuTime("benchmark")  ) << endl;
  cout << "Real Time:	" << Form( "%.01f", bmark->GetRealTime("benchmark") ) << endl;
  cout << endl;
  delete bmark;
  return 0;
}
inline float getMT(LorentzVector lep,LorentzVector met){
  // From cmssw reco::deltaPhi()
  return TMath::Sqrt(2*met.Et()*lep.Et()*(1-TMath::Cos(JetUtil::deltaPhi(lep,met) ) ) );
}
Example #12
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();
  
  
}
Example #13
0
void selectProbesMuEff(const TString infilename,           // input ntuple
                       const TString outputDir, 	   // output directory
		       const Int_t   effType, 	           // type of efficiency to compute
		       const Bool_t  doGenMatch = kFALSE,  // match to generator leptons
		       const Bool_t  doWeighted = kFALSE   // store events with weights
) {
  gBenchmark->Start("selectProbesMuEff");
  
  //--------------------------------------------------------------------------------------------------------------
  // Settings 
  //==============================================================================================================   
 
  const Double_t TAG_PT_CUT = 25;
  

  //--------------------------------------------------------------------------------------------------------------
  // Main analysis code 
  //==============================================================================================================  
  
  enum { eHLTEff, eSelEff, eTrkEff, eStaEff, eStaEff_iso, ePOGIDEff, ePOGIsoEff };
  if(effType > ePOGIsoEff) {
    cout << "Invalid effType option! Exiting..." << endl;
    return;
  }
  
  enum { eMuMu2HLT=1, eMuMu1HLT, eMuMuNoSel, eMuSta, eMuTrk };  // event category enum
  
  Double_t nProbes = 0;
  
  //
  // Set up output ntuple
  //
  gSystem->mkdir(outputDir,kTRUE);
  TFile *outFile = new TFile(outputDir+TString("/probes.root"),"RECREATE"); 
  TTree *outTree = new TTree("Events","Events");
  EffData data;
  outTree->Branch("Events",&data.mass,"mass/F:pt:eta:phi:weight:q/I:npv/i:npu:pass:runNum:lumiSec:evtNum");

  //
  // Declare output ntuple variables
  //
  UInt_t  runNum, lumiSec, evtNum;
  UInt_t  matchGen;
  UInt_t  category;
  UInt_t  npv, npu;
  Float_t scale1fb;
  Float_t met, metPhi, sumEt, u1, u2;
  Int_t   q1, q2;
  LorentzVector *dilep=0, *lep1=0, *lep2=0;
  LorentzVector *sta1=0, *sta2=0;
  Float_t pfCombIso1, pfCombIso2;
  Float_t d01, dz1, d02, dz2;
  Float_t muNchi21,  muNchi22;
  UInt_t nPixHits1, nTkLayers1, nPixHits2, nTkLayers2;
  UInt_t nValidHits1, nMatch1, nValidHits2, nMatch2;
  UInt_t typeBits1, typeBits2;

  // Read input file and get the TTrees
  cout << "Processing " << infilename << "..." << endl;
  TFile *infile = new TFile(infilename);	 assert(infile);
  TTree *intree = (TTree*)infile->Get("Events"); assert(intree);

  intree->SetBranchAddress("runNum",     &runNum);      // event run number
  intree->SetBranchAddress("lumiSec",    &lumiSec);     // event lumi section
  intree->SetBranchAddress("evtNum",     &evtNum);      // event number
  intree->SetBranchAddress("matchGen",   &matchGen);    // event has both leptons matched to MC Z->ll
  intree->SetBranchAddress("category",   &category);    // dilepton category
  intree->SetBranchAddress("npv",        &npv);	        // number of primary vertices
  intree->SetBranchAddress("npu",        &npu);	        // number of in-time PU events (MC)
  intree->SetBranchAddress("scale1fb",   &scale1fb);    // event weight per 1/fb (MC)
  intree->SetBranchAddress("met",        &met);	        // MET
  intree->SetBranchAddress("metPhi",     &metPhi);      // phi(MET)
  intree->SetBranchAddress("sumEt",      &sumEt);       // Sum ET
  intree->SetBranchAddress("u1",         &u1);	        // parallel component of recoil
  intree->SetBranchAddress("u2",         &u2);	        // perpendicular component of recoil
  intree->SetBranchAddress("q1",         &q1);	        // charge of tag lepton
  intree->SetBranchAddress("q2",         &q2);	        // charge of probe lepton
  intree->SetBranchAddress("dilep",      &dilep);       // dilepton 4-vector
  intree->SetBranchAddress("lep1",       &lep1);        // tag lepton 4-vector
  intree->SetBranchAddress("lep2",       &lep2);        // probe lepton 4-vector
  intree->SetBranchAddress("sta1",       &sta1);        // tag STA muon 4-vector
  intree->SetBranchAddress("sta2",       &sta2);        // probe STA muon 4-vector 
  intree->SetBranchAddress("pfCombIso1", &pfCombIso1);  // PF combined isolation of tag lepton
  intree->SetBranchAddress("pfCombIso2", &pfCombIso2);  // PF combined isolation of probe lepton    
  intree->SetBranchAddress("d01",        &d01); 	// transverse impact parameter of tag lepton
  intree->SetBranchAddress("d02",	 &d02); 	// transverse impact parameter of probe lepton      
  intree->SetBranchAddress("dz1",	 &dz1); 	// longitudinal impact parameter of tag lepton
  intree->SetBranchAddress("dz2",	 &dz2); 	// longitudinal impact parameter of probe lepton    
  intree->SetBranchAddress("muNchi21",	 &muNchi21);	// muon fit normalized chi^2 of tag lepton
  intree->SetBranchAddress("muNchi22",	 &muNchi22);	// muon fit normalized chi^2 of probe lepton	 
  intree->SetBranchAddress("nPixHits1",  &nPixHits1);   // number of pixel hits of tag muon
  intree->SetBranchAddress("nPixHits2",  &nPixHits2);   // number of pixel hits of probe muon
  intree->SetBranchAddress("nTkLayers1", &nTkLayers1);  // number of tracker layers of tag muon
  intree->SetBranchAddress("nTkLayers2", &nTkLayers2);  // number of tracker layers of probe muon
  intree->SetBranchAddress("nMatch1",	 &nMatch1);	// number of matched segments of tag muon
  intree->SetBranchAddress("nMatch2",	 &nMatch2);	// number of matched segments of probe muon    
  intree->SetBranchAddress("nValidHits1",&nValidHits1); // number of valid muon hits of tag muon
  intree->SetBranchAddress("nValidHits2",&nValidHits2); // number of valid muon hits of probe muon
  intree->SetBranchAddress("typeBits1",  &typeBits1);   // muon type of tag muon
  intree->SetBranchAddress("typeBits2",  &typeBits2);   // muon type of probe muon

  //
  // loop over events
  //
  for(UInt_t ientry=0; ientry<intree->GetEntries(); ientry++) {
    intree->GetEntry(ientry);

    if(lep1->Pt() < TAG_PT_CUT) continue;
    
    // check GEN match if necessary
    if(doGenMatch && !matchGen) continue;
    
    Bool_t  pass=kFALSE;
    Float_t mass=0;
    
    if(effType==eHLTEff) {
      //
      // probe = muon passing selection
      // pass  = matched to HLT
      // * MuMu2HLT event means a passing probe, MuMu1HLT event means a failing probe
      //   all other categories do not satisfy probe requirements
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kFALSE; }
      else if(category==eMuMuNoSel) { continue; }
      else if(category==eMuSta)     { continue; }
      else                          { continue; }
      
      mass = dilep->M();
    
    } else if(effType==eSelEff) {
      //
      // probe = GLB muon
      // pass  = passing selection
      // * MuMu2HLT, MuMu1HLT event means a passing probe, MuMuNoSel event means a failing probe,
      //   all other categories do not satisfy probe requirements
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) { pass=kFALSE; }
      else if(category==eMuSta)     { continue; }
      else                          { continue; }
      
      mass = dilep->M();
    
    } else if(effType==eTrkEff) {
      //
      // probe = STA muon
      // pass  = is also a GLB muon
      // * MuMu2HLT, MuMu1HLT, MuMuNoSel event means a passing probe, MuSta event means a failing probe, 
      //   MuTrk event does not satisfy probe requirements
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) { pass=kTRUE; }
      else if(category==eMuSta)     { pass=kFALSE; }
      else                          { continue; }
      
      // compute mass using probe STA muon pT
      LorentzVector tp = *lep1 + *sta2;
      mass = tp.M();    
    
    } else if(effType==eStaEff) {
      //
      // probe = tracker track
      // pass  = is also a GLB muon
      // * MuMu2HLT, MuMu1HLT, MuMuNoSel event means a passing probe, MuTrk event means a failing probe, 
      //   MuSta event does not satisfy probe requirements
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) { pass=kTRUE; }
      else if(category==eMuSta)     { continue; }
      else                          { pass=kFALSE; }
      
      mass = dilep->M();
    
    } else if(effType==eStaEff_iso) {
      //
      // probe = isolated tracker track
      // pass  = is also a GLB muon
      // * MuMu2HLT, MuMu1HLT, isolated MuMuNoSel event means a passing probe, isolated MuTrk event means a failing probe, 
      //   MuSta, non-isolated MuMuNoSel, and non-isolated MuTrk events do not satisfy probe requirements
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) { if(pfCombIso2>0.12*(lep2->Pt())) continue; else pass=kTRUE; }
      else if(category==eMuSta)     { continue; }
      else                          { if(pfCombIso2>0.12*(lep2->Pt())) continue; else pass=kFALSE; }
      
      mass = dilep->M();
    
    } else if(effType==ePOGIDEff) {
      //
      // probe = tracker track
      // pass  = passes "tight" muon ID
      // * 
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) { 
        
	pass=kTRUE; 
        if(nTkLayers2  < 6)   pass=kFALSE;
        if(nPixHits2   < 1)   pass=kFALSE;
        if(fabs(d02)   > 0.2) pass=kFALSE;
        if(fabs(dz2)   > 0.5) pass=kFALSE;
        if(muNchi22    > 10)  pass=kFALSE;
        if(nMatch2     < 2)   pass=kFALSE;
        if(nValidHits2 < 1)   pass=kFALSE;
        if(!(typeBits2 & 1))  pass=kFALSE;
        if(!(typeBits2 & 8))  pass=kFALSE;
      }
      else if(category==eMuSta)     { continue; }
      else                          { pass=kFALSE; }
      
      mass = dilep->M();    
    
    } else if(effType==ePOGIsoEff) {
      //
      // probe = "tight" muon
      // pass  = passes isolation
      // * 
      //    
      if     (category==eMuMu2HLT)  { pass=kTRUE; }
      else if(category==eMuMu1HLT)  { pass=kTRUE; }
      else if(category==eMuMuNoSel) {
        
	if(nTkLayers2  < 6)   continue;
        if(nPixHits2   < 1)   continue;
        if(fabs(d02)   > 0.2) continue;
        if(fabs(dz2)   > 0.5) continue;
        if(muNchi22    > 10)  continue;
        if(nMatch2     < 2)   continue;
        if(nValidHits2 < 1)   continue;
        if(!(typeBits2 & 1))  continue;
        if(!(typeBits2 & 8))  continue;

	pass = (pfCombIso2 < 0.12*(lep2->Pt()));      
      }
      else if(category==eMuSta)     { continue; }
      else                          { continue; }
      
      mass = dilep->M();    
    }
    
    nProbes += doWeighted ? scale1fb : 1;

    // Fill tree
    data.mass	 = mass;
    data.pt	 = (effType==eTrkEff) ? sta2->Pt()  : lep2->Pt();
    data.eta	 = (effType==eTrkEff) ? sta2->Eta() : lep2->Eta();
    data.phi	 = (effType==eTrkEff) ? sta2->Phi() : lep2->Phi();
    data.weight  = doWeighted ? scale1fb : 1;
    data.q	 = q2;
    data.npv	 = npv;
    data.npu	 = npu;
    data.pass	 = (pass) ? 1 : 0;
    data.runNum  = runNum;
    data.lumiSec = lumiSec;
    data.evtNum  = evtNum;
    outTree->Fill();
    
    if(category==eMuMu2HLT) {
      if(lep2->Pt() < TAG_PT_CUT) continue;

      nProbes += doWeighted ? scale1fb : 1;

      data.mass	   = mass;
      data.pt	   = (effType==eTrkEff) ? sta1->Pt()  : lep1->Pt();
      data.eta	   = (effType==eTrkEff) ? sta1->Eta() : lep1->Eta();
      data.phi	   = (effType==eTrkEff) ? sta1->Phi() : lep1->Phi();
      data.weight  = doWeighted ? scale1fb : 1;
      data.q	   = q1;
      data.npv	   = npv;
      data.npu	   = npu;
      data.pass	   = 1;
      data.runNum  = runNum;
      data.lumiSec = lumiSec;
      data.evtNum  = evtNum;
      outTree->Fill();
    } 
  }  
  delete infile;
  infile=0, intree=0;	   


  //--------------------------------------------------------------------------------------------------------------
  // Output
  //==============================================================================================================
   
  cout << "*" << endl;
  cout << "* SUMMARY" << endl;
  cout << "*--------------------------------------------------" << endl;
  cout << endl;

  cout << " Number of probes selected: " << nProbes << endl;
  
  outFile->Write();
  outFile->Close();
  delete outFile;
  
  cout << endl;
  cout << "  <> Output saved in " << outputDir << "/" << endl;    
  cout << endl;  
      
  gBenchmark->Show("selectProbesMuEff"); 
}
Example #14
0
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();
  
}
Example #15
0
void looper::ScanChain (TChain* chain, const char* prefix, bool isData, int nEvents){

  bookHistos();

  set_goodrun_file("Cert_TopAug13_Merged_135059-142664_goodruns.txt");
  ofile.open( Form( "output/%s_%s_events.txt" , prefix , iter ) );

  TObjArray *listOfFiles = chain->GetListOfFiles();

  unsigned int nEventsChain = 0;
  if(nEvents == -1) 
    nEvents = chain->GetEntries();
  nEventsChain = nEvents;
  unsigned int nEventsTotal = 0;

  MakeBabyNtuple( Form( "output/%s_%s_baby.root" , prefix , iter) );

  DorkyEventIdentifier dei;

  //pass fail counters
  int nPassDuplicate  = 0;
  int nPassGoodRun    = 0;

  float nGoodMu = 0;
  float nGoodEl = 0;

  if( debug ) cout << "Begin looping over files" << endl;

  if( isData ){
    cout << "|" << setw(8)  << "run"          << setw(4) 
         << "|" << setw(6)  << "lumi"         << setw(4) 
         << "|" << setw(12) << "event"        << setw(4) 
         << "|" << setw(6)  << "type"         << setw(4) 
         << "|" << setw(6)  << "njets"        << setw(4) 
         << "|" << setw(6)  << "nbtags"       << setw(4) 
         << "|" << setw(8)  << "tcmet"        << setw(4) 
         << "|" << setw(8)  << "cltcmet"      << setw(4) 
         << "|" << setw(8)  << "pftcmet"      << setw(4) 
         << "|" << setw(8)  << "pfmet"        << setw(4) 
         << "|" << setw(8)  << "dphi"         << setw(4) << "|" << endl; 
  }

  // file loop
  TIter fileIter(listOfFiles);
  TFile* currentFile = 0;
  while ((currentFile = (TFile*)fileIter.Next()))
    {
      TFile f(currentFile->GetTitle());
      TTree *tree = (TTree*)f.Get("Events");
      cms2.Init(tree);

      // event loop
      unsigned int nEvents = tree->GetEntries();

      for (unsigned int event = 0; event < nEvents; ++event)
        {
          if( debug ) cout << "Event " << event << endl;

          cms2.GetEntry(event);
          ++nEventsTotal;

          // progress feedback to user
          if (nEventsTotal % 1000 == 0)
            {
              // xterm magic from L. Vacavant and A. Cerri
              if (isatty(1))
                {
                  printf("\015\033[32m ---> \033[1m\033[31m%4.1f%%"
                         "\033[0m\033[32m <---\033[0m\015", (float)nEventsTotal/(nEventsChain*0.01));
                  fflush(stdout);
                }
            }
	  

          //APPLY BASIC EVENT SELECTIONS
          //TRIGGER, TRACKING AND VERTEX
          if( dei.is_duplicate( DorkyEvent() ) ) continue;
          nPassDuplicate++;

          if (!isData || goodrun(cms2.evt_run(), cms2.evt_lumiBlock()))
            nPassGoodRun++;
	  else continue;
        
          float weight = 1.;
          if     ( strcmp(prefix,"data") == 0  ) weight = 1;
          else if( strcmp(prefix,"ZJets") == 0 ) weight = 1.27 * 2.2121427 * 0.84e-3;
          else if( strcmp(prefix,"TTBar") == 0 ) weight = 0.1112306 * 0.84e-3;
          else if( strcmp(prefix,"Vqq") == 0   ) weight = 0.0408562 * 0.84e-3;
          else{
            cout << "I DON'T RECOGNIZE " << prefix << endl;
            exit(0);
          }

          for( unsigned int hypIdx = 0 ; hypIdx < hyp_type().size() ; hypIdx++ ){
      
            InitBabyNtuple();
            
            int myType = 99;
            if (hyp_type()[hypIdx] == 3) myType = 0;                          // ee
            if (hyp_type()[hypIdx] == 0) myType = 1;                          // mm
            if (hyp_type()[hypIdx] == 1 || hyp_type()[hypIdx] == 2) myType=2; // em
            if (myType == 99) {
              cout << "Skipping unknown dilepton type = " << hyp_type()[hypIdx] << endl;
              continue;
            }

            //----------SELECTION----------------------------------------------------

            //pT > (20,20) GeV
            if( hyp_ll_p4()[hypIdx].pt() < 20 ) continue;
            if( hyp_lt_p4()[hypIdx].pt() < 20 ) continue;
 
            //ttbar muon ID
            if (abs(hyp_ll_id()[hypIdx]) == 13  && (! (fabs(hyp_ll_p4()[hypIdx].eta()) < 2.4 && muonId(hyp_ll_index()[hypIdx],NominalTTbar))))   continue;
            if (abs(hyp_lt_id()[hypIdx]) == 13  && (! (fabs(hyp_lt_p4()[hypIdx].eta()) < 2.4 && muonId(hyp_lt_index()[hypIdx],NominalTTbar))))   continue;
         
            //ttbarV1 electron ID
            if (abs(hyp_ll_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_ll_index()[hypIdx] , electronSelection_ttbarV1 , isData ))) continue;
            if (abs(hyp_lt_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_lt_index()[hypIdx] , electronSelection_ttbarV1 , isData ))) continue;

            //ttbar electron ID
            //if (abs(hyp_ll_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_ll_index()[hypIdx] , electronSelection_ttbar , isData ))) continue;
            //if (abs(hyp_lt_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_lt_index()[hypIdx] , electronSelection_ttbar , isData ))) continue;

            //nominal muon ID
            //if (abs(hyp_ll_id()[hypIdx]) == 13  && (! (fabs(hyp_ll_p4()[hypIdx].eta()) < 2.4 && muonId(hyp_ll_index()[hypIdx]))))   continue;
            //if (abs(hyp_lt_id()[hypIdx]) == 13  && (! (fabs(hyp_lt_p4()[hypIdx].eta()) < 2.4 && muonId(hyp_lt_index()[hypIdx]))))   continue;
         
            //ttbar electron ID
            //if (abs(hyp_ll_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_ll_index()[hypIdx] , electronSelection_cand01 ))) continue;
            //if (abs(hyp_lt_id()[hypIdx]) == 11  && (! pass_electronSelection( hyp_lt_index()[hypIdx] , electronSelection_cand01 ))) continue;

            //same flavor
            if( hyp_type()[hypIdx] == 1 ) continue;
            if( hyp_type()[hypIdx] == 2 ) continue;
            
            //opposite sign
            if( hyp_lt_id()[hypIdx] *  hyp_ll_id()[hypIdx] > 0 ) continue;

            //fill dilmass histo before cutting on dilmass
            dilMass_ = hyp_p4()[hypIdx].mass();
            fillHistos( hdilMass          , dilMass_  , weight , myType );

            if( dilMass_ < 76. || dilMass_ > 106. ) continue;

            if( myType == 0 ) nGoodEl+=weight;
            if( myType == 1 ) nGoodMu+=weight;

            //----------CORRECT TCMET FOR HYP MUONS---------------------------------------------

            metStruct tcmetStruct = correctTCMETforHypMuons( hypIdx , 
                                                             evt_tcmet() * cos( evt_tcmetPhi() ), 
                                                             evt_tcmet() * sin( evt_tcmetPhi() ),
                                                             evt_tcsumet() );
              
 

            // out-of-the-box  tcmet stuff (corrected for hyp muons)
            tcmet_    = tcmetStruct.met;
            tcmetphi_ = tcmetStruct.metphi;
            tcsumet_  = tcmetStruct.sumet;

            if( isData ){
              
              metStruct tcmetStructNewCalo = correctTCMETforHypMuons( hypIdx , 
                                                                      evtNew_tcmet() * cos( evtNew_tcmetPhi() ), 
                                                                      evtNew_tcmet() * sin( evtNew_tcmetPhi() ),
                                                                      evtNew_tcsumet() );
              tcmetNew_calo_ = tcmetStructNewCalo.met;

              metStruct tcmetStructNewPFC = correctTCMETforHypMuons( hypIdx , 
                                                                     evtNewPFC_tcmet() * cos( evtNewPFC_tcmetPhi() ), 
                                                                     evtNewPFC_tcmet() * sin( evtNewPFC_tcmetPhi() ),
                                                                     evtNewPFC_tcsumet() );
              tcmetNew_pfc_ = tcmetStructNewPFC.met;

            }else{
              tcmetNew_calo_ = tcmet_;
              tcmetNew_pfc_  = tcmet_;
            }


            //---------JET STUFF--------------------------------------------------------------

            int nJets        = 0;
            float sumJetPt   = 0;
            int nBTags       = 0;
            float maxcosdphi = -99;
            int imax         = -1;
            
            for (unsigned int ijet = 0; ijet < pfjets_p4().size(); ijet++) {

              LorentzVector vjet = pfjets_p4().at(ijet);
              LorentzVector vlt  = hyp_lt_p4()[hypIdx];
              LorentzVector vll  = hyp_ll_p4()[hypIdx];
              if (dRbetweenVectors(vjet, vll) < 0.4) continue;
              if (dRbetweenVectors(vjet, vlt) < 0.4) continue;
              
              if ( vjet.pt() > 30. && fabs(vjet.eta()) < 2.5 ) {
                nJets++;
                sumJetPt+=vjet.pt();
                fillHistos( hjetpt , vjet.pt() , weight , myType );

                float dRmin = 100;
                int imin = -1;
                
                if( fabs( cos( tcmetphi_ - vjet.phi() ) ) > maxcosdphi ){
                  maxcosdphi = fabs( cos( tcmetphi_ - vjet.phi() ) );
                  imax = ijet;
                  dphijetmet_ = fabs( tcmetphi_ - vjet.phi() );
                  if( dphijetmet_ > TMath::Pi() ) dphijetmet_ = TMath::TwoPi() - dphijetmet_;
                }

                //find closest calojet to use btagging info
                for( unsigned int icalojet = 0 ; icalojet < jets_p4().size() ; icalojet++ ){

                  LorentzVector vcalojet = jets_p4().at(icalojet);
                  if( vcalojet.pt() * jets_cor().at(icalojet) < 10 ) continue;
                  
                  float dR = dRbetweenVectors(vjet, vcalojet);
                  if( dR < dRmin ){
                    dRmin = dR;
                    imin = icalojet;
                  }
                }

                if( imin > -1 ){
                  if( jets_simpleSecondaryVertexHighEffBJetTag().at(imin) > 1.74 ) nBTags++;
                  //if( jets_trackCountingHighEffBJetTag().at(imin) > 1.7 ) nBTags++;
                }

              }
            }

          
            
      

            // event stuff
            run_    = cms2.evt_run();
            lumi_   = cms2.evt_lumiBlock();
            event_  = cms2.evt_event();

            // pf met stuff
            pfmet_    = cms2.evt_pfmet();
            pfmetphi_ = cms2.evt_pfmetPhi();
            pfsumet_  = cms2.evt_pfsumet();

            //calomet
            met_       = cms2.evt_met();
            metphi_    = cms2.evt_metPhi();
            sumet_     = cms2.evt_sumet();
     
            //electron eta
            if( myType == 0 ){
              if( tcmet_ < 20 ){
                fillUnderOverFlow( heleta_metlt20 , hyp_lt_p4()[hypIdx].eta() , weight );
                fillUnderOverFlow( heleta_metlt20 , hyp_ll_p4()[hypIdx].eta() , weight );
              }
              else if( tcmet_ > 30 ){
                fillUnderOverFlow( heleta_metgt30 , hyp_lt_p4()[hypIdx].eta() , weight );
                fillUnderOverFlow( heleta_metgt30 , hyp_ll_p4()[hypIdx].eta() , weight );
              }
            }

            //muon eta
            if( myType == 1 ){
              if( tcmet_ < 20 ){
                fillUnderOverFlow( hmueta_metlt20 , hyp_lt_p4()[hypIdx].eta() , weight );
                fillUnderOverFlow( hmueta_metlt20 , hyp_ll_p4()[hypIdx].eta() , weight );
              }
              else if( tcmet_ > 30 ){
                fillUnderOverFlow( hmueta_metgt30 , hyp_lt_p4()[hypIdx].eta() , weight );
                fillUnderOverFlow( hmueta_metgt30 , hyp_ll_p4()[hypIdx].eta() , weight );
              }
            }

            //look at track pT's near electron
            if( myType == 0 && tcmet_ > 30 ){
              for( unsigned int itrk = 0 ; itrk < trks_trk_p4().size() ; ++itrk ){
               
                if( isMuon( itrk ) )            continue;
                if( isElectron( itrk ) )        continue;
                if( !isGoodTrack( itrk ) )      continue;
             
                LorentzVector vtrk = trks_trk_p4().at(itrk);
                LorentzVector vlt  = hyp_lt_p4()[hypIdx];
                LorentzVector vll  = hyp_ll_p4()[hypIdx];

                float drll = dRbetweenVectors(vtrk, vll);
                float drlt = dRbetweenVectors(vtrk, vlt);

                if( drll < 0.3 || drlt < 0.3 ){
                  fillUnderOverFlow( htrkptnearel , trks_trk_p4().at(itrk).pt() , weight );
                  //printEvent();
                  //cout << "pt eta phi " << vtrk.pt() << " " << vtrk.eta() << " " << vtrk.phi() << endl;
                }
              }
            }

            string leptype[2]={"ee","mm"};

            if( isData && ( tcmet_ > 30. || pfmet_ > 30. ) ){

              if( calculateTCMET ){
                
                // calculate tcmet on-the-fly
                metStruct structMET = correctedTCMET( true, ofile );
                
              }

              cout << "|" << setw(8)  << evt_run()                   << setw(4) 
                   << "|" << setw(6)  << evt_lumiBlock()             << setw(4) 
                   << "|" << setw(12) << evt_event()                 << setw(4) 
                   << "|" << setw(6)  << leptype[myType]             << setw(4) 
                   << "|" << setw(6)  << nJets                       << setw(4) 
                   << "|" << setw(6)  << nBTags                      << setw(4) 
                   << "|" << setw(8)  << fround(tcmet_,1)            << setw(4) 
                   << "|" << setw(8)  << fround(tcmetNew_calo_,1)    << setw(4) 
                   << "|" << setw(8)  << fround(tcmetNew_pfc_,1)     << setw(4) 
                   << "|" << setw(8)  << fround(pfmet_,1)            << setw(4) 
                   << "|" << setw(8)  << fround(dphijetmet_,2)       << setw(4) << "|" << endl; 
            }

            if( imax > -1 ){

              if( tcmet_ < 20 )
                fillHistos( hdphijetmet_metlt20  , dphijetmet_    , weight , myType , nJets  );

              if( tcmet_ > 30 )
                fillHistos( hdphijetmet_metgt30  , dphijetmet_    , weight , myType , nJets  );

            }

            fillHistos( hnjets            , nJets            , weight , myType );
            fillHistos( htcmet            , tcmet_           , weight , myType , nJets );
            fillHistos( htcmetNew_calo    , tcmetNew_calo_   , weight , myType , nJets  );
            fillHistos( htcmetNew_pfc     , tcmetNew_pfc_    , weight , myType , nJets  );
            fillHistos( hpfmet            , pfmet_           , weight , myType , nJets  );
            
            njets_   = nJets;
            leptype_ = myType;

            eventTree_->Fill();
          }// end loop over hypotheses
        } // end loop over events
    } // end loop over files
  
  cout << "\n\n********************SUMMARY********************" << endl;
  cout << "Total number of events: " << nEventsTotal << endl;
  cout << "Total number of events that pass dup veto: " << nPassDuplicate 
       << " (" << 100*(double)nPassDuplicate/nEventsTotal << "% of total)" << endl;
  cout << "Total number of events that pass good run/lumi: " << nPassGoodRun 
       << " (" << 100*(double)nPassGoodRun/nEventsTotal << "% of total)" << endl;

  cout << nGoodEl << " ee events in Z mass window" << endl;
  cout << nGoodMu << " mm events in Z mass window" << endl;

  if (nEventsChain != nEventsTotal)
    std::cout << "ERROR: number of events from files is not equal to total number of events" << std::endl;

  CloseBabyNtuple();

  TDirectory *rootdir = gDirectory->GetDirectory("Rint:");
  rootdir->cd();
  saveHist( Form( "output/%s_%s_histos.root" , prefix , iter ) );
  deleteHistos();

  
} // end ScanChain
Example #16
0
void looper::ScanChain (TChain* chain, const char* prefix, bool isData, bool calculateTCMET, metAlgo algo, int nEvents, float kFactor){

  algo_ = algo;

  if( algo_ == e_makeTemplate )    cout << "metAlgo makeTemplate" << endl;
  if( algo_ == e_photonSelection ) cout << "metAlgo photonSelection" << endl;
  if( algo_ == e_ZSelection )      cout << "metAlgo ZSelection" << endl;

  TFile *metTemplateFile;
  string metTemplateString = "";
  
  DorkyEventIdentifier dei;

  //select templates
  if( algo_ != e_makeTemplate){
    if( isData ){
      metTemplateString = "_dataTemplate";
      metTemplateFile = TFile::Open("root/JetMETTau_250nb.root");
    }else{
      metTemplateString = "_mcTemplate";
      metTemplateFile = TFile::Open("root/QCD_Pt15_1p9pb.root");
    }
  }

  //set_goodrun_file("Cert_TopAug13_Merged_135059-142664_goodruns.txt");
  //set_goodrun_file("Cert_TopAug25_Merged_135059-143336_goodruns.txt");
  //set_goodrun_file("Cert_TopAug26_Merged_135059-143835_recover_noESDCS_goodruns.txt");
  set_goodrun_file("Cert_TopAug30_Merged_135059-144114_recover_noESDCS_goodruns.txt");

  bookHistos();

  // make a baby ntuple
  stringstream babyfilename;
  babyfilename << prefix << "_baby.root";
  MakeBabyNtuple( Form("root/%s_%s_baby.root", prefix , iter ) );

  TObjArray *listOfFiles = chain->GetListOfFiles();

  unsigned int nEventsChain = 0;
  if(nEvents == -1) 
    nEvents = chain->GetEntries();
  nEventsChain = nEvents;
  unsigned int nEventsTotal = 0;
  
  //pass fail counters
  int nPassGoodRun    = 0;
  int nPassBPTX       = 0;
  int nPassBSC        = 0;
  int nPassBeamHalo   = 0;
  int nPassGoodTracks = 0;
  int nPassGoodVertex = 0;
  int nSkip_els_conv_dist = 0;
  if(debug) cout << "Begin file loop" << endl;

  // file loop
  TIter fileIter(listOfFiles);
  TFile* currentFile = 0;
  while ((currentFile = (TFile*)fileIter.Next())){
    
    TFile f(currentFile->GetTitle());
    TTree *tree = (TTree*)f.Get("Events");
    cms2.Init(tree);

    // event loop
    unsigned int nEvents = tree->GetEntries();
 
    for (unsigned int event = 0 ; event < nEvents; ++event){
      
      cout << endl << "-------------------------------------------------------------" << endl;
        
      cms2.GetEntry(event);
      ++nEventsTotal;

      cout << "Event " << event << " nhyp " << hyp_type().size() << endl;

      // progress feedback to user
      if (nEventsTotal % 1000 == 0){
            
        // xterm magic from L. Vacavant and A. Cerri
        if (isatty(1)){
                
          printf("\015\033[32m ---> \033[1m\033[31m%4.1f%%"
                 "\033[0m\033[32m <---\033[0m\015", (float)nEventsTotal/(nEventsChain*0.01));
          fflush(stdout);
        }
      }

      //duplicate event veto CHECK THIS
      bool myduplicate = dei.is_duplicate(DorkyEvent());
      if(myduplicate) continue;
      
      //skip events with bad els_conv_dist 
      bool skipEvent = false;
      for( unsigned int iEl = 0 ; iEl < els_conv_dist().size() ; ++iEl ){
        if( els_conv_dist().at(iEl) != els_conv_dist().at(iEl) ){
          skipEvent = true;
        }
      }
      
      if( skipEvent ){
        cout << "SKIPPING EVENT WITH BAD ELS_CONV_DIST" << endl;       
        nSkip_els_conv_dist++;
        continue;
      }

      //basic event selection----------------------------------------------------------------

      if (!isData || goodrun(cms2.evt_run(), cms2.evt_lumiBlock()))
        nPassGoodRun++;
      else continue;
          
      // determine if current event passes BPTX triggers
      if (cleaning_BPTX( isData ))
        nPassBPTX++;
      else continue;

      // determine if current event passes BSC triggers
      if (cleaning_BSC())
        nPassBSC++;
      else continue;

      // determine if current event passes beam halo triggers
      if (cleaning_beamHalo())
        nPassBeamHalo++;
      else continue;

      // determine if current event is a beam scraping event
      if (cleaning_goodTracks())
        nPassGoodTracks++;
      else continue;

      // determine if current event has a good vertex
      if (cleaning_goodVertexAugust2010())
        nPassGoodVertex++;
      else continue;
      
      if ( !cleaning_standard( isData ) ) continue;
      
      if(debug) cout << "Pass event selection" << endl;

      cout << "Pass event cleaning" << endl;
      InitBabyNtuple();

      // event stuff
      run_    = cms2.evt_run();
      lumi_   = cms2.evt_lumiBlock();
      event_  = cms2.evt_event();

      weight_ = 1.;
      pthat_  = -1;
      if( !isData ){
        weight_ = cms2.evt_scale1fb() * kFactor * lumi;
        pthat_  = cms2.genps_pthat();
      }

      /*
      //cout << "pthat " << endl;
      //cout << cms2.genps_pthat() << endl;

      float maxphotonpt = -1;
     
      //stitching together PhotonJet_Pt15 and PhotonJet_Pt30
      if( strcmp( prefix , "PhotonJet") == 0 ){
       
        //cout << "Stitching, file " << currentFile->GetTitle() << endl;
        
        if( TString(currentFile->GetTitle()).Contains("PhotonJet_Pt15") ){
          //cout << "Pt15" << endl;
          //weight_ *= 1.245;
          if( cms2.genps_pthat() > 30. ) continue;
        }   
        for( unsigned int ig = 0 ; ig < photons_p4().size() ; ++ig ){
          if( photons_p4().at(ig).pt() > maxphotonpt ) 
            maxphotonpt = photons_p4().at(ig).pt();
        }
      }
 
      fillUnderOverFlow( hgenps_pthat  , genps_pthat() , weight_ );
      fillUnderOverFlow( hphotonpt     , maxphotonpt   , weight_ );
      */


      //access HLT triggers------------------------------------------------------------------

      for( unsigned int itrig = 0 ; itrig < hlt_trigNames().size() ; ++itrig ){

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_L1Jet6U" ) == 0 ){
          if( passHLTTrigger("HLT_L1Jet6U") )                  HLT_L1Jet6U_ = 1;
          else                                                 HLT_L1Jet6U_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_L1Jet10U" ) == 0 ){
          if( passHLTTrigger("HLT_L1Jet10U") )                 HLT_L1Jet10U_ = 1;
          else                                                 HLT_L1Jet10U_ = 0;
        }
        
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Jet15U" ) == 0 ){
          if( passHLTTrigger("HLT_Jet15U") )                   HLT_Jet15U_ = 1;
          else                                                 HLT_Jet15U_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Jet30U" ) == 0 ){
          if( passHLTTrigger("HLT_Jet30U") )                   HLT_Jet30U_ = 1;
          else                                                 HLT_Jet30U_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "L1_SingleEG5" ) == 0 ){
          if( passHLTTrigger("L1_SingleEG5") )                 L1_SingleEG5_ = 1;
          else                                                 L1_SingleEG5_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon10_L1R" ) == 0 ){
          if( passHLTTrigger("HLT_Photon10_L1R") )             HLT_Photon10_L1R_ = 1;
          else                                                 HLT_Photon10_L1R_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon15_L1R" ) == 0 ){
          if( passHLTTrigger("HLT_Photon15_L1R") )             HLT_Photon15_L1R_ = 1;
          else                                                 HLT_Photon15_L1R_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon10_Cleaned_L1R" ) == 0 ){
          if( passHLTTrigger("HLT_Photon10_Cleaned_L1R") )     HLT_Photon10_Cleaned_L1R_ = 1;
          else                                                 HLT_Photon10_Cleaned_L1R_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon15_Cleaned_L1R" ) == 0 ){
          if( passHLTTrigger("HLT_Photon15_Cleaned_L1R") )     HLT_Photon15_Cleaned_L1R_ = 1;
          else                                                 HLT_Photon15_Cleaned_L1R_ = 0;
        }

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon20_Cleaned_L1R" ) == 0 ){
          if( passHLTTrigger("HLT_Photon20_Cleaned_L1R") )     HLT_Photon20_Cleaned_L1R_ = 1;
          else                                                 HLT_Photon20_Cleaned_L1R_ = 0;
        }
      }      
      //met quantities--------------------------------------------------------------------------
      
      //calomet
      met_       = cms2.evt_met();
      metphi_    = cms2.evt_metPhi();
      sumet_     = cms2.evt_sumet();

      // pf met stuff
      pfmet_    = cms2.evt_pfmet();
      pfmetphi_ = cms2.evt_pfmetPhi();
      pfsumet_  = cms2.evt_pfsumet();

      //muon-corrected met stuff
      mumet_    = cms2.evt_metMuonCorr();
      mumetphi_ = cms2.evt_metMuonCorrPhi();
      musumet_  = cms2.evt_sumetMuonCorr();

      //muon-corrected JES met stuff
      mujesmet_    = cms2.evt_metMuonJESCorr();
      mujesmetphi_ = cms2.evt_metMuonJESCorrPhi();
      mujessumet_  = -9999.; //cms2.evt_sumetMuonJESCorr(); //branch doesn't exist!!!

      // genmet stuff
      if (!isData){
//         genmet_     = cms2.gen_met();
//         genmetphi_  = cms2.gen_metPhi();
//         gensumet_   = cms2.gen_sumEt();
      }

      //looper-level tcmet
      if( calculateTCMET ){
        metStruct tcmetNewStruct = correctedTCMET();
        tcmetNew_     = tcmetNewStruct.met;
        tcmetphiNew_  = tcmetNewStruct.metphi;
        tcsumetNew_   = tcmetNewStruct.sumet;
      }

      //just take tcmet from event
      tcmet_     = evt_tcmet();
      tcmetphi_  = evt_tcmetPhi();
      tcsumet_   = evt_tcsumet();

      //photon quantities-----------------------------------------------------------------------

      if(debug) cout << "Get photon quantities" << endl;

      if(debug) cout << "run lumi event " << evt_run() << " " << evt_lumiBlock() << " " << evt_event() << endl;
      
      nPhotons_         =  0;
      float maxPhotonPt = -1;
      int igmax         = -1;

      if( photons_p4().size() == 0 && algo_ == e_photonSelection ) continue;
      
      //count photons pt > 10 GeV
      for (unsigned int iphoton = 0 ; iphoton < photons_p4().size() ; iphoton++) {

        LorentzVector vphoton = photons_p4().at(iphoton);

        if(vphoton.pt() > 10){
          nPhotons_++;
          if(vphoton.pt() > maxPhotonPt){
            maxPhotonPt  = vphoton.pt();
            igmax        = iphoton;
          }
        }
      }

      //if( igmax < 0 && algo_ == e_photonSelection ) continue;

      if( igmax > -1 ){
        etg_   = photons_p4()[igmax].pt();
        etag_  = photons_p4()[igmax].eta();
        phig_  = photons_p4()[igmax].phi();
        hoe_   = photons_hOverE()[igmax];
        //eciso_ = photons_ecalIso()[igmax];
        //hciso_ = photons_hcalIso()[igmax];
        //tkiso_ = photons_tkIsoSolid()[igmax];

        /*
        photon_pixelseed_        = photons_haspixelSeed()[igmax] ? 1 : 0;
	photon_e15_              = photons_e1x5()[igmax];      
	photon_e25max_           = photons_e2x5Max()[igmax];      
	photon_e33_              = photons_e3x3()[igmax];           
	photon_e55_              = photons_e5x5()[igmax];           
	photon_ecalIso03_        = photons_ecalIso03()[igmax];      
	photon_ecalIso04_        = photons_ecalIso04()[igmax];      
	photon_hcalIso03_        = photons_hcalIso03()[igmax];      
	photon_hcalIso04_        = photons_hcalIso04()[igmax];      
	photon_ntkIsoHollow03_   = photons_ntkIsoHollow03()[igmax];
        photon_ntkIsoHollow04_   = photons_ntkIsoHollow04()[igmax];
	photon_ntkIsoSolid03_    = photons_ntkIsoSolid03()[igmax]; 
	photon_ntkIsoSolid04_    = photons_ntkIsoSolid04()[igmax]; 
	photon_sigmaEtaEta_      = photons_sigmaEtaEta()[igmax];    
	photon_sigmaIEtaIEta_    = photons_sigmaIEtaIEta()[igmax];
	photon_tkisoHollow03_    = photons_tkIsoHollow03()[igmax];
	photon_tkisoHollow04_    = photons_tkIsoHollow04()[igmax]; 
	photon_tkisoSolid03_     = photons_tkIsoSolid03()[igmax];   
	photon_tkisoSolid04_     = photons_tkIsoSolid04()[igmax];  
        */

        swiss_      = photons_swissSeed()[igmax];
        int scind   = photons_scindex()[igmax] ;
        seed_       = scs_eSeed()[scind] ;
        s4_         = swiss_ - seed_ ;
        r4_         = 1 - s4_ / seed_ ;
        
        drel_ = 1000;

        for( unsigned int iel = 0 ; iel < els_p4().size() ; iel++ ){
        
          if( els_p4().at(iel).pt() < 5 ) continue;

          float deta = etag_ - trks_trk_p4().at(iel).eta();
          float dphi = fabs( phig_ - trks_trk_p4().at(iel).phi() );
          if( dphi > TMath::Pi() ) dphi = TMath::TwoPi() - dphi;
          float dr = sqrt( deta * deta + dphi * dphi );
          if( dr < drel_ ) drel_ = dr;

        }
      }
      
      //photon-matched jet quantities---------------------------------------------------------------

      if(debug) cout << "Get jet quantities" << endl;

      jet_dr_      = 10000;
      int   ijetg  = -1;

      //find jet corresponding to photon
      for (unsigned int ijet = 0 ; ijet < pfjets_p4().size() ; ijet++) {

        float etajet = pfjets_p4().at(ijet).eta();
        
        if( etajet > 3 ) continue;
        
        float phijet = pfjets_p4().at(ijet).phi();
        float deta   = etajet - etag_;
        float dphi   = phijet - phig_;
        if( dphi > TMath::Pi() ) dphi = TMath::TwoPi() - dphi;
        
        float deltaR = sqrt( deta*deta + dphi*dphi );

        if( deltaR < jet_dr_ ){
          jet_dr_ = deltaR;
          ijetg   = ijet;
        }
      }

    
      if( ijetg < 0 && algo_ == e_photonSelection ) continue;

      if( ijetg > -1 ){
      
        jet_pt_             = pfjets_p4().at(ijetg).pt();
        jet_energy_         = pfjets_p4().at(ijetg).energy();
        jet_eta_            = pfjets_p4().at(ijetg).eta();

        //energy component fractions (add protection for index out of range)
        jet_chg_emfrac_     = pfjets_chargedEmE().at(ijetg)     / jet_energy_;
        jet_chg_hadfrac_    = pfjets_chargedHadronE().at(ijetg) / jet_energy_;
        jet_neu_emfrac_     = pfjets_neutralEmE().at(ijetg)     / jet_energy_;
        jet_neu_hadfrac_    = pfjets_neutralHadronE().at(ijetg) / jet_energy_;
        
        //multiplicities
        jet_nchg_           = pfjets_chargedMultiplicity().at(ijetg);
        jet_nmuon_          = pfjets_muonMultiplicity().at(ijetg);
        jet_nneu_           = pfjets_neutralMultiplicity().at(ijetg);
        
        //deltaPhi( jet - met )
        jet_dphimet_          = deltaPhi( pfjets_p4().at(ijetg).phi() , tcmetphi_);
      
//         if(!isData){
          
//           //deltaR match to genjet
//           int iMin    = -1;
//           float dRmin = -1;
          
//           for (unsigned int igenjet = 0 ; igenjet < genjets_p4().size() ; igenjet++ ){
            
//             LorentzVector vgenjet = genjets_p4().at(igenjet);
            
//             float dR = dRbetweenVectors(pfjets_p4().at(ijetg), vgenjet);
            
//             if(dR < dRmin){
//               iMin = igenjet;
//               dRmin = dR;
//             }
//           }
          
//           if(iMin > -1){
//             jet_dpt_   = jet_pt_ - genjets_p4().at(iMin).pt();
//             jet_drgen_ = dRmin;
//           }
//         }
      }

      //find leading jet------------------------------------------------------------------------

      int imaxjet = -1;
      float maxpt = -1;

      for (unsigned int ijet = 0 ; ijet < pfjets_p4().size() ; ijet++) {

        if( fabs( pfjets_p4().at(ijet).eta() ) > 5.) continue;
        
        if( pfjets_p4().at(ijet).pt() > maxpt ){
          maxpt = pfjets_p4().at(ijet).pt();
          imaxjet = ijet;
        }

      }
      
      if( imaxjet > -1 ){
        jetmax_pt_       = pfjets_p4().at(imaxjet).pt();
        jetmax_dphimet_  = deltaPhi( pfjets_p4().at(imaxjet).phi() , tcmetphi_);
      }
      
      //loop over pfjets, find nJets and sumJetPt-----------------------------------------------

      if(debug) cout << "Get nJets and sumJetPt" << endl;

      nJets_        = 0;
      sumJetPt_     = 0.;
      nJets40_      = 0;
      sumJetPt10_   = 0.;

      LorentzVector jetSystem(0.,0.,0.,0.);

      for (unsigned int ijet = 0 ; ijet < pfjets_p4().size() ; ijet++) {

        LorentzVector vjet = pfjets_p4().at(ijet);
        
        bool skipJet = false;

        //skip jet matched to photon
        if( (int)ijet == ijetg && algo_ == e_photonSelection ){
          skipJet = true;
        }
       
        //skip all hyp leptons
        if( algo_ == e_ZSelection ) { 

          for( unsigned int hypIdx = 0 ; hypIdx < hyp_p4().size() ; hypIdx++ ) {
         
            LorentzVector vlt  = hyp_lt_p4()[hypIdx];
            LorentzVector vll  = hyp_ll_p4()[hypIdx];
            
            if (dRbetweenVectors(vjet, vll) < 0.4) skipJet = true;
            if (dRbetweenVectors(vjet, vlt) < 0.4) skipJet = true;
         
          }
        }
  
        if( skipJet ) continue;

        if( fabs( vjet.eta() ) < 5.){
          
          if ( vjet.pt() > 30. ){
            nJets_++;
          }        
          if ( vjet.pt() > 15. ){
            sumJetPt_ += vjet.pt();
            jetSystem += vjet;
          }
          
          if ( vjet.pt() > 40. ){
            nJets40_++;
          }
          if ( vjet.pt() > 10. ){
            sumJetPt10_ += vjet.pt();
          }
        }
      }

      vecJetPt_ = jetSystem.pt();

      cout << "Check Z selection" << endl;

      if( algo_ == e_ZSelection ){
        
        cout << "hyp_p4 size " << hyp_p4().size() << endl;
        if( hyp_p4().size() != 1 ) continue;       
      
        passz_ = passZSelection() ? 1 : 0;
      
        pdgid_ = 0;
      
        unsigned int i_lt = cms2.hyp_lt_index()[0];
        unsigned int i_ll = cms2.hyp_ll_index()[0];

        if( hyp_type()[0] == 0 ){
          pdgid_ = 13; 
          passm_nom_          = passMuon_Nominal()        ? 1 : 0;
          passm_nomttbar_     = passMuon_NominalTTbar()   ? 1 : 0;
          passm_nomttbarV2_   = passMuon_NominalTTbarV2() ? 1 : 0;
          flagll_             = mus_tcmet_flag().at(i_ll);
          flaglt_             = mus_tcmet_flag().at(i_lt);
        }
        if( hyp_type()[0] == 3 ){
          pdgid_ = 11;
          passe_ttbarV1_    = passElectron_ttbarV1( isData)  ? 1 : 0;
          passe_ttbar_      = passElectron_ttbar( isData)    ? 1 : 0;
          passe_cand01_     = passElectron_cand01()          ? 1 : 0;

        }

        ptll_             = hyp_ll_p4()[0].pt();
        ptlt_             = hyp_lt_p4()[0].pt();
        etall_            = hyp_ll_p4()[0].eta();
        etalt_            = hyp_lt_p4()[0].eta();
        dilmass_          = hyp_p4()[0].mass(); 
        dilpt_            = hyp_p4()[0].pt(); 

        metStruct tcmetStruct = correctTCMETforHypMuons( 0 ,  
                                                         evt_tcmet() * cos( evt_tcmetPhi() ), 
                                                         evt_tcmet() * sin( evt_tcmetPhi() ), 
                                                         evt_tcsumet() );
        
        // out-of-the-box  tcmet stuff (corrected for hyp muons)
        tcmet_    = tcmetStruct.met;
        tcmetphi_ = tcmetStruct.metphi;
        tcsumet_  = tcmetStruct.sumet;   

        metStruct tcmetNewStruct = correctTCMETforHypMuons( 0 ,  
                                                            tcmetNew_ * cos( tcmetphiNew_ ), 
                                                            tcmetNew_ * sin( tcmetphiNew_ ), 
                                                            tcsumetNew_ );
            
        // looper-level  tcmet stuff (corrected for hyp muons)
        tcmetNew_    = tcmetNewStruct.met;
        tcmetphiNew_ = tcmetNewStruct.metphi;
        tcsumetNew_  = tcmetNewStruct.sumet;   

      }

      nGoodVertex_ = 0;
      for (size_t v = 0; v < cms2.vtxs_position().size(); ++v){
        if(isGoodVertex(v)) nGoodVertex_++;
      }
      
      cout << "Check jets" << endl;
      //fill baby ntuple
      if ( nJets_ < 1 )     continue;
      if( jetmax_pt_ < 30 ) continue;

      cout << "Pass jet selection" << endl;
      FillBabyNtuple();

      //require at least 2 jets
      if ( nJets_ < 2 )     continue;

      //require leading jet pt > 50
      if( jetmax_pt_ < 50 ) continue;

      dphixmet_  = deltaPhi( tcmetphi_ , jetSystem.phi() );
      metPar_    = tcmet_ * cos( dphixmet_ );
      metPerp_   = tcmet_ * sin( dphixmet_ );
      
      //fill met template-----------------------------------------------------------------------
      
      if( algo_ == e_makeTemplate ) {

        if( HLT_Jet15U_ == 0 ) continue;
        
        //dphixmet_  = deltaPhi( tcmetphi_ , jetSystem.phi() );
        //metPar_    = -1 * tcmet_ * cos( dphixmet_ );
        //metPerp_   = tcmet_ * sin( dphixmet_ );
        
        int iJetBin      = getJetBin( nJets_ );
        int iSumJetPtBin = getSumJetPtBin( sumJetPt_ );
        
        if( debug ) {
          cout << "nJets " << nJets_ << " sumJetPt " << sumJetPt_ << endl;
          cout << "iJetBin " << iJetBin << " iSumJetPtBin " << iSumJetPtBin << " tcmet " << tcmet_ << endl;
        }

        fillUnderOverFlow( metTemplate[ iJetBin ][ iSumJetPtBin ]     , tcmet_   , weight_ );
        fillUnderOverFlow( metParTemplate[ iJetBin ][ iSumJetPtBin ]  , metPar_  , weight_ );
        fillUnderOverFlow( metPerpTemplate[ iJetBin ][ iSumJetPtBin ] , metPerp_ , weight_ );
        
      }

      
      //apply good photon selection-------------------------------------------------------------
  
      if( algo_ == e_photonSelection ) {

        if( HLT_Photon10_L1R_ == 0         &&         
            HLT_Photon15_L1R_ == 0         && 
            HLT_Photon10_Cleaned_L1R_ == 0 && 
            HLT_Photon15_Cleaned_L1R_ == 0  ) continue;
          
        if ( etg_ < 20 )                                 continue;
        if ( r4_ < 0.05 )                                continue;
        if ( hoe_ > 0.1 )                                continue;
        if ( jet_dr_ > 0.5 )                             continue;
        //if ( jet_neu_emfrac_ + jet_chg_emfrac_< 0.95 )   continue; 
        //if ( drel_ < 0.3 )                               continue;
        if ( jet_neu_emfrac_ < 0.95 )                    continue; 
        //if ( sumJetPt_ < 200. )                          continue;
        
        //dphixmet_  = deltaPhi( tcmetphi_ , phig_ );
        //metPar_    = tcmet_ * cos( dphixmet_ );
        //metPerp_   = tcmet_ * sin( dphixmet_ );
        
      }

      //apply Z selection-----------------------------------------------------------------------

      if( algo_ == e_ZSelection ) {
        
        //if( vecJetPt_  < 100)                                       continue;
        if( hyp_p4().size() != 1 )                                  continue;
        if( hyp_lt_id()[0] * hyp_ll_id()[0] > 0 )                   continue;
        if( hyp_type()[0]==1 || hyp_type()[0]==2)                   continue;
        if( hyp_p4()[0].mass() < 76. || hyp_p4()[0].mass() > 106.)  continue;
        if( hyp_ll_p4()[0].pt() < 10 )                              continue;
        if( hyp_lt_p4()[0].pt() < 10 )                              continue;
        //if ( sumJetPt_ < 200. )                                     continue;
        
        //ttbar muon ID
        if (abs(hyp_ll_id()[0]) == 13  && (!(fabs(hyp_ll_p4()[0].eta()) < 2.4 && muonId(hyp_ll_index()[0],NominalTTbarV2))))   continue;
        if (abs(hyp_lt_id()[0]) == 13  && (!(fabs(hyp_lt_p4()[0].eta()) < 2.4 && muonId(hyp_lt_index()[0],NominalTTbarV2))))   continue;
        
        //ttbarV1 electron ID
        if (abs(hyp_ll_id()[0]) == 11  && (! pass_electronSelection( hyp_ll_index()[0] , electronSelection_ttbarV1 , isData ))) continue;
        if (abs(hyp_lt_id()[0]) == 11  && (! pass_electronSelection( hyp_lt_index()[0] , electronSelection_ttbarV1 , isData ))) continue;

        //ttbar electron ID
        //if (abs(hyp_ll_id()[0]) == 11  && (! pass_electronSelection( hyp_ll_index()[0] , electronSelection_ttbar , isData ))) continue;
        //if (abs(hyp_lt_id()[0]) == 11  && (! pass_electronSelection( hyp_lt_index()[0] , electronSelection_ttbar , isData ))) continue;
        
        //nominal muon ID
        //if (abs(hyp_ll_id()[0]) == 13  && (! (fabs(hyp_ll_p4()[0].eta()) < 2.4 && muonId(hyp_ll_index()[0]))))   continue;
        //if (abs(hyp_lt_id()[0]) == 13  && (! (fabs(hyp_lt_p4()[0].eta()) < 2.4 && muonId(hyp_lt_index()[0]))))   continue;
        
        //ttbar electron ID
        //if (abs(hyp_ll_id()[0]) == 11  && (! pass_electronSelection( hyp_ll_index()[0] , electronSelection_cand01 ))) continue;
        //if (abs(hyp_lt_id()[0]) == 11  && (! pass_electronSelection( hyp_lt_index()[0] , electronSelection_cand01 ))) continue;

        //dphixmet_  = deltaPhi( tcmetphi_ , hyp_p4()[0].phi() );
        //metPar_    = tcmet_ * cos( dphixmet_ );
        //metPerp_   = tcmet_ * sin( dphixmet_ );

  


//         if( tcmet_ > 60 ){
//           cout << "tcmet " << tcmet_ << " type " << hyp_type()[0] << endl;
//         }
      }

     

      //fill predicted and observed met histos--------------------------------------------------

      if( algo_ != e_makeTemplate){
        
        int iJetBin      = getJetBin( nJets_ );
        int iSumJetPtBin = getSumJetPtBin( sumJetPt_ );
        TH1F* hmet     = (TH1F*) metTemplateFile->Get(Form("metTemplate_%i_%i",iJetBin,iSumJetPtBin));
        TH1F* hmetPar  = (TH1F*) metTemplateFile->Get(Form("metParTemplate_%i_%i",iJetBin,iSumJetPtBin));
        TH1F* hmetPerp = (TH1F*) metTemplateFile->Get(Form("metPerpTemplate_%i_%i",iJetBin,iSumJetPtBin));
        
        fillUnderOverFlow( metObserved_njets[iJetBin]  ,  tcmet_ , weight_ );
        metPredicted_njets[iJetBin]->Add( hmet );
        
        fillUnderOverFlow( metObserved , tcmet_ , weight_  );
        metPredicted->Add( hmet );

        fillUnderOverFlow( metParObserved , metPar_ , weight_  );
        metParPredicted->Add( hmetPar );

        fillUnderOverFlow( metPerpObserved ,  metPerp_ , weight_ );
        metPerpPredicted->Add( hmetPerp );
        
        delete hmet;

      }
    } // end loop over events
  } // end loop over files
  
  cout << "\n\n********************SUMMARY********************" << endl;
  cout << "Total number of events: " << nEventsTotal << endl;
  cout << "Total number of events that pass good run/lumi: " << nPassGoodRun 
       << " (" << 100*(double)nPassGoodRun/nEventsTotal << "% of total)" << endl;
  cout << "Total number of events that pass BPTX trigger: " << nPassBPTX
       << " (" << 100*(double)nPassBPTX/nPassGoodRun << "%)" << endl;
  cout << "Total number of events that pass BSC trigger: " << nPassBSC
       << " (" << 100*(double)nPassBSC/nPassBPTX << "%)" << endl;
  cout << "Total number of events that pass BeamHalo trigger: " << nPassBeamHalo
       << " (" << 100*(double)nPassBeamHalo/nPassBSC << "%)" << endl;
  cout << "Total number of events that pass tracking cuts: " << nPassGoodTracks
       << " (" << 100*(double)nPassGoodTracks/nPassBeamHalo << "%)" << endl;
  cout << "Total number of events that pass vertex cuts: " << nPassGoodVertex
       << " (" << 100*(double)nPassGoodVertex/nPassGoodTracks << "%)" << endl;
  cout << endl << endl;

  if( nSkip_els_conv_dist > 0 ){
    cout << "Skipped " << nSkip_els_conv_dist << " events due to nan in els_conv_dist branch" << endl;
  }

  if (nEventsChain != nEventsTotal)
    std::cout << "ERROR: number of events from files is not equal to total number of events" << std::endl;
  
  CloseBabyNtuple();

  //normalize met templates
  if( algo_ == e_makeTemplate ) {
    
    for( int iJetBin = 0 ; iJetBin < nJetBins ; iJetBin++ ){
      for( int iSumJetPtBin = 0 ; iSumJetPtBin < nSumJetPtBins ; iSumJetPtBin++ ){
       
        float scale = metTemplate[ iJetBin ][ iSumJetPtBin ] -> Integral();
        
        if( scale > 0 )
          metTemplate[ iJetBin ][ iSumJetPtBin ] -> Scale ( 1. / scale );

        scale = metParTemplate[ iJetBin ][ iSumJetPtBin ] -> Integral();
        
        if( scale > 0 )
          metParTemplate[ iJetBin ][ iSumJetPtBin ] -> Scale ( 1. / scale );

        scale = metPerpTemplate[ iJetBin ][ iSumJetPtBin ] -> Integral();
        
        if( scale > 0 )
          metPerpTemplate[ iJetBin ][ iSumJetPtBin ] -> Scale ( 1. / scale );
    
      }
    }
  }


  // make histos rootfile
  //stringstream rootfilename;
  //rootfilename << "root/" << prefix << metTemplateString << ".root";
  TDirectory *rootdir = gDirectory->GetDirectory("Rint:");
  rootdir->cd();
  saveHist( Form("root/%s_%s%s.root", prefix , iter , metTemplateString.c_str() ) );
  //saveHist(rootfilename.str().c_str());
  deleteHistos();
  
} // end ScanChain
Example #17
0
void makePhotonBabies::ScanChain (TChain* chain, const char* prefix, bool isData, 
                                  bool calculateTCMET, int nEvents, float kFactor){

  set_goodrun_file( jsonfilename );
  
  if( isData ){
    ofile_tcmet.open(  Form( "photonTemplates/%s/%s_tcmetprintout.txt" , iter , prefix  ) );
    ofile_events.open( Form( "photonTemplates/%s/%s_highmetevents.txt" , iter , prefix  ) );


    ofile_events << "|" << setw(8)  << "run"          << setw(4) 
                 << "|" << setw(6)  << "lumi"         << setw(4) 
                 << "|" << setw(12) << "event"        << setw(4) 
                 << "|" << setw(6)  << "njets"        << setw(4) 
                 << "|" << setw(6)  << "nbtags"       << setw(4) 
                 << "|" << setw(8)  << "tcmet"        << setw(4) 
                 << "|" << setw(8)  << "pfmet"        << setw(4) 
                 << "|" << setw(8)  << "dphi"         << setw(4) << "|" << endl; 
  }

  
  bookHistos();

  int npass = 0;
  
  // make a baby ntuple
  //stringstream babyfilename;
  //babyfilename << prefix << "_baby.root";
  MakeBabyNtuple( Form("photonTemplates/%s/%s_baby.root", iter , prefix ) );

  TObjArray *listOfFiles = chain->GetListOfFiles();

  unsigned int nEventsChain = 0;
  if(nEvents == -1) 
    nEvents = chain->GetEntries();
  nEventsChain = nEvents;
  unsigned int nEventsTotal = 0;
  
  //pass fail counters
  int nSkip_els_conv_dist = 0;
  if(debug) cout << "Begin file loop" << endl;

  // file loop
  TIter fileIter(listOfFiles);
  TFile* currentFile = 0;
  while ((currentFile = (TFile*)fileIter.Next())){
    
    TFile f(currentFile->GetTitle());
    TTree *tree = (TTree*)f.Get("Events");
    cms2.Init(tree);

    // event loop
    unsigned int nEvents = tree->GetEntries();
 
    for (unsigned int event = 0 ; event < nEvents; ++event){
        
      cms2.GetEntry(event);
      ++nEventsTotal;

      // progress feedback to user
      if (nEventsTotal % 1000 == 0){
            
        // xterm magic from L. Vacavant and A. Cerri
        if (isatty(1)){
                
          printf("\015\033[32m ---> \033[1m\033[31m%4.1f%%"
                 "\033[0m\033[32m <---\033[0m\015", (float)nEventsTotal/(nEventsChain*0.01));
          fflush(stdout);
        }
      }
      
      if( isData ) {
	DorkyEventIdentifier id = { evt_run(),evt_event(), evt_lumiBlock() };
	if (is_duplicate(id) )
	  continue;
      }
      /*
      //skip events with bad els_conv_dist 
      bool skipEvent = false;
      for( unsigned int iEl = 0 ; iEl < els_conv_dist().size() ; ++iEl ){
        if( els_conv_dist().at(iEl) != els_conv_dist().at(iEl) ){
          skipEvent = true;
        }
      }
      
      if( skipEvent ){
        cout << "SKIPPING EVENT WITH BAD ELS_CONV_DIST" << endl;       
        nSkip_els_conv_dist++;
        continue;
      }
      */
      
      //good run+event selection-----------------------------------------------------------

      if( isData && !goodrun(cms2.evt_run(), cms2.evt_lumiBlock()) ) continue;
      if( !cleaning_standardAugust2010( isData) )                    continue;

      
      if(debug) cout << "Pass event selection" << endl;

      InitBabyNtuple();

      // event stuff
      strcpy(dataset_, cms2.evt_dataset().Data());
      run_     = cms2.evt_run();
      lumi_    = cms2.evt_lumiBlock();
      event_   = cms2.evt_event();

      weight_ = 1.;
      pthat_  = -1;
      if( !isData ){
        weight_ = cms2.evt_scale1fb() * kFactor * lumi;
        pthat_  = cms2.genps_pthat();
      }

      float maxphotonpt = -1;
     
      //stitching together PhotonJet_Pt15 and PhotonJet_Pt30
      if( strcmp( prefix , "PhotonJet") == 0 ){

        if( TString(currentFile->GetTitle()).Contains("PhotonJet_Pt15") ){
          if( cms2.genps_pthat() > 30. ) continue;
        }
        if( TString(currentFile->GetTitle()).Contains("PhotonJet_Pt30") ){
          if( cms2.genps_pthat() > 80. ) continue;
        }
        if( TString(currentFile->GetTitle()).Contains("PhotonJet_Pt80") ){
          if( cms2.genps_pthat() > 170. ) continue;
        }

        for( unsigned int ig = 0 ; ig < photons_p4().size() ; ++ig ){
          if( photons_p4().at(ig).pt() > maxphotonpt ) 
            maxphotonpt = photons_p4().at(ig).pt();
        }
 
        fillUnderOverFlow( hgenps_pthat  , genps_pthat() , weight_ );
        fillUnderOverFlow( hphotonpt     , maxphotonpt   , weight_ );
      }
      
      

      //access HLT triggers------------------------------------------------------------------
      

      //triggers for data (cleaned)
      
      //first check if trigger is present
      for( unsigned int itrig = 0 ; itrig < hlt_trigNames().size() ; ++itrig ){

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon20_Cleaned_L1R" )    == 0 ) HLT_Photon20_Cleaned_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon30_Cleaned_L1R" )    == 0 ) HLT_Photon30_Cleaned_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon50_Cleaned_L1R" )    == 0 ) HLT_Photon50_Cleaned_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon50_Cleaned_L1R_v1" ) == 0 ) HLT_Photon50_Cleaned_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon70_Cleaned_L1R_v1" ) == 0 ) HLT_Photon70_Cleaned_L1R_    = 0;

      }

      HLT_prescale_Photon20_Cleaned_L1R_    = -1;
      HLT_prescale_Photon30_Cleaned_L1R_    = -1;
      HLT_prescale_Photon50_Cleaned_L1R_    = -1;
      HLT_prescale_Photon70_Cleaned_L1R_    = -1;
  
      if( passHLTTrigger( "HLT_Photon20_Cleaned_L1R" ) ){
        HLT_Photon20_Cleaned_L1R_           = 1;
        HLT_prescale_Photon20_Cleaned_L1R_  = HLT_prescale( "HLT_Photon20_Cleaned_L1R" );
      }

      if( passHLTTrigger( "HLT_Photon30_Cleaned_L1R" ) ){
        HLT_Photon30_Cleaned_L1R_           = 1;
        HLT_prescale_Photon30_Cleaned_L1R_  = HLT_prescale( "HLT_Photon30_Cleaned_L1R" );
      }

      if( passHLTTrigger( "HLT_Photon50_Cleaned_L1R" ) ){
        HLT_Photon50_Cleaned_L1R_           = 1;
        HLT_prescale_Photon50_Cleaned_L1R_  = HLT_prescale( "HLT_Photon50_Cleaned_L1R" );
      }

      if( passHLTTrigger( "HLT_Photon50_Cleaned_L1R_v1" ) ){
        HLT_Photon50_Cleaned_L1R_           = 1;
        HLT_prescale_Photon50_Cleaned_L1R_  = HLT_prescale( "HLT_Photon50_Cleaned_L1R_v1" );
      }
      
      if( passHLTTrigger( "HLT_Photon70_Cleaned_L1R_v1" ) ){
        HLT_Photon70_Cleaned_L1R_           = 1;
        HLT_prescale_Photon70_Cleaned_L1R_  = HLT_prescale( "HLT_Photon70_Cleaned_L1R_v1" );
      }


      //triggers for MC (not cleaned)      

      //first check if trigger is present
      for( unsigned int itrig = 0 ; itrig < hlt_trigNames().size() ; ++itrig ){

        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon20_L1R" )    == 0 ) HLT_Photon20_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon30_L1R" )    == 0 ) HLT_Photon30_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon50_L1R" )    == 0 ) HLT_Photon50_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon50_L1R_v1" ) == 0 ) HLT_Photon50_L1R_    = 0;
        if( strcmp( hlt_trigNames().at(itrig) , "HLT_Photon70_L1R_v1" ) == 0 ) HLT_Photon70_L1R_    = 0;

      }

      HLT_prescale_Photon20_L1R_    = -1;
      HLT_prescale_Photon30_L1R_    = -1;
      HLT_prescale_Photon50_L1R_    = -1;
      HLT_prescale_Photon70_L1R_    = -1;


      if( passHLTTrigger( "HLT_Photon20_L1R" ) ){
        HLT_Photon20_L1R_           = 1;
        HLT_prescale_Photon20_L1R_  = HLT_prescale( "HLT_Photon20_L1R" );
      }
      
      if( passHLTTrigger( "HLT_Photon30_L1R" ) ){
        HLT_Photon30_L1R_           = 1;
        HLT_prescale_Photon30_L1R_  = HLT_prescale( "HLT_Photon30_L1R" );
      }

      if( passHLTTrigger( "HLT_Photon50_L1R" ) ){
        HLT_Photon50_L1R_           = 1;
        HLT_prescale_Photon50_L1R_  = HLT_prescale( "HLT_Photon50_L1R" );
      }

      if( passHLTTrigger( "HLT_Photon50_L1R_v1" ) ){
        HLT_Photon50_L1R_           = 1;
        HLT_prescale_Photon50_L1R_  = HLT_prescale( "HLT_Photon50_L1R_v1" );
      }
      
      if( passHLTTrigger( "HLT_Photon70_L1R_v1" ) ){
        HLT_Photon70_L1R_           = 1;
        HLT_prescale_Photon70_L1R_  = HLT_prescale( "HLT_Photon70_L1R_v1" );
      }
      
              
      // calomet, pfmet, genmet
      met_       = cms2.evt_met();
      metphi_    = cms2.evt_metPhi();
      sumet_     = cms2.evt_sumet();

      pfmet_    = cms2.evt_pfmet();
      pfmetphi_ = cms2.evt_pfmetPhi();
      pfsumet_  = cms2.evt_pfsumet();

      if (!isData){
        genmet_     = cms2.gen_met();
        genmetphi_  = cms2.gen_metPhi();
        gensumet_   = cms2.gen_sumEt();
      }
      
      //tcmet stuff------------------------------------------------------------------- 

      // out-of-the-box  tcmet stuff
      tcmet_    = evt_tcmet();
      tcmetphi_ = evt_tcmetPhi();
      tcsumet_  = evt_tcsumet();

      if( calculateTCMET ){
        
        metStruct tcmetNewStruct = correctedTCMET();
        tcmetNew_     = tcmetNewStruct.met;
        tcmetphiNew_  = tcmetNewStruct.metphi;
        tcsumetNew_   = tcmetNewStruct.sumet;
        
      }else{
        
        tcmetNew_    = -9999;
        tcmetphiNew_ = -9999;
        tcsumetNew_  = -9999;
       
      }

      nGoodVertex_ = 0;
      for (size_t v = 0; v < cms2.vtxs_position().size(); ++v){
        if(isGoodVertex(v)) nGoodVertex_++;
      }

                  
      //photon stuff------------------------------------------------------------------ 

      int ijetg    = -1; //index of jet matched to photon
  
      
      nPhotons_           =  0;
      float maxPhotonPt   = -1;
      int   igmax         = -1;
      
      if( photons_p4().size() == 0 ) continue;
      
      //count photons pt > 10 GeV
      for (unsigned int iphoton = 0 ; iphoton < photons_p4().size() ; iphoton++) {
        
        LorentzVector vphoton = photons_p4().at(iphoton);
        
        if(vphoton.pt() > 10){
          nPhotons_++;
          if(vphoton.pt() > maxPhotonPt){
            maxPhotonPt  = vphoton.pt();
            igmax        = iphoton;
          }
        }
      }
      
      if( igmax < 0 ) continue;
      
      ijetg = isGoodEMObject(igmax);
      
      if( ijetg < 0 ) continue;
      
      etg_        = photons_p4().at(igmax).pt();
      etag_       = photons_p4().at(igmax).eta();
      
      phig_       = photons_p4().at(igmax).phi();
      hoe_        = photons_hOverE().at(igmax);
      swiss_      = photons_swissSeed().at(igmax);
      int scind   = photons_scindex().at(igmax) ;
      
      if( scind > - 1 ){
        seed_       = scs_eSeed().at(scind) ;
        s4_         = swiss_ - seed_ ;
        r4_         = 1 - s4_ / seed_ ;
      }else{
        seed_ = -9999.;
        s4_   = -9999.;
        r4_   = -9999.;
      }
      
      photon_scidx_            = photons_scindex().at(igmax);
      photon_pixelseed_        = photons_haspixelSeed().at(igmax) ? 1 : 0;
      photon_e15_              = photons_e1x5().at(igmax);      
      photon_e25max_           = photons_e2x5Max().at(igmax);      
      photon_e33_              = photons_e3x3().at(igmax);           
      photon_e55_              = photons_e5x5().at(igmax);           
      photon_ecalIso03_        = photons_ecalIso03().at(igmax);      
      photon_ecalIso04_        = photons_ecalIso04().at(igmax);      
      photon_hcalIso03_        = photons_hcalIso03().at(igmax);      
      photon_hcalIso04_        = photons_hcalIso04().at(igmax);      
      photon_ntkIsoHollow03_   = photons_ntkIsoHollow03().at(igmax);
      photon_ntkIsoHollow04_   = photons_ntkIsoHollow04().at(igmax);
      photon_ntkIsoSolid03_    = photons_ntkIsoSolid03().at(igmax); 
      photon_ntkIsoSolid04_    = photons_ntkIsoSolid04().at(igmax); 
      photon_sigmaEtaEta_      = photons_sigmaEtaEta().at(igmax);    
      photon_sigmaIEtaIEta_    = photons_sigmaIEtaIEta().at(igmax);
      photon_tkisoHollow03_    = photons_tkIsoHollow03().at(igmax);
      photon_tkisoHollow04_    = photons_tkIsoHollow04().at(igmax); 
      photon_tkisoSolid03_     = photons_tkIsoSolid03().at(igmax);   
      photon_tkisoSolid04_     = photons_tkIsoSolid04().at(igmax);  
      
      LorentzVector myvjet = pfjets_cor().at(ijetg) * pfjets_p4().at(ijetg);
      LorentzVector myvg   = photons_p4().at(igmax);
      
      jet_dr_             = dRbetweenVectors(myvjet, myvg);
      jet_pt_             = pfjets_p4().at(ijetg).pt();
      jet_energy_         = pfjets_p4().at(ijetg).energy();
      jet_eta_            = pfjets_p4().at(ijetg).eta();
      jet_chg_emfrac_     = pfjets_chargedEmE().at(ijetg)     / jet_energy_;
      jet_chg_hadfrac_    = pfjets_chargedHadronE().at(ijetg) / jet_energy_;
      jet_neu_emfrac_     = pfjets_neutralEmE().at(ijetg)     / jet_energy_;
      jet_neu_hadfrac_    = pfjets_neutralHadronE().at(ijetg) / jet_energy_;
      jet_nchg_           = pfjets_chargedMultiplicity().at(ijetg);
      jet_nmuon_          = pfjets_muonMultiplicity().at(ijetg);
      jet_nneu_           = pfjets_neutralMultiplicity().at(ijetg);
      jet_dphimet_        = deltaPhi( pfjets_p4().at(ijetg).phi() , tcmetphi_);
      jet_pfjetid_        = passesPFJetID( ijetg ) ? 1 : 0;
      
      //jet stuff--------------------------------------------------------------------- 
                    
      nJets_        = 0;
      sumJetPt_     = 0.;
      nJets40_      = 0;
      nJets10_      = 0;
      nJets15_      = 0;
      nJets20_      = 0;
      sumJetPt10_   = 0.;
      nbtags_       = 0;

      LorentzVector jetSystem(0.,0.,0.,0.);        
      float maxcosdphi  = -99;
      //int   imaxcosdphi = -1;
      int   imaxjet     = -1;
      float maxpt       = -1;

      VofP4         good_pfjets15_p4;
      vector<float> good_pfjets15_cor;
      VofP4         good_pfjets30_p4;
      vector<float> good_pfjets30_cor;

      failjetid_ =  0;
      maxemf_    = -1;
      
      //loop over pfjets pt > 30 GeV |eta| < 2.5
      for (unsigned int ijet = 0 ; ijet < pfjets_p4().size() ; ijet++) {
        
        //skip jet matched to photon
        if( (int)ijet == ijetg ) continue;
 
        LorentzVector vjet      = pfjets_cor().at(ijet) * pfjets_p4().at(ijet);
        if( fabs( vjet.eta() ) > 2.5 )           continue;

        if( !passesPFJetID(ijet) ){
          failjetid_ = 1;
          continue;
        }

        if ( vjet.pt() > 10. ){
          sumJetPt10_ += vjet.pt();
        }
        if ( vjet.pt() > 15. ){
          sumJetPt_ += vjet.pt();
          jetSystem += vjet;
          good_pfjets15_p4.push_back ( pfjets_p4().at(ijet)  );
          good_pfjets15_cor.push_back( pfjets_cor().at(ijet) );

          float emfrac = pfjets_neutralEmE().at(ijet) / pfjets_p4().at(ijet).energy();
          if( emfrac > maxemf_ ) maxemf_ = emfrac;
        }

        if ( vjet.pt() > 10. ) nJets10_++;
        if ( vjet.pt() > 15. ) nJets15_++;
        if ( vjet.pt() > 20. ) nJets20_++;
              
        if( vjet.pt() < 30. )                    continue;

        good_pfjets30_p4.push_back ( pfjets_p4().at(ijet)  );
        good_pfjets30_cor.push_back( pfjets_cor().at(ijet) );
        
        //find max jet pt
        if( vjet.pt() > maxpt ){
          maxpt   = vjet.pt();
          imaxjet = ijet;
        }

        //find jet (anti-)aligned with tcmet
        if( fabs( cos( tcmetphi_ - vjet.phi() ) ) > maxcosdphi ){
          maxcosdphi  = fabs( cos( tcmetphi_ - vjet.phi() ) );
          dphijetmet_ = fabs( tcmetphi_ - vjet.phi() );
          if( dphijetmet_ > TMath::Pi() ) dphijetmet_ = TMath::TwoPi() - dphijetmet_;
        }
        
        //find closest calojet to use btagging info
        float dRmin    = 100;
        int   iCaloJet = -1;
          
        for( unsigned int iC = 0 ; iC < jets_p4().size() ; iC++ ){
            
          LorentzVector vcalojet = jets_p4().at(iC);
          if( vcalojet.pt() * jets_cor().at(iC) < 10 ) continue;
            
          float dR = dRbetweenVectors(vjet, vcalojet);
          if( dR < dRmin ){
            dRmin = dR;
            iCaloJet = iC;
          }
        }
                  
        if( iCaloJet > -1 ){
          if( jets_simpleSecondaryVertexHighEffBJetTag().at(iCaloJet) > 1.74 ) ++nbtags_;
          //if( jets_trackCountingHighEffBJetTag().at(iCaloJet) > 1.7 ) ++nbtags_;
        }

        if ( vjet.pt() > 30. ) nJets_++;
        if ( vjet.pt() > 40. ) nJets40_++;
          
      }
                            
      

      jetmax_pt_ = -1;

      if( imaxjet > -1 ){
        jetmax_pt_       = pfjets_cor().at(imaxjet) * pfjets_p4().at(imaxjet).pt();
        jetmax_dphimet_  = deltaPhi( pfjets_p4().at(imaxjet).phi() , tcmetphi_);
      }

      vecJetPt_ = jetSystem.pt();


      VofP4         good_jpts15_p4;
      vector<float> good_jpts15_cor;
      VofP4         good_jpts30_p4;
      vector<float> good_jpts30_cor;
  
      for (unsigned int ijet = 0; ijet < jpts_p4().size(); ijet++) {

        //skip jet matched to photon
        if( (int)ijet == ijetg ) continue;
        
        LorentzVector vjet = jpts_p4().at(ijet) * jpts_cor().at(ijet); 
        
        if( fabs( vjet.eta() ) > 2.5 )         continue;
        if( !passesCaloJetID( vjet ) )         continue;
        
        if ( vjet.pt() > 15. ){
          good_jpts15_p4.push_back ( jpts_p4().at(ijet)  );
          good_jpts15_cor.push_back( jpts_cor().at(ijet) );
        }
        if ( vjet.pt() > 30. ){
          good_jpts30_p4.push_back ( jpts_p4().at(ijet)  );
          good_jpts30_cor.push_back( jpts_cor().at(ijet) );
        }
      }
      

      //calculate type1 METs
      
      metStruct type1PFMET30 = customType1Met( evt_pfmet() * cos( evt_pfmetPhi() ) , 
                                               evt_pfmet() * cos( evt_pfmetPhi() ) , 
                                               evt_pfsumet() ,
                                               good_pfjets30_p4 , 
                                               good_pfjets30_cor );

      pfmet_type1_pt30_ = type1PFMET30.met;

      metStruct type1PFMET15 = customType1Met( evt_pfmet() * cos( evt_pfmetPhi() ) , 
                                               evt_pfmet() * cos( evt_pfmetPhi() ) , 
                                               evt_pfsumet() ,
                                               good_pfjets15_p4 , 
                                               good_pfjets15_cor );
      
      pfmet_type1_pt15_ = type1PFMET15.met;
      
      metStruct type1TCMET30 = customType1Met( tcmetNew_ * cos( tcmetphiNew_ ) , 
                                               tcmetNew_ * sin( tcmetphiNew_ ) , 
                                               tcsumetNew_ ,
                                               good_jpts30_p4 , 
                                               good_jpts30_cor );

      tcmetNew_type1_pt30_ = type1TCMET30.met;

      metStruct type1TCMET15 = customType1Met( tcmetNew_ * cos( tcmetphiNew_ )  , 
                                               tcmetNew_ * sin( tcmetphiNew_ )  , 
                                               tcsumetNew_ ,
                                               good_jpts15_p4 , 
                                               good_jpts15_cor );
      
      tcmetNew_type1_pt15_ = type1TCMET15.met;
      

      //fill histos and ntuple----------------------------------------------------------- 
              
      npass++;
      FillBabyNtuple();
      
      //fillHistos( htcmet            , tcmet_           , weight_ , leptype_ , nJets_ );
      //fillHistos( htcmetNew         , tcmetNew_        , weight_ , leptype_ , nJets_ );
      //fillHistos( hpfmet            , pfmet_           , weight_ , leptype_ , nJets_  );
              
      if( isData && ( tcmet_ > 30 || pfmet_ > 30 ) ){

        metStruct dummyStruct = correctedTCMET( true, ofile_tcmet );

        ofile_events << "|" << setw(8)  << evt_run()                   << setw(4) 
                     << "|" << setw(6)  << evt_lumiBlock()             << setw(4) 
                     << "|" << setw(12) << evt_event()                 << setw(4) 
                     << "|" << setw(6)  << nJets_                      << setw(4) 
                     << "|" << setw(6)  << nbtags_                     << setw(4) 
                     << "|" << setw(8)  << fround(tcmet_,1)            << setw(4) 
                     << "|" << setw(8)  << fround(pfmet_,1)            << setw(4) 
                     << "|" << setw(8)  << fround(dphijetmet_,2)       << setw(4) << "|" << endl; 
       
      }
    } // end loop over events
  } // end loop over files

  if( nSkip_els_conv_dist > 0 ){
    cout << "Skipped " << nSkip_els_conv_dist << " events due to nan in els_conv_dist branch" << endl;
  }

  if (nEventsChain != nEventsTotal)
    std::cout << "ERROR: number of events from files is not equal to total number of events" << std::endl;
  
  CloseBabyNtuple();

  cout << "numEvents passing selection " << npass << endl;

  // make histos rootfile
  //TDirectory *rootdir = gDirectory->GetDirectory("Rint:");
  //rootdir->cd();
  //saveHist( Form("output/%s/%s_templates.root", iter , prefix ) );
  deleteHistos();
  
} // end ScanChain
Example #18
0
void computeAccSelZmmBinned(const TString conf,      // input file
                            const TString outputDir  // output directory
                           ) {
    gBenchmark->Start("computeAccSelZmmBinned");

    //--------------------------------------------------------------------------------------------------------------
    // Settings
    //==============================================================================================================

    const Double_t MASS_LOW   = 60;
    const Double_t MASS_HIGH  = 120;
    const Double_t PT_CUT     = 25;
    const Double_t ETA_CUT    = 2.1;
    const Double_t MUON_MASS  = 0.105658369;

    // efficiency files
    const TString dataHLTEffName_pos = "../Efficiency/May23_MuHLTEff_pos/analysis/eff.root";
    const TString dataHLTEffName_neg = "../Efficiency/May23_MuHLTEff_neg/analysis/eff.root";
    const TString zmmHLTEffName_pos  = "../Efficiency/Zmm_MuHLTEff_pos/analysis/eff.root";
    const TString zmmHLTEffName_neg  = "../Efficiency/Zmm_MuHLTEff_neg/analysis/eff.root";

    const TString dataSelEffName_pos = "../Efficiency/May23_MuSelEff_pos/analysis/eff.root";
    const TString dataSelEffName_neg = "../Efficiency/May23_MuSelEff_neg/analysis/eff.root";
    const TString zmmSelEffName_pos  = "../Efficiency/Zmm_MuSelEff_pos/analysis/eff.root";
    const TString zmmSelEffName_neg  = "../Efficiency/Zmm_MuSelEff_neg/analysis/eff.root";

    const TString dataTrkEffName_pos = "../Efficiency/May23_MuTrkEff_pos/analysis/eff.root";
    const TString dataTrkEffName_neg = "../Efficiency/May23_MuTrkEff_neg/analysis/eff.root";
    const TString zmmTrkEffName_pos  = "../Efficiency/Zmm_MuTrkEff_pos/analysis/eff.root";
    const TString zmmTrkEffName_neg  = "../Efficiency/Zmm_MuTrkEff_neg/analysis/eff.root";

    const TString dataStaEffName_pos = "../Efficiency/May23_MuStaEff_iso_pos/analysis/eff.root";
    const TString dataStaEffName_neg = "../Efficiency/May23_MuStaEff_iso_neg/analysis/eff.root";
    const TString zmmStaEffName_pos  = "../Efficiency/Zmm_MuStaEff_iso_pos/analysis/eff.root";
    const TString zmmStaEffName_neg  = "../Efficiency/Zmm_MuStaEff_iso_neg/analysis/eff.root";


    //--------------------------------------------------------------------------------------------------------------
    // Main analysis code
    //==============================================================================================================

    vector<TString> fnamev;  // file name per input file
    vector<TString> labelv;  // TLegend label per input file
    vector<Int_t>   colorv;  // plot color per input file
    vector<Int_t>   linev;   // plot line style per input file

    //
    // parse .conf file
    //
    ifstream ifs;
    ifs.open(conf.Data());
    assert(ifs.is_open());
    string line;
    while(getline(ifs,line)) {
        if(line[0]=='#') continue;

        string fname;
        Int_t color, linesty;
        stringstream ss(line);
        ss >> fname >> color >> linesty;
        string label = line.substr(line.find('@')+1);
        fnamev.push_back(fname);
        labelv.push_back(label);
        colorv.push_back(color);
        linev.push_back(linesty);
    }
    ifs.close();

    // Create output directory
    gSystem->mkdir(outputDir,kTRUE);


    //
    // HLT efficiency
    //
    cout << "Loading trigger efficiencies..." << endl;

    TFile *dataHLTEffFile_pos = new TFile(dataHLTEffName_pos);
    CEffUser2D dataHLTEff_pos;
    dataHLTEff_pos.loadEff((TH2D*)dataHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataHLTEffFile_neg = new TFile(dataHLTEffName_neg);
    CEffUser2D dataHLTEff_neg;
    dataHLTEff_neg.loadEff((TH2D*)dataHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataHLTEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmHLTEffFile_pos = new TFile(zmmHLTEffName_pos);
    CEffUser2D zmmHLTEff_pos;
    zmmHLTEff_pos.loadEff((TH2D*)zmmHLTEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmHLTEffFile_neg = new TFile(zmmHLTEffName_neg);
    CEffUser2D zmmHLTEff_neg;
    zmmHLTEff_neg.loadEff((TH2D*)zmmHLTEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmHLTEffFile_neg->Get("hErrhEtaPt"));

    //
    // Selection efficiency
    //
    cout << "Loading selection efficiencies..." << endl;

    TFile *dataSelEffFile_pos = new TFile(dataSelEffName_pos);
    CEffUser2D dataSelEff_pos;
    dataSelEff_pos.loadEff((TH2D*)dataSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataSelEffFile_neg = new TFile(dataSelEffName_neg);
    CEffUser2D dataSelEff_neg;
    dataSelEff_neg.loadEff((TH2D*)dataSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataSelEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmSelEffFile_pos = new TFile(zmmSelEffName_pos);
    CEffUser2D zmmSelEff_pos;
    zmmSelEff_pos.loadEff((TH2D*)zmmSelEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmSelEffFile_neg = new TFile(zmmSelEffName_neg);
    CEffUser2D zmmSelEff_neg;
    zmmSelEff_neg.loadEff((TH2D*)zmmSelEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmSelEffFile_neg->Get("hErrhEtaPt"));

    //
    // Standalone efficiency
    //
    cout << "Loading standalone efficiencies..." << endl;

    TFile *dataStaEffFile_pos = new TFile(dataStaEffName_pos);
    CEffUser2D dataStaEff_pos;
    dataStaEff_pos.loadEff((TH2D*)dataStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataStaEffFile_neg = new TFile(dataStaEffName_neg);
    CEffUser2D dataStaEff_neg;
    dataStaEff_neg.loadEff((TH2D*)dataStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataStaEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmStaEffFile_pos = new TFile(zmmStaEffName_pos);
    CEffUser2D zmmStaEff_pos;
    zmmStaEff_pos.loadEff((TH2D*)zmmStaEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmStaEffFile_neg = new TFile(zmmStaEffName_neg);
    CEffUser2D zmmStaEff_neg;
    zmmStaEff_neg.loadEff((TH2D*)zmmStaEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmStaEffFile_neg->Get("hErrhEtaPt"));

    //
    // Tracker efficiency
    //
    cout << "Loading track efficiencies..." << endl;

    TFile *dataTrkEffFile_pos = new TFile(dataTrkEffName_pos);
    CEffUser2D dataTrkEff_pos;
    dataTrkEff_pos.loadEff((TH2D*)dataTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_pos->Get("hErrhEtaPt"));

    TFile *dataTrkEffFile_neg = new TFile(dataTrkEffName_neg);
    CEffUser2D dataTrkEff_neg;
    dataTrkEff_neg.loadEff((TH2D*)dataTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)dataTrkEffFile_neg->Get("hErrhEtaPt"));

    TFile *zmmTrkEffFile_pos = new TFile(zmmTrkEffName_pos);
    CEffUser2D zmmTrkEff_pos;
    zmmTrkEff_pos.loadEff((TH2D*)zmmTrkEffFile_pos->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_pos->Get("hErrhEtaPt"));

    TFile *zmmTrkEffFile_neg = new TFile(zmmTrkEffName_neg);
    CEffUser2D zmmTrkEff_neg;
    zmmTrkEff_neg.loadEff((TH2D*)zmmTrkEffFile_neg->Get("hEffEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrlEtaPt"), (TH2D*)zmmTrkEffFile_neg->Get("hErrhEtaPt"));


    // Data structures to store info from TTrees
    mithep::TEventInfo *info = new mithep::TEventInfo();
    mithep::TGenInfo   *gen  = new mithep::TGenInfo();
    TClonesArray *muonArr    = new TClonesArray("mithep::TMuon");

    TFile *infile=0;
    TTree *eventTree=0;

    // Variables to store acceptances and uncertainties (per input file)
    vector<Double_t> nEvtsv, nSelv, nSelCorrv;
    vector<Double_t> accv, accCorrv;
    vector<Double_t> accErrv, accCorrErrv;

    //
    // loop through files
    //
    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {

        // Read input file and get the TTrees
        cout << "Processing " << fnamev[ifile] << " ..." << endl;
        infile = new TFile(fnamev[ifile]);
        assert(infile);

        eventTree = (TTree*)infile->Get("Events");
        assert(eventTree);
        eventTree->SetBranchAddress("Info", &info);
        TBranch *infoBr = eventTree->GetBranch("Info");
        eventTree->SetBranchAddress("Gen",  &gen);
        TBranch *genBr  = eventTree->GetBranch("Gen");
        eventTree->SetBranchAddress("Muon", &muonArr);
        TBranch *muonBr = eventTree->GetBranch("Muon");

        nEvtsv.push_back(0);
        nSelv.push_back(0);
        nSelCorrv.push_back(0);

        //
        // loop over events
        //
        for(UInt_t ientry=0; ientry<eventTree->GetEntries(); ientry++) {
            genBr->GetEntry(ientry);
            if(gen->vmass<MASS_LOW || gen->vmass>MASS_HIGH) continue;

            infoBr->GetEntry(ientry);

            Double_t weight=1;
            nEvtsv[ifile]+=weight;

            // trigger requirement
            ULong_t trigger = kHLT_Mu15_eta2p1;
            ULong_t trigObj = kHLT_Mu15_eta2p1_MuObj;
            if(!(info->triggerBits & trigger)) continue;

            // good vertex requirement
            if(!(info->hasGoodPV)) continue;

            muonArr->Clear();
            muonBr->GetEntry(ientry);
            for(Int_t i1=0; i1<muonArr->GetEntriesFast(); i1++) {
                const mithep::TMuon *mu1 = (mithep::TMuon*)((*muonArr)[i1]);

                if(mu1->pt	  < PT_CUT)  continue;  // lepton pT cut
                if(fabs(mu1->eta) > ETA_CUT) continue;  // lepton |eta| cut
                if(!passMuonID(mu1))	     continue;  // lepton selection

                LorentzVector vMu1(mu1->pt, mu1->eta, mu1->phi, MUON_MASS);

                for(Int_t i2=i1+1; i2<muonArr->GetEntriesFast(); i2++) {
                    const mithep::TMuon *mu2 = (mithep::TMuon*)((*muonArr)[i2]);

                    if(mu1->q == mu2->q)	       continue;  // opposite charge requirement
                    if(mu2->pt        < PT_CUT)  continue;  // lepton pT cut
                    if(fabs(mu2->eta) > ETA_CUT) continue;  // lepton |eta| cut
                    if(!passMuonID(mu2))	       continue;  // lepton selection

                    LorentzVector vMu2(mu2->pt, mu2->eta, mu2->phi, MUON_MASS);

                    // trigger match
                    if(!(mu1->hltMatchBits & trigObj) && !(mu2->hltMatchBits & trigObj)) continue;

                    // mass window
                    LorentzVector vDilep = vMu1 + vMu2;
                    if((vDilep.M()<MASS_LOW) || (vDilep.M()>MASS_HIGH)) continue;


                    /******** We have a Z candidate! HURRAY! ********/

                    Double_t effdata, effmc;
                    Double_t corr=1;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= (1.-dataHLTEff_pos.getEff(mu1->eta, mu1->pt));
                        effmc   *= (1.-zmmHLTEff_pos.getEff(mu1->eta, mu1->pt));
                    } else {
                        effdata *= (1.-dataHLTEff_neg.getEff(mu1->eta, mu1->pt));
                        effmc   *= (1.-zmmHLTEff_neg.getEff(mu1->eta, mu1->pt));
                    }
                    if(mu2->q>0) {
                        effdata *= (1.-dataHLTEff_pos.getEff(mu2->eta, mu2->pt));
                        effmc   *= (1.-zmmHLTEff_pos.getEff(mu2->eta, mu2->pt));
                    } else {
                        effdata *= (1.-dataHLTEff_neg.getEff(mu2->eta, mu2->pt));
                        effmc   *= (1.-zmmHLTEff_neg.getEff(mu2->eta, mu2->pt));
                    }
                    effdata = 1.-effdata;
                    effmc   = 1.-effmc;
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataSelEff_pos.getEff(mu1->eta, mu1->pt);
                        effmc   *= zmmSelEff_pos.getEff(mu1->eta, mu1->pt);
                    } else {
                        effdata *= dataSelEff_neg.getEff(mu1->eta, mu1->pt);
                        effmc   *= zmmSelEff_neg.getEff(mu1->eta, mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataSelEff_pos.getEff(mu2->eta, mu2->pt);
                        effmc   *= zmmSelEff_pos.getEff(mu2->eta, mu2->pt);
                    } else {
                        effdata *= dataSelEff_neg.getEff(mu2->eta, mu2->pt);
                        effmc   *= zmmSelEff_neg.getEff(mu2->eta, mu2->pt);
                    }
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataStaEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmStaEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                    } else {
                        effdata *= dataStaEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmStaEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataStaEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmStaEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                    } else {
                        effdata *= dataStaEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmStaEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                    }
                    corr *= effdata/effmc;

                    effdata=1;
                    effmc=1;
                    if(mu1->q>0) {
                        effdata *= dataTrkEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmTrkEff_pos.getEff(fabs(mu1->eta), mu1->pt);
                    } else {
                        effdata *= dataTrkEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                        effmc   *= zmmTrkEff_neg.getEff(fabs(mu1->eta), mu1->pt);
                    }
                    if(mu2->q>0) {
                        effdata *= dataTrkEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmTrkEff_pos.getEff(fabs(mu2->eta), mu2->pt);
                    } else {
                        effdata *= dataTrkEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                        effmc   *= zmmTrkEff_neg.getEff(fabs(mu2->eta), mu2->pt);
                    }
                    corr *= effdata/effmc;

                    nSelv[ifile]    +=weight;
                    nSelCorrv[ifile]+=weight*corr;
                }
            }
        }

        // compute acceptances
        accv.push_back(nSelv[ifile]/nEvtsv[ifile]);
        accErrv.push_back(accv[ifile]*sqrt((1.-accv[ifile])/nEvtsv[ifile]));
        accCorrv.push_back(nSelCorrv[ifile]/nEvtsv[ifile]);
        accCorrErrv.push_back(accCorrv[ifile]*sqrt((1.-accCorrv[ifile])/nEvtsv[ifile]));

        delete infile;
        infile=0, eventTree=0;
    }
    delete info;
    delete gen;
    delete muonArr;


    //--------------------------------------------------------------------------------------------------------------
    // Output
    //==============================================================================================================
    cout << "*" << endl;
    cout << "* SUMMARY" << endl;
    cout << "*--------------------------------------------------" << endl;
    cout << " Z -> mu mu" << endl;
    cout << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
    cout << "  pT > " << PT_CUT << endl;
    cout << "  |eta| < " << ETA_CUT << endl;
    cout << endl;

    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
        cout << "   ================================================" << endl;
        cout << "    Label: " << labelv[ifile] << endl;
        cout << "     File: " << fnamev[ifile] << endl;
        cout << endl;
        cout << "    *** Acceptance ***" << endl;
        cout << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
        cout << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
        cout << endl;
    }

    char txtfname[100];
    sprintf(txtfname,"%s/binned.txt",outputDir.Data());
    ofstream txtfile;
    txtfile.open(txtfname);
    txtfile << "*" << endl;
    txtfile << "* SUMMARY" << endl;
    txtfile << "*--------------------------------------------------" << endl;
    txtfile << " Z -> mu mu" << endl;
    txtfile << "  Mass window: [" << MASS_LOW << ", " << MASS_HIGH << "]" << endl;
    txtfile << "  pT > " << PT_CUT << endl;
    txtfile << "  |eta| < " << ETA_CUT << endl;
    txtfile << endl;

    for(UInt_t ifile=0; ifile<fnamev.size(); ifile++) {
        txtfile << "   ================================================" << endl;
        txtfile << "    Label: " << labelv[ifile] << endl;
        txtfile << "     File: " << fnamev[ifile] << endl;
        txtfile << endl;
        txtfile << "    *** Acceptance ***" << endl;
        txtfile << "          nominal: " << setw(12) << nSelv[ifile]   << " / " << nEvtsv[ifile] << " = " << accv[ifile]   << " +/- " << accErrv[ifile] << endl;
        txtfile << "     SF corrected: " << accCorrv[ifile] << " +/- " << accCorrErrv[ifile] << endl;
        txtfile << endl;
    }
    txtfile.close();

    cout << endl;
    cout << "  <> Output saved in " << outputDir << "/" << endl;
    cout << endl;

    gBenchmark->Show("computeAccSelZmmBinned");
}
float GetWeightFLminusFR(float x,float var,LorentzVector p4W, bool Wplus ){
  // variable x is cos(theta) here

  //  TH1F* h_polarization_Wplus[4][3];
  //  TH1F* h_polarization_Wminus[4][3];
  
  float pt_bins[5] = {50,100,300,500,10000};
  float eta_bins[4] = {0,1,2,5};

  //  TString bin_names_pt[4] = {"pt_50_100_","pt_100_300_","pt_300_500_","pt_500_up_"};
  //  TString bin_names_eta[3] = {"eta_0_1","eta_1_2","eta_2_5"};

  float fl_plus = 0;
  float fr_plus = 0;
  float f0_plus = 0;
  
  float fl_minus = 0;  
  float fr_minus = 0; 
  float f0_minus = 0;
  
  if ( H_polarization_Wplus[0]==0 || H_polarization_Wminus[0]==0 ) 
    LoadPolarizationHistograms();

  for(int i=0;i<4;i++){
    for(int ii=0;ii<3;ii++){
      if(p4W.Pt()>pt_bins[i]&&p4W.Pt()<pt_bins[i+1]&&fabs(p4W.Rapidity())>eta_bins[ii]&&fabs(p4W.Rapidity())<eta_bins[ii+1]){

	if(i==3&&ii==2){
	  //in highest rapidity and highest ptW bin do nothing because the statistics is lousy
	}
	else{
	  
	  if(Wplus){
	    fl_plus = H_polarization_Wplus[0]->GetBinContent(i,ii);
	    fr_plus = H_polarization_Wplus[1]->GetBinContent(i,ii);
	    //	    f0_plus = H_polarization_Wplus[2]->GetBinContent(i,ii);
	    f0_plus = 1-fl_plus-fr_plus;
	  }//end of Wplus
	  if(!Wplus){
	    fl_minus = H_polarization_Wminus[0]->GetBinContent(i,ii);
	    fr_minus = H_polarization_Wminus[1]->GetBinContent(i,ii);
	    //	    f0_minus = H_polarization_Wminus[2]->GetBinContent(i,ii);
	    f0_minus = 1-fl_minus-fr_minus;
	  }//end of Wminus
	}//end of requiring that last bin in helicity not be used 
      }//end of if statement for W pt and helicity
    }}//end of for loop




  float f0=0;
  float fl=0;
  float fr=0;
  float fl_variation = 0;
  float fr_variation = 0;
  float original_value = 0;
  float new_value = 0;
  if(Wplus){f0=f0_plus;fl=fl_plus;fr=fr_plus;    
    fl_variation = fl+(fl-fr)*var*0.01;
    fr_variation = fr-(fl-fr)*var*0.01;
    if(fl_variation>1||fr_variation<0){fl_variation=1-f0;fr_variation=0;}
    /*
    cout<<"W plus event"<<endl;
    cout<<"W pt: "<<p4W.Pt()<<endl;
    cout<<"W y:  "<<fabs(p4W.Rapidity())<<endl;
    cout<<"fl original: "<<fl<<", fl vary: "<<fl_variation<<endl;
    cout<<"fr original: "<<fr<<", fr vary: "<<fr_variation<<endl;
    cout<<"fo original: "<<f0<<endl;
    */
    original_value = f0*(1-x*x)+0.5*fl*(1-x)*(1-x)+0.5*fr*(1+x)*(1+x);
    new_value = f0*(1-x*x)+0.5*fl_variation*(1-x)*(1-x)+0.5*fr_variation*(1+x)*(1+x);
  }
  if(!Wplus){f0=f0_minus;fl=fl_minus;fr=fr_minus;
    fl_variation = fl+(fl-fr)*var*0.01;
    fr_variation = fr-(fl-fr)*var*0.01;    
    if(fl_variation>1||fr_variation<0){fl_variation=1-f0;fr_variation=0;}
    /*
    cout<<"W minus event"<<endl;
    cout<<"W pt: "<<p4W.Pt()<<endl;
    cout<<"W y:  "<<fabs(p4W.Rapidity())<<endl;
    cout<<"fl original: "<<fl<<", fl vary: "<<fl_variation<<endl;
    cout<<"fr original: "<<fr<<", fr vary: "<<fr_variation<<endl;
    cout<<"fo original: "<<f0<<endl;
    */
    original_value = f0*(1-x*x)+0.5*fr*(1-x)*(1-x)+0.5*fl*(1+x)*(1+x);
    new_value = f0*(1-x*x)+0.5*fr_variation*(1-x)*(1-x)+0.5*fl_variation*(1+x)*(1+x);
  }

  float w = 1;

  //  cout<<"original_value: "<<original_value<<endl;
  //  cout<<"new_value: "<<new_value<<endl;

  if((f0+fl+fr)!=0){
    if(original_value!=0){
      w = new_value/original_value; }
    else{cout<< "ERROR"<< endl; exit(1);}
  }

  //  cout<<"Weight is: "<<w<<endl;
  return w;

}