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