CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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&);
73 
74  static void fillDescriptions(ConfigurationDescriptions& descriptions);
75 
76 private:
77  virtual void beginStream(StreamID) override;
78  virtual void produce(Event&, const EventSetup&) override;
79  virtual 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  LogError("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)
int i
Definition: DBlmapReader.cc:9
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:122
#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
void addDefault(ParameterSetDescription const &psetDescription)
void setSample(int i, const EcalTriggerPrimitiveSample &sam)
def move
Definition: eostools.py:510
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
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:413
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)
static void fillDescriptions(ConfigurationDescriptions &descriptions)
virtual void endStream() override
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
virtual 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
virtual void beginStream(StreamID) override
bool isLinkMisaligned(CaloType cType, bool negativeEta, uint32_t cEta, uint32_t iPhi)