analysisClass::analysisClass(string * inputList, string * cutFile, string * treeName, string * outputFileName, string * cutEfficFile)
  :baseClass(inputList, cutFile, treeName, outputFileName, cutEfficFile)
{
  std::cout << "analysisClass::analysisClass(): begins " << std::endl;

  //  std::string jetAlgo = getPreCutString1("jetAlgo");
  //  double rParam = getPreCutValue1("DeltaR");

  alphacut_ = getPreCutValue1("AlphaCut");
  DeltaR_ = getPreCutValue1("DeltaR");
  DeltaEtaJJ_ = getPreCutValue1("DeltaEtaJJ");
  MJJCut_ = getPreCutValue1("MJJCut");

  //  if( jetAlgo == "AntiKt" )
  //    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm, rParam) );
  //  else if( jetAlgo == "Kt" )
  //    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::kt_algorithm, rParam) );
  //  else 
  //    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::cambridge_algorithm, rParam) );
  
  std::cout << "analysisClass::analysisClass(): ends " << std::endl;
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

   //Combinations
   TH1F *h_Mej = new TH1F ("Mej","Mej",200,0,2000);  h_Mej->Sumw2();
   TH1F *h_probPt1stSc = new TH1F ("probPt1stSc","probPt1stSc",200,0,1000);  h_probPt1stSc->Sumw2();  //N events based on fake rate
   TH1F *h_matchedPt1stSc = new TH1F ("matchedPt1stSc","matchedPt1stSc",200,0,1000);  h_matchedPt1stSc->Sumw2();  //N events with at least 1 HEEP ele
   TH1F *h_probSt = new TH1F ("probSt","probSt",200,0,1000);  h_probSt->Sumw2();  //N events based on fake rate
   TH1F *h_matchedSt = new TH1F ("matchedSt","matchedSt",200,0,1000);  h_matchedSt->Sumw2();  //N events with at least 1 HEEP ele
   TH1F *h_NeleHEEP = new TH1F ("NeleHEEP","NeleHEEP",4,-0.5,3.5);  h_NeleHEEP->Sumw2();
   TH1F *h_NscISO = new TH1F ("NscISO","NscISO",4,-0.5,3.5);  h_NscISO->Sumw2();
   TH1F *h_dRsc = new TH1F ("dRsc","dRsc",500,-0.01,4.99); h_dRsc->Sumw2();
//    TH2F *h2_Mej_MTnuj_good = new TH2F ("h2_Mej_MTnuj_good","h2_Mej_MTnuj_good",100,0,2000,100,0,2000);  
//    TH2F *h2_Mej_MTnuj_bad = new TH2F ("h2_Mej_MTnuj_bad","h2_Mej_MTnuj_bad",100,0,2000,100,0,2000);  
   TH1F *h_goodEleSCPt = new TH1F ("goodEleSCPt","goodEleSCPt",200,0,1000); h_goodEleSCPt->Sumw2();
   TH1F *h_HEEPallEta = new TH1F ("HEEPallEta","HEEPallEta",100,-3.,3.); h_HEEPallEta->Sumw2();
   TH1F *h_HEEPallPt = new TH1F ("HEEPallPt","HEEPallPt",200,0,1000); h_HEEPallPt->Sumw2();
   TH1F *h_HEEP_2SC_Pt = new TH1F ("HEEP_2SC_Pt","HEEP_2SC_Pt",200,0,1000); h_HEEP_2SC_Pt->Sumw2();
   TH1F *h_HEEP_2SC2Jets_Pt = new TH1F ("HEEP_2SC2Jets_Pt","HEEP_2SC2Jets_Pt",200,0,1000); h_HEEP_2SC2Jets_Pt->Sumw2();
   TH1F *h_HEEP_St_Pt = new TH1F ("HEEP_St_Pt","HEEP_St_Pt",200,0,1000); h_HEEP_St_Pt->Sumw2();
   TH1F *h_HEEP_Mee_St_Pt = new TH1F ("HEEP_Mee_St_Pt","HEEP_Mee_St_Pt",200,0,1000); h_HEEP_Mee_St_Pt->Sumw2();
   TH1F *h_HEEP_Mee_St_Eta_Pt = new TH1F ("HEEP_Mee_St_Eta_Pt","HEEP_Mee_St_Eta_Pt",200,0,1000); h_HEEP_Mee_St_Eta_Pt->Sumw2();
   TH1F *h_HEEP_All_Pt = new TH1F ("HEEP_All_Pt","HEEP_All_Pt",200,0,1000); h_HEEP_All_Pt->Sumw2();
   TH1F *h_HEEP_PassMee_St = new TH1F ("HEEP_PassMee_St","HEEP_PassMee_St",200,0,1000); h_HEEP_PassMee_St->Sumw2();
   TH1F *h_HEEP_Mee_Pt = new TH1F ("HEEP_Mee_Pt","HEEP_Mee_Pt",200,0,1000); h_HEEP_Mee_Pt->Sumw2();
   TH1F *h_goodSCPt = new TH1F ("goodSCPt","goodSCPt",200,0,1000); h_goodSCPt->Sumw2();

   TH1F *h_goodEleSCPt_Barrel_2SC2Jets = new TH1F ("goodEleSCPt_Barrel_2SC2Jets","goodEleSCPt_Barrel_2SC2Jets",200,0,1000); h_goodEleSCPt_Barrel_2SC2Jets->Sumw2();
   TH1F *h_goodSCPt_Barrel_2SC2Jets = new TH1F ("goodSCPt_Barrel_2SC2Jets","goodSCPt_Barrel_2SC2Jets",200,0,1000); h_goodSCPt_Barrel_2SC2Jets->Sumw2();
   TH1F *h_goodEleSCPt_Barrel_2SC2Jets_JetEta = new TH1F ("goodEleSCPt_Barrel_2SC2Jets_JetEta","goodEleSCPt_Barrel_2SC2Jets_JetEta",200,0,1000); h_goodEleSCPt_Barrel_2SC2Jets_JetEta->Sumw2();
   TH1F *h_goodSCPt_Barrel_2SC2Jets_JetEta = new TH1F ("goodSCPt_Barrel_2SC2Jets_JetEta","goodSCPt_Barrel_2SC2Jets_JetEta",200,0,1000); h_goodSCPt_Barrel_2SC2Jets_JetEta->Sumw2();

   /////////initialize variables

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
   //for (Long64_t jentry=0; jentry<1000;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%10000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event


     //cout << "Electrons" << endl;

     //## Electrons
     vector<int> v_idx_ele_all;
     vector<int> v_idx_ele_PtCut;
     vector<int> v_idx_ele_PtCut_final;

     int eleIDType = getPreCutValue1("eleIDType");

    for(int iele=0;iele<eleCount;iele++)
       {

	 //no cut on reco electrons
	 v_idx_ele_all.push_back(iele);

	 //pT pre-cut on ele
	 if ( elePt[iele] < getPreCutValue1("ele_PtCut") ) continue;
	 
	 v_idx_ele_PtCut.push_back(iele);
	 

	 //ID + ISO + NO overlap with good muons	 	
	 int eleID = elePassID[iele];
	 if ( (eleID & 1<< eleIDType) > 0  && eleOverlaps[iele]==0 ) 
	   {
	     v_idx_ele_PtCut_final.push_back(iele);
	     h_HEEPallPt->Fill(elePt[iele]);
	     h_HEEPallEta->Fill(eleEta[iele]);
	   }
	 
       } //loop over electrons     
     

    //## Superclusters
    vector<int> v_idx_sc_all;
    vector<int> v_idx_sc_PtCut;
    vector<int> v_idx_sc_iso;
    bool matchHEEP = false;

     ///Find two highest Pt SC, since they are not ordered 
     float scHighestPt = -99;
     float scNextPt = -99;
     int idx_scHighestPt = -1;
     int idx_scNextPt = -1;
    for(int isc=0;isc<scCount;isc++){
      if ( scPt[isc] < getPreCutValue1("sc_PtCut") ) continue;
      if (scHoE[isc]>0.05) continue;
      if (scSigmaIEIE[isc]>0.0275) continue;
      double scEt = scPt[isc];
      if (scHEEPEcalIso[isc]> (6+(0.01*scEt))) continue;
      if (fabs(scEta[isc])<1.44 && scHEEPTrkIso[isc]>7.5) continue;;
      if (fabs(scEta[isc])>1.56 && scHEEPTrkIso[isc]>15) continue;
      if (scPt[isc]<scNextPt){
	scNextPt = scPt[isc];
	idx_scNextPt = isc;
      }
      if (scPt[isc]<scHighestPt){
	scNextPt = scHighestPt;
	idx_scNextPt = idx_scNextPt;
	scHighestPt = scPt[isc];
	idx_scHighestPt = isc;
      }
    }
    if (idx_scHighestPt != -1) v_idx_sc_iso.push_back(idx_scHighestPt);
    if (idx_scNextPt != -1) v_idx_sc_iso.push_back(idx_scNextPt);

    //////now fill in the rest of the sc in whatever order they are
    for(int isc=0;isc<scCount;isc++){
      if (isc==idx_scHighestPt || isc==idx_scNextPt) continue;
      if ( scPt[isc] < getPreCutValue1("sc_PtCut") ) continue;
      bool scPassHoE= false;
      bool scPassSigmaEE= false;
      bool scPassEcalIso= false;
      bool scPassTrkIso= false;
      if (scHoE[isc]<0.05) scPassHoE=true;
      if (scSigmaIEIE[isc]<0.0275) scPassSigmaEE=true;
      double scEt = scPt[isc];
      if (scHEEPEcalIso[isc]< (6+(0.01*scEt))) scPassEcalIso = true;
      if (fabs(scEta[isc])<1.44 && scHEEPTrkIso[isc]<7.5) scPassTrkIso = true;
      if (fabs(scEta[isc])>1.56 && scHEEPTrkIso[isc]<15) scPassTrkIso = true;
      if (scPassHoE && scPassSigmaEE && scPassEcalIso && scPassTrkIso ){
	v_idx_sc_iso.push_back(isc);
      }
    }


     //## Jets
     vector<int> v_idx_jet_all;
     vector<int> v_idx_jet_PtCut;
     vector<int> v_idx_jet_PtCut_noOverlapSC;
     for(int ijet=0;ijet<caloJetCount;ijet++)
       {

	 //no cut on reco jets
	 v_idx_jet_all.push_back(ijet);

	 //pT pre-cut on reco jets
	 if ( caloJetPt[ijet] < getPreCutValue1("jet_PtCut") ) continue;

	 v_idx_jet_PtCut.push_back(ijet);

	 ///// take the iso SC out of the jet collection
	 TVector3 jet_vec;
	 jet_vec.SetPtEtaPhi(caloJetPt[ijet],caloJetEta[ijet],caloJetPhi[ijet]);
	 float minDRsc = 99;
	 int idx_nearest_sc = -1;
	 for(int isc=0;isc<v_idx_sc_iso.size();isc++)
	     {
	       TVector3 sc_vec;
	       sc_vec.SetPtEtaPhi(scPt[v_idx_sc_iso[isc]],
			   scEta[v_idx_sc_iso[isc]],
			   scPhi[v_idx_sc_iso[isc]]);
	       float DR = jet_vec.DeltaR(sc_vec);
	       if (DR<minDRsc) {
		 minDRsc = DR;
		 idx_nearest_sc = isc;
	       }
	     }

	 //pT pre-cut + no overlaps with electrons or SC
	 if( ( caloJetOverlaps[ijet] & 1 << eleIDType) == 0  && minDRsc>0.5)/* NO overlap with electrons or SC */  
	   v_idx_jet_PtCut_noOverlapSC.push_back(ijet);

       }     


     // Set the evaluation of the cuts to false and clear the variable values and filled status
     resetCuts();
     
     // Set the value of the variableNames listed in the cutFile to their current value


     //## nEle
     fillVariableWithValue( "nSc_PtCut_Iso", v_idx_sc_iso.size() ) ;

     //cout << "nJet" << endl;

     //## nJet
     fillVariableWithValue( "nJet_PtCut_noOvrlpEle", v_idx_jet_PtCut_noOverlapSC.size() ) ;


     //cout << "1st Ele" << endl;
     //## 1st ele
     double MT=-999;
     if( v_idx_sc_iso.size() >= 1 ) 
       {
	 fillVariableWithValue( "Pt1stSc_Iso", scPt[v_idx_sc_iso[0]] );
	 fillVariableWithValue( "mEta1stSc_Iso", fabs(scEta[v_idx_sc_iso[0]]) );
       }

      if( v_idx_sc_iso.size() >= 2 ) 
       {
	 fillVariableWithValue( "Pt2ndSc_Iso", scPt[v_idx_sc_iso[1]] );
	 fillVariableWithValue( "mEta2ndSc_Iso", fabs(scEta[v_idx_sc_iso[1]]) );
       }

    //cout << "1st Jet" << endl;
     //## 1st jet
     if( v_idx_jet_PtCut_noOverlapSC.size() >= 1 ) 
       {
	 fillVariableWithValue( "Pt1stJet_noOvrlpEle", caloJetPt[v_idx_jet_PtCut_noOverlapSC[0]] );
	 fillVariableWithValue( "mEta1stJet_noOvrlpEle", fabs(caloJetEta[v_idx_jet_PtCut_noOverlapSC[0]]) );
       }


     //cout << "2nd Jet" << endl;
     //## 2nd jet
     if( v_idx_jet_PtCut_noOverlapSC.size() >= 2 ) 
       {
	 fillVariableWithValue( "Pt2ndJet_noOvrlpEle", caloJetPt[v_idx_jet_PtCut_noOverlapSC[1]] );
	 fillVariableWithValue( "mEta2ndJet_noOvrlpEle", fabs(caloJetEta[v_idx_jet_PtCut_noOverlapSC[1]]) );
       }

     //## define "2ele" and "2jets" booleans
     bool TwoSc=false;
     bool TwoJets=false;
     if( v_idx_sc_iso.size() >= 2 ) TwoSc = true;
     if( v_idx_jet_PtCut_noOverlapSC.size() >= 2 ) TwoJets = true;

     //cout << "Mee" << endl;

     double MassEE = -99;
     if (TwoSc)
       {
 	 TLorentzVector sc1, sc2, ee;
	 sc1.SetPtEtaPhiM(scPt[v_idx_sc_iso[0]],
			   scEta[v_idx_sc_iso[0]],
			   scPhi[v_idx_sc_iso[0]],0);
	 sc2.SetPtEtaPhiM(scPt[v_idx_sc_iso[1]],
			   scEta[v_idx_sc_iso[1]],
			   scPhi[v_idx_sc_iso[1]],0);
	 ee = sc1+sc2;
	 fillVariableWithValue("Mee", ee.M());
	 MassEE = ee.M();

	 double sc_deltaR = sc1.DeltaR(sc2);
	 h_dRsc->Fill(sc_deltaR);
       }

     //cout << "ST" << endl;

     //## ST
     double calc_sT=-999.; 
     if ( (TwoSc) && (TwoJets) ) 
       {
	 calc_sT = 
	   scPt[v_idx_sc_iso[0]]
	   + scPt[v_idx_sc_iso[1]]
	   + caloJetPt[v_idx_jet_PtCut_noOverlapSC[0]]
	   + caloJetPt[v_idx_jet_PtCut_noOverlapSC[1]];
	 fillVariableWithValue("sT", calc_sT);

       }


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

     // Fill histograms and do analysis based on cut evaluation
     for (int iele=0; iele<v_idx_ele_PtCut_final.size(); iele++){
       if (fabs(eleSCEta[v_idx_ele_PtCut_final[iele]])<1.45 && TwoSc && TwoJets) {
	       h_goodEleSCPt_Barrel_2SC2Jets->Fill(eleSCPt[v_idx_ele_PtCut_final[iele]]);
	       if (passedCut("mEta1stJet_noOvrlpEle") && passedCut ("mEta2ndJet_noOvrlpEle") )
		 h_goodEleSCPt_Barrel_2SC2Jets_JetEta->Fill(eleSCPt[v_idx_ele_PtCut_final[iele]]);
	     }

       if ( passedCut("nSc_PtCut_Iso") && passedCut("mEta1stSc_Iso") && passedCut("mEta2ndSc_Iso") ){
	   h_HEEP_2SC_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
	   if ( passedCut("nJet_PtCut_noOvrlpEle") && passedCut("mEta1stJet_noOvrlpEle") && passedCut ("mEta2ndJet_noOvrlpEle") ) {
	     h_HEEP_2SC2Jets_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
	     if ( passedCut("Mee") ){
	       h_HEEP_Mee_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
	       h_HEEP_PassMee_St->Fill(calc_sT);
	       if ( passedCut("sT") )
		 h_HEEP_Mee_St_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
	     }
	   }
       }

     for(int isc=0;isc<v_idx_sc_iso.size();isc++)
	   {
	     if (fabs(scEta[v_idx_sc_iso[isc]])<1.45 && TwoSc && TwoJets) {
	       h_goodSCPt_Barrel_2SC2Jets->Fill(scPt[v_idx_sc_iso[isc]]);
	       if (passedCut("mEta1stJet_noOvrlpEle") && passedCut ("mEta2ndJet_noOvrlpEle") )
		 h_goodSCPt_Barrel_2SC2Jets_JetEta->Fill(scPt[v_idx_sc_iso[isc]]);
	     }
	   }


     if ( passedCut("sT") )
	       h_HEEP_St_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
     }

     if( passedCut("all") ) 
       {
	 for (int iele=0; iele<v_idx_ele_PtCut_final.size(); iele++){
	   h_HEEP_All_Pt->Fill(elePt[v_idx_ele_PtCut_final[iele]]);
	   h_matchedPt1stSc->Fill(eleSCPt[v_idx_ele_PtCut_final[iele]]);
	   h_matchedSt->Fill(calc_sT);
	 }

	 h_NeleHEEP->Fill(v_idx_ele_PtCut_final.size());
	 h_NscISO->Fill(v_idx_sc_iso.size());

	 double probSC1 = 0, probSC2 = 0;
	 double BarrelCross = -0.001437;
	 double BarrelSlope = 0.000104;
	 double EndcapCross = 0.014;
	 double EndcapSlope = 0.000283;

	 if (fabs(scEta[v_idx_sc_iso[0]])<1.442) probSC1 = BarrelCross + BarrelSlope*scPt[v_idx_sc_iso[0]];
	 if (fabs(scEta[v_idx_sc_iso[0]])>1.56) probSC1 = EndcapCross + EndcapSlope*scPt[v_idx_sc_iso[0]] ;
	 if (fabs(scEta[v_idx_sc_iso[1]])<1.442) probSC2 = BarrelCross + BarrelSlope*scPt[v_idx_sc_iso[1]];
	 if (fabs(scEta[v_idx_sc_iso[1]])>1.56) probSC2 = EndcapCross + EndcapSlope*scPt[v_idx_sc_iso[1]];
      
	 h_probPt1stSc->Fill(scPt[v_idx_sc_iso[0]],probSC1+probSC2);
	 h_probSt->Fill(calc_sT,probSC1+probSC2);


	 ///////Calculate FakeRate based on events that pass

	 for (int iele=0; iele<v_idx_ele_PtCut_final.size(); iele++)
	   {
	     h_goodEleSCPt->Fill(eleSCPt[v_idx_ele_PtCut_final[iele]]);
	   }

	 for(int isc=0;isc<v_idx_sc_iso.size();isc++){
	   h_goodSCPt->Fill(scPt[v_idx_sc_iso[isc]]);
	 }

       }  //end if passedCut("all")


     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

   //////////write histos 
   h_Mej->Write();
   h_probPt1stSc->Write();
   h_matchedPt1stSc->Write();
   h_probSt->Write();
   h_matchedSt->Write();
   h_NeleHEEP->Write();
   h_NscISO->Write();
   h_dRsc->Write();
//    h2_Mej_MTnuj_good->Write();
//    h2_Mej_MTnuj_bad->Write();
   h_HEEPallPt->Write();
   h_HEEP_2SC_Pt->Write();
   h_HEEP_2SC2Jets_Pt->Write();
   h_HEEP_Mee_Pt->Write();
   h_HEEP_Mee_St_Pt->Write();
   h_HEEP_Mee_St_Eta_Pt->Write();
   h_HEEP_All_Pt->Write();
   h_HEEP_St_Pt->Write();
   h_HEEP_PassMee_St->Write();
   h_HEEPallEta->Write();
   h_goodEleSCPt->Write();
   h_goodSCPt->Write();

   h_goodEleSCPt_Barrel_2SC2Jets->Write();
   h_goodSCPt_Barrel_2SC2Jets->Write();
   h_goodEleSCPt_Barrel_2SC2Jets_JetEta->Write();
   h_goodSCPt_Barrel_2SC2Jets_JetEta->Write();


   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");

  if (fChain == 0) return;

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Get all Pre-cut values!
   *
   *
   *
   *///-----------------------------------------------------------------
  
   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 ( !true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

  //-----------------------------------------------------------------
  // Electron cut values
  //-----------------------------------------------------------------
  
  double ele_PtCut_STORE = getPreCutValue2("ele_PtCut");
  double ele_PtCut_ANA   = getPreCutValue1("ele_PtCut");
  
  double eleEta_bar      = getPreCutValue1("eleEta_bar");
  double eleEta_end_min  = getPreCutValue1("eleEta_end");
  double eleEta_end_max  = getPreCutValue2("eleEta_end");
  
  if ( ele_PtCut_STORE > ele_PtCut_ANA ) {
    STDOUT("ERROR in Electron cut values: all storage cuts must be looser or equal to analysis cuts.");
    exit(0) ;
  }

  // For WP80

  double eleMissingHitsWP             = getPreCutValue1("eleMissingHitsWP"        );
  double eleDistWP                    = getPreCutValue1("eleDistWP"               );
  double eleDCotThetaWP               = getPreCutValue1("eleDCotThetaWP"          );
  double eleCombRelIsoWP_bar          = getPreCutValue1("eleCombRelIsoWP"         );
  double eleCombRelIsoWP_end          = getPreCutValue2("eleCombRelIsoWP"         );
  double eleSigmaIetaIetaWP_bar       = getPreCutValue1("eleSigmaIetaIetaWP"      );
  double eleSigmaIetaIetaWP_end       = getPreCutValue2("eleSigmaIetaIetaWP"      );
  double eleDeltaPhiTrkSCWP_bar       = getPreCutValue1("eleDeltaPhiTrkSCWP"      );
  double eleDeltaPhiTrkSCWP_end       = getPreCutValue2("eleDeltaPhiTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_bar       = getPreCutValue1("eleDeltaEtaTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_end       = getPreCutValue2("eleDeltaEtaTrkSCWP"      );
  double eleUseEcalDrivenWP           = getPreCutValue1("eleUseEcalDrivenWP"      );
  double eleUseHasMatchConvWP         = getPreCutValue1("eleUseHasMatchConvWP"    );

  // For HEEP 3.1

  double eleDeltaEtaTrkSCHeep_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaEtaTrkSCHeep_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep"    );
  double eleHoEHeep_bar               = getPreCutValue1("eleHoEHeep"              );
  double eleHoEHeep_end               = getPreCutValue2("eleHoEHeep"              );
  double eleE2x5OverE5x5Heep_bar      = getPreCutValue1("eleE2x5OverE5x5Heep"     );
  double eleE1x5OverE5x5Heep_bar      = getPreCutValue1("eleE1x5OverE5x5Heep"     );
  double eleSigmaIetaIetaHeep_end     = getPreCutValue2("eleSigmaIetaIetaHeep"    );
  double eleEcalHcalIsoHeep_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_1_end     = getPreCutValue3("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_end     = getPreCutValue4("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep_PTthr");
  double eleHcalIsoD2Heep_end         = getPreCutValue2("eleHcalIsoD2Heep"        );
  double eleTrkIsoHeep_bar            = getPreCutValue1("eleTrkIsoHeep"           );
  double eleTrkIsoHeep_end            = getPreCutValue2("eleTrkIsoHeep"           );
  double eleMissingHitsHeep           = getPreCutValue1("eleMissingHitsHeep"      );
  double eleUseEcalDrivenHeep         = getPreCutValue1("eleUseEcalDrivenHeep"    );

  // For HEEP 3.2

  double eleDeltaEtaTrkSCHeep32_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaEtaTrkSCHeep32_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep32"    );
  double eleHoEHeep32_bar               = getPreCutValue1("eleHoEHeep32"              );
  double eleHoEHeep32_end               = getPreCutValue2("eleHoEHeep32"              );
  double eleE2x5OverE5x5Heep32_bar      = getPreCutValue1("eleE2x5OverE5x5Heep32"     );
  double eleE1x5OverE5x5Heep32_bar      = getPreCutValue1("eleE1x5OverE5x5Heep32"     );
  double eleSigmaIetaIetaHeep32_end     = getPreCutValue2("eleSigmaIetaIetaHeep32"    );
  double eleEcalHcalIsoHeep32_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_1_end     = getPreCutValue3("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_end     = getPreCutValue4("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep32_PTthr");
  //double eleHcalIsoD2Heep32_end         = getPreCutValue2("eleHcalIsoD2Heep32"        );
  double eleTrkIsoHeep32_bar            = getPreCutValue1("eleTrkIsoHeep32"           );
  double eleTrkIsoHeep32_end            = getPreCutValue2("eleTrkIsoHeep32"           );
  double eleMissingHitsHeep32           = getPreCutValue1("eleMissingHitsHeep32"      );
  double eleUseEcalDrivenHeep32         = getPreCutValue1("eleUseEcalDrivenHeep32"    );

  CreateUserTH1D("dphi_met_ele", 100, 0, 3.14159 );

  //-----------------------------------------------------------------
  // Which algorithms to use?
  //-----------------------------------------------------------------

  int    eleAlgorithm = (int) getPreCutValue1("eleAlgorithm");

  //-----------------------------------------------------------------
  // Counters
  //-----------------------------------------------------------------

  int n_photon30__160404_163869 = 0;
  int n_photon30_HEEP__160404_163869 = 0;
  int n_photon30_HEEP_ele27__160404_163869 = 0;
  double eff_eleIDIso__160404_163869 = 0.;

  //## Maps 
  // first  = key   = RunNumber 
  // second = value = NumberOfEvents 
  map<int, int> MapTrg; 
  map<int, int> MapDen; 
  map<int, int> MapNum;
  map<int, int> MapNumErrSquare;
    
  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Start analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------


  Long64_t nentries = fChain->GetEntries();
  //Long64_t nentries = 200000;
  STDOUT("analysisClass::Loop(): nentries = " << nentries);

  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry << "/" << nentries );
    
    //-----------------------------------------------------------------
    // Do pileup re-weighting, if necessary
    //  --> To be done after the skim, so commented out for now
    //-----------------------------------------------------------------
    
    // double event_weight = getPileupWeight ( PileUpInteractions, isData ) ;
    
    //-----------------------------------------------------------------
    // Get trigger information, if necessary
    //-----------------------------------------------------------------

    if ( isData ) { 
      getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ;
    }
    
    //-----------------------------------------------------------------
    // Selection: Electrons
    //-----------------------------------------------------------------    

    vector<int> v_idx_ele_PtCut_IDISO_STORE;
    vector<int> v_idx_ele_PtCut_IDISO_ANA;
    vector<int> v_idx_ele_IDISO;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++){
      
      int passEleSel = 0;
      int isBarrel = 0;
      int isEndcap = 0;
      
      if( fabs( ElectronSCEta->at(iele) ) < eleEta_bar )       isBarrel = 1;
      if( fabs( ElectronSCEta->at(iele) ) > eleEta_end_min &&
	  fabs( ElectronSCEta->at(iele) ) < eleEta_end_max )   isEndcap = 1;

      //-----------------------------------------------------------------    
      // HEEP ID application 3.1
      //-----------------------------------------------------------------    

      if ( eleAlgorithm == 1 ) { 
	
	if(isBarrel) {		

	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep_1_bar + eleEcalHcalIsoHeep_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end+eleEcalHcalIsoHeep_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_end 
	     && ElectronHoE->at(iele) < eleHoEHeep_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep_end 
	     && passEcalHcalIsoCut == 1
	     && ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }

      //-----------------------------------------------------------------    
      // WP80 ID application
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 2 ) { 
	// ecal driven	    
	if( eleUseEcalDrivenWP && !ElectronHasEcalDrivenSeed->at(iele) ) continue;
	
	// isolation
	double ElectronCombRelIsoWP_bar  =  ( ElectronTrkIsoDR03->at(iele) 
					    + max( 0., ElectronEcalIsoDR03->at(iele) - 1. ) 
					    + ElectronHcalIsoDR03FullCone->at(iele) 
					    - rhoIso*TMath::Pi()*0.3*0.3 
					    ) / ElectronPt->at(iele) ;
	
	double ElectronCombRelIsoWP_end  =  ( ElectronTrkIsoDR03->at(iele) 
					      + ElectronEcalIsoDR03->at(iele) 
					      + ElectronHcalIsoDR03FullCone->at(iele) 
					      - rhoIso*TMath::Pi()*0.3*0.3 
					      ) / ElectronPt->at(iele) ;
	
	// conversions
	int isPhotConv = 0;
	if(eleUseHasMatchConvWP) {
	  if( ElectronHasMatchedConvPhot->at(iele) ) 
	    isPhotConv = 1;
	}
	else {
	  if( ElectronDist->at(iele) < eleDistWP && ElectronDCotTheta->at(iele) < eleDCotThetaWP )	
	    isPhotConv = 1;
	}

	if(isBarrel) {
	  
	  if( ElectronMissingHits->at(iele) <= eleMissingHitsWP              && 
	      isPhotConv == 0					             && 
	      ElectronCombRelIsoWP_bar < eleCombRelIsoWP_bar		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_bar       && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_bar && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_bar  )
	    passEleSel = 1;		
	  
	}//end barrel
	
	if(isEndcap) {		
	    
	  if( ElectronMissingHits->at(iele) == eleMissingHitsWP              && 
	      isPhotConv == 0						     && 
	      ElectronCombRelIsoWP_end < eleCombRelIsoWP_end		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_end 	     && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_end && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_end  )
	    passEleSel = 1;		
	  
	}//end endcap	
      }

      //-----------------------------------------------------------------    
      // HEEP ID application 3.2
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 3 ) { 
	
	if(isBarrel) {
		
	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep32_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep32_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep32_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep32_1_bar + eleEcalHcalIsoHeep32_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep32_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end+eleEcalHcalIsoHeep32_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep32_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_end 
	     && ElectronHoE->at(iele) < eleHoEHeep32_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep32_end 
	     && passEcalHcalIsoCut == 1
	     //&& ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep32_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep32_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }
      
      if ( passEleSel ) { 
	v_idx_ele_IDISO.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_STORE ) v_idx_ele_PtCut_IDISO_STORE.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_ANA   ) v_idx_ele_PtCut_IDISO_ANA  .push_back ( iele ) ;
      }

    }
    
    //-----------------------------------------------------------------
    // Fill your single-object variables with values
    //-----------------------------------------------------------------

    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    
    fillVariableWithValue( "PassJSON", passJSON(run, ls, isData) );    
    // Set the value of the variableNames listed in the cutFile to their current value

    //event info
    fillVariableWithValue( "isData"   , isData     ) ;
    fillVariableWithValue( "bunch"    , bunch      ) ;
    fillVariableWithValue( "event"    , event      ) ;
    fillVariableWithValue( "ls"       , ls         ) ;
    fillVariableWithValue( "orbit"    , orbit      ) ;
    fillVariableWithValue( "run"      , run        ) ;

    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;
      }
    //triggerFired ("HLT_Photon30_CaloIdVL_v1")

    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    fillVariableWithValue( "PassHBHENoiseFilter", passHBHENoiseFilter ) ;
    fillVariableWithValue( "PassBeamHaloFilterLoose", passBeamHaloFilterLoose ) ;
    fillVariableWithValue( "PassBeamHaloFilterTight", passBeamHaloFilterTight ) ;
    fillVariableWithValue( "PassTrackingFailure", !isTrackingFailure ) ;
    fillVariableWithValue( "PassCaloBoundaryDRFilter", passCaloBoundaryDRFilter ) ;
    fillVariableWithValue( "PassEcalMaskedCellDRFilter", passEcalMaskedCellDRFilter ) ;
    
    // Evaluate cuts (but do not apply them)
    evaluateCuts();

    double met = PFMET -> at(0);
    double met_phi = PFMETPhi -> at(0);

    //Basic Event Selection
    if( passedCut("PassJSON") 
	&& passedCut("PassBPTX0") 
	&& passedCut("PassBeamScraping") 
	&& passedCut("PassPrimaryVertex")
	&& passedCut("PassHBHENoiseFilter")
	&& passedCut("PassBeamHaloFilterTight") 
	)
      {      

	//### Fill Maps (full run range)
	
	if( triggerFired ("HLT_Photon30_CaloIdVL_v1") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v2") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v3") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v4") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v5") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v6") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v7") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v8") 
	    )
	  {
	
	    map<int,int>::iterator MapTrgIt = MapTrg.find(run);
	    map<int,int>::iterator MapTrgItEnd = MapTrg.end();
	    if( MapTrgIt == MapTrgItEnd )
	      {
		MapTrg.insert(pair<int,int>(run,1));
		//MapDen[run]=1;
	      }
	    else
	      MapTrgIt->second++;

	    TLorentzVector my_v_met, my_ele;
	    double my_delta_phi;
	    my_v_met.SetPtEtaPhiM ( met, 0.0, met_phi, 0.0);
	    
	    if( v_idx_ele_PtCut_IDISO_ANA.size()==1){
	      my_ele.SetPtEtaPhiM ( ElectronPt  -> at (v_idx_ele_PtCut_IDISO_ANA[0]),
				    ElectronEta -> at (v_idx_ele_PtCut_IDISO_ANA[0]),
				    ElectronPhi -> at (v_idx_ele_PtCut_IDISO_ANA[0]),
				    0.0 );
	      my_delta_phi = fabs(my_v_met.DeltaPhi ( my_ele ) );
	    }

	    
	    if( v_idx_ele_PtCut_IDISO_ANA.size()==1 && met > 30.0 && my_delta_phi > 2.5 )
	      {
		//denominator
		map<int,int>::iterator MapDenIt = MapDen.find(run);
		map<int,int>::iterator MapDenItEnd = MapDen.end();

		FillUserTH1D("dphi_met_ele", my_delta_phi );
		

		if( MapDenIt == MapDenItEnd )
		  {
		    MapDen.insert(pair<int,int>(run,1));
		    //MapDen[run]=1;
		  }
		else
		  MapDenIt->second++;

		CreateAndFillUserTH1D("ElePt_AfterPhoton30", 100, 0, 1000, ElectronPt -> at (v_idx_ele_PtCut_IDISO_ANA[0]) );
		CreateAndFillUserTH1D("MET_AfterPhoton30", 100, 0, 1000, PFMET->at(0) );

		//numerator
		map<int,int>::iterator MapNumIt = MapNum.find(run);
		map<int,int>::iterator MapNumErrSquareIt = MapNumErrSquare.find(run);
		map<int,int>::iterator MapNumItEnd = MapNum.end();

		//-- 160404-161176
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1"),2);
		      }
		  }

		//-- 161216-163261
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2"),2);
		      }
		  }

		//-- 163269-163869
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3"),2);
		      }
		  }

		//-- 165088-165633
		if( triggerFired ("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3"),2);
		      }
		  }

		//-- 165970-166967
		if( triggerFired ("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4"),2);
		      }
		  }

		//-- 167039-167913
		if( triggerFired ("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5"),2);
		      }
		  }

		//-- 170249-173198
		if( triggerFired ("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6"),2);
		      }
		  }

		//-- 173236-178380
		if( triggerFired ("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7"),2);
		      }
		  }

		//-- 178420-179889
		if( triggerFired ("HLT_Ele27_WP80_v2") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele27_WP80_v2") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele27_WP80_v2"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele27_WP80_v2");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele27_WP80_v2"),2);
		      }
		  }

		//-- 179959-180252
		if( triggerFired ("HLT_Ele27_WP80_v3") )
		  {
		    if( MapNumIt == MapNumItEnd )
		      {
			MapNum.insert(pair<int,int>( run , triggerPrescale("HLT_Ele27_WP80_v3") ));
			//MapNum[run]=1;
			MapNumErrSquare.insert(pair<int,int>( run , pow(triggerPrescale("HLT_Ele27_WP80_v3"),2) ));
		      }
		    else
		      {
			MapNumIt->second += triggerPrescale("HLT_Ele27_WP80_v3");
			MapNumErrSquareIt->second += pow(triggerPrescale("HLT_Ele27_WP80_v3"),2);
		      }
		  }

		// HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1    160404-161176
		// HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2    161216-163261
		// (HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1)  161216-163261
		// HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3    163269-163869
		// (HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2)  163269-163869
		// HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3    165088-165633
		// HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v4    165970-166967
		// HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v5    167039-167913
		// HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v6    170249-173198
		// HLT_Ele32_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v7    173236-178380
		// HLT_Ele27_WP80_v2				 178420-179889
		// HLT_Ele27_WP80_v3				 179959-180252

	      }//end 1 HEEP requirement

	  }//end photon trigger fired
	//###

	//### run range: 160404-163869 (TEST)
	if( triggerFired ("HLT_Photon30_CaloIdVL_v1") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v2") 
	    || triggerFired ("HLT_Photon30_CaloIdVL_v3") 
	    )
	  {
	    n_photon30__160404_163869++;
	    
	    if( v_idx_ele_PtCut_IDISO_ANA.size()==1 )
	      {
		//denominator
		n_photon30_HEEP__160404_163869++; 	
		CreateAndFillUserTH1D("ElePt_AfterPhoton30__160404_163869", 100, 0, 1000, ElectronPt -> at (v_idx_ele_PtCut_IDISO_ANA[0]) );
		
		//numerator
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1") )
		  n_photon30_HEEP_ele27__160404_163869 += triggerPrescale ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v1" ); 
		
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2") )
		  n_photon30_HEEP_ele27__160404_163869 += triggerPrescale ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v2" ); 
		
		if( triggerFired ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3") )
		  n_photon30_HEEP_ele27__160404_163869 += triggerPrescale ("HLT_Ele27_CaloIdVT_CaloIsoT_TrkIdT_TrkIsoT_v3" ); 
	      }//end 1 HEEP requirement
	  }//end photon trigger fired
	//###

      }//end Basic Event Selection


  } // End of loop over events

  //##################################################

  //## Printout (test)
  cout << "---- Test : run range = 160404-163869 ----" << endl;

  eff_eleIDIso__160404_163869 = double(n_photon30_HEEP_ele27__160404_163869) / double(n_photon30_HEEP__160404_163869);

  cout << "n_photon30__160404_163869: " << n_photon30__160404_163869 << endl;
  cout << "n_photon30_HEEP__160404_163869: " << n_photon30_HEEP__160404_163869 << endl;
  cout << "n_photon30_HEEP_ele27__160404_163869: " << n_photon30_HEEP_ele27__160404_163869 << endl;
  cout << "eff_eleIDIso__160404_163869: " << eff_eleIDIso__160404_163869 << endl;
  cout << endl;

  //## Printout (final results)
  cout << "---- Final Results (full run range) ----" << endl;

  map<int,int>::iterator MapTrgIt = MapTrg.begin();
  map<int,int>::iterator MapTrgItEnd = MapTrg.end();
  int sumTrg = 0 ;
  //   FILE * pFileTrg;
  //   pFileTrg = fopen ("MapTrg.txt","w");
  for(;MapTrgIt!=MapTrgItEnd;++MapTrgIt)
    {
      //cout << "run , N : " << MapTrgIt->first << " " << MapTrgIt->second << endl;
      sumTrg += MapTrgIt->second;
      cout << "MAPTRG: " << MapTrgIt->first << " " << MapTrgIt->second << " " << sqrt(MapTrgIt->second) << endl;
      //fprintf (pFileTrg, "%d %d %f\n",MapTrgIt->first,MapTrgIt->second,sqrt(MapTrgIt->second));
    }
  //fclose (pFileTrg);

  map<int,int>::iterator MapDenIt = MapDen.begin();
  map<int,int>::iterator MapDenItEnd = MapDen.end();
  int sumDen = 0 ;
  //   FILE * pFileDen;
  //   pFileDen = fopen ("MapDen.txt","w");
  for(;MapDenIt!=MapDenItEnd;++MapDenIt)
    {
      //cout << "run , N : " << MapDenIt->first << " " << MapDenIt->second << endl;
      sumDen += MapDenIt->second;
      cout << "MAPDEN: " << MapDenIt->first << " " << MapDenIt->second << " " << sqrt(MapDenIt->second) << endl;
      //fprintf (pFileDen, "%d %d %f\n",MapDenIt->first,MapDenIt->second,sqrt(MapDenIt->second));
    }
  //fclose (pFileDen);

  map<int,int>::iterator MapNumIt = MapNum.begin();
  map<int,int>::iterator MapNumErrSquareIt = MapNumErrSquare.begin();
  map<int,int>::iterator MapNumItEnd = MapNum.end();
  int sumNum = 0 ;
  float sumNumErrSquare = 0. ;
  //   FILE * pFileNum;
  //   pFileNum = fopen ("MapNum.txt","w");
  for(;MapNumIt!=MapNumItEnd;++MapNumIt)
    {            
      //cout << "run , N : " << MapNumIt->first << " " << MapNumIt->second << endl;
      sumNum += MapNumIt->second;
      sumNumErrSquare += MapNumErrSquareIt->second;
      cout << "MAPNUM: " << MapNumIt->first << " " << MapNumIt->second << " " << sqrt(MapNumErrSquareIt->second) << endl;
      //fprintf (pFileNum, "%d %d %f\n",MapNumIt->first,MapNumIt->second,sqrt(MapNumErrSquareIt->second));
      ++MapNumErrSquareIt;
    }
  //fclose (pFileNum);

  double eff = double(sumNum) / double(sumDen);

  cout << "sumTrg : " << sumTrg << endl;
  cout << "sumDen : " << sumDen << endl;
  cout << "sumNum +/- err: " << sumNum << " +/- " << sqrt(sumNumErrSquare) << endl;
  cout << "eff : "    << eff    << endl; 

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      End analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------

  STDOUT("analysisClass::Loop() ends");
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 (  true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Pileup reweighting initialization
   //--------------------------------------------------------------------------

   // Lumi3DReWeighting lumiWeights = Lumi3DReWeighting("/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_MC_Summer11_PU_S4_3DReweighting.root",
   // 						     "/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_finebin_2011_finebin.root",
   // 						     "pileup", "pileup");
   // lumiWeights.weight3D_init(1.0);

   //--------------------------------------------------------------------------
   // Any extra features
   //--------------------------------------------------------------------------
   
   TProfile * profile_run_vs_nvtx_HLT = new TProfile("run_vs_nvtx_HLT", "", 20000 , 160300  , 180300 );
   TProfile * profile_run_vs_nvtx_PAS = new TProfile("run_vs_nvtx_PAS", "", 20000 , 160300  , 180300 );
   
   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar_max = getPreCutValue1("eleEta_bar");
   double eleEta_end_min = getPreCutValue1("eleEta_end1");
   double eleEta_end_max = getPreCutValue2("eleEta_end2");

   // dataset
   
   int dataset  = getPreCutValue1("dataset") ;
   bool select2011A = ( dataset == 0 );
   bool select2011B = ( dataset == 1 );
   bool select2011  = ( dataset == 2 );

   if ( ! select2011A &&
	! select2011B &&
	! select2011 ) {
     std::cout << "Error: Must choose dataset to be 0 (2011A), 1 (2011B), or 2 (all 2011)" << std::endl;
   }

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------
   
   // gap: 1.442 - 1.560

   // eleEta_bar            	1.442        -                    -               -               -1
   // eleEta_end1            	1.560        2.0                  -               -               -1
   // eleEta_end2            	2.000        2.5                  -               -               -1
   
   CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METSig_PAS"            ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"        ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"          ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt2ndJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Eta2ndJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Phi2ndJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "sTlep_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTjet_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mjj_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Me1j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j_selected_PAS"     ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j_selected_PAS"     ,    200 , 0       , 2000     );
   CreateUserTH1D( "Mej_selected_avg_PAS"  ,    200 , 0       , 2000     ); 
   CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
   CreateUserTH1D( "run_PAS"               ,    20000 , 160300  , 180300 );
   CreateUserTH1D( "run_HLT"               ,    20000 , 160300  , 180300 );
		                           
   CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );
   		                           
   CreateUserTH1D( "DCotTheta1stEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist1stEle_PAS"        ,    100 , 0.0, 1.0);  
   CreateUserTH1D( "DCotTheta2ndEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist2ndEle_PAS"        ,    100 , 0.0, 1.0);  
		                           
   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 
		                           
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele1Jet2_PAS"	   , 	getHistoNBins("DR_Ele1Jet2"), getHistoMin("DR_Ele1Jet2"), getHistoMax("DR_Ele1Jet2")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet2_PAS"	   , 	getHistoNBins("DR_Ele2Jet2"), getHistoMin("DR_Ele2Jet2"), getHistoMax("DR_Ele2Jet2")     ) ; 
   CreateUserTH1D( "DR_Jet1Jet2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 
   CreateUserTH1D( "DR_Ele1Ele2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 
   CreateUserTH1D( "minDR_EleJet_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 

   CreateUserTH2D( "Me1jVsMe2j_selected",     200, 0, 2000, 200, 0, 2000) ;
   CreateUserTH2D( "Me1jVsMe2j_rejected",     200, 0, 2000, 200, 0, 2000) ;

   CreateUserTH1D( "MTeemunu_PAS"          ,    200 , 0       , 1000	 ); 

   CreateUserTH1D( "Mee_80_100_Preselection", 200, 60, 120 );
   CreateUserTH1D( "Mee_70_110_Preselection", 200, 60, 120 );

   CreateUserTH1D( "Mee_EBEB_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_PAS" 		   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "Mee_EBEB_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_80_100_PAS" 	     	   ,    60 , 60       , 120	 ); 
   
   CreateUserTH1D( "Mee_EBEB_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_70_110_PAS" 	     	   ,    60 , 60       , 120	 ); 

   CreateUserTH1D("Mej_selected_avg_LQ250"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ350"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ400"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ450"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ500"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ550"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ600"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ650"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ750"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ850"         ,   40  , 0        , 2000     );

   CreateUserTH1D("Mej_selected_min_LQ250"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ350"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ400"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ450"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ500"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ550"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ600"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ650"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ750"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ850"         ,   40  , 0        , 2000     );

   CreateUserTH1D("sT_eejj_LQ250"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ350"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ400"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ450"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ500"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ550"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ600"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ650"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ750"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ850"                  ,   20  , 0        , 2000     );

   CreateUserTH1D("Mee_LQ250"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ350"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ400"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ450"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ500"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ550"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ600"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ650"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ750"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ850"                      ,   40  , 0        , 2000     );

   CreateUserTH1D( "PileupWeight"   , 100, -10, 10 );
   CreateUserTH1D( "GeneratorWeight", 100, -2.0, 2.0);
   
   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {

     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int    passedJSON = passJSON ( run, ls , isData ) ;

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------
     
     // double pileup_weight = lumiWeights.weight3D (nPileUpInt_BXminus1, nPileUpInt_BX0, nPileUpInt_BXplus1 );
     // if ( isData ) pileup_weight = 1.0;
     // setPileupWeight ( pileup_weight ) ;

     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;
      
     //--------------------------------------------------------------------------
     // Get information about gen-level reweighting (should be for Sherpa only)
     //--------------------------------------------------------------------------

     double gen_weight = Weight;
     if ( isData ) gen_weight = 1.0;

     // std::cout << "Gen weight = " << int ( 1.0 / gen_weight ) << std::endl;

     //--------------------------------------------------------------------------
     // Is this the dataset we want?
     //--------------------------------------------------------------------------
     
     int PassDataset = 1;
     if ( isData ) { 
       PassDataset = 0;
       if ( select2011A ){ 
	 if ( run >= 160329 && run <= 175770 ) PassDataset = 1;
       }
       if ( select2011B ){
	 if ( run >= 175832 && run <= 180296 ) PassDataset = 1;
       }
       if ( select2011 ) {
	 PassDataset = 1;
       }
     }

     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // JSON variable
     fillVariableWithValue(   "PassJSON"                      , passedJSON, gen_weight   ) ; 

     // Dataset variable
     fillVariableWithValue(   "PassDataset"                      , PassDataset, gen_weight  ) ;

     // Noise filters
     fillVariableWithValue(   "PassHBHENoiseFilter"           , PassHBHENoiseFilter    , gen_weight   ) ; 
     fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight, gen_weight   ) ; 

     //fillVariableWithValue(   "PassBPTX0"                     , PassBPTX0                  , gen_weight  ) ; 
     //fillVariableWithValue(   "PassPhysDecl"                  , PassPhysDecl               , gen_weight  ) ; 
     //fillVariableWithValue(   "PassBeamScraping"              , PassBeamScraping           , gen_weight  ) ; 
     //fillVariableWithValue(   "PassPrimaryVertex"             , PassPrimaryVertex          , gen_weight  ) ; 
     //fillVariableWithValue(   "PassBeamHaloFilterLoose"	      , PassBeamHaloFilterLoose	   , gen_weight  ) ; 
     //fillVariableWithValue(   "PassTrackingFailure"           , PassTrackingFailure        , gen_weight  ) ; 
     //fillVariableWithValue(   "PassCaloBoundaryDRFilter"      , PassCaloBoundaryDRFilter   , gen_weight  ) ; 
     //fillVariableWithValue(   "PassEcalMaskedCellDRFilter"    , PassEcalMaskedCellDRFilter , gen_weight  ) ; 

     // Fill HLT 
     int passHLT = 1;
     if ( isData ) { 
       passHLT = 0;
       
       if ( H_DoubleEle33_CIdL_1  == 1 || 
       	    H_DoubleEle33_CIdL_2  == 1 || 
       	    H_DoubleEle33_CIdL_3  == 1 || 
       	    H_DoubleEle33_CIdL_4  == 1 || 
       	    H_DoubleEle33_CIdL_5  == 1 || 
	    H_DoubleEle33_CIdL_6  == 1 ||
	    H_DoubleEle33_CIdL_7  == 1 ||
	    H_DoubleEle33_CIdT_1  == 1 ||
	    H_DoubleEle33_CIdT_2  == 1 ||
	    H_DoubleEle33_CIdT_3  == 1 ||
       	    H_DoublePhoton33_1    == 1 || 
       	    H_DoublePhoton33_2    == 1 || 
       	    H_DoublePhoton33_3    == 1 || 
       	    H_DoublePhoton33_4    == 1 || 
       	    H_DoublePhoton33_5    == 1 ) {
       	 passHLT = 1;
       }
     }

     // What dataset is this?

     // Electrons
     int PassNEle = 0;
     if ( nEle_Ana == 2 ) PassNEle = 1;
     
     // Muons
     int PassNMuon = 0;
     if ( nMuon_Ana == 0 ) PassNMuon = 1;
     
     fillVariableWithValue ( "Reweighting", 1, gen_weight  );
     fillVariableWithValue ( "PassHLT", passHLT, gen_weight  ) ;
     
     // Electrons
     fillVariableWithValue(   "PassNEle"                      , PassNEle    , gen_weight  ) ;
     if ( nEle_Ana >= 1 ) { 
       fillVariableWithValue( "Ele1_Pt"                       , Ele1_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Ele1_Eta"                      , Ele1_Eta    , gen_weight  ) ;
       fillVariableWithValue( "abs_Ele1_Eta"                  , fabs(Ele1_Eta), gen_weight  );
     }									    
     if ( nEle_Ana >= 2 ) { 						    
       fillVariableWithValue( "Ele2_Pt"                       , Ele2_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Ele2_Eta"                      , Ele2_Eta    , gen_weight  ) ;
       fillVariableWithValue( "abs_Ele2_Eta"                  , fabs(Ele2_Eta), gen_weight  );
       fillVariableWithValue( "M_e1e2"                        , M_e1e2      , gen_weight  ) ;
     }									    
									    
     // Jets								    
     fillVariableWithValue(   "nJet"                          , nJet_Ana    , gen_weight  ) ;
     if ( nJet_Ana >= 1 ) { 						    
       fillVariableWithValue( "Jet1_Pt"                       , Jet1_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Jet1_Eta"                      , Jet1_Eta    , gen_weight  ) ;
     }
     if ( nJet_Ana >= 2 ) { 
       fillVariableWithValue( "Jet2_Pt"                       , Jet2_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Jet2_Eta"                      , Jet2_Eta    , gen_weight  ) ;
       fillVariableWithValue( "DR_Jet1Jet2"                   , DR_Jet1Jet2 , gen_weight  ) ;
     }

     // Muons
     fillVariableWithValue(   "PassNMuon"                     , PassNMuon   , gen_weight  ) ;

     // DeltaR
     if ( nEle_Ana >= 2 && nJet_Ana >= 1) {
       fillVariableWithValue( "DR_Ele1Jet1"                   , DR_Ele1Jet1 , gen_weight  ) ;
       fillVariableWithValue( "DR_Ele2Jet1"                   , DR_Ele2Jet1 , gen_weight  ) ;
       if(nJet_Ana >= 2) {
	 fillVariableWithValue( "DR_Ele1Jet2"                 , DR_Ele1Jet2 , gen_weight  ) ;
	 fillVariableWithValue( "DR_Ele2Jet2"                 , DR_Ele2Jet2 , gen_weight  ) ;
       }
     }

     // sT
     double M_ej_avg;
     double M_ej_min;

     if ( nEle_Ana >= 2 && nJet_Ana >= 2) {
       if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
	 M_ej_avg = (M_e1j1 + M_e2j2) / 2.0;
	 if    ( M_e1j1 < M_e2j2 ) M_ej_min = M_e1j1;
	 else                      M_ej_min = M_e2j2;
       }
       else { 
	 M_ej_avg = (M_e1j2 + M_e2j1) / 2.0;
	 if    ( M_e1j2 < M_e2j1 ) M_ej_min = M_e1j2;
	 else                      M_ej_min = M_e2j1;
       }
       
       fillVariableWithValue( "sT_eejj"                      , sT_eejj, gen_weight  ) ;

       fillVariableWithValue( "sT_eejj_LQ250"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ350"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ400"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ450"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ500"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ550"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ600"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ650"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ750"                , sT_eejj, gen_weight  ) ;
       fillVariableWithValue( "sT_eejj_LQ850"                , sT_eejj, gen_weight  ) ;
       
       fillVariableWithValue( "min_M_ej_LQ250"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ350"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ400"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ450"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ500"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ550"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ600"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ650"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ750"               , M_ej_min, gen_weight ) ;
       fillVariableWithValue( "min_M_ej_LQ850"               , M_ej_min, gen_weight ) ;


       fillVariableWithValue( "M_e1e2_LQ250"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ350"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ400"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ450"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ500"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ550"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ600"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ650"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ750"                , M_e1e2, gen_weight  ) ;
       fillVariableWithValue( "M_e1e2_LQ850"                , M_e1e2, gen_weight  ) ;
       
     }      

     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------

     FillUserTH1D( "PileupWeight"   , pileup_weight );
     FillUserTH1D( "GeneratorWeight", gen_weight ) ;
     
     bool passed_minimum      = ( passedAllPreviousCuts("PassBeamHaloFilterTight") && passedCut ("PassBeamHaloFilterTight"));
     bool passed_250          = ( passedAllPreviousCuts("min_M_ej_LQ250"         ) && passedCut ("min_M_ej_LQ250"         ));
     bool passed_350          = ( passedAllPreviousCuts("min_M_ej_LQ350"         ) && passedCut ("min_M_ej_LQ350"         ));
     bool passed_400          = ( passedAllPreviousCuts("min_M_ej_LQ400"         ) && passedCut ("min_M_ej_LQ400"         ));
     bool passed_450          = ( passedAllPreviousCuts("min_M_ej_LQ450"         ) && passedCut ("min_M_ej_LQ450"         ));
     bool passed_500          = ( passedAllPreviousCuts("min_M_ej_LQ500"         ) && passedCut ("min_M_ej_LQ500"         ));
     bool passed_550          = ( passedAllPreviousCuts("min_M_ej_LQ550"         ) && passedCut ("min_M_ej_LQ550"         ));
     bool passed_600          = ( passedAllPreviousCuts("min_M_ej_LQ600"         ) && passedCut ("min_M_ej_LQ600"         ));
     bool passed_650          = ( passedAllPreviousCuts("min_M_ej_LQ650"         ) && passedCut ("min_M_ej_LQ650"         ));
     bool passed_750          = ( passedAllPreviousCuts("min_M_ej_LQ750"         ) && passedCut ("min_M_ej_LQ750"         ));
     bool passed_850          = ( passedAllPreviousCuts("min_M_ej_LQ850"         ) && passedCut ("min_M_ej_LQ850"         ));

     if ( passed_minimum && isData ){ 
       FillUserTH1D ("run_HLT", run );
       profile_run_vs_nvtx_HLT -> Fill ( run, nVertex, 1 ) ;
     }

     bool passed_preselection = ( passedAllPreviousCuts("M_e1e2") && passedCut ("M_e1e2") );

     /*
     if ( isData ) {
       std::cout.precision(0);
       std::cout << fixed <<  "Run = " << run << ", event = " << event << ", ls = " << ls << std::endl;
       std::cout.precision(3);
       std::cout << fixed <<  "  Mej      = " << M_ej_avg << std::endl;
       std::cout << fixed <<  "  Mee      = " << M_e1e2 << std::endl;
       std::cout << fixed <<  "  sT       = " << sT_enujj << std::endl;
       std::cout << fixed <<  "  Ele1 Pt  = " << Ele1_Pt << "\t, Eta = " << Ele1_Eta << "\t, Phi = " << Ele1_Phi << std::endl;
       std::cout << fixed <<  "  Ele2 Pt  = " << Ele2_Pt << "\t, Eta = " << Ele2_Eta << "\t, Phi = " << Ele2_Phi << std::endl;
       std::cout << fixed <<  "  Jet1 Pt  = " << Jet1_Pt << "\t, Eta = " << Jet1_Eta << "\t, Phi = " << Jet1_Phi << std::endl;
       std::cout << fixed <<  "  Jet2 Pt  = " << Jet2_Pt << "\t, Eta = " << Jet2_Eta << "\t, Phi = " << Jet2_Phi << std::endl;
     }
     */
     
     if ( passed_preselection ) {

       //--------------------------------------------------------------------------
       // Fill skim tree, if necessary
       //--------------------------------------------------------------------------
       
       bool isEB1 = ( fabs(Ele1_Eta) < eleEta_bar_max  ) ;
       bool isEE1 = ( fabs(Ele1_Eta) > eleEta_end_min &&
		      fabs(Ele1_Eta) < eleEta_end_max ) ;
       
       bool isEB2 = ( fabs(Ele2_Eta) < eleEta_bar_max  ) ;
       bool isEE2 = ( fabs(Ele2_Eta) > eleEta_end_min &&
		      fabs(Ele2_Eta) < eleEta_end_max ) ;

       bool isEBEB = ( isEB1 && isEB2 ) ;
       bool isEBEE = ( ( isEB1 && isEE2 ) ||
		       ( isEE1 && isEB2 ) );
       bool isEEEE = ( isEE1  && isEE2  );
       bool isEB   = ( isEBEB || isEBEE );
       
       if ( isData ) { 
	 FillUserTH1D("run_PAS", run ) ;
	 profile_run_vs_nvtx_PAS -> Fill ( run, nVertex, 1 ) ;
       }
       
       FillUserTH1D("nElectron_PAS"        , nEle_Ana         , pileup_weight * gen_weight ) ;
       FillUserTH1D("nMuon_PAS"            , nMuon_Stored     , pileup_weight * gen_weight ) ;
       FillUserTH1D("nJet_PAS"             , nJet_Ana         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Pt1stEle_PAS"	   , Ele1_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta1stEle_PAS"	   , Ele1_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi1stEle_PAS"	   , Ele1_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Pt2ndEle_PAS"	   , Ele2_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta2ndEle_PAS"	   , Ele2_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi2ndEle_PAS"	   , Ele2_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Charge1stEle_PAS"	   , Ele1_Charge      , pileup_weight * gen_weight ) ;
       FillUserTH1D("Charge2ndEle_PAS"	   , Ele2_Charge      , pileup_weight * gen_weight ) ;
       FillUserTH1D("MET_PAS"              , MET_Pt           , pileup_weight * gen_weight ) ;
       FillUserTH1D("METSig_PAS"           , PFMETSig         , pileup_weight * gen_weight ) ;
       FillUserTH1D("METPhi_PAS"	   , MET_Phi          , pileup_weight * gen_weight ) ;
       FillUserTH1D("METCharged_PAS"       , PFMETCharged     , pileup_weight * gen_weight ) ;
       FillUserTH1D("METChargedPhi_PAS"    , PFMETChargedPhi  , pileup_weight * gen_weight ) ;   
       FillUserTH1D("METType1_PAS"         , PFMETType1Cor    , pileup_weight * gen_weight ) ;
       FillUserTH1D("METType1Phi_PAS"      , PFMETPhiType1Cor , pileup_weight * gen_weight ) ;   
       FillUserTH1D("Pt1stJet_PAS"         , Jet1_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Pt2ndJet_PAS"         , Jet2_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta1stJet_PAS"        , Jet1_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta2ndJet_PAS"        , Jet2_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi1stJet_PAS"	   , Jet1_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi2ndJet_PAS"	   , Jet2_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("sTlep_PAS"            , Ele1_Pt + Ele2_Pt, pileup_weight * gen_weight ) ;
       FillUserTH1D("sTjet_PAS"            , Jet1_Pt + Jet2_Pt, pileup_weight * gen_weight ) ;
       FillUserTH1D("sT_PAS"               , sT_eejj          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Mjj_PAS"		   , M_j1j2           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Mee_PAS"		   , M_e1e2           , pileup_weight * gen_weight ) ;
       FillUserTH1D( "MTenu_PAS"           , MT_Ele1MET       , pileup_weight * gen_weight ) ;
       FillUserTH1D("Me1j1_PAS"            , M_e1j1           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Me1j2_PAS"            , M_e1j2           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Me2j1_PAS"            , M_e2j1           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Me2j2_PAS"            , M_e2j2           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Ptee_PAS"             , Pt_e1e2          , pileup_weight * gen_weight ) ;
       FillUserTH1D("DCotTheta1stEle_PAS"  , Ele1_DCotTheta   , pileup_weight * gen_weight ) ;
       FillUserTH1D("Dist1stEle_PAS"       , Ele1_Dist        , pileup_weight * gen_weight ) ;
       FillUserTH1D("DCotTheta2ndEle_PAS"  , Ele2_DCotTheta   , pileup_weight * gen_weight ) ;
       FillUserTH1D("Dist2ndEle_PAS"       , Ele2_Dist        , pileup_weight * gen_weight ) ;
       FillUserTH1D("nVertex_PAS"          , nVertex          , pileup_weight * gen_weight ) ;
       FillUserTH1D("nVertex_good_PAS"     , nVertex_good     , pileup_weight * gen_weight ) ;
       FillUserTH1D("DR_Ele1Jet1_PAS"	   , DR_Ele1Jet1      , pileup_weight * gen_weight ) ;
       FillUserTH1D("DR_Ele1Jet2_PAS"	   , DR_Ele1Jet2      , pileup_weight * gen_weight ) ;
       FillUserTH1D("DR_Ele2Jet1_PAS"	   , DR_Ele2Jet1      , pileup_weight * gen_weight ) ;
       FillUserTH1D("DR_Ele2Jet2_PAS"	   , DR_Ele2Jet2      , pileup_weight * gen_weight ) ;
       FillUserTH1D("DR_Jet1Jet2_PAS"	   , DR_Jet1Jet2      , pileup_weight * gen_weight ) ;
       
       if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_PAS", M_e1e2, pileup_weight * gen_weight ); 
       else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_PAS", M_e1e2, pileup_weight * gen_weight ); 
       else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_PAS", M_e1e2, pileup_weight * gen_weight ); 
       if      ( isEB   ) FillUserTH1D( "Mee_EB_PAS"  , M_e1e2, pileup_weight * gen_weight ); 

       if ( M_e1e2 > 80.0 && M_e1e2 < 100.0 ){
	 FillUserTH1D("Mee_80_100_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_80_100_PAS"  , M_e1e2, pileup_weight * gen_weight ); 
       } 

       if ( M_e1e2 > 70.0 && M_e1e2 < 110.0 ){
	 FillUserTH1D("Mee_70_110_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_70_110_PAS"  , M_e1e2, pileup_weight * gen_weight ); 
       }
       
       double DR_Ele1Jet3 = 999.;
       double DR_Ele2Jet3 = 999.;
       double min_DR_EleJet = 999.;
       TLorentzVector eejj, e1e2mu, e1, j1, e2, j2,j3, mu, met;
       e1.SetPtEtaPhiM ( Ele1_Pt, Ele1_Eta, Ele1_Phi, 0.0 );
       e2.SetPtEtaPhiM ( Ele2_Pt, Ele2_Eta, Ele2_Phi, 0.0 );
       j1.SetPtEtaPhiM ( Jet1_Pt, Jet1_Eta, Jet1_Phi, 0.0 );
       j2.SetPtEtaPhiM ( Jet2_Pt, Jet2_Eta, Jet2_Phi, 0.0 );
       if ( nJet_Ana > 2 ) { 
	 j3.SetPtEtaPhiM ( Jet3_Pt, Jet3_Eta, Jet3_Phi, 0.0 );
	 DR_Ele1Jet3 = e1.DeltaR( j3 );
	 DR_Ele2Jet3 = e2.DeltaR( j3 );
       }
       
       if ( DR_Ele1Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet1;
       if ( DR_Ele1Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet2;
       if ( DR_Ele2Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet1;
       if ( DR_Ele2Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet2;
       if ( nJet_Ana > 2 ) {
	 if ( DR_Ele1Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet3;
	 if ( DR_Ele2Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet3;
       }
       
       FillUserTH1D( "minDR_EleJet_PAS", min_DR_EleJet, pileup_weight * gen_weight);
       
       
       mu.SetPtEtaPhiM ( Muon1_Pt, Muon1_Eta, Muon1_Phi, 0.0 );
       met.SetPtEtaPhiM ( MET_Pt, 0.0, MET_Phi, 0.0 );
       
       double DR_Ele1Ele2 = e1.DeltaR( e2 ) ;
       FillUserTH1D("DR_Ele1Ele2_PAS"	   , DR_Ele1Ele2      , pileup_weight * gen_weight ) ;
       
       eejj = e1 + e2 + j1 + j2 ; 
       double M_eejj = eejj.M();

       // e1e2mu = e1 + e2 + mu;
       // double MT_eemuMET = sqrt(2 * e1e2mu.Pt()    * MET_Pt  * (1 - cos(e1e2mu.DeltaPhi (met))));
       // FillUserTH1D("MTeemunu_PAS"         , MT_eemuMET                        , pileup_weight * gen_weight );
	      
       FillUserTH1D("Meejj_PAS", M_eejj , pileup_weight * gen_weight );

       
       if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
	 FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg, pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me1j_selected_PAS"   , M_e1j1  , pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me2j_selected_PAS"   , M_e2j2  , pileup_weight * gen_weight) ;	   
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j1  , M_e2j2, pileup_weight * gen_weight ) ;
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j2  , M_e2j1, pileup_weight * gen_weight ) ;
       }

       else {
	 FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg, pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me1j_selected_PAS"   , M_e1j2, pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me2j_selected_PAS"   , M_e2j1, pileup_weight * gen_weight) ;	   
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j2, M_e2j1, pileup_weight * gen_weight ) ;
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j1, M_e2j2, pileup_weight * gen_weight ) ;
       }

       if ( passed_250 ) {
	 FillUserTH1D("Mej_selected_avg_LQ250", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ250", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ250"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ250"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_350 ) {
	 FillUserTH1D("Mej_selected_avg_LQ350", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ350", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ350"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ350"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_400 ) {
	 FillUserTH1D("Mej_selected_avg_LQ400", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ400", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ400"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ400"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_450 ) {
	 FillUserTH1D("Mej_selected_avg_LQ450", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ450", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ450"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ450"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_500 ) {
	 FillUserTH1D("Mej_selected_avg_LQ500", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ500", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ500"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ500"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_550 ) {
	 FillUserTH1D("Mej_selected_avg_LQ550", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ550", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ550"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ550"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_600 ) {
	 FillUserTH1D("Mej_selected_avg_LQ600", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ600", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ600"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ600"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_650 ) {
	 FillUserTH1D("Mej_selected_avg_LQ650", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ650", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ650"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ650"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_750 ) {
	 FillUserTH1D("Mej_selected_avg_LQ750", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ750", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ750"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ750"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }

       if ( passed_850 ) {
	 FillUserTH1D("Mej_selected_avg_LQ850", M_ej_avg, pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mej_selected_min_LQ850", M_ej_min, pileup_weight * gen_weight ) ;
	 FillUserTH1D("sT_eejj_LQ850"         , sT_eejj , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Mee_LQ850"             , M_e1e2  , pileup_weight * gen_weight ) ;
       }
     }
   } // End loop over events

   
   output_root_ -> cd();
   profile_run_vs_nvtx_HLT -> Write();
   profile_run_vs_nvtx_PAS -> Write();
   
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here
   TH2F *h_RelDeltaP_vs_trkP_top = new TH2F ("h_RelDeltaP_vs_trkP_top","h_RelDeltaP_vs_trkP_top",500,0,500,500,-10,10);
   TH2F *h_RelDeltaP_vs_trkP_bottom = new TH2F ("h_RelDeltaP_vs_trkP_bottom","h_RelDeltaP_vs_trkP_bottom",500,0,500,500,-10,10);

   TH2F *h_muonDTP_vs_trkP_top = new TH2F ("h_muonDTP_vs_trkP_top","h_muonDTP_vs_trkP_top",500,0,500,500,0,500);
   TH2F *h_muonDTP_vs_trkP_bottom = new TH2F ("h_muonDTP_vs_trkP_bottom","h_muonDTP_vs_trkP_bottom",500,0,500,500,0,500);

#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   
   // number of electrons
   TH1F *h_nEleFinal = new TH1F ("h_nEleFinal","",11,-0.5,10.5);
   h_nEleFinal->Sumw2();
   //pT 1st ele
   TH1F *h_pT1stEle = new TH1F ("h_pT1stEle","",100,0,1000);
   h_pT1stEle->Sumw2();
   //pT 2nd ele
   TH1F *h_pT2ndEle = new TH1F ("h_pT2ndEle","",100,0,1000);
   h_pT2ndEle->Sumw2();

#endif //end of USE_EXAMPLE

   /////////initialize variables

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event

#ifdef USE_EXAMPLE
     // Electrons
     vector<int> v_idx_ele_final;
     for(int iele=0;iele<eleCount;iele++)
       {
	 // ECAL barrel fiducial region
	 bool pass_ECAL_FR=false;
	 if( fabs(eleEta[iele]) < getPreCutValue1("eleFidRegion") )	v_idx_ele_final.push_back(iele);
       }     

     // Set the evaluation of the cuts to false and clear the variable values and filled status
     resetCuts();
     
     // Set the value of the variableNames listed in the cutFile to their current value
     fillVariableWithValue("nEleFinal", v_idx_ele_final.size()) ;
     if( v_idx_ele_final.size() >= 1 ) 
       {
	 fillVariableWithValue( "pT1stEle", elePt[v_idx_ele_final[0]] );
       }
     if( v_idx_ele_final.size() >= 2 ) 
       {
	 fillVariableWithValue( "pT2ndEle", elePt[v_idx_ele_final[1]] );
	 // Calculate Mee
	 TLorentzVector v_ee, ele1, ele2;
	 ele1.SetPtEtaPhiM(elePt[v_idx_ele_final[0]],eleEta[v_idx_ele_final[0]],elePhi[v_idx_ele_final[0]],0);
	 ele2.SetPtEtaPhiM(elePt[v_idx_ele_final[1]],eleEta[v_idx_ele_final[1]],elePhi[v_idx_ele_final[1]],0);
	 v_ee = ele1 + ele2;
	 fillVariableWithValue( "invMass_ee", v_ee.M() ) ;
       }

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // Fill histograms and do analysis based on cut evaluation
     h_nEleFinal->Fill(v_idx_ele_final.size());
     //if( v_idx_ele_final.size()>=1 ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     //if( v_idx_ele_final.size()>=2 && (elePt[v_idx_ele_final[0]])>85 ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     if( passedCut("pT1stEle") ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     if( passedCut("pT2ndEle") ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     
     // reject events that did not pass level 0 cuts
     if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     if( !passedCut("all") ) continue;
     // ......

#endif  // end of USE_EXAMPLE

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

     double LenghtHB = getPreCutValue2("radiusHB") - getPreCutValue1("radiusHB");

     int n_DTtracksT=0;
     int n_DTtracksB=0;
     int n_DTtracksValidProp=0;
     for(int muon=0; muon<muonDTCount; muon++)
       {
	 if(muonDTYin[muon]>0 && muonDTYout[muon]>0)
	   n_DTtracksT++;

	 if(muonDTYin[muon]<0 && muonDTYout[muon]<0)
	   n_DTtracksB++;

	 if(muonDTisValidProp[muon]==1)
	   n_DTtracksValidProp++;
       }

     fillVariableWithValue( "N_DTtracks", muonDTCount );
     fillVariableWithValue( "N_DTtracksProp", n_DTtracksValidProp );
     fillVariableWithValue( "N_DTtracksT", n_DTtracksT );
     fillVariableWithValue( "N_DTtracksB", n_DTtracksB );
     fillVariableWithValue( "N_TRKtracks", trackCount );

     if( muonDTCount >=2  )
       {

	 int indexTOP=-1;
	 int indexBOTTOM=-1;
	 
	 if(muonDTYin[0]>0 && muonDTYout[0]>0)
	   {
	     indexTOP = 0;
	   }
	 else
	   if(muonDTYin[0]<0 && muonDTYout[0]<0)
	     {
	       indexBOTTOM = 0;
	     }

	 if(muonDTYin[1]>0 && muonDTYout[1]>0)
	   {
	     indexTOP = 1;
	   }
	 else
	   if(muonDTYin[1]<0 && muonDTYout[1]<0)
	     {
	       indexBOTTOM = 1;
	     }
	
	 if(indexTOP >= 0 && indexBOTTOM >= 0)
	   {
	     //top
	     fillVariableWithValue( "muonTDXY_DT_TRK", muonDTnrstTrkDXY[indexTOP] );
	     fillVariableWithValue( "muonTDZ_DT_TRK", muonDTnrstTrkDZ[indexTOP] );
	     fillVariableWithValue( "muonTDTNHits", muonDTNumRecHits[indexTOP] );
	     fillVariableWithValue( "muonTDTNValidHits", muonDTNumValidRecHits[indexTOP] );
	     fillVariableWithValue( "muonTDTEtaAtHB", max(muonDTEtaAtInHB[indexTOP],muonDTEtaAtOutHB[indexTOP]) );
	     fillVariableWithValue( "muonTDTPhiAtHB", max(muonDTPhiAtInHB[indexTOP],muonDTPhiAtOutHB[indexTOP]) );
	     fillVariableWithValue( "muonTDTLenghtHB", muonDTLengthInHB[indexTOP] );
	     fillVariableWithValue( "muonTDTdRHitMuInHB", muonDTdeltaRatInHB[indexTOP] );
	     fillVariableWithValue( "muonTDTdRHitMuOutHB", muonDTdeltaRatOutHB[indexTOP] );
	     fillVariableWithValue( "muonTDTEnergy", muonDTTotEnergy[indexTOP] );
	     double normEnergyTOP = (muonDTTotEnergy[indexTOP] / muonDTLengthInHB[indexTOP]) * LenghtHB; 
	     fillVariableWithValue( "muonTDTEnergyNorm", normEnergyTOP );
	     fillVariableWithValue( "muonTDTNCells", muonDTNumCells[indexTOP] );
	     fillVariableWithValue( "muonTDTCellSameEta", muonDTHaveCellsSameEta[indexTOP] );
	     fillVariableWithValue( "muonTDTCellSamePhi", muonDTHaveCellsSamePhi[indexTOP] );
	     if(muonDTHaveCellsSameEta[indexTOP] || muonDTHaveCellsSamePhi[indexTOP])
	       fillVariableWithValue( "muonTDTCellSmEtaOrPhi", 1 );
	     fillVariableWithValue( "muonTDTP", muonDTP[indexTOP] );
	     fillVariableWithValue( "muonTDTPt", muonDTPt[indexTOP] );

	     if(muonDTnrstTrkIdx[indexTOP]>=0)
	       {
		 fillVariableWithValue( "muonTDTtrkChi2", trackChi2[muonDTnrstTrkIdx[indexTOP]] );
		 fillVariableWithValue( "muonTDTtrkNdof", trackNdof[muonDTnrstTrkIdx[indexTOP]] );
		 fillVariableWithValue( "muonTDTtrkNrmChi2", trackChi2[muonDTnrstTrkIdx[indexTOP]]/trackNdof[muonDTnrstTrkIdx[indexTOP]] );
		 fillVariableWithValue( "muonTDTtrkP", trackP[muonDTnrstTrkIdx[indexTOP]] );
		 fillVariableWithValue( "muonTDTtrkPt", trackPt[muonDTnrstTrkIdx[indexTOP]] );
		 double relDeltaP = ( muonDTP[indexTOP] - trackP[muonDTnrstTrkIdx[indexTOP]] ) / trackP[muonDTnrstTrkIdx[indexTOP]];
		 double relDeltaPt = ( muonDTPt[indexTOP] - trackPt[muonDTnrstTrkIdx[indexTOP]] ) / trackPt[muonDTnrstTrkIdx[indexTOP]];
		 fillVariableWithValue( "muonTDTtrkRelDeltaP", relDeltaP );
		 fillVariableWithValue( "muonTDTtrkRelDeltaPt", relDeltaPt );
	       }

	     //bottom
	     fillVariableWithValue( "muonBDXY_DT_TRK", muonDTnrstTrkDXY[indexBOTTOM] );
	     fillVariableWithValue( "muonBDZ_DT_TRK", muonDTnrstTrkDZ[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTNHits", muonDTNumRecHits[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTNValidHits", muonDTNumValidRecHits[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTEtaAtHB", max(muonDTEtaAtInHB[indexBOTTOM],muonDTEtaAtOutHB[indexBOTTOM]) );
	     fillVariableWithValue( "muonBDTPhiAtHB", max(muonDTPhiAtInHB[indexBOTTOM],muonDTPhiAtOutHB[indexBOTTOM]) );
	     fillVariableWithValue( "muonBDTLenghtHB", muonDTLengthInHB[indexBOTTOM] );	     
	     fillVariableWithValue( "muonBDTdRHitMuInHB", muonDTdeltaRatInHB[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTdRHitMuOutHB", muonDTdeltaRatOutHB[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTEnergy", muonDTTotEnergy[indexBOTTOM] );
	     double normEnergyBOTTOM = (muonDTTotEnergy[indexBOTTOM] / muonDTLengthInHB[indexBOTTOM]) * LenghtHB; 
	     fillVariableWithValue( "muonBDTEnergyNorm", normEnergyBOTTOM );
	     fillVariableWithValue( "muonBDTNCells", muonDTNumCells[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTCellSameEta", muonDTHaveCellsSameEta[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTCellSamePhi", muonDTHaveCellsSamePhi[indexBOTTOM] );
	     if(muonDTHaveCellsSameEta[indexBOTTOM] || muonDTHaveCellsSamePhi[indexBOTTOM])
	       fillVariableWithValue( "muonBDTCellSmEtaOrPhi", 1 );
	     fillVariableWithValue( "muonBDTP", muonDTP[indexBOTTOM] );
	     fillVariableWithValue( "muonBDTPt", muonDTPt[indexBOTTOM] );

	     if(muonDTnrstTrkIdx[indexBOTTOM]>=0)
	       {
		 fillVariableWithValue( "muonBDTtrkChi2", trackChi2[muonDTnrstTrkIdx[indexBOTTOM]] );
		 fillVariableWithValue( "muonBDTtrkNdof", trackNdof[muonDTnrstTrkIdx[indexBOTTOM]] );
		 fillVariableWithValue( "muonBDTtrkNrmChi2", trackChi2[muonDTnrstTrkIdx[indexBOTTOM]]/trackNdof[muonDTnrstTrkIdx[indexBOTTOM]] );
		 fillVariableWithValue( "muonBDTtrkP", trackP[muonDTnrstTrkIdx[indexBOTTOM]] );
		 fillVariableWithValue( "muonBDTtrkPt", trackPt[muonDTnrstTrkIdx[indexBOTTOM]] );
		 double relDeltaP = ( muonDTP[indexBOTTOM] - trackP[muonDTnrstTrkIdx[indexBOTTOM]] ) / trackP[muonDTnrstTrkIdx[indexBOTTOM]];
		 double relDeltaPt = ( muonDTPt[indexBOTTOM] - trackPt[muonDTnrstTrkIdx[indexBOTTOM]] ) / trackPt[muonDTnrstTrkIdx[indexBOTTOM]];
		 fillVariableWithValue( "muonBDTtrkRelDeltaP", relDeltaP );
		 fillVariableWithValue( "muonBDTtrkRelDeltaPt", relDeltaPt );
	       }
	   }
       
       }

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

     if( passedCut("0") && passedCut("1") &&  passedCut("2") && passedCut("3") && passedCut("4") ) 
       { 
	 if( muonDTCount >=2  )
	   {
	   
	     int indexTOP=-1;
	     int indexBOTTOM=-1;
	   
	     if(muonDTYin[0]>0 && muonDTYout[0]>0)
	       indexTOP = 0;
	     else
	       if(muonDTYin[0]<0 && muonDTYout[0]<0)
		 indexBOTTOM = 0;
	     if(muonDTYin[1]>0 && muonDTYout[1]>0)
	       indexTOP = 1;
	     else
	       if(muonDTYin[1]<0 && muonDTYout[1]<0)
		 indexBOTTOM = 1;

	     if(indexTOP >= 0 && indexBOTTOM >= 0)
	       {
		 if(muonDTnrstTrkIdx[indexTOP]>=0)
		   {
		     double relDeltaP = ( muonDTP[indexTOP] - trackP[muonDTnrstTrkIdx[indexTOP]] ) / trackP[muonDTnrstTrkIdx[indexTOP]];
		     h_RelDeltaP_vs_trkP_top->Fill(trackP[muonDTnrstTrkIdx[indexTOP]] , relDeltaP);
		     h_muonDTP_vs_trkP_top->Fill(trackP[muonDTnrstTrkIdx[indexTOP]] , muonDTP[indexTOP]);
		   }
	     
		 if(muonDTnrstTrkIdx[indexBOTTOM]>=0)
		   {
		     double relDeltaP = ( muonDTP[indexBOTTOM] - trackP[muonDTnrstTrkIdx[indexBOTTOM]] ) / trackP[muonDTnrstTrkIdx[indexBOTTOM]];
		     h_RelDeltaP_vs_trkP_bottom->Fill(trackP[muonDTnrstTrkIdx[indexBOTTOM]] , relDeltaP);
		     h_muonDTP_vs_trkP_bottom->Fill(trackP[muonDTnrstTrkIdx[indexBOTTOM]] , muonDTP[indexBOTTOM]);
		   }
	       }
	   }
       }
     
     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

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


#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   

   h_nEleFinal->Write();
   h_pT1stEle->Write();
   h_pT2ndEle->Write();

   //pT of both electrons, to be built using the histograms produced automatically by baseClass
   TH1F * h_pTElectrons = new TH1F ("h_pTElectrons","", getHistoNBins("pT1stEle"), getHistoMin("pT1stEle"), getHistoMax("pT1stEle"));
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT1stEle") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT2ndEle") );
   //one could also do:  *h_pTElectrons = getHisto_noCuts_or_skim("pT1stEle") + getHisto_noCuts_or_skim("pT2ndEle");
   h_pTElectrons->Write();
   //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h
#endif // end of USE_EXAMPLE

   h_RelDeltaP_vs_trkP_top->Write();
   h_RelDeltaP_vs_trkP_bottom->Write();
   h_muonDTP_vs_trkP_top->Write();
   h_muonDTP_vs_trkP_bottom->Write();
		 
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");

  if (fChain == 0) return;

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Get all Pre-cut values!
   *
   *
   *
   *///-----------------------------------------------------------------
  
   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 ( !true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;


  //-----------------------------------------------------------------
  // Electron cut values
  //-----------------------------------------------------------------
  
  double ele_PtCut_STORE = getPreCutValue2("ele_PtCut");
  double ele_PtCut_ANA   = getPreCutValue1("ele_PtCut");
  
  double eleEta_bar      = getPreCutValue1("eleEta_bar");
  double eleEta_end_min  = getPreCutValue1("eleEta_end");
  double eleEta_end_max  = getPreCutValue2("eleEta_end");
  
  if ( ele_PtCut_STORE > ele_PtCut_ANA ) {
    STDOUT("ERROR in Electron cut values: all storage cuts must be looser or equal to analysis cuts.");
    exit(0) ;
  }

  // For WP80

  double eleMissingHitsWP             = getPreCutValue1("eleMissingHitsWP"        );
  double eleDistWP                    = getPreCutValue1("eleDistWP"               );
  double eleDCotThetaWP               = getPreCutValue1("eleDCotThetaWP"          );
  double eleCombRelIsoWP_bar          = getPreCutValue1("eleCombRelIsoWP"         );
  double eleCombRelIsoWP_end          = getPreCutValue2("eleCombRelIsoWP"         );
  double eleSigmaIetaIetaWP_bar       = getPreCutValue1("eleSigmaIetaIetaWP"      );
  double eleSigmaIetaIetaWP_end       = getPreCutValue2("eleSigmaIetaIetaWP"      );
  double eleDeltaPhiTrkSCWP_bar       = getPreCutValue1("eleDeltaPhiTrkSCWP"      );
  double eleDeltaPhiTrkSCWP_end       = getPreCutValue2("eleDeltaPhiTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_bar       = getPreCutValue1("eleDeltaEtaTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_end       = getPreCutValue2("eleDeltaEtaTrkSCWP"      );
  double eleUseEcalDrivenWP           = getPreCutValue1("eleUseEcalDrivenWP"      );
  double eleUseHasMatchConvWP         = getPreCutValue1("eleUseHasMatchConvWP"    );

  // For HEEP 3.1

  double eleDeltaEtaTrkSCHeep_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaEtaTrkSCHeep_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep"    );
  double eleHoEHeep_bar               = getPreCutValue1("eleHoEHeep"              );
  double eleHoEHeep_end               = getPreCutValue2("eleHoEHeep"              );
  double eleE2x5OverE5x5Heep_bar      = getPreCutValue1("eleE2x5OverE5x5Heep"     );
  double eleE1x5OverE5x5Heep_bar      = getPreCutValue1("eleE1x5OverE5x5Heep"     );
  double eleSigmaIetaIetaHeep_end     = getPreCutValue2("eleSigmaIetaIetaHeep"    );
  double eleEcalHcalIsoHeep_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_1_end     = getPreCutValue3("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_end     = getPreCutValue4("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep_PTthr");
  double eleHcalIsoD2Heep_end         = getPreCutValue2("eleHcalIsoD2Heep"        );
  double eleTrkIsoHeep_bar            = getPreCutValue1("eleTrkIsoHeep"           );
  double eleTrkIsoHeep_end            = getPreCutValue2("eleTrkIsoHeep"           );
  double eleMissingHitsHeep           = getPreCutValue1("eleMissingHitsHeep"      );
  double eleUseEcalDrivenHeep         = getPreCutValue1("eleUseEcalDrivenHeep"    );

  // For HEEP 3.2

  double eleDeltaEtaTrkSCHeep32_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaEtaTrkSCHeep32_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep32"    );
  double eleHoEHeep32_bar               = getPreCutValue1("eleHoEHeep32"              );
  double eleHoEHeep32_end               = getPreCutValue2("eleHoEHeep32"              );
  double eleE2x5OverE5x5Heep32_bar      = getPreCutValue1("eleE2x5OverE5x5Heep32"     );
  double eleE1x5OverE5x5Heep32_bar      = getPreCutValue1("eleE1x5OverE5x5Heep32"     );
  double eleSigmaIetaIetaHeep32_end     = getPreCutValue2("eleSigmaIetaIetaHeep32"    );
  double eleEcalHcalIsoHeep32_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_1_end     = getPreCutValue3("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_end     = getPreCutValue4("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep32_PTthr");
  //double eleHcalIsoD2Heep32_end         = getPreCutValue2("eleHcalIsoD2Heep32"        );
  double eleTrkIsoHeep32_bar            = getPreCutValue1("eleTrkIsoHeep32"           );
  double eleTrkIsoHeep32_end            = getPreCutValue2("eleTrkIsoHeep32"           );
  double eleMissingHitsHeep32           = getPreCutValue1("eleMissingHitsHeep32"      );
  double eleUseEcalDrivenHeep32         = getPreCutValue1("eleUseEcalDrivenHeep32"    );

  //-----------------------------------------------------------------
  // Vertex cut values
  //-----------------------------------------------------------------

  double vertexMinimumNDOF = getPreCutValue1("vertexMinimumNDOF");
  double vertexMaxAbsZ     = getPreCutValue1("vertexMaxAbsZ");
  double vertexMaxd0       = getPreCutValue1("vertexMaxd0");

  //-----------------------------------------------------------------
  // Which algorithms to use?
  //-----------------------------------------------------------------

  int    eleAlgorithm = (int) getPreCutValue1("eleAlgorithm");

  //-----------------------------------------------------------------
  // Counters
  //-----------------------------------------------------------------
  int    N_probe_PassEleOffline = 0;
  int    N_probe_PassEleOfflineAndWP80 = 0;
  int    N_probe_PassEleOfflineAndTag = 0;  

  int    N_probe_PassEleOffline_bar = 0;
  int    N_probe_PassEleOfflineAndWP80_bar = 0;
  int    N_probe_PassEleOfflineAndTag_bar = 0;  

  int    N_probe_PassEleOffline_end = 0;
  int    N_probe_PassEleOfflineAndWP80_end = 0;
  int    N_probe_PassEleOfflineAndTag_end = 0;  

  //Histograms
  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOffline", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOffline", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_end", 50, 0, 50);			

  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndWP80", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndWP80", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_end", 50, 0, 50);			

  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndTag", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndTag", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_end", 50, 0, 50);			

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Start analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------


  Long64_t nentries = fChain->GetEntries();
  //Long64_t nentries = 100000;
  STDOUT("analysisClass::Loop(): nentries = " << nentries);

  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry << "/" << nentries );
    
    //-----------------------------------------------------------------
    // Do pileup re-weighting, if necessary
    //  --> To be done after the skim, so commented out for now
    //-----------------------------------------------------------------
    
    // double event_weight = getPileupWeight ( PileUpInteractions, isData ) ;
    
    //-----------------------------------------------------------------
    // Get trigger information, if necessary
    //-----------------------------------------------------------------

    if ( isData ) { 
      getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ;
    }
    
    //-----------------------------------------------------------------
    // Selection: Electrons
    //-----------------------------------------------------------------    

    vector<int> v_idx_ele_PtCut_IDISO_STORE;
    vector<int> v_idx_ele_PtCut_IDISO_ANA;
    vector<int> v_idx_ele_IDISO;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++){
      
      int passEleSel = 0;
      int isBarrel = 0;
      int isEndcap = 0;
      
      if( fabs( ElectronSCEta->at(iele) ) < eleEta_bar )       isBarrel = 1;
      if( fabs( ElectronSCEta->at(iele) ) > eleEta_end_min &&
	  fabs( ElectronSCEta->at(iele) ) < eleEta_end_max )   isEndcap = 1;

      //-----------------------------------------------------------------    
      // HEEP ID application 3.1
      //-----------------------------------------------------------------    

      if ( eleAlgorithm == 1 ) { 
	
	if(isBarrel) {		

	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep_1_bar + eleEcalHcalIsoHeep_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end+eleEcalHcalIsoHeep_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_end 
	     && ElectronHoE->at(iele) < eleHoEHeep_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep_end 
	     && passEcalHcalIsoCut == 1
	     && ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }

      //-----------------------------------------------------------------    
      // WP80 ID application
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 2 ) { 
	// ecal driven	    
	if( eleUseEcalDrivenWP && !ElectronHasEcalDrivenSeed->at(iele) ) continue;
	
	// isolation
	double ElectronCombRelIsoWP_bar  =  ( ElectronTrkIsoDR03->at(iele) 
					    + max( 0., ElectronEcalIsoDR03->at(iele) - 1. ) 
					    + ElectronHcalIsoDR03FullCone->at(iele) 
					    - rhoIso*TMath::Pi()*0.3*0.3 
					    ) / ElectronPt->at(iele) ;
	
	double ElectronCombRelIsoWP_end  =  ( ElectronTrkIsoDR03->at(iele) 
					      + ElectronEcalIsoDR03->at(iele) 
					      + ElectronHcalIsoDR03FullCone->at(iele) 
					      - rhoIso*TMath::Pi()*0.3*0.3 
					      ) / ElectronPt->at(iele) ;
	
	// conversions
	int isPhotConv = 0;
	if(eleUseHasMatchConvWP) {
	  if( ElectronHasMatchedConvPhot->at(iele) ) 
	    isPhotConv = 1;
	}
	else {
	  if( ElectronDist->at(iele) < eleDistWP && ElectronDCotTheta->at(iele) < eleDCotThetaWP )	
	    isPhotConv = 1;
	}

	if(isBarrel) {
	  
	  if( ElectronMissingHits->at(iele) <= eleMissingHitsWP              && 
	      isPhotConv == 0					             && 
	      ElectronCombRelIsoWP_bar < eleCombRelIsoWP_bar		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_bar       && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_bar && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_bar  )
	    passEleSel = 1;		
	  
	}//end barrel
	
	if(isEndcap) {		
	    
	  if( ElectronMissingHits->at(iele) == eleMissingHitsWP              && 
	      isPhotConv == 0						     && 
	      ElectronCombRelIsoWP_end < eleCombRelIsoWP_end		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_end 	     && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_end && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_end  )
	    passEleSel = 1;		
	  
	}//end endcap	
      }

      //-----------------------------------------------------------------    
      // HEEP ID application 3.2
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 3 ) { 
	
	if(isBarrel) {
		
	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep32_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep32_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep32_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep32_1_bar + eleEcalHcalIsoHeep32_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep32_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end+eleEcalHcalIsoHeep32_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep32_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_end 
	     && ElectronHoE->at(iele) < eleHoEHeep32_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep32_end 
	     && passEcalHcalIsoCut == 1
	     //&& ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep32_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep32_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }
      
      if ( passEleSel ) { 
	v_idx_ele_IDISO.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_STORE ) v_idx_ele_PtCut_IDISO_STORE.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_ANA   ) v_idx_ele_PtCut_IDISO_ANA  .push_back ( iele ) ;
      }

    }
    

    //-----------------------------------------------------------------
    // Selection: vertices
    //-----------------------------------------------------------------

    vector<int> v_idx_vertex_good;
    // loop over vertices
    for(int ivertex = 0; ivertex<VertexChi2->size(); ivertex++){
      if ( !(VertexIsFake->at(ivertex))
    	   && VertexNDF->at(ivertex) > vertexMinimumNDOF
    	   && fabs( VertexZ->at(ivertex) ) <= vertexMaxAbsZ
    	   && fabs( VertexRho->at(ivertex) ) <= vertexMaxd0 )
    	{
    	  v_idx_vertex_good.push_back(ivertex);
    	  //STDOUT("v_idx_vertex_good.size = "<< v_idx_vertex_good.size() );
    	}
    }

    //-----------------------------------------------------------------
    // Fill your single-object variables with values
    //-----------------------------------------------------------------

    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    
    fillVariableWithValue( "PassJSON", passJSON(run, ls, isData) );    
    // Set the value of the variableNames listed in the cutFile to their current value

    //event info
    fillVariableWithValue( "isData"   , isData     ) ;
    fillVariableWithValue( "bunch"    , bunch      ) ;
    fillVariableWithValue( "event"    , event      ) ;
    fillVariableWithValue( "ls"       , ls         ) ;
    fillVariableWithValue( "orbit"    , orbit      ) ;
    fillVariableWithValue( "run"      , run        ) ;

    // nVertex and pile-up
    fillVariableWithValue( "nVertex", VertexChi2->size() ) ;
    fillVariableWithValue( "nVertex_good", v_idx_vertex_good.size() ) ;

    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;

	bool PassHLT = false;
	if( triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v1") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v2") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v3") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v4") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v5") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v6") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v7") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v8") 
	    )
	  {
	    PassHLT = true;
	  }
	fillVariableWithValue( "PassHLT", PassHLT ) ;
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;
	fillVariableWithValue( "PassHLT", true ) ;
      }


    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    fillVariableWithValue( "PassHBHENoiseFilter", passHBHENoiseFilter ) ;
    fillVariableWithValue( "PassBeamHaloFilterLoose", passBeamHaloFilterLoose ) ;
    fillVariableWithValue( "PassBeamHaloFilterTight", passBeamHaloFilterTight ) ;
    fillVariableWithValue( "PassTrackingFailure", !isTrackingFailure ) ;
    fillVariableWithValue( "PassCaloBoundaryDRFilter", passCaloBoundaryDRFilter ) ;
    fillVariableWithValue( "PassEcalMaskedCellDRFilter", passEcalMaskedCellDRFilter ) ;
    
    // Evaluate cuts (but do not apply them)
    evaluateCuts();


    //Basic Event Selection
    if( passedCut("PassJSON") 
	&& passedCut("run")
	&& passedCut("PassBPTX0") 
	&& passedCut("PassBeamScraping") 
	&& passedCut("PassPrimaryVertex")
	&& passedCut("PassHBHENoiseFilter")
	&& passedCut("PassBeamHaloFilterTight") 
	&& passedCut("PassHLT")
	)
      {      
	//Loop over probes
	for(int iprobe=0; iprobe<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPt->size(); iprobe++)
	  {

	    TLorentzVector probe;
	    probe.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPt->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterEta->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPhi->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterEnergy->at(iprobe)
			       );

	    int isProbeBarrel = 0;
	    int isProbeEndcap = 0;
	    
	    if( fabs( probe.Eta() ) < eleEta_bar )       isProbeBarrel = 1;
	    if( fabs( probe.Eta() ) > eleEta_end_min &&
		fabs( probe.Eta() ) < eleEta_end_max )   isProbeEndcap = 1;


	    CreateAndFillUserTH1D("Pt_Probe", 200, 0, 200, probe.Pt() );

	    //Loop over tags
 	    for(int itag=0; itag<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->size(); itag++)
	      {

		TLorentzVector tag;
		tag.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEta->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPhi->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEnergy->at(itag)
				 );	    

		CreateAndFillUserTH1D("DR_ProbeVsTag", 100, 0, 10, probe.DeltaR(tag) );

		//-----------------
		//if the tag matches in DR with the probe --> move to the next tag candidate
		if( probe.DeltaR(tag) < 0.5) 
		  continue;
		//-----------------


		//Now we should have a good (tag-probe) pair

		bool IsProbeMatchedWithOfflineEle = false;
		bool IsProbeMatchedWithTriggerWP80 = false;
		bool IsProbeMatchedWithTriggerTag = false;
		bool IsTagMatchedWithOfflineEle = false;

		//Loop over offline electrons
		TLorentzVector RecoEleMatchedWithProbe;
		TLorentzVector RecoEleMatchedWithTag;
		for(int iele=0; iele<v_idx_ele_PtCut_IDISO_ANA.size(); iele++)
		  {
		    TLorentzVector ele;
		    ele.SetPtEtaPhiE( ElectronPt->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronEta->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronPhi->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronEnergy->at(v_idx_ele_PtCut_IDISO_ANA[iele])
				      );	    
		    
		    CreateAndFillUserTH1D("DR_ProbeVsEle", 100, 0, 10, probe.DeltaR(ele) );
		    CreateAndFillUserTH1D("DR_TagVsEle", 100, 0, 10, tag.DeltaR(ele) );

		    if( probe.DeltaR(ele) < 0.2 )
		      {
			IsProbeMatchedWithOfflineEle = true;
			RecoEleMatchedWithProbe = ele;
		      }

		    if( tag.DeltaR(ele) < 0.2 ) 
		      {
			IsTagMatchedWithOfflineEle = true;		    
			RecoEleMatchedWithTag = ele;
		      }

		  }

		//Loop over trigger WP80 electrons
		for(int iwp80=0; iwp80<HLTEle27WP80TrackIsoFilterPt->size(); iwp80++)
		  {
		    TLorentzVector wp80;
		    wp80.SetPtEtaPhiE(HLTEle27WP80TrackIsoFilterPt->at(iwp80),
				      HLTEle27WP80TrackIsoFilterEta->at(iwp80),
				      HLTEle27WP80TrackIsoFilterPhi->at(iwp80),
				      HLTEle27WP80TrackIsoFilterEnergy->at(iwp80)
				      );	    
		    
		    CreateAndFillUserTH1D("DR_ProbeVsWP80", 100, 0, 10, probe.DeltaR(wp80) );

		    if( probe.DeltaR(wp80) < 0.2 ) 
		      IsProbeMatchedWithTriggerWP80 = true;
		  }

		//Loop over trigger tag
		for(int itag2=0; itag2<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->size(); itag2++)
		  {
		    TLorentzVector tag2;
		    tag2.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEta->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPhi->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEnergy->at(itag2)
				      );	    

		    CreateAndFillUserTH1D("DR_ProbeVsTag2", 100, 0, 10, probe.DeltaR(tag2) );

		    if( probe.DeltaR(tag2) < 0.2 ) 
		      IsProbeMatchedWithTriggerTag = true;
		  }				

		TLorentzVector tag_probe_system;
		tag_probe_system = tag + probe;
		double mass = tag_probe_system.M();

		CreateAndFillUserTH1D("Mass_TagProbeSystem_NoCutOnProbe", 200, 0, 200, mass );

		if( IsProbeMatchedWithOfflineEle && IsTagMatchedWithOfflineEle )
		  {
		    CreateAndFillUserTH1D("Mass_TagProbeSystem_ProbeMatchedOfflineEle", 200, 0, 200, mass );

		    if( mass > 75 && mass < 95)
		      {
			CreateAndFillUserTH1D("Mass_TagProbeSystem_ForEfficiencyCalculation", 200, 0, 200, mass );

			FillUserTH1D("eta_recoEleMatchProbe_PassEleOffline", RecoEleMatchedWithProbe.Eta() );
			FillUserTH1D("pt_recoEleMatchProbe_PassEleOffline", RecoEleMatchedWithProbe.Pt() );			
			FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline", getVariableValue("nVertex") );			

			N_probe_PassEleOffline++;
			if( isProbeBarrel )
			  {
			    N_probe_PassEleOffline_bar++;
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_bar", getVariableValue("nVertex") );			
			  }
			if( isProbeEndcap )
			  {
			    N_probe_PassEleOffline_end++;
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_end", getVariableValue("nVertex") );			
			  }			

			if(IsProbeMatchedWithTriggerWP80)
			  {
			    FillUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndWP80", RecoEleMatchedWithProbe.Eta() );
			    FillUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndWP80", RecoEleMatchedWithProbe.Pt() );			
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80", getVariableValue("nVertex") );			

			    N_probe_PassEleOfflineAndWP80++;
			    if( isProbeBarrel )
			      {
				N_probe_PassEleOfflineAndWP80_bar++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_bar", getVariableValue("nVertex") );			
			      }
			    if( isProbeEndcap )
			      {
				N_probe_PassEleOfflineAndWP80_end++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_end", getVariableValue("nVertex") );			
			      }
			  }
			
			if(IsProbeMatchedWithTriggerTag)
			  {
			    FillUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndTag", RecoEleMatchedWithProbe.Eta() );
			    FillUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndTag", RecoEleMatchedWithProbe.Pt() );			
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag", getVariableValue("nVertex") );			

			    N_probe_PassEleOfflineAndTag++;
			    if( isProbeBarrel )
			      {
				N_probe_PassEleOfflineAndTag_bar++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_bar", getVariableValue("nVertex") );			
			      }
			    if( isProbeEndcap )
			      {
				N_probe_PassEleOfflineAndTag_end++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_end", getVariableValue("nVertex") );			
			      }
			  }
			
		      }//mass cut

		  }//IsProbeMatchedWithOfflineEle
		
	      }//end loop over tag


	  }//end loop over probe
	  


	//	fillVariableWithValue( "PassEcalMaskedCellDRFilter", passEcalMaskedCellDRFilter ) ;

	//triggerFired ("HLT_Photon30_CaloIdVL_v1") 


	//v_idx_ele_PtCut_IDISO_ANA.size()

	//CreateAndFillUserTH1D("ElePt_AfterPhoton30", 100, 0, 1000, ElectronPt -> at (v_idx_ele_PtCut_IDISO_ANA[0]) );

      }//end Basic Event Selection


  } // End of loop over events

  //##################################################

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      End analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------

  //Printout
  double eff_WP80 = double(N_probe_PassEleOfflineAndWP80)/double(N_probe_PassEleOffline);
  double eff_Tag = double(N_probe_PassEleOfflineAndTag)/double(N_probe_PassEleOffline);

  cout << "*** ALL ***" << endl;
  cout << "N_probe_PassEleOffline: " << N_probe_PassEleOffline << endl;
  cout << "N_probe_PassEleOfflineAndWP80: " << N_probe_PassEleOfflineAndWP80 << endl;
  cout << "N_probe_PassEleOfflineAndTag: " << N_probe_PassEleOfflineAndTag << endl;
  cout << endl;
  cout << "eff_WP80: " << eff_WP80 << " +/- " << sqrt(eff_WP80 * (1- eff_WP80) / N_probe_PassEleOffline ) << endl;  
  cout << "eff_Tag: " << eff_Tag << " +/- " << sqrt(eff_Tag * (1- eff_Tag) / N_probe_PassEleOffline ) << endl;  
  cout << endl;

  double eff_WP80_bar = double(N_probe_PassEleOfflineAndWP80_bar)/double(N_probe_PassEleOffline_bar);
  double eff_Tag_bar = double(N_probe_PassEleOfflineAndTag_bar)/double(N_probe_PassEleOffline_bar);

  cout << "*** BARREL ***" << endl;
  cout << "N_probe_PassEleOffline_bar: " << N_probe_PassEleOffline_bar << endl;
  cout << "N_probe_PassEleOfflineAndWP80_bar: " << N_probe_PassEleOfflineAndWP80_bar << endl;
  cout << "N_probe_PassEleOfflineAndTag_bar: " << N_probe_PassEleOfflineAndTag_bar << endl;
  cout << endl;
  cout << "eff_WP80_bar: " << eff_WP80_bar << " +/- " << sqrt(eff_WP80_bar * (1- eff_WP80_bar) / N_probe_PassEleOffline_bar ) << endl;  
  cout << "eff_Tag_bar: " << eff_Tag_bar << " +/- " << sqrt(eff_Tag_bar * (1- eff_Tag_bar) / N_probe_PassEleOffline_bar ) << endl;  
  cout << endl;

  double eff_WP80_end = double(N_probe_PassEleOfflineAndWP80_end)/double(N_probe_PassEleOffline_end);
  double eff_Tag_end = double(N_probe_PassEleOfflineAndTag_end)/double(N_probe_PassEleOffline_end);

  cout << "*** ENDCAP ***" << endl;
  cout << "N_probe_PassEleOffline_end: " << N_probe_PassEleOffline_end << endl;
  cout << "N_probe_PassEleOfflineAndWP80_end: " << N_probe_PassEleOfflineAndWP80_end << endl;
  cout << "N_probe_PassEleOfflineAndTag_end: " << N_probe_PassEleOfflineAndTag_end << endl;
  cout << endl;
  cout << "eff_WP80_end: " << eff_WP80_end << " +/- " << sqrt(eff_WP80_end * (1- eff_WP80_end) / N_probe_PassEleOffline_end ) << endl;  
  cout << "eff_Tag_end: " << eff_Tag_end << " +/- " << sqrt(eff_Tag_end * (1- eff_Tag_end) / N_probe_PassEleOffline_end ) << endl;  
  cout << endl;


  STDOUT("analysisClass::Loop() ends");
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
   
   //--------------------------------------------------------------------------
   // Final selection mass points
   //--------------------------------------------------------------------------

   const int n_lq_mass = 19;

   int LQ_MASS[n_lq_mass] = { 
     300,  350,  400, 450, 500, 550,  600,  650,
     700,  750,  800, 850, 900, 950, 1000, 1050,
     1100, 1150, 1200
   };

   std::vector<bool> passed_vector;
   
   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 ( !true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;
   
   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar            = getPreCutValue1("eleEta_bar");
   double eleEta_end1_min       = getPreCutValue1("eleEta_end1");
   double eleEta_end1_max       = getPreCutValue2("eleEta_end1");
   double eleEta_end2_min       = getPreCutValue1("eleEta_end2");
   double eleEta_end2_max       = getPreCutValue2("eleEta_end2");

   // fake rates
   
   double fakeRate_low_bar_p0    = getPreCutValue1 ( "fakeRate_bar"  );
   double fakeRate_low_bar_p1    = getPreCutValue2 ( "fakeRate_bar"  );
   double fakeRate_high_bar_p0   = getPreCutValue3 ( "fakeRate_bar"  );
				 
   double fakeRate_low_end1_p0   = getPreCutValue1 ( "fakeRate_end1" );
   double fakeRate_low_end1_p1   = getPreCutValue2 ( "fakeRate_end1" );
   double fakeRate_high_end1_p0  = getPreCutValue3 ( "fakeRate_end1" );
				 
   double fakeRate_low_end2_p0   = getPreCutValue1 ( "fakeRate_end2" );
   double fakeRate_low_end2_p1   = getPreCutValue2 ( "fakeRate_end2" );
   double fakeRate_high_end2_p0  = getPreCutValue3 ( "fakeRate_end2" );
   
   double eFakeRate_low_bar_p0   = getPreCutValue1 ( "eFakeRate_bar" );
   double eFakeRate_low_bar_p1   = getPreCutValue2 ( "eFakeRate_bar" );
   double eFakeRate_high_bar_p0  = getPreCutValue3 ( "eFakeRate_bar" );

   double eFakeRate_low_end1_p0  = getPreCutValue1 ( "eFakeRate_end1");
   double eFakeRate_low_end1_p1  = getPreCutValue2 ( "eFakeRate_end1");
   double eFakeRate_high_end1_p0 = getPreCutValue3 ( "eFakeRate_end1");

   double eFakeRate_low_end2_p0  = getPreCutValue1 ( "eFakeRate_end2");
   double eFakeRate_low_end2_p1  = getPreCutValue2 ( "eFakeRate_end2");
   double eFakeRate_high_end2_p0 = getPreCutValue3 ( "eFakeRate_end2");

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------

   CreateUserTH1D( "sTfrac_Jet1_PAS"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele1_PAS"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele2_PAS"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Jet_PAS"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele_PAS"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Jet1_PASandMee100"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele1_PASandMee100"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele2_PASandMee100"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Jet_PASandMee100"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele_PASandMee100"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Jet1_ROI"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele1_ROI"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele2_ROI"       ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Jet_ROI"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "sTfrac_Ele_ROI"        ,   100  ,  0.0    , 1.0      );
   CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "nJet_PASandMee100"        ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "nJet_ROI"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Pt1stEle_PASandMee100" , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Pt1stEle_ROI"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Pt2ndEle_PASandMee100" , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Pt2ndEle_ROI"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "EleChargeSum_PAS"         ,    3   , -2.5    , 2.5  );
   CreateUserTH1D( "EleChargeSum_PASandMee100",    3   , -2.5    , 2.5  );
   CreateUserTH1D( "EleChargeSum_ROI"         ,    3   , -2.5    , 2.5  );
   CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "MET_ROI"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt1stJet_PASandMee100" ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt1stJet_ROI"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "sTlep_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTlep_PASandMee100"    ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTlep_ROI"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee100"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee110"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee120"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee130"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee140"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee150"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee160"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee170"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee180"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee190"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PASandMee200"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_ROI"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_ROI"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PASandST445"       ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "MTenu_PAS"             ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "Me1j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j1_PASandMee100"    ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j1_ROI"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j_selected_PAS"     ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Meej_PAS"              ,    400 , 0       , 4000     );
   CreateUserTH1D( "Meej_ROI"              ,    400 , 0       , 4000     );

   CreateUserTH1D( "Eta1stJet_ROI"                   ,    100   , -5      , 5	  ); 
   CreateUserTH1D( "Eta1stEle_ROI"	             , 	100    , -5      , 5	  ); 
   CreateUserTH1D( "Eta2ndEle_ROI"	             , 	100    , -5      , 5	  ); 

   CreateUserTH1D( "Phi1stJet_ROI"	             , 	 60    , -3.1416 , +3.1416  ); 
   CreateUserTH1D( "Phi1stEle_ROI"	             , 	 60    , -3.1416 , +3.1416  ); 
   CreateUserTH1D( "Phi2ndEle_ROI"	             , 	 60    , -3.1416 , +3.1416  ); 
		            			     
   CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );
   CreateUserTH1D( "Ptee_PASandMee100"     ,    200 , 0       , 2000     );
   CreateUserTH1D( "Ptee_ROI"              ,    200 , 0       , 2000     );
   		                           
   CreateUserTH1D( "DCotTheta1stEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist1stEle_PAS"        ,    100 , 0.0, 1.0);  
   CreateUserTH1D( "DCotTheta2ndEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist2ndEle_PAS"        ,    100 , 0.0, 1.0);  
		                           
   CreateUserTH1D( "nVertex_PAS"                     ,    101   , -0.5   , 100.5	 ) ; 
   CreateUserTH1D( "nVertex_PASandMee100"            ,    101   , -0.5   , 100.5	 ) ; 
   CreateUserTH1D( "nVertex_ROI"                     ,    101   , -0.5   , 100.5	 ) ; 
   
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele1Ele2_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 

   CreateUserTH1D( "DR_ZJet1_PAS"        ,    getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_ZJet1_ROI"        ,    getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 

   CreateUserTH2D( "MeeVsST_PAS"                 ,     200, 0, 2000, 200, 0, 2000) ;
   CreateUserTH2D( "MeeVsST_PASandMee100"        ,     200, 0, 2000, 200, 0, 2000) ;
   CreateUserTH2D( "MeeVsST_ROI"                 ,     200, 0, 2000, 200, 0, 2000) ;


   CreateUserTH1D( "Mee_80_100_Preselection", 200, 60, 120 );
   CreateUserTH1D( "Mee_70_110_Preselection", 200, 60, 120 );
   CreateUserTH1D( "Mee_70_110_ST600_Preselection", 200, 60, 120 );
   
   CreateUserTH1D( "Mee_EBEB_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_PAS" 		   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "Mee_EBEB_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_80_100_PAS" 	     	   ,    60 , 60       , 120	 ); 
   
   CreateUserTH1D( "Mee_EBEB_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_70_110_PAS" 	     	   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "PileupWeight"   , 100, -10, 10 );
   CreateUserTH1D( "GeneratorWeight", 100, -2.0 , 2.0 );
   
   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {

     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int passedJSON = passJSON ( run, ls , isData ) ;
     
     //--------------------------------------------------------------------------
     // Find the right prescale for this event
     //--------------------------------------------------------------------------
     
     int min_prescale = 0;
     int passTrigger  = 0;

     if ( LooseEle1_hltPhotonPt > 0.0 ) { 
       if ( H_Photon30_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 30.  && LooseEle1_hltPhotonPt < 50. ) { passTrigger = 1; min_prescale = H_Photon30_CIdVL; } 
       if ( H_Photon50_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 50.  && LooseEle1_hltPhotonPt < 75. ) { passTrigger = 1; min_prescale = H_Photon50_CIdVL; } 
       if ( H_Photon75_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 75.  && LooseEle1_hltPhotonPt < 90. ) { passTrigger = 1; min_prescale = H_Photon75_CIdVL; } 
       if ( H_Photon90_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 90.  && LooseEle1_hltPhotonPt < 135.) { passTrigger = 1; min_prescale = H_Photon90_CIdVL; } 
       if ( H_Photon135      > 0.1 && LooseEle1_hltPhotonPt >= 135. && LooseEle1_hltPhotonPt < 150.) { passTrigger = 1; min_prescale = H_Photon135     ; } 
       if ( H_Photon150      > 0.1 && LooseEle1_hltPhotonPt >= 150.                                ) { passTrigger = 1; min_prescale = H_Photon150     ; } 
     }
          
     //--------------------------------------------------------------------------
     // What kind of event is this?
     //   - Barrel
     //   - Endcap 1 (eta < 2.0)
     //   - Endcap 2 (eta > 2.0) 
     //--------------------------------------------------------------------------
     
     bool ele1_isBarrel  = false;
     bool ele1_isEndcap1 = false;
     bool ele1_isEndcap2 = false;
     bool ele2_isBarrel  = false;
     bool ele2_isEndcap1 = false;
     bool ele2_isEndcap2 = false;
     
     if( fabs( LooseEle1_Eta  ) < eleEta_bar )        ele1_isBarrel  = true;
     if( fabs( LooseEle1_Eta  ) > eleEta_end1_min &&
	 fabs( LooseEle1_Eta  ) < eleEta_end1_max )   ele1_isEndcap1 = true;
     if( fabs( LooseEle1_Eta  ) > eleEta_end2_min &&
	 fabs( LooseEle1_Eta  ) < eleEta_end2_max )   ele1_isEndcap2 = true;

     if( fabs( LooseEle2_Eta  ) < eleEta_bar )        ele2_isBarrel  = true;
     if( fabs( LooseEle2_Eta  ) > eleEta_end1_min &&
	 fabs( LooseEle2_Eta  ) < eleEta_end1_max )   ele2_isEndcap1 = true;
     if( fabs( LooseEle2_Eta  ) > eleEta_end2_min &&
	 fabs( LooseEle2_Eta  ) < eleEta_end2_max )   ele2_isEndcap2 = true;

     bool ele1_isEndcap = ( ele1_isEndcap1 || ele1_isEndcap2 ) ;
     bool ele2_isEndcap = ( ele2_isEndcap1 || ele2_isEndcap2 ) ;

     bool isEBEB = ( ele1_isBarrel && ele2_isBarrel ) ;
     bool isEBEE = ( ( ele1_isBarrel && ele2_isEndcap ) ||
		     ( ele2_isBarrel && ele1_isEndcap ) );
     bool isEEEE = ( ele1_isEndcap && ele2_isEndcap ) ;
     bool isEB   = ( isEBEB || isEBEE ) ;

     //--------------------------------------------------------------------------
     // Determine which fake rates to use
     //--------------------------------------------------------------------------

     double fakeRate1  = 0.0;
     double fakeRate2  = 0.0;
     double eFakeRate1 = 0.0 ;
     double eFakeRate2 = 0.0;
     
     if ( LooseEle1_Pt < 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_low_bar_p0  + fakeRate_low_bar_p1  * LooseEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_bar_p1  * LooseEle1_Pt       ) * 
			     ( eFakeRate_low_bar_p1  * LooseEle1_Pt       )) + 
			    (( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 ) * 
			     ( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 )));
       }
       if ( ele1_isEndcap1 ) {
	 fakeRate1  = fakeRate_low_end1_p0 + fakeRate_low_end1_p1 * LooseEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end1_p1  * LooseEle1_Pt       ) * 
			     ( eFakeRate_low_end1_p1  * LooseEle1_Pt       )) + 
			    (( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 ) * 
			     ( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 )));

       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_low_end2_p0 + fakeRate_low_end2_p1 * LooseEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end2_p1  * LooseEle1_Pt       ) * 
			     ( eFakeRate_low_end2_p1  * LooseEle1_Pt       )) + 
			    (( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 ) * 
			     ( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 )));
       } 
     }
     else if  ( LooseEle1_Pt >= 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_high_bar_p0  ;
	 eFakeRate1 = eFakeRate_high_bar_p0 ;
       }
       if ( ele1_isEndcap1 ) { 
	 fakeRate1 = fakeRate_high_end1_p0 ;
	 eFakeRate1 = eFakeRate_high_end1_p0 ;
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_high_end2_p0 ;
	 eFakeRate1 = eFakeRate_high_end2_p0 ;
       }
     }

     if ( LooseEle2_Pt < 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate2  = fakeRate_low_bar_p0  + fakeRate_low_bar_p1  * LooseEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_bar_p1  * LooseEle2_Pt       ) * 
			     ( eFakeRate_low_bar_p1  * LooseEle2_Pt       )) + 
			    (( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 ) * 
			     ( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 )));
       }
       if ( ele1_isEndcap1 ) {
	 fakeRate2 = fakeRate_low_end1_p0 + fakeRate_low_end1_p1 * LooseEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_end1_p1  * LooseEle2_Pt       ) * 
			     ( eFakeRate_low_end1_p1  * LooseEle2_Pt       )) + 
			    (( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 ) * 
			     ( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 )));
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate2 = fakeRate_low_end2_p0 + fakeRate_low_end2_p1 * LooseEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_end2_p1  * LooseEle2_Pt       ) * 
			     ( eFakeRate_low_end2_p1  * LooseEle2_Pt       )) + 
			    (( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 ) * 
			     ( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 )));
       }
     }

     else if  ( LooseEle2_Pt >= 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate2  = fakeRate_high_bar_p0  ;
	 eFakeRate2 = eFakeRate_high_bar_p0;
       }
       if ( ele1_isEndcap1 ) { 
	 fakeRate2 = fakeRate_high_end1_p0 ;
	 eFakeRate2 = eFakeRate_high_end1_p0;
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate2 = fakeRate_high_end2_p0 ;
	 eFakeRate2 = eFakeRate_high_end2_p0;
       }
     }

     //--------------------------------------------------------------------------
     // Finally have the effective fake rate
     //--------------------------------------------------------------------------

     double fakeRateEffective  = fakeRate1 * fakeRate2;
     double eFakeRateEffective = fakeRateEffective * sqrt (  ( eFakeRate1 / fakeRate1 ) * ( eFakeRate1 / fakeRate1 ) +
							     ( eFakeRate2 / fakeRate2 ) * ( eFakeRate2 / fakeRate2 ) );
     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // reweighting
     fillVariableWithValue ( "Reweighting", 1, fakeRateEffective * min_prescale ) ; 
     
     // JSON variable
     fillVariableWithValue(   "PassJSON"                      , passedJSON              , fakeRateEffective * min_prescale ) ; 

     // Noise filters
     fillVariableWithValue(   "PassHBHENoiseFilter"	      , PassHBHENoiseFilter                              , fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight                          , fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassBadEESupercrystalFilter"   , ( isData == 1 ) ? PassBadEESupercrystalFilter : 1, fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassBeamScraping"	      , ( isData == 1 ) ? PassBeamScraping	      : 1, fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassEcalDeadCellBoundEnergy"   , PassEcalDeadCellBoundEnergy                      , fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassEcalDeadCellTrigPrim"      , PassEcalDeadCellTrigPrim                         , fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassEcalLaserCorrFilter"       , ( isData == 1 ) ? PassEcalLaserCorrFilter     : 1, fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassHcalLaserEventFilter"      , ( isData == 1 ) ? PassHcalLaserEventFilter    : 1, fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassPhysDecl"		      , ( isData == 1 ) ? PassPhysDecl		      : 1, fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassPrimaryVertex"	      , PassPrimaryVertex                                , fakeRateEffective * min_prescale );
     fillVariableWithValue(   "PassTrackingFailure"	      , ( isData == 1 ) ? PassTrackingFailure	      : 1, fakeRateEffective * min_prescale );
     
     // Electrons
     int PassNEle = 0;
     if ( nLooseEle_ptCut == 2 ) PassNEle = 1;
     
     double M_ej_avg;
     double M_ej_min;
     double M_ej_max;

     // Muons
     int PassNMuon = 0;
     if ( nMuon_ptCut == 0 ) PassNMuon = 1;

     fillVariableWithValue ( "PassHLT"                        , passTrigger             , fakeRateEffective * min_prescale ) ;
     fillVariableWithValue("nEle_hltMatched",-1, fakeRateEffective * min_prescale ) ;
     fillVariableWithValue("nJet_hltMatched",-1, fakeRateEffective * min_prescale ) ;
     			
							        
     // Electrons								        
     fillVariableWithValue(   "PassNEle"                      , PassNEle                , fakeRateEffective * min_prescale ) ;
     if ( nLooseEle_store >= 1 ) { 							        
       fillVariableWithValue( "Ele1_Pt"                       , LooseEle1_Pt            , fakeRateEffective * min_prescale ) ;
     }										        
     if ( nLooseEle_store >= 2 ) { 							        
       fillVariableWithValue( "Ele2_Pt"                       , LooseEle2_Pt            , fakeRateEffective * min_prescale ) ;
       fillVariableWithValue( "M_e1e2"                        , M_e1e2                  , fakeRateEffective * min_prescale ) ;
     }

     // Jets
     fillVariableWithValue(   "nJet"                          , nJetLooseEle_ptCut      , fakeRateEffective * min_prescale ) ;
     if ( nJetLooseEle_store >= 1 ) { 						                
       fillVariableWithValue( "Jet1_Pt"                       , JetLooseEle1_Pt         , fakeRateEffective * min_prescale ) ;
       fillVariableWithValue( "Jet1_Eta"                      , JetLooseEle1_Eta        , fakeRateEffective * min_prescale ) ;
     }
     
     if ( nJetLooseEle_store >= 2 ) { 
       
       if ( nLooseEle_store >= 2 && nJetLooseEle_store >= 2) {
	 if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
	   M_ej_avg = (M_e1j1 + M_e2j2) / 2.0;
	   if    ( M_e1j1 < M_e2j2 ) { M_ej_min = M_e1j1; M_ej_max = M_e2j2; }
	   else                      { M_ej_min = M_e2j2; M_ej_max = M_e1j1; }
	 }
	 else { 
	   M_ej_avg = (M_e1j2 + M_e2j1) / 2.0;
	   if    ( M_e1j2 < M_e2j1 ) { M_ej_min = M_e1j2; M_ej_max = M_e2j1; }
	   else                      { M_ej_min = M_e2j1; M_ej_max = M_e1j2; }
	 }
       }      
     }

     double sT_eej = LooseEle1_Pt + LooseEle2_Pt + JetLooseEle1_Pt;

     // Muons
     fillVariableWithValue(   "PassNMuon"                     , PassNMuon               , fakeRateEffective * min_prescale ) ;

     // DeltaR
     if ( nLooseEle_store >= 2 && nJetLooseEle_store >= 1) {
       fillVariableWithValue( "DR_Ele1Jet1"                   , DR_Ele1Jet1             , fakeRateEffective * min_prescale ) ;
       fillVariableWithValue( "DR_Ele2Jet1"                   , DR_Ele2Jet1             , fakeRateEffective * min_prescale ) ;
     }

     // sT
     if ( nLooseEle_store >= 2 && nJetLooseEle_store >= 2) {
       fillVariableWithValue( "sT_eej"                        , sT_eej                  , fakeRateEffective  * min_prescale ) ;
     }      
     
     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Did we at least pass the noise filtes?
     //--------------------------------------------------------------------------
     
     bool passed_minimum = ( passedAllPreviousCuts("PassTrackingFailure") && passedCut ("PassTrackingFailure"));
     
     //--------------------------------------------------------------------------
     // Did we pass preselection?
     //--------------------------------------------------------------------------
     
     bool passed_preselection = ( passedAllPreviousCuts("M_e1e2") && passedCut ("M_e1e2") );
     
     //--------------------------------------------------------------------------
     // Are we in the region of interest?
     //--------------------------------------------------------------------------

     bool passed_region_of_interest = bool ( passed_preselection && M_e1e2 > 170. && sT_eej > 600.0 );
     
     //--------------------------------------------------------------------------
     // Fill plots with no selection applied
     //--------------------------------------------------------------------------

     FillUserTH1D( "PileupWeight"   , -1.0 );
     FillUserTH1D( "GeneratorWeight", -1.0 );

     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------

     if ( passed_preselection ) {
       
       //--------------------------------------------------------------------------
       // Recalculate some variables
       //--------------------------------------------------------------------------

       TLorentzVector e1, j1, e2, mu, met;
       TLorentzVector e1e2mu;
       TLorentzVector eej, ee;
       
       e1.SetPtEtaPhiM ( LooseEle1_Pt, LooseEle1_Eta, LooseEle1_Phi, 0.0 );
       e2.SetPtEtaPhiM ( LooseEle2_Pt, LooseEle2_Eta, LooseEle2_Phi, 0.0 );
       j1.SetPtEtaPhiM ( JetLooseEle1_Pt, JetLooseEle1_Eta, JetLooseEle1_Phi, 0.0 );
       mu.SetPtEtaPhiM ( Muon1_Pt, Muon1_Eta, Muon1_Phi, 0.0 );
       met.SetPtEtaPhiM ( PFMET_Type01XY_Pt, 0.0, PFMET_Type01XY_Phi, 0.0 );

       eej  = e1 + e2 + j1;
       ee   = e1 + e2;
       
       double DR_Ele1Ele2 = e1.DeltaR( e2 );       
       double M_eej  = eej.M();
       double DR_ZJ1 = ee.DeltaR ( j1 );
       
       //--------------------------------------------------------------------------
       // Preselection histograms
       //--------------------------------------------------------------------------

       FillUserTH1D("DR_Ele1Ele2_PAS"	   , DR_Ele1Ele2                        , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("EleChargeSum_PAS"     , LooseEle1_Charge + LooseEle2_Charge, min_prescale * fakeRateEffective ) ;
       FillUserTH1D("sT_PAS"               , sT_eejj                            , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("nElectron_PAS"        , nLooseEle_ptCut                    , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("nMuon_PAS"            , nMuon_ptCut                        , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("nJet_PAS"             , nJetLooseEle_ptCut                 , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Pt1stEle_PAS"	   , LooseEle1_Pt                       , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Eta1stEle_PAS"	   , LooseEle1_Eta                      , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Phi1stEle_PAS"	   , LooseEle1_Phi                      , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Pt2ndEle_PAS"	   , LooseEle2_Pt                       , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Eta2ndEle_PAS"	   , LooseEle2_Eta                      , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Phi2ndEle_PAS"	   , LooseEle2_Phi                      , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Charge1stEle_PAS"	   , LooseEle1_Charge                   , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Charge2ndEle_PAS"	   , LooseEle2_Charge                   , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("MET_PAS"              , PFMET_Type01XY_Pt                  , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("METPhi_PAS"	   , PFMET_Type01XY_Phi                 , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Pt1stJet_PAS"         , JetLooseEle1_Pt                    , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Eta1stJet_PAS"        , JetLooseEle1_Eta                   , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Phi1stJet_PAS"	   , JetLooseEle1_Phi                   , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("sTlep_PAS"            , LooseEle1_Pt + LooseEle2_Pt        , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Mee_PAS"		   , M_e1e2                             , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("MTenu_PAS"            , MT_Ele1MET                         , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Me1j1_PAS"            , M_e1j1                             , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Me2j1_PAS"            , M_e2j1                             , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Ptee_PAS"             , Pt_e1e2                            , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("DCotTheta1stEle_PAS"  , LooseEle1_DCotTheta                , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Dist1stEle_PAS"       , LooseEle1_Dist                     , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("DCotTheta2ndEle_PAS"  , LooseEle2_DCotTheta                , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Dist2ndEle_PAS"       , LooseEle2_Dist                     , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("nVertex_PAS"          , nVertex                            , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("DR_Ele1Jet1_PAS"	   , DR_Ele1Jet1                        , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("DR_Ele2Jet1_PAS"	   , DR_Ele2Jet1                        , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("Meej_PAS"             , M_eej                              , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("DR_ZJet1_PAS"         , DR_ZJ1                             , min_prescale * fakeRateEffective ) ;
       FillUserTH1D("sTfrac_Jet1_PAS"      , JetLooseEle1_Pt / sT_eejj          , min_prescale * fakeRateEffective );
       FillUserTH1D("sTfrac_Ele1_PAS"      , LooseEle1_Pt / sT_eejj             , min_prescale * fakeRateEffective );
       FillUserTH1D("sTfrac_Ele2_PAS"      , LooseEle2_Pt / sT_eejj             , min_prescale * fakeRateEffective );
       FillUserTH1D("sTfrac_Jet_PAS"       , ( JetLooseEle1_Pt  ) / sT_eejj     , min_prescale * fakeRateEffective );
       FillUserTH1D("sTfrac_Ele_PAS"       , ( LooseEle1_Pt + LooseEle2_Pt ) / sT_eejj, min_prescale * fakeRateEffective );

       FillUserTH2D("MeeVsST_PAS" , M_e1e2, sT_eej, min_prescale * fakeRateEffective ) ;	   
       
       //--------------------------------------------------------------------------
       // Preselection + event type (EBEB, EEEB, EEEE, etc)
       //--------------------------------------------------------------------------

       if      ( isEB   ) FillUserTH1D( "Mee_EB_PAS"  , M_e1e2, min_prescale * fakeRateEffective  ); 
       if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
       else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
       else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
       
       //--------------------------------------------------------------------------
       // Preselection + high ST plot
       //--------------------------------------------------------------------------

       if ( sT_eej > 445. ) FillUserTH1D( "Mee_PASandST445", M_e1e2, min_prescale * fakeRateEffective ) ;

       //--------------------------------------------------------------------------
       // High M(ee) plots
       //--------------------------------------------------------------------------

       if ( M_e1e2 > 100. ) FillUserTH1D("sT_PASandMee100"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 110. ) FillUserTH1D("sT_PASandMee110"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 120. ) FillUserTH1D("sT_PASandMee120"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 130. ) FillUserTH1D("sT_PASandMee130"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 140. ) FillUserTH1D("sT_PASandMee140"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 150. ) FillUserTH1D("sT_PASandMee150"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 160. ) FillUserTH1D("sT_PASandMee160"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 170. ) FillUserTH1D("sT_PASandMee170"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 180. ) FillUserTH1D("sT_PASandMee180"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 190. ) FillUserTH1D("sT_PASandMee190"   , sT_eej , min_prescale * fakeRateEffective  ); 
       if ( M_e1e2 > 200. ) FillUserTH1D("sT_PASandMee200"   , sT_eej , min_prescale * fakeRateEffective  ); 
       
       
       if ( M_e1e2 > 100. ) { 

	 FillUserTH1D("Me1j1_PASandMee100"           , M_e1j1                              , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("Ptee_PASandMee100"            , Pt_e1e2                             , min_prescale * fakeRateEffective ) ;
	 FillUserTH2D("MeeVsST_PASandMee100"         , M_e1e2, sT_eej                      , min_prescale * fakeRateEffective ) ;	   
	 FillUserTH1D("nVertex_PASandMee100"         , nVertex                             , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sT_PASandMee100"              , sT_eej                              , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("EleChargeSum_PASandMee100"    , LooseEle1_Charge + LooseEle2_Charge , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("nJet_PASandMee100"            , nJetLooseEle_ptCut                  , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sTlep_PASandMee100"           , LooseEle1_Pt    + LooseEle2_Pt      , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("Pt1stEle_PASandMee100"        , LooseEle1_Pt                        , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("Pt2ndEle_PASandMee100"        , LooseEle2_Pt                        , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("Pt1stJet_PASandMee100"        , JetLooseEle1_Pt                     , min_prescale * fakeRateEffective ) ;

	 FillUserTH1D("sTfrac_Jet1_PASandMee100"     , JetLooseEle1_Pt / sT_eej                        , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sTfrac_Ele1_PASandMee100"     , LooseEle1_Pt / sT_eej                           , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sTfrac_Ele2_PASandMee100"     , LooseEle2_Pt / sT_eej                           , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sTfrac_Jet_PASandMee100"      , ( JetLooseEle1_Pt )                   / sT_eej  , min_prescale * fakeRateEffective ) ;
	 FillUserTH1D("sTfrac_Ele_PASandMee100"      , ( LooseEle1_Pt + LooseEle2_Pt ) / sT_eej        , min_prescale * fakeRateEffective ) ;

       }

       //--------------------------------------------------------------------------
       // Preselection + M(ee) normalization region plots
       //--------------------------------------------------------------------------
       
       if ( M_e1e2 > 80.0 && M_e1e2 < 100.0 ){
	 FillUserTH1D("Mee_80_100_Preselection", M_e1e2, min_prescale * fakeRateEffective ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_80_100_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_80_100_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_80_100_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_80_100_PAS"  , M_e1e2, min_prescale * fakeRateEffective  ); 
       }

       if ( M_e1e2 > 70.0 && M_e1e2 < 110.0 ){
	 FillUserTH1D("Mee_70_110_Preselection", M_e1e2, min_prescale * fakeRateEffective ) ;
	 if ( sT_eej > 600 ) 	 FillUserTH1D("Mee_70_110_ST600_Preselection", M_e1e2, min_prescale * fakeRateEffective ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_70_110_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_70_110_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_70_110_PAS", M_e1e2, min_prescale * fakeRateEffective  ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_70_110_PAS"  , M_e1e2, min_prescale * fakeRateEffective  ); 
       }

       //--------------------------------------------------------------------------
       // Region of interest plots
       //-------------------------------------------------------------------------- 
       
       if ( passed_region_of_interest ) { 
	 FillUserTH1D("Me1j1_ROI"           , M_e1j1                                         , min_prescale * fakeRateEffective );
	 FillUserTH1D("Ptee_ROI"            , Pt_e1e2                                        , min_prescale * fakeRateEffective );
	 FillUserTH1D("Eta1stJet_ROI"       , JetLooseEle1_Eta                               , min_prescale * fakeRateEffective );
	 FillUserTH1D("Eta1stEle_ROI"	    , LooseEle1_Eta                                  , min_prescale * fakeRateEffective );
	 FillUserTH1D("Eta2ndEle_ROI"	    , LooseEle2_Eta                                  , min_prescale * fakeRateEffective );
	 FillUserTH1D("Phi1stJet_ROI"       , JetLooseEle1_Phi                               , min_prescale * fakeRateEffective );
	 FillUserTH1D("Phi1stEle_ROI"	    , LooseEle1_Phi                                  , min_prescale * fakeRateEffective );
	 FillUserTH1D("Phi2ndEle_ROI"	    , LooseEle2_Phi                                  , min_prescale * fakeRateEffective );
	 FillUserTH2D("MeeVsST_ROI"         , M_e1e2                                , sT_eej , min_prescale * fakeRateEffective );	   
	 FillUserTH1D("Mee_ROI"		    , M_e1e2                                         , min_prescale * fakeRateEffective );
	 FillUserTH1D("nVertex_ROI"         , nVertex                                        , min_prescale * fakeRateEffective );
	 FillUserTH1D("EleChargeSum_ROI"    , LooseEle1_Charge + LooseEle2_Charge            , min_prescale * fakeRateEffective );
	 FillUserTH1D("nJet_ROI"            , nJetLooseEle_ptCut                             , min_prescale * fakeRateEffective );
	 FillUserTH1D("Meej_ROI"            , M_eej                                          , min_prescale * fakeRateEffective );
	 FillUserTH1D("DR_ZJet1_ROI"        , DR_ZJ1                                         , min_prescale * fakeRateEffective );
	 FillUserTH1D("MET_ROI"             , PFMET_Type01XY_Pt                              , min_prescale * fakeRateEffective );
	 FillUserTH1D("sT_ROI"              , sT_eej                                         , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTlep_ROI"           , LooseEle1_Pt    + LooseEle2_Pt                 , min_prescale * fakeRateEffective );
	 FillUserTH1D("Pt1stEle_ROI"        , LooseEle1_Pt                                   , min_prescale * fakeRateEffective );
	 FillUserTH1D("Pt2ndEle_ROI"        , LooseEle2_Pt                                   , min_prescale * fakeRateEffective );
	 FillUserTH1D("Pt1stJet_ROI"        , JetLooseEle1_Pt                                , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTfrac_Jet1_ROI"     , JetLooseEle1_Pt / sT_eej                       , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTfrac_Ele1_ROI"     , LooseEle1_Pt / sT_eej                          , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTfrac_Ele2_ROI"     , LooseEle2_Pt / sT_eej                          , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTfrac_Jet_ROI"      , ( JetLooseEle1_Pt  )                  / sT_eej , min_prescale * fakeRateEffective );
	 FillUserTH1D("sTfrac_Ele_ROI"      , ( LooseEle1_Pt + LooseEle2_Pt )       / sT_eej , min_prescale * fakeRateEffective );
       }
     } // End preselection 
   } // End loop over events

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 (  true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Pileup reweighting initialization
   //--------------------------------------------------------------------------
   
   // Lumi3DReWeighting lumiWeights = Lumi3DReWeighting("/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_MC_Summer11_PU_S4_3DReweighting.root",
   // 						     "/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_finebin_2011_finebin.root",
   // 						     "pileup", "pileup");
   // lumiWeights.weight3D_init(1.0);
   
   //--------------------------------------------------------------------------
   // Any extra features
   //--------------------------------------------------------------------------
   
   TProfile * profile_run_vs_nvtx_HLT = new TProfile("run_vs_nvtx_HLT", "", 20000 , 160300  , 180300 );
   TProfile * profile_run_vs_nvtx_PAS = new TProfile("run_vs_nvtx_PAS", "", 20000 , 160300  , 180300 );
   
   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar_max = getPreCutValue1("eleEta_bar");
   double eleEta_end_min = getPreCutValue1("eleEta_end1");
   double eleEta_end_max = getPreCutValue2("eleEta_end2");

   // dataset
   
   int dataset  = getPreCutValue1("dataset") ;
   bool select2011A = ( dataset == 0 );
   bool select2011B = ( dataset == 1 );
   bool select2011  = ( dataset == 2 );

   if ( ! select2011A &&
	! select2011B &&
	! select2011 ) {
     std::cout << "Error: Must choose dataset to be 0 (2011A), 1 (2011B), or 2 (all 2011)" << std::endl;
   }

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------
   
   // gap: 1.442 - 1.560

   // eleEta_bar            	1.442        -                    -               -               -1
   // eleEta_end1            	1.560        2.0                  -               -               -1
   // eleEta_end2            	2.000        2.5                  -               -               -1
   
   CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METSig_PAS"            ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"        ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"          ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt2ndJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Eta2ndJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Phi2ndJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "sTlep_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTjet_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mjj_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Me1j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j_selected_PAS"     ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j_selected_PAS"     ,    200 , 0       , 2000     );
   CreateUserTH1D( "Mej_selected_avg_PAS"  ,    200 , 0       , 2000     );
   CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
   CreateUserTH1D( "run_PAS"               ,    20000 , 160300  , 180300 );
   CreateUserTH1D( "run_HLT"               ,    20000 , 160300  , 180300 );
		                           
   CreateUserTH1D( "PtRealEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "EtaRealEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "PhiRealEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "ChargeRealEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 

   CreateUserTH1D( "PtRealMuon_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "EtaRealMuon_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "PhiRealMuon_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "ChargeRealMuon_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   
   CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );
   		                           
   CreateUserTH1D( "DCotTheta1stEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist1stEle_PAS"        ,    100 , 0.0, 1.0);  
   CreateUserTH1D( "DCotTheta2ndEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist2ndEle_PAS"        ,    100 , 0.0, 1.0);  
		                           
   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 
		                           
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele1Jet2_PAS"	   , 	getHistoNBins("DR_Ele1Jet2"), getHistoMin("DR_Ele1Jet2"), getHistoMax("DR_Ele1Jet2")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet2_PAS"	   , 	getHistoNBins("DR_Ele2Jet2"), getHistoMin("DR_Ele2Jet2"), getHistoMax("DR_Ele2Jet2")     ) ; 
   CreateUserTH1D( "DR_Jet1Jet2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 
   CreateUserTH1D( "DR_Ele1Ele2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 
   CreateUserTH1D( "minDR_EleJet_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ; 

   CreateUserTH1D( "DR_RealEleJet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_RealEleJet2_PAS"	   , 	getHistoNBins("DR_Ele1Jet2"), getHistoMin("DR_Ele1Jet2"), getHistoMax("DR_Ele1Jet2")     ) ; 
   CreateUserTH1D( "DR_RealMuonJet1_PAS"   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ; 
   CreateUserTH1D( "DR_RealMuonJet2_PAS"   , 	getHistoNBins("DR_Ele2Jet2"), getHistoMin("DR_Ele2Jet2"), getHistoMax("DR_Ele2Jet2")     ) ; 

   CreateUserTH2D( "Me1jVsMe2j_selected",     200, 0, 2000, 200, 0, 2000) ;
   CreateUserTH2D( "Me1jVsMe2j_rejected",     200, 0, 2000, 200, 0, 2000) ;

   CreateUserTH1D( "MTeemunu_PAS"          ,    200 , 0       , 1000	 ); 

   CreateUserTH1D( "Mee_80_100_Preselection", 200, 60, 120 );
   CreateUserTH1D( "Mee_70_110_Preselection", 200, 60, 120 );

   CreateUserTH1D( "Mee_EBEB_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_PAS" 		   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "Mee_EBEB_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_80_100_PAS" 	     	   ,    60 , 60       , 120	 ); 
   
   CreateUserTH1D( "Mee_EBEB_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_70_110_PAS" 	     	   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "PileupWeight"   , 100, -10, 10 );
   CreateUserTH1D( "GeneratorWeight", 100, -2.0, 2.0);


   CreateUserTH1D("Mej_selected_avg_LQ250"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ350"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ400"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ450"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ500"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ550"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ600"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ650"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ750"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_avg_LQ850"         ,   40  , 0        , 2000     );

   CreateUserTH1D("Mej_selected_min_LQ250"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ350"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ400"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ450"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ500"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ550"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ600"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ650"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ750"         ,   40  , 0        , 2000     );
   CreateUserTH1D("Mej_selected_min_LQ850"         ,   40  , 0        , 2000     );

   CreateUserTH1D("sT_eejj_LQ250"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ350"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ400"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ450"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ500"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ550"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ600"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ650"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ750"                  ,   20  , 0        , 2000     );
   CreateUserTH1D("sT_eejj_LQ850"                  ,   20  , 0        , 2000     );

   CreateUserTH1D("Mee_LQ250"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ350"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ400"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ450"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ500"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ550"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ600"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ650"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ750"                      ,   40  , 0        , 2000     );
   CreateUserTH1D("Mee_LQ850"                      ,   40  , 0        , 2000     );

   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {

     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int    passedJSON = passJSON ( run, ls , isData ) ;

     //--------------------------------------------------------------------------
     // Is this the dataset we want?
     //--------------------------------------------------------------------------
     
     int PassDataset = 1;
     if ( isData ) { 
       PassDataset = 0;
       if ( select2011A ){ 
	 if ( run >= 160329 && run <= 175770 ) PassDataset = 1;
       }
       if ( select2011B ){
	 if ( run >= 175832 && run <= 180296 ) PassDataset = 1;
       }
       if ( select2011 ) {
	 PassDataset = 1;
       }
     }

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------

     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;
     
     //--------------------------------------------------------------------------
     // Calculate electron variables with muon
     //--------------------------------------------------------------------------

     TLorentzVector e1, e2, met, j1, j2, j3;
     met.SetPtEtaPhiM ( MET_Pt, 0.0, MET_Phi, 0.0 );
     if ( nJet_Ana >= 1  ){
       j1.SetPtEtaPhiM ( Jet1_Pt , Jet1_Eta , Jet1_Phi , 0.0 );
       if ( nJet_Ana >= 2  ) {
	 j2.SetPtEtaPhiM ( Jet2_Pt , Jet2_Eta , Jet2_Phi , 0.0 );
	 if ( nJet_Ana >= 3  ) 
	   j3.SetPtEtaPhiM ( Jet3_Pt , Jet3_Eta , Jet3_Phi , 0.0 );
       }
     }

     double DR_Ele1Ele2_new ;
     double DR_Ele1Jet3_new ;
     double DR_Ele2Jet3_new ;
     double Ele1_Pt_new     ;
     double Ele2_Pt_new     ;
     double Ele1_Eta_new    ;
     double Ele2_Eta_new    ;
     double Ele1_Phi_new    ;
     double Ele2_Phi_new    ;
     double Ele1_Charge_new ;
     double Ele2_Charge_new ;

     double DR_Ele1Jet1_new;
     double DR_Ele2Jet1_new;
     double DR_Ele1Jet2_new;
     double DR_Ele2Jet2_new;
           
     double M_e1j1_new;
     double M_e2j1_new;
     double M_e1j2_new;
     double M_e2j2_new;

     double M_e1e2_new  ;
     double Pt_e1e2_new ;
     double MT_Ele1MET_new;

     double sT_eejj_new;

     bool isEB_old = false;
     bool isEE_old = false;
     bool e1_isMuon = false;
     bool e1_isEle  = false;
     bool e2_isMuon = false;
     bool e2_isEle  = false;


     if ( nMuon_Ana >= 1 && nEle_Ana >= 1  ){
       
       bool isEB_old = ( fabs(Ele1_Eta) < eleEta_bar_max  ) ;
       bool isEE_old = ( fabs(Ele1_Eta) > eleEta_end_min &&
			 fabs(Ele1_Eta) < eleEta_end_max ) ;
       
       if ( Ele1_Pt >= Muon1_Pt ) {
	 e1.SetPtEtaPhiM ( Ele1_Pt , Ele1_Eta , Ele1_Phi , 0.0 );
	 e2.SetPtEtaPhiM ( Muon1_Pt, Muon1_Eta, Muon1_Phi, 0.0 );
	 Ele2_Charge_new = Muon1_Charge;
	 Ele1_Charge_new = Ele1_Charge;
	 e1_isEle  = true;
	 e2_isMuon = true;
       }
       else { 
	 e1.SetPtEtaPhiM ( Muon1_Pt, Muon1_Eta, Muon1_Phi, 0.0 );
	 e2.SetPtEtaPhiM ( Ele1_Pt , Ele1_Eta , Ele1_Phi , 0.0 );
	 Ele2_Charge_new = Ele1_Charge;
	 Ele1_Charge_new = Muon1_Charge;
	 e1_isMuon   = true;
	 e2_isEle    = true;
       }

       Ele1_Pt_new  = e1.Pt();
       Ele1_Eta_new = e1.Eta();
       Ele1_Phi_new = e1.Phi();
       
       Ele2_Pt_new  = e2.Pt();
       Ele2_Eta_new = e2.Eta();
       Ele2_Phi_new = e2.Phi();

       TLorentzVector e1e2 = e1 + e2;
       M_e1e2_new  = e1e2.M();
       Pt_e1e2_new = e1e2.Pt();

       DR_Ele1Ele2_new = e1.DeltaR( e2 ) ;
       MT_Ele1MET_new = sqrt(2 * e1.Pt() * met.Pt() * (1 - cos(met.DeltaPhi(e1))));
       
       if ( nJet_Ana >= 1 ){

	 TLorentzVector e1j1 = e1 + j1;
	 TLorentzVector e2j1 = e2 + j1;
	 M_e1j1_new = e1j1.M();
	 M_e2j1_new = e2j1.M();

	 DR_Ele1Jet1_new = e1.DeltaR ( j1 ) ;
	 DR_Ele2Jet1_new = e2.DeltaR ( j1 ) ;
	 
	 if ( nJet_Ana >= 2 ){
	   DR_Ele1Jet2_new = e1.DeltaR ( j2 ) ;
	   DR_Ele2Jet2_new = e2.DeltaR ( j2 ) ;

	   TLorentzVector e1j2 = e1 + j2;
	   TLorentzVector e2j2 = e2 + j2;
	   M_e1j2_new = e1j2.M();
	   M_e2j2_new = e2j2.M();
	   
	   sT_eejj_new = e1.Pt() + e2.Pt() + j1.Pt() + j2.Pt();
	   
	   if ( nJet_Ana >= 3 ){
	     DR_Ele1Jet3_new = e1.DeltaR ( j3 ) ;
	     DR_Ele2Jet3_new = e2.DeltaR ( j3 ) ;
	   }
	 }
       }
     }
     
     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     //fillVariableWithValue(   "PassBPTX0"                     , PassBPTX0                    ) ; 
     //fillVariableWithValue(   "PassPhysDecl"                  , PassPhysDecl                 ) ; 
     //fillVariableWithValue(   "PassBeamScraping"              , PassBeamScraping             ) ; 
     //fillVariableWithValue(   "PassPrimaryVertex"             , PassPrimaryVertex            ) ; 
     //fillVariableWithValue(   "PassBeamHaloFilterLoose"	      , PassBeamHaloFilterLoose	     ) ; 
     //fillVariableWithValue(   "PassTrackingFailure"           , PassTrackingFailure          ) ; 
     //fillVariableWithValue(   "PassCaloBoundaryDRFilter"      , PassCaloBoundaryDRFilter     ) ; 
     //fillVariableWithValue(   "PassEcalMaskedCellDRFilter"    , PassEcalMaskedCellDRFilter   ) ; 

     // Fill HLT 

     int passHLT = 1;
     if ( isData ){ 
       
       passHLT = 0;
       /*
       if (  H_27_CIdVT_CIsT_TIdT_TIsT_1  == 1 ||  // 2011A   /SingleElectron/, runs: 160404 - 161176   --> 5.281(/pb)	 
	     H_27_CIdVT_CIsT_TIdT_TIsT_2  == 1 ||  // 2011A   /SingleElectron/, runs: 161216 - 163261   --> 28.321(/pb) 
	     H_27_CIdVT_CIsT_TIdT_TIsT_3  == 1 ||  // 2011A   /SingleElectron/, runs: 163269 - 163869   --> 168.613(/pb)
	     H_32_CIdVT_CIsT_TIdT_TIsT_3  == 1 ||  // 2011A   /SingleElectron/, runs: 165088 - 165633   --> 139.027(/pb)
	     H_42_CIdVT_CIsT_TIdT_TIsT_1  == 1 ||  // 2011A   /SingleElectron/, runs: 165970 - 166967   --> 524.904(/pb)
	     H_52_CIdVT_TIdT_3		  == 1 ||  // 2011A   /SingleElectron/, runs: 167039 - 167913   --> 265.747(/pb)
	     H_65_CIdVT_TIdT_3		  == 1 ||  // 2011A   /SingleElectron/, runs: 170249 - 173198   --> 748.931(/pb)
	     H_65_CIdVT_TIdT_4		  == 1 ||  // 2011A+B /SingleElectron/, runs: 173236 - 173692   --> 246.527(/pb)  +  175832 - 178380  -->  1.698(/fb)
	     H_80_CIdVT_TIdT_2            == 1 ||  // 2011B   /SingleElectron/, runs: 178420 - 179889  -->  641.378(/pb)
	     H_80_CIdVT_TIdT_3            == 1 ) { // 2011B   /SingleElectron/, runs: 179959 - 180252  -->  117.644(/pb)
	 passHLT = 1;                              // Total: 2.127351 (/fb) +  2.457022 (/fb)  = 4.584373 (/fb)
       }
       */
       
       if ( H_Mu15_Pho20_CIdL_2      == 1 || 
	    H_Mu15_Pho20_CIdL_3      == 1 || 
	    H_Mu15_Pho20_CIdL_4      == 1 || 
	    H_Mu15_Pho20_CIdL_5      == 1 || 
	    H_Mu15_Pho20_CIdL_6      == 1 || 
	    H_Mu15_Pho20_CIdL_7      == 1 || 
	    H_Mu15_Pho20_CIdL_9      == 1 || 
	    H_Mu15_Pho20_CIdL_10     == 1 || 
	    H_Mu15_Photon20_CIdL_13  == 1 || 
	    H_Mu15_Photon20_CIdL_14  == 1 || 
	    H_Mu17_Ele8_CIdT_CIsVL_4 == 1 || 
	    H_Mu17_Ele8_CIdT_CIsVL_7 == 1 || 
	    H_Mu17_Ele8_CIdT_CIsVL_8 == 1 ){
	 passHLT = 1;
       }
     }

     //--------------------------------------------------------------------------
     // Calculate weights for trigger and reconstruction efficiency
     //--------------------------------------------------------------------------

     /*
     if ( isData && passHLT == 1 && isEB_old) {
       if       ( H_27_CIdVT_CIsT_TIdT_TIsT_1  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_27_CIdVT_CIsT_TIdT_TIsT_2  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_27_CIdVT_CIsT_TIdT_TIsT_3  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_32_CIdVT_CIsT_TIdT_TIsT_3  == 1 ) ele_trigger_efficiency = 0.9964;
       else if  ( H_42_CIdVT_CIsT_TIdT_TIsT_1  == 1 ) ele_trigger_efficiency = 0.9964;
       else if  ( H_52_CIdVT_TIdT_3	       == 1 ) ele_trigger_efficiency = 0.9898;
       else if  ( H_65_CIdVT_TIdT_3	       == 1 ) ele_trigger_efficiency = 0.9849;
       else if  ( H_65_CIdVT_TIdT_4	       == 1 ) ele_trigger_efficiency = 0.9849;
       else if  ( H_80_CIdVT_TIdT_2            == 1 ) ele_trigger_efficiency = 0.9849;
       else if  ( H_80_CIdVT_TIdT_3            == 1 ) ele_trigger_efficiency = 0.9849;
       else { 
	 std::cout << "ERROR: Which trigger fired? (EB)" << std::endl;
       }
       
     }

     else if ( isData && passHLT == 1 && isEE_old) {
       if       ( H_27_CIdVT_CIsT_TIdT_TIsT_1  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_27_CIdVT_CIsT_TIdT_TIsT_2  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_27_CIdVT_CIsT_TIdT_TIsT_3  == 1 ) ele_trigger_efficiency = 0.9998;
       else if  ( H_32_CIdVT_CIsT_TIdT_TIsT_3  == 1 ) ele_trigger_efficiency = 0.9996;
       else if  ( H_42_CIdVT_CIsT_TIdT_TIsT_1  == 1 ) ele_trigger_efficiency = 0.9996;
       else if  ( H_52_CIdVT_TIdT_3	       == 1 ) ele_trigger_efficiency = 0.9620;
       else if  ( H_65_CIdVT_TIdT_3	       == 1 ) ele_trigger_efficiency = 0.9710;
       else if  ( H_65_CIdVT_TIdT_4	       == 1 ) ele_trigger_efficiency = 0.9710;
       else if  ( H_80_CIdVT_TIdT_2            == 1 ) ele_trigger_efficiency = 0.9710;
       else if  ( H_80_CIdVT_TIdT_3            == 1 ) ele_trigger_efficiency = 0.9719;
       else { 
	 std::cout << "ERROR: Which trigger fired (EE)?" << std::endl;
       }
     }
     */

     double efficiency_weight = 1.0;

     //--------------------------------------------------------------------------
     
     // JSON variable
     fillVariableWithValue(   "PassJSON"                      , passedJSON, efficiency_weight   ) ; 

     // Dataset variable
     fillVariableWithValue(   "PassDataset"                   , PassDataset, efficiency_weight   ) ; 

     // Noise filters
     fillVariableWithValue(   "PassHBHENoiseFilter"           , PassHBHENoiseFilter    , efficiency_weight   ) ; 
     fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight, efficiency_weight   ) ; 

     
     fillVariableWithValue ( "Reweighting", 1, efficiency_weight  );
     fillVariableWithValue ( "PassHLT", passHLT, efficiency_weight  ) ;
     
     // Electrons
     int PassNEle = 0;
     if ( nEle_Ana == 1 ) PassNEle = 1;
     
     double M_ej_avg;
     double M_ej_min;

     // Muons
     int PassNMuon = 0;
     if ( nMuon_Ana == 1 ) PassNMuon = 1;

     fillVariableWithValue(   "PassNEle"                      , PassNEle          , efficiency_weight ) ;
     fillVariableWithValue(   "PassNMuon"                     , PassNMuon         , efficiency_weight ) ;
									          
     if ( nMuon_Ana >= 1 && nEle_Ana >= 1 ) {				          
       fillVariableWithValue( "Ele1_Pt"                       , Ele1_Pt_new       , efficiency_weight ) ;
       fillVariableWithValue( "Ele1_Eta"                      , Ele1_Eta_new      , efficiency_weight ) ;
       fillVariableWithValue( "abs_Ele1_Eta"                  , fabs(Ele1_Eta_new), efficiency_weight ) ;

       fillVariableWithValue( "Ele2_Pt"                       , Ele2_Pt_new       , efficiency_weight ) ;
       fillVariableWithValue( "Ele2_Eta"                      , Ele2_Eta_new      , efficiency_weight ) ;
       fillVariableWithValue( "abs_Ele2_Eta"                  , fabs(Ele2_Eta_new), efficiency_weight ) ;
       fillVariableWithValue( "M_e1e2"                        , M_e1e2_new        , efficiency_weight ) ;
     }									    
									    
     // Jets								    
     fillVariableWithValue(   "nJet"                          , nJet_Ana      , efficiency_weight ) ;
     if ( nJet_Ana >= 1 ) { 						    
       fillVariableWithValue( "Jet1_Pt"                       , Jet1_Pt       , efficiency_weight ) ;
       fillVariableWithValue( "Jet1_Eta"                      , Jet1_Eta      , efficiency_weight ) ;
     }
     if ( nJet_Ana >= 2 ) { 
       fillVariableWithValue( "Jet2_Pt"                       , Jet2_Pt       , efficiency_weight ) ;
       fillVariableWithValue( "Jet2_Eta"                      , Jet2_Eta      , efficiency_weight ) ;
       fillVariableWithValue( "DR_Jet1Jet2"                   , DR_Jet1Jet2   , efficiency_weight ) ;
     }

     // DeltaR
     if ( nEle_Ana >= 1 && nMuon_Ana >= 1 && nJet_Ana >= 1) {
       fillVariableWithValue( "DR_Ele1Jet1"                   , DR_Ele1Jet1_new   , efficiency_weight ) ;
       fillVariableWithValue( "DR_Ele2Jet1"                   , DR_Ele2Jet1_new   , efficiency_weight ) ;
       if(nJet_Ana >= 2) {					           
	 fillVariableWithValue( "DR_Ele1Jet2"                 , DR_Ele1Jet2_new   , efficiency_weight ) ;
	 fillVariableWithValue( "DR_Ele2Jet2"                 , DR_Ele2Jet2_new   , efficiency_weight ) ;
       }
     }

     // sT
     if ( nEle_Ana >= 1 && nMuon_Ana >= 1 && nJet_Ana >= 2) {
       fillVariableWithValue( "sT_eejj"                      , sT_eejj_new  , efficiency_weight ) ;

       if ( fabs(M_e1j1_new-M_e2j2_new) < fabs(M_e1j2_new-M_e2j1_new) )  {
	 M_ej_avg = (M_e1j1_new + M_e2j2_new) / 2.0;
	 if    ( M_e1j1_new < M_e2j2_new ) M_ej_min = M_e1j1_new;
	 else                              M_ej_min = M_e2j2_new;
       }
       else { 
	 M_ej_avg = (M_e1j2_new + M_e2j1_new) / 2.0;
	 if    ( M_e1j2_new < M_e2j1_new ) M_ej_min = M_e1j2_new;
	 else                              M_ej_min = M_e2j1_new;
       }
       
       fillVariableWithValue( "sT_eejj"                      , sT_eejj_new, efficiency_weight   ) ;
       
       fillVariableWithValue( "sT_eejj_LQ250"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ350"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ400"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ450"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ500"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ550"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ600"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ650"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ750"                , sT_eejj_new, efficiency_weight   ) ;
       fillVariableWithValue( "sT_eejj_LQ850"                , sT_eejj_new, efficiency_weight   ) ;


       fillVariableWithValue( "M_e1e2_LQ250"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ350"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ400"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ450"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ500"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ550"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ600"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ650"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ750"                , M_e1e2_new, efficiency_weight   ) ;
       fillVariableWithValue( "M_e1e2_LQ850"                , M_e1e2_new, efficiency_weight   ) ;
       
       fillVariableWithValue( "min_M_ej_LQ250"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ350"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ400"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ450"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ500"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ550"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ600"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ650"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ750"               , M_ej_min, efficiency_weight  ) ;
       fillVariableWithValue( "min_M_ej_LQ850"               , M_ej_min, efficiency_weight  ) ;

     }      

     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------

     FillUserTH1D( "PileupWeight",   -1.0 );
     FillUserTH1D( "GeneratorWeight", -1.0 ) ;
     
     bool passed_minimum      = ( passedAllPreviousCuts("PassBeamHaloFilterTight") && passedCut ("PassBeamHaloFilterTight"));
     bool passed_250          = ( passedAllPreviousCuts("min_M_ej_LQ250"         ) && passedCut ("min_M_ej_LQ250"         ));
     bool passed_350          = ( passedAllPreviousCuts("min_M_ej_LQ350"         ) && passedCut ("min_M_ej_LQ350"         ));
     bool passed_400          = ( passedAllPreviousCuts("min_M_ej_LQ400"         ) && passedCut ("min_M_ej_LQ400"         ));
     bool passed_450          = ( passedAllPreviousCuts("min_M_ej_LQ450"         ) && passedCut ("min_M_ej_LQ450"         ));
     bool passed_500          = ( passedAllPreviousCuts("min_M_ej_LQ500"         ) && passedCut ("min_M_ej_LQ500"         ));
     bool passed_550          = ( passedAllPreviousCuts("min_M_ej_LQ550"         ) && passedCut ("min_M_ej_LQ550"         ));
     bool passed_600          = ( passedAllPreviousCuts("min_M_ej_LQ600"         ) && passedCut ("min_M_ej_LQ600"         ));
     bool passed_650          = ( passedAllPreviousCuts("min_M_ej_LQ650"         ) && passedCut ("min_M_ej_LQ650"         ));
     bool passed_750          = ( passedAllPreviousCuts("min_M_ej_LQ750"         ) && passedCut ("min_M_ej_LQ750"         ));
     bool passed_850          = ( passedAllPreviousCuts("min_M_ej_LQ850"         ) && passedCut ("min_M_ej_LQ850"         ));

     if ( passed_minimum && isData ){ 
       FillUserTH1D ("run_HLT", run );
       profile_run_vs_nvtx_HLT -> Fill ( run, nVertex, 1 ) ;
     }

     bool passed_preselection = ( passedAllPreviousCuts("M_e1e2") && passedCut ("M_e1e2") );
     
     if ( passed_preselection ) {

       //--------------------------------------------------------------------------
       // Fill skim tree, if necessary
       //--------------------------------------------------------------------------
       
       // fillSkimTree();

       bool isEB1 = ( fabs(Ele1_Eta_new) < eleEta_bar_max  ) ;
       bool isEE1 = ( fabs(Ele1_Eta_new) > eleEta_end_min &&
		      fabs(Ele1_Eta_new) < eleEta_end_max ) ;

       bool isEB2 = ( fabs(Ele2_Eta_new) < eleEta_bar_max  ) ;
       bool isEE2 = ( fabs(Ele2_Eta_new) > eleEta_end_min &&
		      fabs(Ele2_Eta_new) < eleEta_end_max ) ;

       bool isEBEB = ( isEB1 && isEB2 ) ;
       bool isEBEE = ( ( isEB1 && isEE2 ) ||
		       ( isEE1 && isEB2 ) );
       bool isEEEE = ( isEE1  && isEE2  );
       bool isEB   = ( isEBEB || isEBEE );
       
       if ( isData ) { 
	 FillUserTH1D("run_PAS", run ) ;
	 profile_run_vs_nvtx_PAS -> Fill ( run, nVertex, 1 ) ;
       }
       
       FillUserTH1D("nElectron_PAS"        , nEle_Ana                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("nMuon_PAS"            , nMuon_Ana                    , efficiency_weight * pileup_weight) ;
       FillUserTH1D("nJet_PAS"             , nJet_Ana                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Pt1stEle_PAS"	   , Ele1_Pt_new                  , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Eta1stEle_PAS"	   , Ele1_Eta_new                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Phi1stEle_PAS"	   , Ele1_Phi_new                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Pt2ndEle_PAS"	   , Ele2_Pt_new                  , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Eta2ndEle_PAS"	   , Ele2_Eta_new                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Phi2ndEle_PAS"	   , Ele2_Phi_new                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Charge1stEle_PAS"	   , Ele1_Charge_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Charge2ndEle_PAS"	   , Ele2_Charge_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("MET_PAS"              , MET_Pt                       , efficiency_weight * pileup_weight) ;
       FillUserTH1D("METSig_PAS"           , PFMETSig                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("METPhi_PAS"	   , MET_Phi                      , efficiency_weight * pileup_weight) ;
       FillUserTH1D("METCharged_PAS"       , PFMETCharged                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("METChargedPhi_PAS"    , PFMETChargedPhi              , efficiency_weight * pileup_weight) ;   
       FillUserTH1D("METType1_PAS"         , PFMETType1Cor                , efficiency_weight * pileup_weight) ;
       FillUserTH1D("METType1Phi_PAS"      , PFMETPhiType1Cor             , efficiency_weight * pileup_weight) ;   
       FillUserTH1D("Pt1stJet_PAS"         , Jet1_Pt                      , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Pt2ndJet_PAS"         , Jet2_Pt                      , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Eta1stJet_PAS"        , Jet1_Eta                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Eta2ndJet_PAS"        , Jet2_Eta                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Phi1stJet_PAS"	   , Jet1_Phi                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Phi2ndJet_PAS"	   , Jet2_Phi                     , efficiency_weight * pileup_weight) ;
       FillUserTH1D("sTlep_PAS"            , Ele1_Pt_new + Ele2_Pt_new    , efficiency_weight * pileup_weight) ;
       FillUserTH1D("sTjet_PAS"            , Jet1_Pt + Jet2_Pt            , efficiency_weight * pileup_weight) ;
       FillUserTH1D("sT_PAS"               , sT_eejj_new                  , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Mjj_PAS"		   , M_j1j2                       , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Mee_PAS"		   , M_e1e2_new                   , efficiency_weight * pileup_weight) ;
       FillUserTH1D( "MTenu_PAS"           , MT_Ele1MET_new               , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Me1j1_PAS"            , M_e1j1_new                   , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Me1j2_PAS"            , M_e1j2_new                   , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Me2j1_PAS"            , M_e2j1_new                   , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Me2j2_PAS"            , M_e2j2_new                   , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Ptee_PAS"             , Pt_e1e2_new                  , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DCotTheta1stEle_PAS"  , -1.0                         , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Dist1stEle_PAS"       , -1.0                         , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DCotTheta2ndEle_PAS"  , -1.0                         , efficiency_weight * pileup_weight) ;
       FillUserTH1D("Dist2ndEle_PAS"       , -1.0                         , efficiency_weight * pileup_weight) ;
       FillUserTH1D("nVertex_PAS"          , nVertex                      , efficiency_weight * pileup_weight) ;
       FillUserTH1D("nVertex_good_PAS"     , nVertex_good                 , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Ele1Ele2_PAS"	   , DR_Ele1Ele2_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Ele1Jet1_PAS"	   , DR_Ele1Jet1_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Ele1Jet2_PAS"	   , DR_Ele1Jet2_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Ele2Jet1_PAS"	   , DR_Ele2Jet1_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Ele2Jet2_PAS"	   , DR_Ele2Jet2_new              , efficiency_weight * pileup_weight) ;
       FillUserTH1D("DR_Jet1Jet2_PAS"	   , DR_Jet1Jet2                  , efficiency_weight * pileup_weight) ;

       if ( e1_isEle ) {
	 FillUserTH1D("PtRealEle_PAS"      , Ele1_Pt_new                  , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("EtaRealEle_PAS"     , Ele1_Eta_new                 , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("PhiRealEle_PAS"     , Ele1_Phi_new                 , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("ChargeRealEle_PAS"  , Ele1_Charge_new              , efficiency_weight * pileup_weight) ;
	 	                           			          
	 FillUserTH1D("PtRealMuon_PAS"     , Ele2_Pt_new                  , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("EtaRealMuon_PAS"    , Ele2_Eta_new                 , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("PhiRealMuon_PAS"    , Ele2_Phi_new                 , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("ChargeRealMuon_PAS" , Ele2_Charge_new              , efficiency_weight * pileup_weight) ;
		                           			          
	 FillUserTH1D("DR_RealEleJet1_PAS" , DR_Ele1Jet1_new              , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealEleJet2_PAS" , DR_Ele1Jet2_new              , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealMuonJet1_PAS", DR_Ele2Jet1_new              , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealMuonJet2_PAS", DR_Ele2Jet2_new              , efficiency_weight * pileup_weight) ;
       }

       if ( e2_isEle ) {
	 FillUserTH1D("PtRealEle_PAS"      , Ele2_Pt_new          , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("EtaRealEle_PAS"     , Ele2_Eta_new         , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("PhiRealEle_PAS"     , Ele2_Phi_new         , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("ChargeRealEle_PAS"  , Ele2_Charge_new      , efficiency_weight * pileup_weight) ;

	 FillUserTH1D("PtRealMuon_PAS"     , Ele1_Pt_new          , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("EtaRealMuon_PAS"    , Ele1_Eta_new         , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("PhiRealMuon_PAS"    , Ele1_Phi_new         , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("ChargeRealMuon_PAS" , Ele1_Charge_new      , efficiency_weight * pileup_weight) ;

	 FillUserTH1D("DR_RealEleJet1_PAS" , DR_Ele2Jet1_new      , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealEleJet2_PAS" , DR_Ele2Jet2_new      , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealMuonJet1_PAS", DR_Ele1Jet1_new      , efficiency_weight * pileup_weight) ;
	 FillUserTH1D("DR_RealMuonJet2_PAS", DR_Ele1Jet2_new      , efficiency_weight * pileup_weight) ;
       }
       
       if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
       else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
       else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
       if      ( isEB   ) FillUserTH1D( "Mee_EB_PAS"  , M_e1e2_new, efficiency_weight * pileup_weight); 

       if ( M_e1e2_new > 80.0 && M_e1e2_new < 100.0 ){
	 FillUserTH1D("Mee_80_100_Preselection", M_e1e2_new, efficiency_weight * pileup_weight) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_80_100_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_80_100_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_80_100_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_80_100_PAS"  , M_e1e2_new, efficiency_weight * pileup_weight); 
       } 

       if ( M_e1e2_new > 70.0 && M_e1e2_new < 110.0 ){
	 FillUserTH1D("Mee_70_110_Preselection", M_e1e2_new, efficiency_weight * pileup_weight) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_70_110_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_70_110_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_70_110_PAS", M_e1e2_new, efficiency_weight * pileup_weight); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_70_110_PAS"  , M_e1e2_new, efficiency_weight * pileup_weight); 
       }
       

       // e1e2mu = e1 + e2 + mu;
       // double MT_eemuMET = sqrt(2 * e1e2mu.Pt()    * MET_Pt  * (1 - cos(e1e2mu.DeltaPhi (met))));
       // FillUserTH1D("MTeemunu_PAS"         , MT_eemuMET                        , efficiency_weight * pileup_weight);
	      
       double min_DR_EleJet = 999.;
       
       if ( DR_Ele1Jet1_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet1_new;
       if ( DR_Ele1Jet2_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet2_new;
       if ( DR_Ele2Jet1_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet1_new;
       if ( DR_Ele2Jet2_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet2_new;
       if ( nJet_Ana >= 3 ) {
	 if ( DR_Ele1Jet3_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet3_new;
	 if ( DR_Ele2Jet3_new < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet3_new;
       }
       
       TLorentzVector eejj;
       eejj = e1 + e2 + j1 + j2;
       double M_eejj = eejj.M();

       FillUserTH1D("Meejj_PAS", M_eejj , efficiency_weight * pileup_weight);
       
       if ( fabs(M_e1j1_new-M_e2j2_new) < fabs(M_e1j2_new-M_e2j1_new) )  {

	 double M_ej_avg = (M_e1j1_new + M_e2j2_new) / 2.0;

	 FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg                , efficiency_weight * pileup_weight);	   
	 FillUserTH1D("Me1j_selected_PAS"   , M_e1j1_new              , efficiency_weight * pileup_weight);	   
	 FillUserTH1D("Me2j_selected_PAS"   , M_e2j2_new              , efficiency_weight * pileup_weight);	   
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j1_new  , M_e2j2_new, efficiency_weight * pileup_weight);
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j2_new  , M_e2j1_new, efficiency_weight * pileup_weight);
       }
       else {

	 double M_ej_avg = (M_e1j2_new + M_e2j1_new) / 2.0;

	 FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg              , efficiency_weight * pileup_weight) ;	   
	 FillUserTH1D("Me1j_selected_PAS"   , M_e1j2_new            , efficiency_weight * pileup_weight) ;	   
	 FillUserTH1D("Me2j_selected_PAS"   , M_e2j1_new            , efficiency_weight * pileup_weight) ;
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j2_new, M_e2j1_new, efficiency_weight * pileup_weight) ;
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j1_new, M_e2j2_new, efficiency_weight * pileup_weight) ;
       }
       
       if ( passed_250 ) {
	 FillUserTH1D("Mej_selected_avg_LQ250", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ250", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ250"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ250"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_350 ) {
	 FillUserTH1D("Mej_selected_avg_LQ350", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ350", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ350"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ350"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_400 ) {
	 FillUserTH1D("Mej_selected_avg_LQ400", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ400", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ400"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ400"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_450 ) {
	 FillUserTH1D("Mej_selected_avg_LQ450", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ450", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ450"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ450"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_500 ) {
	 FillUserTH1D("Mej_selected_avg_LQ500", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ500", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ500"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ500"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_550 ) {
	 FillUserTH1D("Mej_selected_avg_LQ550", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ550", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ550"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ550"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_600 ) {
	 FillUserTH1D("Mej_selected_avg_LQ600", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ600", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ600"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ600"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_650 ) {
	 FillUserTH1D("Mej_selected_avg_LQ650", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ650", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ650"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ650"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_750 ) {
	 FillUserTH1D("Mej_selected_avg_LQ750", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ750", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ750"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ750"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }

       if ( passed_850 ) {
	 FillUserTH1D("Mej_selected_avg_LQ850", M_ej_avg    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mej_selected_min_LQ850", M_ej_min    , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("sT_eejj_LQ850"         , sT_eejj_new , efficiency_weight * pileup_weight  ) ;
	 FillUserTH1D("Mee_LQ850"             , M_e1e2_new  , efficiency_weight * pileup_weight  ) ;
       }
     }
   } // End loop over events

   
   output_root_ -> cd();
   profile_run_vs_nvtx_HLT -> Write();
   profile_run_vs_nvtx_PAS -> Write();
   
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   
   // number of electrons
   TH1F *h_nEleFinal = new TH1F ("h_nEleFinal","",11,-0.5,10.5);
   h_nEleFinal->Sumw2();
   //pT 1st ele
   TH1F *h_pT1stEle = new TH1F ("h_pT1stEle","",100,0,1000);
   h_pT1stEle->Sumw2();
   //pT 2nd ele
   TH1F *h_pT2ndEle = new TH1F ("h_pT2ndEle","",100,0,1000);
   h_pT2ndEle->Sumw2();

#endif //end of USE_EXAMPLE

   /////////initialize variables

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event

#ifdef USE_EXAMPLE
     // Electrons
     vector<int> v_idx_ele_final;
     for(int iele=0;iele<eleCount;iele++)
       {
	 // ECAL barrel fiducial region
	 bool pass_ECAL_FR=false;
	 if( fabs(eleEta[iele]) < getPreCutValue1("eleFidRegion") )	v_idx_ele_final.push_back(iele);
       }     

     // Set the evaluation of the cuts to false and clear the variable values and filled status
     resetCuts();
     
     // Set the value of the variableNames listed in the cutFile to their current value
     fillVariableWithValue("nEleFinal", v_idx_ele_final.size()) ;
     if( v_idx_ele_final.size() >= 1 ) 
       {
	 fillVariableWithValue( "pT1stEle", elePt[v_idx_ele_final[0]] );
       }
     if( v_idx_ele_final.size() >= 2 ) 
       {
	 fillVariableWithValue( "pT2ndEle", elePt[v_idx_ele_final[1]] );
	 // Calculate Mee
	 TLorentzVector v_ee, ele1, ele2;
	 ele1.SetPtEtaPhiM(elePt[v_idx_ele_final[0]],eleEta[v_idx_ele_final[0]],elePhi[v_idx_ele_final[0]],0);
	 ele2.SetPtEtaPhiM(elePt[v_idx_ele_final[1]],eleEta[v_idx_ele_final[1]],elePhi[v_idx_ele_final[1]],0);
	 v_ee = ele1 + ele2;
	 fillVariableWithValue( "invMass_ee", v_ee.M() ) ;
       }

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // Fill histograms and do analysis based on cut evaluation
     h_nEleFinal->Fill(v_idx_ele_final.size());
     //if( v_idx_ele_final.size()>=1 ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     //if( v_idx_ele_final.size()>=2 && (elePt[v_idx_ele_final[0]])>85 ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     if( passedCut("pT1stEle") ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     if( passedCut("pT2ndEle") ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     
     // retrieve value of previously filled variables (after making sure that they were filled)
     double totpTEle;
     if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
       totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");

     // reject events that did not pass level 0 cuts
     if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     if( !passedCut("all") ) continue;
     // ......

#endif  // end of USE_EXAMPLE


     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

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

#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   

   h_nEleFinal->Write();
   h_pT1stEle->Write();
   h_pT2ndEle->Write();

   //pT of both electrons, to be built using the histograms produced automatically by baseClass
   TH1F * h_pTElectrons = new TH1F ("h_pTElectrons","", getHistoNBins("pT1stEle"), getHistoMin("pT1stEle"), getHistoMax("pT1stEle"));
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT1stEle") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT2ndEle") );
   //one could also do:  *h_pTElectrons = getHisto_noCuts_or_skim("pT1stEle") + getHisto_noCuts_or_skim("pT2ndEle");
   h_pTElectrons->Write();
   //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h
#endif // end of USE_EXAMPLE
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 (  true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar            = getPreCutValue1("eleEta_bar");
   double eleEta_end1_min       = getPreCutValue1("eleEta_end1");
   double eleEta_end1_max       = getPreCutValue2("eleEta_end1");
   double eleEta_end2_min       = getPreCutValue1("eleEta_end2");
   double eleEta_end2_max       = getPreCutValue2("eleEta_end2");

   // fake rates
   
   double fakeRate_low_bar_p0    = getPreCutValue1 ( "fakeRate_bar"  );
   double fakeRate_low_bar_p1    = getPreCutValue2 ( "fakeRate_bar"  );
   double fakeRate_high_bar_p0   = getPreCutValue3 ( "fakeRate_bar"  );
				 
   double fakeRate_low_end1_p0   = getPreCutValue1 ( "fakeRate_end1" );
   double fakeRate_low_end1_p1   = getPreCutValue2 ( "fakeRate_end1" );
   double fakeRate_high_end1_p0  = getPreCutValue3 ( "fakeRate_end1" );
				 
   double fakeRate_low_end2_p0   = getPreCutValue1 ( "fakeRate_end2" );
   double fakeRate_low_end2_p1   = getPreCutValue2 ( "fakeRate_end2" );
   double fakeRate_high_end2_p0  = getPreCutValue3 ( "fakeRate_end2" );
   
   double eFakeRate_low_bar_p0   = getPreCutValue1 ( "eFakeRate_bar" );
   double eFakeRate_low_bar_p1   = getPreCutValue2 ( "eFakeRate_bar" );
   double eFakeRate_high_bar_p0  = getPreCutValue3 ( "eFakeRate_bar" );

   double eFakeRate_low_end1_p0  = getPreCutValue1 ( "eFakeRate_end1");
   double eFakeRate_low_end1_p1  = getPreCutValue2 ( "eFakeRate_end1");
   double eFakeRate_high_end1_p0 = getPreCutValue3 ( "eFakeRate_end1");

   double eFakeRate_low_end2_p0  = getPreCutValue1 ( "eFakeRate_end2");
   double eFakeRate_low_end2_p1  = getPreCutValue2 ( "eFakeRate_end2");
   double eFakeRate_high_end2_p0 = getPreCutValue3 ( "eFakeRate_end2");

   // trigger requirements
    
   double trigger_tolerance = getPreCutValue1("trigger_tolerance"); 
   
   //--------------------------------------------------------------------------
   // Set global variables
   //--------------------------------------------------------------------------
   
   TVector2 v_METCharged, v_METType1, v_ele;

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------

   CreateUserTH1D( "nElectron_PAS"            , 5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"                , 5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"                 , 11  , -0.5    , 10.5     );
   CreateUserTH1D( "Pt1stEle_PAS"	      , 100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	      , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	      , 2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MatchPhotonConv1stEle_PAS",	2   , -0.5    , 1.5      );
   CreateUserTH1D( "MatchPhotonConv2ndEle_PAS",	2   , -0.5    , 1.5      );
   CreateUserTH1D( "MET_PAS"                  , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"           , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"             , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METSig_PAS"               , 100 , 0       , 800      );
   CreateUserTH1D( "minMETPt1stEle_PAS"       , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"             , 100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt2ndJet_PAS"             , 100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"            , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Eta2ndJet_PAS"            , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Phi2ndJet_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "TCHE1stJet_PAS"           , 100 , 0       , 20	 ); 
   CreateUserTH1D( "TCHE2ndJet_PAS"           , 100 , 0       , 20	 ); 
   CreateUserTH1D( "nMuon_PtCut_IDISO_PAS"    , 16  , -0.5    , 15.5	 ); 
   CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "MT_charged_enu_PAS"       , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "MT_type1_enu_PAS"         , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Ptenu_PAS"		      , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTlep_PAS"                , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTjet_PAS"                , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                   , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mjj_PAS"		      , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mej1_PAS"                 , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mej2_PAS"                 , 200 , 0       , 2000	 );
   CreateUserTH1D( "Mej_PAS"                  , 200 , 0       , 2000	 );  
   CreateUserTH1D( "MTjnu_PAS"                , 200 , 0       , 1000     );
   CreateUserTH1D( "DCotTheta1stEle_PAS"      , 100 , 0.0     , 1.0      );
   CreateUserTH1D( "Dist1stEle_PAS"           , 100 , 0.0     , 1.0      );  
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	      , 100 , 0       , 10       ); 
   CreateUserTH1D( "DR_Ele1Jet2_PAS"	      , 100 , 0       , 10       ); 
   CreateUserTH1D( "DR_Jet1Jet2_PAS"	      , 100 , 0       , 10       ); 
   CreateUserTH1D( "minDR_EleJet_PAS"         , 100 , 0       , 10       ); 
   CreateUserTH1D( "mDPhi1stEleMET_PAS"       , 100 , 0.      ,  3.14159 );
   CreateUserTH1D( "mDPhi1stJetMET_PAS"       , 100 , 0.      ,  3.14159 );
   CreateUserTH1D( "mDPhi2ndJetMET_PAS"       , 100 , 0.      ,  3.14159 );

   CreateUserTH1D( "MT_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );

   CreateUserTH1D( "GeneratorWeight"       , 200 , -2.0    , 2.0      );
   CreateUserTH1D( "PileupWeight"          , 200 , -2.0    , 2.0      );

   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 

   CreateUserTH1D( "MTCharged_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );

   CreateUserTH1D( "MTType1_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );
   
   CreateUserTH1D( "MTenu_50_110", 200, 40, 140 );
   
   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%10000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------
     
     // int NPILEUP_AVE = int( (nPileUpInt_BXminus1 + nPileUpInt_BX0 + nPileUpInt_BXplus1)/3 );
     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min ( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int passedJSON = passJSON ( run, ls , isData ) ;

     //--------------------------------------------------------------------------
     // 7 trigger paths (some with multiple versions)
     //--------------------------------------------------------------------------
     
     // Number of times a path fired per event ( should be 0 or 1 )
     
     int N_Photon30_CIdVL  = 0;
     int N_Photon50_CIdVL  = 0;
     int N_Photon75_CIdVL  = 0;
     int N_Photon90_CIdVL  = 0;
     int N_Photon125       = 0;
     int N_Photon135       = 0;
     int N_Photon400       = 0;
     
     // Trigger prescale in an event
     
     int PS_Photon30_CIdVL = 0;
     int PS_Photon50_CIdVL = 0;
     int PS_Photon75_CIdVL = 0;
     int PS_Photon90_CIdVL = 0;
     int PS_Photon125      = 0;
     int PS_Photon135      = 0;
     int PS_Photon400      = 0;
     
     //--------------------------------------------------------------------------
     // Find the right prescale for this event
     //--------------------------------------------------------------------------
     
     // Did the HLT_Photon30_CaloIdVL trigger fire?
     
     if ( H_Photon30_CIdVL_1 > 0 && H_Photon30_CIdVL_1 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_1; } 
     if ( H_Photon30_CIdVL_2 > 0 && H_Photon30_CIdVL_2 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_2; } 
     if ( H_Photon30_CIdVL_3 > 0 && H_Photon30_CIdVL_3 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_3; } 
     if ( H_Photon30_CIdVL_4 > 0 && H_Photon30_CIdVL_4 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_4; } 
     if ( H_Photon30_CIdVL_5 > 0 && H_Photon30_CIdVL_5 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_5; } 
     if ( H_Photon30_CIdVL_6 > 0 && H_Photon30_CIdVL_6 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_6; } 
     if ( H_Photon30_CIdVL_7 > 0 && H_Photon30_CIdVL_7 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_7; } 

     if ( isData && run > 175771 ) { // This trigger only available in 2011B
       if ( H_Photon30_CIdVL_8 > 0 && H_Photon30_CIdVL_8 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_8; }
     }
     
     // Did the HLT_Photon50_CaloIdVL trigger fire?
     
     if ( H_Photon50_CIdVL_1 > 0 && H_Photon50_CIdVL_1 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_1; } 
     if ( H_Photon50_CIdVL_2 > 0 && H_Photon50_CIdVL_2 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_2; } 
     if ( H_Photon50_CIdVL_3 > 0 && H_Photon50_CIdVL_3 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_3; } 
     if ( H_Photon50_CIdVL_4 > 0 && H_Photon50_CIdVL_4 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_4; } 
     
     // Did the HLT_Photon75_CaloIdVL trigger fire?
     
     if ( H_Photon75_CIdVL_1 > 0 && H_Photon75_CIdVL_1 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_1; } 
     if ( H_Photon75_CIdVL_2 > 0 && H_Photon75_CIdVL_2 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_2; } 
     if ( H_Photon75_CIdVL_3 > 0 && H_Photon75_CIdVL_3 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_3; } 
     if ( H_Photon75_CIdVL_4 > 0 && H_Photon75_CIdVL_4 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_4; } 
     if ( H_Photon75_CIdVL_5 > 0 && H_Photon75_CIdVL_5 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_5; } 
     if ( H_Photon75_CIdVL_6 > 0 && H_Photon75_CIdVL_6 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_6; } 
     if ( H_Photon75_CIdVL_7 > 0 && H_Photon75_CIdVL_7 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_7; }
     
     // Did the HLT_Photon90_CaloIdVL trigger fire?
     
     if ( H_Photon90_CIdVL_1 > 0 && H_Photon90_CIdVL_1 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_1; } 
     if ( H_Photon90_CIdVL_2 > 0 && H_Photon90_CIdVL_2 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_2; } 
     if ( H_Photon90_CIdVL_3 > 0 && H_Photon90_CIdVL_3 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_3; } 
     if ( H_Photon90_CIdVL_4 > 0 && H_Photon90_CIdVL_4 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_4; } 
     
     // Did the HLT_Photon125 trigger fire?
     
     if ( H_Photon125_1      > 0 && H_Photon125_1      != 999 ) { N_Photon125     ++; PS_Photon125      = H_Photon125_1     ; } 
     if ( H_Photon125_2      > 0 && H_Photon125_2      != 999 ) { N_Photon125     ++; PS_Photon125      = H_Photon125_2     ; } 
     
     // Did the HLT_Photon135 trigger fire?
     
     if ( H_Photon135_1      > 0 && H_Photon135_1      != 999 ) { N_Photon135     ++; PS_Photon135      = H_Photon135_1     ; } 
     if ( H_Photon135_2      > 0 && H_Photon135_2      != 999 ) { N_Photon135     ++; PS_Photon135      = H_Photon135_2     ; } 
     
     // Did the HLT_Photon400 trigger fire?
     
     if ( H_Photon400_1      > 0 && H_Photon400_1      != 999 ) { N_Photon400     ++; PS_Photon400      = H_Photon400_1     ; } 
     
     if ( isData && run > 175771 ) { // This trigger only available in 2011B
       if ( H_Photon400_2      > 0 && H_Photon400_2      != 999 ) { N_Photon400     ++; PS_Photon400      = H_Photon400_2     ; }
     }
     
     // Sanity check: make sure two versions of the same trigger didn't fire in the same event (impossible)
     
     if ( N_Photon30_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon30_CIdVL" << std::endl; exit (0); }
     if ( N_Photon50_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon50_CIdVL" << std::endl; exit (0); }
     if ( N_Photon75_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon75_CIdVL" << std::endl; exit (0); }
     if ( N_Photon90_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon90_CIdVL" << std::endl; exit (0); }
     if ( N_Photon125      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon125"      << std::endl; exit (0); }
     if ( N_Photon135      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon135"      << std::endl; exit (0); }
     if ( N_Photon400      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon400"      << std::endl; exit (0); }
     
     // What is the lowest-prescale trigger that this electron could have fired?
     
     int min_prescale      = 999999;
     std::string min_prescale_name("");

     if ( N_Photon30_CIdVL != 0 && QCDFakeEle1_Pt > 30. * trigger_tolerance  && PS_Photon30_CIdVL <= min_prescale ) { min_prescale = PS_Photon30_CIdVL; min_prescale_name = std::string("PS_Photon30_CIdVL"); }
     if ( N_Photon50_CIdVL != 0 && QCDFakeEle1_Pt > 50. * trigger_tolerance  && PS_Photon50_CIdVL <= min_prescale ) { min_prescale = PS_Photon50_CIdVL; min_prescale_name = std::string("PS_Photon50_CIdVL"); }
     if ( N_Photon75_CIdVL != 0 && QCDFakeEle1_Pt > 75. * trigger_tolerance  && PS_Photon75_CIdVL <= min_prescale ) { min_prescale = PS_Photon75_CIdVL; min_prescale_name = std::string("PS_Photon75_CIdVL"); }
     if ( N_Photon90_CIdVL != 0 && QCDFakeEle1_Pt > 90. * trigger_tolerance  && PS_Photon90_CIdVL <= min_prescale ) { min_prescale = PS_Photon90_CIdVL; min_prescale_name = std::string("PS_Photon90_CIdVL"); }
     if ( N_Photon125      != 0 && QCDFakeEle1_Pt > 125.* trigger_tolerance  && PS_Photon125      <= min_prescale ) { min_prescale = PS_Photon125     ; min_prescale_name = std::string("PS_Photon125"     ); }
     if ( N_Photon135      != 0 && QCDFakeEle1_Pt > 135.* trigger_tolerance  && PS_Photon135      <= min_prescale ) { min_prescale = PS_Photon135     ; min_prescale_name = std::string("PS_Photon135"     ); }
     if ( N_Photon400      != 0 && QCDFakeEle1_Pt > 400.* trigger_tolerance  && PS_Photon400      <= min_prescale ) { min_prescale = PS_Photon400     ; min_prescale_name = std::string("PS_Photon400"     ); }
     
     // If we find a suitable trigger, scale this event by that trigger's prescale
     
     int passedHLT = 0;
     if ( min_prescale != 999999 ) { // if I found some suitable trigger that fired
       passedHLT = 1;     
     } else {                        // if I was not able to find a suitable trigger that fired
       min_prescale = 0;            
     }

     if ( !isData ) {
       min_prescale = 1;
       passedHLT    = 1;
     }
     
     //--------------------------------------------------------------------------
     // What kind of event is this?
     //   - Barrel
     //   - Endcap 1 (eta < 2.0)
     //   - Endcap 2 (eta > 2.0) 
     //--------------------------------------------------------------------------
     
     bool ele1_isBarrel  = false;
     bool ele1_isEndcap1 = false;
     bool ele1_isEndcap2 = false;
     bool ele2_isBarrel  = false;
     bool ele2_isEndcap1 = false;
     bool ele2_isEndcap2 = false;
     
     if( fabs( QCDFakeEle1_Eta  ) < eleEta_bar )        ele1_isBarrel  = true;
     if( fabs( QCDFakeEle1_Eta  ) > eleEta_end1_min &&
	 fabs( QCDFakeEle1_Eta  ) < eleEta_end1_max )   ele1_isEndcap1 = true;
     if( fabs( QCDFakeEle1_Eta  ) > eleEta_end2_min &&
	 fabs( QCDFakeEle1_Eta  ) < eleEta_end2_max )   ele1_isEndcap2 = true;

     if( fabs( QCDFakeEle2_Eta  ) < eleEta_bar )        ele2_isBarrel  = true;
     if( fabs( QCDFakeEle2_Eta  ) > eleEta_end1_min &&
	 fabs( QCDFakeEle2_Eta  ) < eleEta_end1_max )   ele2_isEndcap1 = true;
     if( fabs( QCDFakeEle2_Eta  ) > eleEta_end2_min &&
	 fabs( QCDFakeEle2_Eta  ) < eleEta_end2_max )   ele2_isEndcap2 = true;

     
     //--------------------------------------------------------------------------
     // Determine which fake rates to use
     //--------------------------------------------------------------------------
     
     double fakeRate1  = 0.0;
     double eFakeRate1 = 0.0 ;
     
     if ( QCDFakeEle1_Pt < 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_low_bar_p0  + fakeRate_low_bar_p1  * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_bar_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_bar_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 ) * 
			     ( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 )));
       }
       if ( ele1_isEndcap1 ) {
	 fakeRate1  = fakeRate_low_end1_p0 + fakeRate_low_end1_p1 * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end1_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_end1_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 ) * 
			     ( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 )));
	 
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_low_end2_p0 + fakeRate_low_end2_p1 * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end2_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_end2_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 ) * 
			     ( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 )));
       } 
     }
     else if  ( QCDFakeEle1_Pt >= 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_high_bar_p0  ;
	 eFakeRate1 = eFakeRate_high_bar_p0 ;
       }
       if ( ele1_isEndcap1 ) { 
	 fakeRate1 = fakeRate_high_end1_p0 ;
	 eFakeRate1 = eFakeRate_high_end1_p0 ;
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_high_end2_p0 ;
	 eFakeRate1 = eFakeRate_high_end2_p0 ;
       }
     }
     
     //--------------------------------------------------------------------------
     // Finally have the effective fake rate
     //--------------------------------------------------------------------------
     
     double fakeRate  = fakeRate1;
     double eFakeRate = eFakeRate1;
     
     //--------------------------------------------------------------------------
     // Calculate some variables:
     //--------------------------------------------------------------------------
     
     TLorentzVector loose_ele1, loose_ele2, jet1, jet2, met;
     loose_ele1.SetPtEtaPhiM ( QCDFakeEle1_Pt , QCDFakeEle1_Eta , QCDFakeEle1_Phi , 0.0 );
     loose_ele2.SetPtEtaPhiM ( QCDFakeEle2_Pt , QCDFakeEle2_Eta , QCDFakeEle2_Phi , 0.0 );
     jet1.SetPtEtaPhiM       ( JetLooseEle1_Pt, JetLooseEle1_Eta, JetLooseEle1_Phi, 0.0 );
     jet2.SetPtEtaPhiM       ( JetLooseEle2_Pt, JetLooseEle2_Eta, JetLooseEle2_Phi, 0.0 );
     met.SetPtEtaPhiM        ( MET_Pt         , 0.0             , MET_Phi         , 0.0 );

     TLorentzVector e1met = loose_ele1 + met;
     TLorentzVector j1j2 = jet1 + jet2;
     TLorentzVector e1j1 = loose_ele1 + jet1;
     TLorentzVector e1j2 = loose_ele1 + jet2;

     M_e1j1 = e1j1.M();
     M_e1j2 = e1j2.M();

     Pt_Ele1MET = e1met.Pt();
     MT_Ele1MET = sqrt(2 * QCDFakeEle1_Pt * MET_Pt  * (1 - cos(loose_ele1.DeltaPhi ( met) ) ) );

     mDPhi_METEle1= fabs(loose_ele1.DeltaPhi ( met ));
     mDPhi_METJet1= fabs(jet1.DeltaPhi ( met ));
     mDPhi_METJet2= fabs(jet2.DeltaPhi ( met ));

     sT_enujj = QCDFakeEle1_Pt + MET_Pt + JetLooseEle1_Pt + JetLooseEle2_Pt ;
     
     int nEle_QCDFake_Ana = 0;
     if      ( QCDFakeEle3_Pt > 35. ) nEle_QCDFake_Ana = 3;
     else if ( QCDFakeEle2_Pt > 35. ) nEle_QCDFake_Ana = 2;
     else if ( QCDFakeEle1_Pt > 35. ) nEle_QCDFake_Ana = 1;
     else                             nEle_QCDFake_Ana = 0;
     
     DR_Ele1Jet1 = loose_ele1.DeltaR ( jet1 ) ;
     DR_Ele1Jet2 = loose_ele1.DeltaR ( jet2 ) ;

     // bug: don't have QCD btag values
     double JetLooseEle1_btagTCHE = 0.0;
     double JetLooseEle2_btagTCHE = 0.0;

     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // JSON variable
     fillVariableWithValue(   "Reweighting"              , 1                       , min_prescale * fakeRate ); 
     fillVariableWithValue(   "PassJSON"                 , passedJSON              , min_prescale * fakeRate ); 
     									          
     // HLT variable							           
     fillVariableWithValue(   "PassHLT"                  , passedHLT               , min_prescale * fakeRate );
     
     // Dataset variable 
     fillVariableWithValue(   "PassDataset"              , 1                       , min_prescale * fakeRate );

     // Filters
     fillVariableWithValue(   "PassHBHENoiseFilter"      , PassHBHENoiseFilter     , min_prescale * fakeRate );
     fillVariableWithValue(   "PassBeamHaloFilterTight"  , PassBeamHaloFilterTight , min_prescale * fakeRate );
									      
     // Muon variables ( for veto ) 					      
     fillVariableWithValue(   "nMuon"                    , nMuon_Ana               , min_prescale * fakeRate );
			                                      		                
     // 1st Electron variables				      		                
     fillVariableWithValue(   "nEle"                     , nEle_QCDFake_Ana        , min_prescale * fakeRate ); 
     fillVariableWithValue(   "Ele1_Pt"                  , QCDFakeEle1_Pt          , min_prescale * fakeRate );
     fillVariableWithValue(   "Ele1_Eta"                 , QCDFakeEle1_Eta         , min_prescale * fakeRate );
									           
     // MET variables	                                      		           
     fillVariableWithValue(   "MET"                      , MET_Pt                  , min_prescale * fakeRate );
     fillVariableWithValue(   "mDeltaPhiMETEle"          , mDPhi_METEle1           , min_prescale * fakeRate );
     									           
     // 1st JET variables                                     		           
     fillVariableWithValue(   "nJet"                     , nJetLooseEle_Ana        , min_prescale * fakeRate );
			
     double MT_Jet1MET, MT_Jet2MET	, MT_Ele1Jet1, MT_Ele1Jet2;					           
     // 1st JET variables                                     		           
     if ( nJetLooseEle_Ana > 0 ) { 						           
       fillVariableWithValue( "Jet1_Pt"                  , JetLooseEle1_Pt         , min_prescale * fakeRate );
       fillVariableWithValue( "Jet1_Eta"                 , JetLooseEle1_Eta        , min_prescale * fakeRate );
       fillVariableWithValue( "mDeltaPhiMET1stJet"       , mDPhi_METJet1           , min_prescale * fakeRate );

       TVector2 v_MET;
       TVector2 v_jet;
       v_MET.SetMagPhi( MET_Pt , MET_Phi  );
       v_jet.SetMagPhi( JetLooseEle1_Pt, JetLooseEle1_Phi );
       float deltaphi = v_MET.DeltaPhi(v_jet);
       MT_Jet1MET = sqrt ( 2 * Jet1_Pt * MET_Pt * ( 1 - cos ( deltaphi ) ) );
     }									           
     									           
     // 2nd JET variables                                     		           
     if ( nJetLooseEle_Ana > 1 ) { 	                                      	           
       fillVariableWithValue( "Jet2_Pt"                  , JetLooseEle2_Pt         , min_prescale * fakeRate );
       fillVariableWithValue( "Jet2_Eta"                 , JetLooseEle2_Eta        , min_prescale * fakeRate );
       fillVariableWithValue( "ST"                       , sT_enujj                , min_prescale * fakeRate );

       TVector2 v_MET;
       TVector2 v_jet;
       v_MET.SetMagPhi( MET_Pt , MET_Phi  );
       v_jet.SetMagPhi( JetLooseEle2_Pt, JetLooseEle2_Phi );
       float deltaphi = v_MET.DeltaPhi(v_jet);
       MT_Jet2MET = sqrt ( 2 * Jet2_Pt * MET_Pt * ( 1 - cos ( deltaphi ) ) );
     }

     // 3rd JET variables 
     // if ( nJetLooseEle_Ana > 2 ) {
     //   fillVariableWithValue( "Jet3_Pt"                  , JetLooseEle3_Pt         , min_prescale * fakeRate );
     //   fillVariableWithValue( "Jet3_Eta"                 , JetLooseEle3_Eta        , min_prescale * fakeRate );
     // }
     
     // 1 electron, 1 jet variables 
     if ( nEle_QCDFake > 0 && nJet_Ana > 0 ) { 
       fillVariableWithValue ( "DR_Ele1Jet1"             , DR_Ele1Jet1             , min_prescale * fakeRate );
       
       TVector2 v_ele;
       TVector2 v_jet1;
       v_ele .SetMagPhi ( QCDFakeEle1_Pt, QCDFakeEle1_Phi );
       v_jet1.SetMagPhi ( JetLooseEle1_Pt, JetLooseEle1_Phi );
       float deltaphi = v_ele.DeltaPhi ( v_jet1 );
       MT_Ele1Jet2 = sqrt ( 2 * JetLooseEle1_Pt * QCDFakeEle1_Pt * ( 1 - cos ( deltaphi ) ) );
     }

     // 1 electron, 2 jet variables 
     if ( nEle_QCDFake > 0 && nJet_Ana > 1 ) { 
       fillVariableWithValue ( "DR_Ele1Jet2"             , DR_Ele1Jet2             , min_prescale * fakeRate );

       TVector2 v_ele;
       TVector2 v_jet2;
       v_ele .SetMagPhi ( QCDFakeEle1_Pt, QCDFakeEle1_Phi );
       v_jet2.SetMagPhi ( JetLooseEle2_Pt, JetLooseEle2_Phi );
       float deltaphi = v_ele.DeltaPhi ( v_jet2 );
       MT_Ele1Jet2 = sqrt ( 2 * JetLooseEle2_Pt * QCDFakeEle1_Pt * ( 1 - cos ( deltaphi ) ) );
     }
     
     // Dummy variables
     fillVariableWithValue ("preselection",1, min_prescale * fakeRate );


     double MT_JetMET;
     double Mej;
     
     if ( fabs ( MT_Jet1MET - MT_Ele1Jet2 ) < fabs( MT_Jet2MET - MT_Ele1Jet1 )){
       MT_JetMET = MT_Jet1MET;
       Mej = M_e1j2;
     } else { 
       MT_JetMET = MT_Jet2MET;
       Mej = M_e1j1;
     }	 

     if ( nEle_QCDFake > 0 && nJet_Ana > 1 ) { 
       fillVariableWithValue("ST_opt"     ,  sT_enujj                , min_prescale * fakeRate );
       fillVariableWithValue("MT_opt"     ,  MT_Ele1MET              , min_prescale * fakeRate );
       fillVariableWithValue("Mej_min_opt",  Mej                     , min_prescale * fakeRate );
     }
     
     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------
     
     bool passed_preselection = passedAllPreviousCuts("preselection");
       
     if ( passed_preselection ) { 

       //--------------------------------------------------------------------------
       // Fill skim tree, if necessary
       //--------------------------------------------------------------------------
       
       // fillSkimTree();
       
       bool use_charged_met = (PFMETCharged < MET_Pt);

       if ( use_charged_met ) v_METCharged.SetMagPhi(PFMETCharged , PFMETChargedPhi );
       else                   v_METCharged.SetMagPhi(MET_Pt       , MET_Phi         );
       
       v_METType1.SetMagPhi  (PFMETType1Cor , PFMETPhiType1Cor);
       v_ele.SetMagPhi       (QCDFakeEle1_Pt, QCDFakeEle1_Phi );
       
       double deltaphi_charged = v_METCharged.DeltaPhi(v_ele);
       double deltaphi_type1   = v_METType1  .DeltaPhi(v_ele);
       double MTCharged = sqrt(2 * QCDFakeEle1_Pt * PFMETCharged  * (1 - cos(deltaphi_charged)) );
       double MTType1   = sqrt(2 * QCDFakeEle1_Pt * PFMETType1Cor * (1 - cos(deltaphi_type1  )) );

       double min_DR_EleJet = 999.0;
       double DR_Ele1Jet3 = 999.0;
       if ( nJetLooseEle_Ana > 2 ) {
	 TLorentzVector ele1, jet3;
	 ele1.SetPtEtaPhiM ( QCDFakeEle1_Pt, QCDFakeEle1_Eta, QCDFakeEle1_Phi, 0.0 );
	 jet3.SetPtEtaPhiM ( JetLooseEle3_Pt, JetLooseEle3_Eta, JetLooseEle3_Phi, 0.0 );
	 DR_Ele1Jet3 = ele1.DeltaR ( jet3 ) ;
       }

       if ( DR_Ele1Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet1;
       if ( DR_Ele1Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet2;
       if ( nJet_Ana > 2 ) {
	 if ( DR_Ele1Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet3;
       }

       FillUserTH1D( "MT_charged_enu_PAS"         , MTCharged                             , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "MT_type1_enu_PAS"           , MTType1                               , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "nElectron_PAS"              , nEle_QCDFake_Ana                      , pileup_weight * min_prescale * fakeRate); 
       FillUserTH1D( "nMuon_PAS"                  , nMuon_Ana                             , pileup_weight * min_prescale * fakeRate); 
       FillUserTH1D( "Pt1stEle_PAS"	          , QCDFakeEle1_Pt                        , pileup_weight * min_prescale * fakeRate); 
       FillUserTH1D( "Eta1stEle_PAS"	          , QCDFakeEle1_Eta                       , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Phi1stEle_PAS"	          , QCDFakeEle1_Phi                       , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Charge1stEle_PAS"           , QCDFakeEle1_Charge                    , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "METSig_PAS"	          , PFMETSig                              , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "MET_PAS"                    , MET_Pt                                , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "METPhi_PAS"	          , MET_Phi                               , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "METCharged_PAS"             , PFMETCharged                          , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "METChargedPhi_PAS"          , PFMETChargedPhi                       , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "METType1_PAS"               , PFMETType1Cor                         , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "METType1Phi_PAS"            , PFMETPhiType1Cor                      , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "minMETPt1stEle_PAS"         , TMath::Min ( QCDFakeEle1_Pt, MET_Pt  ), pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Pt1stJet_PAS"               , JetLooseEle1_Pt                       , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Pt2ndJet_PAS"               , JetLooseEle2_Pt                       , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Eta1stJet_PAS"              , JetLooseEle1_Eta                      , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Eta2ndJet_PAS"              , JetLooseEle2_Eta                      , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Phi1stJet_PAS"              , JetLooseEle1_Phi                      , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Phi2ndJet_PAS"	          , JetLooseEle2_Phi                      , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "TCHE1stJet_PAS"             , JetLooseEle1_btagTCHE                 , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "TCHE2ndJet_PAS"             , JetLooseEle2_btagTCHE                 , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "nMuon_PtCut_IDISO_PAS"      , nMuon_Ana                             , pileup_weight * min_prescale * fakeRate); 
       FillUserTH1D( "MTenu_PAS"                  , MT_Ele1MET                            , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Ptenu_PAS"	          , Pt_Ele1MET                            , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "sTlep_PAS"                  , QCDFakeEle1_Pt + MET_Pt               , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "sTjet_PAS"                  , JetLooseEle1_Pt + JetLooseEle2_Pt     , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "sT_PAS"                     , sT_enujj                              , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Mjj_PAS"	                  , M_j1j2                                , pileup_weight * min_prescale * fakeRate);   
       FillUserTH1D( "DCotTheta1stEle_PAS"        , QCDFakeEle1_DCotTheta                 , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Dist1stEle_PAS"             , QCDFakeEle1_Dist                      , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "mDPhi1stEleMET_PAS"         , mDPhi_METEle1                         , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "mDPhi1stJetMET_PAS"         , mDPhi_METJet1                         , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "mDPhi2ndJetMET_PAS"         , mDPhi_METJet2                         , pileup_weight * min_prescale * fakeRate); 
       FillUserTH1D( "Mej1_PAS"                   , M_e1j1                                , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Mej2_PAS"                   , M_e1j2                                , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "Mej_PAS"                    , Mej                                   , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "MTjnu_PAS"                  , MT_JetMET                             , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "DR_Ele1Jet1_PAS"	          , DR_Ele1Jet1                           , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "DR_Ele1Jet2_PAS"	          , DR_Ele1Jet2                           , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "DR_Jet1Jet2_PAS"	          , DR_Jet1Jet2                           , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "minDR_EleJet_PAS"           , min_DR_EleJet                         , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "nVertex_PAS"                , nVertex                               , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "nVertex_good_PAS"           , nVertex_good                          , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "MatchPhotonConv1stEle_PAS"  , Ele1_MatchPhotConv                    , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "MatchPhotonConv2ndEle_PAS"  , Ele2_MatchPhotConv                    , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "nJet_PAS"                   , nJet_Ana                              , pileup_weight * min_prescale * fakeRate);
       FillUserTH1D( "GeneratorWeight"            , -1.0             );
       FillUserTH1D( "PileupWeight"               , -1.0             );

       if ( MT_Ele1MET > 50 && MT_Ele1MET < 110 ){
	 FillUserTH1D( "MTenu_50_110", MT_Ele1MET, pileup_weight * min_prescale * fakeRate ) ;
       }

       if ( nVertex_good >= 0 && nVertex_good <= 3 ) {
	 FillUserTH1D( "MT_GoodVtxLTE3_PAS"              , MT_Ele1MET, pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTCharged_GoodVtxLTE3_PAS"       , MTCharged , pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTType1_GoodVtxLTE3_PAS"         , MTType1   , pileup_weight * min_prescale * fakeRate ) ;
       }						 
       							 
       if ( nVertex_good >= 4 && nVertex_good <= 8 ) {	 
	 FillUserTH1D( "MT_GoodVtxGTE4_LTE8_PAS"         , MT_Ele1MET, pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE4_LTE8_PAS"  , MTCharged , pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE4_LTE8_PAS"    , MTType1   , pileup_weight * min_prescale * fakeRate ) ;
       }
       
       if ( nVertex_good >= 9 && nVertex_good <= 15) {
	 FillUserTH1D( "MT_GoodVtxGTE9_LTE15_PAS"        , MT_Ele1MET, pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE9_LTE15_PAS" , MTCharged , pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE9_LTE15_PAS"   , MTType1   , pileup_weight * min_prescale * fakeRate ) ;
       }
       
       if ( nVertex_good >= 16                     ) {
	 FillUserTH1D( "MT_GoodVtxGTE16_PAS"             , MT_Ele1MET, pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE16_PAS"      , MTCharged , pileup_weight * min_prescale * fakeRate ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE16_PAS"        , MTType1   , pileup_weight * min_prescale * fakeRate ) ;
       }              
     }
   } // End loop over events

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         (  true  ) ;
   fillAllPreviousCuts              (  true  ) ;
   fillAllOtherCuts                 ( !true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar            = getPreCutValue1("eleEta_bar");
   double eleEta_end1_min       = getPreCutValue1("eleEta_end1");
   double eleEta_end1_max       = getPreCutValue2("eleEta_end1");
   double eleEta_end2_min       = getPreCutValue1("eleEta_end2");
   double eleEta_end2_max       = getPreCutValue2("eleEta_end2");

   // fake rates
   
   double fakeRate_low_bar_p0    = getPreCutValue1 ( "fakeRate_bar"  );
   double fakeRate_low_bar_p1    = getPreCutValue2 ( "fakeRate_bar"  );
   double fakeRate_high_bar_p0   = getPreCutValue3 ( "fakeRate_bar"  );
				 
   double fakeRate_low_end1_p0   = getPreCutValue1 ( "fakeRate_end1" );
   double fakeRate_low_end1_p1   = getPreCutValue2 ( "fakeRate_end1" );
   double fakeRate_high_end1_p0  = getPreCutValue3 ( "fakeRate_end1" );
				 
   double fakeRate_low_end2_p0   = getPreCutValue1 ( "fakeRate_end2" );
   double fakeRate_low_end2_p1   = getPreCutValue2 ( "fakeRate_end2" );
   double fakeRate_high_end2_p0  = getPreCutValue3 ( "fakeRate_end2" );
   
   double eFakeRate_low_bar_p0   = getPreCutValue1 ( "eFakeRate_bar" );
   double eFakeRate_low_bar_p1   = getPreCutValue2 ( "eFakeRate_bar" );
   double eFakeRate_high_bar_p0  = getPreCutValue3 ( "eFakeRate_bar" );

   double eFakeRate_low_end1_p0  = getPreCutValue1 ( "eFakeRate_end1");
   double eFakeRate_low_end1_p1  = getPreCutValue2 ( "eFakeRate_end1");
   double eFakeRate_high_end1_p0 = getPreCutValue3 ( "eFakeRate_end1");

   double eFakeRate_low_end2_p0  = getPreCutValue1 ( "eFakeRate_end2");
   double eFakeRate_low_end2_p1  = getPreCutValue2 ( "eFakeRate_end2");
   double eFakeRate_high_end2_p0 = getPreCutValue3 ( "eFakeRate_end2");

   // trigger requirements
    
   double trigger_tolerance = getPreCutValue1("trigger_tolerance"); 

   // override the fake rate?
   double fakeRate_override = getPreCutValue1("fakeRate_override");
   bool override_fakeRate = ( fakeRate_override > 0.0 );

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------
   
   CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"        ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"          ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j1_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j1_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
   CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );
   		                           
		                           
   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 
		                           
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ; 
   CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ; 

   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {

     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int    passedJSON = passJSON ( run, ls , isData ) ;

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------
     
     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;

     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // JSON variable
     fillVariableWithValue(   "PassJSON"                      , passedJSON ) ; 

     // Noise filters
     fillVariableWithValue(   "PassHBHENoiseFilter"           , PassHBHENoiseFilter ) ; 
     fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight ) ; 

     //--------------------------------------------------------------------------
     // Trigger
     //--------------------------------------------------------------------------

     int min_prescale;
     int passTrigger;
     std::string min_prescale_name;

     if ( isData ) {

       //--------------------------------------------------------------------------
       // 7 trigger paths (some with multiple versions)
       //--------------------------------------------------------------------------

       // Number of times a path fired per event ( should be 0 or 1 )

       int N_Photon30_CIdVL  = 0;
       int N_Photon50_CIdVL  = 0;
       int N_Photon75_CIdVL  = 0;
       int N_Photon90_CIdVL  = 0;
       int N_Photon125       = 0;
       int N_Photon135       = 0;
       int N_Photon400       = 0;

       // Trigger prescale in an event
       
       int PS_Photon30_CIdVL = 0;
       int PS_Photon50_CIdVL = 0;
       int PS_Photon75_CIdVL = 0;
       int PS_Photon90_CIdVL = 0;
       int PS_Photon125      = 0;
       int PS_Photon135      = 0;
       int PS_Photon400      = 0;

       //--------------------------------------------------------------------------
       // Find the right prescale for this event
       //--------------------------------------------------------------------------
       
       // Did the HLT_Photon30_CaloIdVL trigger fire?

       if ( H_Photon30_CIdVL_1 > 0 && H_Photon30_CIdVL_1 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_1; } 
       if ( H_Photon30_CIdVL_2 > 0 && H_Photon30_CIdVL_2 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_2; } 
       if ( H_Photon30_CIdVL_3 > 0 && H_Photon30_CIdVL_3 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_3; } 
       if ( H_Photon30_CIdVL_4 > 0 && H_Photon30_CIdVL_4 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_4; } 
       if ( H_Photon30_CIdVL_5 > 0 && H_Photon30_CIdVL_5 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_5; } 
       if ( H_Photon30_CIdVL_6 > 0 && H_Photon30_CIdVL_6 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_6; } 
       if ( H_Photon30_CIdVL_7 > 0 && H_Photon30_CIdVL_7 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_7; } 

       if ( isData && run > 175771 ) {
       	 if ( H_Photon30_CIdVL_8 > 0 && H_Photon30_CIdVL_8 != 999 ) { N_Photon30_CIdVL++; PS_Photon30_CIdVL = H_Photon30_CIdVL_8; }
       }

       // Did the HLT_Photon50_CaloIdVL trigger fire?
       
       if ( H_Photon50_CIdVL_1 > 0 && H_Photon50_CIdVL_1 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_1; } 
       if ( H_Photon50_CIdVL_2 > 0 && H_Photon50_CIdVL_2 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_2; } 
       if ( H_Photon50_CIdVL_3 > 0 && H_Photon50_CIdVL_3 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_3; } 
       if ( H_Photon50_CIdVL_4 > 0 && H_Photon50_CIdVL_4 != 999 ) { N_Photon50_CIdVL++; PS_Photon50_CIdVL = H_Photon50_CIdVL_4; } 

       // Did the HLT_Photon75_CaloIdVL trigger fire?
       
       if ( H_Photon75_CIdVL_1 > 0 && H_Photon75_CIdVL_1 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_1; } 
       if ( H_Photon75_CIdVL_2 > 0 && H_Photon75_CIdVL_2 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_2; } 
       if ( H_Photon75_CIdVL_3 > 0 && H_Photon75_CIdVL_3 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_3; } 
       if ( H_Photon75_CIdVL_4 > 0 && H_Photon75_CIdVL_4 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_4; } 
       if ( H_Photon75_CIdVL_5 > 0 && H_Photon75_CIdVL_5 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_5; } 
       if ( H_Photon75_CIdVL_6 > 0 && H_Photon75_CIdVL_6 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_6; } 
       if ( H_Photon75_CIdVL_7 > 0 && H_Photon75_CIdVL_7 != 999 ) { N_Photon75_CIdVL++; PS_Photon75_CIdVL = H_Photon75_CIdVL_7; }

       // Did the HLT_Photon90_CaloIdVL trigger fire?
       
       if ( H_Photon90_CIdVL_1 > 0 && H_Photon90_CIdVL_1 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_1; } 
       if ( H_Photon90_CIdVL_2 > 0 && H_Photon90_CIdVL_2 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_2; } 
       if ( H_Photon90_CIdVL_3 > 0 && H_Photon90_CIdVL_3 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_3; } 
       if ( H_Photon90_CIdVL_4 > 0 && H_Photon90_CIdVL_4 != 999 ) { N_Photon90_CIdVL++; PS_Photon90_CIdVL = H_Photon90_CIdVL_4; } 

       // Did the HLT_Photon125 trigger fire?
       
       if ( H_Photon125_1      > 0 && H_Photon125_1      != 999 ) { N_Photon125     ++; PS_Photon125      = H_Photon125_1     ; } 
       if ( H_Photon125_2      > 0 && H_Photon125_2      != 999 ) { N_Photon125     ++; PS_Photon125      = H_Photon125_2     ; } 
   
       // Did the HLT_Photon135 trigger fire?

       if ( H_Photon135_1      > 0 && H_Photon135_1      != 999 ) { N_Photon135     ++; PS_Photon135      = H_Photon135_1     ; } 
       if ( H_Photon135_2      > 0 && H_Photon135_2      != 999 ) { N_Photon135     ++; PS_Photon135      = H_Photon135_2     ; } 
       
       // Did the HLT_Photon400 trigger fire?

       if ( H_Photon400_1      > 0 && H_Photon400_1      != 999 ) { N_Photon400     ++; PS_Photon400      = H_Photon400_1     ; } 
       
       if ( isData && run > 175771 ) {
       	 if ( H_Photon400_2      > 0 && H_Photon400_2      != 999 ) { N_Photon400     ++; PS_Photon400      = H_Photon400_2     ; }
       }
       
       // Sanity check: make sure two versions of the same trigger didn't fire in the same event (impossible)
              
       if ( N_Photon30_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon30_CIdVL" << std::endl; exit (0); }
       if ( N_Photon50_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon50_CIdVL" << std::endl; exit (0); }
       if ( N_Photon75_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon75_CIdVL" << std::endl; exit (0); }
       if ( N_Photon90_CIdVL > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon90_CIdVL" << std::endl; exit (0); }
       if ( N_Photon125      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon125"      << std::endl; exit (0); }
       if ( N_Photon135      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon135"      << std::endl; exit (0); }
       if ( N_Photon400      > 1 ) { std::cout << "ERROR: trigger overlap in N_Photon400"      << std::endl; exit (0); }
      
       // What is the lowest-prescale trigger that this electron could have fired?
 
       min_prescale      = 999999;
       min_prescale_name = std::string("");

       if ( N_Photon30_CIdVL != 0 && QCDFakeEle1_Pt > 30. * trigger_tolerance  && PS_Photon30_CIdVL <= min_prescale ) { min_prescale = PS_Photon30_CIdVL; min_prescale_name = std::string("PS_Photon30_CIdVL"); }
       if ( N_Photon50_CIdVL != 0 && QCDFakeEle1_Pt > 50. * trigger_tolerance  && PS_Photon50_CIdVL <= min_prescale ) { min_prescale = PS_Photon50_CIdVL; min_prescale_name = std::string("PS_Photon50_CIdVL"); }
       if ( N_Photon75_CIdVL != 0 && QCDFakeEle1_Pt > 75. * trigger_tolerance  && PS_Photon75_CIdVL <= min_prescale ) { min_prescale = PS_Photon75_CIdVL; min_prescale_name = std::string("PS_Photon75_CIdVL"); }
       if ( N_Photon90_CIdVL != 0 && QCDFakeEle1_Pt > 90. * trigger_tolerance  && PS_Photon90_CIdVL <= min_prescale ) { min_prescale = PS_Photon90_CIdVL; min_prescale_name = std::string("PS_Photon90_CIdVL"); }
       if ( N_Photon125      != 0 && QCDFakeEle1_Pt > 125.* trigger_tolerance  && PS_Photon125      <= min_prescale ) { min_prescale = PS_Photon125     ; min_prescale_name = std::string("PS_Photon125"     ); }
       if ( N_Photon135      != 0 && QCDFakeEle1_Pt > 135.* trigger_tolerance  && PS_Photon135      <= min_prescale ) { min_prescale = PS_Photon135     ; min_prescale_name = std::string("PS_Photon135"     ); }
       if ( N_Photon400      != 0 && QCDFakeEle1_Pt > 400.* trigger_tolerance  && PS_Photon400      <= min_prescale ) { min_prescale = PS_Photon400     ; min_prescale_name = std::string("PS_Photon400"     ); }

       // If we find a suitable trigger, scale this event by that trigger's prescale

       passTrigger = 0;
       if ( min_prescale != 999999 ) { // if I found some suitable trigger that fired
	 passTrigger = 1;     
       } else {                        // if I was not able to find a suitable trigger that fired
	 min_prescale = 0;            
       }

     }  // end if (isData) 
					       
     else { // i.e., if this is Monte Carlo
       min_prescale = 1;
       passTrigger = 1 ;
     }


     //--------------------------------------------------------------------------
     // What kind of event is this?
     //  - EB-EB
     //  - EB-EE
     //  - EE-EE
     //--------------------------------------------------------------------------
     
     bool ele1_isBarrel  = false;
     bool ele1_isEndcap1 = false;
     bool ele1_isEndcap2 = false;
     bool ele2_isBarrel  = false;
     bool ele2_isEndcap1 = false;
     bool ele2_isEndcap2 = false;
     
     if( fabs( QCDFakeEle1_Eta  ) < eleEta_bar )        ele1_isBarrel  = true;
     if( fabs( QCDFakeEle1_Eta  ) > eleEta_end1_min &&
	 fabs( QCDFakeEle1_Eta  ) < eleEta_end1_max )   ele1_isEndcap1 = true;
     if( fabs( QCDFakeEle1_Eta  ) > eleEta_end2_min &&
	 fabs( QCDFakeEle1_Eta  ) < eleEta_end2_max )   ele1_isEndcap2 = true;

     if( fabs( QCDFakeEle2_Eta  ) < eleEta_bar )        ele2_isBarrel  = true;
     if( fabs( QCDFakeEle2_Eta  ) > eleEta_end1_min &&
	 fabs( QCDFakeEle2_Eta  ) < eleEta_end1_max )   ele2_isEndcap1 = true;
     if( fabs( QCDFakeEle2_Eta  ) > eleEta_end2_min &&
	 fabs( QCDFakeEle2_Eta  ) < eleEta_end2_max )   ele2_isEndcap2 = true;

     bool isEBEB   = ( ele1_isBarrel  && ele2_isBarrel  );
     bool isEBEE1  = ( ele1_isBarrel  && ele2_isEndcap1 );
     bool isEBEE2  = ( ele1_isBarrel  && ele2_isEndcap2 );

     bool isEE1EB  = ( ele1_isEndcap1 && ele2_isBarrel  );
     bool isEE1EE1 = ( ele1_isEndcap1 && ele2_isEndcap1 );
     bool isEE1EE2 = ( ele1_isEndcap1 && ele2_isEndcap2 );

     bool isEE2EB  = ( ele1_isEndcap2 && ele2_isBarrel  );
     bool isEE2EE1 = ( ele1_isEndcap2 && ele2_isEndcap1 );
     bool isEE2EE2 = ( ele1_isEndcap2 && ele2_isEndcap2 );

     bool isEBEE   = ( isEBEE1  || isEBEE2  || isEE1EB  || isEE2EB  );
     bool isEEEE   = ( isEE1EE1 || isEE1EE2 || isEE2EE1 || isEE2EE2 );

     //--------------------------------------------------------------------------
     // Determine which fake rates to use
     //--------------------------------------------------------------------------

     double fakeRate1  = 0.0;
     double fakeRate2  = 0.0;
     double eFakeRate1 = 0.0 ;
     double eFakeRate2 = 0.0;
     
     if ( QCDFakeEle1_Pt < 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_low_bar_p0  + fakeRate_low_bar_p1  * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_bar_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_bar_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 ) * 
			     ( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 )));
       }
       if ( ele1_isEndcap1 ) {
	 fakeRate1  = fakeRate_low_end1_p0 + fakeRate_low_end1_p1 * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end1_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_end1_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 ) * 
			     ( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 )));

       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_low_end2_p0 + fakeRate_low_end2_p1 * QCDFakeEle1_Pt;
	 eFakeRate1 = sqrt ((( eFakeRate_low_end2_p1  * QCDFakeEle1_Pt       ) * 
			     ( eFakeRate_low_end2_p1  * QCDFakeEle1_Pt       )) + 
			    (( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 ) * 
			     ( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 )));
       } 
     }
     else if  ( QCDFakeEle1_Pt >= 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate1  = fakeRate_high_bar_p0  ;
	 eFakeRate1 = eFakeRate_high_bar_p0 ;
       }
       if ( ele1_isEndcap1 ) { 
	 fakeRate1 = fakeRate_high_end1_p0 ;
	 eFakeRate1 = eFakeRate_high_end1_p0 ;
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate1 = fakeRate_high_end2_p0 ;
	 eFakeRate1 = eFakeRate_high_end2_p0 ;
       }
     }

     if ( QCDFakeEle2_Pt < 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate2  = fakeRate_low_bar_p0  + fakeRate_low_bar_p1  * QCDFakeEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_bar_p1  * QCDFakeEle2_Pt       ) * 
			     ( eFakeRate_low_bar_p1  * QCDFakeEle2_Pt       )) + 
			    (( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 ) * 
			     ( eFakeRate_low_bar_p0  * eFakeRate_low_bar_p0 )));
       }
       if ( ele1_isEndcap1 ) {
	 fakeRate2 = fakeRate_low_end1_p0 + fakeRate_low_end1_p1 * QCDFakeEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_end1_p1  * QCDFakeEle2_Pt       ) * 
			     ( eFakeRate_low_end1_p1  * QCDFakeEle2_Pt       )) + 
			    (( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 ) * 
			     ( eFakeRate_low_end1_p0  * eFakeRate_low_end1_p0 )));
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate2 = fakeRate_low_end2_p0 + fakeRate_low_end2_p1 * QCDFakeEle2_Pt;
	 eFakeRate2 = sqrt ((( eFakeRate_low_end2_p1  * QCDFakeEle2_Pt       ) * 
			     ( eFakeRate_low_end2_p1  * QCDFakeEle2_Pt       )) + 
			    (( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 ) * 
			     ( eFakeRate_low_end2_p0  * eFakeRate_low_end2_p0 )));
       }
     }

     else if  ( QCDFakeEle2_Pt >= 100 ){
       if ( ele1_isBarrel  ) {
	 fakeRate2  = fakeRate_high_bar_p0  ;
	 eFakeRate2 = eFakeRate_high_bar_p0;
       }
       if ( ele1_isEndcap1 ) { 
	 fakeRate2 = fakeRate_high_end1_p0 ;
	 eFakeRate2 = eFakeRate_high_end1_p0;
       }
       if ( ele1_isEndcap2 ) {
	 fakeRate2 = fakeRate_high_end2_p0 ;
	 eFakeRate2 = eFakeRate_high_end2_p0;
       }
     }

     //--------------------------------------------------------------------------
     // Finally have the effective fake rate
     //--------------------------------------------------------------------------

     double fakeRateEffective  = fakeRate1 + fakeRate2;
     double eFakeRateEffective = sqrt ( ( eFakeRate1 * eFakeRate1 ) +
					( eFakeRate2 * eFakeRate2 ) );

     // fakeRateEffective += eFakeRateEffective;

     //--------------------------------------------------------------------------
     // User has the option to use a flat fake rate (e.g. 1.0 = no fake rate)
     //--------------------------------------------------------------------------
     
     if ( override_fakeRate ) fakeRateEffective = fakeRate_override;

     //--------------------------------------------------------------------------
     // Bug: we don't have the number for number of loose jets stored... 
     // Have to derive it
     //--------------------------------------------------------------------------

     int nJetLooseEle_Stored = 0;
     if      ( JetLooseEle3_Pt > 10.0 ) nJetLooseEle_Stored = 3;
     else if ( JetLooseEle2_Pt > 10.0 ) nJetLooseEle_Stored = 2;
     else if ( JetLooseEle1_Pt > 10.0 ) nJetLooseEle_Stored = 1;
     else                               nJetLooseEle_Stored = 0;

     //--------------------------------------------------------------------------
     // How many loose electrons have HEEP ID?
     //--------------------------------------------------------------------------

     int nPass = 0;
     if ( QCDFakeEle1_PassID == 1 ) nPass ++;
     if ( QCDFakeEle2_PassID == 1 ) nPass ++;

     //--------------------------------------------------------------------------
     // Calculate a few missing variables
     //--------------------------------------------------------------------------

     TLorentzVector loose_ele1, loose_ele2 , jet1, jet2;
     loose_ele1.SetPtEtaPhiM ( QCDFakeEle1_Pt , QCDFakeEle1_Eta , QCDFakeEle1_Phi , 0.0 );
     loose_ele2.SetPtEtaPhiM ( QCDFakeEle2_Pt , QCDFakeEle2_Eta , QCDFakeEle2_Phi , 0.0 );
     jet1.SetPtEtaPhiM       ( JetLooseEle1_Pt, JetLooseEle1_Eta, JetLooseEle1_Phi, 0.0 );
     jet2.SetPtEtaPhiM       ( JetLooseEle2_Pt, JetLooseEle2_Eta, JetLooseEle2_Phi, 0.0 );

     TLorentzVector loose_e1e2 = loose_ele1 + loose_ele2;
     TLorentzVector j1j2 = jet1 + jet2;

     TLorentzVector e1j1 = loose_ele1 + jet1;
     TLorentzVector e2j1 = loose_ele2 + jet1;

     //--------------------------------------------------------------------------
     // Now fill cut values
     // DON'T use the pileup weight ... it's included by default
     // DO    use the prescale.  It's already 1.0 for MC.
     // DO    use the effective fake rate.  It will only mean anything when you run
     //       over data, though, so be sure to override it to 1.0 
     //       if you run over Monte Carlo
     //--------------------------------------------------------------------------
     
     fillVariableWithValue ( "PassHLT", passTrigger, min_prescale * fakeRateEffective ) ;
     
     // Electrons
     fillVariableWithValue(   "nEleLoose"                     , nEle_QCDFake     , min_prescale  * fakeRateEffective );
     fillVariableWithValue(   "nEleTight"                     , nPass            , min_prescale  * fakeRateEffective );
     if ( nEle_QCDFake >= 1 ) { 
       fillVariableWithValue( "Ele1_Pt"                       , QCDFakeEle1_Pt   , min_prescale  * fakeRateEffective ) ;
       fillVariableWithValue( "Ele1_Eta"                      , QCDFakeEle1_Eta  , min_prescale  * fakeRateEffective ) ;
     }
     if ( nEle_QCDFake >= 2 ) { 
       fillVariableWithValue( "Ele2_Pt"                       , QCDFakeEle2_Pt   , min_prescale  * fakeRateEffective ) ;
       fillVariableWithValue( "Ele2_Eta"                      , QCDFakeEle2_Eta  , min_prescale  * fakeRateEffective ) ;
       fillVariableWithValue( "M_e1e2"                        , loose_e1e2.M()   , min_prescale  * fakeRateEffective );
       fillVariableWithValue( "Pt_e1e2"                       , loose_e1e2.Pt()  , min_prescale  * fakeRateEffective );
     }

     // Jets
     fillVariableWithValue(   "nJet"                          , nJetLooseEle_Stored , min_prescale  * fakeRateEffective );
     if ( nJetLooseEle_Stored >= 1 ) {
       fillVariableWithValue( "Jet1_Pt"                       , JetLooseEle1_Pt   , min_prescale  * fakeRateEffective ) ;
       fillVariableWithValue( "Jet1_Eta"                      , JetLooseEle1_Eta , min_prescale  * fakeRateEffective ) ;
     }

     // Muons
     fillVariableWithValue(   "nMuon"                         , nMuon_Ana           , min_prescale  * fakeRateEffective ); 
										      			      
     // DeltaR
     if ( nEle_QCDFake >= 2 && nJetLooseEle_Stored >= 1) {
       double st = QCDFakeEle1_Pt + QCDFakeEle2_Pt + JetLooseEle1_Pt ;
       fillVariableWithValue( "DR_Ele1Jet1"                   , loose_ele1.DeltaR ( jet1 ), min_prescale  * fakeRateEffective );
       fillVariableWithValue( "DR_Ele2Jet1"                   , loose_ele2.DeltaR ( jet1 ), min_prescale  * fakeRateEffective );
       fillVariableWithValue( "sT_eej_200"                    , st                        , min_prescale  * fakeRateEffective );
       fillVariableWithValue( "sT_eej_450"                    , st                        , min_prescale  * fakeRateEffective );
     }      

     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Fill preselection plots
     // DO    use the pileup weight.  It's equal to 1.0 for data.  
     // DO    use the min_prescale.  It's equal to 1.0 for Monte Carlo
     // DO    use the effective fake rate.  It will only mean anything when you run
     //       over data, though, so be sure to override it to 1.0 
     //       if you run over Monte Carlo
     //--------------------------------------------------------------------------     

     bool passed_preselection = ( passedAllPreviousCuts("sT_eej_200") && passedCut ("sT_eej_200") );
     
     if ( passed_preselection ) {

       double sT_eej = QCDFakeEle1_Pt + QCDFakeEle2_Pt + JetLooseEle1_Pt ;

       FillUserTH1D("nElectron_PAS"        , nEle_QCDFake              , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("nMuon_PAS"            , nMuon_Stored              , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("nJet_PAS"             , nJetLooseEle_Stored       , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Pt1stEle_PAS"	   , QCDFakeEle1_Pt            , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Eta1stEle_PAS"	   , QCDFakeEle1_Eta           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Phi1stEle_PAS"	   , QCDFakeEle1_Phi           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Pt2ndEle_PAS"	   , QCDFakeEle2_Pt            , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Eta2ndEle_PAS"	   , QCDFakeEle2_Eta           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Phi2ndEle_PAS"	   , QCDFakeEle2_Phi           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Charge1stEle_PAS"	   , QCDFakeEle1_Charge        , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Charge2ndEle_PAS"	   , QCDFakeEle2_Charge        , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("MET_PAS"              , MET_Pt                    , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("METPhi_PAS"	   , MET_Phi                   , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("METCharged_PAS"       , PFMETCharged              , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("METChargedPhi_PAS"    , PFMETChargedPhi           , pileup_weight * min_prescale * fakeRateEffective );   
       FillUserTH1D("METType1_PAS"         , PFMETType1Cor             , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("METType1Phi_PAS"      , PFMETPhiType1Cor          , pileup_weight * min_prescale * fakeRateEffective );   
       FillUserTH1D("Pt1stJet_PAS"         , JetLooseEle1_Pt           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Eta1stJet_PAS"        , JetLooseEle1_Eta          , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Phi1stJet_PAS"	   , JetLooseEle1_Phi          , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("sT_PAS"               , sT_eej                    , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Mee_PAS"		   , loose_e1e2.M()            , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Ptee_PAS"             , loose_e1e2.Pt()           , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("nVertex_PAS"          , nVertex                   , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("nVertex_good_PAS"     , nVertex_good              , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("DR_Ele1Jet1_PAS"	   , loose_ele1.DeltaR ( jet1 ), pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("DR_Ele2Jet1_PAS"	   , loose_ele2.DeltaR ( jet1 ), pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Me1j1_PAS"            , e1j1.M()                  , pileup_weight * min_prescale * fakeRateEffective );
       FillUserTH1D("Me2j1_PAS"            , e2j1.M()                  , pileup_weight * min_prescale * fakeRateEffective );
     }
   } // End loop over events

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 (  true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // dataset
   
   int dataset  = getPreCutValue1("dataset") ;
   bool select2011A = ( dataset == 0 );
   bool select2011B = ( dataset == 1 );
   bool select2011  = ( dataset == 2 );

   if ( ! select2011A &&
	! select2011B &&
	! select2011 ) {
     std::cout << "Error: Must choose dataset to be 0 (2011A), 1 (2011B), or 2 (all 2011)" << std::endl;
   }

   //--------------------------------------------------------------------------
   // Set global variables
   //--------------------------------------------------------------------------
   
   TVector2 v_METCharged, v_METType1, v_ele;
   
   //--------------------------------------------------------------------------
   // Pileup reweighting initialization
   //--------------------------------------------------------------------------

   // Lumi3DReWeighting lumiWeights = Lumi3DReWeighting("/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/PUMC_dist.root", "/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/PUData_dist.root", "pileup", "pileup");
   // lumiWeights.weight3D_init("/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/Weight3D.root");
     
   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------

   CreateUserTH1D( "nElectron_PAS"            , 5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"                , 5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"                 , 11  , -0.5    , 10.5     );
   CreateUserTH1D( "Pt1stEle_PAS"	      , 100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	      , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	      , 2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MatchPhotonConv1stEle_PAS",	2   , -0.5    , 1.5      );
   CreateUserTH1D( "MatchPhotonConv2ndEle_PAS",	2   , -0.5    , 1.5      );
   CreateUserTH1D( "MET_PAS"                  , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"           , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"             , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METSig_PAS"               , 100 , 0       , 800      );
   CreateUserTH1D( "minMETPt1stEle_PAS"       , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"             , 100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt2ndJet_PAS"             , 100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"            , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Eta2ndJet_PAS"            , 100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Phi2ndJet_PAS"	      , 60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "TCHE1stJet_PAS"           , 100 , 0       , 20	 ); 
   CreateUserTH1D( "TCHE2ndJet_PAS"           , 100 , 0       , 20	 ); 
   CreateUserTH1D( "nMuon_PtCut_IDISO_PAS"    , 16  , -0.5    , 15.5	 ); 
   CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "MT_charged_enu_PAS"       , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "MT_type1_enu_PAS"         , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Ptenu_PAS"		      , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTlep_PAS"                , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTjet_PAS"                , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                   , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mjj_PAS"		      , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mej1_PAS"                 , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mej2_PAS"                 , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mej_PAS"                  , 200 , 0       , 2000	 ); 
   CreateUserTH1D( "MTjnu_PAS"                , 200 , 0       , 1000     );
   CreateUserTH1D( "DCotTheta1stEle_PAS"      , 100 , 0.0     , 1.0      );
   CreateUserTH1D( "Dist1stEle_PAS"           , 100 , 0.0     , 1.0      );  
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	      , 100 , 0       , 10       ); 
   CreateUserTH1D( "DR_Ele1Jet2_PAS"	      , 100 , 0       , 10       ); 
   CreateUserTH1D( "DR_Jet1Jet2_PAS"	      , 100 , 0       , 10       );
   CreateUserTH1D( "minDR_EleJet_PAS"         , 100 , 0       , 10       );  
   CreateUserTH1D( "mDPhi1stEleMET_PAS"       , 100 , 0.      , 3.14159  );
   CreateUserTH1D( "mDPhi1stJetMET_PAS"       , 100 , 0.      , 3.14159  );
   CreateUserTH1D( "mDPhi2ndJetMET_PAS"       , 100 , 0.      , 3.14159  );
   CreateUserTH1D( "GeneratorWeight"          , 200 , -2.0    , 2.0      );
   CreateUserTH1D( "PileupWeight"             , 200 , -2.0    , 2.0      );

   CreateUserTH1D( "MT_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MT_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );

   CreateUserTH1D( "MTCharged_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTCharged_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );

   CreateUserTH1D( "MTType1_GoodVtxLTE3_PAS"       , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE4_LTE8_PAS"  , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE9_LTE15_PAS" , 200 , 0.      ,  1000    );
   CreateUserTH1D( "MTType1_GoodVtxGTE16_PAS"      , 200 , 0.      ,  1000    );

   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 
   
   CreateUserTH1D( "MTenu_50_110", 200, 40, 140 );

   CreateUserTH1D( "run_PAS"               ,    20000 , 160300  , 180300 );
   CreateUserTH1D( "run_HLT"               ,    20000 , 160300  , 180300 );
   
   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   std::cout << "fChain = " << fChain << std::endl;

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

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%10000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------
     
     // double pileup_weight = lumiWeights.weight3D (nPileUpInt_BXminus1, nPileUpInt_BX0, nPileUpInt_BXplus1 );
     // if ( isData ) pileup_weight = 1.0;
     // setPileupWeight ( pileup_weight ) ;

     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;
     
     // std::cout << "nPileUpInt_BX0 = " << nPileUpInt_BX0 << ", pileup_weight = " << pileup_weight << std::endl;
     // std::cout << "  Data file: " <<       pileupReweighter_.getPileupDataFile () << std::endl;
     // std::cout << "  MC   file: " <<       pileupReweighter_.getPileupMCFile   () << std::endl;
     // pileupReweighter_.printPileupWeights();
     // std::cout << "MC PDF at npileup = 11: " << pileupReweighter_.getMCPDF ( 11 )  << std::endl;
     
     //--------------------------------------------------------------------------
     // Get information about gen-level reweighting (should be for Sherpa only)
     //--------------------------------------------------------------------------

     double gen_weight = Weight;
     if ( isData ) gen_weight = 1.0;

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int passedJSON = passJSON ( run, ls , isData ) ;
     if ( !isData ) passedJSON = 1;
     
     //--------------------------------------------------------------------------
     // Check HLT
     //--------------------------------------------------------------------------
     
     int passedHLT = 1;
     if ( isData ){ 
       
       passedHLT = 0;
       
       if ( run < 175771 ){ // 2011A 
	 if ( H_27_CIdVT_CIsT_TIdT_TIsT_1  == 1|| // SingleElectron, 2011A
	      H_27_CIdVT_CIsT_TIdT_TIsT_2  == 1|| // SingleElectron, 2011A
	      H_27_CIdVT_CIsT_TIdT_TIsT_3  == 1|| // SingleElectron, 2011A
	      H_32_CIdVT_CIsT_TIdT_TIsT_3  == 1|| // SingleElectron, 2011A
	      H_17_HEEP_CJ30_25_MHT15_2    == 1|| // ElectronHad, 2011A
	      H_25_HEEP_CJ30_25_MHT20_4    == 1|| // ElectronHad, 2011A
	      H_22_HEEP_CJ30_25_MHT20_2    == 1|| // ElectronHad, 2011A
	      H_22_HEEP_CJ30_25_MHT20_4    == 1|| // ElectronHad, 2011A
	      H_27_HEEP_CJ30_25_MHT20_2    == 1){ // ElectronHad, 2011A
	   passedHLT = 1;
	 }
       }
       
       else if ( run > 175771 ){ // 2011 B 
	 if ( H_Ele30_HEEP_2CJ30_MHT25_1 == 1 ||  // ElectronHad, 2011B
	      H_Ele27_WP80_2CJ25_MHT15_4 == 1 ||  // ElectronHad, 2011B
	      H_Ele27_WP80_2CJ25_MHT15_5 == 1 ) { // ElectronHad, 2011B
	   passedHLT = 1;
	 }
       }
     }


     //--------------------------------------------------------------------------
     // Is this the dataset we want?
     //--------------------------------------------------------------------------
     
     int PassDataset = 1;
     if ( isData ) { 
       PassDataset = 0;
       if ( select2011A ){ 
	 if ( run >= 160329 && run <= 175770 ) PassDataset = 1;
       }
       if ( select2011B ){
	 if ( run >= 175832 && run <= 180296 ) PassDataset = 1;
       }
       if ( select2011 ) {
	 if ( run >= 160329 && run <= 180296 ) PassDataset = 1;
       }
     }

     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // JSON variable
     fillVariableWithValue(   "Reweighting"              , 1                       , gen_weight );
     fillVariableWithValue(   "PassJSON"                 , passedJSON              , gen_weight ); 
     				
     // Pass dataset variable     
     fillVariableWithValue(   "PassDataset"              , PassDataset             , gen_weight );

     // HLT variable							           
     fillVariableWithValue(   "PassHLT"                  , passedHLT               , gen_weight );
     
     // Filters
     fillVariableWithValue(   "PassHBHENoiseFilter"      , PassHBHENoiseFilter     , gen_weight );
     fillVariableWithValue(   "PassBeamHaloFilterTight"  , PassBeamHaloFilterTight , gen_weight );
									      
     // Muon variables ( for veto ) 					      
     fillVariableWithValue(   "nMuon"                    , nMuon_Ana               , gen_weight );
			                                      		                
     // 1st Electron variables				      		                
     fillVariableWithValue(   "nEle"                     , nEle_Ana                , gen_weight ); 
     fillVariableWithValue(   "Ele1_Pt"                  , Ele1_Pt                 , gen_weight );
     fillVariableWithValue(   "Ele1_Eta"                 , Ele1_Eta                , gen_weight );
									           
     // MET variables	                                      		           
     fillVariableWithValue(   "MET"                      , MET_Pt                  , gen_weight );
     fillVariableWithValue(   "mDeltaPhiMETEle"          , mDPhi_METEle1           , gen_weight );
     									           
     // 1st JET variables                                     		           
     fillVariableWithValue(   "nJet"                     , nJet_Ana                , gen_weight );
				
     double MT_Jet1MET, MT_Jet2MET, MT_Ele1Jet1, MT_Ele1Jet2;
     // 1st JET variables                                     		           
     if ( nJet_Stored > 0 ) { 						           
       fillVariableWithValue( "Jet1_Pt"                  , Jet1_Pt                 , gen_weight );
       fillVariableWithValue( "Jet1_Eta"                 , Jet1_Eta                , gen_weight );
       fillVariableWithValue( "mDeltaPhiMET1stJet"       , mDPhi_METJet1           , gen_weight );

       	TVector2 v_MET;
	TVector2 v_jet;
	v_MET.SetMagPhi( MET_Pt , MET_Phi  );
	v_jet.SetMagPhi( Jet1_Pt, Jet1_Phi );
	float deltaphi = v_MET.DeltaPhi(v_jet);
	MT_Jet1MET = sqrt ( 2 * Jet1_Pt * MET_Pt * ( 1 - cos ( deltaphi ) ) );
     }									           
     									           
     // 2nd JET variables                                     		           
     if ( nJet_Stored > 1 ) { 	                                      	           
       fillVariableWithValue( "Jet2_Pt"                  , Jet2_Pt                 , gen_weight );
       fillVariableWithValue( "Jet2_Eta"                 , Jet2_Eta                , gen_weight );
       fillVariableWithValue( "ST"                       , sT_enujj                , gen_weight );

       	TVector2 v_MET;
	TVector2 v_jet;
	v_MET.SetMagPhi( MET_Pt , MET_Phi  );
	v_jet.SetMagPhi( Jet2_Pt, Jet2_Phi );
	float deltaphi = v_MET.DeltaPhi(v_jet);
	MT_Jet2MET = sqrt ( 2 * Jet2_Pt * MET_Pt * ( 1 - cos ( deltaphi ) ) );
     }

     // 3rd JET variables 
     // if ( nJet_Stored > 2 ) {
     //   fillVariableWithValue( "Jet3_Pt"                  , Jet3_Pt                 , gen_weight );
     //   fillVariableWithValue( "Jet3_Eta"                 , Jet3_Eta                , gen_weight );
     // }

     // 1 electron, 1 jet variables 
     if ( nEle_Ana > 0 && nJet_Ana > 0 ) { 
       fillVariableWithValue ( "DR_Ele1Jet1"             , DR_Ele1Jet1             , gen_weight );
       
       TVector2 v_ele;
       TVector2 v_jet1;
       v_ele .SetMagPhi ( Ele1_Pt, Ele1_Phi );
       v_jet1.SetMagPhi ( Jet1_Pt, Jet1_Phi );
       float deltaphi = v_ele.DeltaPhi ( v_jet1 );
       MT_Ele1Jet1 = sqrt ( 2 * Jet1_Pt * Ele1_Pt * ( 1 - cos ( deltaphi ) ) );
     }

     // 1 electron, 2 jet variables 
     if ( nEle_Ana > 0 && nJet_Ana > 1 ) { 
       fillVariableWithValue ( "DR_Ele1Jet2"             , DR_Ele1Jet2             , gen_weight );

       TVector2 v_ele;
       TVector2 v_jet2;
       v_ele .SetMagPhi ( Ele1_Pt, Ele1_Phi );
       v_jet2.SetMagPhi ( Jet2_Pt, Jet2_Phi );
       float deltaphi = v_ele.DeltaPhi ( v_jet2 );
       MT_Ele1Jet2 = sqrt ( 2 * Jet2_Pt * Ele1_Pt * ( 1 - cos ( deltaphi ) ) );
     }

     double min_ElePt_MET;
     if ( nEle_Ana > 0 ){
       if ( Ele1_Pt > MET_Pt ) min_ElePt_MET = MET_Pt ;
       else                    min_ElePt_MET = Ele1_Pt;
     }

     double MT_JetMET;
     double Mej;
     
     if ( fabs ( MT_Jet1MET - MT_Ele1Jet2 ) < fabs( MT_Jet2MET - MT_Ele1Jet1 )){
       MT_JetMET = MT_Jet1MET;
       Mej = M_e1j2;
     } else { 
       MT_JetMET = MT_Jet2MET;
       Mej = M_e1j1;
     }	 

     if ( nEle_Ana > 0 && nJet_Ana > 1 ) { 
       fillVariableWithValue("MTenu_final"    ,  MT_Ele1MET              , gen_weight );
       fillVariableWithValue("ST_opt"	      ,  sT_enujj                , gen_weight );
       fillVariableWithValue("Mej_min_opt"    ,  Mej                     , gen_weight );
       fillVariableWithValue("MTjnu_opt"      ,  MT_Jet1MET              , gen_weight );
       fillVariableWithValue("MinElePtMET_opt",  min_ElePt_MET           , gen_weight );
     }     
     
     // Dummy variables
     fillVariableWithValue ("preselection",1, gen_weight ); 

     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     if (!isData && !passedCut ("PassJSON")){
       std::cout << "ERROR: This event did not pass the JSON file!" << std::endl;
       std::cout << "  isData = " << isData << std::endl;
       std::cout << "  passedJSON = " << passedJSON << std::endl;
     }
     
     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------
     
     bool passed_preselection = passedAllPreviousCuts("preselection");
     bool passed_minimum      = ( passedAllPreviousCuts("PassBeamHaloFilterTight") && passedCut ("PassBeamHaloFilterTight"));
     
     if ( passed_minimum && isData ){ 
       FillUserTH1D ("run_HLT", run );
     }
     
     if ( passed_preselection ) { 
       
       //--------------------------------------------------------------------------
       // Fill skim tree, if necessary
       //--------------------------------------------------------------------------
       
       // fillSkimTree();

       bool use_charged_met = (PFMETCharged < MET_Pt);

       if ( use_charged_met ) v_METCharged.SetMagPhi(PFMETCharged , PFMETChargedPhi );
       else                   v_METCharged.SetMagPhi(MET_Pt       , MET_Phi         );
       
       v_METType1.SetMagPhi  (PFMETType1Cor, PFMETPhiType1Cor);
       v_ele.SetMagPhi       (Ele1_Pt      , Ele1_Phi        );
       
       double deltaphi_charged = v_METCharged.DeltaPhi(v_ele);
       double deltaphi_type1   = v_METType1  .DeltaPhi(v_ele);
       double MTCharged = sqrt(2 * Ele1_Pt * PFMETCharged  * (1 - cos(deltaphi_charged)) );
       double MTType1   = sqrt(2 * Ele1_Pt * PFMETType1Cor * (1 - cos(deltaphi_type1  )) );

       double min_DR_EleJet = 999.0;
       double DR_Ele1Jet3 = 999.0;
       if ( nJet_Ana > 2 ) {
	 TLorentzVector ele1,  jet3;
	 ele1.SetPtEtaPhiM ( Ele1_Pt, Ele1_Eta, Ele1_Phi, 0.0 );
	 jet3.SetPtEtaPhiM ( Jet3_Pt, Jet3_Eta, Jet3_Phi, 0.0 );	 
	 DR_Ele1Jet3 = ele1.DeltaR ( jet3 ) ;
       }

       if ( DR_Ele1Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet1;
       if ( DR_Ele1Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet2;
       if ( nJet_Ana > 2 ) {
	 if ( DR_Ele1Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet3;
       }
              
       if ( isData )        FillUserTH1D("run_PAS", run ) ;
       FillUserTH1D( "MT_charged_enu_PAS"         , MTCharged                      , pileup_weight * gen_weight);
       FillUserTH1D( "MT_type1_enu_PAS"           , MTType1                        , pileup_weight * gen_weight);
       FillUserTH1D( "nElectron_PAS"              , nEle_Ana                       , pileup_weight * gen_weight); 
       FillUserTH1D( "nMuon_PAS"                  , nMuon_Ana                      , pileup_weight * gen_weight); 
       FillUserTH1D( "Pt1stEle_PAS"	          , Ele1_Pt                        , pileup_weight * gen_weight); 
       FillUserTH1D( "Eta1stEle_PAS"	          , Ele1_Eta                       , pileup_weight * gen_weight);
       FillUserTH1D( "Phi1stEle_PAS"	          , Ele1_Phi                       , pileup_weight * gen_weight);
       FillUserTH1D( "Charge1stEle_PAS"           , Ele1_Charge                    , pileup_weight * gen_weight);   
       FillUserTH1D( "METSig_PAS"	          , PFMETSig                       , pileup_weight * gen_weight);   
       FillUserTH1D( "MET_PAS"                    , MET_Pt                         , pileup_weight * gen_weight);
       FillUserTH1D( "METPhi_PAS"	          , MET_Phi                        , pileup_weight * gen_weight);   
       FillUserTH1D( "METCharged_PAS"             , PFMETCharged                   , pileup_weight * gen_weight);
       FillUserTH1D( "METChargedPhi_PAS"          , PFMETChargedPhi                , pileup_weight * gen_weight);   
       FillUserTH1D( "METType1_PAS"               , PFMETType1Cor                  , pileup_weight * gen_weight);
       FillUserTH1D( "METType1Phi_PAS"            , PFMETPhiType1Cor               , pileup_weight * gen_weight);   
       FillUserTH1D( "minMETPt1stEle_PAS"         , TMath::Min ( Ele1_Pt, MET_Pt  ), pileup_weight * gen_weight);
       FillUserTH1D( "Pt1stJet_PAS"               , Jet1_Pt                        , pileup_weight * gen_weight);
       FillUserTH1D( "Pt2ndJet_PAS"               , Jet2_Pt                        , pileup_weight * gen_weight);
       FillUserTH1D( "Eta1stJet_PAS"              , Jet1_Eta                       , pileup_weight * gen_weight);
       FillUserTH1D( "Eta2ndJet_PAS"              , Jet2_Eta                       , pileup_weight * gen_weight);
       FillUserTH1D( "Phi1stJet_PAS"              , Jet1_Phi                       , pileup_weight * gen_weight);
       FillUserTH1D( "Phi2ndJet_PAS"	          , Jet2_Phi                       , pileup_weight * gen_weight);
       FillUserTH1D( "TCHE1stJet_PAS"             , Jet1_btagTCHE                  , pileup_weight * gen_weight);
       FillUserTH1D( "TCHE2ndJet_PAS"             , Jet2_btagTCHE                  , pileup_weight * gen_weight);
       FillUserTH1D( "nMuon_PtCut_IDISO_PAS"      , nMuon_Ana                      , pileup_weight * gen_weight); 
       FillUserTH1D( "MTenu_PAS"                  , MT_Ele1MET                     , pileup_weight * gen_weight);
       FillUserTH1D( "Ptenu_PAS"	          , Pt_Ele1MET                     , pileup_weight * gen_weight);
       FillUserTH1D( "sTlep_PAS"                  , Ele1_Pt + MET_Pt               , pileup_weight * gen_weight);
       FillUserTH1D( "sTjet_PAS"                  , Jet1_Pt + Jet2_Pt              , pileup_weight * gen_weight);
       FillUserTH1D( "sT_PAS"                     , sT_enujj                       , pileup_weight * gen_weight);
       FillUserTH1D( "Mjj_PAS"	                  , M_j1j2                         , pileup_weight * gen_weight);   
       FillUserTH1D( "DCotTheta1stEle_PAS"        , Ele1_DCotTheta                 , pileup_weight * gen_weight);
       FillUserTH1D( "Dist1stEle_PAS"             , Ele1_Dist                      , pileup_weight * gen_weight);
       FillUserTH1D( "mDPhi1stEleMET_PAS"         , mDPhi_METEle1                  , pileup_weight * gen_weight);
       FillUserTH1D( "mDPhi1stJetMET_PAS"         , mDPhi_METJet1                  , pileup_weight * gen_weight);
       FillUserTH1D( "mDPhi2ndJetMET_PAS"         , mDPhi_METJet2                  , pileup_weight * gen_weight); 
       FillUserTH1D( "Mej1_PAS"                   , M_e1j1                         , pileup_weight * gen_weight);
       FillUserTH1D( "Mej2_PAS"                   , M_e1j2                         , pileup_weight * gen_weight);
       FillUserTH1D( "Mej_PAS"                    , Mej                            , pileup_weight * gen_weight);
       FillUserTH1D( "MTjnu_PAS"                  , MT_JetMET                      , pileup_weight * gen_weight);
       FillUserTH1D( "DR_Ele1Jet1_PAS"	          , DR_Ele1Jet1                    , pileup_weight * gen_weight);
       FillUserTH1D( "DR_Ele1Jet2_PAS"	          , DR_Ele1Jet2                    , pileup_weight * gen_weight);
       FillUserTH1D( "DR_Jet1Jet2_PAS"	          , DR_Jet1Jet2                    , pileup_weight * gen_weight);
       FillUserTH1D( "minDR_EleJet_PAS"           , min_DR_EleJet                  , pileup_weight * gen_weight);
       FillUserTH1D( "nVertex_PAS"                , nVertex                        , pileup_weight * gen_weight);
       FillUserTH1D( "nVertex_good_PAS"           , nVertex_good                   , pileup_weight * gen_weight);
       FillUserTH1D( "MatchPhotonConv1stEle_PAS"  , Ele1_MatchPhotConv             , pileup_weight * gen_weight);
       FillUserTH1D( "MatchPhotonConv2ndEle_PAS"  , Ele2_MatchPhotConv             , pileup_weight * gen_weight);
       FillUserTH1D( "nJet_PAS"                   , nJet_Ana                       , pileup_weight * gen_weight);
       FillUserTH1D( "GeneratorWeight"       , gen_weight                     );
       FillUserTH1D( "PileupWeight"          , pileup_weight                  ); 
       
       if ( MT_Ele1MET > 50 && MT_Ele1MET < 110 ){
	 FillUserTH1D( "MTenu_50_110", MT_Ele1MET,  pileup_weight * gen_weight ) ;
       }
       
       if ( nVertex_good >= 0 && nVertex_good <= 3 ) {
	 FillUserTH1D( "MT_GoodVtxLTE3_PAS"              , MT_Ele1MET, pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTCharged_GoodVtxLTE3_PAS"       , MTCharged , pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTType1_GoodVtxLTE3_PAS"         , MTType1   , pileup_weight * gen_weight ) ;
       }						 
       
       if ( nVertex_good >= 4 && nVertex_good <= 8 ) {	 
	 FillUserTH1D( "MT_GoodVtxGTE4_LTE8_PAS"         , MT_Ele1MET, pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE4_LTE8_PAS"  , MTCharged , pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE4_LTE8_PAS"    , MTType1   , pileup_weight * gen_weight ) ;
       }
       
       if ( nVertex_good >= 9 && nVertex_good <= 15) {
	 FillUserTH1D( "MT_GoodVtxGTE9_LTE15_PAS"        , MT_Ele1MET, pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE9_LTE15_PAS" , MTCharged , pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE9_LTE15_PAS"   , MTType1   , pileup_weight * gen_weight ) ;
       }
       
       if ( nVertex_good >= 16                     ) {
	 FillUserTH1D( "MT_GoodVtxGTE16_PAS"             , MT_Ele1MET, pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTCharged_GoodVtxGTE16_PAS"      , MTCharged , pileup_weight * gen_weight ) ;
	 FillUserTH1D( "MTType1_GoodVtxGTE16_PAS"        , MTType1   , pileup_weight * gen_weight ) ;
       }
     }
   } // End loop over events

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop() {
  
  //--------------------------------------------------------------------------
  // Decide which plots to save (default is to save everything)
  //--------------------------------------------------------------------------
  
  fillSkim                         (  true  ) ;
  fillAllPreviousCuts              (  true  ) ;
  fillAllOtherCuts                 (  true  ) ;
  fillAllSameLevelAndLowerLevelCuts( !true  ) ;
  fillAllCuts                      (  true  ) ;

  double lj_filter_lead_ele_min_pt = getPreCutValue1("LJFilterLeadEleMinPt");
  
  //------------------------------------------------------------------
  // How many events to skim over?
  //------------------------------------------------------------------
  
  Long64_t nentries = fChain->GetEntries();
  std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

  //------------------------------------------------------------------
  // Loop over events
  //------------------------------------------------------------------

  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) {

    //------------------------------------------------------------------
    // ROOT loop preamble
    //------------------------------------------------------------------

    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;

    //------------------------------------------------------------------
    // Tell user how many events we've looped over
    //------------------------------------------------------------------

    if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
    
    //------------------------------------------------------------------
    // What HLT paths to apply?
    //------------------------------------------------------------------
    
    char trigger_name[200];
    
    if ( isData ){ 
      if      ( run >= 190456 && run <= 190738 ) sprintf(trigger_name, "HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_Mass50_v3");
      else if ( run >= 190782 && run <= 191419 ) sprintf(trigger_name, "HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_Mass50_v4");
      else if ( run >= 191691 && run <= 196531 ) sprintf(trigger_name, "HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_Mass50_v5");
      else if ( run >= 198022                  ) sprintf(trigger_name, "HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_Mass50_v6");
    } 
    else                                         sprintf(trigger_name, "HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_Mass50_v5");
    
    //------------------------------------------------------------------
    // Get trigger decision
    //------------------------------------------------------------------
    
    getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ; 
    bool trigger_fired = triggerFired ( trigger_name );

    //------------------------------------------------------------------
    // Also skim on electron filter
    //------------------------------------------------------------------
    
    bool pass_lj_filter = false;
    if (  ElectronPt -> size() > 0 ) 
      pass_lj_filter = ((*ElectronPt)[0] > lj_filter_lead_ele_min_pt );

    //------------------------------------------------------------------
    // Fill cut values
    //------------------------------------------------------------------

    fillVariableWithValue ( "PassTrigger" , int ( trigger_fired  ) );
    fillVariableWithValue ( "PassLJFilter", int ( pass_lj_filter ) );

    //------------------------------------------------------------------
    // Evaluate cuts
    //------------------------------------------------------------------

    evaluateCuts();

    //------------------------------------------------------------------
    // If event passes, fill the tree
    //------------------------------------------------------------------

    if ( trigger_fired && pass_lj_filter) fillSkimTree();

   } // End loop over events

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
analysisClass::analysisClass(string * inputList, string * cutFile, string * treeName, string * outputFileName, string * cutEfficFile)
  :baseClass(inputList, cutFile, treeName, outputFileName, cutEfficFile)
{
  std::cout << "analysisClass::analysisClass(): begins " << std::endl;

  std::string jetAlgo = getPreCutString1("jetAlgo");
  double rParam = getPreCutValue1("DeltaR");

  if( jetAlgo == "AntiKt" )
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm, rParam) );
  else if( jetAlgo == "Kt" )
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::kt_algorithm, rParam) );
  else 
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::cambridge_algorithm, rParam) );

  // For JECs
  if( int(getPreCutValue1("useJECs"))==1 )
  {
    std::cout << "Reapplying JECs on the fly" << std::endl;
    //std::string L1Path = "/cmshome/gdimperi/Dijet/CMSDIJETrepo/CMSSW_7_4_6_patch6/src/CMSDIJET/DijetRootTreeMaker/data/Summer15_V5/Summer15_V5_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2Path = "/cmshome/gdimperi/Dijet/CMSDIJETrepo/CMSSW_7_4_6_patch6/src/CMSDIJET/DijetRootTreeMaker/data/Summer15_V5/Summer15_V5_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3Path = "/cmshome/gdimperi/Dijet/CMSDIJETrepo/CMSSW_7_4_6_patch6/src/CMSDIJET/DijetRootTreeMaker/data/Summer15_V5/Summer15_V5_MC_L3Absolute_AK4PFchs.txt";
    //std::string L1Path = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2Path = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3Path = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L3Absolute_AK4PFchs.txt";
    //std::string L1DATAPath = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2DATAPath = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3DATAPath = "data/Summer15_50nsV2/Summer15_50nsV2_MC_L3Absolute_AK4PFchs.txt";
    //
    //std::string L1Path = "data/Summer15_50nsV4/Summer15_50nsV4_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2Path = "data/Summer15_50nsV4/Summer15_50nsV4_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3Path = "data/Summer15_50nsV4/Summer15_50nsV4_MC_L3Absolute_AK4PFchs.txt";
    //std::string L1DATAPath = "data/Summer15_50nsV4/Summer15_50nsV4_DATA_L1FastJet_AK4PFchs.txt";
    //std::string L2DATAPath = "data/Summer15_50nsV4/Summer15_50nsV4_DATA_L2Relative_AK4PFchs.txt"; 
    //std::string L3DATAPath = "data/Summer15_50nsV4/Summer15_50nsV4_DATA_L3Absolute_AK4PFchs.txt";
    //std::string L2L3ResidualPath = "data/Summer15_50nsV4/Summer15_50nsV4_DATA_L2L3Residual_AK4PFchs.txt" ;
    //
    //std::string L1Path = "data/Summer15_25nsV3_MC/Summer15_25nsV3_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2Path = "data/Summer15_25nsV3_MC/Summer15_25nsV3_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3Path = "data/Summer15_25nsV3_MC/Summer15_25nsV3_MC_L3Absolute_AK4PFchs.txt";
    //std::string L1DATAPath = "data/Summer15_25nsV3_DATA/Summer15_25nsV3_DATA_L1FastJet_AK4PFchs.txt";
    //std::string L2DATAPath = "data/Summer15_25nsV3_DATA/Summer15_25nsV3_DATA_L2Relative_AK4PFchs.txt"; 
    //std::string L3DATAPath = "data/Summer15_25nsV3_DATA/Summer15_25nsV3_DATA_L3Absolute_AK4PFchs.txt";
    //std::string L2L3ResidualPath = "data/Summer15_25nsV3_DATA/Summer15_25nsV3_DATA_L2L3Residual_AK4PFchs.txt" ;
    //
    //std::string L1Path = "data/Summer15_25nsV5_MC/Summer15_25nsV5_MC_L1FastJet_AK4PFchs.txt";
    //std::string L2Path = "data/Summer15_25nsV5_MC/Summer15_25nsV5_MC_L2Relative_AK4PFchs.txt"; 
    //std::string L3Path = "data/Summer15_25nsV5_MC/Summer15_25nsV5_MC_L3Absolute_AK4PFchs.txt";
    //std::string L1DATAPath = "data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_L1FastJet_AK4PFchs.txt";
    //std::string L2DATAPath = "data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_L2Relative_AK4PFchs.txt"; 
    //std::string L3DATAPath = "data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_L3Absolute_AK4PFchs.txt";
    //std::string L2L3ResidualPath = "data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_L2L3Residual_AK4PFchs.txt" ;
    //
    std::string L1Path = "data/Summer15_25nsV6_MC/Summer15_25nsV6_MC_L1FastJet_AK4PFchs.txt";
    std::string L2Path = "data/Summer15_25nsV6_MC/Summer15_25nsV6_MC_L2Relative_AK4PFchs.txt"; 
    std::string L3Path = "data/Summer15_25nsV6_MC/Summer15_25nsV6_MC_L3Absolute_AK4PFchs.txt";
    std::string L1DATAPath = "data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_L1FastJet_AK4PFchs.txt";
    std::string L2DATAPath = "data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_L2Relative_AK4PFchs.txt"; 
    std::string L3DATAPath = "data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_L3Absolute_AK4PFchs.txt";
    std::string L2L3ResidualPath = "data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_L2L3Residual_AK4PFchs.txt" ;

    
    L1Par = new JetCorrectorParameters(L1Path);
    L2Par = new JetCorrectorParameters(L2Path);
    L3Par = new JetCorrectorParameters(L3Path);
    L1DATAPar = new JetCorrectorParameters(L1DATAPath);
    L2DATAPar = new JetCorrectorParameters(L2DATAPath);
    L3DATAPar = new JetCorrectorParameters(L3DATAPath);
    L2L3Residual = new JetCorrectorParameters(L2L3ResidualPath);

    std::vector<JetCorrectorParameters> vPar;
    std::vector<JetCorrectorParameters> vPar_data;
    vPar.push_back(*L1Par);
    vPar.push_back(*L2Par);
    vPar.push_back(*L3Par);
   
    //residuals are applied only to data
    vPar_data.push_back(*L1DATAPar);
    vPar_data.push_back(*L2DATAPar);
    vPar_data.push_back(*L3DATAPar);
    vPar_data.push_back(*L2L3Residual);

    JetCorrector = new FactorizedJetCorrector(vPar);
    JetCorrector_data = new FactorizedJetCorrector(vPar_data);

    //uncertainty
    //unc = new JetCorrectionUncertainty("data/Summer15_50nsV5_DATA/Summer15_50nsV5_DATA_Uncertainty_AK4PFchs.txt");
    //unc = new JetCorrectionUncertainty("data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_Uncertainty_AK4PFchs.txt");
    unc = new JetCorrectionUncertainty("data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_Uncertainty_AK4PFchs.txt");
  }
  
  std::cout << "analysisClass::analysisClass(): ends " << std::endl;
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;

   TH1F *h_TrigDiff = new TH1F("TrigDiff","TrigDiff",3.0,-1.5,1.5);
   TH2F *h2_DebugTrig = new TH2F("DebugTrig","DebugTrig;HLTResults;HLTBits",2,0,2,2,0,2);
   
   TH1F *h_dPhi_JetSC = new TH1F("dPhi_JetSC","dPhi_JetSC",650,0,6.5); h_dPhi_JetSC->Sumw2();
   TH1F *h_dR_JetSC = new TH1F("dR_JetSC","dR_JetSC",600,0,3.0); h_dR_JetSC->Sumw2();
   TH1F *h_NisoSC = new TH1F ("NisoSC","NisoSC",6,-0.5,5.5);  h_NisoSC->Sumw2();

   TH1F *h_goodEleSCPt = new TH1F ("goodEleSCPt","goodEleSCPt",100,0,100); h_goodEleSCPt->Sumw2();
   TH1F *h_goodEleSCEta = new TH1F ("goodEleSCEta","goodEleSCEta",100,-3.,3.); h_goodEleSCEta->Sumw2();
   TH1F *h_goodEleSCPt_Barrel = new TH1F ("goodEleSCPt_Barrel","goodEleSCPt_Barrel",100,0,100); h_goodEleSCPt_Barrel->Sumw2();
   TH1F *h_goodEleSCPt_Endcap = new TH1F ("goodEleSCPt_Endcap","goodEleSCPt_Endcap",100,0,100); h_goodEleSCPt_Endcap->Sumw2();

   TH1F *h_goodSCPt = new TH1F ("goodSCPt","goodSCPt",100,0,100); h_goodSCPt->Sumw2();
   TH1F *h_goodSCEta = new TH1F ("goodSCEta","goodSCEta",100,-3.,3.); h_goodSCEta->Sumw2();
   TH1F *h_goodSCPt_Barrel = new TH1F ("goodSCPt_Barrel","goodSCPt_Barrel",100,0,100); h_goodSCPt_Barrel->Sumw2();
   TH1F *h_goodSCPt_Endcap = new TH1F ("goodSCPt_Endcap","goodSCPt_Endcap",100,0,100); h_goodSCPt_Endcap->Sumw2();

   TH1F *h_eta_failHLT = new TH1F("eta_failHLT","eta_failHLT",500,-3.0,3.0);
   TH1F *h_phi_failHLT = new TH1F("phi_failHLT","phi_failHLT",100,-3.5,3.5);

   /////////initialize variables
   double FailRate = 0;
   double NFailHLT = 0;
   double HasSC = 0;

  
  ////////////////////// User's code to book histos - END ///////////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
  //for (Long64_t jentry=0; jentry<10000;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%10000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //## HLT

    bool PassTrig=HLTResults->at(1); // results of HLTPhoton15 
    //bool PassTrig=HLTBits->at(71); // results of HLTPhoton15 
    int TrigDiff = HLTBits->at(71) - HLTResults->at(1);
    h_TrigDiff->Fill(TrigDiff);
    h2_DebugTrig->Fill(HLTResults->at(1),HLTBits->at(71));

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_HEEP;
    int eleIDType = (int) getPreCutValue1("eleIDType");
     
    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {
	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	//ID + ISO + NO overlap with good muons 
	int eleID = ElectronPassID->at(iele);
	if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	  {
	    v_idx_ele_HEEP.push_back(iele);
	  }

// 	bool HEEP = false;
// 	if (fabs(ElectronEta->at(iele))<1.442){
// 	if (fabs(ElectronDeltaEtaTrkSC->at(iele))<0.005){
// 	  if (fabs(ElectronDeltaPhiTrkSC->at(iele))<0.09){
// 	    if (ElectronHoE->at(iele)<0.05){
// 		if ((ElectronE2x5OverE5x5->at(iele)>0.94)||(ElectronE1x5OverE5x5->at(iele)>0.83)){
// 		  if ((ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))<(2+0.03*ElectronPt->at(iele))){
// 		    if (ElectronTrkIsoHeep->at(iele)<7.5){
// 		      HEEP = true;
// 		    }
// 		  }
// 		}
// 	      }
// 	    }
// 	  }
// 	}

// 	double eleEt = ElectronPt->at(iele);
// 	if ((fabs(ElectronEta->at(iele))>1.56) && (fabs(ElectronEta->at(iele))<2.5)){
// 	if (fabs(ElectronDeltaEtaTrkSC->at(iele))<0.007){
// 	  if (fabs(ElectronDeltaPhiTrkSC->at(iele))<0.09){
// 	    if (ElectronHoE->at(iele)<0.05){
// 	      if (ElectronSigmaIEtaIEta->at(iele)<0.03){
// 		if (((ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))<2.5) || 
// 		    ((eleEt>50)&&(ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))< ((0.03*(eleEt-50))+2.5))){
// 		    if (ElectronTrkIsoHeep->at(iele)<15){
// 		      if (ElectronHcalIsoD2Heep->at(iele)<0.5){
// 		      HEEP = true;
// 		      }
// 		    }
// 		}
// 	      }
// 	    }
// 	  }
// 	}
// 	}

// 	if ( HEEP  && ElectronOverlaps->at(iele)==0 )
// 	  {
// 	    v_idx_ele_HEEP.push_back(iele);
// 	  }

      } // End loop over electrons

    
    //////// Fill SC histos

     vector<int> v_idx_sc_iso;

    for(int isc=0;isc<SuperClusterPt->size();isc++){
      if ( SuperClusterPt->at(isc) < getPreCutValue1("ele_PtCut") ) continue;
      if (SuperClusterHoE->at(isc)<0.05) {
	v_idx_sc_iso.push_back(isc);
      }
    }

    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
 
    // Loop over jets
    for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
      {

	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( CaloJetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;

	if( ( CaloJetOverlaps->at(ijet) & 1 << eleIDType) == 0 )/* NO overlap with electrons */  
	  v_idx_jet_PtCut.push_back(ijet);

      } // End loop over jets


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

    // Set the value of the variableNames listed in the cutFile to their current value
    
    // HLT
    fillVariableWithValue( "HLT", PassTrig ) ;

    //## SC
    fillVariableWithValue( "nIsoSC", v_idx_sc_iso.size() );
    //fillVariableWithValue( "nIsoSC",v_idx_sc_iso_barrel.size() );

    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size() ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlpSC", v_idx_jet_PtCut.size() ) ;

    // 1st SC
    if( v_idx_sc_iso.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stSC_ISO", SuperClusterPt->at(v_idx_sc_iso[0]) );
	fillVariableWithValue( "Eta1stSC_ISO", SuperClusterEta->at(v_idx_sc_iso[0]) );
	fillVariableWithValue( "mEta1stSC_ISO", fabs(SuperClusterEta->at(v_idx_sc_iso[0])) );
      }

    // 2nd SC
    if( v_idx_sc_iso.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndSC_ISO", SuperClusterPt->at(v_idx_sc_iso[1]) );
	fillVariableWithValue( "Eta2ndSC_ISO", SuperClusterEta->at(v_idx_sc_iso[1]) );
	fillVariableWithValue( "mEta2ndSC_ISO", fabs(SuperClusterEta->at(v_idx_sc_iso[1])) );
	fillVariableWithValue( "maxMEtaSC_ISO", max( getVariableValue("mEta1stSC_ISO"), getVariableValue("mEta2ndSC_ISO") ) );
      }

    // 1st jet
    if( v_idx_jet_PtCut.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlpSC", CaloJetPt->at(v_idx_jet_PtCut[0]) );
	fillVariableWithValue( "Eta1stJet_noOvrlpSC", CaloJetEta->at(v_idx_jet_PtCut[0]) );
	fillVariableWithValue( "mEta1stJet_noOvrlpSC", fabs(CaloJetEta->at(v_idx_jet_PtCut[0])) );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlpSC", CaloJetPt->at(v_idx_jet_PtCut[1]) );
	fillVariableWithValue( "Eta2ndJet_noOvrlpSC", CaloJetEta->at(v_idx_jet_PtCut[1]) );
	fillVariableWithValue( "mEta2ndJet_noOvrlpSC", fabs(CaloJetEta->at(v_idx_jet_PtCut[1])) );
	fillVariableWithValue( "maxMEtaJets_noOvrlpSC", max( getVariableValue("mEta1stJet_noOvrlpSC"), getVariableValue("mEta2ndJet_noOvrlpSC") ) );
      }


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

     if (passedCut("nIsoSC")){
       HasSC++;
     }

     // Fill histograms and do analysis based on cut evaluation
     if (v_idx_sc_iso.size()>0 && !passedCut("HLT")){
       NFailHLT++;
       h_eta_failHLT->Fill(SuperClusterEta->at(v_idx_sc_iso[0]));
       h_phi_failHLT->Fill(SuperClusterPhi->at(v_idx_sc_iso[0]));
     }


     if ( v_idx_ele_PtCut.size()>1) continue; // require at most one loose ele to reject Zs
     if (PFMET->at(0) > 10) continue; // get rid of Ws
	 for(int isc=0;isc<v_idx_sc_iso.size();isc++)
	   {
	     //Require dR>2.6 between SC and JET
	     TVector3 sc_vec;
	     sc_vec.SetPtEtaPhi(SuperClusterPt->at(v_idx_sc_iso[isc]),
			   SuperClusterEta->at(v_idx_sc_iso[isc]),
			   SuperClusterPhi->at(v_idx_sc_iso[isc]));
	     double dPhi_SC_Jet=0;
	     for (int ijet=0;ijet<v_idx_jet_PtCut.size();ijet++){
	       TVector3 jet_vec;
	       jet_vec.SetPtEtaPhi(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
			    CaloJetEta->at(v_idx_jet_PtCut[ijet]),
			    CaloJetPhi->at(v_idx_jet_PtCut[ijet]));
	       double deltaPhi=fabs(jet_vec.DeltaPhi(sc_vec));
	       if (deltaPhi>dPhi_SC_Jet)dPhi_SC_Jet=deltaPhi;
	     }
	     if (dPhi_SC_Jet<2.6) continue;
	     h_dPhi_JetSC->Fill(dPhi_SC_Jet);	

	     h_goodSCPt->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));
	     h_goodSCEta->Fill(SuperClusterEta->at(v_idx_sc_iso[isc]));

	     bool Barrel = false;
	     bool Endcap = false;
	     if (fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))<1.45) Barrel = true;
	     if (fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))>1.56 && fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))<2.5) Endcap = true;

	     if (Barrel) h_goodSCPt_Barrel->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));
	     if (Endcap) h_goodSCPt_Endcap->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));

	     ///  see if there is a HEEP ele to match this
	     double deltaR_ele_sc = 99;
	     int idx_HEEP = -1;
	     for(int iele=0;iele<v_idx_ele_HEEP.size();iele++){
	       TVector3 ele_vec;
	       ele_vec.SetPtEtaPhi(ElectronPt->at(v_idx_ele_HEEP[iele]),
			   ElectronEta->at(v_idx_ele_HEEP[iele]),
			   ElectronPhi->at(v_idx_ele_HEEP[iele]));
	       double tmp_deltaR = ele_vec.DeltaR(sc_vec);
	       if (tmp_deltaR<deltaR_ele_sc){
		 deltaR_ele_sc = tmp_deltaR;
		 idx_HEEP = iele;
	       }
	     }
	     if (deltaR_ele_sc<0.3){
		h_goodEleSCPt->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		h_goodEleSCEta->Fill(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]));
		
		bool Barrel = false;
		bool Endcap = false;
		if (fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))<1.45) Barrel = true;
		if (fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))>1.56 && fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))<2.5) Endcap = true;
		
		if (Barrel) h_goodEleSCPt_Barrel->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		if (Endcap) h_goodEleSCPt_Endcap->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		}
	   } // for sc


    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

   h_TrigDiff->Write();
   h2_DebugTrig->Write();

   h_dPhi_JetSC->Write();
   h_dR_JetSC->Write();
   h_NisoSC->Write();
   h_goodEleSCPt->Write();
   h_goodEleSCEta->Write();
   h_goodEleSCPt_Barrel->Write();
   h_goodEleSCPt_Endcap->Write();
   h_goodSCPt->Write();
   h_goodSCEta->Write();
   h_goodSCPt_Barrel->Write();
   h_goodSCPt_Endcap->Write();

   h_eta_failHLT->Write();
   h_phi_failHLT->Write();

   FailRate = 100 * NFailHLT/HasSC;
   //cout << "NFail: " << NFailHLT << "\t" << "FailRate: " << FailRate << " %" << endl;
  
  //STDOUT("analysisClass::Loop() ends");   
}
void analysisClass::Loop()
{
    std::cout << "analysisClass::Loop() begins" <<std::endl;

    if (fChain == 0) return;

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

    TH1F *h_ele_E_bit1 = new TH1F ("ele_E_bit1","ele_E_bit1",100,0,1000);
    TH1F *h_ele_Pt_bit1  = new TH1F ("ele_Pt_bit1","ele_Pt_bit1",100,0,1000);
    TH1F *h_ele_Phi_bit1  = new TH1F ("ele_Phi_bit1","ele_Phi_bit1",71,-3.55,3.55);
    TH1F *h_ele_Eta_bit1  = new TH1F ("ele_Eta_bit1","ele_Eta_bit1",121,-6.05,6.05);
    TH1F *h_ele_CaloEnergy_bit1  = new TH1F ("ele_CaloEnergy_bit1","ele_CaloEnergy_bit1",100,0,1000);

    TH1F *h_ele_E_bit2 = new TH1F ("ele_E_bit2","ele_E_bit2",100,0,1000);
    TH1F *h_ele_Pt_bit2  = new TH1F ("ele_Pt_bit2","ele_Pt_bit2",100,0,1000);
    TH1F *h_ele_Phi_bit2  = new TH1F ("ele_Phi_bit2","ele_Phi_bit2",71,-3.55,3.55);
    TH1F *h_ele_Eta_bit2  = new TH1F ("ele_Eta_bit2","ele_Eta_bit2",121,-6.05,6.05);
    TH1F *h_ele_CaloEnergy_bit2  = new TH1F ("ele_CaloEnergy_bit2","ele_CaloEnergy_bit2",100,0,1000);

    TH1F *h_ele_E_bit3 = new TH1F ("ele_E_bit3","ele_E_bit3",100,0,1000);
    TH1F *h_ele_Pt_bit3  = new TH1F ("ele_Pt_bit3","ele_Pt_bit3",100,0,1000);
    TH1F *h_ele_Phi_bit3  = new TH1F ("ele_Phi_bit3","ele_Phi_bit3",71,-3.55,3.55);
    TH1F *h_ele_Eta_bit3  = new TH1F ("ele_Eta_bit3","ele_Eta_bit3",121,-6.05,6.05);
    TH1F *h_ele_CaloEnergy_bit3  = new TH1F ("ele_CaloEnergy_bit3","ele_CaloEnergy_bit3",100,0,1000);

    TH1F *h_ele_E_bit4 = new TH1F ("ele_E_bit4","ele_E_bit4",100,0,1000);
    TH1F *h_ele_Pt_bit4  = new TH1F ("ele_Pt_bit4","ele_Pt_bit4",100,0,1000);
    TH1F *h_ele_Phi_bit4  = new TH1F ("ele_Phi_bit4","ele_Phi_bit4",71,-3.55,3.55);
    TH1F *h_ele_Eta_bit4  = new TH1F ("ele_Eta_bit4","ele_Eta_bit4",121,-6.05,6.05);
    TH1F *h_ele_CaloEnergy_bit4  = new TH1F ("ele_CaloEnergy_bit4","ele_CaloEnergy_bit4",100,0,1000);

    /////////initialize variables
    double EventsPassed_bit1=0;
    double EventsPassed_bit2=0;
    double EventsPassed_bit3=0;
    double EventsPassed_bit4=0;
    double n_Events=0;

    int electron_PID=11;
    int LQ_PID=42;
    //int LQ_PID=23; //PdgID for Z
    float elePt_cut=10.;
    float eleEta_cut=2.6;

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

    ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
    ////// If the root version is updated and rootNtupleClass regenerated,     /////
    ////// these lines may need to be updated.                                 /////
    Long64_t nbytes = 0, nb = 0;
    for (Long64_t jentry=0; jentry<nentries; jentry++) {
        Long64_t ientry = LoadTree(jentry);
        if (ientry < 0) break;
        nb = fChain->GetEntry(jentry);
        nbytes += nb;
        if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;
        // if (Cut(ientry) < 0) continue;

        ////////////////////// User's code starts here ///////////////////////

        //HLT
        int TrigBit1=getPreCutValue1("TriggerBits1");
        int TrigBit2=getPreCutValue1("TriggerBits2");
        int TrigBit3=getPreCutValue1("TriggerBits3");
        int TrigBit4=getPreCutValue1("TriggerBits4");

        /////To print out list of trigger names:
//      int results_index=0;
//      string tmp="";
//      for (int itrig=0;itrig<hltNamesLen;itrig++){
//        if (HLTNames[itrig]==':') {
// 	 cout << tmp << "   " << HLTResults[results_index] << endl;
// 	 tmp.clear(); //reset temporary string of HLT name
// 	 results_index++; //move to next HLT result
//        }
//        else tmp.push_back(HLTNames[itrig]) ;  //build up HLT name until ":" is reached, indicating end of name
//      }

        if (HLTResults[TrigBit1]) {
            EventsPassed_bit1++;
            for (int iele=0; iele<eleCount; iele++) {
                if (elePt[iele]<elePt_cut) continue;
                h_ele_E_bit1->Fill(eleEnergy[iele]);
                h_ele_Pt_bit1->Fill(elePt[iele]);
                h_ele_Phi_bit1->Fill(elePhi[iele]);
                h_ele_Eta_bit1->Fill(eleEta[iele]);
                h_ele_CaloEnergy_bit1->Fill(eleCaloEnergy[iele]);
            } //for iele
        }


        if (HLTResults[TrigBit2]) {
            EventsPassed_bit2++;
            for (int iele=0; iele<eleCount; iele++) {
                if (elePt[iele]<elePt_cut) continue;
                h_ele_E_bit2->Fill(eleEnergy[iele]);
                h_ele_Pt_bit2->Fill(elePt[iele]);
                h_ele_Phi_bit2->Fill(elePhi[iele]);
                h_ele_Eta_bit2->Fill(eleEta[iele]);
                h_ele_CaloEnergy_bit2->Fill(eleCaloEnergy[iele]);
            } //for iele
        }

        if (HLTResults[TrigBit3]) {
            EventsPassed_bit3++;
            for (int iele=0; iele<eleCount; iele++) {
                if (elePt[iele]<elePt_cut) continue;
                h_ele_E_bit3->Fill(eleEnergy[iele]);
                h_ele_Pt_bit3->Fill(elePt[iele]);
                h_ele_Phi_bit3->Fill(elePhi[iele]);
                h_ele_Eta_bit3->Fill(eleEta[iele]);
                h_ele_CaloEnergy_bit3->Fill(eleCaloEnergy[iele]);
            } //for iele
        }

        if (HLTResults[TrigBit4]) {
            EventsPassed_bit4++;
            for (int iele=0; iele<eleCount; iele++) {
                if (elePt[iele]<elePt_cut) continue;
                h_ele_E_bit4->Fill(eleEnergy[iele]);
                h_ele_Pt_bit4->Fill(elePt[iele]);
                h_ele_Phi_bit4->Fill(elePhi[iele]);
                h_ele_Eta_bit4->Fill(eleEta[iele]);
                h_ele_CaloEnergy_bit4->Fill(eleCaloEnergy[iele]);
            } //for iele
        }

        resetCuts();
        if (HLTResults[TrigBit1]) fillVariableWithValue("HLT_bit1",1) ;
        if (HLTResults[TrigBit2]) fillVariableWithValue("HLT_bit2",1) ;
        if (HLTResults[TrigBit3]) fillVariableWithValue("HLT_bit3",1) ;
        if (HLTResults[TrigBit4]) fillVariableWithValue("HLT_bit4",1) ;
        evaluateCuts();

        n_Events++;

    } // End loop over events

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

    h_ele_E_bit1->Write();
    h_ele_Pt_bit1->Write();
    h_ele_Phi_bit1->Write();
    h_ele_Eta_bit1->Write();
    h_ele_CaloEnergy_bit1->Write();

    h_ele_E_bit2->Write();
    h_ele_Pt_bit2->Write();
    h_ele_Phi_bit2->Write();
    h_ele_Eta_bit2->Write();
    h_ele_CaloEnergy_bit2->Write();

    h_ele_E_bit3->Write();
    h_ele_Pt_bit3->Write();
    h_ele_Phi_bit3->Write();
    h_ele_Eta_bit3->Write();
    h_ele_CaloEnergy_bit3->Write();

    h_ele_E_bit4->Write();
    h_ele_Pt_bit4->Write();
    h_ele_Phi_bit4->Write();
    h_ele_Eta_bit4->Write();
    h_ele_CaloEnergy_bit4->Write();

    cout << "Events Passed Trigger EM_bit1: " << EventsPassed_bit1 << "  Fraction: " << EventsPassed_bit1/n_Events << endl;
    cout << "Events Passed Trigger EM_bit2: " << EventsPassed_bit2 << "  Fraction: " << EventsPassed_bit2/n_Events <<endl;
    cout << "Events Passed Trigger EM_bit3: " << EventsPassed_bit3 << "  Fraction: " << EventsPassed_bit3/n_Events << endl;
    cout << "Events Passed Trigger EM_bit4: " << EventsPassed_bit4 << "  Fraction: " << EventsPassed_bit4/n_Events <<endl;

    std::cout << "analysisClass::Loop() ends" <<std::endl;
}
void analysisClass::Loop()
{
    std::cout << "analysisClass::Loop() begins" <<std::endl;

    //--------------------------------------------------------------------------
    // Decide which plots to save (default is to save everything)
    //--------------------------------------------------------------------------

    fillSkim                         (  true  ) ;
    fillAllPreviousCuts              (  true  ) ;
    fillAllOtherCuts                 ( !true  ) ;
    fillAllSameLevelAndLowerLevelCuts( !true  ) ;
    fillAllCuts                      ( !true  ) ;

    //--------------------------------------------------------------------------
    // Get pre-cut values
    //--------------------------------------------------------------------------

    // fake rates

    int qcd_fit_function_version      = getPreCutValue1 ("QCD_fit_func_version" );
    std::string qcd_file_name         = getPreCutString1("QCD_file");
    std::string qcd_barrel_plot_name  = getPreCutString1("QCD_barrel_plot" );
    std::string qcd_endcap1_plot_name = getPreCutString1("QCD_endcap1_plot");
    std::string qcd_endcap2_plot_name = getPreCutString1("QCD_endcap2_plot");

    qcdFitter * fitter = new qcdFitter(qcd_fit_function_version,
                                       qcd_file_name           ,
                                       qcd_barrel_plot_name    ,
                                       qcd_endcap1_plot_name   ,
                                       qcd_endcap2_plot_name    );
    fitter -> print();

    // override the fake rate?
    double fakeRate_override = getPreCutValue1("fakeRate_override");
    bool override_fakeRate = ( fakeRate_override > 0.0 );

    //--------------------------------------------------------------------------
    // Create TH1D's
    //--------------------------------------------------------------------------

    CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
    CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
    CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
    CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     );
    CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 );
    CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     );
    CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 );
    CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 );
    CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 );
    CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 );
    CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 );
    CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 );
    CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me1j1_PAS"		   ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me2j1_PAS"		   ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
    CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );


    CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ;

    CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ;
    CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ;

    //--------------------------------------------------------------------------
    // Loop over the chain
    //--------------------------------------------------------------------------

    if (fChain == 0) return;

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

    Long64_t nbytes = 0, nb = 0;
    for (Long64_t jentry=0; jentry<nentries; jentry++) {

        Long64_t ientry = LoadTree(jentry);
        if (ientry < 0) break;
        nb = fChain->GetEntry(jentry);
        nbytes += nb;
        if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;

        //--------------------------------------------------------------------------
        // Reset the cuts
        //--------------------------------------------------------------------------

        resetCuts();

        //--------------------------------------------------------------------------
        // Check good run list
        //--------------------------------------------------------------------------

        int    passedJSON = passJSON ( run, ls , isData ) ;

        //--------------------------------------------------------------------------
        // Do pileup re-weighting
        //--------------------------------------------------------------------------

        double pileup_weight = getPileupWeight ( nPileUpInt_True, isData ) ;

        //--------------------------------------------------------------------------
        // Trigger
        //--------------------------------------------------------------------------

        short min_prescale = 0;
        int passTrigger = 0;

        if ( isData ) {

            if ( LooseEle1_hltPhotonPt > 0.0 ) {
                if ( H_Photon30_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 30.  && LooseEle1_hltPhotonPt < 50. ) {
                    passTrigger = 1;
                    min_prescale = H_Photon30_CIdVL;
                }
                if ( H_Photon50_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 50.  && LooseEle1_hltPhotonPt < 75. ) {
                    passTrigger = 1;
                    min_prescale = H_Photon50_CIdVL;
                }
                if ( H_Photon75_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 75.  && LooseEle1_hltPhotonPt < 90. ) {
                    passTrigger = 1;
                    min_prescale = H_Photon75_CIdVL;
                }
                if ( H_Photon90_CIdVL > 0.1 && LooseEle1_hltPhotonPt >= 90.  && LooseEle1_hltPhotonPt < 135.) {
                    passTrigger = 1;
                    min_prescale = H_Photon90_CIdVL;
                }
                if ( H_Photon135      > 0.1 && LooseEle1_hltPhotonPt >= 135. && LooseEle1_hltPhotonPt < 150.) {
                    passTrigger = 1;
                    min_prescale = H_Photon135     ;
                }
                if ( H_Photon150      > 0.1 && LooseEle1_hltPhotonPt >= 150.                                ) {
                    passTrigger = 1;
                    min_prescale = H_Photon150     ;
                }
            }

        }  // end if (isData)

        else {
            min_prescale = 1;
            passTrigger = 1 ;
        }

        //--------------------------------------------------------------------------
        // Calculate the fake rate
        //--------------------------------------------------------------------------

        double fakeRate1  = fitter -> getFakeRate    ( LooseEle1_Pt, LooseEle1_Eta );
        double fakeRate2  = fitter -> getFakeRate    ( LooseEle2_Pt, LooseEle2_Eta );
        double eFakeRate1 = fitter -> getFakeRateErr ( LooseEle1_Pt, LooseEle1_Eta );
        double eFakeRate2 = fitter -> getFakeRateErr ( LooseEle2_Pt, LooseEle2_Eta );

        double fakeRateEffective  = fakeRate1 + fakeRate2;
        double eFakeRateEffective = sqrt ( ( eFakeRate1 * eFakeRate1 ) +
                                           ( eFakeRate2 * eFakeRate2 ) );

        // fakeRateEffective += eFakeRateEffective;

        //--------------------------------------------------------------------------
        // User has the option to use a flat fake rate (e.g. 1.0 = no fake rate)
        //--------------------------------------------------------------------------

        if ( override_fakeRate ) fakeRateEffective = fakeRate_override;

        //--------------------------------------------------------------------------
        // How many loose electrons have HEEP ID?
        //--------------------------------------------------------------------------

        int nPass = 0;
        if ( LooseEle1_PassID == 1 ) nPass ++;
        if ( LooseEle2_PassID == 1 ) nPass ++;

        //--------------------------------------------------------------------------
        // Calculate a few missing variables
        //--------------------------------------------------------------------------

        TLorentzVector loose_ele1, loose_ele2 , jet1, jet2;
        loose_ele1.SetPtEtaPhiM ( LooseEle1_Pt , LooseEle1_Eta , LooseEle1_Phi , 0.0 );
        loose_ele2.SetPtEtaPhiM ( LooseEle2_Pt , LooseEle2_Eta , LooseEle2_Phi , 0.0 );
        jet1.SetPtEtaPhiM       ( JetLooseEle1_Pt, JetLooseEle1_Eta, JetLooseEle1_Phi, 0.0 );
        jet2.SetPtEtaPhiM       ( JetLooseEle2_Pt, JetLooseEle2_Eta, JetLooseEle2_Phi, 0.0 );

        TLorentzVector loose_e1e2 = loose_ele1 + loose_ele2;
        TLorentzVector j1j2 = jet1 + jet2;

        TLorentzVector e1j1 = loose_ele1 + jet1;
        TLorentzVector e2j1 = loose_ele2 + jet1;

        //--------------------------------------------------------------------------
        // Now fill cut values
        // DON'T use the pileup weight ... it's included by default
        // DO    use the prescale.  It's already 1.0 for MC.
        // DO    use the effective fake rate.  It will only mean anything when you run
        //       over data, though, so be sure to override it to 1.0
        //       if you run over Monte Carlo
        //--------------------------------------------------------------------------


        //--------------------------------------------------------------------------
        // Fill variables
        //--------------------------------------------------------------------------

        // JSON variable
        fillVariableWithValue(   "PassJSON"                      , passedJSON ) ;

        // Noise filters
        fillVariableWithValue(   "PassHBHENoiseFilter"           , PassHBHENoiseFilter ) ;
        fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight ) ;

        //--------------------------------------------------------------------------
        // MET filters
        //--------------------------------------------------------------------------

        fillVariableWithValue(   "PassHBHENoiseFilter"	      , PassHBHENoiseFilter                              , pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight                          , pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassBadEESupercrystalFilter"   , ( isData == 1 ) ? PassBadEESupercrystalFilter : 1, pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassBeamScraping"	      , ( isData == 1 ) ? PassBeamScraping	      : 1, pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassEcalDeadCellBoundEnergy"   , PassEcalDeadCellBoundEnergy                      , pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassEcalDeadCellTrigPrim"      , PassEcalDeadCellTrigPrim                         , pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassEcalLaserCorrFilter"       , ( isData == 1 ) ? PassEcalLaserCorrFilter     : 1, pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassPhysDecl"		      , ( isData == 1 ) ? PassPhysDecl		      : 1, pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassPrimaryVertex"	      , PassPrimaryVertex                                , pileup_weight * min_prescale  * fakeRateEffective);
        fillVariableWithValue(   "PassTrackingFailure"	      , ( isData == 1 ) ? PassTrackingFailure	      : 1, pileup_weight * min_prescale  * fakeRateEffective);


        fillVariableWithValue ( "PassHLT", passTrigger, pileup_weight * min_prescale * fakeRateEffective ) ;
        fillVariableWithValue ( "PFMET"  , PFMET_Type01XY_Pt, pileup_weight * min_prescale * fakeRateEffective ) ;

        // Electrons
        fillVariableWithValue(   "nEleLoose"                     , nLooseEle_ptCut     , pileup_weight * min_prescale  * fakeRateEffective );
        fillVariableWithValue(   "nEleTight"                     , nPass            , pileup_weight * min_prescale  * fakeRateEffective );
        if ( nLooseEle_ptCut >= 1 ) {
            fillVariableWithValue( "Ele1_Pt"                       , LooseEle1_Pt   , pileup_weight * min_prescale  * fakeRateEffective ) ;
            fillVariableWithValue( "Ele1_Eta"                      , LooseEle1_Eta  , pileup_weight * min_prescale  * fakeRateEffective ) ;
        }
        if ( nLooseEle_ptCut >= 2 ) {
            fillVariableWithValue( "Ele2_Pt"                       , LooseEle2_Pt   , pileup_weight * min_prescale  * fakeRateEffective ) ;
            fillVariableWithValue( "Ele2_Eta"                      , LooseEle2_Eta  , pileup_weight * min_prescale  * fakeRateEffective ) ;
            fillVariableWithValue( "M_e1e2"                        , loose_e1e2.M()   , pileup_weight * min_prescale  * fakeRateEffective );
            fillVariableWithValue( "Pt_e1e2"                       , loose_e1e2.Pt()  , pileup_weight * min_prescale  * fakeRateEffective );
        }

        // Jets
        fillVariableWithValue(   "nJet"                          , nJetLooseEle_ptCut , pileup_weight * min_prescale  * fakeRateEffective );
        if ( nJetLooseEle_store >= 1 ) {
            fillVariableWithValue( "Jet1_Pt"                       , JetLooseEle1_Pt   , pileup_weight * min_prescale  * fakeRateEffective ) ;
            fillVariableWithValue( "Jet1_Eta"                      , JetLooseEle1_Eta , pileup_weight * min_prescale  * fakeRateEffective ) ;
        }

        // Muons
        fillVariableWithValue(   "nMuon"                         , nMuon_ptCut           , pileup_weight * min_prescale  * fakeRateEffective );

        // DeltaR
        if ( nLooseEle_ptCut >= 2 && nJetLooseEle_store >= 1) {
            double st = LooseEle1_Pt + LooseEle2_Pt + JetLooseEle1_Pt ;
            fillVariableWithValue( "DR_Ele1Jet1"                   , loose_ele1.DeltaR ( jet1 ), pileup_weight * min_prescale  * fakeRateEffective );
            fillVariableWithValue( "DR_Ele2Jet1"                   , loose_ele2.DeltaR ( jet1 ), pileup_weight * min_prescale  * fakeRateEffective );
            fillVariableWithValue( "sT_eej_200"                    , st                        , pileup_weight * min_prescale  * fakeRateEffective );
            fillVariableWithValue( "sT_eej_450"                    , st                        , pileup_weight * min_prescale  * fakeRateEffective );
            fillVariableWithValue( "sT_eej_850"                    , st                        , pileup_weight * min_prescale  * fakeRateEffective );
        }

        //--------------------------------------------------------------------------
        // Evaluate the cuts
        //--------------------------------------------------------------------------

        evaluateCuts();

        //--------------------------------------------------------------------------
        // Fill preselection plots
        // DO    use the pileup weight.  It's equal to 1.0 for data.
        // DO    use the min_prescale.  It's equal to 1.0 for Monte Carlo
        // DO    use the effective fake rate.  It will only mean anything when you run
        //       over data, though, so be sure to override it to 1.0
        //       if you run over Monte Carlo
        //--------------------------------------------------------------------------

        bool passed_preselection = ( passedAllPreviousCuts("sT_eej_200") && passedCut ("sT_eej_200") );

        if ( passed_preselection ) {

            double sT_eej = LooseEle1_Pt + LooseEle2_Pt + JetLooseEle1_Pt ;

            FillUserTH1D("nElectron_PAS"        , nLooseEle_ptCut           , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("nMuon_PAS"            , nMuon_ptCut               , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("nJet_PAS"             , nJetLooseEle_ptCut        , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Pt1stEle_PAS"	   , LooseEle1_Pt              , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Eta1stEle_PAS"	   , LooseEle1_Eta             , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Phi1stEle_PAS"	   , LooseEle1_Phi             , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Pt2ndEle_PAS"	   , LooseEle2_Pt              , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Eta2ndEle_PAS"	   , LooseEle2_Eta             , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Phi2ndEle_PAS"	   , LooseEle2_Phi             , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Charge1stEle_PAS"	   , LooseEle1_Charge          , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Charge2ndEle_PAS"	   , LooseEle2_Charge          , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("MET_PAS"              , PFMET_Type01XY_Pt         , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("METPhi_PAS"	   , PFMET_Type01XY_Phi        , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Pt1stJet_PAS"         , JetLooseEle1_Pt           , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Eta1stJet_PAS"        , JetLooseEle1_Eta          , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Phi1stJet_PAS"	   , JetLooseEle1_Phi          , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("sT_PAS"               , sT_eej                    , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Mee_PAS"		   , loose_e1e2.M()            , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Ptee_PAS"             , loose_e1e2.Pt()           , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("nVertex_PAS"          , nVertex                   , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("DR_Ele1Jet1_PAS"	   , loose_ele1.DeltaR ( jet1 ), pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("DR_Ele2Jet1_PAS"	   , loose_ele2.DeltaR ( jet1 ), pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Me1j1_PAS"            , e1j1.M()                  , pileup_weight * min_prescale * fakeRateEffective );
            FillUserTH1D("Me2j1_PAS"            , e2j1.M()                  , pileup_weight * min_prescale * fakeRateEffective );
        }
    } // End loop over events

    std::cout << "analysisClass::Loop() ends" <<std::endl;
}
Пример #18
0
void analysisClass::Loop()
{
  std::cout << "analysisClass::Loop() begins" <<std::endl; 

  if (fChain == 0) return;

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


  int   Nbins_METSumET = 500;
  float Max_METSumET = 500;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

  Long64_t nb = 0;

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

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

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

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

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

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

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

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

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

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

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

	}//end loop over calotowers
      

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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




      //ECAL spikes EB
      int pass_ECALSpikesVeto_tcMET = 1;

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

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

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

	  float S4_tcMEToverS1 = S4_tcMET / seedEnergy;

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  //## 1D histograms

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

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

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

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

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

  //## 2D histograms

  std::cout << "analysisClass::Loop() ends" <<std::endl; 
}
analysisClass::analysisClass(string * inputList, string * cutFile, string * treeName, string * outputFileName, string * cutEfficFile)
  :baseClass(inputList, cutFile, treeName, outputFileName, cutEfficFile)
{
  std::cout << "analysisClass::analysisClass(): begins " << std::endl;

  std::string jetAlgo = getPreCutString1("jetAlgo");
  double rParam = getPreCutValue1("DeltaR");

  if( jetAlgo == "AntiKt" )
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::antikt_algorithm, rParam) );
  else if( jetAlgo == "Kt" )
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::kt_algorithm, rParam) );
  else 
    fjJetDefinition = JetDefPtr( new fastjet::JetDefinition(fastjet::cambridge_algorithm, rParam) );

  // For JECs
  if( int(getPreCutValue1("useJECs"))==1 )
  {
    std::cout << "Reapplying JECs on the fly" << std::endl;
    std::string L1Path = "data/Summer15_25nsV7_MC/Summer15_25nsV7_MC_L1FastJet_AK4PFchs.txt";
    std::string L2Path = "data/Summer15_25nsV7_MC/Summer15_25nsV7_MC_L2Relative_AK4PFchs.txt";
    std::string L3Path = "data/Summer15_25nsV7_MC/Summer15_25nsV7_MC_L3Absolute_AK4PFchs.txt";
    std::string L1DATAPath = "data/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_MC/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_L1FastJet_AK4PFchs.txt";
    std::string L2DATAPath = "data/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_MC/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_L2Relative_AK4PFchs.txt"; 
    std::string L3DATAPath = "data/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_MC/74X_HLT_mcRun2_asymptotic_fromSpring15DR_v0_L3Absolute_AK4PFchs.txt";
    std::string L2L3ResidualPath = "data/Summer15_25nsV7_DATA/Summer15_25nsV7_DATA_L2L3Residual_AK4PFchs.txt" ;


    
    L1Par = new JetCorrectorParameters(L1Path);
    L2Par = new JetCorrectorParameters(L2Path);
    L3Par = new JetCorrectorParameters(L3Path);
    L1DATAPar = new JetCorrectorParameters(L1DATAPath);
    L2DATAPar = new JetCorrectorParameters(L2DATAPath);
    L3DATAPar = new JetCorrectorParameters(L3DATAPath);
    L2L3Residual = new JetCorrectorParameters(L2L3ResidualPath);

    std::vector<JetCorrectorParameters> vPar;
    std::vector<JetCorrectorParameters> vPar_data;
    vPar.push_back(*L1Par);
    vPar.push_back(*L2Par);
    vPar.push_back(*L3Par);
   
    //residuals are applied only to data
    vPar_data.push_back(*L1DATAPar);
    vPar_data.push_back(*L2DATAPar);
    vPar_data.push_back(*L3DATAPar);
    vPar_data.push_back(*L2L3Residual);

    JetCorrector = new FactorizedJetCorrector(vPar);
    JetCorrector_data = new FactorizedJetCorrector(vPar_data);

    //uncertainty
    //unc = new JetCorrectionUncertainty("data/Summer15_50nsV5_DATA/Summer15_50nsV5_DATA_Uncertainty_AK4PFchs.txt");
    //unc = new JetCorrectionUncertainty("data/Summer15_25nsV5_DATA/Summer15_25nsV5_DATA_Uncertainty_AK4PFchs.txt");
    //unc = new JetCorrectionUncertainty("data/Summer15_25nsV6_DATA/Summer15_25nsV6_DATA_Uncertainty_AK4PFchs.txt");
    unc = new JetCorrectionUncertainty("data/Summer15_25nsV7_DATA/Summer15_25nsV7_DATA_Uncertainty_AK4PFchs.txt");

  }
  
  std::cout << "analysisClass::analysisClass(): ends " << std::endl;
}
Пример #20
0
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   

   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 (  true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;

   //--------------------------------------------------------------------------
   // Pileup reweighting initialization
   //--------------------------------------------------------------------------

   Lumi3DReWeighting lumiWeights = Lumi3DReWeighting("/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_MC_Summer11_PU_S4_3DReweighting.root",
						     "/afs/cern.ch/user/e/eberry/public/LQ_PILEUP/pileup_truth_finebin_2011_finebin.root",
						     "pileup", "pileup");
   lumiWeights.weight3D_init(1.0);

   //--------------------------------------------------------------------------
   // Any extra features
   //--------------------------------------------------------------------------
   
   TProfile * profile_run_vs_nvtx_HLT = new TProfile("run_vs_nvtx_HLT", "", 20000 , 160300  , 180300 );
   TProfile * profile_run_vs_nvtx_PAS = new TProfile("run_vs_nvtx_PAS", "", 20000 , 160300  , 180300 );
   
   //--------------------------------------------------------------------------
   // Get pre-cut values
   //--------------------------------------------------------------------------

   // eta boundaries

   double eleEta_bar_max = getPreCutValue1("eleEta_bar");
   double eleEta_end_min = getPreCutValue1("eleEta_end1");
   double eleEta_end_max = getPreCutValue2("eleEta_end2");

   // dataset
   
   int dataset  = getPreCutValue1("dataset") ;
   bool select2011A = ( dataset == 0 );
   bool select2011B = ( dataset == 1 );
   bool select2011  = ( dataset == 2 );

   if ( ! select2011A &&
	! select2011B &&
	! select2011 ) {
     std::cout << "Error: Must choose dataset to be 0 (2011A), 1 (2011B), or 2 (all 2011)" << std::endl;
   }

   //--------------------------------------------------------------------------
   // Create TH1D's
   //--------------------------------------------------------------------------
   
   // gap: 1.442 - 1.560

   // eleEta_bar            	1.442        -                    -               -               -1
   // eleEta_end1            	1.560        2.0                  -               -               -1
   // eleEta_end2            	2.000        2.5                  -               -               -1
   
   CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
   CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
   CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     ); 
   CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 ); 
   CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METSig_PAS"            ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METCharged_PAS"        ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METChargedPhi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "METType1_PAS"          ,    200 , 0       , 1000	 ); 
   CreateUserTH1D( "METType1Phi_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Pt2ndJet_PAS"          ,    100 , 0       , 1000	 ); 
   CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Eta2ndJet_PAS"         ,    100 , -5      , 5	 ); 
   CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "Phi2ndJet_PAS"	   , 	60  , -3.1416 , +3.1416	 ); 
   CreateUserTH1D( "sTlep_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sTjet_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mjj_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 ); 
   CreateUserTH1D( "Me1j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j1_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j2_PAS"             ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me1j_selected_PAS"     ,    200 , 0       , 2000	 ); 
   CreateUserTH1D( "Me2j_selected_PAS"     ,    200 , 0       , 2000     );
   CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
   CreateUserTH1D( "run_PAS"               ,    20000 , 160300  , 180300 );
   CreateUserTH1D( "run_HLT"               ,    20000 , 160300  , 180300 );
		                           
   CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );
   		                           
   CreateUserTH1D( "DCotTheta1stEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist1stEle_PAS"        ,    100 , 0.0, 1.0);  
   CreateUserTH1D( "DCotTheta2ndEle_PAS"   ,    100 , 0.0, 1.0);
   CreateUserTH1D( "Dist2ndEle_PAS"        ,    100 , 0.0, 1.0);  
		                           
   CreateUserTH1D( "nVertex_PAS"           ,    31   , -0.5   , 30.5	 ) ; 
   CreateUserTH1D( "nVertex_good_PAS"      ,    31   , -0.5   , 30.5	 ) ; 
		                           
   CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "DR_Ele1Jet2_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "DR_Ele2Jet2_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "DR_Jet1Jet2_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "DR_Ele1Ele2_PAS"	   , 	100 , 0.0 , 10.0  ) ; 
   CreateUserTH1D( "minDR_EleJet_PAS"	   , 	100 , 0.0 , 10.0  ) ; 

   CreateUserTH2D( "Me1jVsMe2j_selected",     200, 0, 2000, 200, 0, 2000) ;
   CreateUserTH2D( "Me1jVsMe2j_rejected",     200, 0, 2000, 200, 0, 2000) ;

   CreateUserTH1D( "MTeemunu_PAS"          ,    200 , 0       , 1000	 ); 

   CreateUserTH1D( "Mee_80_100_Preselection", 200, 60, 120 );
   CreateUserTH1D( "Mee_70_110_Preselection", 200, 60, 120 );

   CreateUserTH1D( "Mee_EBEB_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_PAS"		   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_PAS" 		   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "Mee_EBEB_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_80_100_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_80_100_PAS" 	     	   ,    60 , 60       , 120	 ); 
   
   CreateUserTH1D( "Mee_EBEB_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EBEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EEEE_70_110_PAS"	   ,    60 , 60       , 120	 ); 
   CreateUserTH1D( "Mee_EB_70_110_PAS" 	     	   ,    60 , 60       , 120	 ); 

   CreateUserTH1D( "PileupWeight"   , 100, -10, 10 );
   CreateUserTH1D( "GeneratorWeight", 100, -2.0, 2.0);

   //--------------------------------------------------------------------------
   // Loop over the chain
   //--------------------------------------------------------------------------

   if (fChain == 0) return;
   
   Long64_t nentries = fChain->GetEntries();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {

     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;   

     //--------------------------------------------------------------------------
     // Reset the cuts
     //--------------------------------------------------------------------------

     resetCuts();

     //--------------------------------------------------------------------------
     // Check good run list
     //--------------------------------------------------------------------------
     
     int    passedJSON = passJSON ( run, ls , isData ) ;

     //--------------------------------------------------------------------------
     // Do pileup re-weighting
     //--------------------------------------------------------------------------
     
     // double pileup_weight = lumiWeights.weight3D (nPileUpInt_BXminus1, nPileUpInt_BX0, nPileUpInt_BXplus1 );
     // if ( isData ) pileup_weight = 1.0;
     // setPileupWeight ( pileup_weight ) ;

     int NPILEUP_AVE = int( nPileUpInt_BX0 );
     int NPILEUP_FINAL = min( NPILEUP_AVE , 25 );
     double pileup_weight = getPileupWeight ( NPILEUP_FINAL, isData ) ;
      
     //--------------------------------------------------------------------------
     // Get information about gen-level reweighting (should be for Sherpa only)
     //--------------------------------------------------------------------------

     double gen_weight = Weight;
     if ( isData ) gen_weight = 1.0;

     // std::cout << "Gen weight = " << int ( 1.0 / gen_weight ) << std::endl;

     //--------------------------------------------------------------------------
     // Is this the dataset we want?
     //--------------------------------------------------------------------------
     
     int PassDataset = 1;
     if ( isData ) { 
       PassDataset = 0;
       if ( select2011A ){ 
	 if ( run >= 160329 && run <= 175770 ) PassDataset = 1;
       }
       if ( select2011B ){
	 if ( run >= 175832 && run <= 180296 ) PassDataset = 1;
       }
       if ( select2011 ) {
	 PassDataset = 1;
       }
     }

     //--------------------------------------------------------------------------
     // Fill variables
     //--------------------------------------------------------------------------

     // JSON variable
     fillVariableWithValue(   "PassJSON"                      , passedJSON, gen_weight   ) ; 

     // Dataset variable
     fillVariableWithValue(   "PassDataset"                      , PassDataset, gen_weight  ) ;

     // Noise filters
     fillVariableWithValue(   "PassHBHENoiseFilter"           , PassHBHENoiseFilter    , gen_weight   ) ; 
     fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight, gen_weight   ) ; 

     //fillVariableWithValue(   "PassBPTX0"                     , PassBPTX0                  , gen_weight  ) ; 
     //fillVariableWithValue(   "PassPhysDecl"                  , PassPhysDecl               , gen_weight  ) ; 
     //fillVariableWithValue(   "PassBeamScraping"              , PassBeamScraping           , gen_weight  ) ; 
     //fillVariableWithValue(   "PassPrimaryVertex"             , PassPrimaryVertex          , gen_weight  ) ; 
     //fillVariableWithValue(   "PassBeamHaloFilterLoose"	      , PassBeamHaloFilterLoose	   , gen_weight  ) ; 
     //fillVariableWithValue(   "PassTrackingFailure"           , PassTrackingFailure        , gen_weight  ) ; 
     //fillVariableWithValue(   "PassCaloBoundaryDRFilter"      , PassCaloBoundaryDRFilter   , gen_weight  ) ; 
     //fillVariableWithValue(   "PassEcalMaskedCellDRFilter"    , PassEcalMaskedCellDRFilter , gen_weight  ) ; 

     // Fill HLT 
     int passHLT = 1;
     if ( isData ) { 
       passHLT = 0;
       
       if ( H_DoubleEle33_CIdL_1  == 1 || 
       	    H_DoubleEle33_CIdL_2  == 1 || 
       	    H_DoubleEle33_CIdL_3  == 1 || 
       	    H_DoubleEle33_CIdL_4  == 1 || 
       	    H_DoubleEle33_CIdL_5  == 1 || 
	    H_DoubleEle33_CIdL_6  == 1 ||
	    H_DoubleEle33_CIdL_7  == 1 ||
	    H_DoubleEle33_CIdT_1  == 1 ||
	    H_DoubleEle33_CIdT_2  == 1 ||
	    H_DoubleEle33_CIdT_3  == 1 ||
       	    H_DoublePhoton33_1    == 1 || 
       	    H_DoublePhoton33_2    == 1 || 
       	    H_DoublePhoton33_3    == 1 || 
       	    H_DoublePhoton33_4    == 1 || 
       	    H_DoublePhoton33_5    == 1 ) {
       	 passHLT = 1;
       }
     }

     // What dataset is this?

     fillVariableWithValue ( "Reweighting", 1, gen_weight  );
     fillVariableWithValue ( "PassHLT", passHLT, gen_weight  ) ;
     
     // Electrons
     fillVariableWithValue(   "nEle"                          , nEle_Ana    , gen_weight  ) ;
     if ( nEle_Ana >= 1 ) { 
       fillVariableWithValue( "Ele1_Pt"                       , Ele1_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Ele1_Eta"                      , Ele1_Eta    , gen_weight  ) ;
       fillVariableWithValue( "abs_Ele1_Eta"                  , fabs(Ele1_Eta), gen_weight  );
     }									    
     if ( nEle_Ana >= 2 ) { 						    
       fillVariableWithValue( "Ele2_Pt"                       , Ele2_Pt     , gen_weight  ) ;
       fillVariableWithValue( "Ele2_Eta"                      , Ele2_Eta    , gen_weight  ) ;
       fillVariableWithValue( "abs_Ele2_Eta"                  , fabs(Ele2_Eta), gen_weight  );
       fillVariableWithValue( "M_e1e2"                        , M_e1e2      , gen_weight  ) ;
       fillVariableWithValue( "Pt_e1e2"                       , Pt_e1e2     , gen_weight  ) ;
     }									    
									    
     // Jets								    
     fillVariableWithValue(   "nJet"                          , nJet_Ana    , gen_weight  ) ;

     // Muons
     fillVariableWithValue(   "nMuon"                         , nMuon_Ana   , gen_weight  ) ;



     //--------------------------------------------------------------------------
     // Evaluate the cuts
     //--------------------------------------------------------------------------
     
     evaluateCuts();

     //--------------------------------------------------------------------------
     // Fill preselection plots
     //--------------------------------------------------------------------------

     FillUserTH1D( "PileupWeight"   , pileup_weight );
     FillUserTH1D( "GeneratorWeight", gen_weight ) ;
     
     bool passed_minimum      = ( passedAllPreviousCuts("PassBeamHaloFilterTight") && passedCut ("PassBeamHaloFilterTight"));

     if ( passed_minimum && isData ){ 
       FillUserTH1D ("run_HLT", run );
       profile_run_vs_nvtx_HLT -> Fill ( run, nVertex, 1 ) ;
     }

     bool passed_preselection = ( passedAllPreviousCuts("M_e1e2") && passedCut ("M_e1e2") );
     
     if ( passed_preselection ) {

       bool isEB1 = ( fabs(Ele1_Eta) < eleEta_bar_max  ) ;
       bool isEE1 = ( fabs(Ele1_Eta) > eleEta_end_min &&
		      fabs(Ele1_Eta) < eleEta_end_max ) ;

       bool isEB2 = ( fabs(Ele2_Eta) < eleEta_bar_max  ) ;
       bool isEE2 = ( fabs(Ele2_Eta) > eleEta_end_min &&
		      fabs(Ele2_Eta) < eleEta_end_max ) ;

       bool isEBEB = ( isEB1 && isEB2 ) ;
       bool isEBEE = ( ( isEB1 && isEE2 ) ||
		       ( isEE1 && isEB2 ) );
       bool isEEEE = ( isEE1  && isEE2  );
       bool isEB   = ( isEBEB || isEBEE );
       
       if ( isData )   { 
	 FillUserTH1D("run_PAS", run ) ;
	 profile_run_vs_nvtx_PAS -> Fill ( run, nVertex, 1 ) ;
       }
       FillUserTH1D("nElectron_PAS"        , nEle_Ana         , pileup_weight * gen_weight ) ;
       FillUserTH1D("nMuon_PAS"            , nMuon_Stored     , pileup_weight * gen_weight ) ;
       FillUserTH1D("nJet_PAS"             , nJet_Ana         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Pt1stEle_PAS"	   , Ele1_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta1stEle_PAS"	   , Ele1_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi1stEle_PAS"	   , Ele1_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Pt2ndEle_PAS"	   , Ele2_Pt          , pileup_weight * gen_weight ) ;
       FillUserTH1D("Eta2ndEle_PAS"	   , Ele2_Eta         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Phi2ndEle_PAS"	   , Ele2_Phi         , pileup_weight * gen_weight ) ;
       FillUserTH1D("Charge1stEle_PAS"	   , Ele1_Charge      , pileup_weight * gen_weight ) ;
       FillUserTH1D("Charge2ndEle_PAS"	   , Ele2_Charge      , pileup_weight * gen_weight ) ;
       FillUserTH1D("MET_PAS"              , MET_Pt           , pileup_weight * gen_weight ) ;
       FillUserTH1D("METSig_PAS"           , PFMETSig         , pileup_weight * gen_weight ) ;
       FillUserTH1D("METPhi_PAS"	   , MET_Phi          , pileup_weight * gen_weight ) ;
       FillUserTH1D("METCharged_PAS"       , PFMETCharged     , pileup_weight * gen_weight ) ;
       FillUserTH1D("METChargedPhi_PAS"    , PFMETChargedPhi  , pileup_weight * gen_weight ) ;   
       FillUserTH1D("METType1_PAS"         , PFMETType1Cor    , pileup_weight * gen_weight ) ;
       FillUserTH1D("METType1Phi_PAS"      , PFMETPhiType1Cor , pileup_weight * gen_weight ) ;   
       
       if ( nJet_Ana >= 1 ){
	 FillUserTH1D("Pt1stJet_PAS"       , Jet1_Pt          , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Eta1stJet_PAS"      , Jet1_Eta         , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Phi1stJet_PAS"	   , Jet1_Phi         , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Me1j1_PAS"          , M_e1j1           , pileup_weight * gen_weight ) ;
	 FillUserTH1D("Me2j1_PAS"          , M_e2j1           , pileup_weight * gen_weight ) ;
	 FillUserTH1D("DR_Ele1Jet1_PAS"	   , DR_Ele1Jet1      , pileup_weight * gen_weight ) ;
	 FillUserTH1D("DR_Ele2Jet1_PAS"	   , DR_Ele2Jet1      , pileup_weight * gen_weight ) ;
	 if ( nJet_Ana >= 2 ){
	   FillUserTH1D("Pt2ndJet_PAS"     , Jet2_Pt          , pileup_weight * gen_weight ) ;
	   FillUserTH1D("Eta2ndJet_PAS"    , Jet2_Eta         , pileup_weight * gen_weight ) ;
	   FillUserTH1D("Phi2ndJet_PAS"	   , Jet2_Phi         , pileup_weight * gen_weight ) ;
	   FillUserTH1D("Me1j2_PAS"        , M_e1j2           , pileup_weight * gen_weight ) ;
	   FillUserTH1D("Me2j2_PAS"        , M_e2j2           , pileup_weight * gen_weight ) ;
	   FillUserTH1D("DR_Ele1Jet2_PAS"  , DR_Ele1Jet2      , pileup_weight * gen_weight ) ;
	   FillUserTH1D("DR_Ele2Jet2_PAS"  , DR_Ele2Jet2      , pileup_weight * gen_weight ) ;
	   FillUserTH1D("DR_Jet1Jet2_PAS"  , DR_Jet1Jet2      , pileup_weight * gen_weight ) ;
	   FillUserTH1D("sTjet_PAS"        , Jet1_Pt + Jet2_Pt, pileup_weight * gen_weight ) ;
	   FillUserTH1D("sT_PAS"           , sT_eejj          , pileup_weight * gen_weight ) ;
	 }
       }


       FillUserTH1D("sTlep_PAS"            , Ele1_Pt + Ele2_Pt, pileup_weight * gen_weight ) ;
       FillUserTH1D("Mjj_PAS"		   , M_j1j2           , pileup_weight * gen_weight ) ;
       FillUserTH1D("Mee_PAS"		   , M_e1e2           , pileup_weight * gen_weight ) ;
       FillUserTH1D( "MTenu_PAS"           , MT_Ele1MET       , pileup_weight * gen_weight ) ;


       FillUserTH1D("Ptee_PAS"             , Pt_e1e2          , pileup_weight * gen_weight ) ;
       FillUserTH1D("DCotTheta1stEle_PAS"  , Ele1_DCotTheta   , pileup_weight * gen_weight ) ;
       FillUserTH1D("Dist1stEle_PAS"       , Ele1_Dist        , pileup_weight * gen_weight ) ;
       FillUserTH1D("DCotTheta2ndEle_PAS"  , Ele2_DCotTheta   , pileup_weight * gen_weight ) ;
       FillUserTH1D("Dist2ndEle_PAS"       , Ele2_Dist        , pileup_weight * gen_weight ) ;
       FillUserTH1D("nVertex_PAS"          , nVertex          , pileup_weight * gen_weight ) ;
       FillUserTH1D("nVertex_good_PAS"     , nVertex_good     , pileup_weight * gen_weight ) ;

       if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_PAS", M_e1e2, pileup_weight * gen_weight ); 
       else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_PAS", M_e1e2, pileup_weight * gen_weight ); 
       else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_PAS", M_e1e2, pileup_weight * gen_weight ); 
       if      ( isEB   ) FillUserTH1D( "Mee_EB_PAS"  , M_e1e2, pileup_weight * gen_weight ); 

       if ( M_e1e2 > 80.0 && M_e1e2 < 100.0 ){
	 FillUserTH1D("Mee_80_100_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_80_100_PAS"  , M_e1e2, pileup_weight * gen_weight ); 
       } 

       if ( M_e1e2 > 70.0 && M_e1e2 < 110.0 ){
	 FillUserTH1D("Mee_70_110_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
	 if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight ); 
	 if      ( isEB   ) FillUserTH1D( "Mee_EB_70_110_PAS"  , M_e1e2, pileup_weight * gen_weight ); 
       }
              
       if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
	 FillUserTH1D("Me1j_selected_PAS" , M_e1j1, pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me2j_selected_PAS" , M_e2j2, pileup_weight * gen_weight) ;	   
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j1, M_e2j2, pileup_weight * gen_weight ) ;
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j2, M_e2j1, pileup_weight * gen_weight ) ;
       }
       else {
	 FillUserTH1D("Me1j_selected_PAS" , M_e1j2, pileup_weight * gen_weight) ;	   
	 FillUserTH1D("Me2j_selected_PAS" , M_e2j1, pileup_weight * gen_weight) ;	   
	 FillUserTH2D( "Me1jVsMe2j_selected", M_e1j2, M_e2j1, pileup_weight * gen_weight ) ;
	 FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j1, M_e2j2, pileup_weight * gen_weight ) ;
       }
     }
   } // End loop over events

   // profile_file -> cd();
   output_root_ -> cd();
   profile_run_vs_nvtx_HLT -> Write();
   profile_run_vs_nvtx_PAS -> Write();

   // if ( profile_run_vs_nvtx_HLT ) delete profile_run_vs_nvtx_HLT;
   // if ( profile_run_vs_nvtx_PAS ) delete profile_run_vs_nvtx_PAS;
   // profile_file -> Close();
   // if ( profile_file ) delete profile_file;

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

   // TH1F *h_nJetFinal = new TH1F ("h_nJetFinal","",10,0,10);
   // h_nJetFinal->Sumw2();      
   // TH1F *h_nVtx = new TH1F ("h_nVtx","",30,0,30);
   // h_nVtx->Sumw2(); 
   // TH1F *h_trueVtx = new TH1F ("h_trueVtx","",40,0,40);
   // h_trueVtx->Sumw2();  
   // TH1F *h_pT1stJet = new TH1F ("h_pT1stJet","",100,0,3000);
   // h_pT1stJet->Sumw2();
   // TH1F *h_pT2ndJet = new TH1F ("h_pT2ndJet","",100,0,3000);
   // h_pT2ndJet->Sumw2();
   // TH1F *h_eta1stJet = new TH1F ("h_eta1stJet","",5,-2.5,2.5);
   // h_eta1stJet->Sumw2();
   // TH1F *h_eta2ndJet = new TH1F ("h_eta2ndJet","",5,-2.5,2.5);
   // h_eta2ndJet->Sumw2();
   // TH1F *h_DijetMass = new TH1F ("h_DijetMass","",600,0,6000);
   // h_DijetMass->Sumw2();
   // TH1F *h_DeltaETAjj = new TH1F ("h_DeltaETAjj","",120,0,3.);
   // h_DeltaETAjj->Sumw2();

   // variable binning for mjj trigger efficiency plots
   const int nMassBins = 103;

   double massBoundaries[nMassBins+1] = {1, 3, 6, 10, 16, 23, 31, 40, 50, 61, 74, 88, 103, 119, 137, 156, 176, 197, 220, 244, 270, 296, 325,
     354, 386, 419, 453, 489, 526, 565, 606, 649, 693, 740, 788, 838, 890, 944, 1000, 1058, 1118, 1181, 1246, 1313, 1383, 1455, 1530, 1607, 1687,
     1770, 1856, 1945, 2037, 2132, 2231, 2332, 2438, 2546, 2659, 2775, 2895, 3019, 3147, 3279, 3416, 3558, 3704, 3854, 4010, 4171, 4337, 4509,
     4686, 4869, 5058, 5253, 5455, 5663, 5877, 6099, 6328, 6564, 6808, 7060, 7320, 7589, 7866, 8152, 8447, 8752, 9067, 9391, 9726, 10072, 10430, 
     10798, 11179, 11571, 11977, 12395, 12827, 13272, 13732, 14000};

   // char* HLTname[50] = {"noTrig","PFHT475","PFHT800","PFHT650MJJ900","PFHT800_OR_PFHT650MJJ900","PFHT800_noPFHT475", 
   //                      "Mu45Eta2p1", "PFHT800AndMu45Eta2p1"};
   // TH1F* h_mjj_HLTpass[8];
   // char name_histoHLT[50];
   // for (int i=0; i<8; i++){  
   //   sprintf(name_histoHLT,"h_mjj_HLTpass_%s",HLTname[i]);
   //   h_mjj_HLTpass[i]= new TH1F(name_histoHLT,"",103,massBoundaries);
   // }

   //For trigger efficiency measurements
   //No trigger selection applied (full offline selection applied)
   TH1F* h_mjj_NoTrigger_1GeVbin = new TH1F("h_mjj_NoTrigger_1GeVbin","",14000,0,14000);
   TH1F* h_mjj_NoTrigger = new TH1F("h_mjj_NoTrigger","",103,massBoundaries);
   //L1
   //TH1F* h_mjj_HLTpass_ZeroBias = new TH1F("h_mjj_HLTpass_ZeroBias","",103,massBoundaries);
   //TH1F* h_mjj_HLTpass_ZeroBias_L1HTT150 = new TH1F("h_mjj_HLTpass_ZeroBias_L1HTT150","",103,massBoundaries);  
   //HLT
   //TH1F* h_mjj_HLTpass_L1HTT150 = new TH1F("h_mjj_HLTpass_L1HTT150","",103,massBoundaries);
   //TH1F* h_mjj_HLTpass_L1HTT150_HT450 = new TH1F("h_mjj_HLTpass_L1HTT150_HT450","",103,massBoundaries);


   /////////initialize variables

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
   //for (Long64_t jentry=0; jentry<2000;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done for every event

     size_t no_jets_ak4=jetPtAK4->size();

     vector<TLorentzVector> widejets;
     TLorentzVector wj1, wj2, wdijet; 
     TLorentzVector wj1_shift, wj2_shift, wdijet_shift; 

     vector<TLorentzVector> AK4jets;
     TLorentzVector ak4j1, ak4j2, ak4dijet;      

     resetCuts();

     // //find intime BX
     // int idx_InTimeBX=-1;
     // for(size_t j=0; j<PileupOriginBX->size(); ++j)
     //   {
     // 	 //cout << PileupOriginBX->at(j) << endl;	 
     // 	 if(PileupOriginBX->at(j)==0)
     // 	   {
     // 	     idx_InTimeBX = j;
     // 	     //cout << "idx_InTimeBX: " << idx_InTimeBX << endl; 
     // 	   }
     //   }

     std::vector<double> jecFactors;
     std::vector<double> jecUncertainty;
     // new JECs could change the jet pT ordering. the vector below
     // holds sorted jet indices after the new JECs had been applied
     std::vector<unsigned> sortedJetIdx;

     if( int(getPreCutValue1("useJECs"))==1 )
       {
	 // sort jets by increasing pT
	 std::multimap<double, unsigned> sortedJets;
	 for(size_t j=0; j<no_jets_ak4; ++j)
	   {
	     JetCorrector->setJetEta(jetEtaAK4->at(j));
	     JetCorrector->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)); //pTraw
	     JetCorrector->setJetA(jetAreaAK4->at(j));
	     JetCorrector->setRho(rho);

  	     JetCorrector_data->setJetEta(jetEtaAK4->at(j));
	     JetCorrector_data->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)); //pTraw
	     JetCorrector_data->setJetA(jetAreaAK4->at(j));
	     JetCorrector_data->setRho(rho);


  	     //nominal value of JECs
	     double correction;//, old_correction, nominal_correction;
	     //if( int(getPreCutValue1("shiftJECs"))==0 ){
	     if (isData == 1) correction = JetCorrector_data->getCorrection();
	     else correction = JetCorrector->getCorrection();
	     //nominal_correction=correction;
	     //old_correction = jetJecAK4->at(j);
	     //}
	     //JEC uncertainties
	     unc->setJetEta(jetEtaAK4->at(j));
	     unc->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)*correction);
	     double uncertainty = unc->getUncertainty(true);
	     jecUncertainty.push_back(uncertainty); 

	     // std::cout << "run:" << runNo << "    lumi:" << lumi << "   event:" << evtNo << "   jet pt:" << jetPtAK4->at(j)/jetJecAK4->at(j)*correction << "   correction:" << correction <<   "   uncertainty:" <<  uncertainty  << "  nominal correction:" << nominal_correction  << " old correction: " << old_correction << std::endl;
	     //use "shifted" JECs for study of systematic uncertainties 
	     if( int(getPreCutValue1("shiftJECs"))==1 ){
	       //flat shift
	       //if (isData == 1) correction = JetCorrector_data->getCorrection() * getPreCutValue2("shiftJECs");
	       //else correction = JetCorrector->getCorrection() * getPreCutValue2("shiftJECs");
	       //shift of the corresponding unc
	       correction = correction + getPreCutValue2("shiftJECs")*uncertainty*correction;
	       //  std::cout << "run:" << runNo << "    lumi:" << lumi << "   event:" << evtNo << "   jet pt:" << jetPtAK3->at(j)/jetJecAK4->at(j)*correction << "   correction:" << correction << "   uncertainty:" <<  uncertainty  << std::endl << std::endl;
	       
	   }

	 jecFactors.push_back(correction);
	 sortedJets.insert(std::make_pair((jetPtAK4->at(j)/jetJecAK4->at(j))*correction, j));

       }
     // get jet indices in decreasing pT order
     for(std::multimap<double, unsigned>::const_reverse_iterator it = sortedJets.rbegin(); it != sortedJets.rend(); ++it)
	 sortedJetIdx.push_back(it->second);
     
     }
     else if( int(getPreCutValue1("noJECs"))==1  )
       {
	 // sort jets by increasing pT
	 std::multimap<double, unsigned> sortedJets;
	 for(size_t j=0; j<no_jets_ak4; ++j) //same ordering of original root trees
	   {
	     jecUncertainty.push_back(0.); 
	     jecFactors.push_back(1.);
	     sortedJets.insert(std::make_pair((jetPtAK4->at(j)/jetJecAK4->at(j)), j)); //raw
	   }       
	 // get jet indices in decreasing pT order
	 for(std::multimap<double, unsigned>::const_reverse_iterator it = sortedJets.rbegin(); it != sortedJets.rend(); ++it)
	   sortedJetIdx.push_back(it->second);
       }
     else
       {
	 for(size_t j=0; j<no_jets_ak4; ++j) //same ordering of original root trees
	   {
	     jecFactors.push_back(jetJecAK4->at(j));
	     jecUncertainty.push_back(0.); 
	     sortedJetIdx.push_back(j);
	   }
       }


     //#############################################################
     //########## NOTE: from now on sortedJetIdx[ijet] should be used
     //#############################################################

     // if(no_jets_ak4>=2){
     //  if(!(fabs(jetEtaAK4->at(0)) < getPreCutValue1("jetFidRegion") && idTAK4->at(0) == getPreCutValue1("tightJetID"))){
     //    std::cout << " JET 0 FAIL " << jetEtaAK4->at(0) << " JET 0  ID " << idTAK4->at(0) << std::endl;
     //  }
     //  if(!(fabs(jetEtaAK4->at(1)) < getPreCutValue1("jetFidRegion") && idTAK4->at(1) == getPreCutValue1("tightJetID"))){
     //    std::cout << " JET 1 FAIL " << jetEtaAK4->at(1) << " JET 1  ID " << idTAK4->at(1) << std::endl;
     //  }  
     // }

     //count ak4 jets passing pt threshold and id criteria
     int Nak4 = 0;
     double HTak4 = 0;

     for(size_t ijet=0; ijet<no_jets_ak4; ++ijet)
       {	 
	 //cout << "evtNo: " << evtNo << endl;	 
	 // cout << "ijet=" << ijet << " , sortedJetIdx[ijet]=" << sortedJetIdx[ijet] 
	 //      << " , raw pT=" << jetPtAK4->at(sortedJetIdx[ijet])/jetJecAK4->at(sortedJetIdx[ijet]) 
	 //      << " , final corrected pT - old =" << jetPtAK4->at(sortedJetIdx[ijet] ) 
	 //      << " , final corrected pT - new =" << (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet])
	 //      << endl;

	 //////////////cout << "id Tight jet" << sortedJetIdx[1] << " = " << idTAK4->at(sortedJetIdx[1]) << endl;
	 if(fabs(jetEtaAK4->at(sortedJetIdx[ijet])) < getPreCutValue1("jetFidRegion")
	    && idTAK4->at(sortedJetIdx[ijet]) == getPreCutValue1("tightJetID")
	    && (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]) > getPreCutValue1("ptCut"))
	   {
	     Nak4 += 1;
	     HTak4 += (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]);
	   }
       }


     if( int(getPreCutValue1("useFastJet"))==1 )
     {
       // vector of ak4 jets used for wide jet clustering
       std::vector<fastjet::PseudoJet> fjInputs, fjInputs_shift;

       for(size_t j=0; j<no_jets_ak4; ++j)
       {
	 if( !(jetEtaAK4->at(sortedJetIdx[j]) < getPreCutValue1("jetFidRegion")
	       && idTAK4->at(sortedJetIdx[j]) == getPreCutValue1("tightJetID")) ) continue;

	 double rescale = (jecFactors[sortedJetIdx[j]]/jetJecAK4->at(sortedJetIdx[j]));

	 if( j==0 && !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("pt0Cut")) ) continue;
	 else if( j==1 && !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("pt1Cut")) ) continue;
	 else if( !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("ptCut")) ) continue;

	 TLorentzVector tempJet, tempJet_shift;

	 tempJet.SetPtEtaPhiM( rescale*jetPtAK4->at(sortedJetIdx[j]) , jetEtaAK4->at(sortedJetIdx[j]) , jetPhiAK4->at(sortedJetIdx[j]) , rescale*jetMassAK4->at(sortedJetIdx[j]));
	 tempJet_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[j]])* rescale*jetPtAK4->at(sortedJetIdx[j]) , jetEtaAK4->at(sortedJetIdx[j]) , jetPhiAK4->at(sortedJetIdx[j]) ,  (1+jecUncertainty[sortedJetIdx[j]])* rescale*jetMassAK4->at(sortedJetIdx[j]));

	 fjInputs.push_back(fastjet::PseudoJet(tempJet.Px(),tempJet.Py(),tempJet.Pz(),tempJet.E()));
	 fjInputs_shift.push_back(fastjet::PseudoJet(tempJet_shift.Px(),tempJet_shift.Py(),tempJet_shift.Pz(),tempJet_shift.E()));
       }

       fjClusterSeq = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs, *fjJetDefinition ) );
       fjClusterSeq_shift = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs_shift, *fjJetDefinition ) );

       std::vector<fastjet::PseudoJet> inclusiveWideJets = fastjet::sorted_by_pt( fjClusterSeq->inclusive_jets(0.) );
       std::vector<fastjet::PseudoJet> inclusiveWideJets_shift = fastjet::sorted_by_pt( fjClusterSeq_shift->inclusive_jets(0.) );

       if( inclusiveWideJets.size()>1 )
       {
	 wj1.SetPxPyPzE(inclusiveWideJets.at(0).px(), inclusiveWideJets.at(0).py(), inclusiveWideJets.at(0).pz(), inclusiveWideJets.at(0).e());
	 wj2.SetPxPyPzE(inclusiveWideJets.at(1).px(), inclusiveWideJets.at(1).py(), inclusiveWideJets.at(1).pz(), inclusiveWideJets.at(1).e());
	 wj1_shift.SetPxPyPzE(inclusiveWideJets_shift.at(0).px(), inclusiveWideJets_shift.at(0).py(), inclusiveWideJets_shift.at(0).pz(), inclusiveWideJets_shift.at(0).e());
	 wj2_shift.SetPxPyPzE(inclusiveWideJets_shift.at(1).px(), inclusiveWideJets_shift.at(1).py(), inclusiveWideJets_shift.at(1).pz(), inclusiveWideJets_shift.at(1).e());
       }
     }
     else
     {
       TLorentzVector wj1_tmp, wj2_tmp;
       TLorentzVector wj1_shift_tmp, wj2_shift_tmp;
       double wideJetDeltaR_ = getPreCutValue1("DeltaR");

       if(no_jets_ak4>=2)
	 {
	   if(fabs(jetEtaAK4->at(sortedJetIdx[0])) < getPreCutValue1("jetFidRegion") 
	      && (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0]))*jetPtAK4->at(sortedJetIdx[sortedJetIdx[0]]) > getPreCutValue1("pt0Cut"))
	     {
	       if(fabs(jetEtaAK4->at(sortedJetIdx[1])) < getPreCutValue1("jetFidRegion") 
		  && (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1]))*jetPtAK4->at(sortedJetIdx[1]) > getPreCutValue1("pt1Cut"))
		 {
		   TLorentzVector jet1, jet2, jet1_shift, jet2_shift;
		   jet1.SetPtEtaPhiM( (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				      ,jetEtaAK4->at(sortedJetIdx[0]),jetPhiAK4->at(sortedJetIdx[0])
				      , (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) * jetMassAK4->at(sortedJetIdx[0]));
		   jet2.SetPtEtaPhiM( (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				      ,jetEtaAK4->at(sortedJetIdx[1]),jetPhiAK4->at(sortedJetIdx[1])
				      , (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) * jetMassAK4->at(sortedJetIdx[1]));
		   jet1_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				      ,jetEtaAK4->at(sortedJetIdx[0]),jetPhiAK4->at(sortedJetIdx[0])
				      , (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) * jetMassAK4->at(sortedJetIdx[0]));
		   jet2_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[1]])* (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				      ,jetEtaAK4->at(sortedJetIdx[1]),jetPhiAK4->at(sortedJetIdx[1])
				      , (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) * jetMassAK4->at(sortedJetIdx[1]));
		   
		   for(Long64_t ijet=0; ijet<no_jets_ak4; ijet++)
		     { //jet loop for ak4
		       TLorentzVector currentJet;
		       
		       if(fabs(jetEtaAK4->at(sortedJetIdx[ijet])) < getPreCutValue1("jetFidRegion") 
			  && idTAK4->at(sortedJetIdx[ijet]) == getPreCutValue1("tightJetID") 
			  && (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]) > getPreCutValue1("ptCut"))
			 {
			   TLorentzVector currentJet, currentJet_shift;
			   currentJet.SetPtEtaPhiM( (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetPtAK4->at(sortedJetIdx[ijet])
						    ,jetEtaAK4->at(sortedJetIdx[ijet]),jetPhiAK4->at(sortedJetIdx[ijet])
						    , (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetMassAK4->at(sortedJetIdx[ijet]));   
			   currentJet_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[ijet]])*(jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetPtAK4->at(sortedJetIdx[ijet])
						    ,jetEtaAK4->at(sortedJetIdx[ijet]),jetPhiAK4->at(sortedJetIdx[ijet])
						    , (1+jecUncertainty[sortedJetIdx[ijet]])*(jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetMassAK4->at(sortedJetIdx[ijet]));   
			   
			   double DeltaR1 = currentJet.DeltaR(jet1);
			   double DeltaR2 = currentJet.DeltaR(jet2);
			   
			   if(DeltaR1 < DeltaR2 && DeltaR1 < wideJetDeltaR_)
			     {
			       wj1_tmp += currentJet;
			       wj1_shift_tmp += currentJet_shift;
			     }
			   else if(DeltaR2 < wideJetDeltaR_)
			     {
			       wj2_tmp += currentJet;
			       wj2_shift_tmp += currentJet_shift;
			     }			 
			 } // if AK4 jet passes fid and jetid.
		     } //end of ak4 jet loop		     

		   // if(wj1_tmp.Pt()==0 && wj2_tmp.Pt() ==0) 
		   // std::cout << " wj1_tmp.Pt() IN  " <<wj1_tmp.Pt()  << " wj2_tmp.Pt() " <<  wj2_tmp.Pt()  << std::endl;		     

		 } //fid, jet id, pt cut
	     } //fid, jet id, pt cut
	 } // end of two jets.
	 
       // Re-order the wide jets in pt
       if( wj1_tmp.Pt() > wj2_tmp.Pt())
	 {
	   wj1 = wj1_tmp;
	   wj2 = wj2_tmp;
	   wj1_shift = wj1_shift_tmp;
	   wj2_shift = wj2_shift_tmp;
	 }
       else
	 {
	   wj1 = wj2_tmp;
	   wj2 = wj1_tmp;
	   wj1_shift = wj2_shift_tmp;
	   wj2_shift = wj1_shift_tmp;
	 }
     }


     double MJJWide = 0; 
     double DeltaEtaJJWide = 0;
     double DeltaPhiJJWide = 0;
     double MJJWide_shift = 0; 
     if( wj1.Pt()>0 && wj2.Pt()>0 )
     {
       // Create dijet system
       wdijet = wj1 + wj2;
       MJJWide = wdijet.M();
       DeltaEtaJJWide = fabs(wj1.Eta()-wj2.Eta());
       DeltaPhiJJWide = fabs(wj1.DeltaPhi(wj2));
       
       wdijet_shift = wj1_shift + wj2_shift;
       MJJWide_shift = wdijet_shift.M();

       // Put widejets in the container
       widejets.push_back( wj1 );
       widejets.push_back( wj2 );
     }

     //AK4 jets
     if(no_jets_ak4>=2)
       //cout << "eta j1 " << jetEtaAK4->at(sortedJetIdx[0]) << endl;
       //cout << "pt j1 " << (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0]) << endl;
       {
	 if(fabs(jetEtaAK4->at(sortedJetIdx[0])) < getPreCutValue1("jetFidRegion") 
	    && (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0]))*jetPtAK4->at(sortedJetIdx[0]) > getPreCutValue1("pt0Cut"))
	   {
	     if(fabs(jetEtaAK4->at(sortedJetIdx[1])) < getPreCutValue1("jetFidRegion") 
		&& (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1]))*jetPtAK4->at(sortedJetIdx[1]) > getPreCutValue1("pt1Cut"))
	       {
		 //cout << "filling ak4j1 and ak4j2" << endl;
		 //cout << "pt ak4 j1 = " << (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0]) << endl;
		 ak4j1.SetPtEtaPhiM( (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				     ,jetEtaAK4->at(sortedJetIdx[0])
				     ,jetPhiAK4->at(sortedJetIdx[0])
				     , (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetMassAK4->at(sortedJetIdx[0]));
		 ak4j2.SetPtEtaPhiM( (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				     ,jetEtaAK4->at(sortedJetIdx[1])
				     ,jetPhiAK4->at(sortedJetIdx[1])
				     , (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetMassAK4->at(sortedJetIdx[1]));
	       }
	   }
       }   

     double MJJAK4 = 0; 
     double DeltaEtaJJAK4 = 0;
     double DeltaPhiJJAK4 = 0;
     
     //std::cout << "ak4j1.Pt()=" << ak4j1.Pt() << "   ak4j2.Pt()=" << ak4j2.Pt() << std::endl;
     if( ak4j1.Pt()>0 && ak4j2.Pt()>0 )
     {
       // Create dijet system
       ak4dijet = ak4j1 + ak4j2;
       MJJAK4 = ak4dijet.M();
       DeltaEtaJJAK4 = fabs(ak4j1.Eta()-ak4j2.Eta());
       DeltaPhiJJAK4 = fabs(ak4j1.DeltaPhi(ak4j2));

       // Put widejets in the container
       AK4jets.push_back( ak4j1 );
       AK4jets.push_back( ak4j2 );
     }

     // GenJets
     double gen_mjj = -9999.0;
     double gen_deltaETAjj = -9999.0;
     TLorentzVector gen_wj1, gen_wj2;
     double pTGenAK4_j1 = -9999.0;
     double pTGenAK4_j2 = -9999.0;
     if (!isData) {
         double gen_wideJetDeltaR_ = getPreCutValue1("DeltaR");
         if (nGenJetsAK4 >= 2) {
             if (fabs(jetEtaGenAK4->at(0)) < getPreCutValue1("jetFidRegion")
                 && jetPtGenAK4->at(0) > getPreCutValue1("pt0Cut")
                 && fabs(jetEtaGenAK4->at(1)) < getPreCutValue1("jetFidRegion")
                 && jetPtGenAK4->at(1) > getPreCutValue1("pt1Cut")) {
                 TLorentzVector jet1, jet2;
                 jet1.SetPtEtaPhiM(jetPtGenAK4->at(0), jetEtaGenAK4->at(0),
                                   jetPhiGenAK4->at(0), jetMassGenAK4->at(0));
                 jet2.SetPtEtaPhiM(jetPtGenAK4->at(1), jetEtaGenAK4->at(1),
                                   jetPhiGenAK4->at(1), jetMassGenAK4->at(1));
                 for (int i=0; i<nGenJetsAK4; ++i) {
                     if(fabs(jetEtaGenAK4->at(i)) < getPreCutValue1("jetFidRegion")
                        && jetPtGenAK4->at(i) > getPreCutValue1("ptCut")) {
                         TLorentzVector currentJet;
                         currentJet.SetPtEtaPhiM(jetPtGenAK4->at(i),
                                                 jetEtaGenAK4->at(i),
                                                 jetPhiGenAK4->at(i),
                                                 jetMassGenAK4->at(i));
                         double DeltaR1 = currentJet.DeltaR(jet1);
                         double DeltaR2 = currentJet.DeltaR(jet2);

                         if (DeltaR1 < DeltaR2 && DeltaR1 < gen_wideJetDeltaR_)
                             gen_wj1 += currentJet;
                         else if (DeltaR2 < gen_wideJetDeltaR_)
                             gen_wj2 += currentJet;
                     }
                 }
             }
         }

         if (gen_wj1.Pt() > 0.0 && gen_wj2.Pt() > 0.0) {
             TLorentzVector gen_wdijet = gen_wj1 + gen_wj2;
             gen_mjj = gen_wdijet.M();
             gen_deltaETAjj = fabs(gen_wj1.Eta() - gen_wj2.Eta());
         }

         double gen_minDeltaR_j1 = 9999.0;
         double gen_minDeltaR_j2 = 9999.0;
         double gen_maxDeltaR = 0.4;
         if (AK4jets.size() > 1) {
             for (int i=0; i<nGenJetsAK4; ++i) {
                 TLorentzVector currentJet;
                 currentJet.SetPtEtaPhiM(jetPtGenAK4->at(i), jetEtaGenAK4->at(i),
                                         jetPhiGenAK4->at(i), jetMassGenAK4->at(i));
                 double DeltaR1 = currentJet.DeltaR(AK4jets[0]);
                 double DeltaR2 = currentJet.DeltaR(AK4jets[1]);

                 if (DeltaR1 < DeltaR2 && DeltaR1 < gen_maxDeltaR) {
                     if (DeltaR1 < gen_minDeltaR_j1) {
                         pTGenAK4_j1 = currentJet.Pt();
                         gen_minDeltaR_j1 = DeltaR1;
                     } else if (DeltaR2 < gen_minDeltaR_j2 && DeltaR2 < gen_maxDeltaR) {
                         pTGenAK4_j2 = currentJet.Pt();
                         gen_minDeltaR_j2 = DeltaR2;
                     }
                 } else { // DeltaR2 > DeltaR1
                     if (DeltaR2 < gen_maxDeltaR && DeltaR2 < gen_minDeltaR_j2) {
                         pTGenAK4_j2 = currentJet.Pt();
                         gen_minDeltaR_j2 = DeltaR2;
                     } else if (DeltaR1 < gen_minDeltaR_j1 && DeltaR1 < gen_maxDeltaR) {
                         pTGenAK4_j1 = currentJet.Pt();
                         gen_minDeltaR_j1 = DeltaR1;
                     }
                 }
             }
         }
     }

     //== Fill Variables ==
     fillVariableWithValue("isData",isData);     
     fillVariableWithValue("run",runNo);     
     fillVariableWithValue("event",evtNo);     
     fillVariableWithValue("lumi",lumi);     
     fillVariableWithValue("nVtx",nvtx);     
     fillVariableWithValue("nJet",widejets.size());
     fillVariableWithValue("Nak4",Nak4);
     fillVariableWithValue ( "PassJSON", passJSON (runNo, lumi, isData));

     //directly taken from big root tree (i.e. jec not reapplied)
     fillVariableWithValue("htAK4",htAK4); // summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("mhtAK4",mhtAK4); //summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("mhtAK4Sig",mhtAK4Sig); // mhtAK4/htAK4 summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("offMet",offMet); //recomputed from PF candidates (off=offline)
     fillVariableWithValue("offMetSig",offMetSig); // offMet/offSumEt recomputed from PF candidates (off=offline)
     fillVariableWithValue("met",met); //directly taken from event
     fillVariableWithValue("metSig",metSig); // met/offMetSig (to be substituted with met/SumEt from event in future)

     if( AK4jets.size() >=1 ){
       //cout << "AK4jets.size() " <<  AK4jets.size() << endl;
       //cout << "IdTight_j1 : " << idTAK4->at(sortedJetIdx[0]) << endl;
       fillVariableWithValue( "IdTight_j1",idTAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "pTAK4_j1", AK4jets[0].Pt());
       fillVariableWithValue( "etaAK4_j1", AK4jets[0].Eta());
       fillVariableWithValue( "phiAK4_j1", AK4jets[0].Phi());
       //fillVariableWithValue( "jetPtAK4matchCaloJet_j1", jetPtAK4matchCaloJet->at(sortedJetIdx[0]));
       fillVariableWithValue( "jetJecAK4_j1", jecFactors[sortedJetIdx[0]] );
       fillVariableWithValue( "jetJecUncAK4_j1", jecUncertainty[sortedJetIdx[0]] );
       //jetID
       fillVariableWithValue( "neutrHadEnFrac_j1", jetNhfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedHadEnFrac_j1", jetChfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "photonEnFrac_j1", jetPhfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "eleEnFract_j1", jetElfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "muEnFract_j1", jetMufAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "neutrElectromFrac_j1", jetNemfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedElectromFrac_j1", jetCemfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedMult_j1", chMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "neutrMult_j1", neMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "photonMult_j1", phoMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "jetCSVAK4_j1", jetCSVAK4->at(sortedJetIdx[0]) );
     }
     if( AK4jets.size() >=2 ){
       //cout << "IdTight_j2 : " << idTAK4->at(sortedJetIdx[1]) << endl << endl;
       fillVariableWithValue( "IdTight_j2",idTAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "pTAK4_j2", AK4jets[1].Pt() );
       fillVariableWithValue( "etaAK4_j2", AK4jets[1].Eta());
       fillVariableWithValue( "phiAK4_j2", AK4jets[1].Phi());
       //fillVariableWithValue( "jetPtAK4matchCaloJet_j2", jetPtAK4matchCaloJet->at(sortedJetIdx[1]));
       fillVariableWithValue( "jetJecAK4_j2", jecFactors[sortedJetIdx[1]]); 
       fillVariableWithValue( "jetJecUncAK4_j2", jecUncertainty[sortedJetIdx[1]] );
       //jetID
       fillVariableWithValue( "neutrHadEnFrac_j2", jetNhfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedHadEnFrac_j2", jetChfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "photonEnFrac_j2", jetPhfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "eleEnFract_j2", jetElfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "muEnFract_j2", jetMufAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "neutrElectromFrac_j2", jetNemfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedElectromFrac_j2", jetCemfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedMult_j2", chMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "neutrMult_j2", neMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "photonMult_j2", phoMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "jetCSVAK4_j2", jetCSVAK4->at(sortedJetIdx[1]) );
       //dijet
       fillVariableWithValue( "Dijet_MassAK4", MJJAK4) ; 
       fillVariableWithValue( "CosThetaStarAK4", TMath::TanH( (AK4jets[0].Eta()-AK4jets[1].Eta())/2 )); 
       fillVariableWithValue( "deltaETAjjAK4", DeltaEtaJJAK4 ) ;
       fillVariableWithValue( "deltaPHIjjAK4", DeltaPhiJJAK4 ) ;
     }

     if( widejets.size() >= 1 ){
         fillVariableWithValue( "pTWJ_j1", widejets[0].Pt() );
         fillVariableWithValue( "etaWJ_j1", widejets[0].Eta());
	 //no cuts on these variables, just to store in output
         fillVariableWithValue( "massWJ_j1", widejets[0].M());
         fillVariableWithValue( "phiWJ_j1", widejets[0].Phi());
       }

     if( widejets.size() >= 2 ){
         fillVariableWithValue( "pTWJ_j2", widejets[1].Pt() );
         fillVariableWithValue( "etaWJ_j2", widejets[1].Eta());
	 fillVariableWithValue( "deltaETAjj", DeltaEtaJJWide ) ;
         fillVariableWithValue( "mjj", MJJWide ) ;
         fillVariableWithValue( "mjj_shiftJEC", MJJWide_shift ) ;
	 //no cuts on these variables, just to store in output
         fillVariableWithValue( "massWJ_j2", widejets[1].M());
         fillVariableWithValue( "phiWJ_j2", widejets[1].Phi());	
	 //dijet
         fillVariableWithValue( "CosThetaStarWJ", TMath::TanH( (widejets[0].Eta()-widejets[1].Eta())/2 )); 
	 fillVariableWithValue( "deltaPHIjj", DeltaPhiJJWide ) ;
	 //fillVariableWithValue( "Dijet_MassAK8", mjjAK8 ) ;  
	 //fillVariableWithValue( "Dijet_MassC", mjjCA8 ) ;
	 // if(wdijet.M()<1){
	 //    std::cout << " INV MASS IS " << wdijet.M() << std::endl;
	 //    std::cout << " Delta Eta IS " << DeltaEtaJJWide << " n is  " << widejets.size() << std::endl;
	 //    std::cout << " INV MASS FROM NTUPLE AK8 " << mjjAK8 << std::endl;
	 //    //std::cout << " INV MASS FROM NTUPLE CA8 " << mjjCA8 << std::endl;
       }

     if (!isData) {
         fillVariableWithValue("gen_mjj", gen_mjj);
         fillVariableWithValue("gen_deltaETAjj", gen_deltaETAjj);
         fillVariableWithValue("pTGenAK4_j1", pTGenAK4_j1);
         fillVariableWithValue("pTGenAK4_j2", pTGenAK4_j2);
     }

     //no cuts on these variables, just to store in output
     // if(!isData)
     //   fillVariableWithValue("trueVtx",PileupInteractions->at(idx_InTimeBX));
     // else if(isData)
     //   fillVariableWithValue("trueVtx",999);     

     // Trigger
     //int NtriggerBits = triggerResult->size();
     /*if (isData)
       {
	 fillVariableWithValue("passHLT_ZeroBias_BtagSeq",triggerResult->at(8));// DST_ZeroBias_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_ZeroBias",triggerResult->at(7));// DST_ZeroBias_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_L1DoubleMu_BtagSeq",triggerResult->at(9));// DST_L1DoubleMu_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_L1DoubleMu",triggerResult->at(10));// DST_L1DoubleMu_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_CaloJet40_BtagSeq",triggerResult->at(0));//  DST_CaloJet40_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                        //  OR DST_CaloJet40_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_CaloJet40",triggerResult->at(1));// DST_CaloJet40_CaloScouting_PFScouting_v*  (run>=259636)

	 fillVariableWithValue("passHLT_L1HTT150_BtagSeq",triggerResult->at(2));// DST_L1HTT125ORHTT150ORHTT175_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                        // OR DST_L1HTT_BTagScouting_v* (run>=259636)    
	 fillVariableWithValue("passHLT_L1HTT150",triggerResult->at(3));// DST_L1HTT_CaloScouting_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_HT450_BtagSeq",triggerResult->at(5));// DST_HT450_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                     // OR DST_HT450_BTagScouting_v* (run>=259636)    
	 fillVariableWithValue("passHLT_HT450",triggerResult->at(6));// DST_HT450_PFScouting_v* (run>=259636)        

	 fillVariableWithValue("passHLT_PFHT800",triggerResult->at(13));// HLT_PFHT800_v* (all runs)   
	 fillVariableWithValue("passHLT_PFHT650MJJ950",triggerResult->at(22));// HLT_PFHT650_WideJetMJJ950DEtaJJ1p5_v* (all runs)        
	 fillVariableWithValue("passHLT_PFHT650MJJ900",triggerResult->at(23));// HLT_PFHT650_WideJetMJJ900DEtaJJ1p5_v* (all runs)        
       }*/

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // optional call to fill a skim with the full content of the input roottuple
     //if( passedCut("nJetFinal") ) fillSkimTree();
     if( passedCut("PassJSON")
	 && passedCut("nVtx") 
	 && passedCut("IdTight_j1")
	 && passedCut("IdTight_j2")
	 && passedCut("nJet")
	 && passedCut("pTWJ_j1")
	 && passedCut("etaWJ_j1")
	 && passedCut("pTWJ_j2")
	 && passedCut("etaWJ_j2")
	 && getVariableValue("deltaETAjj") <  getPreCutValue1("DetaJJforTrig") ){

       h_mjj_NoTrigger_1GeVbin -> Fill(MJJWide); 
       h_mjj_NoTrigger -> Fill(MJJWide); 
       
       /*if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) )
	 h_mjj_HLTpass_ZeroBias -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) 
	   && (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
	 h_mjj_HLTpass_ZeroBias_L1HTT150 -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
	 h_mjj_HLTpass_L1HTT150 -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) 
	   && (getVariableValue("passHLT_HT450_BtagSeq")||getVariableValue("passHLT_HT450")) )
           h_mjj_HLTpass_L1HTT150_HT450 -> Fill(MJJWide);  */
       
     }

     // optional call to fill a skim with a subset of the variables defined in the cutFile (use flag SAVE)
     if( passedAllPreviousCuts("mjj") && passedCut("mjj") ) 
       {
	 fillReducedSkimTree();

	 // ===== Take a look at this =====
	 // //Example on how to investigate quickly the data
	 // if(getVariableValue("mjj")>4000)
	 //   {
	 //     //fast creation and filling of histograms
	 //     CreateAndFillUserTH1D("h_dphijj_mjjgt4000", 100, 0, 3.15, getVariableValue("deltaPHIjj"));
	 //     CreateAndFillUserTH1D("h_htak4_mjjgt4000", 1000, 0, 10000, getVariableValue("HTAK4"));
	 //     CreateAndFillUserTH1D("h_nvtx_mjjgt4000", 31, -0.5, 30.5, getVariableValue("nVtx"));
	 //   }

       }

     // ===== Example of mjj spectrum after HLT selection =====
     // if( passedAllPreviousCuts("mjj") )
     //   {
     // 	 if(getVariableValue("passHLT")>0)
     // 	   {
     // 	     //fast creation and filling of histograms
     // 	     CreateAndFillUserTH1D("h_mjj_passHLT", getHistoNBins("mjj"), getHistoMin("mjj"), getHistoMax("mjj"), getVariableValue("mjj"));
     // 	   }
     //   }

     // reject events that did not pass level 0 cuts
     //if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     //if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     //if( !passedCut("all") ) continue;
     // ......

     // if( widejets.size() >= 2) {
     //  h_nJetFinal->Fill(widejets.size());
     //  h_DijetMass->Fill(wdijet.M());
     //  h_pT1stJet->Fill(widejets[0].Pt());
     //  h_pT2ndJet->Fill(widejets[1].Pt());
     //  h_eta1stJet->Fill(widejets[0].Eta());
     //  h_eta2ndJet->Fill(widejets[1].Eta());
     // }
     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

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

   h_mjj_NoTrigger_1GeVbin -> Write();
   h_mjj_NoTrigger -> Write();
   /*h_mjj_HLTpass_ZeroBias -> Write();
   h_mjj_HLTpass_ZeroBias_L1HTT150 -> Write();
   h_mjj_HLTpass_L1HTT150 -> Write();
   h_mjj_HLTpass_L1HTT150_HT450 -> Write();*/

   // h_nVtx->Write();
   // h_trueVtx->Write();
   // h_nJetFinal->Write();
   // h_pT1stJet->Write();
   // h_pT2ndJet->Write();
   // h_DijetMass->Write();
   // h_eta1stJet->Write();
   // h_eta2ndJet->Write();

   // //pT of both jets, to be built using the histograms produced automatically by baseClass
   // TH1F * h_pTJets = new TH1F ("h_pTJets","", getHistoNBins("pT1stJet"), getHistoMin("pT1stJet"), getHistoMax("pT1stJet"));
   // h_pTJets->Add( & getHisto_noCuts_or_skim("pT1stJet") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   // h_pTJets->Add( & getHisto_noCuts_or_skim("pT2ndJet") );
   // //one could also do:  *h_pTJets = getHisto_noCuts_or_skim("pT1stJet") + getHisto_noCuts_or_skim("pT2ndJet");
   // h_pTJets->Write();
   // //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
   }
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

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

   TH1F *h_nJetFinal = new TH1F ("h_nJetFinal","",10,0,10);
   h_nJetFinal->Sumw2();      
   TH1F *h_nVtx = new TH1F ("h_nVtx","",30,0,30);
   h_nVtx->Sumw2();   
   TH1F *h_pT1stJet = new TH1F ("h_pT1stJet","",100,0,3000);
   h_pT1stJet->Sumw2();
   TH1F *h_pT2ndJet = new TH1F ("h_pT2ndJet","",100,0,3000);
   h_pT2ndJet->Sumw2();
   TH1F *h_eta1stJet = new TH1F ("h_eta1stJet","",5,-2.5,2.5);
   h_eta1stJet->Sumw2();
   TH1F *h_eta2ndJet = new TH1F ("h_eta2ndJet","",5,-2.5,2.5);
   h_eta2ndJet->Sumw2();
   TH1F *h_DijetMass = new TH1F ("h_DijetMass","",600,0,6000);
   h_DijetMass->Sumw2();
   TH1F *h_DeltaETAjj = new TH1F ("h_DeltaETAjj","",120,0,3.);
   h_DeltaETAjj->Sumw2();


   /////////initialize variables

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event
 
     Int_t no_jets_ak4=jetPtAK4->size();
     Int_t no_jets_ak8=jetPtAK8->size();
     vector<TLorentzVector> widejets;
     TLorentzVector currentJet, wj1_tmp, wj1, wj2_tmp, wj2, v_jet_ak4,wdijet,wj1math,wj2math;
     ////cone size wide 1.1
     double wideJetDeltaR_ = 1.1;

     resetCuts();
  
     //Eirini wide jet
     // if(no_jets_ak4>=2){
     //   if( fabs(jetEtaAK4->at(0)) < getPreCutValue1("jetFidRegion") && idTAK4->at(0) == getPreCutValue1("tightJetID")){
     // 	 if( fabs(jetEtaAK4->at(1)) < getPreCutValue1("jetFidRegion") && idTAK4->at(1) == getPreCutValue1("tightJetID")){
     // 	   TLorentzVector jet1, jet2;
     // 	   jet1.SetPtEtaPhiM(jetPtAK4->at(0),jetEtaAK4->at(0),jetPhiAK4->at(0),jetMassAK4->at(0));
     // 	   jet2.SetPtEtaPhiM(jetPtAK4->at(1),jetEtaAK4->at(1),jetPhiAK4->at(1),jetMassAK4->at(1));
	   
     // 	   for(Long64_t ijet=0; ijet<no_jets_ak4; ijet++){ //jet loop for ak4
     // 	     TLorentzVector currentJet;
	     
     // 	     if( fabs(jetEtaAK4->at(ijet)) < getPreCutValue1("jetFidRegion") && idTAK4->at(ijet) == getPreCutValue1("tightJetID")){
     // 	       TLorentzVector currentJet;
     // 	       currentJet.SetPtEtaPhiM(jetPtAK4->at(ijet),jetEtaAK4->at(ijet),jetPhiAK4->at(ijet),jetMassAK4->at(ijet));          
     // 	       double DeltaR1 = currentJet.DeltaR(jet1);
     // 	       double DeltaR2 = currentJet.DeltaR(jet2);

     // 	       if(DeltaR1 < DeltaR2 && DeltaR1 < wideJetDeltaR_){
     // 		 wj1_tmp += currentJet;
     // 	       }
     // 	       else if(DeltaR2 < wideJetDeltaR_){
     // 		 wj2_tmp += currentJet;
     // 	       }
	       
	       
     // 	     } // if AK4 jet passes fid and jetid.
     // 	   } //end of ak4 jet loop

     // 	   if(wj1_tmp.Pt()==0 && wj2_tmp.Pt() ==0) 
     // 	     std::cout << " wj1_tmp.Pt() IN  " <<wj1_tmp.Pt()  << " wj2_tmp.Pt() " <<  wj2_tmp.Pt()  << std::endl;
	   
     // 	 } //fid and jet id
     //   } //fid and jet id
     // } // end of two jets.

     // -------- Start Giulia Wide jet  --------------------- 
/////////////giulia
//use only jets pt>30, fiducial region and looseId
     
     if(no_jets_ak4>=2){
       if(!(jetPtAK4->at(0)>getPreCutValue1("jetPtCut") && fabs(jetEtaAK4->at(0)) < getPreCutValue1("jetFidRegion") && idLAK4->at(0) == getPreCutValue1("looseJetID"))){
     	 std::cout << " JET 0 FAIL " <<  jetEtaAK4->at(0) << " JET 0  ID " << idLAK4->at(0) << std::endl;

       }
       if(!(jetPtAK4->at(1)>getPreCutValue1("jetPtCut") && fabs(jetEtaAK4->at(1)) < getPreCutValue1("jetFidRegion") && idLAK4->at(1) == getPreCutValue1("looseJetID"))){
     	 std::cout << " JET 1 FAIL " << jetEtaAK4->at(1) << " JET 1  ID " << idTAK4->at(1) << std::endl;

       }  
     }
     //////////////////////////

     
     //code to create wide jets : use ak4 passing loose ID
     if(no_jets_ak4>=2){

       if( fabs(jetEtaAK4->at(0)) < getPreCutValue1("jetFidRegion") && idLAK4->at(0) == getPreCutValue1("looseJetID") && jetPtAK4->at(0)>getPreCutValue1("jetPtCut")){
     	 if( fabs(jetEtaAK4->at(1)) < getPreCutValue1("jetFidRegion") && idLAK4->at(1) == getPreCutValue1("looseJetID") && jetPtAK4->at(1)>getPreCutValue1("jetPtCut")){
     	   TLorentzVector jet1, jet2;
     	   jet1.SetPtEtaPhiM(jetPtAK4->at(0),jetEtaAK4->at(0),jetPhiAK4->at(0),jetMassAK4->at(0));
     	   jet2.SetPtEtaPhiM(jetPtAK4->at(1),jetEtaAK4->at(1),jetPhiAK4->at(1),jetMassAK4->at(1));
        
     	   for(Long64_t ijet=0; ijet<no_jets_ak4; ijet++){ //jet loop for ak4
     	     TLorentzVector currentJet;
          
     	     if( fabs(jetEtaAK4->at(ijet)) < getPreCutValue1("jetFidRegion") && idLAK4->at(ijet) == 1){
     	       TLorentzVector currentJet;
     	       currentJet.SetPtEtaPhiM(jetPtAK4->at(ijet),jetEtaAK4->at(ijet),jetPhiAK4->at(ijet),jetMassAK4->at(ijet));          
     	       double DeltaR1 = currentJet.DeltaR(jet1);
     	       double DeltaR2 = currentJet.DeltaR(jet2);
            
     	       if(DeltaR1 < DeltaR2 && DeltaR1 < wideJetDeltaR_){
     		 wj1_tmp += currentJet;
     	       }
     	       else if(DeltaR2 < wideJetDeltaR_){
     		 wj2_tmp += currentJet;
     	       }
            
            
     	     } // if AK4 jet passes fid and jetid.
     	   } //end of ak4 jet loop
        
     	   if(wj1_tmp.Pt()==0 && wj2_tmp.Pt() ==0) 
     	     std::cout << " wj1_tmp.Pt() IN  " <<wj1_tmp.Pt()  << " wj2_tmp.Pt() " <<  wj2_tmp.Pt()  << std::endl;
        
     	 } //fid and jet id j2
       } //fid and jet id j1
     } // end of two jets.
     //-------------- end Giulia Wide jet --------------------------     


     //
     if(wj1_tmp.Pt()==0 && wj2_tmp.Pt() ==0)     std::cout << " wj1_tmp.Pt()  " <<wj1_tmp.Pt()  << " wj2_tmp.Pt() " << wj2_tmp.Pt()  << "  no_jets_ak4 " << no_jets_ak4 << std::endl;
     //
     double MJJWide,DeltaEtaJJWide,DeltaPhiJJWide;
     
     if( wj1_tmp.Pt()>0 && wj2_tmp.Pt() >0 ){
       // Re-order the wide jets in pt
       if( wj1_tmp.Pt() > wj2_tmp.Pt()){
	 wj1 = wj1_tmp;
	 wj2 = wj2_tmp;
       }
       else{
	 wj1 = wj2_tmp;
	 wj2 = wj1_tmp;
       }
       
       // Create dijet system
       wdijet = wj1 + wj2;
       MJJWide = wdijet.M();
       DeltaEtaJJWide = fabs(wj1.Eta()-wj2.Eta());
       DeltaPhiJJWide = fabs(wj1.DeltaPhi(wj2));
       
       // Put widejets in the container
       wj1math.SetPtEtaPhiM(wj1.Pt(), wj1.Eta(), wj1.Phi(), wj1.M());
       wj2math.SetPtEtaPhiM(wj2.Pt(), wj2.Eta(), wj2.Phi(), wj2.M());  
       widejets.push_back( wj1math );
       widejets.push_back( wj2math );
     }
     


     fillVariableWithValue("nJetFinal",widejets.size()) ;
     fillVariableWithValue("nVtx",nvtx) ;
     fillVariableWithValue("ptHat", ptHat);    
     fillVariableWithValue("neutralHadronEnergyFraction_j1", jetNhfAK4->at(0));    
     fillVariableWithValue("photonEnergyFraction_j1", jetPhfAK4->at(0));    
     fillVariableWithValue("electronEnergyFraction_j1", jetElfAK4->at(0));         
     fillVariableWithValue("muonEnergyFraction_j1", jetMufAK4->at(0));    
     fillVariableWithValue("chargedHadronMultiplicity_j1", jetChfAK4->at(0));    
     fillVariableWithValue("neutralHadronEnergyFraction_j2", jetNhfAK4->at(1));    
     fillVariableWithValue("photonEnergyFraction_j2", jetPhfAK4->at(1));    
     fillVariableWithValue("electronEnergyFraction_j2", jetElfAK4->at(1));         
     fillVariableWithValue("muonEnergyFraction_j2", jetMufAK4->at(1));    
     fillVariableWithValue("chargedHadronMultiplicity_j2", jetChfAK4->at(1));    
     fillVariableWithValue("jetIdT1",idTAK4->at(0)) ;
     fillVariableWithValue("jetIdT2",idTAK4->at(1)) ;

     if( widejets.size() >= 1 )
       
       {
	 fillVariableWithValue( "pT1stJet", widejets[0].Pt() );
	 fillVariableWithValue( "eta1stJet", widejets[0].Eta());

	 
       }
     
     if( widejets.size() >= 2 )
       {
         fillVariableWithValue( "pT2ndJet", widejets[1].Pt() );
         fillVariableWithValue( "eta2ndJet", widejets[1].Eta());

	 
         // Calculate deltaETAjj
	 //giulia 
	 fillVariableWithValue( "deltaETAjj", DeltaEtaJJWide ) ;
	 
         // Calculate Mjj
         fillVariableWithValue( "Dijet_MassW", wdijet.M() ) ;
         fillVariableWithValue( "Dijet_MassAK8", mjjAK8 ) ;  
	 fillVariableWithValue( "Dijet_MassAK4", mjjAK4 ) ;  
	 //giulia - test
	 //fillVariableWithValue( "Dijet_MassC", mjjCA8 ) ;
	 if(wdijet.M()<1){
	   std::cout << " INV MASS IS " << wdijet.M() << std::endl;
	   std::cout << " Delta Eta IS " << DeltaEtaJJWide << " n is  " << widejets.size() << std::endl;
	   std::cout << " INV MASS FROM NTUPLE AK8 " << mjjAK8 << std::endl;
	   //std::cout << " INV MASS FROM NTUPLE CA8 " << mjjCA8 << std::endl;
	 }
       }
     
     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // optional call to fill a skim with the full content of the input roottuple
     if( passedCut("nJetFinal") ) fillSkimTree();
     
     // optional call to fill a skim with a subset of the variables defined in the cutFile (use flag SAVE)
     if( passedCut("nJetFinal") ) fillReducedSkimTree();

     // reject events that did not pass level 0 cuts
     if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     if( !passedCut("all") ) continue;
     // ......

     if( widejets.size() >= 2) {
      h_nJetFinal->Fill(widejets.size());
      h_DijetMass->Fill(wdijet.M());
      h_pT1stJet->Fill(widejets[0].Pt());
      h_pT2ndJet->Fill(widejets[1].Pt());
      h_eta1stJet->Fill(widejets[0].Eta());
      h_eta2ndJet->Fill(widejets[0].Eta());
     }
     ////////////////////// User's code ends here ///////////////////////
     
   } // End loop over events
   
   //////////write histos 
   
   h_nVtx->Write();
   h_nJetFinal->Write();
   h_pT1stJet->Write();
   h_pT2ndJet->Write();
   h_DijetMass->Write();
   h_DeltaETAjj->Write();
   h_eta1stJet->Write();
   h_eta2ndJet->Write();

   //pT of both jets, to be built using the histograms produced automatically by baseClass
   TH1F * h_pTJets = new TH1F ("h_pTJets","", getHistoNBins("pT1stJet"), getHistoMin("pT1stJet"), getHistoMax("pT1stJet"));
   h_pTJets->Add( & getHisto_noCuts_or_skim("pT1stJet") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   h_pTJets->Add( & getHisto_noCuts_or_skim("pT2ndJet") );
   //one could also do:  *h_pTJets = getHisto_noCuts_or_skim("pT1stJet") + getHisto_noCuts_or_skim("pT2ndJet");
   h_pTJets->Write();
   //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;
   
  ////////////////////// User's code to book histos - BEGIN ///////////////////////

  TH1F *h_Mlj_PAS = new TH1F ("h_Mlj_PAS","h_Mlj_PAS",200,0,2000);  h_Mlj_PAS->Sumw2();

  ////////////////////// User's code to book histos - END ///////////////////////

  ////////////////////// User's code to get preCut values - BEGIN ///////////////

  double eleEta_bar = getPreCutValue1("eleEta_bar");
  double eleEta_end_min = getPreCutValue1("eleEta_end");
  double eleEta_end_max = getPreCutValue2("eleEta_end");

  double EleEnergyScale_EB=getPreCutValue1("EleEnergyScale_EB");
  double EleEnergyScale_EE=getPreCutValue1("EleEnergyScale_EE");
  double JetEnergyScale=getPreCutValue1("JetEnergyScale");

  // Not used when using ElectronHeepID and heepBitMask // int eleIDType = (int) getPreCutValue1("eleIDType");
  int heepBitMask_EB  =  getPreCutValue1("heepBitMask_EBGapEE") ;
  int heepBitMask_GAP =  getPreCutValue2("heepBitMask_EBGapEE") ;

  int heepBitMask_EE  =  getPreCutValue3("heepBitMask_EBGapEE") ;

  int looseBitMask_EB       =  getPreCutValue1("looseBitMask_EBGapEE") ;
  int looseBitMask_GAP      =  getPreCutValue2("looseBitMask_EBGapEE") ;
  int looseBitMask_EE       =  getPreCutValue3("looseBitMask_EBGapEE") ;
  int looseBitMask_enabled  =  getPreCutValue4("looseBitMask_EBGapEE") ;

  double muon_PtCut = getPreCutValue1("muon_PtCut");
  double muFidRegion = getPreCutValue1("muFidRegion"); // currently unused !!!
  double muNHits_minThresh = getPreCutValue1("muNHits_minThresh");
  double muTrkD0Maximum = getPreCutValue1("muTrkD0Maximum");

  int jetAlgorithm = getPreCutValue1("jetAlgorithm");
  int metAlgorithm = getPreCutValue1("metAlgorithm");

  ////////////////////// User's code to get preCut values - END /////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //## Define new jet collection
    std::auto_ptr<std::vector<double> >  JetPt  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetPtRaw  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetEnergy  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetEta  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetPhi  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<int> >     JetPassID  ( new std::vector<int>()  );
    std::auto_ptr<std::vector<double> >  JetTCHE  ( new std::vector<double>()  );

    if(jetAlgorithm==1) //PF jets
      {
	for (int ijet=0 ; ijet< PFJetPt->size() ; ijet++)
	  {
	    JetPt->push_back( PFJetPt->at(ijet) );
	    JetPtRaw->push_back( PFJetPtRaw->at(ijet) );
	    JetEnergy->push_back( PFJetEnergy->at(ijet) );
	    JetEta->push_back( PFJetEta->at(ijet) );
	    JetPhi->push_back( PFJetPhi->at(ijet) );
            JetPassID->push_back( PFJetPassLooseID->at(ijet) );
	    //     JetPassID->push_back(
	    //  PFJetIdloose(PFJetChargedHadronEnergyFraction->at(ijet),
	    //       PFJetChargedEmEnergyFraction->at(ijet),
	    //       PFJetNeutralHadronEnergyFraction->at(ijet),
	    //       PFJetNeutralEmEnergyFraction->at(ijet),
	    //       PFJetEta->at(ijet) )
	    //  );
            JetTCHE->push_back( PFJetTrackCountingHighEffBTag->at(ijet) );
	  }//end loop over pf jets
      }//end if "pf jets"

    if(jetAlgorithm==2) //Calo jets
      {
	for (int ijet=0 ; ijet < CaloJetPt->size() ; ijet++)
	  {
	    JetPt->push_back( CaloJetPt->at(ijet) );
	    JetPtRaw->push_back( CaloJetPtRaw->at(ijet) );
	    JetEnergy->push_back( CaloJetEnergy->at(ijet) );
	    JetEta->push_back( CaloJetEta->at(ijet) );
	    JetPhi->push_back( CaloJetPhi->at(ijet) );
            JetPassID->push_back( CaloJetPassLooseID->at(ijet) );
	    //     JetPassID->push_back(
	    //  JetIdloose(CaloJetresEMF->at(ijet),
	    //     CaloJetfHPD->at(ijet),
	    //     CaloJetn90Hits->at(ijet),
	    //     CaloJetEta->at(ijet) )
	    //  );
            JetTCHE->push_back( CaloJetTrackCountingHighEffBTag->at(ijet) );
	  }//end loop over calo jets
      }//end if "calo jets"

    //## Define new met collection
    double thisMET;
    double thisMETPhi;
    double thisSumET;
    double thisGenSumET;

    if(isData==0)
      thisGenSumET = GenSumETTrue->at(0);
    else
      thisGenSumET = -1;

    if(metAlgorithm==1) // --> PFMET
      {
	thisMET = PFMET->at(0);
	thisMETPhi = PFMETPhi->at(0);
	thisSumET = PFSumET->at(0);
      }
    if(metAlgorithm==2) // --> CaloMET
      {
	thisMET = CaloMET->at(0);
	thisMETPhi = CaloMETPhi->at(0);
	thisSumET = CaloSumET->at(0);
      }
    if(metAlgorithm==3) // --> PFMET (with type-1 corrections)
      {
	thisMET = PFMETType1Cor->at(0);
	thisMETPhi = PFMETPhiType1Cor->at(0);
	thisSumET = PFSumETType1Cor->at(0);
      }


    // EES and JES
    if( EleEnergyScale_EB != 1 || EleEnergyScale_EE != 1 )
      {
	for(int iele=0; iele<ElectronPt->size(); iele++)
	  {
	    if( fabs(ElectronEta->at(iele)) < eleEta_bar )
	      ElectronPt->at(iele) *= EleEnergyScale_EB;
	    if( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max )
	      ElectronPt->at(iele) *= EleEnergyScale_EE;
	  }
      }
    if( JetEnergyScale != 1 )
      {
	for(int ijet=0; ijet<JetPt->size(); ijet++)
	  {
	    JetPt->at(ijet) *= JetEnergyScale;
	    JetEnergy->at(ijet) *= JetEnergyScale;
	  }
      }

    //## HLT
    int PassTrig = 0;
    int HLTFromRun[4] = {getPreCutValue1("HLTFromRun"),
			 getPreCutValue2("HLTFromRun"),
			 getPreCutValue3("HLTFromRun"),
			 getPreCutValue4("HLTFromRun")};
    int HLTTrigger[4] = {getPreCutValue1("HLTTrigger"),
			 getPreCutValue2("HLTTrigger"),
			 getPreCutValue3("HLTTrigger"),
			 getPreCutValue4("HLTTrigger")};
    int HLTTrgUsed;
    for (int i=0; i<4; i++) {
      if ( !isData && i != 0) continue; // For MC use HLTPhoton15 as the cleaned trigger is not in MC yet as of July 20, 2010
      if ( HLTFromRun[i] <= run ) {
 	//if(jentry == 0 ) STDOUT("run, i, HLTTrigger[i], HLTFromRun[i] = "<<run<<"\t"<<i<<"\t"<<"\t"<<HLTTrigger[i]<<"\t"<<HLTFromRun[i]);
	if (HLTTrigger[i] > 0 && HLTTrigger[i] < HLTResults->size() ) {
	  PassTrig=HLTResults->at(HLTTrigger[i]);
	  HLTTrgUsed=HLTTrigger[i];
	} else {
	  STDOUT("ERROR: HLTTrigger out of range of HLTResults: HLTTrigger = "<<HLTTrigger[i] <<"and HLTResults size = "<< HLTResults->size());
	}
      }
    }
    if(jentry == 0 ) STDOUT("Run = "<<run <<", HLTTrgUsed is number = "<<HLTTrgUsed<<" of the list HLTPathsOfInterest");

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_PtCut_IDISO_noOverlap;
    int heepBitMask;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {

	// Reject ECAL spikes
	if ( 1 - ElectronSCS4S1->at(iele) > 0.95 ) continue; 

	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	// get heepBitMask for EB, GAP, EE 
	if( fabs(ElectronEta->at(iele)) < eleEta_bar ) 
	  {
	    heepBitMask = heepBitMask_EB;
	  }
	else if ( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max ) 
	  {
	    heepBitMask = heepBitMask_EE;
	  }
	else {
	    heepBitMask = heepBitMask_GAP;
	}

	//ID + ISO + NO overlap with good muons 
	// int eleID = ElectronPassID->at(iele);
	// if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	if ( (ElectronHeepID->at(iele) & ~heepBitMask)==0x0  && ElectronOverlaps->at(iele)==0 )
	  {
	    //STDOUT("ElectronHeepID = " << hex << ElectronHeepID->at(iele) << " ; ElectronPassID = " << ElectronPassID->at(iele) )
	    v_idx_ele_PtCut_IDISO_noOverlap.push_back(iele);
	  }

      } // End loop over electrons

    // tight-loose electrons, if enabled from cut file
    if ( looseBitMask_enabled == 1 && v_idx_ele_PtCut_IDISO_noOverlap.size() == 1 )
      {
	//STDOUT("v_idx_ele_PtCut_IDISO_noOverlap[0] = "<<v_idx_ele_PtCut_IDISO_noOverlap[0] << " - Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]));
	bool loosePtLargerThanTightPt = true;
	for(int iele=0; iele<v_idx_ele_PtCut.size(); iele++)
	  {
	    
	    if (v_idx_ele_PtCut[iele] == v_idx_ele_PtCut_IDISO_noOverlap[0])
	      {
		loosePtLargerThanTightPt = false;
		continue;
	      }
	    // get looseBitMask for EB, GAP, EE 

	    int looseBitMask;
	    if( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_bar ) 
	      {
		looseBitMask = looseBitMask_EB;
	      }
	    else if ( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) > eleEta_end_min && fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_end_max ) 
	      {
		looseBitMask = looseBitMask_EE;
	      }
	    else {
	      looseBitMask = looseBitMask_GAP;
	    }
	    if ( (ElectronHeepID->at(v_idx_ele_PtCut[iele]) & ~looseBitMask)==0x0  && ElectronOverlaps->at(v_idx_ele_PtCut[iele])==0 )
	      {
		if ( loosePtLargerThanTightPt )
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.insert(v_idx_ele_PtCut_IDISO_noOverlap.begin(),1,v_idx_ele_PtCut[iele]);
		  }
		else 
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.push_back(v_idx_ele_PtCut[iele]);
		  }
		break; // happy with one loose electron - Note: if you want more than 1 loose, pt sorting will not be OK with the code as is. 
	      }
	  }	
// 	for ( int i=0; i<v_idx_ele_PtCut_IDISO_noOverlap.size(); i++)
// 	  {
// 	    STDOUT("i="<<i<<", v_idx_ele_PtCut_IDISO_noOverlap[i] = "<<v_idx_ele_PtCut_IDISO_noOverlap[i] << ", Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
// 	  }
      } // tight-loose electrons, if enabled from cut file


    // Muons
    vector<int> v_idx_muon_all;
    vector<int> v_idx_muon_PtCut;
    vector<int> v_idx_muon_PtCut_IDISO;
    
    // Loop over muons  
    for(int imuon=0; imuon<MuonPt->size(); imuon++){

      // no cut on reco muons
      v_idx_muon_all.push_back(imuon);

      if ( (*MuonPt)[imuon] < muon_PtCut) continue;

      // pT pre-cut on muons
      v_idx_muon_PtCut.push_back(imuon);
      
      if ( ((*MuonTrkHits)[imuon]  >= muNHits_minThresh  )&&( fabs((*MuonTrkD0)[imuon]) < muTrkD0Maximum ) &&((*MuonPassIso)[imuon]==1 ) &&((*MuonPassID)[imuon]==1) ) 
	{
	  v_idx_muon_PtCut_IDISO.push_back(imuon);
	}
    }// end loop over muons


    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
    vector<int> v_idx_jet_PtCut_noOverlap;
    vector<int> v_idx_jet_PtCut_noOverlap_ID;
    vector<int> v_idx_jet_PtCut_noOverlap_ID_EtaCut;

    // Loop over jets
    for(int ijet=0; ijet<JetPt->size(); ijet++)
      {
	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( JetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;
	v_idx_jet_PtCut.push_back(ijet);
      }

// 	//Checking overlap between electrons and jets
// 	int JetOverlapsWithEle = 0; //don't change the default (0) 
// 	float minDeltaR=9999.;
// 	TVector3 jet_vec;
// 	jet_vec.SetPtEtaPhi(JetPt->at(ijet),JetEta->at(ijet),JetPhi->at(ijet));
// 	for (int i=0; i < v_idx_ele_PtCut_IDISO_noOverlap.size(); i++){
// 	  TVector3 ele_vec;	  
// 	  ele_vec.SetPtEtaPhi(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i])
// 			      ,ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[i])
// 			      ,ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
// 	  double distance = jet_vec.DeltaR(ele_vec);
// 	  if (distance<minDeltaR) minDeltaR=distance;
// 	}
// 	if ( minDeltaR < getPreCutValue1("jet_ele_DeltaRcut") )
// 	  JetOverlapsWithEle = 1; //this jet overlaps with a good electron --> remove it from the analysis

// 	//pT pre-cut + no overlaps with electrons
// 	// ---- use the flag stored in rootTuples
// 	//if( ( JetOverlaps->at(ijet) & 1 << eleIDType) == 0)/* NO overlap with electrons */  
// 	// && (caloJetOverlaps[ijet] & 1 << 5)==0 )/* NO overlap with muons */   
// 	// ----
// 	if( JetOverlapsWithEle == 0 )  /* NO overlap with electrons */  
// 	  v_idx_jet_PtCut_noOverlap.push_back(ijet);

    vector <int> jetFlags(v_idx_jet_PtCut.size(), 0);
    int Njetflagged = 0;
    for (int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
      {
	TLorentzVector ele;
        ele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
			 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
			 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
			     JetEta->at(v_idx_jet_PtCut[ijet]),
			     JetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(ele);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_ele_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags[ijet_minDR] = 1;
	    Njetflagged++;
	  }
      }

//     // printouts for jet cleaning
//     STDOUT("CLEANING ----------- v_idx_ele_PtCut_IDISO_noOverlap.size = "<< v_idx_ele_PtCut_IDISO_noOverlap.size() <<", Njetflagged = "<< Njetflagged<<", diff="<< v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged );
//     if( (v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged) == 1 ) 
//       {
// 	TLorentzVector thisele;
// 	for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
// 	  {
// 	    thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
// 				 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
// 				 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
// 	    STDOUT("CLEANING: e"<<iele+1<<" Pt, eta, phi = "  << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi());
// 	  }
// 	TLorentzVector thisjet;
// 	for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
// 	  {
// 	    thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
// 				 JetEta->at(v_idx_jet_PtCut[ijet]),
// 				 JetPhi->at(v_idx_jet_PtCut[ijet]),0);
// 	    STDOUT("CLEANING: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<" jetFlags="<<jetFlags[ijet] );
// 	  }
//       } // printouts for jet cleaning
    
    // Flagging jets if they overlap with muons
    vector <int> jetFlags_muon(v_idx_jet_PtCut.size(), 0);
    int Njetflagged_muon = 0;
    for (int imuon=0; imuon<v_idx_muon_PtCut_IDISO.size(); imuon++)
      {
	TLorentzVector muon;
        muon.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[imuon]),
			  MuonEta->at(v_idx_muon_PtCut_IDISO[imuon]),
			  MuonPhi->at(v_idx_muon_PtCut_IDISO[imuon]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags_muon[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
			     JetEta->at(v_idx_jet_PtCut[ijet]),
			     JetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(muon);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_muon_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags_muon[ijet_minDR] = 1;
	    Njetflagged_muon++;
	  }
      }

    
    float JetEtaCutValue = getPreCutValue1("jet_EtaCut");
    for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++) //pT pre-cut + no overlaps with electrons + jetID
      {	
	bool passjetID = JetPassID->at(v_idx_jet_PtCut[ijet]);
	//bool passjetID = JetIdloose(CaloJetresEMF->at(v_idx_jet_PtCut[ijet]),CaloJetfHPD->at(v_idx_jet_PtCut[ijet]),CaloJetn90Hits->at(v_idx_jet_PtCut[ijet]), CaloJetEta->at(v_idx_jet_PtCut[ijet]));
	// ---- use the flag stored in rootTuples
	//if( (JetOverlaps->at(v_idx_jet_PtCut[ijet]) & 1 << eleIDType) == 0  /* NO overlap with electrons */  
	// ----

	if( jetFlags[ijet] == 0                            /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0 )                  /* NO overlap with muons */
	  //  && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                            /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0                    /* NO overlap with muons */
	    && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0                   /* NO overlap with muons */
	    && passjetID == true                             /* pass JetID */
	    && fabs( JetEta->at(v_idx_jet_PtCut[ijet]) ) < JetEtaCutValue )
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID_EtaCut.push_back(v_idx_jet_PtCut[ijet]);

	
	//NOTE: We should verify that caloJetOverlaps match with the code above
      } // End loop over jets
    


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

    // Set the value of the variableNames listed in the cutFile to their current value
    
    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;       
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;       
      }

    fillVariableWithValue( "PassHLT", PassTrig ) ;

    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    //    fillVariableWithValue( "PassHBHENoiseFilter", passLooseNoiseFilter ) ;

    // nMu
    fillVariableWithValue( "nMu_all", MuonPt->size() ) ;
    fillVariableWithValue( "nMu_PtCut", v_idx_muon_PtCut.size() ) ;
    fillVariableWithValue( "nMu_PtCut_IDISO", v_idx_muon_PtCut_IDISO.size() ) ;

    // nEle
    fillVariableWithValue( "nEle_all", v_idx_ele_all.size() ) ;
    fillVariableWithValue( "nEle_PtCut", v_idx_ele_PtCut.size() ) ;
    fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp", v_idx_ele_PtCut_IDISO_noOverlap.size() ) ;

    // nLeptons
    fillVariableWithValue( "nLept_PtCut_IDISO", v_idx_ele_PtCut_IDISO_noOverlap.size()+v_idx_muon_PtCut_IDISO.size() ) ;
     
    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size() ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp", v_idx_jet_PtCut_noOverlap.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp_ID", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    //OneEleOneMu
    fillVariableWithValue( "nJet_OneEleOneMu_All", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    fillVariableWithValue( "nJet_OneEleOneMu_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size() ) ;
    //PAS June 2010
    fillVariableWithValue( "nJet_PAS_All", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    fillVariableWithValue( "nJet_PAS_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size() ) ;

    // MET
    //PAS June 2010
    fillVariableWithValue( "MET_PAS", thisMET ) ;
    fillVariableWithValue( "METPhi_PAS", thisMETPhi);
    fillVariableWithValue( "pfMET_PAS", PFMET->at(0) ) ;
    fillVariableWithValue( "tcMET_PAS", TCMET->at(0) ) ;
    fillVariableWithValue( "caloMET_PAS", CaloMET->at(0) ) ;
    TVector2 v_MET;
    v_MET.SetMagPhi( thisMET , thisMETPhi);

    // 1st ele
    if( v_idx_ele_PtCut_IDISO_noOverlap.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stEle_IDISO_NoOvrlp", ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "Eta1stEle_IDISO_NoOvrlp", ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "mEta1stEle_IDISO_NoOvrlp", fabs(ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stEle_PAS", ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "Eta1stEle_PAS", ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
        fillVariableWithValue( "Phi1stEle_PAS", ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	// transverse mass ele+MET
	TVector2 v_ele;
	v_ele.SetMagPhi( ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) , ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	double deltaphi = v_MET.DeltaPhi(v_ele);
	double MT_eleMET = sqrt(2 * v_ele.Mod() * thisMET * (1 - cos(deltaphi)) );
	fillVariableWithValue("MT_eleMET", MT_eleMET);
      }

    // 1st muon
    if( v_idx_muon_PtCut_IDISO.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stMu_IDISO", MuonPt->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "Eta1stMu_IDISO", MuonEta->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "mEta1stMu_IDISO", fabs(MuonEta->at(v_idx_muon_PtCut_IDISO[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stMu_PAS", MuonPt->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "Eta1stMu_PAS", MuonEta->at(v_idx_muon_PtCut_IDISO[0]) );
        fillVariableWithValue( "Phi1stMu_PAS", MuonPhi->at(v_idx_muon_PtCut_IDISO[0]) );
	// transverse mass ele+MET
	TVector2 v_muon;
	v_muon.SetMagPhi( MuonPt->at(v_idx_muon_PtCut_IDISO[0]) , MuonPhi->at(v_idx_muon_PtCut_IDISO[0]) );
	double deltaphi = v_MET.DeltaPhi(v_muon);
	double MT_muonMET = sqrt(2 * v_muon.Mod() * thisMET * (1 - cos(deltaphi)) );
	fillVariableWithValue("MT_muonMET", MT_muonMET);
      }

    // 1st jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlp_ID", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "Eta1stJet_noOvrlp_ID", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "mEta1stJet_noOvrlp_ID", fabs(JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stJet_PAS", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "Eta1stJet_PAS", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
        fillVariableWithValue( "Phi1stJet_PAS", JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlp_ID", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "Eta2ndJet_noOvrlp_ID", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "mEta2ndJet_noOvrlp_ID", fabs(JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1])) );
	fillVariableWithValue( "maxMEtaJets_noOvrlp_ID", max( getVariableValue("mEta1stJet_noOvrlp_ID"), getVariableValue("mEta2ndJet_noOvrlp_ID") ) );
	//PAS June 2010
	fillVariableWithValue( "Pt2ndJet_PAS", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "Eta2ndJet_PAS", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
        fillVariableWithValue( "Phi2ndJet_PAS", JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
      }

    //## define "1ele+1muon" and "2jets" booleans
    bool OneEleOneMu=false;
    bool TwoJets=false;
    if( v_idx_ele_PtCut_IDISO_noOverlap.size() >= 1 && v_idx_muon_PtCut_IDISO.size() >= 1 ) OneEleOneMu = true;
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) TwoJets = true;

    // ST
    double calc_sT=-999.; 
    if ( (OneEleOneMu) && (TwoJets) ) 
      {
	calc_sT = 
	  ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) +
	  MuonPt->at(v_idx_muon_PtCut_IDISO[0]) +
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) +
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]);
	fillVariableWithValue("sT", calc_sT);
	fillVariableWithValue("sT_MLQ250", calc_sT);
	fillVariableWithValue("sT_MLQ280", calc_sT);
	fillVariableWithValue("sT_MLQ300", calc_sT);
	fillVariableWithValue("sT_MLQ320", calc_sT);
	fillVariableWithValue("sT_MLQ340", calc_sT);
	fillVariableWithValue("sT_MLQ400", calc_sT);       
	//PAS June 2010
	fillVariableWithValue("sT_PAS", calc_sT);
      }

    // ST jets
    if (TwoJets)
      {
	double calc_sTjet=-999.;
	calc_sTjet =
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) + 
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) ;
	fillVariableWithValue("sTjet_PAS", calc_sTjet);
      }

    // Mjj
    if (TwoJets)
      {
	TLorentzVector jet1, jet2, jj;
	jet1.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	jj = jet1+jet2;
	//PAS June 2010
	fillVariableWithValue("Mjj_PAS", jj.M());
      }


    // Memu
    if (OneEleOneMu)
      {
	fillVariableWithValue( "maxMEtaEleMu_IDISO", max( getVariableValue("mEta1stEle_IDISO_NoOvrlp"), getVariableValue("mEta1stMu_IDISO") ) );
	TLorentzVector ele1, mu1, emu;
	ele1.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),0);
	mu1.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonEta->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonPhi->at(v_idx_muon_PtCut_IDISO[0]),0);
	emu = ele1+mu1;
	fillVariableWithValue("Memu", emu.M());
	//OneEleOneMu
	fillVariableWithValue("Memu_OneEleOneMu", emu.M());
	fillVariableWithValue("Memu_presel", emu.M());
	//
	//PAS June 2010
	fillVariableWithValue("Memu_PAS", emu.M());

	double calc_sTemu=-999.;
        calc_sTemu =
	   ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) +
	   MuonPt->at(v_idx_muon_PtCut_IDISO[0]) ;
	fillVariableWithValue("sTemu_PAS", calc_sTemu);

	if(isData==true) 
	  {
	    STDOUT("OneEleOneMu: Run, LS, Event = "<<run<<", "<<ls<<", "<<event);
	    STDOUT("OneEleOneMu: M_emu, Pt_emu, Eta_emu, Phi_emu = "<<emu.M() <<", "<< emu.Pt() <<", "<< emu.Eta() <<", "<< emu.Phi());
	    STDOUT("OneEleOneMu: 1st ele  Pt, eta, phi = "<< ele1.Pt() <<", "<< ele1.Eta() <<", "<< ele1.Phi() );
	    STDOUT("OneEleOneMu: 1st muon Pt, eta, phi = "<< mu1.Pt() <<", "<< mu1.Eta() <<", "<< mu1.Phi() );
	  }
      }

    // Mlj 
    double Me1j1, Me1j2, Mm1j1, Mm1j2 = -999;
    double deltaM_e1j1_m1j2 = 9999;
    double deltaM_e1j2_m1j1 = 9999;
    double Mlj_1stPair = 0;
    double Mlj_2ndPair = 0;
    double deltaR_e1j1 ;
    double deltaR_m1j2 ;
    double deltaR_e1j2 ;
    double deltaR_m1j1 ;
    if ( (OneEleOneMu) && (TwoJets) ) // OneEleOneMu and TwoJets
      {
	TLorentzVector jet1, jet2, ele1, mu1;
	ele1.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),0);
	mu1.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonEta->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonPhi->at(v_idx_muon_PtCut_IDISO[0]),0);
	jet1.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	TLorentzVector e1j1, e1j2, m1j1, m1j2;
	e1j1 = ele1 + jet1;
	m1j2 =  mu1 + jet2;
	m1j1 =  mu1 + jet1;
	e1j2 = ele1 + jet2;
	Me1j1 = e1j1.M();
	Mm1j2 = m1j2.M();
	Me1j2 = e1j2.M();
	Mm1j1 = m1j1.M();

	deltaM_e1j1_m1j2 = Me1j1 - Mm1j2;
	deltaM_e1j2_m1j1 = Me1j2 - Mm1j1;


	double deltaR_e1j1 = ele1.DeltaR(jet1);
	double deltaR_m1j2 =  mu1.DeltaR(jet2);
	double deltaR_e1j2 = ele1.DeltaR(jet2);
	double deltaR_m1j1 =  mu1.DeltaR(jet1);

// 	// Fill min DR between any of the 2 selected eles and any of the 2 selected jets
// 	double minDR_2ele_2jet = min ( min(deltaR_e1j1,deltaR_m1j2) , min(deltaR_e1j2,deltaR_m1j1) );
// 	fillVariableWithValue("minDR_2ele_2jet", minDR_2ele_2jet);

	if(fabs(deltaM_e1j1_m1j2) > fabs(deltaM_e1j2_m1j1))
	  {
	    Mlj_1stPair = Me1j2;
	    Mlj_2ndPair = Mm1j1;
	    fillVariableWithValue("minDRlj_selecPairs", min(deltaR_e1j2,deltaR_m1j1) );
	    fillVariableWithValue("minDRlj_unselPairs", min(deltaR_e1j1,deltaR_m1j2) );
	  }
	else
	  {
	    Mlj_1stPair = Me1j1;
	    Mlj_2ndPair = Mm1j2;
	    fillVariableWithValue("minDRlj_selecPairs", min(deltaR_e1j1,deltaR_m1j2) );
	    fillVariableWithValue("minDRlj_unselPairs", min(deltaR_e1j2,deltaR_m1j1) );
	  } 
	fillVariableWithValue("Mlj_1stPair", Mlj_1stPair);       
	fillVariableWithValue("Mlj_2ndPair", Mlj_2ndPair);
	//PAS June 2010
	h_Mlj_PAS->Fill(Mlj_1stPair);
	h_Mlj_PAS->Fill(Mlj_2ndPair);
	fillVariableWithValue("Mlj_1stPair_PAS", Mlj_1stPair);       
	fillVariableWithValue("Mlj_2ndPair_PAS", Mlj_2ndPair);

	// min and max DeltaR between electrons and any jet
	double minDeltaR_lj = 999999;
	double maxDeltaR_lj = -1;
	double thisMinDR, thisMaxDR, DR_thisjet_e1, DR_thisjet_m1;
	TLorentzVector thisjet;
	for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	  {
	    thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 JetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	    DR_thisjet_e1 = thisjet.DeltaR(ele1);
	    DR_thisjet_m1 = thisjet.DeltaR(mu1);
	    thisMinDR = min(DR_thisjet_e1, DR_thisjet_m1);
	    thisMaxDR = max(DR_thisjet_e1, DR_thisjet_m1);
	    if(thisMinDR < minDeltaR_lj)
	      minDeltaR_lj = thisMinDR;
	    if(thisMaxDR > maxDeltaR_lj)
	      maxDeltaR_lj = thisMaxDR;
	  } 
	fillVariableWithValue("minDeltaR_lj", minDeltaR_lj);
	fillVariableWithValue("maxDeltaR_lj", maxDeltaR_lj);

	// printouts for small Mlj
	if(isData==true && ( Mlj_1stPair<20 || Mlj_2ndPair<20 ) ) // printouts for low Mlj 
	  {
	    STDOUT("Mlj<20GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	    STDOUT("Mlj<20GeV: Mlj_1stPair = "<<Mlj_1stPair <<", Mlj_2ndPair = "<< Mlj_2ndPair );
	    STDOUT("Mlj<20GeV: e1j1.M = "<<e1j1.M() <<", m1j2.M = "<<m1j2.M() <<", e1j2.M = "<<e1j2.M()  <<", m1j1.M = "<<m1j1.M()  );
	    STDOUT("Mlj<20GeV: deltaM_e1j1_m1j2 = "<<deltaM_e1j1_m1j2 <<", deltaM_e1j2_m1j1 = "<<deltaM_e1j2_m1j1  );
	    STDOUT("Mlj<20GeV: deltaR_e1j1 = "<<deltaR_e1j1 <<", deltaR_m1j2 = "<<deltaR_m1j2 <<", deltaR_e1j2 = "<<deltaR_e1j2  <<", deltaR_m1j1 = "<<deltaR_m1j1  );
	    TLorentzVector thisele;
	    // Add printout for muons?
	    for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
	      {
		thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
				     ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
				     ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
		STDOUT("Mlj<20GeV: e"<<iele+1<<" Pt, eta, phi = " 
		       << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi()<<"; DR_j1, DR_j2 = "<< thisele.DeltaR(jet1)<<", "<<thisele.DeltaR(jet2));
	      }
	    TLorentzVector thisjet;
	    TLorentzVector thisjet_e1, thisjet_m1;
	    for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	      {
		thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				     JetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				     JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
		thisjet_e1 = thisjet + ele1;
		thisjet_m1 = thisjet +  mu1;
		STDOUT("Mlj<20GeV: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<"; DR_e1, DR_m1 = "<< thisjet.DeltaR(ele1)<<", "<<thisjet.DeltaR(mu1) << "; M_e1, M_m1 = " <<thisjet_e1.M() <<", "<<thisjet_m1.M() );
	      }
	  } // printouts for low Mlj 

      } // OneEleOneMu and TwoJets



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

    // Fill histograms and do analysis based on cut evaluation
    //h_nEleFinal->Fill( ElectronPt->size() );
     

    // printouts for OneEleOneMuTwoJets
    if( isData==true && passedAllPreviousCuts("Memu") ) 
      {
	STDOUT("OneEleOneMuTwoJets: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	STDOUT("OneEleOneMuTwoJets: sT, Memu, Mjj_PAS = "******"sT") <<", "<< getVariableValue("Memu")<<", "<< getVariableValue("Mjj_PAS") );
	STDOUT("OneEleOneMuTwoJets: Mlj_1stPair, Mlj_2ndPair = "<< getVariableValue("Mlj_1stPair")<<", "<< getVariableValue("Mlj_2ndPair") );
	STDOUT("OneEleOneMuTwoJets: 1stEle Pt, eta, phi = "<<getVariableValue("Pt1stEle_PAS") <<", "<< getVariableValue("Eta1stEle_PAS") <<", "<< getVariableValue("Phi1stEle_PAS") );
	STDOUT("OneEleOneMuTwoJets: 1stMu  Pt, eta, phi = "<<getVariableValue("Pt1stMu_PAS") <<", "<< getVariableValue("Eta1stMu_PAS") <<", "<< getVariableValue("Phi1stMu_PAS") );
	STDOUT("OneEleOneMuTwoJets: 1stJet Pt, eta, phi = "<<getVariableValue("Pt1stJet_PAS") <<", "<< getVariableValue("Eta1stJet_PAS") <<", "<< getVariableValue("Phi1stJet_PAS") );
	STDOUT("OneEleOneMuTwoJets: 2ndJet Pt, eta, phi = "<<getVariableValue("Pt2ndJet_PAS") <<", "<< getVariableValue("Eta2ndJet_PAS") <<", "<< getVariableValue("Phi2ndJet_PAS") );
	STDOUT("OneEleOneMuTwoJets: minDRlj_selecPairs, minDRlj_unselPairs = "<<getVariableValue("minDRlj_selecPairs") <<", "<< getVariableValue("minDRlj_unselPairs") );
// 	if ( passedCut("Mee") )
// 	  {
// 	    STDOUT("PassedMeeAndAllPrevious: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event<<", sT = "<< getVariableValue("sT"));
// 	  }
      } // printouts for OneEleOneMuTwoJets:

    
    //INFO
    //      // retrieve value of previously filled variables (after making sure that they were filled)
    //      double totpTEle;
    //      if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
    //        totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");
    //      // reject events that did not pass level 0 cuts
    //      if( !passedCut("0") ) continue;
    //      // ......

        
    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

  h_Mlj_PAS->Write();

  ////////////////////// User's code to write histos - END ///////////////////////
  
  
  //STDOUT("analysisClass::Loop() ends");   
}
void analysisClass::Loop(){

  std::cout << "analysisClass::Loop() begins" <<std::endl;   
  if (fChain == 0) return;
  
  //--------------------------------------------------------------------------
  // Verbose? Or not?
  //--------------------------------------------------------------------------
  
  bool verbose = !true;
  
  //--------------------------------------------------------------------------
  // Decide which plots to save (default is to save everything)
  //--------------------------------------------------------------------------
  
  fillSkim                         ( !true  ) ;
  fillAllPreviousCuts              ( !true  ) ;
  fillAllOtherCuts                 ( !true  ) ;
  fillAllSameLevelAndLowerLevelCuts( !true  ) ;
  fillAllCuts                      ( !true  ) ;

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Get all Pre-cut values!
   *
   *
   *
   *///-----------------------------------------------------------------

  //--------------------------------------------------------------------------
  // Cuts for physics objects selection
  //--------------------------------------------------------------------------

  // jet cuts
  double jet_PtCut               = getPreCutValue1("jet_PtCut");
  double jet_EtaCut              = getPreCutValue1("jet_EtaCut");
  double jet_ele_DeltaRCut       = getPreCutValue1("jet_ele_DeltaRCut") ;
  double jet_muon_DeltaRCut      = getPreCutValue1("jet_muon_DeltaRCut");
  double jet_hltMatch_DeltaRCut  = getPreCutValue1("jet_hltMatch_DeltaRCut");

  // muon cuts
  double muon_EtaCut             = getPreCutValue1("muon_EtaCut");
  double muon_PtCut              = getPreCutValue1("muon_PtCut");
  double muon_hltMatch_DeltaRCut = getPreCutValue1("muon_hltMatch_DeltaRCut");

  // electron cuts
  double ele_PtCut    	         = getPreCutValue1("ele_PtCut");
  double ele_hltMatch_DeltaRCut  = getPreCutValue1("ele_hltMatch_DeltaRCut");

  //--------------------------------------------------------------------------
  // Tell the user how many entries we'll look at
  //--------------------------------------------------------------------------

  Long64_t nentries = fChain->GetEntries();
  // Long64_t nentries = 1000;
  std::cout << "analysisClass::Loop(): nentries = " << fChain -> GetEntries() << std::endl;   
  
  //--------------------------------------------------------------------------
  // Create HLT collections in advance (won't need all of them)
  //--------------------------------------------------------------------------
  
  // Signal
  CollectionPtr c_hltEle30_Signal_all;
  CollectionPtr c_hltPFJetNoPU25_Signal_all;
  CollectionPtr c_hltPFJetNoPU100_Signal_all;
  CollectionPtr c_hltDoubleEle_Signal_all;

  // Tag and probe
  CollectionPtr c_hltEle27WP80_all;

  //--------------------------------------------------------------------------
  // Create historgams
  //--------------------------------------------------------------------------

  CreateUserTH1D( "nEle_all"              , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_pass_ejj"         , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_pass_eejj_veto"   , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_pass_eejj_noveto" , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_pass_enujj_veto"  , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_pass_enujj_noveto", 6, -0.5, 5.5 );
  
  CreateUserTH1D( "nEle_ele1Pass"         , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_ele2Pass_eejj"    , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_passVeto_enujj"   , 6, -0.5, 5.5 );
  CreateUserTH1D( "nEle_passVeto_eejj"    , 6, -0.5, 5.5 );
  CreateUserTH1D( "nJet_jet1Pass"         , 17, -0.5, 16.5 );
  CreateUserTH1D( "nJet_jet2Pass"         , 17, -0.5, 16.5 );  
  CreateUserTH1D( "MET_metPass_enujj"     , 200, 0, 2000 );

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Start analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------
  
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) {
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    
    //-----------------------------------------------------------------
    // Print progress
    //-----------------------------------------------------------------
    
    if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
    
    //-----------------------------------------------------------------
    // Get access to HLT decisions
    //-----------------------------------------------------------------

    getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ; 
        
    //-----------------------------------------------------------------
    // Get access to HLT filter objects
    //-----------------------------------------------------------------
    
    HLTFilterObjectCollectionHelper helper (*this);
    
    c_hltEle30_Signal_all        = helper.GetHLTFilterObjects("hltEle30CaloIdVTTrkIdTDphiFilter");
    c_hltPFJetNoPU25_Signal_all  = helper.GetHLTFilterObjects("hltEle30CaloIdVTTrkIdTDiCentralPFNoPUJet25EleCleaned");
    c_hltPFJetNoPU100_Signal_all = helper.GetHLTFilterObjects("hltEle30CaloIdVTTrkIdTDiCentralPFNoPUJet100EleCleaned");
    c_hltDoubleEle_Signal_all    = helper.GetHLTFilterObjects("hltDiEle33CaloIdLGsfTrkIdVLDPhiDoubleFilter");
    
    //-----------------------------------------------------------------
    // Define initial, inclusive collections for physics objects
    //-----------------------------------------------------------------
    
    CollectionPtr c_ele_all   ( new Collection(*this, ElectronPt -> size()));
    CollectionPtr c_muon_all  ( new Collection(*this, MuonPt     -> size()));
    CollectionPtr c_pfjet_all ( new Collection(*this, PFJetPt    -> size()));
    
    //-----------------------------------------------------------------
    // ID electrons
    //-----------------------------------------------------------------

    CollectionPtr c_ele_final;
    CollectionPtr c_ele_final_ptCut;
    
    CollectionPtr c_ele_HEEP  = c_ele_all -> SkimByID <Electron> ( HEEP );
    c_ele_final               = c_ele_HEEP;
    c_ele_final_ptCut         = c_ele_final -> SkimByMinPt<Electron>( ele_PtCut  );
    
    //-----------------------------------------------------------------
    // ID muons
    //-----------------------------------------------------------------
    
    CollectionPtr c_muon_eta2p1      = c_muon_all       -> SkimByEtaRange<Muon> ( -muon_EtaCut, muon_EtaCut );
    CollectionPtr c_muon_eta2p1_ID   = c_muon_eta2p1    -> SkimByID      <Muon> ( MUON_TIGHT_PFISO04 );
    CollectionPtr c_muon_final       = c_muon_eta2p1_ID;
    CollectionPtr c_muon_final_ptCut = c_muon_final     -> SkimByMinPt   <Muon> ( muon_PtCut );
    
    //-----------------------------------------------------------------
    // ID jets
    //-----------------------------------------------------------------
    
    CollectionPtr c_pfjet_central                     = c_pfjet_all                          -> SkimByEtaRange   <PFJet>          ( -jet_EtaCut, jet_EtaCut   );
    CollectionPtr c_pfjet_central_ID                  = c_pfjet_central                      -> SkimByID         <PFJet>          ( PFJET_LOOSE );    
    CollectionPtr c_pfjet_central_ID_noMuonOverlap    = c_pfjet_central_ID                   -> SkimByVetoDRMatch<PFJet, Muon>    ( c_muon_final_ptCut   , jet_ele_DeltaRCut  );
    CollectionPtr c_pfjet_central_ID_noLeptonOverlap  = c_pfjet_central_ID_noMuonOverlap     -> SkimByVetoDRMatch<PFJet, Electron>( c_ele_final_ptCut    , jet_muon_DeltaRCut );
    CollectionPtr c_pfjet_final                       = c_pfjet_central_ID_noLeptonOverlap;
    CollectionPtr c_pfjet_final_ptCut                 = c_pfjet_final                        -> SkimByMinPt      <PFJet>          ( jet_PtCut );
    
    //------------------------------------------------------------------
    // Map triggers to decisions and prescales
    //------------------------------------------------------------------

    getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ; 

    //------------------------------------------------------------------
    // Get JSON and trigger decisions
    //------------------------------------------------------------------
    
    bool passed_json = passJSON ( run, ls , isData );
    bool trigger_fired = triggerFired ( "HLT_Ele30_CaloIdVT_TrkIdT_PFNoPUJet100_PFNoPUJet25_v8" );
    
    //-----------------------------------------------------------------
    // How many ID'd objects are there?
    //-----------------------------------------------------------------
    
    int n_ele   = c_ele_final   -> GetSize();
    int n_jet   = c_pfjet_final -> GetSize();

    //-----------------------------------------------------------------
    // Get ready to fill variables 
    //-----------------------------------------------------------------

    resetCuts();
    
    //------------------------------------------------------------------
    // Fill cut values
    //------------------------------------------------------------------

    fillVariableWithValue ( "PassJSON"    , int ( passed_json    ) );
    fillVariableWithValue ( "PassTrigger" , int ( trigger_fired  ) );
        
    //-----------------------------------------------------------------
    // Evaluate the cuts
    //-----------------------------------------------------------------    
    
    evaluateCuts();

    //-----------------------------------------------------------------    
    // Did we pass the minimum?
    //-----------------------------------------------------------------    
    
    bool pass_minimum = passedCut( "PassJSON" ) && passedCut ( "PassTrigger" );

    //-----------------------------------------------------------------    
    // Declare purity requirements
    //-----------------------------------------------------------------    

    bool jet1_pass              = false;
    bool jet2_pass              = false;
    bool ele1_pass              = false;
    bool ele2_pass_eejj         = false;
    bool met_pass_enujj         = false;
    bool ele_pass_veto_enujj    = false;
    bool ele_pass_veto_eejj     = false;

    bool passAll_ejj            = false;
    bool passAll_eejj_veto      = false;
    bool passAll_eejj_noveto    = false;
    bool passAll_enujj_veto     = false;
    bool passAll_enujj_noveto   = false;
    
    //-----------------------------------------------------------------    
    // Evaluate purity requirements
    //-----------------------------------------------------------------    
    
    // electrons

    if ( n_ele >= 1 ) { 
      Electron ele1 = c_ele_final -> GetConstituent<Electron>(0);
      if ( ele1.Pt() > 45. ) { 
	ele1_pass  = true;
      }
    }

    if ( n_ele >= 2 ) { 
      Electron ele2 = c_ele_final -> GetConstituent<Electron>(1);
      if ( ele2.Pt() > 45. ) ele2_pass_eejj = true;
    }

    if ( n_ele == 1 ) ele_pass_veto_enujj = true;
    if ( n_ele == 2 ) ele_pass_veto_eejj  = true;
    
    // jets ( same for both analyses ) 
    

    if ( n_jet >= 1 ){
      PFJet jet1 = c_pfjet_final -> GetConstituent<PFJet>(0);
      if ( jet1.Pt () >= 125. ) jet1_pass = true;
    }
    
    if ( n_jet >= 2 ){
      PFJet jet2 = c_pfjet_final -> GetConstituent<PFJet>(1);
      if ( jet2.Pt () >= 45. ) jet2_pass = true;
    }

    if ( PFMETType01XYCor -> at (0) > 45. ) met_pass_enujj = true;

    //-----------------------------------------------------------------    
    // Combine eejj purity requirements
    //-----------------------------------------------------------------    
    
    if ( ele1_pass           &&
	 jet1_pass           && 
	 jet2_pass           ){
      passAll_ejj          = true;
    }

    if ( ele1_pass           &&
	 ele2_pass_eejj      && 
	 jet1_pass           && 
	 jet2_pass           ){
      passAll_eejj_noveto  = true;
    }

    if ( ele1_pass           &&
	 ele2_pass_eejj      && 
	 ele_pass_veto_eejj  && 
	 jet1_pass           && 
	 jet2_pass           ){
      passAll_eejj_veto    = true;
    }

    if ( ele1_pass           &&
	 met_pass_enujj      && 
	 jet1_pass           && 
	 jet2_pass           ){
      passAll_enujj_noveto = true;
    }

    if ( ele1_pass           &&
	 ele_pass_veto_enujj && 
	 met_pass_enujj      && 
	 jet1_pass           && 
	 jet2_pass           ){
      passAll_enujj_veto   = true;
    }
    
    //-----------------------------------------------------------------    
    // Act on outcome of purity requirements
    //-----------------------------------------------------------------    
    
    FillUserTH1D ( "nEle_all" , n_ele );
    
    if ( passAll_ejj          ) FillUserTH1D ( "nEle_pass_ejj"          , n_ele );
    if ( passAll_eejj_veto    ) FillUserTH1D ( "nEle_pass_eejj_veto"    , n_ele );
    if ( passAll_eejj_noveto  ) FillUserTH1D ( "nEle_pass_eejj_noveto"  , n_ele );
    if ( passAll_enujj_veto   ) FillUserTH1D ( "nEle_pass_enujj_veto"   , n_ele );
    if ( passAll_enujj_noveto ) FillUserTH1D ( "nEle_pass_enujj_noveto" , n_ele );
    					                               
    if ( met_pass_enujj       ) FillUserTH1D ( "MET_metPass_enujj"      , PFMETType01XYCor -> at (0) );
    if ( jet1_pass            ) FillUserTH1D ( "nJet_jet1Pass"          , n_jet );
    if ( jet2_pass            ) FillUserTH1D ( "nJet_jet2Pass"          , n_jet );
    if ( ele1_pass            ) FillUserTH1D ( "nEle_ele1Pass"          , n_ele );
    if ( ele2_pass_eejj       ) FillUserTH1D ( "nEle_ele2Pass_eejj"     , n_ele );
    if ( ele_pass_veto_enujj  ) FillUserTH1D ( "nEle_passVeto_enujj"    , n_ele ); 
    if ( ele_pass_veto_eejj   ) FillUserTH1D ( "nEle_passVeto_eejj"     , n_ele ); 
    
  }

  std::cout << "analysisClass::Loop() ends" <<std::endl;   
  
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;
   
  ////////////////////// User's code to book histos - BEGIN ///////////////////////

  TH1F *h_Mej_PAS = new TH1F ("h_Mej_PAS","h_Mej_PAS",200,0,2000);  h_Mej_PAS->Sumw2();

  ////////////////////// User's code to book histos - END ///////////////////////

  ////////////////////// User's code to get preCut values - BEGIN ///////////////

  double eleEta_bar = getPreCutValue1("eleEta_bar");
  double eleEta_end_min = getPreCutValue1("eleEta_end");
  double eleEta_end_max = getPreCutValue2("eleEta_end");

  double EleEnergyScale_EB=getPreCutValue1("EleEnergyScale_EB");
  double EleEnergyScale_EE=getPreCutValue1("EleEnergyScale_EE");
  double JetEnergyScale=getPreCutValue1("JetEnergyScale");

  // Not used when using ElectronHeepID and heepBitMask // int eleIDType = (int) getPreCutValue1("eleIDType");
  int heepBitMask_EB  =  getPreCutValue1("heepBitMask_EBGapEE") ;
  int heepBitMask_GAP =  getPreCutValue2("heepBitMask_EBGapEE") ;

  int heepBitMask_EE  =  getPreCutValue3("heepBitMask_EBGapEE") ;

  int looseBitMask_EB       =  getPreCutValue1("looseBitMask_EBGapEE") ;
  int looseBitMask_GAP      =  getPreCutValue2("looseBitMask_EBGapEE") ;
  int looseBitMask_EE       =  getPreCutValue3("looseBitMask_EBGapEE") ;
  int looseBitMask_enabled  =  getPreCutValue4("looseBitMask_EBGapEE") ;

  double muon_PtCut = getPreCutValue1("muon_PtCut");
  double muFidRegion = getPreCutValue1("muFidRegion"); // currently unused !!!
  double muNHits_minThresh = getPreCutValue1("muNHits_minThresh");
  double muTrkD0Maximum = getPreCutValue1("muTrkD0Maximum");

  double BarrelCross = getPreCutValue1("fakeRate_Barrel");
  double BarrelSlope = getPreCutValue2("fakeRate_Barrel");
  double EndcapCross = getPreCutValue1("fakeRate_Endcap");
  double EndcapSlope = getPreCutValue2("fakeRate_Endcap");

  ////////////////////// User's code to get preCut values - END /////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    //for (Long64_t jentry=0; jentry<10000;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //if (PtHat>=30) continue;

    // EES and JES
    if( EleEnergyScale_EB != 1 || EleEnergyScale_EE != 1 )
      {
	for(int iele=0; iele<SuperClusterPt->size(); iele++)
	  {
	    if( fabs(SuperClusterEta->at(iele)) < eleEta_bar )
	      SuperClusterPt->at(iele) *= EleEnergyScale_EB;
	    if( fabs(SuperClusterEta->at(iele)) > eleEta_end_min && fabs(SuperClusterEta->at(iele)) < eleEta_end_max )
	      SuperClusterPt->at(iele) *= EleEnergyScale_EE;
	  }
      }
    if( JetEnergyScale != 1 )
      {
	for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
	  {
	    CaloJetPt->at(ijet) *= JetEnergyScale;
	  }
      }

    //## HLT
    int PassTrig = 0;
    int HLTFromRun[4] = {getPreCutValue1("HLTFromRun"),
			 getPreCutValue2("HLTFromRun"),
			 getPreCutValue3("HLTFromRun"),
			 getPreCutValue4("HLTFromRun")};
    int HLTTrigger[4] = {getPreCutValue1("HLTTrigger"),
			 getPreCutValue2("HLTTrigger"),
			 getPreCutValue3("HLTTrigger"),
			 getPreCutValue4("HLTTrigger")};
    int HLTTrgUsed;
    for (int i=0; i<4; i++) {
      if ( !isData && i != 0) continue; // For MC use HLTPhoton15 as the cleaned trigger is not in MC yet as of July 20, 2010
      if ( HLTFromRun[i] <= run ) {
 	//if(jentry == 0 ) STDOUT("run, i, HLTTrigger[i], HLTFromRun[i] = "<<run<<"\t"<<i<<"\t"<<"\t"<<HLTTrigger[i]<<"\t"<<HLTFromRun[i]);
	if (HLTTrigger[i] > 0 && HLTTrigger[i] < HLTResults->size() ) {
	  PassTrig=HLTResults->at(HLTTrigger[i]);
	  HLTTrgUsed=HLTTrigger[i];
	} else {
	  STDOUT("ERROR: HLTTrigger out of range of HLTResults: HLTTrigger = "<<HLTTrigger[i] <<"and HLTResults size = "<< HLTResults->size());
	}
      }
    }
    if(jentry == 0 ) STDOUT("Run = "<<run <<", HLTTrgUsed is number = "<<HLTTrgUsed<<" of the list HLTPathsOfInterest");
    
    // Superclusters
    vector<int> v_idx_sc_all;
    vector<int> v_idx_sc_PtCut;
    vector<int> v_idx_sc_Iso;
    
    //Create vector with indices of supercluster ordered by pT
    vector<pair<size_t, myiter> > order(SuperClusterPt->size());
    size_t n = 0;
    for (myiter it = SuperClusterPt->begin(); it != SuperClusterPt->end(); ++it, ++n)
      order[n] = make_pair(n, it);
    sort(order.begin(), order.end(), ordering());
    
    for(int isc=0; isc<order.size(); isc++)
      {
	// 	cout << "index , pT: " 
	// 	     << order[isc].first 
	// 	     << " , " 
	// 	     << *order[isc].second 
	// 	     << endl;
	v_idx_sc_all.push_back(order[isc].first); //### All superclusters ordered by pT
      }
    
    for(int isc=0;isc<v_idx_sc_all.size();isc++){

      //pT cut + ECAL acceptance cut + remove spikes (all together)
      if ( 1 - SuperClusterS4S1->at(v_idx_sc_all[isc]) > 0.95 ) continue;  

      bool Barrel = false;
      bool Endcap = false;
      if (fabs(SuperClusterEta->at(v_idx_sc_all[isc]))<eleEta_bar) Barrel = true;
      if ((fabs(SuperClusterEta->at(v_idx_sc_all[isc]))<eleEta_end_max)
	  &&(fabs(SuperClusterEta->at(v_idx_sc_all[isc]))>eleEta_end_min)) Endcap = true;
      if ( !Barrel && !Endcap) continue;

      bool PassPt = false;
      if ( SuperClusterPt->at(v_idx_sc_all[isc]) > getPreCutValue1("ele_PtCut") ) PassPt=true;
      if ( !PassPt ) continue;

      v_idx_sc_PtCut.push_back(v_idx_sc_all[isc]); //### Pt cut (+ no gaps + no spikes)

      //ID+Isolation together
      bool PassHoE = false;
      if ( SuperClusterHoE->at(v_idx_sc_all[isc])<0.05) PassHoE=true;
      if ( !PassHoE ) continue;

      bool PassEcalIso = false;
      if (Barrel && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc]) <(6+(0.01*SuperClusterPt->at(v_idx_sc_all[isc])))) 
	PassEcalIso=true;
      if (Endcap && SuperClusterPt->at(v_idx_sc_all[isc])<50 
	  && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc])<(6+(0.01*SuperClusterPt->at(v_idx_sc_all[isc])))) 
	PassEcalIso=true;
      if (Endcap && SuperClusterPt->at(v_idx_sc_all[isc])>=50 
	  && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc])<(6+(0.01*(SuperClusterPt->at(v_idx_sc_all[isc])-50)))) 
	PassEcalIso=true;
      if ( !PassEcalIso ) continue;

      v_idx_sc_Iso.push_back(v_idx_sc_all[isc]); //### Pt cut + ID+ISO

    }

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_PtCut_IDISO_noOverlap;
    int heepBitMask;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {

	// Reject ECAL spikes
	if ( 1 - ElectronSCS4S1->at(iele) > 0.95 ) continue; 

	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	// get heepBitMask for EB, GAP, EE 
	if( fabs(ElectronEta->at(iele)) < eleEta_bar ) 
	  {
	    heepBitMask = heepBitMask_EB;
	  }
	else if ( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max ) 
	  {
	    heepBitMask = heepBitMask_EE;
	  }
	else {
	  heepBitMask = heepBitMask_GAP;
	}

	//ID + ISO + NO overlap with good muons 
	// int eleID = ElectronPassID->at(iele);
	// if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	if ( (ElectronHeepID->at(iele) & ~heepBitMask)==0x0  && ElectronOverlaps->at(iele)==0 )
	  {
	    //STDOUT("ElectronHeepID = " << hex << ElectronHeepID->at(iele) << " ; ElectronPassID = " << ElectronPassID->at(iele) )
	    v_idx_ele_PtCut_IDISO_noOverlap.push_back(iele);
	  }

      } // End loop over electrons

    // tight-loose electrons, if enabled from cut file
    if ( looseBitMask_enabled == 1 && v_idx_ele_PtCut_IDISO_noOverlap.size() == 1 )
      {
	//STDOUT("v_idx_ele_PtCut_IDISO_noOverlap[0] = "<<v_idx_ele_PtCut_IDISO_noOverlap[0] << " - Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]));
	bool loosePtLargerThanTightPt = true;
	for(int iele=0; iele<v_idx_ele_PtCut.size(); iele++)
	  {
	    
	    if (v_idx_ele_PtCut[iele] == v_idx_ele_PtCut_IDISO_noOverlap[0])
	      {
		loosePtLargerThanTightPt = false;
		continue;
	      }
	    // get looseBitMask for EB, GAP, EE 

	    int looseBitMask;
	    if( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_bar ) 
	      {
		looseBitMask = looseBitMask_EB;
	      }
	    else if ( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) > eleEta_end_min && fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_end_max ) 
	      {
		looseBitMask = looseBitMask_EE;
	      }
	    else {
	      looseBitMask = looseBitMask_GAP;
	    }
	    if ( (ElectronHeepID->at(v_idx_ele_PtCut[iele]) & ~looseBitMask)==0x0  && ElectronOverlaps->at(v_idx_ele_PtCut[iele])==0 )
	      {
		if ( loosePtLargerThanTightPt )
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.insert(v_idx_ele_PtCut_IDISO_noOverlap.begin(),1,v_idx_ele_PtCut[iele]);
		  }
		else 
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.push_back(v_idx_ele_PtCut[iele]);
		  }
		break; // happy with one loose electron - Note: if you want more than 1 loose, pt sorting will not be OK with the code as is. 
	      }
	  }	
	// 	for ( int i=0; i<v_idx_ele_PtCut_IDISO_noOverlap.size(); i++)
	// 	  {
	// 	    STDOUT("i="<<i<<", v_idx_ele_PtCut_IDISO_noOverlap[i] = "<<v_idx_ele_PtCut_IDISO_noOverlap[i] << ", Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
	// 	  }
      } // tight-loose electrons, if enabled from cut file

    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
    vector<int> v_idx_jet_PtCut_noOverlap;
    vector<int> v_idx_jet_PtCut_noOverlap_ID;
    vector<int> v_idx_jet_PtCut_noOverlap_ID_EtaCut;

    // Loop over jets
    for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
      {
	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( CaloJetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;
	v_idx_jet_PtCut.push_back(ijet);
      }

    vector <int> jetFlags(v_idx_jet_PtCut.size(), 0);
    int Njetflagged = 0;
    for (int isc=0; isc<v_idx_sc_Iso.size(); isc++)
      {
	TLorentzVector sc;
        sc.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[isc]),
			SuperClusterEta->at(v_idx_sc_Iso[isc]),
			SuperClusterPhi->at(v_idx_sc_Iso[isc]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
			     CaloJetEta->at(v_idx_jet_PtCut[ijet]),
			     CaloJetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(sc);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_ele_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags[ijet_minDR] = 1;
	    Njetflagged++;
	  }
      }

    //     // printouts for jet cleaning
    //     STDOUT("CLEANING ----------- v_idx_ele_PtCut_IDISO_noOverlap.size = "<< v_idx_ele_PtCut_IDISO_noOverlap.size() <<", Njetflagged = "<< Njetflagged<<", diff="<< v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged );
    //     if( (v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged) == 1 ) 
    //       {
    // 	TLorentzVector thisele;
    // 	for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
    // 	  {
    // 	    thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
    // 				 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
    // 				 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
    // 	    STDOUT("CLEANING: e"<<iele+1<<" Pt, eta, phi = "  << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi());
    // 	  }
    // 	TLorentzVector thisjet;
    // 	for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
    // 	  {
    // 	    thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
    // 				 CaloJetEta->at(v_idx_jet_PtCut[ijet]),
    // 				 CaloJetPhi->at(v_idx_jet_PtCut[ijet]),0);
    // 	    STDOUT("CLEANING: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<" jetFlags="<<jetFlags[ijet] );
    // 	  }
    //       } // printouts for jet cleaning
    
    
    float JetEtaCutValue = getPreCutValue1("jet_EtaCut");
    for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++) //pT pre-cut + no overlaps with electrons + jetID
      {	
	bool passjetID = JetIdloose(CaloJetresEMF->at(v_idx_jet_PtCut[ijet]),CaloJetfHPD->at(v_idx_jet_PtCut[ijet]),CaloJetn90Hits->at(v_idx_jet_PtCut[ijet]), CaloJetEta->at(v_idx_jet_PtCut[ijet]));
	// ---- use the flag stored in rootTuples
	//if( (CaloJetOverlaps->at(v_idx_jet_PtCut[ijet]) & 1 << eleIDType) == 0  /* NO overlap with electrons */  
	// ----

	if( jetFlags[ijet] == 0  )                         /* NO overlap with electrons */  
	  //  && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && passjetID == true                             /* pass JetID */
	    && fabs( CaloJetEta->at(v_idx_jet_PtCut[ijet]) ) < JetEtaCutValue )
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID_EtaCut.push_back(v_idx_jet_PtCut[ijet]);

	
	//NOTE: We should verify that caloJetOverlaps match with the code above
      } // End loop over jets
    

    // Muons
    vector<int> v_idx_muon_all;
    vector<int> v_idx_muon_PtCut;
    vector<int> v_idx_muon_PtCut_IDISO;
    
    // Loop over muons  
    for(int imuon=0; imuon<MuonPt->size(); imuon++){

      // no cut on reco muons
      v_idx_muon_all.push_back(imuon);

      if ( (*MuonPt)[imuon] < muon_PtCut) continue;

      // pT pre-cut on muons
      v_idx_muon_PtCut.push_back(imuon);
      
      if ( ((*MuonTrkHits)[imuon]  >= muNHits_minThresh  )
	   &&( fabs((*MuonTrkD0)[imuon]) < muTrkD0Maximum ) 
	   &&((*MuonPassIso)[imuon]==1 ) 
	   &&((*MuonPassID)[imuon]==1) ) 
	{
	  v_idx_muon_PtCut_IDISO.push_back(imuon);
	}

    }// end loop over muons


    /////  Define the fake rate for QCD and calculate prob. for each sc to be an ele

    double p1 = 0, p2 = 0, p3 = 0;
    if (v_idx_sc_Iso.size()>=1){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[0]))<eleEta_bar) p1 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[0]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[0]))>eleEta_end_min) p1 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[0]) ;
    }
    if (v_idx_sc_Iso.size()>=2){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[1]))<eleEta_bar) p2 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[1]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[1]))>eleEta_end_min) p2 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[1]);
    }
    if (v_idx_sc_Iso.size()>=3){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[2]))<eleEta_bar) p3 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[2]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[2]))>eleEta_end_min) p3 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[2]);
    }

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

    // Set the value of the variableNames listed in the cutFile to their current value


    //     //-------------- EXAMPLE OF RESET-EVALUATE LOOP -
    //     //TEST : loop reset-evaluate cuts    
    //     fillVariableWithValue("Test",0,0.5);    
    //     evaluateCuts();
    //     resetCuts();    
    //     fillVariableWithValue("Test",0,0.25);    
    //     evaluateCuts();
    //     resetCuts();
    //     fillVariableWithValue("Test",1,1);
    //     evaluateCuts();
    //     resetCuts();
    //     fillVariableWithValue("Test",1,0.2);
    //     //---------------


    // original code from Ellie available at 
    // http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/Leptoquarks/rootNtupleMacrosV2/src/analysisClass_eejjSample_QCD.C?revision=1.8&view=markup
    //here we report only the code to fill correctly the "nEle_PtCut_IDISO_noOvrlp" variable
    
    //## fill bin Nele=0
    
    //     if (v_idx_sc_Iso.size()==0) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp", v_idx_sc_Iso.size()) ;
    //     else if (v_idx_sc_Iso.size()==1) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, 1-p1 ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()==2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, (1-p1)*(1-p2) ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, (1-p1)*(1-p2)*(1-p3) ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=1

    //     if (v_idx_sc_Iso.size()==1) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 ) ;
    //     else if (v_idx_sc_Iso.size()==2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 + p2 - 2*p1*p2 ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 + p2 + p3 - 2*p1*p2 - 2*p2*p3 - 2*p1*p3   ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=2

    //     if (v_idx_sc_Iso.size()==2) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",2, p1*p2) ;
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",2, p1*p3 + p1*p2 + p3*p2 ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=3

    //     if (v_idx_sc_Iso.size()>2) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",3, p1*p2*p3) ;


    //-----

    ///  Just fill all histograms assuming exactly 2 superclusters.
    //     if (v_idx_sc_all.size()>=2) fillVariableWithValue( "nEle_all",v_idx_sc_all.size() , p1*p2 ) ;
    //     if (v_idx_sc_PtCut.size()>=2) fillVariableWithValue( "nEle_PtCut",v_idx_sc_PtCut.size(), p1*p2) ;
    if (v_idx_sc_Iso.size()>=2) fillVariableWithValue("nEle_PtCut_IDISO_noOvrlp",v_idx_sc_Iso.size(), p1*p2) ;


    /// Now fill all variables that are filled just once
    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;       
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;       
      }

    fillVariableWithValue( "PassHLT", PassTrig ) ;

    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    //fillVariableWithValue( "PassHBHENoiseFilter", passLooseNoiseFilter ) ;

    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp", v_idx_jet_PtCut_noOverlap.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp_ID", v_idx_jet_PtCut_noOverlap_ID.size(), p1*p2 ) ;
    //TwoEleOnly
    fillVariableWithValue( "nJet_TwoEleOnly_All", v_idx_jet_PtCut_noOverlap_ID.size() , p1*p2) ;
    fillVariableWithValue( "nJet_TwoEleOnly_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size(), p1*p2 ) ;
    //PAS June 2010
    fillVariableWithValue( "nJet_PAS_All", v_idx_jet_PtCut_noOverlap_ID.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PAS_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size(), p1*p2 ) ;

    // MET
    //PAS June 2010
    fillVariableWithValue( "pfMET_PAS", PFMET->at(0), p1*p2 ) ;
    fillVariableWithValue( "tcMET_PAS", TCMET->at(0), p1*p2 ) ;
    fillVariableWithValue( "caloMET_PAS", CaloMET->at(0), p1*p2 ) ;

    //ele Pt
    if( v_idx_sc_Iso.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt1stEle_IDISO_NoOvrlp", SuperClusterPt->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "Eta1stEle_IDISO_NoOvrlp", SuperClusterEta->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "mEta1stEle_IDISO_NoOvrlp", fabs(SuperClusterEta->at(v_idx_sc_Iso[0])), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt1stEle_PAS", SuperClusterPt->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "Eta1stEle_PAS", SuperClusterEta->at(v_idx_sc_Iso[0]), p1*p2 );

	fillVariableWithValue( "Pt2ndEle_IDISO_NoOvrlp", SuperClusterPt->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndEle_IDISO_NoOvrlp", SuperClusterEta->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "mEta2ndEle_IDISO_NoOvrlp", fabs(SuperClusterEta->at(v_idx_sc_Iso[1])), p1*p2 );
	fillVariableWithValue( "maxMEtaEles_IDISO_NoOvrl", max( getVariableValue("mEta1stEle_IDISO_NoOvrlp"), getVariableValue("mEta2ndEle_IDISO_NoOvrlp") ) , p1*p2);
	//PAS June 2010
	fillVariableWithValue( "Pt2ndEle_PAS", SuperClusterPt->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndEle_PAS", SuperClusterEta->at(v_idx_sc_Iso[1]), p1*p2 );
      }

    // 1st jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlp_ID", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
	fillVariableWithValue( "Eta1stJet_noOvrlp_ID", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) , p1*p2);
	fillVariableWithValue( "mEta1stJet_noOvrlp_ID", fabs(CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0])), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt1stJet_PAS", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
	fillVariableWithValue( "Eta1stJet_PAS", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlp_ID", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndJet_noOvrlp_ID", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "mEta2ndJet_noOvrlp_ID", fabs(CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1])), p1*p2 );
	fillVariableWithValue( "maxMEtaJets_noOvrlp_ID", max( getVariableValue("mEta1stJet_noOvrlp_ID"), getVariableValue("mEta2ndJet_noOvrlp_ID") ), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt2ndJet_PAS", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndJet_PAS", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
      }

    //## define "2ele" and "2jets" booleans
    bool TwoEle=false;
    bool TwoJets=false;
    if( v_idx_sc_Iso.size() >= 2 ) TwoEle = true;
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) TwoJets = true;

    // ST
    double calc_sT=-999.; 
    if ( (TwoEle) && (TwoJets) ) 
      {
	calc_sT = 
	  SuperClusterPt->at(v_idx_sc_Iso[0]) +
	  SuperClusterPt->at(v_idx_sc_Iso[1]) +
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) +
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]);
	fillVariableWithValue("sT", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ100", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ200", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ250", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ300", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ400", calc_sT, p1*p2);       
	//PAS June 2010
	fillVariableWithValue("sT_PAS", calc_sT, p1*p2);
      }

    // ST jets
    if (TwoJets)
      {
	double calc_sTjet=-999.;
	calc_sTjet =
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) + 
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) ;
	fillVariableWithValue("sTjet_PAS", calc_sTjet, p1*p2);
      }

    // Mjj
    if (TwoJets)
      {
	TLorentzVector jet1, jet2, jj;
	jet1.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	jj = jet1+jet2;
	//PAS June 2010
	fillVariableWithValue("Mjj_PAS", jj.M(), p1*p2);
      }


    // Mee
    if (TwoEle)
      {
	TLorentzVector ele1, ele2, ee;
	ele1.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[0]),
			  SuperClusterEta->at(v_idx_sc_Iso[0]),
			  SuperClusterPhi->at(v_idx_sc_Iso[0]),0);
	ele2.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[1]),
			  SuperClusterEta->at(v_idx_sc_Iso[1]),
			  SuperClusterPhi->at(v_idx_sc_Iso[1]),0);
	ee = ele1+ele2;
	fillVariableWithValue("Mee", ee.M(), p1*p2);
	//TwoEleOnly
	fillVariableWithValue("Mee_TwoEleOnly", ee.M(), p1*p2);
	fillVariableWithValue("Mee_presel", ee.M(), p1*p2);
	//
	//PAS June 2010
	fillVariableWithValue("Mee_PAS", ee.M(), p1*p2);

	double calc_sTele=-999.;
        calc_sTele =
	  SuperClusterPt->at(v_idx_sc_Iso[0]) +
	  SuperClusterPt->at(v_idx_sc_Iso[1]) ;
	fillVariableWithValue("sTele_PAS", calc_sTele, p1*p2);

	// 	if(isData==true) 
	// 	  {
	// 	    STDOUT("Two electrons: Run, LS, Event = "<<run<<", "<<ls<<", "<<event);
	// 	    STDOUT("Two electrons: M_ee, Pt_ee, Eta_ee, Phi_ee = "<<ee.M() <<", "<< ee.Pt() <<", "<< ee.Eta() <<", "<< ee.Phi());
	// 	    STDOUT("Two electrons: 1st ele Pt, eta, phi = "<< ele1.Pt() <<", "<< ele1.Eta() <<", "<< ele1.Phi() );
	// 	    STDOUT("Two electrons: 2nd ele Pt, eta, phi = "<< ele2.Pt() <<", "<< ele2.Eta() <<", "<< ele2.Phi() );
	// 	  }
      }

    // Mej 
    double Me1j1, Me1j2, Me2j1, Me2j2 = -999;
    double deltaM_e1j1_e2j2 = 9999;
    double deltaM_e1j2_e2j1 = 9999;
    double Mej_1stPair = 0;
    double Mej_2ndPair = 0;
    double deltaR_e1j1 ;
    double deltaR_e2j2 ;
    double deltaR_e1j2 ;
    double deltaR_e2j1 ;
    if ( (TwoEle) && (TwoJets) ) // TwoEle and TwoJets
      {
	TLorentzVector jet1, jet2, ele1, ele2;
	ele1.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[0]),
			  SuperClusterEta->at(v_idx_sc_Iso[0]),
			  SuperClusterPhi->at(v_idx_sc_Iso[0]),0);
	ele2.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[1]),
			  SuperClusterEta->at(v_idx_sc_Iso[1]),
			  SuperClusterPhi->at(v_idx_sc_Iso[1]),0);
	jet1.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	TLorentzVector e1j1, e1j2, e2j1, e2j2;
	e1j1 = ele1 + jet1;
	e2j2 = ele2 + jet2;
	e2j1 = ele2 + jet1;
	e1j2 = ele1 + jet2;
	Me1j1 = e1j1.M();
	Me2j2 = e2j2.M();
	Me1j2 = e1j2.M();
	Me2j1 = e2j1.M();

	deltaM_e1j1_e2j2 = Me1j1 - Me2j2;
	deltaM_e1j2_e2j1 = Me1j2 - Me2j1;


	double deltaR_e1j1 = ele1.DeltaR(jet1);
	double deltaR_e2j2 = ele2.DeltaR(jet2);
	double deltaR_e1j2 = ele1.DeltaR(jet2);
	double deltaR_e2j1 = ele2.DeltaR(jet1);

	// 	// Fill min DR between any of the 2 selected eles and any of the 2 selected jets
	// 	double minDR_2ele_2jet = min ( min(deltaR_e1j1,deltaR_e2j2) , min(deltaR_e1j2,deltaR_e2j1) );
	// 	fillVariableWithValue("minDR_2ele_2jet", minDR_2ele_2jet);

	if(fabs(deltaM_e1j1_e2j2) > fabs(deltaM_e1j2_e2j1))
	  {
	    Mej_1stPair = Me1j2;
	    Mej_2ndPair = Me2j1;
	    fillVariableWithValue("minDRej_selecPairs", min(deltaR_e1j2,deltaR_e2j1), p1*p2 );
	    fillVariableWithValue("minDRej_unselPairs", min(deltaR_e1j1,deltaR_e2j2), p1*p2 );
	  }
	else
	  {
	    Mej_1stPair = Me1j1;
	    Mej_2ndPair = Me2j2;
	    fillVariableWithValue("minDRej_selecPairs", min(deltaR_e1j1,deltaR_e2j2), p1*p2 );
	    fillVariableWithValue("minDRej_unselPairs", min(deltaR_e1j2,deltaR_e2j1), p1*p2 );
	  } 
	fillVariableWithValue("Mej_1stPair", Mej_1stPair, p1*p2);       
	fillVariableWithValue("Mej_2ndPair", Mej_2ndPair, p1*p2);
	//PAS June 2010
	h_Mej_PAS->Fill(Mej_1stPair);
	h_Mej_PAS->Fill(Mej_2ndPair);
	fillVariableWithValue("Mej_1stPair_PAS", Mej_1stPair, p1*p2);       
	fillVariableWithValue("Mej_2ndPair_PAS", Mej_2ndPair, p1*p2);

	// min and max DeltaR between electrons and any jet
	double minDeltaR_ej = 999999;
	double maxDeltaR_ej = -1;
	double thisMinDR, thisMaxDR, DR_thisjet_e1, DR_thisjet_e2;
	TLorentzVector thisjet;
	for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	  {
	    thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	    DR_thisjet_e1 = thisjet.DeltaR(ele1);
	    DR_thisjet_e2 = thisjet.DeltaR(ele2);
	    thisMinDR = min(DR_thisjet_e1, DR_thisjet_e2);
	    thisMaxDR = max(DR_thisjet_e1, DR_thisjet_e2);
	    if(thisMinDR < minDeltaR_ej)
	      minDeltaR_ej = thisMinDR;
	    if(thisMaxDR > maxDeltaR_ej)
	      maxDeltaR_ej = thisMaxDR;
	  } 
	fillVariableWithValue("minDeltaR_ej", minDeltaR_ej, p1*p2);
	fillVariableWithValue("maxDeltaR_ej", maxDeltaR_ej, p1*p2);

	// 	// printouts for small Mej
	// 	if(isData==true && ( Mej_1stPair<20 || Mej_2ndPair<20 ) ) // printouts for low Mej 
	// 	  {
	// 	    STDOUT("Mej<20GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	// 	    STDOUT("Mej<20GeV: Mej_1stPair = "<<Mej_1stPair <<", Mej_2ndPair = "<< Mej_2ndPair );
	// 	    STDOUT("Mej<20GeV: e1j1.M = "<<e1j1.M() <<", e2j2.M = "<<e2j2.M() <<", e1j2.M = "<<e1j2.M()  <<", e2j1.M = "<<e2j1.M()  );
	// 	    STDOUT("Mej<20GeV: deltaM_e1j1_e2j2 = "<<deltaM_e1j1_e2j2 <<", deltaM_e1j2_e2j1 = "<<deltaM_e1j2_e2j1  );
	// 	    STDOUT("Mej<20GeV: deltaR_e1j1 = "<<deltaR_e1j1 <<", deltaR_e2j2 = "<<deltaR_e2j2 <<", deltaR_e1j2 = "<<deltaR_e1j2  <<", deltaR_e2j1 = "<<deltaR_e2j1  );
	// // 	    STDOUT("Mej<20GeV: 1st ele Pt, eta, phi = "<< ele1.Pt() <<",\t"<< ele1.Eta() <<",\t"<< ele1.Phi() );
	// // 	    STDOUT("Mej<20GeV: 2nd ele Pt, eta, phi = "<< ele2.Pt() <<",\t"<< ele2.Eta() <<",\t"<< ele2.Phi() );
	// // 	    STDOUT("Mej<20GeV: 1st jet Pt, eta, phi = "<< jet1.Pt() <<",\t"<< jet1.Eta() <<",\t"<< jet1.Phi() );
	// // 	    STDOUT("Mej<20GeV: 2nd jet Pt, eta, phi = "<< jet2.Pt() <<",\t"<< jet2.Eta() <<",\t"<< jet2.Phi() );
	// 	    TLorentzVector thisele;
	// 	    for(int iele=0; iele<v_idx_sc_Iso.size(); iele++)
	// 	      {
	// 		thisele.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[iele]),
	// 				     SuperClusterEta->at(v_idx_sc_Iso[iele]),
	// 				     SuperClusterPhi->at(v_idx_sc_Iso[iele]),0);
	// 		STDOUT("Mej<20GeV: e"<<iele+1<<" Pt, eta, phi = " 
	// 		       << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi()<<"; DR_j1, DR_j2 = "<< thisele.DeltaR(jet1)<<", "<<thisele.DeltaR(jet2));
	// 	      }
	// 	    TLorentzVector thisjet;
	// 	    TLorentzVector thisjet_e1, thisjet_e2;
	// 	    for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	// 	      {
	// 		thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
	// 				     CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
	// 				     CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	// 		thisjet_e1 = thisjet + ele1;
	// 		thisjet_e2 = thisjet + ele2;
	// 		STDOUT("Mej<20GeV: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<"; DR_e1, DR_e2 = "<< thisjet.DeltaR(ele1)<<", "<<thisjet.DeltaR(ele2) << "; M_e1, M_e2 = " <<thisjet_e1.M() <<", "<<thisjet_e2.M() );
	// 	      }
	// 	  } // printouts for low Mej 

      } // TwoEle and TwoJets



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

    // Fill histograms and do analysis based on cut evaluation
    //h_nEleFinal->Fill( ElectronPt->size() );
     

    //     //Large MET events passing pre-selection
    //     float METcut = 60;
    //     if( variableIsFilled("pfMET_PAS") && passedAllPreviousCuts("pfMET_PAS") && isData==true) 
    //       {

    // 	if( getVariableValue("pfMET_PAS") > METcut )
    // 	  {

    // 	    STDOUT("pfMET>60GeV: ----------- START ------------");

    // 	    STDOUT("pfMET>60GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);	    
    // 	    if( variableIsFilled("Pt1stEle_PAS") && variableIsFilled("Eta1stEle_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt1stEle_PAS,Eta1stEle_PAS = "******"Pt1stEle_PAS")<<",\t"<<getVariableValue("Eta1stEle_PAS"));
    // 	    if( variableIsFilled("Pt2ndEle_PAS") && variableIsFilled("Eta2ndEle_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt2ndEle_PAS,Eta2ndEle_PAS = "******"Pt2ndEle_PAS")<<",\t"<<getVariableValue("Eta2ndEle_PAS"));
    // 	    if( variableIsFilled("Pt1stJet_PAS") && variableIsFilled("Eta1stJet_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt1stJet_PAS,Eta1stJet_PAS = "******"Pt1stJet_PAS")<<",\t"<<getVariableValue("Eta1stJet_PAS"));
    // 	    if( variableIsFilled("Pt2ndJet_PAS") && variableIsFilled("Eta2ndJet_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt2ndJet_PAS,Eta2ndJet_PAS = "******"Pt2ndJet_PAS")<<",\t"<<getVariableValue("Eta2ndJet_PAS"));
    // 	    if( variableIsFilled("Mee_PAS") && variableIsFilled("Mjj_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Mee_PAS,Mjj_PAS = "******"Mee_PAS")<<",\t"<<getVariableValue("Mjj_PAS"));
    // 	    if( variableIsFilled("Mej_1stPair_PAS") && variableIsFilled("Mej_2ndPair_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Mej_1stPair_PAS,Mej_2ndPair_PAS = "******"Mej_1stPair_PAS")
    // 		     <<",\t"<<getVariableValue("Mej_2ndPair_PAS"));
    // 	    if( variableIsFilled("pfMET_PAS") && variableIsFilled("caloMET_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: pfMET_PAS,caloMET_PAS = "******"pfMET_PAS")<<",\t"<<getVariableValue("caloMET_PAS"));

    // 	    STDOUT("pfMET>60GeV: ------------ END -------------");

    // 	  }
    //       }


    //INFO
    //      // retrieve value of previously filled variables (after making sure that they were filled)
    //      double totpTEle;
    //      if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
    //        totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");
    //      // reject events that did not pass level 0 cuts
    //      if( !passedCut("0") ) continue;
    //      // ......

        
    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

  h_Mej_PAS->Write();

  ////////////////////// User's code to write histos - END ///////////////////////
  
  
  //STDOUT("analysisClass::Loop() ends");   
}
void analysisClass::Loop()
{
    std::cout << "analysisClass::Loop() begins" <<std::endl;

    //--------------------------------------------------------------------------
    // Final selection mass points
    //--------------------------------------------------------------------------

    const int n_lq_mass = 19;

    int LQ_MASS[n_lq_mass] = {
        300,  350,  400, 450, 500, 550,  600,  650,
        700,  750,  800, 850, 900, 950, 1000, 1050,
        1100, 1150, 1200
    };

    std::vector<bool> passed_vector;

    //--------------------------------------------------------------------------
    // Decide which plots to save (default is to save everything)
    //--------------------------------------------------------------------------

    fillSkim                         ( !true  ) ;
    fillAllPreviousCuts              ( !true  ) ;
    fillAllOtherCuts                 ( !true  ) ;
    fillAllSameLevelAndLowerLevelCuts( !true  ) ;
    fillAllCuts                      ( !true  ) ;

    //--------------------------------------------------------------------------
    // Any extra features
    //--------------------------------------------------------------------------

    TProfile * profile_run_vs_nvtx_HLT = new TProfile("run_vs_nvtx_HLT", "", 20000 , 160300  , 180300 );
    TProfile * profile_run_vs_nvtx_PAS = new TProfile("run_vs_nvtx_PAS", "", 20000 , 160300  , 180300 );

    //--------------------------------------------------------------------------
    // Get pre-cut values
    //--------------------------------------------------------------------------

    // eta boundaries

    double eleEta_bar_max = getPreCutValue1("eleEta_bar");
    double eleEta_end_min = getPreCutValue1("eleEta_end1");
    double eleEta_end_max = getPreCutValue2("eleEta_end2");

    //--------------------------------------------------------------------------
    // Create TH1D's
    //--------------------------------------------------------------------------

    CreateUserTH1D( "ProcessID"             ,    21  , -0.5    , 20.5     );
    CreateUserTH1D( "ProcessID_PAS"         ,    21  , -0.5    , 20.5     );
    CreateUserTH1D( "ProcessID_ZWindow"     ,    21  , -0.5    , 20.5     );
    CreateUserTH1D( "nElectron_PAS"         ,    5   , -0.5    , 4.5      );
    CreateUserTH1D( "nMuon_PAS"             ,    5   , -0.5    , 4.5      );
    CreateUserTH1D( "nJet_PAS"              ,    10  , -0.5    , 9.5      );
    CreateUserTH1D( "Pt1stEle_PAS"	   , 	100 , 0       , 1000     );
    CreateUserTH1D( "Eta1stEle_PAS"	   , 	100 , -5      , 5	 );
    CreateUserTH1D( "Phi1stEle_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Pt2ndEle_PAS"	   , 	100 , 0       , 1000     );
    CreateUserTH1D( "Eta2ndEle_PAS"	   , 	100 , -5      , 5	 );
    CreateUserTH1D( "Phi2ndEle_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Charge1stEle_PAS"	   , 	2   , -1.0001 , 1.0001	 );
    CreateUserTH1D( "Charge2ndEle_PAS"	   , 	2   , -1.0001 , 1.0001	 );
    CreateUserTH1D( "MET_PAS"               ,    200 , 0       , 1000	 );
    CreateUserTH1D( "METPhi_PAS"		   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Pt1stJet_PAS"          ,    100 , 0       , 1000	 );
    CreateUserTH1D( "Pt2ndJet_PAS"          ,    100 , 0       , 1000	 );
    CreateUserTH1D( "Eta1stJet_PAS"         ,    100 , -5      , 5	 );
    CreateUserTH1D( "Eta2ndJet_PAS"         ,    100 , -5      , 5	 );
    CreateUserTH1D( "Phi1stJet_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "Phi2ndJet_PAS"	   , 	60  , -3.1416 , +3.1416	 );
    CreateUserTH1D( "sTlep_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "sTjet_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "sT_PAS"                ,    200 , 0       , 2000	 );
    CreateUserTH1D( "sT_PASandMee100"       ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Mjj_PAS"		   ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Mee_PAS"		   ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Mee_PASandST445"       ,    200 , 0       , 2000	 );
    CreateUserTH1D( "MTenu_PAS"                , 200 , 0       , 1000	 );
    CreateUserTH1D( "Me1j1_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me1j2_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me2j1_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me2j2_PAS"             ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me1j_selected_PAS"     ,    200 , 0       , 2000	 );
    CreateUserTH1D( "Me2j_selected_PAS"     ,    200 , 0       , 2000     );
    CreateUserTH1D( "Mej_selected_avg_PAS"  ,    200 , 0       , 2000     );
    CreateUserTH1D( "Mej_selected_min_PAS"  ,    200 , 0       , 2000     );
    CreateUserTH1D( "Mej_selected_max_PAS"  ,    200 , 0       , 2000     );
    CreateUserTH1D( "Mej_minmax_PAS"        ,    200 , 0       , 2000     );
    CreateUserTH1D( "Meejj_PAS"             ,    200 , 0       , 2000     );
    CreateUserTH1D( "run_PAS"               ,    20000 , 160300  , 180300 );
    CreateUserTH1D( "run_HLT"               ,    20000 , 160300  , 180300 );

    CreateUserTH1D( "Ptee_PAS"              ,    200 , 0       , 2000     );

    CreateUserTH1D( "DCotTheta1stEle_PAS"   ,    100 , 0.0, 1.0);
    CreateUserTH1D( "Dist1stEle_PAS"        ,    100 , 0.0, 1.0);
    CreateUserTH1D( "DCotTheta2ndEle_PAS"   ,    100 , 0.0, 1.0);
    CreateUserTH1D( "Dist2ndEle_PAS"        ,    100 , 0.0, 1.0);

    CreateUserTH1D( "nVertex_PAS"           ,    101   , -0.5   , 100.5	 ) ;

    CreateUserTH1D( "DR_Ele1Jet1_PAS"	   , 	getHistoNBins("DR_Ele1Jet1"), getHistoMin("DR_Ele1Jet1"), getHistoMax("DR_Ele1Jet1")     ) ;
    CreateUserTH1D( "DR_Ele1Jet2_PAS"	   , 	getHistoNBins("DR_Ele1Jet2"), getHistoMin("DR_Ele1Jet2"), getHistoMax("DR_Ele1Jet2")     ) ;
    CreateUserTH1D( "DR_Ele2Jet1_PAS"	   , 	getHistoNBins("DR_Ele2Jet1"), getHistoMin("DR_Ele2Jet1"), getHistoMax("DR_Ele2Jet1")     ) ;
    CreateUserTH1D( "DR_Ele2Jet2_PAS"	   , 	getHistoNBins("DR_Ele2Jet2"), getHistoMin("DR_Ele2Jet2"), getHistoMax("DR_Ele2Jet2")     ) ;
    CreateUserTH1D( "DR_Jet1Jet2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ;
    CreateUserTH1D( "DR_Ele1Ele2_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ;
    CreateUserTH1D( "minDR_EleJet_PAS"	   , 	getHistoNBins("DR_Jet1Jet2"), getHistoMin("DR_Jet1Jet2"), getHistoMax("DR_Jet1Jet2")     ) ;

    CreateUserTH2D( "Me1jVsMe2j_selected",     200, 0, 2000, 200, 0, 2000) ;
    CreateUserTH2D( "Me1jVsMe2j_rejected",     200, 0, 2000, 200, 0, 2000) ;

    CreateUserTH1D( "MTeemunu_PAS"          ,    200 , 0       , 1000	 );

    CreateUserTH1D( "Mee_80_100_Preselection", 200, 60, 120 );
    CreateUserTH1D( "Mee_70_110_Preselection", 200, 60, 120 );

    CreateUserTH1D( "Mee_70_110_Preselection_Process0", 200, 60, 120 );
    CreateUserTH1D( "Mee_70_110_Preselection_Process1", 200, 60, 120 );
    CreateUserTH1D( "Mee_70_110_Preselection_Process2", 200, 60, 120 );
    CreateUserTH1D( "Mee_70_110_Preselection_Process3", 200, 60, 120 );
    CreateUserTH1D( "Mee_70_110_Preselection_Process4", 200, 60, 120 );

    CreateUserTH1D( "Mee_EBEB_PAS"		   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EBEE_PAS"		   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EEEE_PAS"		   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EB_PAS" 		   ,    60 , 60       , 120	 );

    CreateUserTH1D( "Mee_EBEB_80_100_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EBEE_80_100_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EEEE_80_100_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EB_80_100_PAS" 	     	   ,    60 , 60       , 120	 );

    CreateUserTH1D( "Mee_EBEB_70_110_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EBEE_70_110_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EEEE_70_110_PAS"	   ,    60 , 60       , 120	 );
    CreateUserTH1D( "Mee_EB_70_110_PAS" 	     	   ,    60 , 60       , 120	 );

    CreateUserTH1D( "PileupWeight"   , 100, -10, 10 );
    CreateUserTH1D( "GeneratorWeight", 100, -2.0, 2.0);

    //--------------------------------------------------------------------------
    // Final selection plots
    //--------------------------------------------------------------------------

    char plot_name[100];

    for (int i_lq_mass = 0; i_lq_mass < n_lq_mass ; ++i_lq_mass ) {
        int lq_mass = LQ_MASS[i_lq_mass];
        sprintf(plot_name, "Mej_selected_avg_LQ%d"       , lq_mass );
        CreateUserTH1D ( plot_name, 50  , 0 , 2500 );
        sprintf(plot_name, "Mej_selected_min_LQ%d"       , lq_mass );
        CreateUserTH1D ( plot_name, 50  , 0 , 2500 );
        sprintf(plot_name, "Mej_selected_max_LQ%d"       , lq_mass );
        CreateUserTH1D ( plot_name, 50  , 0 , 2500 );
        sprintf(plot_name, "Mej_minmax_LQ%d"             , lq_mass );
        CreateUserTH1D ( plot_name, 50  , 0 , 2500 );
        sprintf(plot_name, "sT_eejj_LQ%d"                , lq_mass );
        CreateUserTH1D ( plot_name, 25  , 0 , 2500 );
        sprintf(plot_name, "Mee_LQ%d"                    , lq_mass );
        CreateUserTH1D ( plot_name, 40  , 0 , 2000 );
        sprintf(plot_name, "Mej_selected_min_vs_max_LQ%d", lq_mass );
        CreateUserTH2D ( plot_name, 50  , 0 , 1000, 50  , 0 , 1000 );
    }

    //--------------------------------------------------------------------------
    // Loop over the chain
    //--------------------------------------------------------------------------

    if (fChain == 0) return;

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

    Long64_t nbytes = 0, nb = 0;
    for (Long64_t jentry=0; jentry<nentries; jentry++) {

        Long64_t ientry = LoadTree(jentry);
        if (ientry < 0) break;
        nb = fChain->GetEntry(jentry);
        nbytes += nb;
        if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << "/" << nentries << std::endl;

        //--------------------------------------------------------------------------
        // Reset the cuts
        //--------------------------------------------------------------------------

        resetCuts();

        //--------------------------------------------------------------------------
        // Check good run list
        //--------------------------------------------------------------------------

        int    passedJSON = passJSON ( run, ls , isData ) ;

        //--------------------------------------------------------------------------
        // Do pileup re-weighting
        //--------------------------------------------------------------------------

        double pileup_weight = getPileupWeight ( nPileUpInt_True, isData ) ;

        //--------------------------------------------------------------------------
        // Get information about gen-level reweighting (should be for Sherpa only)
        //--------------------------------------------------------------------------

        double gen_weight = Weight;
        if ( isData ) gen_weight = 1.0;
        if ( isData && Ele2_ValidFrac > 998. ) {
            gen_weight = 0.0;
            if      (  60.0 < M_e1e2 < 120. ) gen_weight = 0.61;
            else if ( 120.0 < M_e1e2 < 200. ) gen_weight = 0.42;
            else if ( 200.0 < M_e1e2        ) gen_weight = 0.42;
        }

        // std::cout << "Gen weight = " << int ( 1.0 / gen_weight ) << std::endl;

        //--------------------------------------------------------------------------
        // Fill variables
        //--------------------------------------------------------------------------

        // JSON variable
        fillVariableWithValue(   "PassJSON"                      , passedJSON, gen_weight * pileup_weight   ) ;

        // Noise filters
        fillVariableWithValue(   "PassHBHENoiseFilter"	      , PassHBHENoiseFilter                              , gen_weight * pileup_weight );
        fillVariableWithValue(   "PassBeamHaloFilterTight"       , PassBeamHaloFilterTight                          , gen_weight * pileup_weight );
        fillVariableWithValue(   "PassBadEESupercrystalFilter"   , ( isData == 1 ) ? PassBadEESupercrystalFilter : 1, gen_weight * pileup_weight );
        fillVariableWithValue(   "PassBeamScraping"	      , ( isData == 1 ) ? PassBeamScraping	      : 1, gen_weight * pileup_weight );
        fillVariableWithValue(   "PassEcalDeadCellBoundEnergy"   , PassEcalDeadCellBoundEnergy                      , gen_weight * pileup_weight );
        fillVariableWithValue(   "PassEcalDeadCellTrigPrim"      , PassEcalDeadCellTrigPrim                         , gen_weight * pileup_weight );
        fillVariableWithValue(   "PassEcalLaserCorrFilter"       , ( isData == 1 ) ? PassEcalLaserCorrFilter     : 1, gen_weight * pileup_weight );
        fillVariableWithValue(   "PassHcalLaserEventFilter"      , ( isData == 1 ) ? PassHcalLaserEventFilter    : 1, gen_weight * pileup_weight );
        fillVariableWithValue(   "PassPhysDecl"		      , ( isData == 1 ) ? PassPhysDecl		      : 1, gen_weight * pileup_weight );
        fillVariableWithValue(   "PassPrimaryVertex"	      , PassPrimaryVertex                                , gen_weight * pileup_weight );
        fillVariableWithValue(   "PassTrackingFailure"	      , ( isData == 1 ) ? PassTrackingFailure	      : 1, gen_weight * pileup_weight );

        //fillVariableWithValue(   "PassBPTX0"                     , PassBPTX0                  , gen_weight  ) ;
        //fillVariableWithValue(   "PassPhysDecl"                  , PassPhysDecl               , gen_weight  ) ;
        //fillVariableWithValue(   "PassBeamScraping"              , PassBeamScraping           , gen_weight  ) ;
        //fillVariableWithValue(   "PassPrimaryVertex"             , PassPrimaryVertex          , gen_weight  ) ;
        //fillVariableWithValue(   "PassBeamHaloFilterLoose"	      , PassBeamHaloFilterLoose	   , gen_weight  ) ;
        //fillVariableWithValue(   "PassTrackingFailure"           , PassTrackingFailure        , gen_weight  ) ;
        //fillVariableWithValue(   "PassCaloBoundaryDRFilter"      , PassCaloBoundaryDRFilter   , gen_weight  ) ;
        //fillVariableWithValue(   "PassEcalMaskedCellDRFilter"    , PassEcalMaskedCellDRFilter , gen_weight  ) ;

        // Fill HLT

        int passHLT = 1;
        if ( isData ) {
            passHLT = 0;
            if ( H_DoubleEle33_CIdL_GsfIdVL == 1 ) {
                passHLT = 1;
            }
        }


        int nEle_hltMatched = 0.0;
        if ( Ele1_hltEleSignalPt > 0.0 ) nEle_hltMatched++;
        if ( Ele2_hltEleSignalPt > 0.0 ) nEle_hltMatched++;

        int nJet_hltMatched = 0.0;
        if ( Jet1_hltNoPUJetPt > 0.0 || Jet1_hltJetPt > 0.0 ) nJet_hltMatched++;
        if ( Jet2_hltNoPUJetPt > 0.0 || Jet2_hltJetPt > 0.0 ) nJet_hltMatched++;


        /*
        int passHLT = 0;
        if ( H_Ele30_PFJet100_25      == 1 ||
         H_Ele30_PFNoPUJet100_25  == 1 ){
          passHLT = 1;
        }
        */

        // Muons and electrons
        bool is_ttbar_from_data = false;
        if ( Ele2_ValidFrac > 998. ) is_ttbar_from_data = true;

        int PassNEle = 0;
        if ( !is_ttbar_from_data && nEle_ptCut == 2 ) PassNEle = 1;
        if (  is_ttbar_from_data && nEle_ptCut == 2 ) PassNEle = 1;

        int PassNMuon = 0;
        if ( !is_ttbar_from_data && nMuon_ptCut == 0 ) PassNMuon = 1;
        if (  is_ttbar_from_data && nMuon_ptCut >  0 ) PassNMuon = 1;

        fillVariableWithValue ( "Reweighting", 1, gen_weight * pileup_weight  );
        fillVariableWithValue ( "PassHLT", passHLT, gen_weight * pileup_weight  ) ;
        fillVariableWithValue("nEle_hltMatched",nEle_hltMatched, gen_weight * pileup_weight  );
        fillVariableWithValue("nJet_hltMatched",nJet_hltMatched, gen_weight * pileup_weight  );

        // Electrons
        fillVariableWithValue(   "PassNEle"                      , PassNEle    , gen_weight * pileup_weight  ) ;
        if ( nEle_store >= 1 ) {
            fillVariableWithValue( "Ele1_Pt"                       , Ele1_Pt     , gen_weight * pileup_weight  ) ;
        }
        if ( nEle_store >= 2 ) {
            fillVariableWithValue( "Ele2_Pt"                       , Ele2_Pt     , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "M_e1e2"                        , M_e1e2      , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "M_e1e2_opt"                    , M_e1e2      , gen_weight * pileup_weight  ) ;
        }

        // Jets
        fillVariableWithValue(   "nJet"                          , nJet_ptCut  , gen_weight * pileup_weight  ) ;
        if ( nJet_store >= 1 ) {
            fillVariableWithValue( "Jet1_Pt"                       , Jet1_Pt     , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "Jet1_Eta"                      , Jet1_Eta    , gen_weight * pileup_weight  ) ;
        }
        if ( nJet_store >= 2 ) {
            fillVariableWithValue( "Jet2_Pt"                       , Jet2_Pt     , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "Jet2_Eta"                      , Jet2_Eta    , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "DR_Jet1Jet2"                   , DR_Jet1Jet2 , gen_weight * pileup_weight  ) ;
        }

        // Muons
        fillVariableWithValue(   "PassNMuon"                     , PassNMuon   , gen_weight * pileup_weight  ) ;

        // DeltaR
        if ( nEle_store >= 2 && nJet_store >= 1) {
            fillVariableWithValue( "DR_Ele1Jet1"                   , DR_Ele1Jet1 , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "DR_Ele2Jet1"                   , DR_Ele2Jet1 , gen_weight * pileup_weight  ) ;
            if(nJet_store >= 2) {
                fillVariableWithValue( "DR_Ele1Jet2"                 , DR_Ele1Jet2 , gen_weight * pileup_weight  ) ;
                fillVariableWithValue( "DR_Ele2Jet2"                 , DR_Ele2Jet2 , gen_weight * pileup_weight  ) ;
            }
        }

        // sT
        double M_ej_avg;
        double M_ej_min;
        double M_ej_max;

        if ( nEle_store >= 2 && nJet_store >= 2) {
            if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
                M_ej_avg = (M_e1j1 + M_e2j2) / 2.0;
                if    ( M_e1j1 < M_e2j2 ) {
                    M_ej_min = M_e1j1;
                    M_ej_max = M_e2j2;
                }
                else                      {
                    M_ej_min = M_e2j2;
                    M_ej_max = M_e1j1;
                }
            }
            else {
                M_ej_avg = (M_e1j2 + M_e2j1) / 2.0;
                if    ( M_e1j2 < M_e2j1 ) {
                    M_ej_min = M_e1j2;
                    M_ej_max = M_e2j1;
                }
                else                      {
                    M_ej_min = M_e2j1;
                    M_ej_max = M_e1j2;
                }
            }

            fillVariableWithValue( "sT_eejj"                      , sT_eejj , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "sT_eejj_opt"                  , sT_eejj , gen_weight * pileup_weight  ) ;
            fillVariableWithValue( "Mej_min_opt"                  , M_ej_min, gen_weight * pileup_weight  ) ;
        }

        //--------------------------------------------------------------------------
        // Fill final selection cuts
        //--------------------------------------------------------------------------

        char cut_name[100];
        for (int i_lq_mass = 0; i_lq_mass < n_lq_mass; ++i_lq_mass ) {
            int lq_mass = LQ_MASS[i_lq_mass];
            sprintf(cut_name, "M_e1e2_LQ%d"  , lq_mass );
            fillVariableWithValue ( cut_name, M_e1e2  , gen_weight * pileup_weight  ) ;
            sprintf(cut_name, "sT_eejj_LQ%d" , lq_mass );
            fillVariableWithValue ( cut_name, sT_eejj , gen_weight * pileup_weight  ) ;
            sprintf(cut_name, "min_M_ej_LQ%d", lq_mass );
            fillVariableWithValue ( cut_name, M_ej_min, gen_weight * pileup_weight  ) ;
        }

        //--------------------------------------------------------------------------
        // Evaluate the cuts
        //--------------------------------------------------------------------------

        evaluateCuts();

        //--------------------------------------------------------------------------
        // Did we pass any final selections?
        //--------------------------------------------------------------------------

        passed_vector.clear();
        for (int i_lq_mass = 0; i_lq_mass < n_lq_mass; ++i_lq_mass ) {
            int lq_mass = LQ_MASS[i_lq_mass];
            sprintf(cut_name, "M_e1e2_LQ%d", lq_mass );
            bool decision = bool ( passedAllPreviousCuts(cut_name) && passedCut (cut_name));
            passed_vector.push_back (decision);
        }

        //--------------------------------------------------------------------------
        // Fill skim-level plots
        //--------------------------------------------------------------------------

        bool passed_minimum = ( passedAllPreviousCuts("PassTrackingFailure") && passedCut ("PassTrackingFailure"));

        if ( passed_minimum && isData ) {
            FillUserTH1D ("run_HLT", run );
            profile_run_vs_nvtx_HLT -> Fill ( run, nVertex, 1 ) ;
        }

        //--------------------------------------------------------------------------
        // Fill preselection plots
        //--------------------------------------------------------------------------

        FillUserTH1D( "PileupWeight"   , pileup_weight );
        FillUserTH1D( "GeneratorWeight", gen_weight ) ;

        bool passed_preselection = ( passedAllPreviousCuts("M_e1e2") && passedCut ("M_e1e2") );

        /*
        if ( isData ) {
          std::cout.precision(0);
          std::cout << fixed <<  "Run = " << run << ", event = " << event << ", ls = " << ls << std::endl;
          std::cout.precision(3);
          std::cout << fixed <<  "  Mej      = " << M_ej_avg << std::endl;
          std::cout << fixed <<  "  Mee      = " << M_e1e2 << std::endl;
          std::cout << fixed <<  "  sT       = " << sT_enujj << std::endl;
          std::cout << fixed <<  "  Ele1 Pt  = " << Ele1_Pt << "\t, Eta = " << Ele1_Eta << "\t, Phi = " << Ele1_Phi << std::endl;
          std::cout << fixed <<  "  Ele2 Pt  = " << Ele2_Pt << "\t, Eta = " << Ele2_Eta << "\t, Phi = " << Ele2_Phi << std::endl;
          std::cout << fixed <<  "  Jet1 Pt  = " << Jet1_Pt << "\t, Eta = " << Jet1_Eta << "\t, Phi = " << Jet1_Phi << std::endl;
          std::cout << fixed <<  "  Jet2 Pt  = " << Jet2_Pt << "\t, Eta = " << Jet2_Eta << "\t, Phi = " << Jet2_Phi << std::endl;
        }
        */

        if ( passed_preselection ) {

            FillUserTH1D( "ProcessID_PAS"      , ProcessID, pileup_weight * gen_weight ) ;

            //--------------------------------------------------------------------------
            // Fill skim tree, if necessary
            //--------------------------------------------------------------------------

            bool isEB1 = ( fabs(Ele1_Eta) < eleEta_bar_max  ) ;
            bool isEE1 = ( fabs(Ele1_Eta) > eleEta_end_min &&
                           fabs(Ele1_Eta) < eleEta_end_max ) ;

            bool isEB2 = ( fabs(Ele2_Eta) < eleEta_bar_max  ) ;
            bool isEE2 = ( fabs(Ele2_Eta) > eleEta_end_min &&
                           fabs(Ele2_Eta) < eleEta_end_max ) ;

            bool isEBEB = ( isEB1 && isEB2 ) ;
            bool isEBEE = ( ( isEB1 && isEE2 ) ||
                            ( isEE1 && isEB2 ) );
            bool isEEEE = ( isEE1  && isEE2  );
            bool isEB   = ( isEBEB || isEBEE );

            if ( isData ) {
                FillUserTH1D("run_PAS", run ) ;
                profile_run_vs_nvtx_PAS -> Fill ( run, nVertex, 1 ) ;
            }

            FillUserTH1D("nElectron_PAS"        , nEle_ptCut         , pileup_weight * gen_weight ) ;
            FillUserTH1D("nMuon_PAS"            , nMuon_ptCut        , pileup_weight * gen_weight ) ;
            FillUserTH1D("nJet_PAS"             , nJet_ptCut         , pileup_weight * gen_weight ) ;
            FillUserTH1D("Pt1stEle_PAS"	   , Ele1_Pt            , pileup_weight * gen_weight ) ;
            FillUserTH1D("Eta1stEle_PAS"	   , Ele1_Eta           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Phi1stEle_PAS"	   , Ele1_Phi           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Pt2ndEle_PAS"	   , Ele2_Pt            , pileup_weight * gen_weight ) ;
            FillUserTH1D("Eta2ndEle_PAS"	   , Ele2_Eta           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Phi2ndEle_PAS"	   , Ele2_Phi           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Charge1stEle_PAS"	   , Ele1_Charge        , pileup_weight * gen_weight ) ;
            FillUserTH1D("Charge2ndEle_PAS"	   , Ele2_Charge        , pileup_weight * gen_weight ) ;
            FillUserTH1D("MET_PAS"              , PFMET_Type01XY_Pt  , pileup_weight * gen_weight ) ;
            FillUserTH1D("METPhi_PAS"	   , PFMET_Type01XY_Phi , pileup_weight * gen_weight ) ;
            FillUserTH1D("Pt1stJet_PAS"         , Jet1_Pt            , pileup_weight * gen_weight ) ;
            FillUserTH1D("Pt2ndJet_PAS"         , Jet2_Pt            , pileup_weight * gen_weight ) ;
            FillUserTH1D("Eta1stJet_PAS"        , Jet1_Eta           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Eta2ndJet_PAS"        , Jet2_Eta           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Phi1stJet_PAS"	   , Jet1_Phi           , pileup_weight * gen_weight ) ;
            FillUserTH1D("Phi2ndJet_PAS"	   , Jet2_Phi           , pileup_weight * gen_weight ) ;
            FillUserTH1D("sTlep_PAS"            , Ele1_Pt + Ele2_Pt  , pileup_weight * gen_weight ) ;
            FillUserTH1D("sTjet_PAS"            , Jet1_Pt + Jet2_Pt  , pileup_weight * gen_weight ) ;
            FillUserTH1D("sT_PAS"               , sT_eejj            , pileup_weight * gen_weight ) ;
            FillUserTH1D("Mjj_PAS"		   , M_j1j2             , pileup_weight * gen_weight ) ;
            FillUserTH1D("Mee_PAS"		   , M_e1e2             , pileup_weight * gen_weight ) ;
            FillUserTH1D( "MTenu_PAS"           , MT_Ele1MET         , pileup_weight * gen_weight ) ;
            FillUserTH1D("Me1j1_PAS"            , M_e1j1             , pileup_weight * gen_weight ) ;
            FillUserTH1D("Me1j2_PAS"            , M_e1j2             , pileup_weight * gen_weight ) ;
            FillUserTH1D("Me2j1_PAS"            , M_e2j1             , pileup_weight * gen_weight ) ;
            FillUserTH1D("Me2j2_PAS"            , M_e2j2             , pileup_weight * gen_weight ) ;
            FillUserTH1D("Ptee_PAS"             , Pt_e1e2            , pileup_weight * gen_weight ) ;
            FillUserTH1D("DCotTheta1stEle_PAS"  , Ele1_DCotTheta     , pileup_weight * gen_weight ) ;
            FillUserTH1D("Dist1stEle_PAS"       , Ele1_Dist          , pileup_weight * gen_weight ) ;
            FillUserTH1D("DCotTheta2ndEle_PAS"  , Ele2_DCotTheta     , pileup_weight * gen_weight ) ;
            FillUserTH1D("Dist2ndEle_PAS"       , Ele2_Dist          , pileup_weight * gen_weight ) ;
            FillUserTH1D("nVertex_PAS"          , nVertex            , pileup_weight * gen_weight ) ;
            FillUserTH1D("DR_Ele1Jet1_PAS"	   , DR_Ele1Jet1        , pileup_weight * gen_weight ) ;
            FillUserTH1D("DR_Ele1Jet2_PAS"	   , DR_Ele1Jet2        , pileup_weight * gen_weight ) ;
            FillUserTH1D("DR_Ele2Jet1_PAS"	   , DR_Ele2Jet1        , pileup_weight * gen_weight ) ;
            FillUserTH1D("DR_Ele2Jet2_PAS"	   , DR_Ele2Jet2        , pileup_weight * gen_weight ) ;
            FillUserTH1D("DR_Jet1Jet2_PAS"	   , DR_Jet1Jet2        , pileup_weight * gen_weight ) ;

            if ( passedCut ("sT_eejj_LQ300") ) {
                FillUserTH1D( "Mee_PASandST445", M_e1e2, pileup_weight * gen_weight ) ;
            }

            if ( passedCut ("M_e1e2_LQ300") ) {
                FillUserTH1D("sT_PASandMee100", sT_eejj, pileup_weight * gen_weight ) ;
            }

            if ( passedCut ("sT_eejj_LQ300" ) &&
                    passedCut ("min_M_ej_LQ300") ) {

            }



            if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_PAS", M_e1e2, pileup_weight * gen_weight );
            else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_PAS", M_e1e2, pileup_weight * gen_weight );
            else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_PAS", M_e1e2, pileup_weight * gen_weight );
            if      ( isEB   ) FillUserTH1D( "Mee_EB_PAS"  , M_e1e2, pileup_weight * gen_weight );

            if ( M_e1e2 > 80.0 && M_e1e2 < 100.0 ) {
                FillUserTH1D("Mee_80_100_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
                if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_80_100_PAS", M_e1e2, pileup_weight * gen_weight );
                else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight );
                else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_80_100_PAS", M_e1e2, pileup_weight * gen_weight );
                if      ( isEB   ) FillUserTH1D( "Mee_EB_80_100_PAS"  , M_e1e2, pileup_weight * gen_weight );
            }

            if ( M_e1e2 > 70.0 && M_e1e2 < 110.0 ) {
                FillUserTH1D("Mee_70_110_Preselection", M_e1e2, pileup_weight * gen_weight ) ;
                if      ( isEBEB ) FillUserTH1D( "Mee_EBEB_70_110_PAS", M_e1e2, pileup_weight * gen_weight );
                else if ( isEBEE ) FillUserTH1D( "Mee_EBEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight );
                else if ( isEEEE ) FillUserTH1D( "Mee_EEEE_70_110_PAS", M_e1e2, pileup_weight * gen_weight );
                if      ( isEB   ) FillUserTH1D( "Mee_EB_70_110_PAS"  , M_e1e2, pileup_weight * gen_weight );

                FillUserTH1D( "ProcessID_ZWindow", ProcessID, pileup_weight * gen_weight );
                if ( ProcessID == 0 ) FillUserTH1D ( "Mee_70_110_Preselection_Process0", M_e1e2, pileup_weight * gen_weight );
                if ( ProcessID == 1 ) FillUserTH1D ( "Mee_70_110_Preselection_Process1", M_e1e2, pileup_weight * gen_weight );
                if ( ProcessID == 2 ) FillUserTH1D ( "Mee_70_110_Preselection_Process2", M_e1e2, pileup_weight * gen_weight );
                if ( ProcessID == 3 ) FillUserTH1D ( "Mee_70_110_Preselection_Process3", M_e1e2, pileup_weight * gen_weight );
                if ( ProcessID == 4 ) FillUserTH1D ( "Mee_70_110_Preselection_Process4", M_e1e2, pileup_weight * gen_weight );
            }

            double DR_Ele1Jet3 = 999.;
            double DR_Ele2Jet3 = 999.;
            double min_DR_EleJet = 999.;
            TLorentzVector eejj, e1e2mu, e1, j1, e2, j2,j3, mu, met;
            e1.SetPtEtaPhiM ( Ele1_Pt, Ele1_Eta, Ele1_Phi, 0.0 );
            e2.SetPtEtaPhiM ( Ele2_Pt, Ele2_Eta, Ele2_Phi, 0.0 );
            j1.SetPtEtaPhiM ( Jet1_Pt, Jet1_Eta, Jet1_Phi, 0.0 );
            j2.SetPtEtaPhiM ( Jet2_Pt, Jet2_Eta, Jet2_Phi, 0.0 );
            if ( nJet_store > 2 ) {
                j3.SetPtEtaPhiM ( Jet3_Pt, Jet3_Eta, Jet3_Phi, 0.0 );
                DR_Ele1Jet3 = e1.DeltaR( j3 );
                DR_Ele2Jet3 = e2.DeltaR( j3 );
            }

            if ( DR_Ele1Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet1;
            if ( DR_Ele1Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet2;
            if ( DR_Ele2Jet1 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet1;
            if ( DR_Ele2Jet2 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet2;
            if ( nJet_store > 2 ) {
                if ( DR_Ele1Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele1Jet3;
                if ( DR_Ele2Jet3 < min_DR_EleJet ) min_DR_EleJet = DR_Ele2Jet3;
            }

            FillUserTH1D( "minDR_EleJet_PAS", min_DR_EleJet, pileup_weight * gen_weight);


            mu.SetPtEtaPhiM ( Muon1_Pt, Muon1_Eta, Muon1_Phi, 0.0 );
            met.SetPtEtaPhiM ( PFMET_Type01XY_Pt, 0.0, PFMET_Type01XY_Phi, 0.0 );

            double DR_Ele1Ele2 = e1.DeltaR( e2 ) ;
            FillUserTH1D("DR_Ele1Ele2_PAS"	   , DR_Ele1Ele2      , pileup_weight * gen_weight ) ;

            eejj = e1 + e2 + j1 + j2 ;
            double M_eejj = eejj.M();

            FillUserTH1D("Meejj_PAS", M_eejj , pileup_weight * gen_weight );


            if ( fabs(M_e1j1-M_e2j2) < fabs(M_e1j2-M_e2j1) )  {
                FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_selected_min_PAS", M_ej_min, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_selected_max_PAS", M_ej_max, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_minmax_PAS"      , M_ej_min, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_minmax_PAS"      , M_ej_max, pileup_weight * gen_weight) ;
                FillUserTH1D("Me1j_selected_PAS"   , M_e1j1  , pileup_weight * gen_weight) ;
                FillUserTH1D("Me2j_selected_PAS"   , M_e2j2  , pileup_weight * gen_weight) ;
                FillUserTH2D( "Me1jVsMe2j_selected", M_e1j1  , M_e2j2, pileup_weight * gen_weight ) ;
                FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j2  , M_e2j1, pileup_weight * gen_weight ) ;
            }

            else {
                FillUserTH1D("Mej_selected_avg_PAS", M_ej_avg, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_selected_min_PAS", M_ej_min, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_selected_max_PAS", M_ej_max, pileup_weight * gen_weight) ;
                FillUserTH1D("Me1j_selected_PAS"   , M_e1j2, pileup_weight * gen_weight) ;
                FillUserTH1D("Me2j_selected_PAS"   , M_e2j1, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_minmax_PAS"      , M_ej_min, pileup_weight * gen_weight) ;
                FillUserTH1D("Mej_minmax_PAS"      , M_ej_max, pileup_weight * gen_weight) ;
                FillUserTH2D( "Me1jVsMe2j_selected", M_e1j2, M_e2j1, pileup_weight * gen_weight ) ;
                FillUserTH2D( "Me1jVsMe2j_rejected", M_e1j1, M_e2j2, pileup_weight * gen_weight ) ;
            }

            for (int i_lq_mass = 0; i_lq_mass < n_lq_mass; ++i_lq_mass ) {
                int  lq_mass = LQ_MASS      [i_lq_mass];
                bool pass    = passed_vector[i_lq_mass];
                if ( !pass ) continue;

                if ( lq_mass == 1200 && isData == 1) {
                    std::cout << std::fixed << "RUN = " << run << ", EVENT = " << event << ", LS = " << ls << std::endl;
                }

                sprintf(plot_name, "Mej_selected_avg_LQ%d"       , lq_mass );
                FillUserTH1D ( plot_name, M_ej_avg          , pileup_weight * gen_weight );
                sprintf(plot_name, "Mej_selected_min_LQ%d"       , lq_mass );
                FillUserTH1D ( plot_name, M_ej_min          , pileup_weight * gen_weight );
                sprintf(plot_name, "Mej_selected_max_LQ%d"       , lq_mass );
                FillUserTH1D ( plot_name, M_ej_max          , pileup_weight * gen_weight );
                sprintf(plot_name, "Mej_minmax_LQ%d"             , lq_mass );
                FillUserTH1D ( plot_name, M_ej_min          , pileup_weight * gen_weight );
                sprintf(plot_name, "Mej_minmax_LQ%d"             , lq_mass );
                FillUserTH1D ( plot_name, M_ej_max          , pileup_weight * gen_weight );
                sprintf(plot_name, "sT_eejj_LQ%d"                , lq_mass );
                FillUserTH1D ( plot_name, sT_eejj           , pileup_weight * gen_weight );
                sprintf(plot_name, "Mee_LQ%d"                    , lq_mass );
                FillUserTH1D ( plot_name, M_e1e2            , pileup_weight * gen_weight );
                sprintf(plot_name, "Mej_selected_min_vs_max_LQ%d", lq_mass );
                FillUserTH2D ( plot_name, M_ej_min, M_ej_max, pileup_weight * gen_weight );

            }
        }
    } // End loop over events

    output_root_ -> cd();
    profile_run_vs_nvtx_HLT -> Write();
    profile_run_vs_nvtx_PAS -> Write();

    std::cout << "analysisClass::Loop() ends" <<std::endl;
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;

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

   // number of electrons
   //    TH1F *h_nEleFinal = new TH1F ("h_nEleFinal","",11,-0.5,10.5);
   //    h_nEleFinal->Sumw2();


   //barrel - all   
   TH1F *h_ElectronPt_barrel_all = new TH1F ("h_ElectronPt_barrel_all","h_ElectronPt_barrel_all",100,0,500);
   TH1F *h_ElectronSCEta_fabs_barrel_all = new TH1F ("h_ElectronSCEta_fabs_barrel_all","h_ElectronSCEta_fabs_barrel_all",50,0,5);
   TH1F *h_ElectronDeltaEtaTrkSC_barrel_all = new TH1F ("h_ElectronDeltaEtaTrkSC_barrel_all","h_ElectronDeltaEtaTrkSC_barrel_all",200,-0.05,0.05);
   TH1F *h_ElectronDeltaPhiTrkSC_barrel_all = new TH1F ("h_ElectronDeltaPhiTrkSC_barrel_all","h_ElectronDeltaPhiTrkSC_barrel_all",200,-0.5,0.5);
   TH1F *h_ElectronHoE_barrel_all = new TH1F ("h_ElectronHoE_barrel_all","h_ElectronHoE_barrel_all",75,0,0.15);
   TH1F *h_ElectronSigmaIEtaIEta_barrel_all = new TH1F ("h_ElectronSigmaIEtaIEta_barrel_all","h_ElectronSigmaIEtaIEta_barrel_all",100,0,0.1);
   TH2F *h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all = new TH2F ("h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all"
									,"h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all"
									,100,0,1,100,0,1);
   TH2F *h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all 
     = new TH2F ("h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all"
		 ,"h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all"
		 ,100,0,500,500,0,100);
   TH1F *h_ElectronHcalIsoD2Heep_barrel_all = new TH1F ("h_ElectronHcalIsoD2Heep_barrel_all","h_ElectronHcalIsoD2Heep_barrel_all",200,0,100);
   TH1F *h_ElectronTrkIsoHeep_barrel_all = new TH1F ("h_ElectronTrkIsoHeep_barrel_all","h_ElectronTrkIsoHeep_barrel_all",200,0,100);


   h_ElectronPt_barrel_all->Sumw2();
   h_ElectronSCEta_fabs_barrel_all->Sumw2();
   h_ElectronDeltaEtaTrkSC_barrel_all->Sumw2();
   h_ElectronDeltaPhiTrkSC_barrel_all->Sumw2();
   h_ElectronHoE_barrel_all->Sumw2();
   h_ElectronSigmaIEtaIEta_barrel_all->Sumw2();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all->Sumw2();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all->Sumw2(); 
   h_ElectronHcalIsoD2Heep_barrel_all->Sumw2();
   h_ElectronTrkIsoHeep_barrel_all->Sumw2();


   //barrel - heep   
   TH1F *h_ElectronPt_barrel_heep = new TH1F ("h_ElectronPt_barrel_heep","h_ElectronPt_barrel_heep",100,0,500);
   TH1F *h_ElectronSCEta_fabs_barrel_heep = new TH1F ("h_ElectronSCEta_fabs_barrel_heep","h_ElectronSCEta_fabs_barrel_heep",50,0,5);
   TH1F *h_ElectronDeltaEtaTrkSC_barrel_heep = new TH1F ("h_ElectronDeltaEtaTrkSC_barrel_heep","h_ElectronDeltaEtaTrkSC_barrel_heep",200,-0.05,0.05);
   TH1F *h_ElectronDeltaPhiTrkSC_barrel_heep = new TH1F ("h_ElectronDeltaPhiTrkSC_barrel_heep","h_ElectronDeltaPhiTrkSC_barrel_heep",200,-0.5,0.5);
   TH1F *h_ElectronHoE_barrel_heep = new TH1F ("h_ElectronHoE_barrel_heep","h_ElectronHoE_barrel_heep",75,0,0.15);
   TH1F *h_ElectronSigmaIEtaIEta_barrel_heep = new TH1F ("h_ElectronSigmaIEtaIEta_barrel_heep","h_ElectronSigmaIEtaIEta_barrel_heep",100,0,0.1);
   TH2F *h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep = new TH2F ("h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep"
									,"h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep"
									,100,0,1,100,0,1);
   TH2F *h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep 
     = new TH2F ("h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep"
		 ,"h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep"
		 ,100,0,500,500,0,100);
   TH1F *h_ElectronHcalIsoD2Heep_barrel_heep = new TH1F ("h_ElectronHcalIsoD2Heep_barrel_heep","h_ElectronHcalIsoD2Heep_barrel_heep",200,0,100);
   TH1F *h_ElectronTrkIsoHeep_barrel_heep = new TH1F ("h_ElectronTrkIsoHeep_barrel_heep","h_ElectronTrkIsoHeep_barrel_heep",200,0,100);

   h_ElectronPt_barrel_heep->Sumw2();
   h_ElectronSCEta_fabs_barrel_heep->Sumw2();
   h_ElectronDeltaEtaTrkSC_barrel_heep->Sumw2();
   h_ElectronDeltaPhiTrkSC_barrel_heep->Sumw2();
   h_ElectronHoE_barrel_heep->Sumw2();
   h_ElectronSigmaIEtaIEta_barrel_heep->Sumw2();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep->Sumw2();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep->Sumw2(); 
   h_ElectronHcalIsoD2Heep_barrel_heep->Sumw2();
   h_ElectronTrkIsoHeep_barrel_heep->Sumw2();


   //endcap - all   
   TH1F *h_ElectronPt_endcap_all = new TH1F ("h_ElectronPt_endcap_all","h_ElectronPt_endcap_all",100,0,500);
   TH1F *h_ElectronSCEta_fabs_endcap_all = new TH1F ("h_ElectronSCEta_fabs_endcap_all","h_ElectronSCEta_fabs_endcap_all",50,0,5);
   TH1F *h_ElectronDeltaEtaTrkSC_endcap_all = new TH1F ("h_ElectronDeltaEtaTrkSC_endcap_all","h_ElectronDeltaEtaTrkSC_endcap_all",200,-0.05,0.05);
   TH1F *h_ElectronDeltaPhiTrkSC_endcap_all = new TH1F ("h_ElectronDeltaPhiTrkSC_endcap_all","h_ElectronDeltaPhiTrkSC_endcap_all",200,-0.5,0.5);
   TH1F *h_ElectronHoE_endcap_all = new TH1F ("h_ElectronHoE_endcap_all","h_ElectronHoE_endcap_all",75,0,0.15);
   TH1F *h_ElectronSigmaIEtaIEta_endcap_all = new TH1F ("h_ElectronSigmaIEtaIEta_endcap_all","h_ElectronSigmaIEtaIEta_endcap_all",100,0,0.1);
   TH2F *h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all = new TH2F ("h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all"
									,"h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all"
									,100,0,1,100,0,1);
   TH2F *h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all 
     = new TH2F ("h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all"
		 ,"h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all"
		 ,100,0,500,500,0,100);
   TH1F *h_ElectronHcalIsoD2Heep_endcap_all = new TH1F ("h_ElectronHcalIsoD2Heep_endcap_all","h_ElectronHcalIsoD2Heep_endcap_all",200,0,100);
   TH1F *h_ElectronTrkIsoHeep_endcap_all = new TH1F ("h_ElectronTrkIsoHeep_endcap_all","h_ElectronTrkIsoHeep_endcap_all",200,0,100);

   h_ElectronPt_endcap_all->Sumw2();
   h_ElectronSCEta_fabs_endcap_all->Sumw2();
   h_ElectronDeltaEtaTrkSC_endcap_all->Sumw2();
   h_ElectronDeltaPhiTrkSC_endcap_all->Sumw2();
   h_ElectronHoE_endcap_all->Sumw2();
   h_ElectronSigmaIEtaIEta_endcap_all->Sumw2();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all->Sumw2();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all->Sumw2(); 
   h_ElectronHcalIsoD2Heep_endcap_all->Sumw2();
   h_ElectronTrkIsoHeep_endcap_all->Sumw2();


   //endcap - heep   
   TH1F *h_ElectronPt_endcap_heep = new TH1F ("h_ElectronPt_endcap_heep","h_ElectronPt_endcap_heep",100,0,500);
   TH1F *h_ElectronSCEta_fabs_endcap_heep = new TH1F ("h_ElectronSCEta_fabs_endcap_heep","h_ElectronSCEta_fabs_endcap_heep",50,0,5);
   TH1F *h_ElectronDeltaEtaTrkSC_endcap_heep = new TH1F ("h_ElectronDeltaEtaTrkSC_endcap_heep","h_ElectronDeltaEtaTrkSC_endcap_heep",200,-0.05,0.05);
   TH1F *h_ElectronDeltaPhiTrkSC_endcap_heep = new TH1F ("h_ElectronDeltaPhiTrkSC_endcap_heep","h_ElectronDeltaPhiTrkSC_endcap_heep",200,-0.5,0.5);
   TH1F *h_ElectronHoE_endcap_heep = new TH1F ("h_ElectronHoE_endcap_heep","h_ElectronHoE_endcap_heep",75,0,0.15);
   TH1F *h_ElectronSigmaIEtaIEta_endcap_heep = new TH1F ("h_ElectronSigmaIEtaIEta_endcap_heep","h_ElectronSigmaIEtaIEta_endcap_heep",100,0,0.1);
   TH2F *h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep = new TH2F ("h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep"
									,"h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep"
									,100,0,1,100,0,1);
   TH2F *h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep 
     = new TH2F ("h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep"
		 ,"h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep"
		 ,100,0,500,500,0,100);
   TH1F *h_ElectronHcalIsoD2Heep_endcap_heep = new TH1F ("h_ElectronHcalIsoD2Heep_endcap_heep","h_ElectronHcalIsoD2Heep_endcap_heep",200,0,100);
   TH1F *h_ElectronTrkIsoHeep_endcap_heep = new TH1F ("h_ElectronTrkIsoHeep_endcap_heep","h_ElectronTrkIsoHeep_endcap_heep",200,0,100);

   h_ElectronPt_endcap_heep->Sumw2();
   h_ElectronSCEta_fabs_endcap_heep->Sumw2();
   h_ElectronDeltaEtaTrkSC_endcap_heep->Sumw2();
   h_ElectronDeltaPhiTrkSC_endcap_heep->Sumw2();
   h_ElectronHoE_endcap_heep->Sumw2();
   h_ElectronSigmaIEtaIEta_endcap_heep->Sumw2();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep->Sumw2();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep->Sumw2(); 
   h_ElectronHcalIsoD2Heep_endcap_heep->Sumw2();
   h_ElectronTrkIsoHeep_endcap_heep->Sumw2();


   //HEEP checks
   TH2F *h2_HEEPcheck_barrel = new TH2F ("h2_HEEPcheck_barrel","h2_HEEPcheck_barrel",2,-0.5,1.5,2,-0.5,1.5);
   TH2F *h2_HEEPcheck_endcap = new TH2F ("h2_HEEPcheck_endcap","h2_HEEPcheck_endcap",2,-0.5,1.5,2,-0.5,1.5);
   h2_HEEPcheck_barrel->Sumw2();
   h2_HEEPcheck_endcap->Sumw2();

   h2_HEEPcheck_barrel->GetXaxis()->SetTitle("HEEP flag");
   h2_HEEPcheck_barrel->GetYaxis()->SetTitle("HEEP emulation");

   h2_HEEPcheck_endcap->GetXaxis()->SetTitle("HEEP flag");
   h2_HEEPcheck_endcap->GetYaxis()->SetTitle("HEEP emulation");

   /////////initialize variables

   int printout = (int) getPreCutValue1("printout");

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

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event
     
     vector<int> v_idx_HeepElectrons;

     //Loop over electrons
     for(int ele=0; ele<ElectronPt->size(); ele++)
       {

	 int isBarrel = 0;
	 int isEndcap = 0;

	 if( fabs( ElectronSCEta->at(ele) ) < 1.442 ) 
	   isBarrel = 1;

	 if( fabs( ElectronSCEta->at(ele) ) > 1.560 && fabs( ElectronSCEta->at(ele) ) < 2.5 ) 
	   isEndcap = 1;
	     
	 if(isBarrel)
	   {
	     //HEEP flag
	     int passHEEPflag = 0;
	     if( ElectronHeepID->at(ele) == 0 )
	       {
		 passHEEPflag = 1;
		 v_idx_HeepElectrons.push_back(ele);       
	       }

	     //Emulate HEEP selection
	     int passHEEPemu = 0;
	     if(ElectronPt->at(ele) > 25 
		&& fabs(ElectronDeltaEtaTrkSC->at(ele)) < 0.005
		&& fabs(ElectronDeltaPhiTrkSC->at(ele)) < 0.09
		&& ElectronHoE->at(ele) < 0.05 
		&& (ElectronE2x5OverE5x5->at(ele) >0.94 || ElectronE1x5OverE5x5->at(ele) > 0.83 )
		&& ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele) < 2+0.03*ElectronPt->at(ele)
		&& ElectronTrkIsoHeep->at(ele) <7.5
		)
	       passHEEPemu = 1;

	     h2_HEEPcheck_barrel->Fill(passHEEPflag,passHEEPemu);
	      
	     h_ElectronPt_barrel_all->Fill( ElectronPt->at(ele) );
	     h_ElectronSCEta_fabs_barrel_all->Fill( fabs( ElectronSCEta->at(ele) ) );
	     h_ElectronDeltaEtaTrkSC_barrel_all->Fill( ElectronDeltaEtaTrkSC->at(ele) ) ;
	     h_ElectronDeltaPhiTrkSC_barrel_all->Fill( ElectronDeltaPhiTrkSC->at(ele) ) ;
	     h_ElectronHoE_barrel_all->Fill( ElectronHoE->at(ele) );
	     h_ElectronSigmaIEtaIEta_barrel_all->Fill( ElectronSigmaIEtaIEta->at(ele) );
	     h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all->Fill( ElectronE1x5OverE5x5->at(ele) , ElectronE2x5OverE5x5->at(ele) );
	     h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all
	       ->Fill( ElectronPt->at(ele) , ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele) );
	     h_ElectronHcalIsoD2Heep_barrel_all->Fill( ElectronHcalIsoD2Heep->at(ele) );
	     h_ElectronTrkIsoHeep_barrel_all->Fill( ElectronTrkIsoHeep->at(ele) );
	     
	     if( ElectronHeepID->at(ele) == 0 )
	       {
		 h_ElectronPt_barrel_heep->Fill( ElectronPt->at(ele) );
		 h_ElectronSCEta_fabs_barrel_heep->Fill( fabs(ElectronSCEta->at(ele)) );
		 h_ElectronDeltaEtaTrkSC_barrel_heep->Fill( ElectronDeltaEtaTrkSC->at(ele) ) ;
		 h_ElectronDeltaPhiTrkSC_barrel_heep->Fill( ElectronDeltaPhiTrkSC->at(ele) ) ;
		 h_ElectronHoE_barrel_heep->Fill( ElectronHoE->at(ele) );
		 h_ElectronSigmaIEtaIEta_barrel_heep->Fill( ElectronSigmaIEtaIEta->at(ele) );
		 h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep->Fill( ElectronE1x5OverE5x5->at(ele) , ElectronE2x5OverE5x5->at(ele) );
		 h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep
		   ->Fill( ElectronPt->at(ele) , ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele) );
		 h_ElectronHcalIsoD2Heep_barrel_heep->Fill( ElectronHcalIsoD2Heep->at(ele) );
		 h_ElectronTrkIsoHeep_barrel_heep->Fill( ElectronTrkIsoHeep->at(ele) );	       
	       }	     
	   }


	 if(isEndcap)
	   {
	     //HEEP flag
	     int passHEEPflag = 0;
	     if( ElectronHeepID->at(ele) == 0 )
	       {
		 passHEEPflag = 1;
		 v_idx_HeepElectrons.push_back(ele);       
	       }

	     //Emulate HEEP selection
	     int passHEEPemu = 0;

	     int passEcalHcalIsoCut=0;
	     if(ElectronPt->at(ele) < 50 && (ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele)) < 2.5)
	       passEcalHcalIsoCut=1;
	     if(ElectronPt->at(ele) > 50 && (ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele)) < 2.5+0.03*(ElectronPt->at(ele)-50) )
	       passEcalHcalIsoCut=1;

	     if(ElectronPt->at(ele) > 25 
		&& fabs(ElectronDeltaEtaTrkSC->at(ele)) < 0.007
		&& fabs(ElectronDeltaPhiTrkSC->at(ele)) < 0.09
		&& ElectronHoE->at(ele) < 0.05 
		&& ElectronSigmaIEtaIEta->at(ele) < 0.03
		&& passEcalHcalIsoCut == 1
		&& ElectronHcalIsoD2Heep->at(ele) < 0.5
		&& ElectronTrkIsoHeep->at(ele) < 15
		)
	       passHEEPemu = 1;

	     h2_HEEPcheck_endcap->Fill(passHEEPflag,passHEEPemu);

	     h_ElectronPt_endcap_all->Fill( ElectronPt->at(ele) );
	     h_ElectronSCEta_fabs_endcap_all->Fill( fabs(ElectronSCEta->at(ele)) );
	     h_ElectronDeltaEtaTrkSC_endcap_all->Fill( ElectronDeltaEtaTrkSC->at(ele) ) ;
	     h_ElectronDeltaPhiTrkSC_endcap_all->Fill( ElectronDeltaPhiTrkSC->at(ele) ) ;
	     h_ElectronHoE_endcap_all->Fill( ElectronHoE->at(ele) );
	     h_ElectronSigmaIEtaIEta_endcap_all->Fill( ElectronSigmaIEtaIEta->at(ele) );
	     h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all->Fill( ElectronE1x5OverE5x5->at(ele) , ElectronE2x5OverE5x5->at(ele) );
	     h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all
	       ->Fill( ElectronPt->at(ele) , ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele) );
	     h_ElectronHcalIsoD2Heep_endcap_all->Fill( ElectronHcalIsoD2Heep->at(ele) );
	     h_ElectronTrkIsoHeep_endcap_all->Fill( ElectronTrkIsoHeep->at(ele) );
	     
	     if( ElectronHeepID->at(ele) == 0 )
	       {
		 h_ElectronPt_endcap_heep->Fill( ElectronPt->at(ele) );
		 h_ElectronSCEta_fabs_endcap_heep->Fill( fabs(ElectronSCEta->at(ele)) );
		 h_ElectronDeltaEtaTrkSC_endcap_heep->Fill( ElectronDeltaEtaTrkSC->at(ele) ) ;
		 h_ElectronDeltaPhiTrkSC_endcap_heep->Fill( ElectronDeltaPhiTrkSC->at(ele) ) ;
		 h_ElectronHoE_endcap_heep->Fill( ElectronHoE->at(ele) );
		 h_ElectronSigmaIEtaIEta_endcap_heep->Fill( ElectronSigmaIEtaIEta->at(ele) );
		 h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep->Fill( ElectronE1x5OverE5x5->at(ele) , ElectronE2x5OverE5x5->at(ele) );
		 h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep
		   ->Fill( ElectronPt->at(ele) , ElectronEcalIsoHeep->at(ele)+ElectronHcalIsoD1Heep->at(ele) );
		 h_ElectronHcalIsoD2Heep_endcap_heep->Fill( ElectronHcalIsoD2Heep->at(ele) );
		 h_ElectronTrkIsoHeep_endcap_heep->Fill( ElectronTrkIsoHeep->at(ele) );	       
	       }	     
	   }
	 
       }

     // Set the evaluation of the cuts to false and clear the variable values and filled status
     resetCuts();
     
     // Set the value of the variableNames listed in the cutFile to their current value
     //fillVariableWithValue("nEleFinal", ElectronPt->size() ) ;
     fillVariableWithValue("nHeepEle", v_idx_HeepElectrons.size() ) ;
     fillVariableWithValue("CaloMET", CaloMET->at(0) ) ;
     fillVariableWithValue("TCMET", TCMET->at(0) ) ;
     fillVariableWithValue("PFMET", PFMET->at(0) ) ;

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // Fill histograms and do analysis based on cut evaluation


     //# Print run/event/ls + other info for events with Heep electrons
     if( passedCut("nHeepEle") && printout )
       {
	 
	 for(int ele=0; ele < v_idx_HeepElectrons.size(); ele++)
	   {
	     cout << "!!Heep Candidate!! -- " 
		  << "run: " << run << " lumi: " << ls 
		  << " event: " << event << " Et(GeV): " <<  ElectronPt->at( v_idx_HeepElectrons[ele] )
		  << " eta(SC): " << ElectronSCEta->at( v_idx_HeepElectrons[ele] )  
		  << " phi(SC): " << ElectronSCPhi->at( v_idx_HeepElectrons[ele] ) 
		  << " 1-eSwissCross/eMax: " << 1 - ElectronSCS4S1->at( v_idx_HeepElectrons[ele] )
		  << " -- CaloMET: " << CaloMET->at(0) 
		  << " TCMET: " << TCMET->at(0) 
		  << " PFMET: " << PFMET->at(0) 
		  << endl;	      
	   }

	 if( v_idx_HeepElectrons.size() >=2 )
	   {
	     cout << "-----------------" << endl;
	     cout << "!! Z Candidate !!" << endl;
	     cout << "-----------------" << endl;
	   }

       }

     //h_nEleFinal->Fill( ElectronPt->size() );
     

     //INFO
     //      // retrieve value of previously filled variables (after making sure that they were filled)
     //      double totpTEle;
     //      if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
     //        totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");
     //      // reject events that did not pass level 0 cuts
     //      if( !passedCut("0") ) continue;
     //      // ......

     
     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

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


   //h_nEleFinal->Write();

   //barrel - all
   h_ElectronPt_barrel_all->Write();
   h_ElectronSCEta_fabs_barrel_all->Write();
   h_ElectronDeltaEtaTrkSC_barrel_all->Write();
   h_ElectronDeltaPhiTrkSC_barrel_all->Write();
   h_ElectronHoE_barrel_all->Write();
   h_ElectronSigmaIEtaIEta_barrel_all->Write();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_all->Write();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_all->Write(); 
   h_ElectronHcalIsoD2Heep_barrel_all->Write();
   h_ElectronTrkIsoHeep_barrel_all->Write();

   //barrel - heep
   h_ElectronPt_barrel_heep->Write();
   h_ElectronSCEta_fabs_barrel_heep->Write();
   h_ElectronDeltaEtaTrkSC_barrel_heep->Write();
   h_ElectronDeltaPhiTrkSC_barrel_heep->Write();
   h_ElectronHoE_barrel_heep->Write();
   h_ElectronSigmaIEtaIEta_barrel_heep->Write();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_barrel_heep->Write();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_barrel_heep->Write(); 
   h_ElectronHcalIsoD2Heep_barrel_heep->Write();
   h_ElectronTrkIsoHeep_barrel_heep->Write();

   //endcap - all
   h_ElectronPt_endcap_all->Write();
   h_ElectronSCEta_fabs_endcap_all->Write();
   h_ElectronDeltaEtaTrkSC_endcap_all->Write();
   h_ElectronDeltaPhiTrkSC_endcap_all->Write();
   h_ElectronHoE_endcap_all->Write();
   h_ElectronSigmaIEtaIEta_endcap_all->Write();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_all->Write();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_all->Write(); 
   h_ElectronHcalIsoD2Heep_endcap_all->Write();
   h_ElectronTrkIsoHeep_endcap_all->Write();

   //endcap - heep
   h_ElectronPt_endcap_heep->Write();
   h_ElectronSCEta_fabs_endcap_heep->Write();
   h_ElectronDeltaEtaTrkSC_endcap_heep->Write();
   h_ElectronDeltaPhiTrkSC_endcap_heep->Write();
   h_ElectronHoE_endcap_heep->Write();
   h_ElectronSigmaIEtaIEta_endcap_heep->Write();
   h2_ElectronE2x5OverE5x5_vs_E1x5OverE5x5_endcap_heep->Write();
   h2_ElectronEcalIsoHeep_plus_HcalIsoD1Heep_vs_ElectronPt_endcap_heep->Write(); 
   h_ElectronHcalIsoD2Heep_endcap_heep->Write();
   h_ElectronTrkIsoHeep_endcap_heep->Write();

   //HEEP checks
   h2_HEEPcheck_barrel->Write();
   h2_HEEPcheck_endcap->Write();

   //INFO
   //    //pT of both electrons, to be built using the histograms produced automatically by baseClass
   //    TH1F * h_pTElectrons = new TH1F ("h_pTElectrons","", getHistoNBins("pT1stEle"), getHistoMin("pT1stEle"), getHistoMax("pT1stEle"));
   //    h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT1stEle") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   //    h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT2ndEle") );
   //    //one could also do:  *h_pTElectrons = getHisto_noCuts_or_skim("pT1stEle") + getHisto_noCuts_or_skim("pT2ndEle");
   //    h_pTElectrons->Write();
   //    //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h
   
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}