CMS 3D CMS Logo

L1TCaloLayer1RawToDigi.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: EventFilter/L1TXRawToDigi
4 // Class: L1TCaloLayer1RawToDigi
5 //
16 //
17 // Original Author: Sridhara Rao Dasu
18 // Created: Sun, 13 Sep 2015 00:31:25 GMT
19 //
20 //
21 
22 // system include files
23 #include <memory>
24 
25 // user include files
31 
33 
36 
37 // Raw data collection headers
41 
45 
47 
51 
53 
56 
60 
61 using namespace edm;
62 
63 //
64 // class declaration
65 //
66 
68 public:
69  explicit L1TCaloLayer1RawToDigi(const ParameterSet&);
70 
71  static void fillDescriptions(ConfigurationDescriptions& descriptions);
72 
73 private:
74  void produce(Event&, const EventSetup&) override;
75 
76  void makeECalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<EcalTrigPrimDigiCollection>& ecalTPGs);
77 
78  void makeHCalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs);
79 
80  void makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs);
81 
82  void makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<L1CaloRegionCollection>& regions);
83 
84  // ----------member data ---------------------------
85 
87  std::vector<int> fedIDs;
88 
89  uint32_t event;
90 
91  bool verbose;
92 };
93 
94 //
95 // constants, enums and typedefs
96 //
97 
98 //
99 // static data member definitions
100 //
101 
102 //
103 // constructors and destructor
104 //
106  : fedRawDataLabel(iConfig.getParameter<InputTag>("fedRawDataLabel")),
107  fedIDs(iConfig.getParameter<std::vector<int> >("FEDIDs")),
108  event(0),
109  verbose(iConfig.getParameter<bool>("verbose")) {
110  produces<EcalTrigPrimDigiCollection>();
111  produces<HcalTrigPrimDigiCollection>();
112  produces<L1CaloRegionCollection>();
113 
114  consumes<FEDRawDataCollection>(fedRawDataLabel);
115 }
116 
117 //
118 // member functions
119 //
120 
121 // ------------ method called to produce the data ------------
123  using namespace edm;
124  using namespace std;
125 
126  Handle<FEDRawDataCollection> fedRawDataCollection;
127  iEvent.getByLabel(fedRawDataLabel, fedRawDataCollection);
128 
129  std::unique_ptr<EcalTrigPrimDigiCollection> ecalTPGs(new EcalTrigPrimDigiCollection);
130  std::unique_ptr<HcalTrigPrimDigiCollection> hcalTPGs(new HcalTrigPrimDigiCollection);
131  std::unique_ptr<L1CaloRegionCollection> regions(new L1CaloRegionCollection);
132 
133  // if raw data collection is present, check the headers and do the unpacking
134  if (fedRawDataCollection.isValid()) {
135  for (uint32_t i = 0; i < fedIDs.size(); i++) {
136  uint32_t fed = fedIDs[i];
137 
138  const FEDRawData& fedRawData = fedRawDataCollection->FEDData(fed);
139 
140  //Check FED size
141  if (verbose)
142  LogDebug("L1TCaloLayer1RawToDigi")
143  << "Upacking FEDRawData for fed " << std::dec << fed << " of size " << fedRawData.size();
144 
145  const uint64_t* fedRawDataArray = (const uint64_t*)fedRawData.data();
146 
147  if (fedRawData.size() == 0 || fedRawDataArray == nullptr) {
148  LogDebug("L1TCaloLayer1RawToDigi") << "Could not load FED data for " << fed << ", putting empty collections!";
149  continue;
150  }
151 
152  UCTDAQRawData daqData(fedRawDataArray);
153  if (verbose && event < 5)
154  daqData.print();
155  for (uint32_t i = 0; i < daqData.nAMCs(); i++) {
156  UCTAMCRawData amcData(daqData.amcPayload(i));
157  if (verbose && event < 5) {
158  LogDebug("L1TCaloLayer1") << endl;
159  amcData.print();
160  LogDebug("L1TCaloLayer1") << endl;
161  }
162  uint32_t lPhi = amcData.layer1Phi();
163  UCTCTP7RawData ctp7Data(amcData.payload());
164  if (verbose && event < 5)
165  ctp7Data.print();
166  if (verbose && event < 5)
167  LogDebug("L1TCaloLayer1") << endl;
168  makeECalTPGs(lPhi, ctp7Data, ecalTPGs);
169  makeHCalTPGs(lPhi, ctp7Data, hcalTPGs);
170  // Note: HF TPGs are added at the tail of other TPGs
171  makeHFTPGs(lPhi, ctp7Data, hcalTPGs);
172  makeRegions(lPhi, ctp7Data, regions);
173  }
174  }
175 
176  } else {
177  LogError("L1T") << "Cannot unpack: no collection found";
178 
179  return;
180  }
181 
182  iEvent.put(std::move(ecalTPGs));
183  iEvent.put(std::move(hcalTPGs));
184  iEvent.put(std::move(regions));
185 
186  event++;
187  if (verbose && event == 5)
188  LogDebug("L1TCaloLayer1") << "L1TCaloLayer1RawToDigi: Goodbye! Tired of printing junk" << endl;
189 }
190 
192  UCTCTP7RawData& ctp7Data,
193  std::unique_ptr<EcalTrigPrimDigiCollection>& ecalTPGs) {
195  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
196  int cPhi = -1 + lPhi * 4 + iPhi; // Calorimeter phi index
197  if (cPhi == 0)
198  cPhi = 72;
199  else if (cPhi == -1)
200  cPhi = 71;
201  else if (cPhi < -1) {
202  LogError("L1TCaloLayer1RawToDigi") << "L1TCaloLayer1RawToDigi: Major error in makeECalTPGs" << std::endl;
203  return;
204  }
205  for (int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
206  if (cEta != 0) { // Calorimeter eta = 0 is invalid
207  bool negativeEta = false;
208  if (cEta < 0)
209  negativeEta = true;
210  uint32_t iEta = abs(cEta);
211  // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
212  // Bottom 8-bits are ET
213  // Then finegrain feature bit
214  // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
215  // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
216  // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
217  // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
218  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
219  if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
220  towerDatum |= 0x0100;
221  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
222  towerDatum |= 0x2000;
223  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
224  towerDatum |= 0x4000;
225  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
226  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
227  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
228  towerDatum |= 0x8000;
230  int zSide = cEta / ((int)iEta);
231  // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
232  const EcalSubdetector ecalTriggerTower =
234  EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
235  EcalTriggerPrimitiveDigi tpg(id);
236  tpg.setSize(1);
237  tpg.setSample(0, sample);
238  ecalTPGs->push_back(tpg);
239  }
240  }
241  }
242 }
243 
245  UCTCTP7RawData& ctp7Data,
246  std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs) {
248  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
249  int cPhi = -1 + lPhi * 4 + iPhi; // Calorimeter phi index
250  if (cPhi == 0)
251  cPhi = 72;
252  else if (cPhi == -1)
253  cPhi = 71;
254  else if (cPhi < -1) {
255  LogError("L1TCaloLayer1RawToDigi") << "L1TCaloLayer1RawToDigi: Major error in makeHCalTPGs" << std::endl;
256  return;
257  }
258  for (int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
259  if (cEta != 0) { // Calorimeter eta = 0 is invalid
260  bool negativeEta = false;
261  if (cEta < 0)
262  negativeEta = true;
263  uint32_t iEta = abs(cEta);
264  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
265  // Bottom 8-bits are ET
266  // Then feature bit
267  // The remaining bits are undefined presently
268  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
269  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
270  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
271  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
272  if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
273  towerDatum |= 0x0100;
274  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
275  towerDatum |= 0x0200;
276  if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
277  towerDatum |= 0x0400;
278  if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
279  towerDatum |= 0x0800;
280  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
281  towerDatum |= 0x2000;
282  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
283  towerDatum |= 0x4000;
284  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
285  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
286  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
287  towerDatum |= 0x8000;
289  HcalTrigTowerDetId id(cEta, cPhi);
290  HcalTriggerPrimitiveDigi tpg(id);
291  tpg.setSize(1);
292  tpg.setSample(0, sample);
293  hcalTPGs->push_back(tpg);
294  }
295  }
296  }
297 }
298 
300  UCTCTP7RawData& ctp7Data,
301  std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs) {
303  for (uint32_t side = 0; side <= 1; side++) {
304  bool negativeEta = false;
305  if (side == 0)
306  negativeEta = true;
307  for (uint32_t iEta = 30; iEta <= 40; iEta++) {
308  for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
309  if (iPhi == 1 && iEta == 40)
310  iEta = 41;
311  int cPhi = 1 + lPhi * 4 + iPhi * 2; // Calorimeter phi index: 1, 3, 5, ... 71
312  if (iEta == 41)
313  cPhi -= 2; // Last two HF are 3, 7, 11, ...
314  cPhi = (cPhi + 69) % 72 + 1; // cPhi -= 2 mod 72
315  int cEta = iEta;
316  if (negativeEta)
317  cEta = -iEta;
318  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
319  // Bottom 8-bits are ET
320  // Then feature bit
321  // Then minBias ADC count bit
322  // The remaining bits are undefined presently
323  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
324  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
325  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
326  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
327  towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
328  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
329  towerDatum |= 0x0400;
330  if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
331  towerDatum |= 0x0800;
332  if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
333  towerDatum |= 0x1000;
334  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
335  towerDatum |= 0x2000;
336  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
337  towerDatum |= 0x4000;
338  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
339  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
340  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
341  towerDatum |= 0x8000;
343  HcalTrigTowerDetId id(cEta, cPhi);
344  id.setVersion(1); // To not process these 1x1 HF TPGs with RCT
345  HcalTriggerPrimitiveDigi tpg(id);
346  tpg.setSize(1);
347  tpg.setSample(0, sample);
348  hcalTPGs->push_back(tpg);
349  }
350  }
351  }
352 }
353 
355  UCTCTP7RawData& ctp7Data,
356  std::unique_ptr<L1CaloRegionCollection>& regions) {
357  for (uint32_t side = 0; side <= 1; side++) {
358  bool negativeEta = false;
359  if (side == 0)
360  negativeEta = true;
361  for (uint32_t region = 0; region <= 6; region++) {
362  uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
363  uint32_t lEta = 10 - region; // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
364  if (!negativeEta)
365  lEta = region + 11;
366  regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
367  }
368  }
369 }
370 
371 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
373  //The following says we do not know what parameters are allowed so do no validation
374  // Please change this to state exactly what you do use, even if it is no parameters
376  desc.setUnknown();
377  descriptions.addDefault(desc);
378 }
379 
380 //define this as a plug-in
void makeHCalTPGs(uint32_t lPhi, UCTCTP7RawData &ctp7Data, std::unique_ptr< HcalTrigPrimDigiCollection > &hcalTPGs)
void setSample(int i, const HcalTriggerPrimitiveSample &sam)
uint32_t getFB(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
bool verbose
bool isLinkMasked(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
void makeRegions(uint32_t lPhi, UCTCTP7RawData &ctp7Data, std::unique_ptr< L1CaloRegionCollection > &regions)
Log< level::Error, false > LogError
bool isLinkDown(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
uint32_t nAMCs()
Definition: UCTDAQRawData.h:41
L1TCaloLayer1RawToDigi(const ParameterSet &)
const uint32_t * amcPayload(uint32_t amc)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void makeHFTPGs(uint32_t lPhi, UCTCTP7RawData &ctp7Data, std::unique_ptr< HcalTrigPrimDigiCollection > &hcalTPGs)
unsigned long long uint64_t
Definition: Time.h:13
void makeECalTPGs(uint32_t lPhi, UCTCTP7RawData &ctp7Data, std::unique_ptr< EcalTrigPrimDigiCollection > &ecalTPGs)
bool isValid() const
Definition: HandleBase.h:70
uint32_t getET(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
HLT enums.
static void fillDescriptions(ConfigurationDescriptions &descriptions)
void produce(Event &, const EventSetup &) override
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:21
std::vector< L1CaloRegion > L1CaloRegionCollection
uint32_t getRegionSummary(bool negativeEta, uint32_t region)
EcalSubdetector
def move(src, dest)
Definition: eostools.py:511
Definition: event.py:1
bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)
#define LogDebug(id)