void analysisClass::loop() {

    //--------------------------------------------------------------------------------
    // Configurables
    //--------------------------------------------------------------------------------
    const int nSample = 10;
    const double min_charge = 20.;

    //--------------------------------------------------------------------------------
    // Declare HCAL tree(s)
    //--------------------------------------------------------------------------------

    HcalTupleTree * utca_tree = getTree<HcalTupleTree>("tuple_tree","utca_file");
    HcalTupleTree * vme_tree = getTree<HcalTupleTree>("tuple_tree","vme_file");

    //--------------------------------------------------------------------------------
    // Check number of events
    //--------------------------------------------------------------------------------

    int n_utca_events = utca_tree -> fChain -> GetEntries();
    std::cout << "n events in utca tree = " << n_utca_events << std::endl;
    int n_vme_events = vme_tree -> fChain -> GetEntries();
    std::cout << "n events in vme tree = " << n_vme_events << std::endl;

    if (n_utca_events != n_vme_events) {
        std::cout << "Number of events in utca trees not equal to number of vme trees" << std::endl;
        return;
    };

    int n_events = n_utca_events;
    std::map<std::string,HcalTupleTree*> treeMap;
    treeMap["utca"] = utca_tree;
    treeMap["vme"] = vme_tree;

    //--------------------------------------------------------------------------------
    // Turn on/off branches
    //--------------------------------------------------------------------------------

    std::map<std::string,HcalTupleTree*>::iterator it = treeMap.begin();
    for (; it != treeMap.end(); ++it) {
        it -> second -> fChain -> SetBranchStatus("*"                 , kFALSE);
        it -> second -> fChain -> SetBranchStatus("run"               , kTRUE);
        it -> second -> fChain -> SetBranchStatus("event"             , kTRUE);
        it -> second -> fChain -> SetBranchStatus("ls"                , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiFC"        , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiADC"       , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiIEta"      , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiIPhi"      , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiDepth"     , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HBHEDigiSize"      , kTRUE);
        it -> second -> fChain -> SetBranchStatus("HcalTriggerPrimitiveCompressedEtSOI",kTRUE);
        it -> second -> fChain -> SetBranchStatus("HcalTriggerPrimitiveIEta",kTRUE);
        it -> second -> fChain -> SetBranchStatus("HcalTriggerPrimitiveIPhi",kTRUE);
    };

    //--------------------------------------------------------------------------------
    // Basic Histograms
    //--------------------------------------------------------------------------------

    char histName[100];
    char titleName[100];

    TH2F * h_utcaOccp = makeTH2F("h_utcaOccp",81,-40.5,40.5,72,0.5,72.5);
    h_utcaOccp -> SetTitle(" ; uTCA i#eta ; uTCA i#phi ");

    TH2F * h_vmeOccp = makeTH2F("h_vmeOccp",81,-40.5,40.5,72,0.5,72.5);
    h_vmeOccp -> SetTitle(" ; VME i#eta ; VME i#phi ");

    TH2F * h_fcTotal = makeTH2F("h_fcTotal",100,0.,200.,100.,0.,200.);
    h_fcTotal -> SetTitle(" ; uTCA Total fC ; VME Total fC ");

    std::map <int,TH2F*> h_fc;
    std::map <int,TH1F*> h_uTCAfC;
    std::map <int,TH1F*> h_vmefC;

    for (int ifc = 0; ifc != nSample; ifc++) {
        sprintf(histName,"h_fc%d",ifc);
        h_fc[ifc] = makeTH2F(histName,50,0.,50.,50,0.,50.);
        sprintf(titleName," ; uTCA fC at TS %d ; VME fC at TS %d ",ifc,ifc);
        h_fc[ifc] -> SetTitle(titleName);

        sprintf(histName,"h_uTCAfc%d",ifc);
        h_uTCAfC[ifc] = makeTH1F(histName,50,0.,50.);
        sprintf(titleName," ; uTCA fC at TS %d ; ",ifc);
        h_uTCAfC[ifc] -> SetTitle(titleName);

        sprintf(histName,"h_vmefc%d",ifc);
        h_vmefC[ifc] = makeTH1F(histName,50,0.,50.);
        sprintf(titleName," ; vme fC at TS %d ; ",ifc);
        h_vmefC[ifc] -> SetTitle(titleName);
    };

    TH2F * h_adcTotal = makeTH2F("h_adcTotal",201,-0.5,200.5,201,-0.5,200.5);
    h_adcTotal -> SetTitle(" ; uTCA Total ADC ; VME Total ADC ");

    TH2F * h_tpEt = makeTH2F("h_tpEt",50,0.,100.,50,0.,100.);
    h_tpEt -> SetTitle(" ; uTCA TP ET ; VME TP ET");

    //--------------------------------------------------------------------------------
    // Custom Histograms
    //--------------------------------------------------------------------------------
    TH2F * h_utcaOccp_cut = makeTH2F("h_utcaOccp_cut",81,-40.5,40.5,72,0.5,72.5);
    h_utcaOccp_cut -> SetTitle("Cut ; uTCA i#eta ; uTCA i#phi ");

    TH2F * h_vmeOccp_cut = makeTH2F("h_vmeOccp_cut",81,-40.5,40.5,72,0.5,72.5);
    h_vmeOccp_cut -> SetTitle("Cut ; VME i#eta ; VME i#phi ");


    //--------------------------------------------------------------------------------
    // Loop
    //--------------------------------------------------------------------------------
    for (int i = 0; i < n_events; ++i) {

        utca_tree -> GetEntry(i);
        vme_tree -> GetEntry(i);

        if ( (i + 1) % 100 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

        // HBHE Digi
        CollectionPtr utcaDigis (new Collection(*utca_tree, utca_tree -> HBHEDigiIEta -> size()));
        CollectionPtr vmeDigis (new Collection(*vme_tree, vme_tree -> HBHEDigiIEta -> size()));

        int n_utcaDigis = utcaDigis -> GetSize();
        int n_vmeDigis = vmeDigis -> GetSize();

        //--------------------------------------------------------------------------------
        // uTCA Digis
        //--------------------------------------------------------------------------------

        for (int i_utcaDigis = 0; i_utcaDigis < n_utcaDigis; i_utcaDigis++) {
            HBHEDigi utcaDigi = utcaDigis -> GetConstituent<HBHEDigi>(i_utcaDigis);
            h_utcaOccp -> Fill( utcaDigi.ieta() , utcaDigi.iphi() );

            if ( utcaDigi.fc(4) + utcaDigi.fc(5) > min_charge) {
                h_utcaOccp_cut -> Fill( utcaDigi.ieta() , utcaDigi.iphi() );
            };

            for (int ifc = 0; ifc != nSample; ifc++) {
                h_uTCAfC[ifc] -> Fill( utcaDigi.fc(ifc) );
            };
        };

        //--------------------------------------------------------------------------------
        // VME Digis
        //--------------------------------------------------------------------------------

        for (int i_vmeDigis = 0; i_vmeDigis < n_vmeDigis; i_vmeDigis++) {
            HBHEDigi vmeDigi = vmeDigis -> GetConstituent<HBHEDigi>(i_vmeDigis);
            h_vmeOccp -> Fill( vmeDigi.ieta() , vmeDigi.iphi() );

            if ( vmeDigi.fc(4) + vmeDigi.fc(5) > min_charge) {
                h_vmeOccp_cut -> Fill( vmeDigi.ieta() , vmeDigi.iphi() );
            };

            for (int ifc = 0; ifc != nSample; ifc++) {
                h_vmefC[ifc] -> Fill( vmeDigi.fc(ifc) );
            };
        };

        //--------------------------------------------------------------------------------
        // Matching uTCA and VME Digis
        //--------------------------------------------------------------------------------

        for (int i_utcaDigis = 0; i_utcaDigis < n_utcaDigis; i_utcaDigis++) {

            HBHEDigi utcaDigi = utcaDigis -> GetConstituent<HBHEDigi>(i_utcaDigis);

            for (int i_vmeDigis = 0; i_vmeDigis < n_vmeDigis; i_vmeDigis++) {

                HBHEDigi vmeDigi = vmeDigis -> GetConstituent<HBHEDigi>(i_vmeDigis);

                if ( ( utcaDigi.ieta() != vmeDigi.ieta() ) || ( utcaDigi.iphi() != vmeDigi.iphi() ) || ( utcaDigi.depth() != vmeDigi.depth() ) ) continue;

                h_fcTotal -> Fill( utcaDigi.fcTotal() , vmeDigi.fcTotal() );
                h_adcTotal -> Fill( utcaDigi.adcTotal() , vmeDigi.adcTotal() );

                for (int ifc = 0; ifc != nSample; ifc++) {
                    h_fc[ifc] -> Fill( utcaDigi.fc(ifc) , vmeDigi.fc(ifc) );
                };
            };
        };

        //--------------------------------------------------------------------------------
        // TPs
        //--------------------------------------------------------------------------------

        CollectionPtr utcaTPs (new Collection(*utca_tree, utca_tree -> HcalTriggerPrimitiveIEta -> size()));
        CollectionPtr vmeTPs (new Collection(*vme_tree, vme_tree -> HcalTriggerPrimitiveIEta -> size()));

        int n_uTCATPs = utcaTPs -> GetSize();
        int n_vmeTPs = vmeTPs -> GetSize();

        for (int i_uTCATP = 0; i_uTCATP < n_uTCATPs; i_uTCATP++) {
            HcalTP utcaTP = utcaTPs -> GetConstituent<HcalTP>(i_uTCATP);

            for (int i_vmeTP = 0; i_vmeTP < n_vmeTPs; i_vmeTP++) {
                HcalTP vmeTP = vmeTPs -> GetConstituent<HcalTP>(i_vmeTP);

                if ( ( utcaTP.ieta() != vmeTP.ieta() ) || ( utcaTP.iphi() != vmeTP.iphi() )  ) continue;

                h_tpEt -> Fill( utcaTP.Et() , vmeTP.Et() );

            };
        };

    };
}
void analysisClass::loop(){
  
  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalTupleTree * tuple_tree = getTree<HcalTupleTree>("tuple_tree");
  int n_events = tuple_tree -> fChain -> GetEntries();
  std::cout << "n events = " << n_events << std::endl;

  //--------------------------------------------------------------------------------
  // Turn on/off branches
  //--------------------------------------------------------------------------------
  
  tuple_tree -> fChain -> SetBranchStatus("*", kFALSE);
  tuple_tree -> fChain -> SetBranchStatus("run", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiRecEnergy", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiRecTime", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiIEta", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiIPhi", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiDepth", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiFC", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiSize", kTRUE);

  //--------------------------------------------------------------------------------
  // Make histograms
  //--------------------------------------------------------------------------------
  std::map<int,std::map<int,TH1F*>> RecHitTiming;
  std::map<int,std::map<int,TH1F*>> AvgTiming;

  // std::map<int,std::map<int,TH1F*>> HBRecHitTiming;
  // std::map<int,std::map<int,TH1F*>> HBAvgTiming;

  // std::map<int,std::map<int,TH1F*>> HERecHitTiming;
  // std::map<int,std::map<int,TH1F*>> HEAvgTiming;

  int hash;
  char histName[100];
  
  //--------------------------------------------------------------------------------
  // Loop
  //--------------------------------------------------------------------------------
  
  for (int i = 0; i < n_events; ++i){
    
    tuple_tree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    int runNumber = tuple_tree -> run;

    //-----------------------------------------------------------------
    // Collections of HBHE
    //-----------------------------------------------------------------
    CollectionPtr hbheDigis (new Collection(*tuple_tree, tuple_tree -> HBHEDigiIEta -> size()));

    if (RecHitTiming.find(runNumber) == RecHitTiming.end()){
      RecHitTiming[runNumber] = std::map<int,TH1F*>();
    };
    if (AvgTiming.find(runNumber) == AvgTiming.end()){
      AvgTiming[runNumber] = std::map<int,TH1F*>();
    };
    // if (HBRecHitTiming.find(runNumber) == HBRecHitTiming.end()){
    //   HBRecHitTiming[runNumber] = std::map<int,TH1F*>();
    // };
    // if (HBAvgTiming.find(runNumber) == HBAvgTiming.end()){
    //   HBAvgTiming[runNumber] = std::map<int,TH1F*>();
    // };
    // if (HERecHitTiming.find(runNumber) == HERecHitTiming.end()){
    //   HBRecHitTiming[runNumber] = std::map<int,TH1F*>();
    // };
    // if (HEAvgTiming.find(runNumber) == HEAvgTiming.end()){
    //   HEAvgTiming[runNumber] = std::map<int,TH1F*>();
    // };

    int nHBHEDigis = hbheDigis -> GetSize();
    for (int iHBHEDigi = 0; iHBHEDigi < nHBHEDigis; ++iHBHEDigi){
      HBHEDigi hbheDigi = hbheDigis -> GetConstituent<HBHEDigi>(iHBHEDigi);

      if ( hbheDigi.energy() < 5.0 ) continue;

      hash = getHash( hbheDigi.ieta() , hbheDigi.iphi() , hbheDigi.depth() );
      
      if ( RecHitTiming[runNumber].find(hash) == RecHitTiming[runNumber].end() ){
        sprintf(histName, "%d_RecHitTiming_HBHE_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
        RecHitTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,-10.,10.)));
      };

      if ( AvgTiming[runNumber].find(hash) == AvgTiming[runNumber].end() ){
        sprintf(histName, "%d_AvgTiming_HBHE_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
        AvgTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,0.,10.)));
      };

      RecHitTiming[runNumber][hash] -> Fill(hbheDigi.recHitTime());
      AvgTiming[runNumber][hash] -> Fill(hbheDigi.time());

      // if (hbheDigi.ieta() <= 16){
      //   if ( HBRecHitTiming[runNumber].find(hash) == HBRecHitTiming[runNumber].end() ){
      //     sprintf(histName, "%d_RecHitTiming_HB_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
      //     HBRecHitTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,-10.,10.)));
      //   };

      //   if ( HBAvgTiming[runNumber].find(hash) == HBAvgTiming[runNumber].end() ){
      //     sprintf(histName, "%d_HBAvgTiming_HBHE_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
      //     HBAvgTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,0.,10.)));
      //   };

      //   HBRecHitTiming[runNumber][hash] -> Fill(hbheDigi.recHitTime());
      //   HBAvgTiming[runNumber][hash] -> Fill(hbheDigi.time());
      // };

      // if ((hbheDigi.ieta() > 16) and (hbheDigi.ieta() <= 29)){
      //   if ( HERecHitTiming[runNumber].find(hash) == HERecHitTiming[runNumber].end() ){
      //     sprintf(histName, "%d_RecHitTiming_HE_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
      //     HERecHitTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,-10.,10.)));
      //   };

      //   if ( HEAvgTiming[runNumber].find(hash) == HEAvgTiming[runNumber].end() ){
      //     sprintf(histName, "%d_AvgTiming_HE_%d_%d_%d", runNumber , hbheDigi.ieta(), hbheDigi.iphi(), hbheDigi.depth());
      //     HEAvgTiming[runNumber].insert(std::pair<int,TH1F*>(hash, makeTH1F(histName,100,0.,10.)));
      //   };

      //   HERecHitTiming[runNumber][hash] -> Fill(hbheDigi.recHitTime());
      //   HEAvgTiming[runNumber][hash] -> Fill(hbheDigi.time());
      // };

    };
  };
  
  // TH1F * graph = makeTH1F("HBRecHitTiming_vs_RunNumber",HBRecHitTiming.size(),-0.5,HBRecHitTiming.size()-0.5);
  // char binLabel[100];
  // int iBin = 1;
  // for (std::map<int,std::map<int,TH1F*>>::iterator it = HBRecHitTiming.begin(); it != HBRecHitTiming.end(); it++){
  //   double sum = 0;
  //   double error2 = 0;
  //   int count = 0;
  //   int channelCount = 0;
  //   for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
  //     channelCount++;
  //     count += it2 -> second -> Integral(0,101);
  //     sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
  //     error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
  //   };

  //   graph -> SetBinContent( iBin , sum/count  );
  //   graph -> SetBinError(iBin , sqrt(error2/count/channelCount) );
  //   sprintf(binLabel,"%d",it -> first);
  //   graph -> GetXaxis() -> SetBinLabel( iBin , binLabel );
  //   iBin++;
  // };
  // 
  // TH1F * graph2 = makeTH1F("HBAvgTiming_vs_RunNumber",HBAvgTiming.size(),-0.5,HBAvgTiming.size()-0.5);
  // iBin = 1;
  // for (std::map<int,std::map<int,TH1F*>>::iterator it = HBAvgTiming.begin(); it != HBAvgTiming.end(); it++){
  //   double sum = 0;
  //   double error2 = 0;
  //   int count = 0;
  //   int channelCount = 0;
  //   for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
  //     channelCount++;
  //     count += it2 -> second -> Integral(0,101);
  //     sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
  //     error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
  //   };

  //   graph2 -> SetBinContent( iBin , sum/count  );
  //   graph2 -> SetBinError(iBin , sqrt(error2/count/channelCount) );
  //   sprintf(binLabel,"%d",it -> first);
  //   graph2 -> GetXaxis() -> SetBinLabel( iBin , binLabel );
  //   iBin++;
  // };

  // TH1F * graph3 = makeTH1F("HERecHitTiming_vs_RunNumber",HERecHitTiming.size(),-0.5,HERecHitTiming.size()-0.5);
  // iBin = 1;
  // for (std::map<int,std::map<int,TH1F*>>::iterator it = HERecHitTiming.begin(); it != HERecHitTiming.end(); it++){
  //   double sum = 0;
  //   double error2 = 0;
  //   int count = 0;
  //   int channelCount = 0;
  //   for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
  //     channelCount++;
  //     count += it2 -> second -> Integral(0,101);
  //     sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
  //     error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
  //   };

  //   graph3 -> SetBinContent( iBin , sum/count  );
  //   graph3 -> SetBinError(iBin , sqrt(error2/count/channelCount) );
  //   sprintf(binLabel,"%d",it -> first);
  //   graph3 -> GetXaxis() -> SetBinLabel( iBin , binLabel );
  //   iBin++;
  // };
  // 
  // TH1F * graph4 = makeTH1F("HEAvgTiming_vs_RunNumber",HEAvgTiming.size(),-0.5,HEAvgTiming.size()-0.5);
  // iBin = 1;
  // for (std::map<int,std::map<int,TH1F*>>::iterator it = HEAvgTiming.begin(); it != HEAvgTiming.end(); it++){
  //   double sum = 0;
  //   double error2 = 0;
  //   int count = 0;
  //   int channelCount = 0;
  //   for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
  //     channelCount++;
  //     count += it2 -> second -> Integral(0,101);
  //     sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
  //     error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
  //   };

  //   graph4 -> SetBinContent( iBin , sum/count  );
  //   graph4 -> SetBinError(iBin , sqrt(error2/count/channelCount) );
  //   sprintf(binLabel,"%d",it -> first);
  //   graph4 -> GetXaxis() -> SetBinLabel( iBin , binLabel );
  //   iBin++;
  // };

  TH1F * graph = makeTH1F("RecHitTiming_vs_RunNumber",RecHitTiming.size(),-0.5,RecHitTiming.size()-0.5);
  char binLabel[100];
  int iBin = 1;
  for (std::map<int,std::map<int,TH1F*>>::iterator it = RecHitTiming.begin(); it != RecHitTiming.end(); it++){
    double sum = 0;
    double error2 = 0;
    int count = 0;
    int channelCount = 0;
    for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
      channelCount++;
      count += it2 -> second -> Integral(0,101);
      sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
      error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
    };

    graph -> SetBinContent( iBin , sum/count  );
    graph -> SetBinError(iBin , sqrt(error2/count/channelCount) );
    sprintf(binLabel,"%d",it -> first);
    graph -> GetXaxis() -> SetBinLabel( iBin , binLabel );
    iBin++;
  };
  
  TH1F * graph2 = makeTH1F("AvgTiming_vs_RunNumber",AvgTiming.size(),-0.5,AvgTiming.size()-0.5);
  iBin = 1;
  for (std::map<int,std::map<int,TH1F*>>::iterator it = AvgTiming.begin(); it != AvgTiming.end(); it++){
    double sum = 0;
    double error2 = 0;
    int count = 0;
    int channelCount = 0;
    for (std::map<int,TH1F*>::iterator it2 = it -> second.begin(); it2 != it -> second.end(); it2++){
      channelCount++;
      count += it2 -> second -> Integral(0,101);
      sum += (it2 -> second -> Integral(0,101))*(it2 -> second -> GetMean());
      error2 += (it2 -> second -> GetRMS())*(it2 -> second -> GetRMS())*( it2 -> second -> Integral(0,101));
    };

    graph2 -> SetBinContent( iBin , sum/count  );
    graph2 -> SetBinError(iBin , sqrt(error2/count/channelCount) );
    sprintf(binLabel,"%d",it -> first);
    graph2 -> GetXaxis() -> SetBinLabel( iBin , binLabel );
    iBin++;
  };

};
void analysisClassL1::loop(){

  std::string MyTrigger="HLT_Any";

  L1Tree * l1Tree = getTree<L1Tree>("l1Tree");
  L1ExtraTree * l1ExtraTree = getTree<L1ExtraTree>("l1ExtraTree");

  int n_events = l1Tree -> fChain -> GetEntries();

  l1Tree -> fChain -> SetBranchStatus("*", kFALSE);

  l1ExtraTree -> fChain -> SetBranchStatus("*", kFALSE);
  l1ExtraTree -> fChain -> SetBranchStatus("nFwdJets", kTRUE);
  l1ExtraTree -> fChain -> SetBranchStatus("fwdJetEt", kTRUE);
  l1ExtraTree -> fChain -> SetBranchStatus("fwdJetBx", kTRUE);

  l1ExtraTree -> fChain -> SetBranchStatus("nCenJets", kTRUE);
  l1ExtraTree -> fChain -> SetBranchStatus("cenJetEt", kTRUE); 
  l1ExtraTree -> fChain -> SetBranchStatus("cenJetBx", kTRUE);

  TH1F * h_cenJetPt = makeTH1F("h_cenJetPt",250,-0.5,249.5);
  TH1F * h_fwdJetPt = makeTH1F("h_fwdJetPt",250,-0.5,249.5);
  TH1F * h_leadingCenJetPt = makeTH1F("h_leadingCenJetPt",250,-0.5,249.5);
  TH1F * h_leadingFwdJetPt = makeTH1F("h_leadingFwdJetPt",250,-0.5,249.5);
  TH1F * h_leadingFwdJetPt_BxM1 = makeTH1F("h_leadingFwdJetPt_BxM1",250,-0.5,249.5);
  TH2F * h_leadingFwdJet_Bx0_BxM1 = makeTH2F("h_leadingFwdJet_BxM1_Bx0",100,-0.5,249.5,100,-0.5,249.5);
  TH2F * h_leadingFwdJet_Bx0_BxM1_CenJetPt50 = makeTH2F("h_leadingFwdJet_Bx0_BxM1_CenJetPt50",100,-0.5,249.5,100,-0.5,249.5);

  TH1F * h_fwdJetBx = makeTH1F("h_fwdJetBx",10,-5.5,4.5);

  double leadingCenJetPt;
  double leadingFwdJetPt;
  double leadingFwdJetPt_BxM1;

  for (int i = 0; i < n_events; ++i){
    l1Tree -> GetEntry(i);
    l1ExtraTree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    if ((l1ExtraTree -> cenJetEt.size() == 0) && (l1ExtraTree -> fwdJetEt.size() == 0) ) continue;

    leadingCenJetPt = 0.;
    for (int j = 0; j != l1ExtraTree -> cenJetEt.size(); j++){
      h_cenJetPt -> Fill(l1ExtraTree -> cenJetEt[j]);
      if ((leadingCenJetPt < l1ExtraTree -> cenJetEt[j]) && (l1ExtraTree -> cenJetBx[j] == 0) ){
        leadingCenJetPt = l1ExtraTree -> cenJetEt[j];
      };
    };
    h_leadingCenJetPt -> Fill(leadingCenJetPt);

    leadingFwdJetPt = 0.;
    leadingFwdJetPt_BxM1 = 0.;
    for (int j = 0; j != l1ExtraTree -> fwdJetEt.size(); j++){
      h_fwdJetPt -> Fill(l1ExtraTree -> fwdJetEt[j]);
      h_fwdJetBx -> Fill(l1ExtraTree -> fwdJetBx[j]);
      if ((leadingFwdJetPt < l1ExtraTree -> fwdJetEt[j]) && (l1ExtraTree -> fwdJetBx[j] == 0) ){
        leadingFwdJetPt = l1ExtraTree -> fwdJetEt[j];
      };
      if ((leadingFwdJetPt_BxM1 < l1ExtraTree -> fwdJetEt[j]) && (l1ExtraTree -> fwdJetBx[j] == -1) ){
        leadingFwdJetPt_BxM1 = l1ExtraTree -> fwdJetEt[j];
      };
    };
    h_leadingFwdJetPt -> Fill(leadingFwdJetPt);
    h_leadingFwdJetPt_BxM1 -> Fill(leadingFwdJetPt_BxM1);

    h_leadingFwdJet_Bx0_BxM1 -> Fill(leadingFwdJetPt,leadingFwdJetPt_BxM1);
    if (leadingCenJetPt > 50.){
      h_leadingFwdJet_Bx0_BxM1_CenJetPt50 -> Fill(leadingFwdJetPt,leadingFwdJetPt_BxM1);
    };
  };

    h_leadingFwdJet_Bx0_BxM1 -> SetTitle(" ; leading Fwd Jet E_{T} (Bx = 0) GeV ; leading Fwd Jet E_{T} (Bx = -1) GeV ");
    h_leadingFwdJet_Bx0_BxM1_CenJetPt50 -> SetTitle("Leading Cen Jet pT > 50 GeV ; leading Fwd Jet E_{T} (Bx = 0) GeV ; leading Fwd Jet E_{T} (Bx = -1) GeV ");

}
void analysisClass::loop(){
 
  //--------------------------------------------------------------------------------
  // Configurables
  //--------------------------------------------------------------------------------
 
  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalTupleTree * tuple_tree = getTree<HcalTupleTree>("skim_tree");
  int n_events = tuple_tree -> fChain -> GetEntries();
  std::cout << "n events = " << n_events << std::endl;
  
  //--------------------------------------------------------------------------------
  // Turn on/off branches
  //--------------------------------------------------------------------------------
  
  tuple_tree -> fChain -> SetBranchStatus("*", kFALSE);
  tuple_tree -> fChain -> SetBranchStatus("run", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("event", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("ls", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiRecEnergy", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiIEta", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiIPhi", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HBHEDigiFC", kTRUE);

  //--------------------------------------------------------------------------------
  // Make histograms
  //--------------------------------------------------------------------------------
  char histName[100];
  char title[100];

  //--------------------------------------------------------------------------------
  // Necessary Variables
  //--------------------------------------------------------------------------------

  //--------------------------------------------------------------------------------
  // Loop
  //--------------------------------------------------------------------------------
  
  for (int i = 0; i < n_events; ++i){
    
    tuple_tree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    //-----------------------------------------------------------------
    // Select Event
    //-----------------------------------------------------------------
    int runNumber = tuple_tree -> run;
    int lumiSection = tuple_tree -> ls;
    int eventNumber = tuple_tree -> event;

    //-----------------------------------------------------------------
    // Collections of HBHE
    //-----------------------------------------------------------------
    CollectionPtr hbheDigis (new Collection(*tuple_tree, tuple_tree -> HBHEDigiIEta -> size()));
    
    int nHBHEDigis = hbheDigis -> GetSize();
    int count = 0; int count3 = 0;
    for (int iHBHEDigi = 0; iHBHEDigi < nHBHEDigis; ++iHBHEDigi){
      HBHEDigi hbheDigi = hbheDigis -> GetConstituent<HBHEDigi>(iHBHEDigi);

      if ( hbheDigi.energy() < 5.0 ) continue;

      if ( abs(hbheDigi.ieta()) > 12 ) continue;

      if ( hbheDigi.fc(3) < 50 ) continue;

      sprintf(histName,"PulseShape_%d_%d_%d_%d",runNumber,lumiSection,eventNumber,iHBHEDigi);
      sprintf(title," %d %d %d %d  ; TS ; FC",runNumber,lumiSection,eventNumber,iHBHEDigi);
      TH1F * tempHist = makeTH1F(histName,10,-0.5,9.5);
      tempHist -> SetTitle(title);
      for (int its = 0; its != 10; its++){
        tempHist -> Fill ( its , hbheDigi.fc(its) );
      };
    };
  };
};
void analysisClass::loop(){

  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalNoiseTree * noise_tree = getTree<HcalNoiseTree>("noise_tree");
  int n_events = noise_tree -> fChain -> GetEntries();

  //--------------------------------------------------------------------------------
  // Clean branches we don't need
  //--------------------------------------------------------------------------------

  noise_tree -> fChain -> SetBranchStatus("*"         , kFALSE);
  noise_tree -> fChain -> SetBranchStatus("PulseCount", kTRUE );
  noise_tree -> fChain -> SetBranchStatus("IEta"      , kTRUE );
  noise_tree -> fChain -> SetBranchStatus("IPhi"      , kTRUE );
  noise_tree -> fChain -> SetBranchStatus("Depth"     , kTRUE );
  noise_tree -> fChain -> SetBranchStatus("Energy"    , kTRUE );
  noise_tree -> fChain -> SetBranchStatus("Charge"    , kTRUE );
  noise_tree -> fChain -> SetBranchStatus("OfficialDecision", kTRUE);
  noise_tree -> fChain -> SetBranchStatus("NumberOfGoodPrimaryVertices", kTRUE);

  //--------------------------------------------------------------------------------
  // Declare some important quantities
  //--------------------------------------------------------------------------------
  
  const int nrings = 6;

  //--------------------------------------------------------------------------------
  // Declare histograms
  //--------------------------------------------------------------------------------

  TH1F * h_npv = makeTH1F("npv",5,-0.5,4.5);
  TH1F * h_ieta= makeTH1F("ieta", 59, -29.5, 29.5 );
  TH1F * h_iphi= makeTH1F("iphi", 73, -0.5, 72.5 );
  TH2F * h_ieta_iphi = makeTH2F("ieta_iphi", 59, -29.5, 29.5, 73, -0.5, 72.5 );
  
  char hist_name[100];
  std::vector<TH2F*> a0_histograms, a1_histograms, a2_histograms, a3_histograms;
  for (int iring = 0; iring < nrings; ++iring){
    sprintf(hist_name, "a0_ring%d", iring); a0_histograms.push_back(makeTH2F(hist_name, 3000, 0, 3000, 10000, -10.0, 10.0));
    sprintf(hist_name, "a1_ring%d", iring); a1_histograms.push_back(makeTH2F(hist_name, 3000, 0, 3000, 10000, -10.0, 10.0));
    sprintf(hist_name, "a2_ring%d", iring); a2_histograms.push_back(makeTH2F(hist_name, 3000, 0, 3000, 10000, -10.0, 10.0));
    sprintf(hist_name, "a3_ring%d", iring); a3_histograms.push_back(makeTH2F(hist_name, 3000, 0, 3000, 10000, -10.0, 10.0));
  }

  TH2F* a0_histogram_hb = makeTH2F("a0_hb", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a1_histogram_hb = makeTH2F("a1_hb", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a2_histogram_hb = makeTH2F("a2_hb", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a3_histogram_hb = makeTH2F("a3_hb", 3000, 0, 3000, 100, -10.0, 10.0);

  TH2F* a0_histogram_he = makeTH2F("a0_he", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a1_histogram_he = makeTH2F("a1_he", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a2_histogram_he = makeTH2F("a2_he", 3000, 0, 3000, 100, -10.0, 10.0);
  TH2F* a3_histogram_he = makeTH2F("a3_he", 3000, 0, 3000, 100, -10.0, 10.0);
  
  //--------------------------------------------------------------------------------
  // Loop over the events
  //--------------------------------------------------------------------------------
  
  for (int iEvent = 0; iEvent < n_events; ++iEvent){

    //--------------------------------------------------------------------------------
    // Tell the user where we are
    //--------------------------------------------------------------------------------

    if (iEvent%1000 == 0) std::cout << "Processing event " << iEvent << "/" << n_events << std::endl;
    
    //--------------------------------------------------------------------------------
    // Get each entry in the event
    //--------------------------------------------------------------------------------

    noise_tree -> GetEntry(iEvent);

    //--------------------------------------------------------------------------------
    // Event-level selection
    // Note: "official selection" variable is always zero for MC?
    //--------------------------------------------------------------------------------

    // if ( noise_tree -> OfficialDecision ) continue;
    if ( noise_tree -> NumberOfGoodPrimaryVertices == 0 ) continue;

    //--------------------------------------------------------------------------------
    // Loop over the cells
    //--------------------------------------------------------------------------------
    
    int nHBHE = noise_tree -> PulseCount;
    
    h_npv -> Fill(noise_tree -> NumberOfGoodPrimaryVertices);

    for (int iHBHE = 0; iHBHE < nHBHE; ++iHBHE){

      //--------------------------------------------------------------------------------
      // Store some important values for selection
      //--------------------------------------------------------------------------------

      int     ieta   = noise_tree -> IEta  [iHBHE];
      int     iphi   = noise_tree -> IPhi  [iHBHE];
      int    depth   = noise_tree -> Depth [iHBHE];
      bool     bad   = isBadChannel(0, ieta, iphi, depth);
      int     ring   = getRing(ieta);
      
      //--------------------------------------------------------------------------------
      // Cell-level selection
      //--------------------------------------------------------------------------------
      
      if (ring < 0) continue;
      if (noise_tree -> Energy[iHBHE]    < 1.0) continue;
      if (noise_tree -> Charge[iHBHE][4] < 5.0) continue;
      if (bad) continue;

      //--------------------------------------------------------------------------------
      // Store some important values for plotting
      //--------------------------------------------------------------------------------
      
      double TS1 = noise_tree -> Charge[iHBHE][1];
      double TS2 = noise_tree -> Charge[iHBHE][2];
      double TS3 = noise_tree -> Charge[iHBHE][3];
      double TS4 = noise_tree -> Charge[iHBHE][4];
      double TS5 = noise_tree -> Charge[iHBHE][5];
      double TS6 = noise_tree -> Charge[iHBHE][6];
      double TS7 = noise_tree -> Charge[iHBHE][7];

      /*
      std::cout << "-------------------------------------------------------------------------------------------------------------------------------" << std::endl;
      for (int i = 0; i < 10; i++){
	std::cout << i << "\t";
      }
      std::cout << std::endl;
      for (int i = 0; i < 10; i++){
	std::cout << std::setprecision(2) <<  noise_tree -> Charge[iHBHE][i] << "\t";
      }
      std::cout << std::endl;
      */
      
      double a0  = TS3/TS4;
      double a1  = TS5/TS4;
      double a2  = TS6/TS4;
      double a3  = TS7/TS4;
      
      //--------------------------------------------------------------------------------
      // Fill histograms
      //--------------------------------------------------------------------------------

      h_ieta      -> Fill ( ieta );
      h_iphi      -> Fill ( iphi );
      h_ieta_iphi -> Fill ( ieta, iphi );

      a0_histograms[ring] -> Fill(TS4, a0);
      a1_histograms[ring] -> Fill(TS4, a1);
      a2_histograms[ring] -> Fill(TS4, a2);
      a3_histograms[ring] -> Fill(TS4, a3);

      if ( ring == 0 ){
	a0_histogram_hb -> Fill(TS4, a0);
	a1_histogram_hb -> Fill(TS4, a1);
	a2_histogram_hb -> Fill(TS4, a2);
	a3_histogram_hb -> Fill(TS4, a3);
      }

      else { 
      	a0_histogram_he -> Fill(TS4, a0);
      	a1_histogram_he -> Fill(TS4, a1);
	a2_histogram_he -> Fill(TS4, a2);
	a3_histogram_he -> Fill(TS4, a3);
      }
      
    }      
  }
}
void analysisClass::loop(){

  //--------------------------------------------------------------------------------
  // Store important variables
  //--------------------------------------------------------------------------------

  for (int i_radius = 1; i_radius <= n_radii; ++i_radius){
    radii[i_radius-1] = min_radius + i_radius * (max_radius - min_radius) / double(n_radii);
  }
  
  //--------------------------------------------------------------------------------
  // Declare tree(s)
  //--------------------------------------------------------------------------------
  
  HgcalTupleTree * tree = getTree<HgcalTupleTree>("hgcal_tree");
  int n_events = tree -> fChain -> GetEntries();
  // int n_events = 200;
  
  std::vector<std::string> * rcut_values = new std::vector<std::string>();
  rcut_values -> push_back ("R5"); 
  rcut_values -> push_back ("R4"); 
  rcut_values -> push_back ("R3"); 
  rcut_values -> push_back ("R2"); 
  rcut_values -> push_back ("R1"); 
  rcut_values -> push_back ("R05"); 
  rcut_values -> push_back ("R04"); 
  rcut_values -> push_back ("R03"); 
  rcut_values -> push_back ("R02"); 
  rcut_values -> push_back ("R01"); 
  rcut_values -> push_back ("R008"); 
  rcut_values -> push_back ("R005"); 
  rcut_values -> push_back ("R003"); 
  rcut_values -> push_back ("R001");
  
  //--------------------------------------------------------------------------------
  // Likelihood getter
  //--------------------------------------------------------------------------------

  int n_rcut_variables = rcut_values -> size();

  std::vector<std::string> likelihood_variables;
  likelihood_variables.push_back ( "nDaught" );
  likelihood_variables.push_back ( "width"   );
  likelihood_variables.push_back ( "multi"   );
  likelihood_variables.push_back ( "ptd"     );
  likelihood_variables.push_back ( "nsubj"   );
  likelihood_variables.push_back ( "mass"    );
  likelihood_variables.push_back ( "profile50" );
  likelihood_variables.push_back ( "leadCoreJetFraction" );
  likelihood_variables.push_back ("leadCoreJetDR");
  
  std::string file_name ("likelihood_hists_fromWJet.root");

  std::vector<likelihoodGetter> likelihoods;

  for (int ircut = 0; ircut < n_rcut_variables; ++ircut){
    std::string signal("quarkPruned");
    signal = signal + (*rcut_values)[ircut];
    signal = signal + std::string("Jets");
    std::vector<std::string> signals;
    signals.push_back ( signal );
    likelihoodGetter l ( file_name,(*rcut_values)[ircut] , likelihood_variables, signals );
    likelihoods.push_back (l);
  }
  
  //--------------------------------------------------------------------------------
  // Make histograms
  //--------------------------------------------------------------------------------

  TH2F * all_tau_ptVsPull      = makeTH2F("all_tau_ptVsPull" ,  100, 0, 500,  100, -2, 2);
  TH2F * fid_tau_ptVsPull      = makeTH2F("fid_tau_ptVsPull" ,  100, 0, 500,  100, -2, 2);
  TH2F * all_vbfq_ptVsPull     = makeTH2F("all_vbfq_ptVsPull",  100, 0, 500,   100, -2, 2);
  TH2F * fid_vbfq_ptVsPull     = makeTH2F("fid_vbfq_ptVsPull",  100, 0, 500,   100, -2, 2);

  TH1F * all_vbfq_matchDR = makeTH1F( "all_vbfq_matchDR", 100, 0, 2 );
  TH1F * fid_vbfq_matchDR = makeTH1F( "fid_vbfq_matchDR", 100, 0, 2 );

  TH1F * all_recojet_matched_matchDR = makeTH1F("all_recojet_matched_matchDR", 100, 0, 2 );
  TH1F * all_recojet_matched_eta     = makeTH1F("all_recojet_matched_eta", 100, -5., 5.);
  TH1F * all_recojet_matched_pt      = makeTH1F("all_recojet_matched_pt", 100, 0, 200 );
	                             
  TH1F * fid_recojet_matched_matchDR = makeTH1F("fid_recojet_matched_matchDR", 100, 0, 2 );
  TH1F * fid_recojet_matched_eta     = makeTH1F("fid_recojet_matched_eta", 100, -5., 5.);
  TH1F * fid_recojet_matched_pt      = makeTH1F("fid_recojet_matched_pt", 100, 0, 200 );
  
  TH1F* all_tau_pull      = makeTH1F("all_tau_pull"     , 100, -2, 2);
  TH1F* fid_tau_pull      = makeTH1F("fid_tau_pull"     , 100, -2, 2);
  TH1F* all_vbfq_pull     = makeTH1F("all_vbfq_pull"     , 100, -2, 2);
  TH1F* fid_vbfq_pull     = makeTH1F("fid_vbfq_pull"     , 100, -2, 2);

  TH1F* all_tau_rawPull      = makeTH1F("all_tau_rawPull"     , 100, -2, 2);
  TH1F* fid_tau_rawPull      = makeTH1F("fid_tau_rawPull"     , 100, -2, 2);
  TH1F* all_vbfq_rawPull     = makeTH1F("all_vbfq_rawPull"     , 100, -2, 2);
  TH1F* fid_vbfq_rawPull     = makeTH1F("fid_vbfq_rawPull"     , 100, -2, 2);
  
  TH1F* all_tau_gen_pt    = makeTH1F("all_tau_gen_pt"   , 100, 0, 500);
  TH1F* all_tau_reco_pt   = makeTH1F("all_tau_reco_pt"  , 100, 0, 500);
  TH1F* fid_tau_gen_pt    = makeTH1F("fid_tau_gen_pt"   , 100, 0, 500);
  TH1F* fid_tau_reco_pt   = makeTH1F("fid_tau_reco_pt"  , 100, 0, 500);

  TH1F* all_vbfq_gen_pt   = makeTH1F("all_vbfq_gen_pt"  , 100, 0, 500);
  TH1F* all_vbfq_reco_pt  = makeTH1F("all_vbfq_reco_pt" , 100, 0, 500);
  TH1F* fid_vbfq_gen_pt   = makeTH1F("fid_vbfq_gen_pt"  , 100, 0, 500);
  TH1F* fid_vbfq_reco_pt  = makeTH1F("fid_vbfq_reco_pt" , 100, 0, 500);

  TH1F* all_tau_gen_eta   = makeTH1F("all_tau_gen_eta"  , 100, -5., 5.);
  TH1F* all_tau_reco_eta  = makeTH1F("all_tau_reco_eta" , 100, -5., 5.);
  TH1F* fid_tau_gen_eta   = makeTH1F("fid_tau_gen_eta"  , 100, -5., 5.);
  TH1F* fid_tau_reco_eta  = makeTH1F("fid_tau_reco_eta" , 100, -5., 5.);

  TH1F* all_vbfq_gen_eta  = makeTH1F("all_vbfq_gen_eta" , 100, -5., 5.);
  TH1F* all_vbfq_reco_eta = makeTH1F("all_vbfq_reco_eta", 100, -5., 5.);
  TH1F* fid_vbfq_gen_eta  = makeTH1F("fid_vbfq_gen_eta" , 100, -5., 5.);
  TH1F* fid_vbfq_reco_eta = makeTH1F("fid_vbfq_reco_eta", 100, -5., 5.);

  TH1F * fid_vbfq_reco_chargedFraction = makeTH1F("fid_vbfq_reco_chargedFraction", 100, 0, 1.);
  TH1F * fid_vbfq_reco_neutralFraction = makeTH1F("fid_vbfq_reco_neutralFraction", 100, 0, 1.);

  std::vector<TH1F*> th1_templates;
  th1_templates.push_back ( makeTH1F ("nsubj"                 , 20  ,  0. ,     1.  )); // 0
  th1_templates.push_back ( makeTH1F ("mass"                  , 40 ,  0. , 200000.  )); // 1
  th1_templates.push_back ( makeTH1F ("nDaught"               , 50  , -0.5,    49.5 )); // 2
  th1_templates.push_back ( makeTH1F ("multi"                 , 100 , -0.5,   999.5 ));	// 3
  th1_templates.push_back ( makeTH1F ("width"                 , 200 ,  0. ,     1.  ));	// 4
  th1_templates.push_back ( makeTH1F ("chargedWidth"          , 200 ,  0. ,     1.  ));	// 5
  th1_templates.push_back ( makeTH1F ("neutralWidth"          , 200 ,  0. ,     1.  ));	// 6
  th1_templates.push_back ( makeTH1F ("depth"                 , 200 ,  0. ,  1000.  ));	// 7
  th1_templates.push_back ( makeTH1F ("depth_noEE"            , 200 ,  0. ,  1000.  ));	// 8
  th1_templates.push_back ( makeTH1F ("ptd"                   ,  20 ,  0. ,     1.  ));	// 9
  th1_templates.push_back ( makeTH1F ("like"                  , 100 ,  0. ,     1.1 ));	// 10
  th1_templates.push_back ( makeTH1F ("ee_energy_fraction"    , 100 ,  0. ,     1.  ));	// 11
  th1_templates.push_back ( makeTH1F ("ee015_energy_fraction" , 100 ,  0. ,     1.  ));	// 12
  th1_templates.push_back ( makeTH1F ("ee1631_energy_fraction", 100 ,  0. ,     1.  )); // 13
  th1_templates.push_back ( makeTH1F ("heb_energy_fraction"   , 100 ,  0. ,     1.  ));	// 14
  th1_templates.push_back ( makeTH1F ("hef_energy_fraction"   , 100 ,  0. ,     1.  ));	// 15
  th1_templates.push_back ( makeTH1F ("hef11_energy_fraction" , 100 ,  0. ,     1.  ));	// 16
  th1_templates.push_back ( makeTH1F ("hef22_energy_fraction" , 100 ,  0. ,     1.  ));	// 17
  th1_templates.push_back ( makeTH1F ("hef34_energy_fraction" , 100 ,  0. ,     1.  ));	// 18
  th1_templates.push_back ( makeTH1F ("hef56_energy_fraction" , 100 ,  0. ,     1.  ));	// 19
  th1_templates.push_back ( makeTH1F ("hef712_energy_fraction", 100 ,  0. ,     1.  )); // 20
  th1_templates.push_back ( makeTH1F ("profile"               , n_radii + 1 ,  min_radius, max_radius )); // 21
  th1_templates.push_back ( makeTH1F ("profile50"             , n_radii + 1 ,  min_radius, max_radius )); // 22
  th1_templates.push_back ( makeTH1F ("profile90"             , n_radii + 1 ,  min_radius, max_radius )); // 23
  th1_templates.push_back ( makeTH1F ("profile95"             , n_radii + 1 ,  min_radius, max_radius )); // 24
  th1_templates.push_back ( makeTH1F ("profile99"             , n_radii + 1 ,  min_radius, max_radius )); // 25
  th1_templates.push_back ( makeTH1F ("nCoreJets"             , 10, -0.5, 9.5 )); // 26
  th1_templates.push_back ( makeTH1F ("leadCoreJetDR"         , 100, 0., 0.4 )); // 27
  th1_templates.push_back ( makeTH1F ("leadCoreJetFraction"   , 100, 0., 1.  )); // 28
  th1_templates.push_back ( makeTH1F ("volume"                , 100, -10, 10)); // 29
  th1_templates.push_back ( makeTH1F ("length"                , 100, -10, 10)); // 30
  
  std::vector<TH2F*> th2_templates;
  th2_templates.push_back ( makeTH2F ("jetPt_vs_depth"      , 100, 0, 250, 200 ,  0. ,  1000.  ));
  th2_templates.push_back ( makeTH2F ("jetPt_vs_maxRHDepth" , 100, 0, 250, 200 ,  0. ,  1000.  ));
  th2_templates.push_back ( makeTH2F ("NPFCands_vs_NSubJets", 51 , -0.5, 50.5, 5 , -0.5, 4.5 ));

  std::map<std::string, std::vector<TH1F*> > m_quark_rcut_th1;
  std::map<std::string, std::vector<TH1F*> > m_gluon_rcut_th1;
  std::map<std::string, std::vector<TH2F*> > m_quark_rcut_th2;
  std::map<std::string, std::vector<TH2F*> > m_gluon_rcut_th2;
  
  int n_th1_templates = th1_templates.size();
  int n_th2_templates = th2_templates.size();
  int n_rcutValues    = rcut_values -> size();
  char quark_hist_name[100];
  char gluon_hist_name[100];

  for (int i_th1_template = 0; i_th1_template < n_th1_templates; ++i_th1_template){
    for (int i_rcutValue = 0; i_rcutValue < n_rcutValues; ++i_rcutValue ){
      
      TH1F * hist_template = th1_templates[i_th1_template];
      
      sprintf(quark_hist_name, "%s_quarkPruned%sJets", hist_template -> GetName(), (*rcut_values)[i_rcutValue].c_str());
      sprintf(gluon_hist_name, "%s_gluonPruned%sJets", hist_template -> GetName(), (*rcut_values)[i_rcutValue].c_str());
      
      TH1F * quark_hist = makeTH1F(quark_hist_name, 
				   hist_template -> GetNbinsX(), 
				   hist_template -> GetXaxis() -> GetXmin(),
				   hist_template -> GetXaxis() -> GetXmax() );
				   
      TH1F * gluon_hist = makeTH1F(gluon_hist_name, 
				   hist_template -> GetNbinsX(), 
				   hist_template -> GetXaxis() -> GetXmin(),
				   hist_template -> GetXaxis() -> GetXmax() );

      m_quark_rcut_th1[(*rcut_values)[i_rcutValue]].push_back(quark_hist);
      m_gluon_rcut_th1[(*rcut_values)[i_rcutValue]].push_back(gluon_hist);
      
    }
  }

  
  for (int i_th2_template = 0; i_th2_template < n_th2_templates; ++i_th2_template){
    for (int i_rcutValue = 0; i_rcutValue < n_rcutValues; ++i_rcutValue ){
      
      TH2F * hist_template = th2_templates[i_th2_template];
      
      sprintf(quark_hist_name, "%s_quarkPruned%sJets", hist_template -> GetName(), (*rcut_values)[i_rcutValue].c_str());
      sprintf(gluon_hist_name, "%s_gluonPruned%sJets", hist_template -> GetName(), (*rcut_values)[i_rcutValue].c_str());
      
      TH2F * quark_hist = makeTH2F(quark_hist_name, 
				   hist_template -> GetNbinsX(), 
				   hist_template -> GetXaxis() -> GetXmin(),
				   hist_template -> GetXaxis() -> GetXmax(),
				   hist_template -> GetNbinsY(), 
				   hist_template -> GetYaxis() -> GetXmin(),
				   hist_template -> GetYaxis() -> GetXmax());
				   
      TH2F * gluon_hist = makeTH2F(gluon_hist_name, 
				   hist_template -> GetNbinsX(), 
				   hist_template -> GetXaxis() -> GetXmin(),
				   hist_template -> GetXaxis() -> GetXmax(),
				   hist_template -> GetNbinsY(), 
				   hist_template -> GetYaxis() -> GetXmin(),
				   hist_template -> GetYaxis() -> GetXmax());
				   
      m_quark_rcut_th2[(*rcut_values)[i_rcutValue]].push_back(quark_hist);
      m_gluon_rcut_th2[(*rcut_values)[i_rcutValue]].push_back(gluon_hist);
      
    }
  }

  
  
  //--------------------------------------------------------------------------------
  // Loop over the events
  //--------------------------------------------------------------------------------
  
  for (int iEvent = 0; iEvent < n_events; ++iEvent){

    //--------------------------------------------------------------------------------
    // Tell the user where we are
    //--------------------------------------------------------------------------------

    if ( (iEvent + 1) <= 10 || (iEvent + 1) % 100 == 0 ) 
      std::cout << "Processing event " << (iEvent + 1) << "/" << n_events << std::endl;
    
    //--------------------------------------------------------------------------------
    // Get each entry in the event
    //--------------------------------------------------------------------------------

    tree -> GetEntry (iEvent);

    //--------------------------------------------------------------------------------
    // GEN particle collections
    //--------------------------------------------------------------------------------
    
    // All GEN particles
    CollectionPtr c_gen_all  ( new Collection(*tree, tree -> GenParticlePt -> size()));

    // std::cout << "------------------------------------------------------------" << std::endl;
    // c_gen_all ->  examine <GenParticle> ( "All GEN particles" );
    // 
    // continue;

    // GEN particles for jet matching
    CollectionPtr c_partons  = c_gen_all -> SkimByID<GenParticle>(GEN_PARTICLE_IS_FINAL_STATE_PARTON);
    CollectionPtr c_gen_vbfq = c_gen_all -> SkimByID<GenParticle>(GEN_PARTICLE_IS_HARD_SCATTER_VBF_QUARK);
    CollectionPtr c_gen_tau  = c_gen_all -> SkimByID<GenParticle>(GEN_PARTICLE_IS_HARD_SCATTER_TAU);

    //--------------------------------------------------------------------------------
    // PFJet collections
    //--------------------------------------------------------------------------------

    CollectionPtr c_pfjet_all  ( new Collection(*tree, tree -> PFCA4JetPt -> size()));
    CollectionPtr c_pfjet_minPt       = c_pfjet_all   -> SkimByMinPt<PFPrunedJet> ( pfjet_pt_minimum ) ;
    CollectionPtr c_pfjet_fid         = c_pfjet_all   -> SkimByAbsEtaRange<PFPrunedJet> ( HGCAL_abseta_min, HGCAL_abseta_max );
    CollectionPtr c_pfjet_minPtAndFid = c_pfjet_minPt -> SkimByAbsEtaRange<PFPrunedJet> ( HGCAL_abseta_min, HGCAL_abseta_max );

    CollectionPtr c_pfcorejet_all  ( new Collection(*tree, tree -> PFAK1p5JetPt -> size()));
    CollectionPtr c_pfcorejet_minPt       = c_pfcorejet_all   -> SkimByMinPt<PFCoreJet> ( pfcorejet_pt_minimum ) ;
    CollectionPtr c_pfcorejet_minPtAndFid = c_pfcorejet_minPt -> SkimByAbsEtaRange<PFCoreJet> ( HGCAL_abseta_min, HGCAL_abseta_max );

    //--------------------------------------------------------------------------------
    // Clusters
    //--------------------------------------------------------------------------------

    CollectionPtr c_hgceeClusters_all  ( new Collection (*tree, tree -> HGCEEPFClusterPt  -> size()));
    CollectionPtr c_hgchefClusters_all ( new Collection (*tree, tree -> HGCHEFPFClusterPt -> size()));
    CollectionPtr c_hgchebClusters_all ( new Collection (*tree, tree -> HGCHEBPFClusterPt -> size()));
    
    //--------------------------------------------------------------------------------
    // GenJet collections
    //--------------------------------------------------------------------------------

    /*
    CollectionPtr c_genjet_all ( new Collection(*tree, tree -> GenJetPt -> size()));
    int n_genjet = c_genjet_all -> GetSize();

    for (int i_genjet = 0; i_genjet < n_genjet; ++i_genjet){
      GenJet genjet = c_genjet_all -> GetConstituent<GenJet>(i_genjet);
      int flavor = getFlavor( genjet, c_partons );
      if ( flavor == 0 ) continue;
      PFPrunedJet jet_matched_reco = c_pfjet_all -> GetClosestInDR<PFPrunedJet, GenJet>(genjet);
      double deltaR = jet_matched_reco.DeltaR( &genjet );
      double eta    = jet_matched_reco.Eta();
      double pt     = jet_matched_reco.Pt();
      
      all_recojet_matched_matchDR  -> Fill ( deltaR );
      all_recojet_matched_eta      -> Fill ( eta    );
      all_recojet_matched_pt       -> Fill ( pt     );
                                  
      if ( abs(genjet.Eta()) > HGCAL_abseta_min && 
	   abs(genjet.Eta()) < HGCAL_abseta_max ){
	
	fid_recojet_matched_matchDR -> Fill ( deltaR ) ;
	fid_recojet_matched_eta     -> Fill ( eta    ) ;
	fid_recojet_matched_pt      -> Fill ( pt     ) ;
      }
    }
    */

    //--------------------------------------------------------------------------------
    // Match PFJets 
    //--------------------------------------------------------------------------------

    int n_gen_vbfq = c_gen_vbfq -> GetSize();

    for (int i_gen_vbfq = 0; i_gen_vbfq < n_gen_vbfq; ++i_gen_vbfq){

      GenParticle vbfq_gen  = c_gen_vbfq    -> GetConstituent<GenParticle> (i_gen_vbfq);
      PFPrunedJet vbfq_reco = c_pfjet_minPt -> GetClosestInDR<PFPrunedJet, GenParticle>(vbfq_gen);      

      if ( vbfq_reco.GetRawIndex() < 0 ) continue;
      double pull, rawPull;
      if ( vbfq_gen.Pt() > 0. ) pull    = (vbfq_reco.Pt()    - vbfq_gen.Pt()) / vbfq_gen.Pt();
      if ( vbfq_gen.Pt() > 0. ) rawPull = (vbfq_reco.PtRaw() - vbfq_gen.Pt()) / vbfq_gen.Pt();
      else continue;
      
      bool isFid = ( fabs(vbfq_gen.Eta()) >= HGCAL_abseta_min &&
		     fabs(vbfq_gen.Eta()) <= HGCAL_abseta_max );

      double deltaR = vbfq_reco.DeltaR(&vbfq_gen);
      if ( deltaR > maximum_deltaR_match ) continue;

      all_vbfq_ptVsPull -> Fill ( vbfq_gen.Pt(), pull );
      all_vbfq_pull     -> Fill ( pull );
      all_vbfq_rawPull  -> Fill ( rawPull );
      all_vbfq_gen_pt   -> Fill ( vbfq_gen.Pt() );
      all_vbfq_reco_pt  -> Fill ( vbfq_reco.Pt() );
      all_vbfq_gen_eta  -> Fill ( vbfq_gen.Eta() );
      all_vbfq_reco_eta -> Fill ( vbfq_reco.Eta() );
      all_vbfq_matchDR  -> Fill ( deltaR );

      if ( isFid ){
	fid_vbfq_reco_chargedFraction -> Fill ( vbfq_reco.getChargedFraction() );
	fid_vbfq_reco_neutralFraction -> Fill ( vbfq_reco.getNeutralFraction() );
	fid_vbfq_ptVsPull -> Fill ( vbfq_gen.Pt(), pull );
	fid_vbfq_pull     -> Fill ( pull );
	fid_vbfq_rawPull  -> Fill ( rawPull );
	fid_vbfq_gen_pt   -> Fill ( vbfq_gen.Pt() );
	fid_vbfq_reco_pt  -> Fill ( vbfq_reco.Pt() );
	fid_vbfq_gen_eta  -> Fill ( vbfq_gen.Eta() );
	fid_vbfq_reco_eta -> Fill ( vbfq_reco.Eta() );
	fid_vbfq_matchDR  -> Fill ( vbfq_reco.DeltaR(&vbfq_gen));
      }
    }

    int n_gen_tau = c_gen_tau -> GetSize();
    for (int i_gen_tau = 0; i_gen_tau < n_gen_tau; ++i_gen_tau){
      GenParticle tau_gen  = c_gen_tau  -> GetConstituent<GenParticle> (i_gen_tau);
      PFPrunedJet tau_reco = c_pfjet_all -> GetClosestInDR<PFPrunedJet, GenParticle>(tau_gen);
      if ( tau_reco.GetRawIndex() < 0 ) continue;
      double pull, rawPull;
      if ( tau_gen.Pt() > 0. ) pull    = (tau_reco.Pt()    - tau_gen.Pt()) / tau_gen.Pt();
      if ( tau_gen.Pt() > 0. ) rawPull = (tau_reco.PtRaw() - tau_gen.Pt()) / tau_gen.Pt();
      bool isFid = ( fabs(tau_gen.Eta()) >= HGCAL_abseta_min &&
		     fabs(tau_gen.Eta()) <= HGCAL_abseta_max );


      all_tau_ptVsPull -> Fill ( tau_gen.Pt(), pull );
      all_tau_pull     -> Fill ( pull );
      all_tau_rawPull  -> Fill ( rawPull );
      all_tau_gen_pt   -> Fill ( tau_gen.Pt() );
      all_tau_reco_pt  -> Fill ( tau_reco.Pt() );
      all_tau_gen_eta   -> Fill ( tau_gen.Eta() );
      all_tau_reco_eta  -> Fill ( tau_reco.Eta() );

      if ( isFid ){
	fid_tau_ptVsPull -> Fill ( tau_gen.Pt(), pull );
	fid_tau_pull     -> Fill ( pull );
	fid_tau_rawPull  -> Fill ( rawPull );
	fid_tau_gen_pt   -> Fill ( tau_gen.Pt() );
	fid_tau_reco_pt  -> Fill ( tau_reco.Pt() );
	fid_tau_gen_eta   -> Fill ( tau_gen.Eta() );
	fid_tau_reco_eta  -> Fill ( tau_reco.Eta() );
      }
    }

    //--------------------------------------------------------------------------------
    // Loop over rcut values
    //--------------------------------------------------------------------------------

    for (int i_rcutValue = 0; i_rcutValue < n_rcutValues; ++i_rcutValue){

      fillPlots<PFPrunedJet> ( c_pfjet_minPtAndFid, c_pfcorejet_minPtAndFid , c_partons,
			       c_hgceeClusters_all, c_hgchefClusters_all, c_hgchebClusters_all, 
			       likelihoods[i_rcutValue], i_rcutValue,
    			       m_quark_rcut_th1[(*rcut_values)[i_rcutValue]], 
    			       m_gluon_rcut_th1[(*rcut_values)[i_rcutValue]], 
    			       m_quark_rcut_th2[(*rcut_values)[i_rcutValue]], 
    			       m_gluon_rcut_th2[(*rcut_values)[i_rcutValue]] );
      
    }
    // end loop over r-cut values
  } // end loop over events
} // end loop function
void analysisClassL1::loop(){

  std::string MyTrigger="HLT_Any";

  std::vector<std::string> triggerList =  {"L1_SingleJet092","L1_SingleJet128","L1_SingleJet176","L1_SingleJet200","L1_SingleJet240"};
  std::vector<std::string> preTriggerList =  {"L1_SingleJet092","L1_SingleJet128","L1_SingleJet176","L1_SingleJet200","L1_SingleJet240"};

  L1Tree * l1Tree = getTree<L1Tree>("l1Tree");

  int n_events = l1Tree -> fChain -> GetEntries();

  l1Tree -> fChain -> SetBranchStatus("*", kFALSE);
  l1Tree -> fChain -> SetBranchStatus("lumi",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Njet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Bxjet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Rankjet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Etajet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Phijet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Fwdjet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("tw1",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("tw2",kTRUE);
  
  std::map<std::string,TH1F*> etaHistList;
  std::map<std::string,TH2F*> etaPhiHistList;
  std::map<std::string,TH1F*> l1BitHistList;
  std::map<std::string,std::map<std::string,TH1F*>> preFireEtaHistList;
  std::map<std::string,std::map<std::string,TH2F*>> prePreFireEtaPhiHistList;
  std::map<std::string,std::map<std::string,TH2F*>> preFireEtaPhiHistList;
  std::map<std::string,std::map<std::string,TH2F*>> postFireEtaPhiHistList;
  std::map<std::string,std::map<std::string,TH2F*>> postPostFireEtaPhiHistList;
  std::map<std::string,std::map<std::string,TH1F*>> deltaRHistList;
  std::map<std::string,std::map<std::string,TH1F*>> postDeltaRHistList;
  std::map<std::string,std::map<std::string,TH1F*>> postPostDeltaRHistList;
  std::map<std::string,std::map<std::string,TH1F*>> prePreDeltaRHistList;
  char histName[100];
  for (std::vector<std::string>::iterator it = triggerList.begin(); it != triggerList.end(); it++){
    sprintf(histName,"h_etaBin_%s",it->c_str());
    etaHistList[*it] = makeTH1F(histName,22,-0.5,21.5);
    sprintf(histName,"h_etaPhiBin_%s",it->c_str());
    etaPhiHistList[*it] = makeTH2F(histName,22,-0.5,21.5,18,-0.5,17.5);
    sprintf(histName,"h_l1Bit_%s",it->c_str());
    l1BitHistList[*it] = makeTH1F(histName,2,-0.5,1.5);
    preFireEtaHistList[*it] = std::map<std::string,TH1F*>();
    for (std::vector<std::string>::iterator it2 = preTriggerList.begin(); it2 != preTriggerList.end(); it2++){
      sprintf(histName,"h_preFireEtaBin%s_%s",it->c_str(),it2->c_str());
      preFireEtaHistList[*it][*it2] = makeTH1F(histName,22,-0.5,21.5);
      sprintf(histName,"h_prePreFireEtaPhiBin%s_%s",it->c_str(),it2->c_str());
      prePreFireEtaPhiHistList[*it][*it2] = makeTH2F(histName,22,-0.5,21.5,18,-0.5,17.5);
      sprintf(histName,"h_preFireEtaPhiBin%s_%s",it->c_str(),it2->c_str());
      preFireEtaPhiHistList[*it][*it2] = makeTH2F(histName,22,-0.5,21.5,18,-0.5,17.5);
      sprintf(histName,"h_postFireEtaPhiBin%s_%s",it->c_str(),it2->c_str());
      postFireEtaPhiHistList[*it][*it2] = makeTH2F(histName,22,-0.5,21.5,18,-0.5,17.5);
      sprintf(histName,"h_postPostFireEtaPhiBin%s_%s",it->c_str(),it2->c_str());
      postPostFireEtaPhiHistList[*it][*it2] = makeTH2F(histName,22,-0.5,21.5,18,-0.5,17.5);
      sprintf(histName,"h_deltaR%s_%s",it->c_str(),it2->c_str());
      deltaRHistList[*it][*it2] = makeTH1F(histName,50,-0.5,5.5);
      sprintf(histName,"h_postDeltaR%s_%s",it->c_str(),it2->c_str());
      postDeltaRHistList[*it][*it2] = makeTH1F(histName,50,-0.5,5.5);
      sprintf(histName,"h_prePreDeltaR%s_%s",it->c_str(),it2->c_str());
      prePreDeltaRHistList[*it][*it2] = makeTH1F(histName,50,-0.5,5.5);
      sprintf(histName,"h_postPostDeltaR%s_%s",it->c_str(),it2->c_str());
      postPostDeltaRHistList[*it][*it2] = makeTH1F(histName,50,-0.5,5.5);
    };
  };

  loadPrescaleMap();
  loadBitMap();

  for (int i = 0; i < n_events; ++i){
    l1Tree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    int lumi = l1Tree -> lumi;
    if (lumi < 126) continue;
    int prescaleIndex;
    if (lumi < 317){
      prescaleIndex = 6;
    }else{
      prescaleIndex = 7;
    };

    tw1 = l1Tree -> tw1;
    tw2 = l1Tree -> tw2;
    Njet = l1Tree -> Njet;
    Bxjet = l1Tree -> Bxjet;
    Rankjet = l1Tree -> Rankjet;
    Etajet = l1Tree -> Etajet;
    Phijet = l1Tree -> Phijet;
    Fwdjet = l1Tree -> Fwdjet;
    tw1 = l1Tree -> tw1;
    tw2 = l1Tree -> tw2;

    for (std::vector<std::string>::iterator it = triggerList.begin(); it != triggerList.end(); it++){
      bool Bx2Fired = checkTriggerBit(BitMap[*it],2);
      float ptThreshold = (float)std::stoi(it -> substr(12)); 
      int jetEtaBin = SingleJetEtaBin(ptThreshold,0);
      int jetPhiBin = SingleJetPhiBin(ptThreshold,0);
      if (Bx2Fired){
        l1BitHistList[*it] -> Fill(1,PrescaleMap[prescaleIndex][*it]);
      };

      if ((jetEtaBin != -10) && (jetPhiBin != -10)){
        etaHistList[*it] -> Fill(jetEtaBin,PrescaleMap[prescaleIndex][*it]);
	etaPhiHistList[*it] -> Fill(jetEtaBin,jetPhiBin,PrescaleMap[prescaleIndex][*it]);
        for (std::vector<std::string>::iterator it2 = preTriggerList.begin(); it2 != preTriggerList.end(); it2++){
	  float ptThreshold_OtherBx = (float)std::stoi(it2 -> substr(12));
	  int jetEtaBin_BxM1 = SingleJetEtaBin(ptThreshold_OtherBx,-1);
	  int jetPhiBin_BxM1 = SingleJetPhiBin(ptThreshold_OtherBx,-1);
          if ((jetEtaBin_BxM1 != -10) && (jetPhiBin_BxM1 != -10)){
            preFireEtaHistList[*it][*it2] -> Fill(jetEtaBin_BxM1,PrescaleMap[prescaleIndex][*it2]);
	    preFireEtaPhiHistList[*it][*it2] -> Fill(jetEtaBin_BxM1,jetPhiBin_BxM1,PrescaleMap[prescaleIndex][*it2]);
            double jetEta_BxM1 = SingleJetEta(ptThreshold_OtherBx,-1);
            double jetPhi_BxM1 = SingleJetPhi(ptThreshold_OtherBx,-1);
            double jetEta = SingleJetEta(ptThreshold,0);
            double jetPhi = SingleJetPhi(ptThreshold,0);
	    deltaRHistList[*it][*it2] -> Fill(DeltaR(jetEta_BxM1,jetEta,jetPhi_BxM1,jetPhi));
	  };
	  int jetEtaBin_BxP1 = SingleJetEtaBin(ptThreshold_OtherBx,1);
	  int jetPhiBin_BxP1 = SingleJetPhiBin(ptThreshold_OtherBx,1);
	  if ((jetEtaBin_BxP1 != -10) && (jetPhiBin_BxP1 != -10)){
	    double jetEta = SingleJetEta(ptThreshold,0);
            double jetPhi = SingleJetPhi(ptThreshold,0);
	    postFireEtaPhiHistList[*it][*it2] -> Fill(jetEtaBin_BxP1,jetPhiBin_BxP1,PrescaleMap[prescaleIndex][*it2]);
            postDeltaRHistList[*it][*it2] -> Fill(DeltaR(jetEtaBin_BxP1,jetEta,jetPhiBin_BxP1,jetPhi));
	  };
	  int jetEtaBin_BxM2 = SingleJetEtaBin(ptThreshold_OtherBx,-2);
	  int jetPhiBin_BxM2 = SingleJetPhiBin(ptThreshold_OtherBx,-2);
	  if ((jetEtaBin_BxM2 != -10) && (jetPhiBin_BxM2 != -10)){
	    double jetEta = SingleJetEta(ptThreshold,0);
            double jetPhi = SingleJetPhi(ptThreshold,0);
	    prePreFireEtaPhiHistList[*it][*it2] -> Fill(jetEtaBin_BxM2,jetPhiBin_BxM2,PrescaleMap[prescaleIndex][*it2]);
            prePreDeltaRHistList[*it][*it2] -> Fill(DeltaR(jetEtaBin_BxM2,jetEta,jetPhiBin_BxM2,jetPhi));
	  };
	  int jetEtaBin_BxP2 = SingleJetEtaBin(ptThreshold_OtherBx,2);
	  int jetPhiBin_BxP2 = SingleJetPhiBin(ptThreshold_OtherBx,2);
	  if ((jetEtaBin_BxP2 != -10) && (jetPhiBin_BxP2 != -10)){
	    double jetEta = SingleJetEta(ptThreshold,0);
            double jetPhi = SingleJetPhi(ptThreshold,0);
	    postPostFireEtaPhiHistList[*it][*it2] -> Fill(jetEtaBin_BxP2,jetPhiBin_BxP2,PrescaleMap[prescaleIndex][*it2]);
            postPostDeltaRHistList[*it][*it2] -> Fill(DeltaR(jetEtaBin_BxP2,jetEta,jetPhiBin_BxP2,jetPhi));
	  };

	};
      };
    };
  };

  char titleName[100];
  for (std::map<std::string,TH1F*>::iterator itr = etaHistList.begin(); itr != etaHistList.end(); ++itr){
    sprintf(titleName,"%s, L1Object:%4.0f, L1Bit:%4.0f ; Eta Bin ( 0 - 21 ); Number of Event",itr->first.c_str(),itr -> second -> Integral(),l1BitHistList[itr->first]->Integral());
    itr -> second -> SetTitle(titleName);
    sprintf(titleName,"%s, L1Object:%4.0f, L1Bit:%4.0f ; Eta Bin ( 0 - 21 ); Phi Bin ( 0 - 17 )",itr->first.c_str(),etaPhiHistList[itr -> first],l1BitHistList[itr->first]->Integral());
    etaPhiHistList[itr -> first] -> SetTitle(titleName);
    for (std::vector<std::string>::iterator it2 = preTriggerList.begin(); it2 != preTriggerList.end(); it2++){
      sprintf(titleName,"Bx2: %s, Bx1: %s, Prefire Rate: %4.3f ; Eta Bin ( 0 - 21 ); Number of Event",itr->first.c_str(),it2->c_str(),preFireEtaHistList[itr->first][*it2]->Integral()/itr->second->Integral());
      preFireEtaHistList[itr->first][*it2] -> SetTitle(titleName);
      sprintf(titleName,"Bx2: %s, Bx1: %s, Prefire Rate: %4.3f ; Eta Bin ( 0 - 21 ); Phi Bin (0 - 17)",itr->first.c_str(),it2->c_str(),preFireEtaHistList[itr->first][*it2]->Integral()/itr->second->Integral());
      preFireEtaPhiHistList[itr->first][*it2] -> SetTitle(titleName);
      sprintf(titleName,"Bx2: %s, Bx1: %s, Prefire Rate: %4.3f ; Eta Bin ( 0 - 21 ); Phi Bin (0 - 17)",itr->first.c_str(),it2->c_str(),preFireEtaHistList[itr->first][*it2]->Integral()/itr->second->Integral());
      postFireEtaPhiHistList[itr->first][*it2] -> SetTitle(titleName);
    };
  };
}
void analysisClassL1::loop(){

//__________________________________________________________________||
//Configurables

  std::string HLT_Trigger = "HLT_Any";
  std::vector<double> preFireTrigger = {30., 60., 90.,120.,150.,180.,210.,240.};
  // std::vector<std::string> preFireTrigger = {"L1_HTT075","L1_HTT100","L1_HTT125","L1_HTT150","L1_HTT175","L1_HTT200"};
  double lowPtThreshold = 45.;
  double highPtThreshold = 305.;
  int nThresholds = 26;

//__________________________________________________________________||
//Constant
  std::vector<int> hfEtaBin = {0,1,2,3,18,19,20,21};

//__________________________________________________________________||
//Get Trees

  L1Tree * l1Tree = getTree<L1Tree>("l1Tree");
  L1ExtraTree * l1ExtraTree = getTree<L1ExtraTree>("l1ExtraTree");

//__________________________________________________________________||
//Number of Events

  int n_events = l1Tree -> fChain -> GetEntries();

//__________________________________________________________________||
//Loading Trigger Map

//__________________________________________________________________||
//Turn on necessary branches
  l1Tree -> fChain -> SetBranchStatus("*", kFALSE);
  l1Tree -> fChain -> SetBranchStatus("lumi", kTRUE);
  l1Tree -> fChain -> SetBranchStatus("bx", kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Njet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Bxjet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Rankjet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Etajet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Phijet",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("Fwdjet",kTRUE);
//__________________________________________________________________||
//Histograms
  char histName[100];
  std::map<double,TEfficiency*> h_previousBxFire_HF;
  std::map<double,TEfficiency*> h_previousBxFire_HBHE;
  for (std::vector<double>::iterator it = preFireTrigger.begin(); it != preFireTrigger.end(); it++){
    sprintf(histName,"h_previousBxFire_HF_%.0f",*it);
    h_previousBxFire_HF[*it] =  makeTEff(histName,nThresholds,lowPtThreshold,highPtThreshold);
    sprintf(histName,"h_previousBxFire_HBHE_%.0f",*it);
    h_previousBxFire_HBHE[*it] =  makeTEff(histName,nThresholds,lowPtThreshold,highPtThreshold);
  }; 
  // TH1F* h_previousBxFire_HF = makeTH1F("h_previousBxFire_HF",nThresholds,lowPtThreshold,highPtThreshold);
  // TH1F* h_previousBxFire_HBHE = makeTH1F("h_previousBxFire_HBHE",nThresholds,lowPtThreshold,highPtThreshold);
  TH1F* h_nominalBxFire = makeTH1F("h_nominalBxFire",nThresholds,lowPtThreshold,highPtThreshold);
  int nBins = h_nominalBxFire -> GetNbinsX(); 

//__________________________________________________________________||
//Event loop
  for (int i = 0; i < n_events; ++i){
    l1Tree -> GetEntry(i);
    l1ExtraTree -> GetEntry(i);

    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;
    
    if ((l1ExtraTree -> cenJetEt.size() == 0) && (l1ExtraTree -> fwdJetEt.size() == 0) ) continue;

    int bunchNumber = l1Tree -> bx;
    
    // if (bunchNumber != 39) continue;

    Njet = l1Tree -> Njet;
    Bxjet = l1Tree -> Bxjet;
    Rankjet = l1Tree -> Rankjet;
    Etajet = l1Tree -> Etajet;
    Phijet = l1Tree -> Phijet;
    Fwdjet = l1Tree -> Fwdjet;

    for (int iBin = 0; iBin != nBins; iBin++){
      double ptThreshold = h_nominalBxFire -> GetBinCenter( iBin );
      int jetEtaBin = SingleJetEtaBin(ptThreshold,0);
      if (jetEtaBin != -10){
        h_nominalBxFire -> Fill( ptThreshold );
	for (std::vector<double>::iterator it = preFireTrigger.begin(); it != preFireTrigger.end(); it++){
          int jetEtaBin_BxM1 = SingleJetEtaBin(*it,-1);
          if (jetEtaBin_BxM1 == -10) {
	    h_previousBxFire_HF[*it] -> Fill( false , ptThreshold );
            h_previousBxFire_HBHE[*it] -> Fill( false, ptThreshold ); 
	  } else {
	    if (std::find(hfEtaBin.begin(),hfEtaBin.end(),jetEtaBin_BxM1) != hfEtaBin.end()){
              h_previousBxFire_HF[*it] -> Fill( true , ptThreshold ); 
            } else {
              h_previousBxFire_HBHE[*it] -> Fill( true , ptThreshold ); 
	    };
	  };
	};	
      };
    };       
  };
//__________________________________________________________________||
//Wrap up result

//__________________________________________________________________||

}
void analysisClass::loop(){
  
  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalTupleTree * tuple_tree = getTree<HcalTupleTree>("tuple_tree");
  int n_events = tuple_tree -> fChain -> GetEntries();

  //--------------------------------------------------------------------------------
  // Turn on/off branches
  //--------------------------------------------------------------------------------
  
  tuple_tree -> fChain -> SetBranchStatus("*"               , kFALSE);
  tuple_tree -> fChain -> SetBranchStatus("HODigiIEta"      , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiIPhi"      , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiDepth"     , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiRecEnergy" , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiRecTime"   , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiFC"        , kTRUE );
  tuple_tree -> fChain -> SetBranchStatus("HODigiSize"      , kTRUE );

  //--------------------------------------------------------------------------------
  // Declare and load RBX map
  //--------------------------------------------------------------------------------

  RBXMap map;
  map.LoadFile ( "data/emaps/HCALmapHBEF_E.txt" );
  map.LoadFile ( "data/emaps/HCALmapHO_E.txt" );

  //--------------------------------------------------------------------------------
  // Make histograms
  //--------------------------------------------------------------------------------

  std::vector<TH1F*> h_ho_rbx_charge     (n_hbheho_rbx, 0);
  std::vector<TH1F*> h_ho_channel_charge (n_ho_channels, 0);
  
  char rbx_name[10];
  char hist_name[200];

  for (int i = 0; i < n_hbheho_rbx; ++i){
    std::string rbx_name = getHORBXNameFromIndex(i);
    sprintf(hist_name, "%s_energy", rbx_name.c_str());
    std::cout << i << "\t" << hist_name << std::endl;
    h_ho_rbx_charge[i] = makeTH1F ( hist_name, 1000, -100, 10000 );
  }

  for ( int i = 0; i < n_ho_channels; ++i){
    int side, ieta, iphi, depth;
    map.getCoordinates(i, 3, side, ieta, iphi, depth);
    sprintf(hist_name, "HO_Side%d_IEta%d_IPhi%d_Depth%d_energy", side, ieta, iphi, depth);
    h_ho_channel_charge[i] = makeTH1F(hist_name, 1000, -100, 10000 );
  }

  //--------------------------------------------------------------------------------
  // Loop
  //--------------------------------------------------------------------------------

  for (int i = 0; i < n_events; ++i){
    
    tuple_tree -> GetEntry(i);
    if ( (i + 1) % 100 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    CollectionPtr hoDigis (new Collection(*tuple_tree, tuple_tree -> HODigiIEta -> size()));

    int nHODigis = hoDigis -> GetSize();
    for (int iHODigi = 0; iHODigi < nHODigis; ++iHODigi){
      HODigi hoDigi = hoDigis -> GetConstituent<HODigi>(iHODigi);

      // Collect values
      float  energy = hoDigi.energy();
      float  charge = hoDigi.fcTotal();
      int    ieta   = hoDigi.ieta();
      int    iphi   = hoDigi.iphi();
      int    depth  = hoDigi.depth();
      int    det    = 3;
      int    side   = hoDigi.ieta() / abs(hoDigi.ieta());
      int    rbx_side = map.getRBXSide( det, side, abs(ieta), iphi, depth );
      int    rbx    = map.getRBXNumber( det, side, abs(ieta), iphi, depth );
      int    fed    = map.getFEDNumber( det, side, abs(ieta), iphi, depth );
      int    idet   = det - 1;
      int    iside  = rbx_side + 1;
      int    index  = map.getIndex    ( det, side, abs(ieta), iphi, depth );
      if ( det != 3 ) iside /= 2;
      
      int rbx_index;
      if      ( det <= 2 ) rbx_index = (iside * (n_hbheho_rbx / 2)) + rbx - 1;
      else if ( det == 3 ) rbx_index = getHORBXIndex ( rbx_side, rbx );
      else if ( det == 4 ) rbx_index = (iside * (n_hf_rbx     / 2)) + rbx - 1;

      h_ho_rbx_charge[rbx_index] -> Fill ( charge );
      h_ho_channel_charge[index] -> Fill ( charge );
      
    }
  }
}
void addtestSelection(){
  
  TFile *fnew = new TFile("addtestSelection.root","recreate");
  
  ///all L1 
  TH1F *hh_nL1fired = new TH1F("hh_nL1fired","L1 bit fired",200,0,200);
  TH1F *hh_nL1fired_passpizeb = new TH1F("hh_nL1fired_passpizeb","L1 bit fired && pizeb",200,0,200);
  TH1F *hh_nL1fired_passpizee = new TH1F("hh_nL1fired_passpizee","L1 bit fired && pizee",200,0,200);
  TH1F *hh_nL1fired_passetaeb = new TH1F("hh_nL1fired_passetaeb","L1 bit fired && etaeb",200,0,200);
  TH1F *hh_nL1fired_passetaee = new TH1F("hh_nL1fired_passetaee","L1 bit fired && etaee",200,0,200);
  
  
  //only alcal1 no ps, ps1,ps2
  TH1F *hh_nalcaL1Selected = new TH1F("hh_nalcaL1Selected","hh_nalcaL1Selected",10,0,10);
  TH1F *hh_nalcaL1Selected_passebpiz = new TH1F("hh_nalcaL1Selected_passebpiz","hh_nalcaL1Selected_passebpiz",10,0,10);
  TH1F *hh_nalcaL1Selected_passeepiz = new TH1F("hh_nalcaL1Selected_passeepiz","hh_nalcaL1Selected_passeepiz",10,0,10);
  TH1F *hh_nalcaL1Selected_passebeta = new TH1F("hh_nalcaL1Selected_passebeta","hh_nalcaL1Selected_passebeta",10,0,10);
  TH1F *hh_nalcaL1Selected_passeeeta = new TH1F("hh_nalcaL1Selected_passeeeta","hh_nalcaL1Selected_passeeeta",10,0,10);
  TH1F *hh_nalcaL1Selected_passall = new TH1F("hh_nalcaL1Selected_passall","hh_nalcaL1Selected_passall",10,0,10);
  
  

  ifstream txtin("l1algoName",ios::in);
  string l1; 
  vector<string> l1algo; 
  while(txtin.good()){
    txtin>> l1; 
    if(txtin.eof()) break; 
    l1algo.push_back(l1);
  }
  
  
  for(int j=0;j<3;j++){
    string histname = string(Form("mpair_ebpiz_l1alcaps_%d",j));
    makeTH1F(histname,200,0,1);
    histname = string(Form("mpair_eepiz_l1alcaps_%d",j));
    makeTH1F(histname,200,0,1);
    histname = string(Form("mpair_ebeta_l1alcaps_%d",j));
    makeTH1F(histname,200,0,1);
    histname = string(Form("mpair_eeeta_l1alcaps_%d",j));
    makeTH1F(histname,200,0,1);
  }

  for(int j=0; j<int(l1algo.size());j++){
    l1 = l1algo[j];
    string histname = "mpair_pizeb_" +l1;	
    makeTH1F(histname,200,0,1);
    histname = "mpair_pizee_" +l1;
    makeTH1F(histname,200,0,1);
    histname = "mpair_etaeb_" +l1;
    makeTH1F(histname,200,0,1);
    histname = "mpair_etaee_" +l1;
    makeTH1F(histname,200,0,1);
  }
  
  for(int r=1; r<=162; r++){
    TString filename = TString(Form("res/testSelection.MinimumBiasRun2011B-v1RAW.r%d.root",r));


    TString checkfilename = TString(Form("ls res/testSelection.MinimumBiasRun2011B-v1RAW.r%d.root",r));
    if( gSystem->Exec(checkfilename) !=0){
      continue; 
    }
    
    
    TFile *ff = new TFile(filename,"read");
    
    
    TH1F *hhtmp1 = (TH1F*)ff->Get("hh_nL1fired");
    hh_nL1fired->Add(hhtmp1);
    TH1F *hhtmp2 = (TH1F*)ff->Get("hh_nL1fired_passpizeb");
    hh_nL1fired_passpizeb->Add(hhtmp2);
    TH1F *hhtmp3 = (TH1F*)ff->Get("hh_nL1fired_passpizee");
    hh_nL1fired_passpizee->Add(hhtmp3);
    TH1F *hhtmp4 = (TH1F*)ff->Get("hh_nL1fired_passetaeb");
    hh_nL1fired_passetaeb->Add(hhtmp4);
    TH1F *hhtmp5 = (TH1F*)ff->Get("hh_nL1fired_passetaee");
    hh_nL1fired_passetaee->Add(hhtmp5);
    
    if(r==1){
      for(int b=1; b<= 200; b++){
	TString label = hhtmp1->GetXaxis()->GetBinLabel(b);
	hh_nL1fired->GetXaxis()->SetBinLabel(b,label);
	hh_nL1fired_passpizeb->GetXaxis()->SetBinLabel(b,label);
	hh_nL1fired_passpizee->GetXaxis()->SetBinLabel(b,label);
	hh_nL1fired_passetaeb->GetXaxis()->SetBinLabel(b,label);
	hh_nL1fired_passetaee->GetXaxis()->SetBinLabel(b,label);
      }
    }
    
    TH1F *hhtmp6 = (TH1F*)ff->Get("hh_nalcaL1Selected");
    hh_nalcaL1Selected->Add(hhtmp6);
    TH1F *hhtmp7 = (TH1F*)ff->Get("hh_nalcaL1Selected_passebpiz");
    hh_nalcaL1Selected_passebpiz->Add(hhtmp7);
    TH1F *hhtmp8 = (TH1F*)ff->Get("hh_nalcaL1Selected_passeepiz");
    hh_nalcaL1Selected_passeepiz->Add(hhtmp8);
    TH1F *hhtmp9 = (TH1F*)ff->Get("hh_nalcaL1Selected_passebeta");
    hh_nalcaL1Selected_passebeta->Add(hhtmp9);
    TH1F *hhtmp10 = (TH1F*)ff->Get("hh_nalcaL1Selected_passeeeta");
    hh_nalcaL1Selected_passeeeta->Add(hhtmp10);
    TH1F *hhtmp11 = (TH1F*)ff->Get("hh_nalcaL1Selected_passall");
    hh_nalcaL1Selected_passall->Add(hhtmp11);
    
    for(int j=0;j<3;j++){
      string histname = string(Form("mpair_ebpiz_l1alcaps_%d",j));
      TString hname = TString("th1f_") + histname; 
      TH1F *hh1 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh1);
      

      histname = string(Form("mpair_eepiz_l1alcaps_%d",j));
      hname = TString("th1f_") + histname; 
      TH1F *hh2 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh2);
      
      
      histname = string(Form("mpair_ebeta_l1alcaps_%d",j));
      hname = TString("th1f_") + histname; 
      TH1F *hh3 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh3);
      
      histname = string(Form("mpair_eeeta_l1alcaps_%d",j));
      hname = TString("th1f_") + histname; 
      TH1F *hh4 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh4);
      

    }
    
    
    
    for(int j=0; j<int(l1algo.size());j++){
      l1 = l1algo[j];
      string histname = "mpair_pizeb_" +l1;	
      TString hname = TString("th1f_mpair_pizeb_") +TString(l1);
      TH1F *hh1 = (TH1F*)ff->Get(hname);
      if( !hh1){
	cout<<"non hist " << r<<" "<< hname<<endl; 
	return; 
      }
      
      th1f_map[histname]->Add(hh1);
      
      histname = "mpair_pizee_" +l1;	
      hname = TString("th1f_mpair_pizee_") +TString(l1);
      TH1F *hh2 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh2);

      histname = "mpair_etaeb_" +l1;	
      hname = TString("th1f_mpair_etaeb_") +TString(l1);
      TH1F *hh3 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh3);
      
      histname = "mpair_etaee_" +l1;	
      hname = TString("th1f_mpair_etaee_") +TString(l1);
      TH1F *hh4 = (TH1F*)ff->Get(hname);
      th1f_map[histname]->Add(hh4);
      
    }
    
  }
  

  fnew->Write();
  fnew->Close();
  
  
//    "L1_SingleEG5",
//     "L1_SingleEG7",
//     "L1_SingleEG12",
//     "L1_SingleEG20",
//     "L1_SingleEG22",
//     "L1_SingleEG24",
//     "L1_SingleEG30",
//     "L1_DoubleEG_13_7",
//     "L1_TripleEG7",
//     "L1_TripleEG_12_7_5",
//     "L1_DoubleEG5",
//     "L1_TripleJet_64_44_24_VBF",
//     "L1_TripleJet_64_48_28_VBF",
//     "L1_TripleJetC_52_28_28",
//     "L1_QuadJetC32",
//     "L1_QuadJetC36",
//     "L1_QuadJetC40",
//     "L1_DoubleEG6_HTT100",
//     "L1_DoubleEG6_HTT125",
//     "L1_EG8_DoubleJetC20",
//     "L1_Mu12_EG7",
//     "L1_MuOpen_EG12",
//     "L1_DoubleMu3p5_EG5",
//     "L1_DoubleMu5_EG5",
//     "L1_Mu12_EG7",
//     "L1_Mu5_DoubleEG5",
//     "L1_Mu5_DoubleEG6",
//     "L1_MuOpen_EG5"
  

}
void analysisClass::loop(){


  
  //--------------------------------------------------------------------------------
  // Configurables
  //--------------------------------------------------------------------------------
  std::vector<int> selectIPhis = {19,21,23,25};
 
  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalTupleTree * tuple_tree = getTree<HcalTupleTree>("tuple_tree");
  int n_events = tuple_tree -> fChain -> GetEntries();
  std::cout << "n events = " << n_events << std::endl;

  //--------------------------------------------------------------------------------
  // Turn on/off branches
  //--------------------------------------------------------------------------------
  
  tuple_tree -> fChain -> SetBranchStatus("*"               , kFALSE);
  tuple_tree -> fChain -> SetBranchStatus("run", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("event", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("ls", kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalTriggerPrimitiveCompressedEtSOI",kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalEmulTriggerPrimitiveCompressedEtSOI",kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalTriggerPrimitiveIEta",kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalEmulTriggerPrimitiveIEta",kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalTriggerPrimitiveIPhi",kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HcalEmulTriggerPrimitiveIPhi",kTRUE);

  //--------------------------------------------------------------------------------
  // Make histograms
  //--------------------------------------------------------------------------------
  char histName[100];
  std::map<int,std::map<int,TH2F*>> h_emulTPEt_vs_TPEt;
  h_emulTPEt_vs_TPEt[1] = std::map<int,TH2F*>();
  h_emulTPEt_vs_TPEt[2] = std::map<int,TH2F*>();
  
  for (int iIPhi = 0; iIPhi != selectIPhis.size(); ++iIPhi){
    sprintf(histName,"h_emulTPEt_vs_TPEt_1_%d",selectIPhis[iIPhi]);
    h_emulTPEt_vs_TPEt[1][selectIPhis[iIPhi]] = makeTH2F(histName,50,0.,100.,50,0.,100.);
    sprintf(histName,"h_emulTPEt_vs_TPEt_2_%d",selectIPhis[iIPhi]);
    h_emulTPEt_vs_TPEt[2][selectIPhis[iIPhi]] = makeTH2F(histName,50,0.,100.,50,0.,100.);
  };
  TH1F * h_lumiSection = makeTH1F("h_lumiSection",497,0.5,497.5);  

  //--------------------------------------------------------------------------------
  // Loop
  //--------------------------------------------------------------------------------
  int lumiSectionIndex;
  for (int i = 0; i < n_events; ++i){
    
    tuple_tree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;
    
    //-----------------------------------------------------------------
    // Collections of Hcal Trigger Primitive 
    //-----------------------------------------------------------------
    int lumiSection = tuple_tree -> ls;

    h_lumiSection -> Fill(lumiSection);
    if (lumiSection < 400){
      lumiSectionIndex = 1;
    } else {
      lumiSectionIndex = 2;
    };

    CollectionPtr hcalTPs (new Collection(*tuple_tree, tuple_tree -> HcalTriggerPrimitiveIEta -> size()));
    CollectionPtr hcalEmulTPs (new Collection(*tuple_tree, tuple_tree -> HcalEmulTriggerPrimitiveIEta -> size()));


    int nHcalTPs = hcalTPs -> GetSize();
    int nHcalEmulTPs = hcalEmulTPs -> GetSize();
    for (int iHcalTP = 0; iHcalTP < nHcalTPs; ++iHcalTP){
       HcalTP hcalTP = hcalTPs -> GetConstituent<HcalTP>(iHcalTP);
       if( std::find( selectIPhis.begin() , selectIPhis.end() , hcalTP.iphi() ) == selectIPhis.end() ) continue;
       for (int iHcalEmulTP = 0; iHcalEmulTP  < nHcalEmulTPs; ++iHcalEmulTP){
         HcalEmulTP hcalEmulTP = hcalEmulTPs -> GetConstituent<HcalEmulTP>(iHcalEmulTP);
         if ( (hcalEmulTP.ieta() == hcalTP.ieta() && (hcalEmulTP.iphi() == hcalTP.iphi()) ) ){
	   h_emulTPEt_vs_TPEt[lumiSectionIndex][hcalTP.iphi()] -> Fill(hcalEmulTP.Et(),hcalTP.Et());
	 };	 
       };
    };
  };
};
void analysisClassL1::loop(){

  // std::string HLT_Trigger = "HLT_ZeroBias_v2";
  std::string HLT_Trigger = "HLT_Any";
  std::vector<std::string> preFireTrigger = {"L1_SingleJet092","L1_SingleJet128","L1_SingleJet176","L1_SingleJet200","L1_SingleJet240"};
  // std::vector<std::string> preFireTrigger = {"L1_HTT075","L1_HTT100","L1_HTT125","L1_HTT150","L1_HTT175","L1_HTT200"};

  L1Tree * l1Tree = getTree<L1Tree>("l1Tree");

  int n_events = l1Tree -> fChain -> GetEntries();

  loadSingleJetTrigMap();
  // loadHTTTrigMap();
  loadBitMap();
  loadPrescaleMap();

  l1Tree -> fChain -> SetBranchStatus("*", kFALSE);
  l1Tree -> fChain -> SetBranchStatus("tw1", kTRUE);
  l1Tree -> fChain -> SetBranchStatus("tw2", kTRUE);
  l1Tree -> fChain -> SetBranchStatus("lumi",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("tt",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("bx",kTRUE);
  l1Tree -> fChain -> SetBranchStatus("hlt",kTRUE);

  std::map<std::string,std::map<std::string,int>> nBx1,nBx2;

  for (int i = 0; i < n_events; ++i){
    l1Tree -> GetEntry(i);
    if ( (i + 1) % 10000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;
    int lumi = l1Tree -> lumi;
    if (lumi < 126) continue;
    int prescaleIndex;
    if (lumi < 317){
      prescaleIndex = 6;
    }else{
      prescaleIndex = 7;
    };

    int bunchNumber = l1Tree -> bx;
    hlt = l1Tree -> hlt;

    // if (not selectBX(bunchNumber)) continue;
    if (not checkHLT(HLT_Trigger)) continue;

    tw1 = l1Tree -> tw1;
    tw2 = l1Tree -> tw2;
    tt = l1Tree -> tt;

    for (int iTrig = 0; iTrig != preFireTrigger.size(); iTrig++){
      Int_t nBx=tw1.size();
      if (nBx1.find(preFireTrigger[iTrig]) == nBx1.end()){
        nBx1[preFireTrigger[iTrig]] = std::map<std::string,int>();
      };
      if (nBx2.find(preFireTrigger[iTrig]) == nBx2.end()){
        nBx2[preFireTrigger[iTrig]] = std::map<std::string,int>();
      };

      for (trigbit_iter = HFPrefiringBitMap.begin(); trigbit_iter != HFPrefiringBitMap.end(); trigbit_iter++){
        int ibit = trigbit_iter->second;
        std::string triggerName = trigbit_iter->first;
        
        bool Bx1Fired = checkTriggerBit(BitMap[preFireTrigger[iTrig]],1);      
        bool Bx2Fired = checkTriggerBit(ibit,2);
        bool ttbit0 = (tt[2]>>0)&1; 	
  
        if (Bx2Fired && ttbit0){
          if (nBx2[preFireTrigger[iTrig]].find(triggerName) == nBx2[preFireTrigger[iTrig]].end()){
  	    nBx2[preFireTrigger[iTrig]][triggerName] = 0;
  	  };
  	  nBx2[preFireTrigger[iTrig]][triggerName] += PrescaleMap[prescaleIndex][triggerName];
  	  if (Bx1Fired){
  	    if (nBx2[preFireTrigger[iTrig]].find(triggerName) == nBx2[preFireTrigger[iTrig]].end()){
  	      nBx1[preFireTrigger[iTrig]][triggerName] = 0;
  	    };
            nBx1[preFireTrigger[iTrig]][triggerName]  += PrescaleMap[prescaleIndex][preFireTrigger[iTrig]]; 
  	  };
        };
      };
    };
  };

  std::map<std::string,TH1F*> graphs;
  for (int iTrig = 0; iTrig != preFireTrigger.size(); iTrig++){
    graphs[preFireTrigger[iTrig]] = makeTH1F(preFireTrigger[iTrig].c_str(),nBx2[preFireTrigger[iTrig]].size(),-0.5,nBx2[preFireTrigger[iTrig]].size()-0.5);
    for (std::map<std::string,int>::iterator it = nBx2[preFireTrigger[iTrig]].begin(); it != nBx2[preFireTrigger[iTrig]].end(); it++){
      std::string triggerName = it -> first;
      int nIt = std::distance(nBx2[preFireTrigger[iTrig]].begin(),it)+1;
      if (it -> second != 0){
        graphs[preFireTrigger[iTrig]] -> SetBinContent(nIt,(double) nBx1[preFireTrigger[iTrig]][triggerName]/ it -> second);
        graphs[preFireTrigger[iTrig]] -> SetBinError(nIt,binoError( nBx1[preFireTrigger[iTrig]][triggerName], it -> second) );
        graphs[preFireTrigger[iTrig]] -> GetXaxis() -> SetBinLabel(nIt,triggerName.c_str());
      };
    };
    char titleName[200];
    sprintf(titleName," ; Trigger at Nominal BX  ; Pretrigger Rate");
    graphs[preFireTrigger[iTrig]] -> SetTitle(titleName);
  };

}
void analysisClass::loop(){
  
  //--------------------------------------------------------------------------------
  // Declare HCAL tree(s)
  //--------------------------------------------------------------------------------

  HcalTupleTree * tuple_tree = getTree<HcalTupleTree>("tuple_tree");
  int n_events = tuple_tree -> fChain -> GetEntries();
  std::cout << "n events = " << n_events << std::endl;
  
  double min_charge12 = 50.;
  
  //--------------------------------------------------------------------------------
  // Turn on/off branches
  //--------------------------------------------------------------------------------
  
  tuple_tree -> fChain -> SetBranchStatus("*"               , kFALSE);
  tuple_tree -> fChain -> SetBranchStatus("run"             , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("event"           , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("ls"              , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HFDigiFC"        , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HFDigiDepth"     , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HFDigiIEta"      , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HFDigiIPhi"      , kTRUE);
  tuple_tree -> fChain -> SetBranchStatus("HFDigiSize"      , kTRUE);
  
  //--------------------------------------------------------------------------------
  // Loop
  //--------------------------------------------------------------------------------
  
  int hash; 
  int nHFDigis;
  double timing12 = 0.;
  double charge12 = 0.;
  char hist_name[200];
  
  std::map<int, TH1F*> map_hash_timing12;
  std::map<int, TH1F*>::iterator map_it;

  for (int i = 0; i < n_events; ++i){
    
    tuple_tree -> GetEntry(i);
    if ( (i + 1) % 1000 == 0 ) std::cout << "Processing event " << i + 1 << "/" << n_events << std::endl;

    CollectionPtr hfDigis (new Collection(*tuple_tree, tuple_tree -> HFDigiIEta -> size()));
    
    nHFDigis = hfDigis -> GetSize();

    for (int iHFDigi = 0; iHFDigi < nHFDigis; ++iHFDigi){
      HFDigi hfDigi = hfDigis -> GetConstituent<HFDigi>(iHFDigi);
      
      hash = getHash ( hfDigi.ieta(), hfDigi.iphi(), hfDigi.depth());
      charge12 = hfDigi.charge12();
      timing12 = hfDigi.time12();
      map_it = map_hash_timing12.find (hash);
      
      if ( map_hash_timing12.find (hash) == map_hash_timing12.end() ){
	sprintf(hist_name, "HF_%d_%d_%d", hfDigi.ieta(), hfDigi.iphi(), hfDigi.depth());
	map_hash_timing12.insert(std::pair<int, TH1F*>(hash, makeTH1F(hist_name, 200, 0.0, 5.0)));
      }
      
      if ( charge12 > min_charge12 ) map_hash_timing12[hash] -> Fill ( timing12 );
      
    }
  }
}