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  uint32_t * ptr = &*block.payload().begin();
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  ecalTPGs->reserve(4228); // # of ECAL TT
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) cPhi = 72;
40  else if(cPhi == -1) cPhi = 71;
41  else if(cPhi < -1) {
42  LogError("CaloLayer1Unpacker") << "Major error in makeECalTPGs" << std::endl;
43  return;
44  }
45  for(int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
46  if(cEta != 0) { // Calorimeter eta = 0 is invalid
47  bool negativeEta = false;
48  if(cEta < 0) negativeEta = true;
49  uint32_t iEta = abs(cEta);
50  // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
51  // Bottom 8-bits are ET
52  // Then finegrain feature bit
53  // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
54  // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
55  // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
56  // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
57  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
58  if(ctp7Data.getFB(cType, negativeEta, iEta, iPhi)!=0) towerDatum |= 0x0100;
59  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
60  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
61  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
62  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
63  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
65  int zSide = cEta / ((int) iEta);
66  // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
67  const EcalSubdetector ecalTriggerTower = (iEta > 17 ) ? EcalSubdetector::EcalEndcap : EcalSubdetector::EcalBarrel;
68  EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
70  tpg.setSize(1);
71  tpg.setSample(0, sample);
72  ecalTPGs->push_back(tpg);
73  }
74  }
75  }
76 
77  }
78 
79  void CaloLayer1Unpacker::makeHCalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
80  hcalTPGs->reserve(4608); // # of HCAL TT
82  for(uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
83  int cPhi = - 1 + lPhi * 4 + iPhi; // Calorimeter phi index
84  if(cPhi == 0) cPhi = 72;
85  else if(cPhi == -1) cPhi = 71;
86  else if(cPhi < -1) {
87  LogError("CaloLayer1Unpacker") << "Major error in makeHCalTPGs" << std::endl;
88  return;
89  }
90  for(int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
91  if(cEta != 0) { // Calorimeter eta = 0 is invalid
92  bool negativeEta = false;
93  if(cEta < 0) negativeEta = true;
94  uint32_t iEta = abs(cEta);
95  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
96  // Bottom 8-bits are ET
97  // Then feature bit
98  // The remaining bits are undefined presently
99  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
100  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
101  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
102  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
103  if(ctp7Data.getFB(cType, negativeEta, iEta, iPhi)!=0) towerDatum |= 0x0100;
104  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0200;
105  if(ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0400;
106  if(ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0800;
107  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
108  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
109  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
110  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
111  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
112  HcalTriggerPrimitiveSample sample(towerDatum);
113  HcalTrigTowerDetId id(cEta, cPhi);
114  HcalTriggerPrimitiveDigi tpg(id);
115  tpg.setSize(1);
116  tpg.setSample(0, sample);
117  hcalTPGs->push_back(tpg);
118  }
119  }
120  }
121 
122  }
123 
124  void CaloLayer1Unpacker::makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, HcalTrigPrimDigiCollection* hcalTPGs) {
126  for(uint32_t side = 0; side <= 1; side++) {
127  bool negativeEta = false;
128  if(side == 0) negativeEta = true;
129  for(uint32_t iEta = 30; iEta <= 40; iEta++) {
130  for(uint32_t iPhi = 0; iPhi < 2; iPhi++) {
131  if(iPhi == 1 && iEta == 40) iEta = 41;
132  int cPhi = 1 + lPhi * 4 + iPhi * 2; // Calorimeter phi index: 1, 3, 5, ... 71
133  if(iEta == 41) cPhi -= 2; // Last two HF are 3, 7, 11, ...
134  cPhi = (cPhi+69)%72 + 1; // cPhi -= 2 mod 72
135  int cEta = iEta;
136  if(negativeEta) cEta = -iEta;
137  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
138  // Bottom 8-bits are ET
139  // Then feature bit
140  // Then minBias ADC count bit
141  // The remaining bits are undefined presently
142  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
143  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
144  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
145  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
146  towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
147  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0400;
148  if(ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x0800;
149  if(ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x1000;
150  if(ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x2000;
151  if(ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x4000;
152  if(ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
153  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
154  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi)) towerDatum |= 0x8000;
155  HcalTriggerPrimitiveSample sample(towerDatum);
156  HcalTrigTowerDetId id(cEta, cPhi);
157  id.setVersion(1); // To not process these 1x1 HF TPGs with RCT
158  HcalTriggerPrimitiveDigi tpg(id);
159  tpg.setSize(1);
160  tpg.setSample(0, sample);
161  hcalTPGs->push_back(tpg);
162  }
163  }
164  }
165  }
166 
167  void
168  CaloLayer1Unpacker::makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, L1CaloRegionCollection* regions) {
169  for(uint32_t side = 0; side <= 1; side++) {
170  bool negativeEta = false;
171  if(side == 0) negativeEta = true;
172  for(uint32_t region = 0; region <= 6; region++) {
173  uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
174  uint32_t lEta = 10 - region; // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
175  if(!negativeEta) lEta = region + 11;
176  regions->push_back(L1CaloRegion((uint16_t) regionData, (unsigned) lEta, (unsigned) lPhi, (int16_t) 0));
177  }
178  }
179  }
180 
181 }
182 }
183 
#define LogDebug(id)
void setSample(int i, const HcalTriggerPrimitiveSample &sam)
uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
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
std::vector< uint32_t > payload() const
Definition: Block.h:60
bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
Definition: Electron.h:4
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
void reserve(size_type n)
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)