Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
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