Beispiel #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
Beispiel #2
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