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