void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
   TStopwatch time;
   frame("Starting the analysis");
   time.Start(true);
   setTDRStyle();
   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();

   /////////initialize variables

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

   double lepton_mass;
   std::vector <int> goodLepton, looseLepton, goodAK08, goodAK04, goodAK08_lep, goodAK04_lep, goodAK08Pruned, goodEle, goodMuon, looseEle, looseMuon;
   TLorentzVector genW, ak04, ak08, ak08Pruned, lepton, leptonLoose, W, MET, wGenQ1, wGenQ2, wGenSumi, subjet1, subjet2, subjetSum, wGenSum, bGen1, bGen2;
   int btag_ak04_loose, btag_ak04_medium, btag_ak04_tight;
   int subjet_index1, subjet_index2;
   ////// 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%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
     btag_ak04_loose=0;
     btag_ak04_medium=0;
     btag_ak04_tight=0;
     goodLepton.clear();
     looseLepton.clear();
     goodAK04.clear();
     goodAK08.clear();
     goodAK08_lep.clear();
     goodAK04_lep.clear();
     goodAK08Pruned.clear();
     goodEle.clear();
     goodMuon.clear();
     looseEle.clear();
     looseMuon.clear();

     resetCuts();
   

//=== Forse da inserire ===

/*     fillVariableWithValue("run",runNo);     
     fillVariableWithValue("event",evtNo);     
     fillVariableWithValue("lumi",lumi);     
     fillVariableWithValue("nVtx",nvtx);     
     fillVariableWithValue("nJet",widejets.size());
*/
    

    for(int i=0; i<nselLeptons; ++i){
      if((abs(selLeptons_pdgId[i])==11 && selLeptons_isMyGoodElectron[i]==1 && selLeptons_pt[i]>30 && (abs(selLeptons_eta[i])<1.442 || (abs(selLeptons_eta[i])>1.56 && abs(selLeptons_eta[i])<2.5))) || (abs(selLeptons_pdgId[i])==13 && selLeptons_isMyGoodMuon[i]==1 && selLeptons_pt[i]>30 && abs(selLeptons_eta[i])<2.1)){// && selLeptons_relIso03[0]<0.1)){
        goodLepton.push_back(i);
        //std::cout<<"Passing tight selection"<<std::endl;
        CreateAndFillUserTH1D("goodEleTightSelection", 2,-.5,1.5, 1);
      }//end if 'good' lepton cuts
      else if(((abs(selLeptons_pdgId[i])==11 && selLeptons_isMyGoodElectron[i]==1 && selLeptons_pt[i]>35 && (abs(selLeptons_eta[i])<1.442 || (abs(selLeptons_eta[i])>1.56 && abs(selLeptons_eta[i])<2.5))) || (abs(selLeptons_pdgId[i])==13 && selLeptons_isMyGoodMuon[i]==1 && selLeptons_pt[i]>20 && abs(selLeptons_eta[i])<2.1))){// && selLeptons_relIso03[i]<0.1))){
        looseLepton.push_back(i);
        //if(abs(selLeptons_pdgId[i])==11) lepton_mass=e_mass;
        //if(abs(selLeptons_pdgId[i])==13) lepton_mass=mu_mass;
        //leptonLoose.SetPtEtaPhiM(selLeptons_pt[i],selLeptons_eta[i],selLeptons_phi[i], lepton_mass);
      }//end if loose lepton
      if(abs(selLeptons_pdgId[i])==13 && selLeptons_isMyGoodMuon[i]==1 && selLeptons_pt[i]>53 && abs(selLeptons_eta[i])<2.1 && (selLeptons_muTrackIso[i]/selLeptons_pt[i])<0.1){
        goodMuon.push_back(i);
      }
      else if(abs(selLeptons_pdgId[i])==13 && selLeptons_isMyGoodMuon[i]==1 && selLeptons_pt[i]>20 && abs(selLeptons_eta[i])<2.4 && (selLeptons_muTrackIso[i]/selLeptons_pt[i])<0.1){
        // if(abs(selLeptons_pdgId[i])==13 && selLeptons_isMyGoodMuon[i]==1 && selLeptons_pt[i]>53 && abs(selLeptons_eta[i])<2.1 && (selLeptons_muTrackIso[i]/selLeptons_pt[i])<0.1){
        looseMuon.push_back(i);
        
      }
      if(abs(selLeptons_pdgId[i])==11 && selLeptons_isMyGoodElectron[i]==1 && selLeptons_pt[i]>120 && abs(selLeptons_eta[i])<2.1){
        goodEle.push_back(i);
      }else if((abs(selLeptons_pdgId[i])==11 && selLeptons_isMyGoodElectron[i]==1 && selLeptons_pt[i]>35 && abs(selLeptons_eta[i])<2.4)){
        looseEle.push_back(i);
      }
    }//end if nselLeptons

    for(int i=0; i<nFatjetAK08ungroomed;++i){
      if((((FatjetAK08ungroomed_neHEFrac[i]<0.99 && FatjetAK08ungroomed_neEmEFrac[i]<0.99 && (FatjetAK08ungroomed_chMult[i]+FatjetAK08ungroomed_neMult[i])>1) && ((abs(FatjetAK08ungroomed_eta[i])<=2.4 && FatjetAK08ungroomed_chHEFrac[i]>0 && FatjetAK08ungroomed_chMult[i]>0 && FatjetAK08ungroomed_chEmEFrac[i]<0.99) || abs(FatjetAK08ungroomed_eta[i])>2.4) && abs(FatjetAK08ungroomed_eta[i])<=3.0)||((FatjetAK08ungroomed_neEmEFrac[i]<0.90 && FatjetAK08ungroomed_neMult[i]>10 && abs(FatjetAK08ungroomed_eta[i])>3.0 ))) && FatjetAK08ungroomed_pt[i]>100 && abs(FatjetAK08ungroomed_eta[i])<2.4){
        goodAK08.push_back(i);
      }//end if good AK08
    }//end loop over nFatjetAK08ungroomed

    for(int i=0; i<nJet; ++i){
      if((((Jet_neHEF[i]<0.99 && Jet_neEmEF[i]<0.99 && (Jet_chMult[i]+Jet_neMult[i])>1) && ((abs(Jet_eta[i])<=2.4 && Jet_chHEF[i]>0 && Jet_chMult[i]>0 && Jet_chEmEF[i]<0.99) || abs(Jet_eta[i])>2.4) && abs(Jet_eta[i])<=3.0)||((Jet_neEmEF[i]<0.90 && Jet_neMult[i]>10 && abs(Jet_eta[i])>3.0 ))) && Jet_pt[i]>30 && abs(Jet_eta[i])<2.4){
        CreateAndFillUserTH1D("goodAk04LooseSelection", 2,-.5,1.5, 1);
        goodAK04.push_back(i);
      }
    }//end loop over nJet

    fillVariableWithValue("lepton_goodNumber", goodLepton.size());
    fillVariableWithValue("lepton_looseNumber", looseLepton.size());
    fillVariableWithValue("ak08_goodNumber", goodAK08.size());
    fillVariableWithValue("nLepton",nselLeptons);
    fillVariableWithValue("nGoodEle", goodEle.size());
    fillVariableWithValue("nLooseEle", looseEle.size());
    fillVariableWithValue("nGoodMuon", goodMuon.size());
    fillVariableWithValue("nLooseMuon", looseMuon.size());
    if(goodAK08.size()>=1){
      fillVariableWithValue("ak08Ungroomed_1_pt", FatjetAK08ungroomed_pt[goodAK08[0]]);
      fillVariableWithValue("ak08Ungroomed_1_eta", FatjetAK08ungroomed_eta[goodAK08[0]]);
      fillVariableWithValue("ak08Ungroomed_1_phi", FatjetAK08ungroomed_phi[goodAK08[0]]);
      fillVariableWithValue("ak08Ungroomed_1_mass", FatjetAK08ungroomed_mass[goodAK08[0]]);
      fillVariableWithValue("ak08Ungroomed_1_tau21", FatjetAK08ungroomed_tau2[goodAK08[0]]/FatjetAK08ungroomed_tau1[goodAK08[0]]);
      ak08.SetPtEtaPhiM(FatjetAK08ungroomed_pt[goodAK08[0]], FatjetAK08ungroomed_eta[goodAK08[0]], FatjetAK08ungroomed_phi[goodAK08[0]], FatjetAK08ungroomed_mass[goodAK08[0]]);
      double minDR_subjetJet=999.;
      subjet_index1=subjet_index2=0;
      for(int s=0; s<nSubjetAK08pruned; ++s){
        subjet1.SetPtEtaPhiM(SubjetAK08pruned_pt[s], SubjetAK08pruned_eta[s], SubjetAK08pruned_phi[s], SubjetAK08pruned_mass[s]);
        for(int ss=0; ss<nSubjetAK08pruned; ++ss){
          if(ss!=s){
            subjet2.SetPtEtaPhiM(SubjetAK08pruned_pt[ss], SubjetAK08pruned_eta[ss], SubjetAK08pruned_phi[ss], SubjetAK08pruned_mass[ss]);
            subjetSum=subjet1+subjet2;
            if(subjetSum.DeltaR(ak08)){
              minDR_subjetJet=subjetSum.DeltaR(ak08);
              subjet_index1=s;
              subjet_index2=ss;
            }
          }
        }
      }//end loop over subjets
      fillVariableWithValue("ak08_subjetDR", minDR_subjetJet);
      if(nSubjetAK08pruned>0){
        subjet1.SetPtEtaPhiM(SubjetAK08pruned_pt[subjet_index1], SubjetAK08pruned_eta[subjet_index1], SubjetAK08pruned_phi[subjet_index1], SubjetAK08pruned_mass[subjet_index1]);
        subjet2.SetPtEtaPhiM(SubjetAK08pruned_pt[subjet_index2], SubjetAK08pruned_eta[subjet_index2], SubjetAK08pruned_phi[subjet_index2], SubjetAK08pruned_mass[subjet_index2]);
        if(SubjetAK08pruned_btag[subjet_index1]>0.605) fillVariableWithValue("subjet1_btagLoose", 1);
        if(SubjetAK08pruned_btag[subjet_index1]>0.89) fillVariableWithValue("subjet1_btagMedium", 1);
        if(SubjetAK08pruned_btag[subjet_index1]>0.97) fillVariableWithValue("subjet1_btagTight", 1);
        if(SubjetAK08pruned_btag[subjet_index2]>0.605) fillVariableWithValue("subjet2_btagLoose", 1);
        if(SubjetAK08pruned_btag[subjet_index2]>0.89) fillVariableWithValue("subjet2_btagMedium", 1);
        if(SubjetAK08pruned_btag[subjet_index2]>0.97) fillVariableWithValue("subjet2_btagTight", 1);
        fillVariableWithValue("subjetDR", subjet1.DeltaR(subjet2));
        fillVariableWithValue("subjet1_pt", SubjetAK08pruned_pt[subjet_index1]);
        fillVariableWithValue("subjet1_eta", SubjetAK08pruned_eta[subjet_index1]);
        fillVariableWithValue("subjet1_phi", SubjetAK08pruned_phi[subjet_index1]);
        fillVariableWithValue("subjet2_pt", SubjetAK08pruned_pt[subjet_index2]);
        fillVariableWithValue("subjet2_eta", SubjetAK08pruned_eta[subjet_index2]);
        fillVariableWithValue("subjet2_phi", SubjetAK08pruned_phi[subjet_index2]);

      }
      double minDR_W=999;
      int w_counter=0;
      if(isData==0){
        if(nGenWZQuark==2){
          wGenQ1.SetPtEtaPhiM(GenWZQuark_pt[0], GenWZQuark_eta[0], GenWZQuark_phi[0], GenWZQuark_mass[0]);
          wGenQ2.SetPtEtaPhiM(GenWZQuark_pt[1], GenWZQuark_eta[1], GenWZQuark_phi[1], GenWZQuark_mass[1]);
          fillVariableWithValue("genQ1_pt", GenWZQuark_pt[0]);
          fillVariableWithValue("genQ1_eta", GenWZQuark_eta[0]);
          fillVariableWithValue("genQ1_phi", GenWZQuark_phi[0]);
          fillVariableWithValue("genQ2_pt", GenWZQuark_pt[1]);
          fillVariableWithValue("genQ2_eta", GenWZQuark_eta[1]);
          fillVariableWithValue("genQ2_phi", GenWZQuark_phi[1]);
          fillVariableWithValue("genQ_DR", wGenQ1.DeltaR(wGenQ2));
          if(nSubjetAK08pruned>0){
            fillVariableWithValue("subjet1_qGen1_DR", TMath::Min(wGenQ1.DeltaR(subjet1), wGenQ2.DeltaR(subjet1)));
            fillVariableWithValue("subjet2_qGen2_DR", TMath::Min(wGenQ1.DeltaR(subjet2), wGenQ2.DeltaR(subjet2)));
            //std::cout<<"1. "<<TMath::Min(wGenQ1.DeltaR(subjet1), wGenQ2.DeltaR(subjet1))<<std::endl;
            //std::cout<<"2. "<<TMath::Min(wGenQ1.DeltaR(subjet2), wGenQ2.DeltaR(subjet2))<<std::endl;
          }else{
            fillVariableWithValue("subjet1_qGen1_DR", -1);
            fillVariableWithValue("subjet2_qGen2_DR", -1);
          }
          wGenSum=wGenQ1+wGenQ2;
          for (int w=0; w<nGenVbosons; ++w){
            if(abs(GenVbosons_pdgId[w])==24){
              genW.SetPtEtaPhiM(GenVbosons_pt[w], GenVbosons_eta[w], GenVbosons_phi[w], W_mass);
              if(goodLepton.size()>=1){
                if(abs(selLeptons_pdgId[goodLepton[0]])==11) lepton_mass=e_mass;
                if(abs(selLeptons_pdgId[goodLepton[0]])==13) lepton_mass=mu_mass;
                  lepton.SetPtEtaPhiM(selLeptons_pt[goodLepton[0]],selLeptons_eta[goodLepton[0]],selLeptons_phi[goodLepton[0]], lepton_mass);
              } 
              if(wGenSum.DeltaR(genW)<minDR_W){
                minDR_W=wGenSum.DeltaR(genW);
                w_counter=w;
              }
           }//if gen Boson==W
          }
          genW.SetPtEtaPhiM(GenVbosons_pt[w_counter], GenVbosons_eta[w_counter], GenVbosons_phi[w_counter], W_mass);
          fillVariableWithValue("ak08Ungroomed_WGen_DR",ak08.DeltaR(genW));
          fillVariableWithValue("WGen_quark_DR", minDR_W);
          fillVariableWithValue("W_Gen_pt", GenVbosons_pt[w_counter]);
          fillVariableWithValue("W_Gen_eta", GenVbosons_eta[w_counter]);
          fillVariableWithValue("W_Gen_phi", GenVbosons_phi[w_counter]);
          fillVariableWithValue("lepton_WGen_DR", lepton.DeltaR(genW));
          bGen1.SetPtEtaPhiM(GenBQuarkFromTop_pt[0],GenBQuarkFromTop_eta[0],GenBQuarkFromTop_phi[0],GenBQuarkFromTop_mass[0]);
          bGen2.SetPtEtaPhiM(GenBQuarkFromTop_pt[1],GenBQuarkFromTop_eta[1],GenBQuarkFromTop_phi[1],GenBQuarkFromTop_mass[1]);
          fillVariableWithValue("genW_genBquark1_DR", genW.DeltaR(bGen1));
          fillVariableWithValue("genW_genBquarkMin_DR", TMath::Min(genW.DeltaR(bGen1), genW.DeltaR(bGen2)));
          fillVariableWithValue("genW_genBquarkMax_DR", TMath::Max(genW.DeltaR(bGen1), genW.DeltaR(bGen2)));
          //std::cout<<"1. "<<genW.DeltaR(bGen1)<<std::endl;
          fillVariableWithValue("genW_genBquark2_DR", genW.DeltaR(bGen2));
         // std::cout<<"2. "<<genW.DeltaR(bGen2)<<std::endl;
        }else{//end if 2 quarks from VBosons
          fillVariableWithValue("subjet1_qGen1_DR", -1);
          fillVariableWithValue("subjet2_qGen2_DR", -1);
        }
      }//end if isData
      else{
        fillVariableWithValue("ak08Ungroomed_WGen_DR",minDR_W);
        fillVariableWithValue("lepton_WGen_DR", minDR_W);
      }
      double dr_tmp=99;
      int index=0;
      for(int ii=0; ii<nFatjetAK08pruned; ++ii){
        ak08Pruned.SetPtEtaPhiM(FatjetAK08pruned_pt[ii],FatjetAK08pruned_eta[ii], FatjetAK08pruned_phi[ii], FatjetAK08pruned_mass[ii]);
        if(ak08.DeltaR(ak08Pruned)<dr_tmp){
          dr_tmp=ak08.DeltaR(ak08Pruned);
          index=ii;
        }//matched good pruned AK08
        goodAK08Pruned.push_back(index);
      }//end loop over nFatjetAK08pruned

    }//end if ak08GoodUngroomed jet
    else{
      fillVariableWithValue("ak08Ungroomed_WGen_DR",999);
    }

    if(goodLepton.size()>=1){
      if(abs(selLeptons_pdgId[goodLepton[0]])==11) lepton_mass=e_mass;
      if(abs(selLeptons_pdgId[goodLepton[0]])==13) lepton_mass=mu_mass;
      lepton.SetPtEtaPhiM(selLeptons_pt[goodLepton[0]],selLeptons_eta[goodLepton[0]],selLeptons_phi[goodLepton[0]], lepton_mass);
      fillVariableWithValue("lepton_pt", selLeptons_pt[goodLepton[0]]);
      fillVariableWithValue("lepton_eta", selLeptons_eta[goodLepton[0]]);
      fillVariableWithValue("lepton_phi", selLeptons_phi[goodLepton[0]]);
      fillVariableWithValue("lepton_pdgID", selLeptons_pdgId[goodLepton[0]]);
      fillVariableWithValue("muonRelIso03", selLeptons_relIso03[0]);
      fillVariableWithValue("muontrkIso", selLeptons_muTrackIso[0]);
      MET.SetPtEtaPhiM(met_pt, met_eta, met_phi, 0);
      W=lepton+MET;
      fillVariableWithValue("W_pt", W.Pt());
      fillVariableWithValue("W_eta",W.Eta());
      fillVariableWithValue("W_phi",W.Phi());
      fillVariableWithValue("W_mT", 2*abs(MET.Pt())*abs(lepton.Pt())*(1-cos(lepton.DeltaPhi(MET))));
      //fillVariableWithValue("W_mT",W.Mt());
      MET.SetPtEtaPhiM(metType1p2_pt, met_eta, met_phi, 0);
      W=lepton+MET;
      fillVariableWithValue("WType1_pt", W.Pt());
      fillVariableWithValue("WType1_eta",W.Eta());
      fillVariableWithValue("WType1_phi",W.Phi());
      fillVariableWithValue("W_mT", 2*abs(MET.Pt())*abs(lepton.Pt())*(1-cos(lepton.DeltaPhi(MET))));
      //fillVariableWithValue("WType1_mT",W.Mt());
      //MET.SetPtEtaPhiM(metPuppi_pt, met_eta, met_phi, 0); 
      //W=lepton+MET;
      //fillVariableWithValue("WPuppi_pt", W.Pt());
      //fillVariableWithValue("WPuppi_eta",W.Eta());
      //fillVariableWithValue("WPuppi_phi",W.Phi());
      //fillVariableWithValue("W_mT", 2*abs(MET.Pt())*abs(lepton.Pt())*(1-cos(lepton.DeltaPhi(MET))));
      //fillVariableWithValue("WPuppi_mT",W.Mt());

      if(goodAK08.size()>1) fillVariableWithValue("ak08Ungroomed_lepton_DR", lepton.DeltaR(ak08));
      fillVariableWithValue("nAK04", goodAK04.size());
        for(int j=0; j<goodAK04.size(); ++j){
          ak04.SetPtEtaPhiM(Jet_pt[goodAK04[j]], Jet_eta[goodAK04[j]], Jet_phi[goodAK04[j]], Jet_mass[goodAK04[j]]);
          if(ak04.DeltaR(ak08)>.8 && ak04.DeltaR(lepton)>.3){
            CreateAndFillUserTH1D("Ak04_lepton&AK08_DRCut", 2,-.5,1.5, 1);
            goodAK04_lep.push_back(goodAK04[j]);
            if(Jet_btagCSV[goodAK04[j]]>0.605){
              ++btag_ak04_loose;
            }
            if(Jet_btagCSV[goodAK04[j]]>0.890){
              ++btag_ak04_medium;
            }
            if(Jet_btagCSV[goodAK04[j]]>0.97){
              ++btag_ak04_tight;
            }//end if for CSV medium working point
          }//end if ak04 without leptons and ak08 nearby
        }//end loop over goodAK04.size()

      }//end loop over goodLepton.size()
      if(goodLepton.size()>=2){
        fillVariableWithValue("lepton2_pt", selLeptons_pt[goodLepton[1]]);
        fillVariableWithValue("lepton2_eta", selLeptons_eta[goodLepton[1]]);
        fillVariableWithValue("lepton2_phi", selLeptons_phi[goodLepton[1]]);
        fillVariableWithValue("lepton2_pdgID", selLeptons_pdgId[goodLepton[1]]);
      }
      fillVariableWithValue("btag_loose",btag_ak04_loose);
      fillVariableWithValue("btag_medium",btag_ak04_medium);
      fillVariableWithValue("btag_tight",btag_ak04_tight);
      if(goodAK08Pruned.size()>=1){
        fillVariableWithValue("ak08Pruned_1_pt", FatjetAK08pruned_pt[goodAK08Pruned[0]]);
        fillVariableWithValue("ak08Pruned_1_eta", FatjetAK08pruned_eta[goodAK08Pruned[0]]);
        fillVariableWithValue("ak08Pruned_1_phi", FatjetAK08pruned_phi[goodAK08Pruned[0]]);
        fillVariableWithValue("ak08Pruned_1_mass", FatjetAK08pruned_mass[goodAK08Pruned[0]]);
      }
      if(goodAK08Pruned.size()>=2){
        fillVariableWithValue("ak08Pruned_2_pt", FatjetAK08pruned_pt[goodAK08Pruned[1]]);
        fillVariableWithValue("ak08Pruned_2_eta", FatjetAK08pruned_eta[goodAK08Pruned[1]]);
        fillVariableWithValue("ak08Pruned_2_phi", FatjetAK08pruned_phi[goodAK08Pruned[1]]);
        fillVariableWithValue("ak08Pruned_2_mass", FatjetAK08pruned_mass[goodAK08Pruned[1]]);
      }
      if(goodAK04_lep.size()>=1){
        fillVariableWithValue("ak04_1_pt", Jet_pt[goodAK04_lep[0]]);
        fillVariableWithValue("ak04_1_eta", Jet_eta[goodAK04_lep[0]]);
        fillVariableWithValue("ak04_1_phi", Jet_phi[goodAK04_lep[0]]);
        fillVariableWithValue("ak04_1_mass", Jet_mass[goodAK04_lep[0]]);
        //=== TH1D to check the fillReduceSkim procedure ===
        CreateAndFillUserTH1D("ak04_first_pt", 1000,0,500, Jet_pt[goodAK04_lep[0]]);
      }
      if(goodAK04_lep.size()>=2){
        fillVariableWithValue("ak04_2_pt", Jet_pt[goodAK04_lep[1]]);
        fillVariableWithValue("ak04_2_eta", Jet_eta[goodAK04_lep[1]]);
        fillVariableWithValue("ak04_2_phi", Jet_phi[goodAK04_lep[1]]);
        fillVariableWithValue("ak04_2_mass", Jet_mass[goodAK04_lep[1]]);
      }
      //fillVariableWithValue("metPuppi",metPuppi_pt);
      fillVariableWithValue("metType1", metType1p2_pt);
      fillVariableWithValue("met",met_pt);
      fillVariableWithValue("nPrimaryVertexes", nPVs);
      fillVariableWithValue("Mu45_TRG", HLT_HLT_Mu45_eta2p1);
      fillVariableWithValue("Mu50_TRG", HLT_HLT_Mu50);
      fillVariableWithValue("HBHE", Flag_HBHENoiseFilter);
      fillVariableWithValue("HBHE_IsoFilter", Flag_hbheIsoFilter);
      fillVariableWithValue("CSC_filter",Flag_CSCTightHaloFilter);
      fillVariableWithValue("eeBADFilter", Flag_eeBadScFilter);
      fillVariableWithValue("run", run);
      fillVariableWithValue("nBtag_gen",nGenBQuarkFromTop); 



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

     // 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( passedAllPreviousCuts("mjj") && passedCut("mjj") ) 
     if( passedCut("met"))//passedAllPreviousCuts("eeBADFilter") && passedCut("eeBADFilter"))
       {
         //frame("Beware! This part can be set outside the if -Passed cuts-");
	 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_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;   
   std::cout<<""<<std::endl;
   std::cout << "------ TIME ELAPSED DURING ANALYSIS  ----- " << time.RealTime() << " s" <<std::endl;
   std::cout<<""<<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;   

  srand48( time(0) );    
  if (fChain == 0) return;
   
  //////////book histos here


  /////////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++) { // running over all events
    //   for (Long64_t jentry=0; jentry<25;jentry++) { //runnig over few events for test
    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;   
    //std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
    // if (Cut(ientry) < 0) continue;
   
    ////////////////////// User's code starts here ///////////////////////

    //     verbose = true;

    if(verbose){
      std::cout<< std::endl;
      std::cout<<"Start"<< std::endl;
      std::cout<<"PassJSON "<< PassJSON<<std::endl;

      std::cout<<"RECO"<< std::endl;
      std::cout<<"AK4 jet1"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_recoj1<<" eta: "<<etaAK4_recoj1<<" phi: "<<phiAK4_recoj1<< std::endl;
      std::cout<<"AK4 jet2"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_recoj2<<" eta: "<<etaAK4_recoj2<<" phi: "<<phiAK4_recoj2<< std::endl;
      std::cout<<"AK4 jet3"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_recoj3<<" eta: "<<etaAK4_recoj3<<" phi: "<<phiAK4_recoj3<< std::endl;

      std::cout<<"HLT"<< std::endl;
      std::cout<<"AK4 jet1"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_j1<<" eta: "<<etaAK4_j1<<" phi: "<<phiAK4_j1<< std::endl;
      std::cout<<"AK4 jet2"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_j2<<" eta: "<<etaAK4_j2<<" phi: "<<phiAK4_j2<< std::endl;
      std::cout<<"AK4 jet3"<< std::endl;
      std::cout<<"Pt: "<< pTAK4_j3<<" eta: "<<etaAK4_j3<<" phi: "<<phiAK4_j3<< std::endl;
    }
     
    //     if(PassJSON) 	   std::cout<<"Passed JSON"<< std::endl;
    //     if( mjjreco > MJJCut_ && mjj > MJJCut_ ) 	   std::cout<<"Passed MJJ"<< std::endl;
    //     if( deltaETAjjreco < DeltaEtaJJ_ && deltaETAjj < DeltaEtaJJ_) std::cout<<"Passed deltaEta"<< std::endl;

    //  if( passHLT_ZeroBias_BtagSeq || passHLT_ZeroBias || passHLT_L1DoubleMu_BtagSeq || passHLT_L1DoubleMu || passHLT_CaloJet40_BtagSeq || passHLT_CaloJet40 || passHLT_L1HTT150_BtagSeq || passHLT_L1HTT150 || passHLT_CaloScoutingHT250 || passHLT_HT450_BtagSeq || passHLT_HT450 || passHLT_PFHT800 || passHLT_PFHT650MJJ950 || passHLT_PFHT650MJJ900 ){

    if( PassJSON){
      // trigger selected
      //   if( passHLT_ZeroBias_BtagSeq || passHLT_ZeroBias ){ // #1
      //   if( passHLT_L1DoubleMu_BtagSeq || passHLT_L1DoubleMu ){ // #2
      //   if( passHLT_CaloJet40_BtagSeq || passHLT_CaloJet40 ){ // #3
      //   if( passHLT_L1HTT150_BtagSeq || passHLT_L1HTT150 ){ // #4
      //   if( passHLT_CaloScoutingHT250 ){ // #5
      if( passHLT_HT450_BtagSeq || passHLT_HT450 ){ // #6
	 
	// AK4 Jets
	vector<TLorentzVector> AK4recojets;
	TLorentzVector ak4j1Reco, ak4j2Reco, ak4dijetReco;             
	TLorentzVector ak4j3Reco ;
	   
	vector<TLorentzVector> AK4jets;
	TLorentzVector ak4j1, ak4j2, ak4dijet;      
	TLorentzVector ak4j3 ; 
       
	// Reco
	ak4j1Reco.SetPtEtaPhiM(pTAK4_recoj1, etaAK4_recoj1, phiAK4_recoj1, massAK4_recoj1);
	ak4j2Reco.SetPtEtaPhiM(pTAK4_recoj2, etaAK4_recoj2, phiAK4_recoj2, massAK4_recoj2);
	ak4j3Reco.SetPtEtaPhiM(pTAK4_recoj3, etaAK4_recoj3, phiAK4_recoj3, massAK4_recoj3);
	AK4recojets.push_back( ak4j1Reco );
	AK4recojets.push_back( ak4j2Reco );	 
	AK4recojets.push_back( ak4j3Reco );	 
       
	// HLT
	ak4j1.SetPtEtaPhiM(pTAK4_j1, etaAK4_j1, phiAK4_j1, massAK4_j1);
	ak4j2.SetPtEtaPhiM(pTAK4_j2, etaAK4_j2, phiAK4_j2, massAK4_j2);
	ak4j3.SetPtEtaPhiM(pTAK4_j3, etaAK4_j3, phiAK4_j3, massAK4_j3);
	AK4jets.push_back( ak4j1 );
	AK4jets.push_back( ak4j2 );
	AK4jets.push_back( ak4j3 );

	//////////// matching	 
	double DeltaReco1HLT1 = AK4recojets[0].DeltaR(AK4jets[0]);
	double DeltaReco1HLT2 = AK4recojets[0].DeltaR(AK4jets[1]);
	double DeltaReco2HLT1 = AK4recojets[1].DeltaR(AK4jets[0]);
	double DeltaReco2HLT2 = AK4recojets[1].DeltaR(AK4jets[1]);
	     
	if(verbose){
	  //	   cout << endl;
	  cout << "AK4: " << endl;
	  cout << "deltaR Reco1-HLT1 " <<  DeltaReco1HLT1 << endl;
	  cout << "deltaR Reco1-HLT2 " <<  DeltaReco1HLT2 << endl;
	  cout << "deltaR Reco2-HLT1 " <<  DeltaReco2HLT1 << endl;
	  cout << "deltaR Reco2-HLT2 " <<  DeltaReco2HLT2 << endl;
	}       
	     
	vector<int> IdxMatched;
	vector<double> deltaR_min;
	if( DeltaReco1HLT1 <= DeltaReco2HLT1 )
	  {
	    IdxMatched.push_back(0) ; // index Reco jets
	    IdxMatched.push_back(1) ; // index Reco jets
	    deltaR_min.push_back( DeltaReco1HLT1);
	    deltaR_min.push_back( DeltaReco2HLT2);
	  }else
	  {
	    IdxMatched.push_back(1) ; // index Reco jets
	    IdxMatched.push_back(0) ; // index Reco jets
	    deltaR_min.push_back( DeltaReco2HLT1);
	    deltaR_min.push_back( DeltaReco1HLT2);
	  }

	// HLT-Reco Matched : AK4
	if(verbose) cout << "deltaR_min_1_1 " << deltaR_min.at(0)  << endl;
	if(verbose) cout << "deltaR_min_2_2 " << deltaR_min.at(1)  << endl;

	// Asymmetry
	if(deltaR_min.at(0) < DeltaR_ && deltaR_min.at(1) < DeltaR_ ){   

	  int random;
	  random = lrand48()%(2);
	  if(verbose) std::cout<< "random = " <<random << std::endl;
	       
	  double pTaveReco = ( ak4j1Reco.Pt() + ak4j2Reco.Pt() ) / 2;
	  if(verbose) std::cout<< "Average pT Reco = " << pTaveReco << std::endl;
	  CreateAndFillUserTH1D("pTaveReco", 30 , 0, 3000, pTaveReco);	     
	  double alphaReco = ak4j3Reco.Pt() / pTaveReco ;
	  if(verbose) std::cout<< "alpha Reco = " << alphaReco << std::endl;
	  CreateAndFillUserTH1D("alphaReco", 100 , 0, 2, alphaReco);
	  double AsymmetryReco;

	  EtaBinning mEtaBinning;                                                                                                               
	  PtBinning mPtBinning; 
	     
	  int etaBin_j1Reco = mEtaBinning.getBin( fabs(ak4j1Reco.Eta()) );
	  int etaBin_j2Reco = mEtaBinning.getBin( fabs(ak4j2Reco.Eta()) );
	  int ptBin_Reco = mPtBinning.getPtBin( pTaveReco );
	  std::pair<float, float> ptBins_Reco = mPtBinning.getBinValue(ptBin_Reco);

	  if(verbose){       
	    cout<<"|Eta_ak4j1Reco| =   "<<fabs(ak4j1Reco.Eta())<<endl;
	    cout<<"|Eta_ak4j2Reco| =   "<<fabs(ak4j2Reco.Eta())<<endl;

	    std::pair<float, float> etaBins_j1 = mEtaBinning.getBinValue(etaBin_j1Reco);
	    std::pair<float, float> etaBins_j2 = mEtaBinning.getBinValue(etaBin_j2Reco);
	    cout<<"EtaBin_j1 =   "<<etaBin_j1Reco<<endl;
	    cout<<"EtaBin_j2 =   "<<etaBin_j2Reco<<endl;
	    cout<<"pTBin =   "<<ptBin_Reco<<endl;
	    cout<<"j1: etaBin.first  "<< etaBins_j1.first << "    etaBin.second   "<<etaBins_j1.second<<endl;
	    cout<<"j2: etaBin.first  "<< etaBins_j2.first << "    etaBin.second   "<<etaBins_j2.second<<endl;
	    cout<<"ptBin.first  "<< ptBins_Reco.first << "    ptBin.second   "<<ptBins_Reco.second<<endl;
	  }

	  /// HLT
	  double pTave = ( ak4j1.Pt() + ak4j2.Pt() ) /2;
	  if(verbose) std::cout<< "Average pT = " << pTave << std::endl;
	  CreateAndFillUserTH1D("pTave", 30 , 0, 3000, pTave);
	  double alpha = ak4j3.Pt() / pTave ;
	  if(verbose) std::cout<< "alpha = " << alpha << std::endl;
	  CreateAndFillUserTH1D("alpha", 100 , 0, 2, alpha);
	  double Asymmetry;
	       
	  int etaBin_j1 = mEtaBinning.getBin( fabs(ak4j1.Eta()) );
	  int etaBin_j2 = mEtaBinning.getBin( fabs(ak4j2.Eta()) );
	  int ptBin = mPtBinning.getPtBin( pTave );
	  std::pair<float, float> ptBins = mPtBinning.getBinValue(ptBin);	       
	   
	  if(verbose){
	    cout<<"|Eta_ak4j1| =   "<<fabs(ak4j1.Eta())<<endl;
	    cout<<"|Eta_ak4j2| =   "<<fabs(ak4j2.Eta())<<endl;
	       
	    std::pair<float, float> etaBins_j1 = mEtaBinning.getBinValue(etaBin_j1);
	    std::pair<float, float> etaBins_j2 = mEtaBinning.getBinValue(etaBin_j2);
	    cout<<"EtaBin_j1 =   "<<etaBin_j1<<endl;
	    cout<<"EtaBin_j2 =   "<<etaBin_j2<<endl;
	    cout<<"pTBin =   "<<ptBin <<endl;
	    cout<<"j1: etaBin.first  "<< etaBins_j1.first << "    etaBin.second   "<<etaBins_j1.second<<endl;
	    cout<<"j2: etaBin.first  "<< etaBins_j2.first << "    etaBin.second   "<<etaBins_j2.second<<endl;
	    cout<<"ptBin.first  "<< ptBins.first << "    ptBin.second   "<<ptBins.second<<endl;
	  }

      	  // seleziono gli stessi eventi	     
	  if(etaBin_j1Reco == etaBin_j2Reco){ // same eta bin RECO
	    std::string etaNameReco = mEtaBinning.getBinName(etaBin_j1Reco);	     
	    if(etaBin_j1 == etaBin_j2){ // same eta bin HLT
	      std::string etaName = mEtaBinning.getBinName(etaBin_j1);	     
	      if(alphaReco < alphacut_ ){	// alpha cut RECO
		if(alpha < alphacut_ ){	// alpha cut HLT		    

		  cout<< "PASSED"<< endl;
		  /// HLT
		  // introduco uno smearing 
		  /*
		    Devi cambiare il pT di tutti i jet che usi.
		    pTnew = pTold * smear
		    dove smear e’ un numero generato random secondo una distribuzione Gaussiana
		    di media=1 e sigma usuale allo smearing che vuoi mettere (es. 10%=0.1)
		  */
		  vector<TLorentzVector> AK4jetsSmeared;
		  // for(int ii = 0; ii < AK4jets.size(); ii++){
		  for(int ii = 0; ii < 2; ii++){
		    TLorentzVector ak4jetSmeared;      
		    double PtSmeared;      
		    double smear;      
		    TRandom *factor=new TRandom3(0);  //factor -> SetSeed(0);
		    smear = factor -> Gaus(1, 0.1);
		    PtSmeared= AK4jets[ii].Pt() * smear;
		    
		    ak4jetSmeared.SetPtEtaPhiM(PtSmeared, AK4jets[ii].Eta(), AK4jets[ii].Phi(), AK4jets[ii].M() );
		    AK4jetsSmeared.push_back(ak4jetSmeared);
		    
		    if(verbose){
		      std::cout<<"smearing factor = "<< smear << std::endl;
		      std::cout<<"HLT SMEARED"<< std::endl;
		      std::cout<<"AK4 smeared "<< ii << std::endl;
		      std::cout<<"Pt: "<< AK4jetsSmeared[ii].Pt() <<" eta: "<< AK4jetsSmeared[ii].Eta() <<" phi: "<< AK4jetsSmeared[ii].Phi() << std::endl;
		    }
		  } // end smearing
		  
		  double pTaveSmeared = ( AK4jetsSmeared[0].Pt() + AK4jetsSmeared[1].Pt() ) /2;
		  if(verbose) std::cout<< "Average pT = " << pTaveSmeared << std::endl;
		  CreateAndFillUserTH1D("pTaveSmeared", 300 , 0, 3000, pTaveSmeared);
		  //	    double alphaSmeared = AK4jetsSmeared[2].Pt() / pTaveSmeared ;
		  //	    if(verbose) std::cout<< "alpha Smeared = " << alphaSmeared << std::endl;
		  //	    CreateAndFillUserTH1D("alphaSmeared", 100 , 0, 2, alphaSmeared);
		  double AsymmetrySmeared;
		  
		  if(random == 0){
		    AsymmetryReco = ( ak4j1Reco.Pt() - ak4j2Reco.Pt() ) / ( ak4j1Reco.Pt() + ak4j2Reco.Pt() ) ;
		    Asymmetry        = ( ak4j1.Pt() - ak4j2.Pt() ) / ( ak4j1.Pt() + ak4j2.Pt() ) ;
		    AsymmetrySmeared = ( AK4jetsSmeared[0].Pt() - AK4jetsSmeared[1].Pt() ) / ( AK4jetsSmeared[0].Pt() + AK4jetsSmeared[1].Pt() ) ;
		  }else if(random == 1){
		    AsymmetryReco = ( ak4j2Reco.Pt() - ak4j1Reco.Pt() ) / ( ak4j1Reco.Pt() + ak4j2Reco.Pt() ) ; 
		    Asymmetry        = ( ak4j2.Pt() - ak4j1.Pt() ) / ( ak4j1.Pt() + ak4j2.Pt() ) ; 
		    AsymmetrySmeared = ( AK4jetsSmeared[1].Pt() - AK4jetsSmeared[0].Pt() ) / ( AK4jetsSmeared[0].Pt() + AK4jetsSmeared[1].Pt() ) ; 
		  }
		  std::string HistoNameReco = TString::Format("AsymmetryReco_%s_pT_%i_%i", etaNameReco.c_str(), (int) ptBins_Reco.first, (int) ptBins_Reco.second ).Data();	 	     
		  if(verbose) std::cout << HistoNameReco.c_str()<< std::endl;
		  if(verbose) std::cout<< "Asymmetry Reco = " << AsymmetryReco << std::endl; 
		  CreateAndFillUserTH1D(HistoNameReco.c_str(), 300, -2, 2, AsymmetryReco);
		  std::string HistoName = TString::Format("Asymmetry_%s_pT_%i_%i", etaName.c_str(), (int) ptBins.first, (int) ptBins.second ).Data();	 	     
		  if(verbose) std::cout << HistoName.c_str()<< std::endl;
		  if(verbose) std::cout<< "Asymmetry  = " << Asymmetry << std::endl; 
		  CreateAndFillUserTH1D(HistoName.c_str(), 300, -2, 2, Asymmetry);
		  std::string HistoNameSmeared = TString::Format("AsymmetrySmeared_%s_pT_%i_%i", etaName.c_str(), (int) ptBins.first, (int) ptBins.second ).Data();	 	     
		  if(verbose) std::cout << HistoNameSmeared.c_str()<< std::endl;
		  if(verbose) std::cout<< "Asymmetry Smeared  = " << AsymmetrySmeared << std::endl; 
		  CreateAndFillUserTH1D(HistoNameSmeared.c_str(), 300, -2, 2, AsymmetrySmeared);

		}else{//alpha cut HLT
		  if(verbose) std::cout<< "HLT: alpha too large = "<<alpha<<std::endl;
		}
	      }else{
		if(verbose) std::cout<< "Reco: alpha too large = "<<alphaReco<<std::endl;
	      }
	    }// eta bin HLT
	  } // eta bin Reco

	}// both jet matched
      }// trigger
    }// pass json
     
    /////////////////////////////////////////////////////////////////
     
    //== Fill Variables ==
    fillVariableWithValue("PassJSON", PassJSON);     
    fillVariableWithValue("MJJ_reco", mjjreco);     
    fillVariableWithValue("MJJ", mjj);     
    fillVariableWithValue("deltaETAjj_reco", deltaETAjjreco);     
    fillVariableWithValue("deltaETAjj", deltaETAjj);     
    
    ////////////////////////////////////////

    //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 -> Fill(MJJWideReco); 
       
      if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) )
      h_mjj_HLTpass_ZeroBias -> Fill(MJJWideReco);  
      if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) 
      && (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
      h_mjj_HLTpass_ZeroBias_L1HTT150 -> Fill(MJJWideReco);  

      if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
      h_mjj_HLTpass_L1HTT150 -> Fill(MJJWideReco);  

      if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) 
      && (getVariableValue("passHLT_HT450_BtagSeq")||getVariableValue("passHLT_HT450")) )
      h_mjj_HLTpass_L1HTT150_HT450 -> Fill(MJJWideReco);  
       
      }
    */
    // 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("HTAK4reco"));
    //     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 -> 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()
{
  //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");
}