Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:10:49

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