Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-17 23:36:13

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       if (N_BX == 1) {
0028         UCTCTP7RawData ctp7Data(ptr);
0029         makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis());
0030         makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
0031         makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
0032         makeRegions(ctp7_phi, ctp7Data, res->getRegions());
0033       } else if (N_BX == 5) {
0034         UCTCTP7RawData5BX ctp7Data5BX(ptr);
0035         // BX_n = 0, 1, 2, 3, 4, where 2 is nominal
0036         makeECalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getEcalDigis(), 2);
0037         makeHCalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getHcalDigis(), 2);
0038         makeHFTPGs5BX(ctp7_phi, ctp7Data5BX, res->getHcalDigis(), 2);
0039         makeRegions5BX(ctp7_phi, ctp7Data5BX, res->getRegions(), 2);
0040         for (int i = 0; i < 5; i++) {
0041           makeECalTPGs5BX(ctp7_phi, ctp7Data5BX, res->getEcalDigisBx(i), i);
0042         }
0043       } else {
0044         LogError("CaloLayer1Unpacker") << "Number of BXs to unpack is not 1 or 5, stop here !!! " << N_BX << std::endl;
0045         return false;
0046       }
0047 
0048       return true;
0049     }
0050 
0051     void CaloLayer1Unpacker::makeECalTPGs(uint32_t lPhi,
0052                                           UCTCTP7RawData& ctp7Data,
0053                                           EcalTrigPrimDigiCollection* ecalTPGs) {
0054       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::EBEE;
0055       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0056         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0057         if (cPhi == 0)
0058           cPhi = 72;
0059         else if (cPhi == -1)
0060           cPhi = 71;
0061         else if (cPhi < -1) {
0062           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs" << std::endl;
0063           return;
0064         }
0065         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0066           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0067             bool negativeEta = false;
0068             if (cEta < 0)
0069               negativeEta = true;
0070             uint32_t iEta = abs(cEta);
0071             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0072             // Bottom 8-bits are ET
0073             // Then finegrain feature bit
0074             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0075             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0076             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0077             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0078             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0079             if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
0080               towerDatum |= 0x0100;
0081             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0082               towerDatum |= 0x2000;
0083             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0084               towerDatum |= 0x4000;
0085             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0086                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0087                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0088               towerDatum |= 0x8000;
0089             EcalTriggerPrimitiveSample sample(towerDatum);
0090             int zSide = cEta / ((int)iEta);
0091             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0092             const EcalSubdetector ecalTriggerTower =
0093                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0094             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0095             EcalTriggerPrimitiveDigi tpg(id);
0096             tpg.setSize(1);
0097             tpg.setSample(0, sample);
0098             ecalTPGs->push_back(tpg);
0099           }
0100         }
0101       }
0102     }
0103 
0104     void CaloLayer1Unpacker::makeHCalTPGs(uint32_t lPhi,
0105                                           UCTCTP7RawData& ctp7Data,
0106                                           HcalTrigPrimDigiCollection* hcalTPGs) {
0107       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HBHE;
0108       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0109         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0110         if (cPhi == 0)
0111           cPhi = 72;
0112         else if (cPhi == -1)
0113           cPhi = 71;
0114         else if (cPhi < -1) {
0115           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs" << std::endl;
0116           return;
0117         }
0118         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0119           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0120             bool negativeEta = false;
0121             if (cEta < 0)
0122               negativeEta = true;
0123             uint32_t iEta = abs(cEta);
0124             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0125             // Bottom 8-bits are ET
0126             // Then feature bit
0127             // The remaining bits are undefined presently
0128             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0129             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0130             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0131             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0132             if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
0133               towerDatum |= 0x0100;
0134             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0135               towerDatum |= 0x0200;
0136             if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
0137               towerDatum |= 0x0400;
0138             if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0139               towerDatum |= 0x0800;
0140             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0141               towerDatum |= 0x2000;
0142             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0143               towerDatum |= 0x4000;
0144             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0145                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0146                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0147               towerDatum |= 0x8000;
0148             HcalTriggerPrimitiveSample sample(towerDatum);
0149             HcalTrigTowerDetId id(cEta, cPhi);
0150             HcalTriggerPrimitiveDigi tpg(id);
0151             tpg.setSize(1);
0152             tpg.setSample(0, sample);
0153             hcalTPGs->push_back(tpg);
0154           }
0155         }
0156       }
0157     }
0158 
0159     void CaloLayer1Unpacker::makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
0160       UCTCTP7RawData::CaloType cType = UCTCTP7RawData::HF;
0161       for (uint32_t side = 0; side <= 1; side++) {
0162         bool negativeEta = false;
0163         if (side == 0)
0164           negativeEta = true;
0165         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0166           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0167             if (iPhi == 1 && iEta == 40)
0168               iEta = 41;
0169             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0170             if (iEta == 41)
0171               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0172             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0173             int cEta = iEta;
0174             if (negativeEta)
0175               cEta = -iEta;
0176             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0177             // Bottom 8-bits are ET
0178             // Then feature bit
0179             // Then minBias ADC count bit
0180             // The remaining bits are undefined presently
0181             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0182             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0183             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0184             uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
0185             towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
0186             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
0187               towerDatum |= 0x0400;
0188             if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
0189               towerDatum |= 0x0800;
0190             if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0191               towerDatum |= 0x1000;
0192             if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
0193               towerDatum |= 0x2000;
0194             if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
0195               towerDatum |= 0x4000;
0196             if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
0197                 ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
0198                 ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
0199               towerDatum |= 0x8000;
0200             HcalTriggerPrimitiveSample sample(towerDatum);
0201             HcalTrigTowerDetId id(cEta, cPhi);
0202             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0203             HcalTriggerPrimitiveDigi tpg(id);
0204             tpg.setSize(1);
0205             tpg.setSample(0, sample);
0206             hcalTPGs->push_back(tpg);
0207           }
0208         }
0209       }
0210     }
0211 
0212     void CaloLayer1Unpacker::makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, L1CaloRegionCollection* regions) {
0213       for (uint32_t side = 0; side <= 1; side++) {
0214         bool negativeEta = false;
0215         if (side == 0)
0216           negativeEta = true;
0217         for (uint32_t region = 0; region <= 6; region++) {
0218           uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
0219           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0220           if (!negativeEta)
0221             lEta = region + 11;
0222           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0223         }
0224       }
0225     }
0226 
0227     // The following four functions are duplicated from above, to be used for 5BX events
0228     // They have a new parameter BX_n = 0, 1, 2, 3, 4, where 2 is nominal
0229     // And use functions defined in UCTCTP7RawData5BX.h
0230     // The idea is not to intervene the normal events unpacking
0231 
0232     void CaloLayer1Unpacker::makeECalTPGs5BX(uint32_t lPhi,
0233                                              UCTCTP7RawData5BX& ctp7Data5BX,
0234                                              EcalTrigPrimDigiCollection* ecalTPGs,
0235                                              uint32_t BX_n) {
0236       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::EBEE;
0237       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0238         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0239         if (cPhi == 0)
0240           cPhi = 72;
0241         else if (cPhi == -1)
0242           cPhi = 71;
0243         else if (cPhi < -1) {
0244           LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs5BX" << std::endl;
0245           return;
0246         }
0247         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0248           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0249             bool negativeEta = false;
0250             if (cEta < 0)
0251               negativeEta = true;
0252             uint32_t iEta = abs(cEta);
0253             // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
0254             // Bottom 8-bits are ET
0255             // Then finegrain feature bit
0256             // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
0257             // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
0258             // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
0259             // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
0260             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0261             if (ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) != 0)
0262               towerDatum |= 0x0100;
0263             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0264               towerDatum |= 0x2000;
0265             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0266               towerDatum |= 0x4000;
0267             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0268                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0269                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0270               towerDatum |= 0x8000;
0271             EcalTriggerPrimitiveSample sample(towerDatum);
0272             int zSide = cEta / ((int)iEta);
0273             // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
0274             const EcalSubdetector ecalTriggerTower =
0275                 (iEta > 17) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
0276             EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
0277             EcalTriggerPrimitiveDigi tpg(id);
0278             tpg.setSize(1);
0279             tpg.setSample(0, sample);
0280             ecalTPGs->push_back(tpg);
0281           }
0282         }
0283       }
0284     }
0285 
0286     void CaloLayer1Unpacker::makeHCalTPGs5BX(uint32_t lPhi,
0287                                              UCTCTP7RawData5BX& ctp7Data5BX,
0288                                              HcalTrigPrimDigiCollection* hcalTPGs,
0289                                              uint32_t BX_n) {
0290       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::HBHE;
0291       for (uint32_t iPhi = 0; iPhi < 4; iPhi++) {  // Loop over all four phi divisions on card
0292         int cPhi = -1 + lPhi * 4 + iPhi;           // Calorimeter phi index
0293         if (cPhi == 0)
0294           cPhi = 72;
0295         else if (cPhi == -1)
0296           cPhi = 71;
0297         else if (cPhi < -1) {
0298           LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs5BX" << std::endl;
0299           return;
0300         }
0301         for (int cEta = -28; cEta <= 28; cEta++) {  // Calorimeter Eta indices (HB/HE for now)
0302           if (cEta != 0) {                          // Calorimeter eta = 0 is invalid
0303             bool negativeEta = false;
0304             if (cEta < 0)
0305               negativeEta = true;
0306             uint32_t iEta = abs(cEta);
0307             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0308             // Bottom 8-bits are ET
0309             // Then feature bit
0310             // The remaining bits are undefined presently
0311             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0312             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0313             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0314             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0315             if (ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) != 0)
0316               towerDatum |= 0x0100;
0317             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0318               towerDatum |= 0x0200;
0319             if (ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0320               towerDatum |= 0x0400;
0321             if (ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0322               towerDatum |= 0x0800;
0323             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0324               towerDatum |= 0x2000;
0325             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0326               towerDatum |= 0x4000;
0327             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0328                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0329                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0330               towerDatum |= 0x8000;
0331             HcalTriggerPrimitiveSample sample(towerDatum);
0332             HcalTrigTowerDetId id(cEta, cPhi);
0333             HcalTriggerPrimitiveDigi tpg(id);
0334             tpg.setSize(1);
0335             tpg.setSample(0, sample);
0336             hcalTPGs->push_back(tpg);
0337           }
0338         }
0339       }
0340     }
0341 
0342     void CaloLayer1Unpacker::makeHFTPGs5BX(uint32_t lPhi,
0343                                            UCTCTP7RawData5BX& ctp7Data5BX,
0344                                            HcalTrigPrimDigiCollection* hcalTPGs,
0345                                            uint32_t BX_n) {
0346       UCTCTP7RawData5BX::CaloType cType = UCTCTP7RawData5BX::HF;
0347       for (uint32_t side = 0; side <= 1; side++) {
0348         bool negativeEta = false;
0349         if (side == 0)
0350           negativeEta = true;
0351         for (uint32_t iEta = 30; iEta <= 40; iEta++) {
0352           for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
0353             if (iPhi == 1 && iEta == 40)
0354               iEta = 41;
0355             int cPhi = 1 + lPhi * 4 + iPhi * 2;  // Calorimeter phi index: 1, 3, 5, ... 71
0356             if (iEta == 41)
0357               cPhi -= 2;                  // Last two HF are 3, 7, 11, ...
0358             cPhi = (cPhi + 69) % 72 + 1;  // cPhi -= 2 mod 72
0359             int cEta = iEta;
0360             if (negativeEta)
0361               cEta = -iEta;
0362             // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
0363             // Bottom 8-bits are ET
0364             // Then feature bit
0365             // Then minBias ADC count bit
0366             // The remaining bits are undefined presently
0367             // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
0368             // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
0369             // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
0370             uint32_t towerDatum = ctp7Data5BX.getET(cType, negativeEta, iEta, iPhi, BX_n);
0371             towerDatum |= ctp7Data5BX.getFB(cType, negativeEta, iEta, iPhi, BX_n) << 8;
0372             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n))
0373               towerDatum |= 0x0400;
0374             if (ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n))
0375               towerDatum |= 0x0800;
0376             if (ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0377               towerDatum |= 0x1000;
0378             if (ctp7Data5BX.isTowerMasked(cType, negativeEta, iEta, iPhi, BX_n))
0379               towerDatum |= 0x2000;
0380             if (ctp7Data5BX.isLinkMasked(cType, negativeEta, iEta, iPhi, BX_n))
0381               towerDatum |= 0x4000;
0382             if (ctp7Data5BX.isLinkMisaligned(cType, negativeEta, iEta, iPhi, BX_n) ||
0383                 ctp7Data5BX.isLinkInError(cType, negativeEta, iEta, iPhi, BX_n) ||
0384                 ctp7Data5BX.isLinkDown(cType, negativeEta, iEta, iPhi, BX_n))
0385               towerDatum |= 0x8000;
0386             HcalTriggerPrimitiveSample sample(towerDatum);
0387             HcalTrigTowerDetId id(cEta, cPhi);
0388             id.setVersion(1);  // To not process these 1x1 HF TPGs with RCT
0389             HcalTriggerPrimitiveDigi tpg(id);
0390             tpg.setSize(1);
0391             tpg.setSample(0, sample);
0392             hcalTPGs->push_back(tpg);
0393           }
0394         }
0395       }
0396     }
0397 
0398     void CaloLayer1Unpacker::makeRegions5BX(uint32_t lPhi,
0399                                             UCTCTP7RawData5BX& ctp7Data5BX,
0400                                             L1CaloRegionCollection* regions,
0401                                             uint32_t BX_n) {
0402       for (uint32_t side = 0; side <= 1; side++) {
0403         bool negativeEta = false;
0404         if (side == 0)
0405           negativeEta = true;
0406         for (uint32_t region = 0; region <= 6; region++) {
0407           uint32_t regionData = ctp7Data5BX.getRegionSummary(negativeEta, region, BX_n);
0408           uint32_t lEta = 10 - region;  // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
0409           if (!negativeEta)
0410             lEta = region + 11;
0411           regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
0412         }
0413       }
0414     }
0415 
0416   }  // namespace stage2
0417 }  // namespace l1t
0418 
0419 DEFINE_L1T_UNPACKER(l1t::stage2::CaloLayer1Unpacker);