CMS 3D CMS Logo

CaloLayer1Unpacker.cc
Go to the documentation of this file.
3 
4 #include "CaloLayer1Unpacker.h"
5 
6 using namespace edm;
7 
8 namespace l1t {
9 namespace stage2 {
10 
11  // max_iEta_HcalTP = 41; // barrel <= 16, endcap <= 29, hf <= 41
12  // there are two TT29’s: one in HE readout in TT28 and another in HF readout in TT30
13  // max_iPhi_HcalTP = 72;
14 
16  {
17  LogDebug("L1T") << "Block size = " << block.header().getSize();
18  LogDebug("L1T") << "Board ID = " << block.amc().getBoardID();
19 
20  auto res = static_cast<CaloLayer1Collections*>(coll);
21 
22  auto ctp7_phi = block.amc().getBoardID();
23  const uint32_t * ptr = block.payload().data();
24 
25  UCTCTP7RawData ctp7Data(ptr);
26  makeECalTPGs(ctp7_phi, ctp7Data, res->getEcalDigis());
27  makeHCalTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
28  makeHFTPGs(ctp7_phi, ctp7Data, res->getHcalDigis());
29  makeRegions(ctp7_phi, ctp7Data, res->getRegions());
30 
31  return true;
32  }
33 
34  void CaloLayer1Unpacker::makeECalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, EcalTrigPrimDigiCollection* ecalTPGs) {
36  for(uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
37  int cPhi = - 1 + lPhi * 4 + iPhi; // Calorimeter phi index
38  if(cPhi == 0) cPhi = 72;
39  else if(cPhi == -1) cPhi = 71;
40  else if(cPhi < -1) {
41  LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs" << std::endl;
42  return;
43  }
44  for(int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
45  if(cEta != 0) { // Calorimeter eta = 0 is invalid
46  bool negativeEta = false;
47  if(cEta < 0) negativeEta = true;
48  uint32_t iEta = abs(cEta);
49  // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
50  // Bottom 8-bits are ET
51  // Then finegrain feature bit
52  // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
53  // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
54  // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
55  // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
56  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
57  if(ctp7Data.getFB(cType, negativeEta, iEta, iPhi)!=0) towerDatum |= 0x0100;
58  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
59  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
60  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
61  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
62  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
64  int zSide = cEta / ((int) iEta);
65  // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
66  const EcalSubdetector ecalTriggerTower = (iEta > 17 ) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
67  EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
69  tpg.setSize(1);
70  tpg.setSample(0, sample);
71  ecalTPGs->push_back(tpg);
72  }
73  }
74  }
75 
76  }
77 
78  void CaloLayer1Unpacker::makeHCalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
80  for(uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
81  int cPhi = - 1 + lPhi * 4 + iPhi; // Calorimeter phi index
82  if(cPhi == 0) cPhi = 72;
83  else if(cPhi == -1) cPhi = 71;
84  else if(cPhi < -1) {
85  LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs" << std::endl;
86  return;
87  }
88  for(int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
89  if(cEta != 0) { // Calorimeter eta = 0 is invalid
90  bool negativeEta = false;
91  if(cEta < 0) negativeEta = true;
92  uint32_t iEta = abs(cEta);
93  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
94  // Bottom 8-bits are ET
95  // Then feature bit
96  // The remaining bits are undefined presently
97  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
98  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
99  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
100  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
101  if(ctp7Data.getFB(cType, negativeEta, iEta, iPhi)!=0) towerDatum |= 0x0100;
102  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0200;
103  if(ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0400;
104  if(ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0800;
105  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
106  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
107  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
108  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
109  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
110  HcalTriggerPrimitiveSample sample(towerDatum);
111  HcalTrigTowerDetId id(cEta, cPhi);
112  HcalTriggerPrimitiveDigi tpg(id);
113  tpg.setSize(1);
114  tpg.setSample(0, sample);
115  hcalTPGs->push_back(tpg);
116  }
117  }
118  }
119 
120  }
121 
122  void CaloLayer1Unpacker::makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
124  for(uint32_t side = 0; side <= 1; side++) {
125  bool negativeEta = false;
126  if(side == 0) negativeEta = true;
127  for(uint32_t iEta = 30; iEta <= 40; iEta++) {
128  for(uint32_t iPhi = 0; iPhi < 2; iPhi++) {
129  if(iPhi == 1 && iEta == 40) iEta = 41;
130  int cPhi = 1 + lPhi * 4 + iPhi * 2; // Calorimeter phi index: 1, 3, 5, ... 71
131  if(iEta == 41) cPhi -= 2; // Last two HF are 3, 7, 11, ...
132  cPhi = (cPhi+69)%72 + 1; // cPhi -= 2 mod 72
133  int cEta = iEta;
134  if(negativeEta) cEta = -iEta;
135  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
136  // Bottom 8-bits are ET
137  // Then feature bit
138  // Then minBias ADC count bit
139  // The remaining bits are undefined presently
140  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
141  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
142  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
143  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
144  towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
145  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0400;
146  if(ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0800;
147  if(ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x1000;
148  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
149  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
150  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
151  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
152  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
153  HcalTriggerPrimitiveSample sample(towerDatum);
154  HcalTrigTowerDetId id(cEta, cPhi);
155  id.setVersion(1); // To not process these 1x1 HF TPGs with RCT
156  HcalTriggerPrimitiveDigi tpg(id);
157  tpg.setSize(1);
158  tpg.setSample(0, sample);
159  hcalTPGs->push_back(tpg);
160  }
161  }
162  }
163  }
164 
165  void
166  CaloLayer1Unpacker::makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, L1CaloRegionCollection* regions) {
167  for(uint32_t side = 0; side <= 1; side++) {
168  bool negativeEta = false;
169  if(side == 0) negativeEta = true;
170  for(uint32_t region = 0; region <= 6; region++) {
171  uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
172  uint32_t lEta = 10 - region; // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
173  if(!negativeEta) lEta = region + 11;
174  regions->push_back(L1CaloRegion((uint16_t) regionData, (unsigned) lEta, (unsigned) lPhi, (int16_t) 0));
175  }
176  }
177  }
178 
179 }
180 }
181 
#define LogDebug(id)
void setSample(int i, const HcalTriggerPrimitiveSample &sam)
uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
const std::vector< uint32_t > & payload() const
Definition: Block.h:60
bool isLinkMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
BlockHeader header() const
Definition: Block.h:59
void push_back(T const &t)
delete x;
Definition: CaloConfig.h:22
bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
Definition: Electron.h:6
void setSample(int i, const EcalTriggerPrimitiveSample &sam)
bool isLinkInError(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool isTowerMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
JetCorrectorParametersCollection coll
Definition: classes.h:10
uint32_t getET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
HLT enums.
#define DEFINE_L1T_UNPACKER(type)
unsigned int getSize() const
Definition: Block.h:22
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:22
std::vector< L1CaloRegion > L1CaloRegionCollection
void amc(const amc::Header &h)
Definition: Block.h:62
uint32_t getRegionSummary(bool negativeEta, uint32_t region)
EcalSubdetector
bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)