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  ~L1TCaloLayer1RawToDigi() override;
71 
72  static void fillDescriptions(ConfigurationDescriptions& descriptions);
73 
74 private:
75  void beginStream(StreamID) override;
76  void produce(Event&, const EventSetup&) override;
77  void endStream() override;
78 
79  void makeECalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<EcalTrigPrimDigiCollection>& ecalTPGs);
80 
81  void makeHCalTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs);
82 
83  void makeHFTPGs(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs);
84 
85  void makeRegions(uint32_t lPhi, UCTCTP7RawData& ctp7Data, std::unique_ptr<L1CaloRegionCollection>& regions);
86 
87  //virtual void beginRun(Run const&, EventSetup const&) override;
88  //virtual void endRun(Run const&, EventSetup const&) override;
89  //virtual void beginLuminosityBlock(LuminosityBlock const&, EventSetup const&) override;
90  //virtual void endLuminosityBlock(LuminosityBlock const&, EventSetup const&) override;
91 
92  // ----------member data ---------------------------
93 
95  std::vector<int> fedIDs;
96 
97  uint32_t event;
98 
99  bool verbose;
100 };
101 
102 //
103 // constants, enums and typedefs
104 //
105 
106 //
107 // static data member definitions
108 //
109 
110 //
111 // constructors and destructor
112 //
114  : fedRawDataLabel(iConfig.getParameter<InputTag>("fedRawDataLabel")),
115  fedIDs(iConfig.getParameter<std::vector<int> >("FEDIDs")),
116  event(0),
117  verbose(iConfig.getParameter<bool>("verbose")) {
118  produces<EcalTrigPrimDigiCollection>();
119  produces<HcalTrigPrimDigiCollection>();
120  produces<L1CaloRegionCollection>();
121 
122  consumes<FEDRawDataCollection>(fedRawDataLabel);
123 }
124 
126 
127 //
128 // member functions
129 //
130 
131 // ------------ method called to produce the data ------------
133  using namespace edm;
134  using namespace std;
135 
136  Handle<FEDRawDataCollection> fedRawDataCollection;
137  iEvent.getByLabel(fedRawDataLabel, fedRawDataCollection);
138 
139  std::unique_ptr<EcalTrigPrimDigiCollection> ecalTPGs(new EcalTrigPrimDigiCollection);
140  std::unique_ptr<HcalTrigPrimDigiCollection> hcalTPGs(new HcalTrigPrimDigiCollection);
141  std::unique_ptr<L1CaloRegionCollection> regions(new L1CaloRegionCollection);
142 
143  // if raw data collection is present, check the headers and do the unpacking
144  if (fedRawDataCollection.isValid()) {
145  for (uint32_t i = 0; i < fedIDs.size(); i++) {
146  uint32_t fed = fedIDs[i];
147 
148  const FEDRawData& fedRawData = fedRawDataCollection->FEDData(fed);
149 
150  //Check FED size
151  if (verbose)
152  LogDebug("L1TCaloLayer1RawToDigi")
153  << "Upacking FEDRawData for fed " << std::dec << fed << " of size " << fedRawData.size();
154 
155  const uint64_t* fedRawDataArray = (const uint64_t*)fedRawData.data();
156 
157  if (fedRawData.size() == 0 || fedRawDataArray == nullptr) {
158  LogDebug("L1TCaloLayer1RawToDigi") << "Could not load FED data for " << fed << ", putting empty collections!";
159  continue;
160  }
161 
162  UCTDAQRawData daqData(fedRawDataArray);
163  if (verbose && event < 5)
164  daqData.print();
165  for (uint32_t i = 0; i < daqData.nAMCs(); i++) {
166  UCTAMCRawData amcData(daqData.amcPayload(i));
167  if (verbose && event < 5) {
168  LogDebug("L1TCaloLayer1") << endl;
169  amcData.print();
170  LogDebug("L1TCaloLayer1") << endl;
171  }
172  uint32_t lPhi = amcData.layer1Phi();
173  UCTCTP7RawData ctp7Data(amcData.payload());
174  if (verbose && event < 5)
175  ctp7Data.print();
176  if (verbose && event < 5)
177  LogDebug("L1TCaloLayer1") << endl;
178  makeECalTPGs(lPhi, ctp7Data, ecalTPGs);
179  makeHCalTPGs(lPhi, ctp7Data, hcalTPGs);
180  // Note: HF TPGs are added at the tail of other TPGs
181  makeHFTPGs(lPhi, ctp7Data, hcalTPGs);
182  makeRegions(lPhi, ctp7Data, regions);
183  }
184  }
185 
186  } else {
187  LogError("L1T") << "Cannot unpack: no collection found";
188 
189  return;
190  }
191 
192  iEvent.put(std::move(ecalTPGs));
193  iEvent.put(std::move(hcalTPGs));
194  iEvent.put(std::move(regions));
195 
196  event++;
197  if (verbose && event == 5)
198  LogDebug("L1TCaloLayer1") << "L1TCaloLayer1RawToDigi: Goodbye! Tired of printing junk" << endl;
199 }
200 
202  UCTCTP7RawData& ctp7Data,
203  std::unique_ptr<EcalTrigPrimDigiCollection>& ecalTPGs) {
205  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
206  int cPhi = -1 + lPhi * 4 + iPhi; // Calorimeter phi index
207  if (cPhi == 0)
208  cPhi = 72;
209  else if (cPhi == -1)
210  cPhi = 71;
211  else if (cPhi < -1) {
212  LogError("L1TCaloLayer1RawToDigi") << "L1TCaloLayer1RawToDigi: Major error in makeECalTPGs" << std::endl;
213  return;
214  }
215  for (int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
216  if (cEta != 0) { // Calorimeter eta = 0 is invalid
217  bool negativeEta = false;
218  if (cEta < 0)
219  negativeEta = true;
220  uint32_t iEta = abs(cEta);
221  // This code is fragile! Note that towerDatum is packed as is done in EcalTriggerPrimitiveSample
222  // Bottom 8-bits are ET
223  // Then finegrain feature bit
224  // Then three bits have ttBits, which I have no clue about (not available on ECAL links so not set)
225  // Then there is a spare FG Veto bit, which is used for L1 spike detection (not available on ECAL links so not set)
226  // Top three bits seem to be unused. So, we steal those to set the tower masking, link masking and link status information
227  // To decode these custom three bits use ((EcalTriggerPrimitiveSample::raw() >> 13) & 0x7)
228  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
229  if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
230  towerDatum |= 0x0100;
231  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
232  towerDatum |= 0x2000;
233  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
234  towerDatum |= 0x4000;
235  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
236  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
237  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
238  towerDatum |= 0x8000;
240  int zSide = cEta / ((int)iEta);
241  // As far as I can tell, the ECal unpacker only uses barrel and endcap IDs, never EcalTriggerTower
242  const EcalSubdetector ecalTriggerTower =
244  EcalTrigTowerDetId id(zSide, ecalTriggerTower, iEta, cPhi);
245  EcalTriggerPrimitiveDigi tpg(id);
246  tpg.setSize(1);
247  tpg.setSample(0, sample);
248  ecalTPGs->push_back(tpg);
249  }
250  }
251  }
252 }
253 
255  UCTCTP7RawData& ctp7Data,
256  std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs) {
258  for (uint32_t iPhi = 0; iPhi < 4; iPhi++) { // Loop over all four phi divisions on card
259  int cPhi = -1 + lPhi * 4 + iPhi; // Calorimeter phi index
260  if (cPhi == 0)
261  cPhi = 72;
262  else if (cPhi == -1)
263  cPhi = 71;
264  else if (cPhi < -1) {
265  LogError("L1TCaloLayer1RawToDigi") << "L1TCaloLayer1RawToDigi: Major error in makeHCalTPGs" << std::endl;
266  return;
267  }
268  for (int cEta = -28; cEta <= 28; cEta++) { // Calorimeter Eta indices (HB/HE for now)
269  if (cEta != 0) { // Calorimeter eta = 0 is invalid
270  bool negativeEta = false;
271  if (cEta < 0)
272  negativeEta = true;
273  uint32_t iEta = abs(cEta);
274  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
275  // Bottom 8-bits are ET
276  // Then feature bit
277  // The remaining bits are undefined presently
278  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
279  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
280  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
281  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
282  if (ctp7Data.getFB(cType, negativeEta, iEta, iPhi) != 0)
283  towerDatum |= 0x0100;
284  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
285  towerDatum |= 0x0200;
286  if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
287  towerDatum |= 0x0400;
288  if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
289  towerDatum |= 0x0800;
290  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
291  towerDatum |= 0x2000;
292  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
293  towerDatum |= 0x4000;
294  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
295  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
296  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
297  towerDatum |= 0x8000;
299  HcalTrigTowerDetId id(cEta, cPhi);
300  HcalTriggerPrimitiveDigi tpg(id);
301  tpg.setSize(1);
302  tpg.setSample(0, sample);
303  hcalTPGs->push_back(tpg);
304  }
305  }
306  }
307 }
308 
310  UCTCTP7RawData& ctp7Data,
311  std::unique_ptr<HcalTrigPrimDigiCollection>& hcalTPGs) {
313  for (uint32_t side = 0; side <= 1; side++) {
314  bool negativeEta = false;
315  if (side == 0)
316  negativeEta = true;
317  for (uint32_t iEta = 30; iEta <= 40; iEta++) {
318  for (uint32_t iPhi = 0; iPhi < 2; iPhi++) {
319  if (iPhi == 1 && iEta == 40)
320  iEta = 41;
321  int cPhi = 1 + lPhi * 4 + iPhi * 2; // Calorimeter phi index: 1, 3, 5, ... 71
322  if (iEta == 41)
323  cPhi -= 2; // Last two HF are 3, 7, 11, ...
324  cPhi = (cPhi + 69) % 72 + 1; // cPhi -= 2 mod 72
325  int cEta = iEta;
326  if (negativeEta)
327  cEta = -iEta;
328  // This code is fragile! Note that towerDatum is packed as is done in HcalTriggerPrimitiveSample
329  // Bottom 8-bits are ET
330  // Then feature bit
331  // Then minBias ADC count bit
332  // The remaining bits are undefined presently
333  // We use next three bits for link details, which we did not have room in EcalTriggerPrimitiveSample case
334  // We use next three bits to set the tower masking, link masking and link status information as done for Ecal
335  // To decode these custom six bits use ((EcalTriggerPrimitiveSample::raw() >> 9) & 0x77)
336  uint32_t towerDatum = ctp7Data.getET(cType, negativeEta, iEta, iPhi);
337  towerDatum |= ctp7Data.getFB(cType, negativeEta, iEta, iPhi) << 8;
338  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi))
339  towerDatum |= 0x0400;
340  if (ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi))
341  towerDatum |= 0x0800;
342  if (ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
343  towerDatum |= 0x1000;
344  if (ctp7Data.isTowerMasked(cType, negativeEta, iEta, iPhi))
345  towerDatum |= 0x2000;
346  if (ctp7Data.isLinkMasked(cType, negativeEta, iEta, iPhi))
347  towerDatum |= 0x4000;
348  if (ctp7Data.isLinkMisaligned(cType, negativeEta, iEta, iPhi) ||
349  ctp7Data.isLinkInError(cType, negativeEta, iEta, iPhi) ||
350  ctp7Data.isLinkDown(cType, negativeEta, iEta, iPhi))
351  towerDatum |= 0x8000;
353  HcalTrigTowerDetId id(cEta, cPhi);
354  id.setVersion(1); // To not process these 1x1 HF TPGs with RCT
355  HcalTriggerPrimitiveDigi tpg(id);
356  tpg.setSize(1);
357  tpg.setSample(0, sample);
358  hcalTPGs->push_back(tpg);
359  }
360  }
361  }
362 }
363 
365  UCTCTP7RawData& ctp7Data,
366  std::unique_ptr<L1CaloRegionCollection>& regions) {
367  for (uint32_t side = 0; side <= 1; side++) {
368  bool negativeEta = false;
369  if (side == 0)
370  negativeEta = true;
371  for (uint32_t region = 0; region <= 6; region++) {
372  uint32_t regionData = ctp7Data.getRegionSummary(negativeEta, region);
373  uint32_t lEta = 10 - region; // GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
374  if (!negativeEta)
375  lEta = region + 11;
376  regions->push_back(L1CaloRegion((uint16_t)regionData, (unsigned)lEta, (unsigned)lPhi, (int16_t)0));
377  }
378  }
379 }
380 
381 // ------------ method called once each stream before processing any runs, lumis or events ------------
383 
384 // ------------ method called once each stream after processing all runs, lumis and events ------------
386 
387 // ------------ method called when starting to processes a run ------------
388 /*
389  void
390  L1TCaloLayer1RawToDigi::beginRun(Run const&, EventSetup const&)
391  {
392  }
393 */
394 
395 // ------------ method called when ending the processing of a run ------------
396 /*
397  void
398  L1TCaloLayer1RawToDigi::endRun(Run const&, EventSetup const&)
399  {
400  }
401 */
402 
403 // ------------ method called when starting to processes a luminosity block ------------
404 /*
405  void
406  L1TCaloLayer1RawToDigi::beginLuminosityBlock(LuminosityBlock const&, EventSetup const&)
407  {
408  }
409 */
410 
411 // ------------ method called when ending the processing of a luminosity block ------------
412 /*
413  void
414  L1TCaloLayer1RawToDigi::endLuminosityBlock(LuminosityBlock const&, EventSetup const&)
415  {
416  }
417 */
418 
419 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
421  //The following says we do not know what parameters are allowed so do no validation
422  // Please change this to state exactly what you do use, even if it is no parameters
424  desc.setUnknown();
425  descriptions.addDefault(desc);
426 }
427 
428 //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
void beginStream(StreamID) override
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)