static int
setFreeBlock(int blockNumber){
	if( blockNumber <= 0 || blockNumber > 2047 ){
		return -1;
	}
	
	char bitMap[4*512];
	loadBitMap(bitMap);
	
	int indexToModify = blockNumber / 8;
	int indexOfIndexToModify = blockNumber % 8;
	
	char newEntry;
	switch( indexOfIndexToModify ){
		case 0: newEntry = 0x80; break;
		case 1: newEntry = 0x40; break;
		case 2: newEntry = 0x20; break;
		case 3: newEntry = 0x10; break;
		case 4: newEntry = 0x08; break;
		case 5: newEntry = 0x04; break;
		case 6: newEntry = 0x02; break;
		case 7: newEntry = 0x01; break;
	}
	
	bitMap[indexToModify] |= newEntry;
	
	setBitMap(bitMap);
	
	return 0;
}
static int
getFreeBlock(){
	char bitMap[4*512];
	loadBitMap(bitMap);
	int j = 0;
	int i = 0;
	for( j = 0; j < 512*4 && bitMap[j] == 0x00 ; j++ ) {
	}	
	if( j == 512 * 4 ){
		return -1;	
	}
	int k = 0;

	for ( i = 0 ; i < sizeof(char) * 8 ; i++ ) {
		if ( ((bitMap[j] << i) & 0x80) == 0x80 ) {
			int aux = 0x1;
			for ( k = 0 ; k < sizeof(char)*8 - i - 1 ; k++ ) {
				aux <<= 1;
			}
			aux = ~aux;
			bitMap[j] &= aux;
			setBitMap(bitMap);
			return j * sizeof(char) * 8 + i;
		}
	}	
	return 0xCABA110;
}
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(){

  // 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);
  };

}