Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-18 02:44:59

0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "EventFilter/L1TRawToDigi/plugins/UnpackerFactory.h"
0003 
0004 #include "CaloLayer1Unpacker.h"
0005 
0006 using namespace edm;
0007 
0008 namespace l1t {
0009   namespace stage2 {
0010 
0011     // max_iEta_HcalTP = 41; // barrel <= 16, endcap <= 29, hf <= 41
0012     // there are two TT29’s: one in HE readout in TT28 and another in HF readout in TT30
0013     // max_iPhi_HcalTP = 72;
0014 
0015     bool CaloLayer1Unpacker::unpack(const Block& block, UnpackerCollections* coll) {
0016       LogDebug("L1T") << "Block size = " << block.header().getSize();
0017       LogDebug("L1T") << "Board ID = " << block.amc().getBoardID();
0018 
0019       auto res = static_cast<CaloLayer1Collections*>(coll);
0020 
0021       auto ctp7_phi = block.amc().getBoardID();
0022       const uint32_t* ptr = block.payload().data();
0023 
0024       int N_BX = (block.header().getFlags() >> 16) & 0xf;
0025       //      std::cout << " N_BX calculated " << N_BX << std::endl;
0026 
0027       int HCALFB = (block.header().getFlags() >> 15) & 0x1;
0028 
0029       if (N_BX == 1) {
0030         if (HCALFB == 0) {
0031           UCTCTP7RawData ctp7Data(ptr);
0032           makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis());
0033           makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
0034           makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
0035           makeRegions(ctp7_phi, ctp7Data, res->getRegions());
0036         }
0037         if (HCALFB == 1) {
0038           UCTCTP7RawData_HCALFB ctp7Data_HCALFB(ptr);
0039           makeECalTPGs_HCALFB(ctp7_phi, ctp7Data_HCALFB, res->getEcalDigis());
0040           makeHCalTPGs_HCALFB(ctp7_phi, ctp7Data_HCALFB, res->getHcalDigis());
0041           makeHFTPGs_HCALFB(ctp7_phi, ctp7Data_HCALFB, res->getHcalDigis());
0042           makeRegions_HCALFB(ctp7_phi, ctp7Data_HCALFB, res->getRegions());
0043         }
0044       } else if (N_BX == 5) {
0045         if (HCALFB == 0) {
0046           UCTCTP7RawData5BX ctp7Data5BX(ptr);
0047           // BX_n = 0, 1, 2, 3, 4, where 2 is nominal
0048           makeECalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getEcalDigis(), 2);
0049           makeHCalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getHcalDigis(), 2);
0050           makeHFTPGs5BX(ctp7_phi, ctp7Data5BX, res->getHcalDigis(), 2);
0051           makeRegions5BX(ctp7_phi, ctp7Data5BX, res->getRegions(), 2);
0052           for (int i = 0; i < 5; i++) {
0053             makeECalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getEcalDigisBx(i), i);
0054           }
0055         }
0056         if (HCALFB == 1) {
0057           UCTCTP7RawData5BX_HCALFB ctp7Data5BX_HCALFB(ptr);
0058           // BX_n = 0, 1, 2, 3, 4, where 2 is nominal
0059           makeECalTPGs5BX_HCALFB(ctp7_phi, ctp7Data5BX_HCALFB, res->getEcalDigis(), 2);
0060           makeHCalTPGs5BX_HCALFB(ctp7_phi, ctp7Data5BX_HCALFB, res->getHcalDigis(), 2);
0061           makeHFTPGs5BX_HCALFB(ctp7_phi, ctp7Data5BX_HCALFB, res->getHcalDigis(), 2);
0062           makeRegions5BX_HCALFB(ctp7_phi, ctp7Data5BX_HCALFB, res->getRegions(), 2);
0063           for (int i = 0; i < 5; i++) {
0064             makeECalTPGs5BX_HCALFB(ctp7_phi, ctp7Data5BX_HCALFB, res->getEcalDigisBx(i), i);
0065           }
0066         }
0067       } else {
0068         LogError("CaloLayer1Unpacker") << "Number of BXs to unpack is not 1 or 5, stop here !!! " << N_BX << std::endl;
0069         return false;
0070       }
0071 
0072       return true;
0073     }
0074 
0075     void CaloLayer1Unpacker::makeECalTPGs(uint32_t lPhi,
0076                                           UCTCTP7RawData& ctp7Data,
0077                                           EcalTrigPrimDigiCollection* ecalTPGs) {
0078       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::EBEE;
0079       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0080         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0081         if (cPhi == 0)
0082           cPhi = 72;
0083         else if (cPhi == -1)
0084           cPhi = 71;
0085         else if (cPhi < -1) {
0086           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs" << std::endl;
0087           return;
0088         }
0089         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0090           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0091             bool negativeEta = false;
0092             if (cEta < 0)
0093               negativeEta = true;
0094             uint32_t iEta = abs(cEta);
0095             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0096             // Bottom 8-bits are ET
0097             // Then finegrain feature bit
0098             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0099             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0100             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0101             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0102             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0103             if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
0104               towerDatum |= 0x0100;
0105             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0106               towerDatum |= 0x2000;
0107             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0108               towerDatum |= 0x4000;
0109             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0110                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0111                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0112               towerDatum |= 0x8000;
0113             EcalTriggerPrimitiveSample sample(towerDatum);
0114             int zSide = cEta / ((int)iEta);
0115             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0116             const EcalSubdetector ecalTriggerTower =
0117                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0118             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0119             EcalTriggerPrimitiveDigi tpg(id);
0120             tpg.setSize(1);
0121             tpg.setSample(0, sample);
0122             ecalTPGs->push_back(tpg);
0123           }
0124         }
0125       }
0126     }
0127 
0128     void CaloLayer1Unpacker::makeHCalTPGs(uint32_t lPhi,
0129                                           UCTCTP7RawData& ctp7Data,
0130                                           HcalTrigPrimDigiCollection* hcalTPGs) {
0131       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HBHE;
0132       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0133         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0134         if (cPhi == 0)
0135           cPhi = 72;
0136         else if (cPhi == -1)
0137           cPhi = 71;
0138         else if (cPhi < -1) {
0139           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs" << std::endl;
0140           return;
0141         }
0142         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0143           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0144             bool negativeEta = false;
0145             if (cEta < 0)
0146               negativeEta = true;
0147             uint32_t iEta = abs(cEta);
0148             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0149             // Bottom 8-bits are ET
0150             // Then feature bit
0151             // The remaining bits are undefined presently
0152             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0153             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0154             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0155             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0156             if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
0157               towerDatum |= 0x0100;
0158             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0159               towerDatum |= 0x0200;
0160             if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
0161               towerDatum |= 0x0400;
0162             if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0163               towerDatum |= 0x0800;
0164             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0165               towerDatum |= 0x2000;
0166             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0167               towerDatum |= 0x4000;
0168             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0169                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0170                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0171               towerDatum |= 0x8000;
0172             HcalTriggerPrimitiveSample sample(towerDatum);
0173             HcalTrigTowerDetId id(cEta, cPhi);
0174             HcalTriggerPrimitiveDigi tpg(id);
0175             tpg.setSize(1);
0176             tpg.setSample(0, sample);
0177             hcalTPGs->push_back(tpg);
0178           }
0179         }
0180       }
0181     }
0182 
0183     void CaloLayer1Unpacker::makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
0184       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HF;
0185       for (uint32_t side = 0; side <= 1; side++) {
0186         bool negativeEta = false;
0187         if (side == 0)
0188           negativeEta = true;
0189         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0190           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0191             if (iPhi == 1 && iEta == 40)
0192               iEta = 41;
0193             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0194             if (iEta == 41)
0195               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0196             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0197             int cEta = iEta;
0198             if (negativeEta)
0199               cEta = -iEta;
0200             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0201             // Bottom 8-bits are ET
0202             // Then feature bit
0203             // Then minBias ADC count bit
0204             // The remaining bits are undefined presently
0205             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0206             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0207             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0208             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0209             towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
0210             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0211               towerDatum |= 0x0400;
0212             if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
0213               towerDatum |= 0x0800;
0214             if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0215               towerDatum |= 0x1000;
0216             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0217               towerDatum |= 0x2000;
0218             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0219               towerDatum |= 0x4000;
0220             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0221                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0222                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0223               towerDatum |= 0x8000;
0224             HcalTriggerPrimitiveSample sample(towerDatum);
0225             HcalTrigTowerDetId id(cEta, cPhi);
0226             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0227             HcalTriggerPrimitiveDigi tpg(id);
0228             tpg.setSize(1);
0229             tpg.setSample(0, sample);
0230             hcalTPGs->push_back(tpg);
0231           }
0232         }
0233       }
0234     }
0235 
0236     void CaloLayer1Unpacker::makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, L1CaloRegionCollection* regions) {
0237       for (uint32_t side = 0; side <= 1; side++) {
0238         bool negativeEta = false;
0239         if (side == 0)
0240           negativeEta = true;
0241         for (uint32_t region = 0; region <= 6; region++) {
0242           uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
0243           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0244           if (!negativeEta)
0245             lEta = region + 11;
0246           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0247         }
0248       }
0249     }
0250 
0251     // For additional HCAL FB implementation
0252     void CaloLayer1Unpacker::makeECalTPGs_HCALFB(uint32_t lPhi,
0253                                                  UCTCTP7RawData_HCALFB& ctp7Data_HCALFB,
0254                                                  EcalTrigPrimDigiCollection* ecalTPGs) {
0255       UCTCTP7RawData_HCALFB::CaloType cType = UCTCTP7RawData_HCALFB::EBEE;
0256       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0257         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0258         if (cPhi == 0)
0259           cPhi = 72;
0260         else if (cPhi == -1)
0261           cPhi = 71;
0262         else if (cPhi < -1) {
0263           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs_HCALFB" << std::endl;
0264           return;
0265         }
0266         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0267           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0268             bool negativeEta = false;
0269             if (cEta < 0)
0270               negativeEta = true;
0271             uint32_t iEta = abs(cEta);
0272             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0273             // Bottom 8-bits are ET
0274             // Then finegrain feature bit
0275             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0276             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0277             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0278             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0279             uint32_t towerDatum = ctp7Data_HCALFB.getET(cType, negativeEta, iEta, iPhi);
0280             if (ctp7Data_HCALFB.getFB(cType, negativeEta, iEta, iPhi) != 0)
0281               towerDatum |= 0x0100;
0282             if (ctp7Data_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi))
0283               towerDatum |= 0x2000;
0284             if (ctp7Data_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi))
0285               towerDatum |= 0x4000;
0286             if (ctp7Data_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0287                 ctp7Data_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0288                 ctp7Data_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi))
0289               towerDatum |= 0x8000;
0290             EcalTriggerPrimitiveSample sample(towerDatum);
0291             int zSide = cEta / ((int)iEta);
0292             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0293             const EcalSubdetector ecalTriggerTower =
0294                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0295             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0296             EcalTriggerPrimitiveDigi tpg(id);
0297             tpg.setSize(1);
0298             tpg.setSample(0, sample);
0299             ecalTPGs->push_back(tpg);
0300           }
0301         }
0302       }
0303     }
0304 
0305     void CaloLayer1Unpacker::makeHCalTPGs_HCALFB(uint32_t lPhi,
0306                                                  UCTCTP7RawData_HCALFB& ctp7Data_HCALFB,
0307                                                  HcalTrigPrimDigiCollection* hcalTPGs) {
0308       UCTCTP7RawData_HCALFB::CaloType cType = UCTCTP7RawData_HCALFB::HBHE;
0309       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0310         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0311         if (cPhi == 0)
0312           cPhi = 72;
0313         else if (cPhi == -1)
0314           cPhi = 71;
0315         else if (cPhi < -1) {
0316           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs_HCALFB" << std::endl;
0317           return;
0318         }
0319         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0320           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0321             bool negativeEta = false;
0322             if (cEta < 0)
0323               negativeEta = true;
0324             uint32_t iEta = abs(cEta);
0325             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0326             // Bottom 8-bits are ET
0327             // Then feature bit
0328             // The remaining bits are undefined presently
0329             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0330             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0331             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0332             uint32_t towerDatum = ctp7Data_HCALFB.getET(cType, negativeEta, iEta, iPhi);
0333             uint32_t fb = ctp7Data_HCALFB.getFB(cType, negativeEta, iEta, iPhi);
0334             towerDatum |= ((fb & 0x1) << 8);
0335             uint32_t towerDatum2 = ((fb & 0x3E) >> 1);
0336             if (ctp7Data_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0337               towerDatum |= 0x0200;
0338             if (ctp7Data_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi))
0339               towerDatum |= 0x0400;
0340             if (ctp7Data_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi))
0341               towerDatum |= 0x0800;
0342             if (ctp7Data_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi))
0343               towerDatum |= 0x2000;
0344             if (ctp7Data_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi))
0345               towerDatum |= 0x4000;
0346             if (ctp7Data_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0347                 ctp7Data_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0348                 ctp7Data_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi))
0349               towerDatum |= 0x8000;
0350             HcalTriggerPrimitiveSample sample(towerDatum);
0351             HcalTriggerPrimitiveSample sample2(towerDatum2);
0352             HcalTrigTowerDetId id(cEta, cPhi);
0353             HcalTriggerPrimitiveDigi tpg(id);
0354             tpg.setSize(2);
0355             tpg.setSample(0, sample);
0356             tpg.setSample(1, sample2);
0357             hcalTPGs->push_back(tpg);
0358           }
0359         }
0360       }
0361     }
0362 
0363     void CaloLayer1Unpacker::makeHFTPGs_HCALFB(uint32_t lPhi,
0364                                                UCTCTP7RawData_HCALFB& ctp7Data_HCALFB,
0365                                                HcalTrigPrimDigiCollection* hcalTPGs) {
0366       UCTCTP7RawData_HCALFB::CaloType cType = UCTCTP7RawData_HCALFB::HF;
0367       for (uint32_t side = 0; side <= 1; side++) {
0368         bool negativeEta = false;
0369         if (side == 0)
0370           negativeEta = true;
0371         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0372           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0373             if (iPhi == 1 && iEta == 40)
0374               iEta = 41;
0375             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0376             if (iEta == 41)
0377               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0378             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0379             int cEta = iEta;
0380             if (negativeEta)
0381               cEta = -iEta;
0382             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0383             // Bottom 8-bits are ET
0384             // Then feature bit
0385             // Then minBias ADC count bit
0386             // The remaining bits are undefined presently
0387             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0388             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0389             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0390             uint32_t towerDatum = ctp7Data_HCALFB.getET(cType, negativeEta, iEta, iPhi);
0391             towerDatum |= ctp7Data_HCALFB.getFB(cType, negativeEta, iEta, iPhi) << 8;
0392             if (ctp7Data_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0393               towerDatum |= 0x0400;
0394             if (ctp7Data_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi))
0395               towerDatum |= 0x0800;
0396             if (ctp7Data_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi))
0397               towerDatum |= 0x1000;
0398             if (ctp7Data_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi))
0399               towerDatum |= 0x2000;
0400             if (ctp7Data_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi))
0401               towerDatum |= 0x4000;
0402             if (ctp7Data_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0403                 ctp7Data_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0404                 ctp7Data_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi))
0405               towerDatum |= 0x8000;
0406             HcalTriggerPrimitiveSample sample(towerDatum);
0407             HcalTrigTowerDetId id(cEta, cPhi);
0408             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0409             HcalTriggerPrimitiveDigi tpg(id);
0410             tpg.setSize(1);
0411             tpg.setSample(0, sample);
0412             hcalTPGs->push_back(tpg);
0413           }
0414         }
0415       }
0416     }
0417 
0418     void CaloLayer1Unpacker::makeRegions_HCALFB(uint32_t lPhi,
0419                                                 UCTCTP7RawData_HCALFB& ctp7Data_HCALFB,
0420                                                 L1CaloRegionCollection* regions) {
0421       for (uint32_t side = 0; side <= 1; side++) {
0422         bool negativeEta = false;
0423         if (side == 0)
0424           negativeEta = true;
0425         for (uint32_t region = 0; region <= 6; region++) {
0426           uint32_t regionData = ctp7Data_HCALFB.getRegionSummary(negativeEta, region);
0427           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0428           if (!negativeEta)
0429             lEta = region + 11;
0430           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0431         }
0432       }
0433     }
0434 
0435     // The following four functions are duplicated from above, to be used for 5BX events
0436     // They have a new parameter BX_n = 0, 1, 2, 3, 4, where 2 is nominal
0437     // And use functions defined in UCTCTP7RawData5BX.h
0438     // The idea is not to intervene the normal events unpacking
0439 
0440     void CaloLayer1Unpacker::makeECalTPGs5BX(uint32_t lPhi,
0441                                              UCTCTP7RawData5BX& ctp7Data5BX,
0442                                              EcalTrigPrimDigiCollection* ecalTPGs,
0443                                              uint32_t BX_n) {
0444       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::EBEE;
0445       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0446         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0447         if (cPhi == 0)
0448           cPhi = 72;
0449         else if (cPhi == -1)
0450           cPhi = 71;
0451         else if (cPhi < -1) {
0452           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs5BX" << std::endl;
0453           return;
0454         }
0455         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0456           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0457             bool negativeEta = false;
0458             if (cEta < 0)
0459               negativeEta = true;
0460             uint32_t iEta = abs(cEta);
0461             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0462             // Bottom 8-bits are ET
0463             // Then finegrain feature bit
0464             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0465             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0466             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0467             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0468             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0469             if (ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) != 0)
0470               towerDatum |= 0x0100;
0471             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0472               towerDatum |= 0x2000;
0473             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0474               towerDatum |= 0x4000;
0475             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0476                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0477                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0478               towerDatum |= 0x8000;
0479             EcalTriggerPrimitiveSample sample(towerDatum);
0480             int zSide = cEta / ((int)iEta);
0481             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0482             const EcalSubdetector ecalTriggerTower =
0483                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0484             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0485             EcalTriggerPrimitiveDigi tpg(id);
0486             tpg.setSize(1);
0487             tpg.setSample(0, sample);
0488             ecalTPGs->push_back(tpg);
0489           }
0490         }
0491       }
0492     }
0493 
0494     void CaloLayer1Unpacker::makeHCalTPGs5BX(uint32_t lPhi,
0495                                              UCTCTP7RawData5BX& ctp7Data5BX,
0496                                              HcalTrigPrimDigiCollection* hcalTPGs,
0497                                              uint32_t BX_n) {
0498       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::HBHE;
0499       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0500         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0501         if (cPhi == 0)
0502           cPhi = 72;
0503         else if (cPhi == -1)
0504           cPhi = 71;
0505         else if (cPhi < -1) {
0506           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs5BX" << std::endl;
0507           return;
0508         }
0509         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0510           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0511             bool negativeEta = false;
0512             if (cEta < 0)
0513               negativeEta = true;
0514             uint32_t iEta = abs(cEta);
0515             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0516             // Bottom 8-bits are ET
0517             // Then feature bit
0518             // The remaining bits are undefined presently
0519             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0520             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0521             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0522             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0523             if (ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) != 0)
0524               towerDatum |= 0x0100;
0525             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0526               towerDatum |= 0x0200;
0527             if (ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0528               towerDatum |= 0x0400;
0529             if (ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0530               towerDatum |= 0x0800;
0531             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0532               towerDatum |= 0x2000;
0533             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0534               towerDatum |= 0x4000;
0535             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0536                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0537                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0538               towerDatum |= 0x8000;
0539             HcalTriggerPrimitiveSample sample(towerDatum);
0540             HcalTrigTowerDetId id(cEta, cPhi);
0541             HcalTriggerPrimitiveDigi tpg(id);
0542             tpg.setSize(1);
0543             tpg.setSample(0, sample);
0544             hcalTPGs->push_back(tpg);
0545           }
0546         }
0547       }
0548     }
0549 
0550     void CaloLayer1Unpacker::makeHFTPGs5BX(uint32_t lPhi,
0551                                            UCTCTP7RawData5BX& ctp7Data5BX,
0552                                            HcalTrigPrimDigiCollection* hcalTPGs,
0553                                            uint32_t BX_n) {
0554       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::HF;
0555       for (uint32_t side = 0; side <= 1; side++) {
0556         bool negativeEta = false;
0557         if (side == 0)
0558           negativeEta = true;
0559         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0560           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0561             if (iPhi == 1 && iEta == 40)
0562               iEta = 41;
0563             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0564             if (iEta == 41)
0565               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0566             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0567             int cEta = iEta;
0568             if (negativeEta)
0569               cEta = -iEta;
0570             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0571             // Bottom 8-bits are ET
0572             // Then feature bit
0573             // Then minBias ADC count bit
0574             // The remaining bits are undefined presently
0575             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0576             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0577             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0578             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0579             towerDatum |= ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) << 8;
0580             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0581               towerDatum |= 0x0400;
0582             if (ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0583               towerDatum |= 0x0800;
0584             if (ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0585               towerDatum |= 0x1000;
0586             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0587               towerDatum |= 0x2000;
0588             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0589               towerDatum |= 0x4000;
0590             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0591                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0592                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0593               towerDatum |= 0x8000;
0594             HcalTriggerPrimitiveSample sample(towerDatum);
0595             HcalTrigTowerDetId id(cEta, cPhi);
0596             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0597             HcalTriggerPrimitiveDigi tpg(id);
0598             tpg.setSize(1);
0599             tpg.setSample(0, sample);
0600             hcalTPGs->push_back(tpg);
0601           }
0602         }
0603       }
0604     }
0605 
0606     void CaloLayer1Unpacker::makeRegions5BX(uint32_t lPhi,
0607                                             UCTCTP7RawData5BX& ctp7Data5BX,
0608                                             L1CaloRegionCollection* regions,
0609                                             uint32_t BX_n) {
0610       for (uint32_t side = 0; side <= 1; side++) {
0611         bool negativeEta = false;
0612         if (side == 0)
0613           negativeEta = true;
0614         for (uint32_t region = 0; region <= 6; region++) {
0615           uint32_t regionData = ctp7Data5BX.getRegionSummary(negativeEta, region, BX_n);
0616           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0617           if (!negativeEta)
0618             lEta = region + 11;
0619           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0620         }
0621       }
0622     }
0623 
0624     // For addtional HCAL FB implementation
0625     void CaloLayer1Unpacker::makeECalTPGs5BX_HCALFB(uint32_t lPhi,
0626                                                     UCTCTP7RawData5BX_HCALFB& ctp7Data5BX_HCALFB,
0627                                                     EcalTrigPrimDigiCollection* ecalTPGs,
0628                                                     uint32_t BX_n) {
0629       UCTCTP7RawData5BX_HCALFB::CaloType cType = UCTCTP7RawData5BX_HCALFB::EBEE;
0630       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0631         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0632         if (cPhi == 0)
0633           cPhi = 72;
0634         else if (cPhi == -1)
0635           cPhi = 71;
0636         else if (cPhi < -1) {
0637           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs5BX_HCALFB" << std::endl;
0638           return;
0639         }
0640         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0641           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0642             bool negativeEta = false;
0643             if (cEta < 0)
0644               negativeEta = true;
0645             uint32_t iEta = abs(cEta);
0646             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0647             // Bottom 8-bits are ET
0648             // Then finegrain feature bit
0649             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0650             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0651             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0652             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0653             uint32_t towerDatum = ctp7Data5BX_HCALFB.getET(cType, negativeEta, iEta, iPhi, BX_n);
0654             if (ctp7Data5BX_HCALFB.getFB(cType, negativeEta, iEta, iPhi, BX_n) != 0)
0655               towerDatum |= 0x0100;
0656             if (ctp7Data5BX_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0657               towerDatum |= 0x2000;
0658             if (ctp7Data5BX_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0659               towerDatum |= 0x4000;
0660             if (ctp7Data5BX_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0661                 ctp7Data5BX_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0662                 ctp7Data5BX_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0663               towerDatum |= 0x8000;
0664             EcalTriggerPrimitiveSample sample(towerDatum);
0665             int zSide = cEta / ((int)iEta);
0666             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0667             const EcalSubdetector ecalTriggerTower =
0668                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0669             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0670             EcalTriggerPrimitiveDigi tpg(id);
0671             tpg.setSize(1);
0672             tpg.setSample(0, sample);
0673             ecalTPGs->push_back(tpg);
0674           }
0675         }
0676       }
0677     }
0678 
0679     void CaloLayer1Unpacker::makeHCalTPGs5BX_HCALFB(uint32_t lPhi,
0680                                                     UCTCTP7RawData5BX_HCALFB& ctp7Data5BX_HCALFB,
0681                                                     HcalTrigPrimDigiCollection* hcalTPGs,
0682                                                     uint32_t BX_n) {
0683       UCTCTP7RawData5BX_HCALFB::CaloType cType = UCTCTP7RawData5BX_HCALFB::HBHE;
0684       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0685         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0686         if (cPhi == 0)
0687           cPhi = 72;
0688         else if (cPhi == -1)
0689           cPhi = 71;
0690         else if (cPhi < -1) {
0691           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs5BX_HCALFB" << std::endl;
0692           return;
0693         }
0694         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0695           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0696             bool negativeEta = false;
0697             if (cEta < 0)
0698               negativeEta = true;
0699             uint32_t iEta = abs(cEta);
0700             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0701             // Bottom 8-bits are ET
0702             // Then feature bit
0703             // The remaining bits are undefined presently
0704             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0705             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0706             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0707             uint32_t towerDatum = ctp7Data5BX_HCALFB.getET(cType, negativeEta, iEta, iPhi, BX_n);
0708             uint32_t fb = ctp7Data5BX_HCALFB.getFB(cType, negativeEta, iEta, iPhi, BX_n);
0709             towerDatum |= ((fb & 0x1) << 8);
0710             uint32_t towerDatum2 = ((fb & 0x3E) >> 1);
0711             if (ctp7Data5BX_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0712               towerDatum |= 0x0200;
0713             if (ctp7Data5BX_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0714               towerDatum |= 0x0400;
0715             if (ctp7Data5BX_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0716               towerDatum |= 0x0800;
0717             if (ctp7Data5BX_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0718               towerDatum |= 0x2000;
0719             if (ctp7Data5BX_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0720               towerDatum |= 0x4000;
0721             if (ctp7Data5BX_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0722                 ctp7Data5BX_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0723                 ctp7Data5BX_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0724               towerDatum |= 0x8000;
0725             HcalTriggerPrimitiveSample sample(towerDatum);
0726             HcalTriggerPrimitiveSample sample2(towerDatum2);
0727             HcalTrigTowerDetId id(cEta, cPhi);
0728             HcalTriggerPrimitiveDigi tpg(id);
0729             tpg.setSize(2);
0730             tpg.setSample(0, sample);
0731             tpg.setSample(1, sample2);
0732             hcalTPGs->push_back(tpg);
0733           }
0734         }
0735       }
0736     }
0737 
0738     void CaloLayer1Unpacker::makeHFTPGs5BX_HCALFB(uint32_t lPhi,
0739                                                   UCTCTP7RawData5BX_HCALFB& ctp7Data5BX_HCALFB,
0740                                                   HcalTrigPrimDigiCollection* hcalTPGs,
0741                                                   uint32_t BX_n) {
0742       UCTCTP7RawData5BX_HCALFB::CaloType cType = UCTCTP7RawData5BX_HCALFB::HF;
0743       for (uint32_t side = 0; side <= 1; side++) {
0744         bool negativeEta = false;
0745         if (side == 0)
0746           negativeEta = true;
0747         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0748           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0749             if (iPhi == 1 && iEta == 40)
0750               iEta = 41;
0751             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0752             if (iEta == 41)
0753               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0754             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0755             int cEta = iEta;
0756             if (negativeEta)
0757               cEta = -iEta;
0758             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0759             // Bottom 8-bits are ET
0760             // Then feature bit
0761             // Then minBias ADC count bit
0762             // The remaining bits are undefined presently
0763             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0764             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0765             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0766             uint32_t towerDatum = ctp7Data5BX_HCALFB.getET(cType, negativeEta, iEta, iPhi, BX_n);
0767             towerDatum |= ctp7Data5BX_HCALFB.getFB(cType, negativeEta, iEta, iPhi, BX_n) << 8;
0768             if (ctp7Data5BX_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0769               towerDatum |= 0x0400;
0770             if (ctp7Data5BX_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0771               towerDatum |= 0x0800;
0772             if (ctp7Data5BX_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0773               towerDatum |= 0x1000;
0774             if (ctp7Data5BX_HCALFB.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0775               towerDatum |= 0x2000;
0776             if (ctp7Data5BX_HCALFB.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0777               towerDatum |= 0x4000;
0778             if (ctp7Data5BX_HCALFB.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0779                 ctp7Data5BX_HCALFB.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0780                 ctp7Data5BX_HCALFB.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0781               towerDatum |= 0x8000;
0782             HcalTriggerPrimitiveSample sample(towerDatum);
0783             HcalTrigTowerDetId id(cEta, cPhi);
0784             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0785             HcalTriggerPrimitiveDigi tpg(id);
0786             tpg.setSize(1);
0787             tpg.setSample(0, sample);
0788             hcalTPGs->push_back(tpg);
0789           }
0790         }
0791       }
0792     }
0793 
0794     void CaloLayer1Unpacker::makeRegions5BX_HCALFB(uint32_t lPhi,
0795                                                    UCTCTP7RawData5BX_HCALFB& ctp7Data5BX_HCALFB,
0796                                                    L1CaloRegionCollection* regions,
0797                                                    uint32_t BX_n) {
0798       for (uint32_t side = 0; side <= 1; side++) {
0799         bool negativeEta = false;
0800         if (side == 0)
0801           negativeEta = true;
0802         for (uint32_t region = 0; region <= 6; region++) {
0803           uint32_t regionData = ctp7Data5BX_HCALFB.getRegionSummary(negativeEta, region, BX_n);
0804           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0805           if (!negativeEta)
0806             lEta = region + 11;
0807           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0808         }
0809       }
0810     }
0811 
0812   }  // namespace stage2
0813 }  // namespace l1t
0814 
0815 DEFINE_L1T_UNPACKER(l1t::stage2::CaloLayer1Unpacker);