CMS 3D CMS Logo

L1TCaloLayer1.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1Trigger/L1TCaloLayer1
4 // Class: L1TCaloLayer1
5 //
13 //
14 // Original Author: Sridhara Rao Dasu
15 // Created: Thu, 08 Oct 2015 09:20:16 GMT
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
25 
28 
30 
33 
34 #include "L1Trigger/L1TCaloLayer1/src/UCTLayer1.hh"
35 #include "L1Trigger/L1TCaloLayer1/src/UCTCrate.hh"
36 #include "L1Trigger/L1TCaloLayer1/src/UCTCard.hh"
37 #include "L1Trigger/L1TCaloLayer1/src/UCTRegion.hh"
38 #include "L1Trigger/L1TCaloLayer1/src/UCTTower.hh"
39 
40 #include "L1Trigger/L1TCaloLayer1/src/UCTGeometry.hh"
41 #include "L1Trigger/L1TCaloLayer1/src/UCTLogging.hh"
42 
46 
48 
49 #include "L1Trigger/L1TCaloLayer1/src/L1TCaloLayer1FetchLUTs.hh"
50 
51 using namespace l1t;
52 using namespace l1tcalo;
53 
54 //
55 // class declaration
56 //
57 
59 public:
60  explicit L1TCaloLayer1(const edm::ParameterSet&);
61 
62  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
63 
64 private:
65  void produce(edm::Event&, const edm::EventSetup&) override;
66 
67  void beginRun(edm::Run const&, edm::EventSetup const&) override;
68 
69  //virtual void endRun(edm::Run const&, edm::EventSetup const&) override;
70  //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
71  //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
72 
73  // ----------member data ---------------------------
74 
79  const L1TCaloLayer1FetchLUTsTokens lutsTokens;
80 
81  std::vector<std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> > ecalLUT;
82  std::vector<std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> > hcalLUT;
83  std::vector<std::array<std::array<uint32_t, nEtBins>, nHfEtaBins> > hfLUT;
84  std::vector<unsigned long long int> hcalFBLUT;
85 
86  std::vector<unsigned int> ePhiMap;
87  std::vector<unsigned int> hPhiMap;
88  std::vector<unsigned int> hfPhiMap;
89 
90  std::vector<UCTTower*> twrList;
91 
92  bool useLSB;
93  bool useCalib;
94  bool useECALLUT;
95  bool useHCALLUT;
96  bool useHFLUT;
98  bool verbose;
102 
103  std::unique_ptr<UCTLayer1> layer1;
104 };
105 
106 //
107 // constants, enums and typedefs
108 //
109 
110 //
111 // static data member definitions
112 //
113 
114 //
115 // constructors and destructor
116 //
118  : ecalTPSource(consumes<EcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("ecalToken"))),
119  hcalTPSource(consumes<HcalTrigPrimDigiCollection>(iConfig.getParameter<edm::InputTag>("hcalToken"))),
120  towerPutToken{produces<CaloTowerBxCollection>()},
121  regionPutToken{produces<L1CaloRegionCollection>()},
122  lutsTokens{esConsumes<edm::Transition::BeginRun>(),
123  esConsumes<edm::Transition::BeginRun>(),
124  esConsumes<edm::Transition::BeginRun>()},
125  ePhiMap(72 * 2, 0),
126  hPhiMap(72 * 2, 0),
127  hfPhiMap(72 * 2, 0),
128  useLSB(iConfig.getParameter<bool>("useLSB")),
129  useCalib(iConfig.getParameter<bool>("useCalib")),
130  useECALLUT(iConfig.getParameter<bool>("useECALLUT")),
131  useHCALLUT(iConfig.getParameter<bool>("useHCALLUT")),
132  useHFLUT(iConfig.getParameter<bool>("useHFLUT")),
133  useHCALFBLUT(iConfig.getParameter<bool>("useHCALFBLUT")),
134  verbose(iConfig.getUntrackedParameter<bool>("verbose")),
135  unpackHcalMask(iConfig.getParameter<bool>("unpackHcalMask")),
136  unpackEcalMask(iConfig.getParameter<bool>("unpackEcalMask")),
137  fwVersion(iConfig.getParameter<int>("firmwareVersion")) {
138  // See UCTLayer1.hh for firmware version definitions
139  layer1 = std::make_unique<UCTLayer1>(fwVersion);
140 
141  vector<UCTCrate*> crates = layer1->getCrates();
142  for (uint32_t crt = 0; crt < crates.size(); crt++) {
143  vector<UCTCard*> cards = crates[crt]->getCards();
144  for (uint32_t crd = 0; crd < cards.size(); crd++) {
145  vector<UCTRegion*> regions = cards[crd]->getRegions();
146  for (uint32_t rgn = 0; rgn < regions.size(); rgn++) {
147  vector<UCTTower*> towers = regions[rgn]->getTowers();
148  for (uint32_t twr = 0; twr < towers.size(); twr++) {
149  twrList.push_back(towers[twr]);
150  }
151  }
152  }
153  }
154 
155  // This sort corresponds to the sort condition on
156  // the output CaloTowerBxCollection
157  std::sort(twrList.begin(), twrList.end(), [](UCTTower* a, UCTTower* b) {
158  return CaloTools::caloTowerHash(a->caloEta(), a->caloPhi()) < CaloTools::caloTowerHash(b->caloEta(), b->caloPhi());
159  });
160 }
161 
162 //
163 // member functions
164 //
165 
166 // ------------ method called to produce the data ------------
168  using namespace edm;
169 
171  iEvent.getByToken(ecalTPSource, ecalTPs);
173  iEvent.getByToken(hcalTPSource, hcalTPs);
174 
175  CaloTowerBxCollection towersColl;
176  L1CaloRegionCollection rgnCollection;
177 
178  if (!layer1->clearEvent()) {
179  LOG_ERROR << "UCT: Failed to clear event" << std::endl;
180  return;
181  }
182 
183  for (const auto& ecalTp : *ecalTPs) {
184  if (unpackEcalMask && ((ecalTp.sample(0).raw() >> 13) & 0x1))
185  continue;
186  int caloEta = ecalTp.id().ieta();
187  int caloPhi = ecalTp.id().iphi();
188  int et = ecalTp.compressedEt();
189  bool fgVeto = ecalTp.fineGrain();
190  UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
191  if (!layer1->setECALData(t, fgVeto, et)) {
192  LOG_ERROR << "UCT: Failed loading an ECAL tower" << std::endl;
193  return;
194  }
195  }
196 
197  if (hcalTPs.isValid()) {
198  for (const auto& hcalTp : *hcalTPs) {
199  if (unpackHcalMask && ((hcalTp.sample(0).raw() >> 13) & 0x1))
200  continue;
201  int caloEta = hcalTp.id().ieta();
202  uint32_t absCaloEta = std::abs(caloEta);
203  // Tower 29 is not used by Layer-1
204  if (absCaloEta == 29) {
205  continue;
206  }
207  // Prevent usage of HF TPs with Layer-1 emulator if HCAL TPs are old style
208  else if (hcalTp.id().version() == 0 && absCaloEta > 29) {
209  continue;
210  } else if (absCaloEta <= 41) {
211  int caloPhi = hcalTp.id().iphi();
212  int et = hcalTp.SOI_compressedEt();
213  bool fg = hcalTp.t0().fineGrain(0); // depth
214  bool fg2 = hcalTp.t0().fineGrain(1); // prompt
215  bool fg3 = hcalTp.t0().fineGrain(2); // delay 1
216  bool fg4 = hcalTp.t0().fineGrain(3); // delay 2
217  // note that hcalTp.t0().fineGrain(4) and hcalTp.t0().fineGrain(5) are the reserved MIP bits (not used for LLP logic)
218  if (caloPhi <= 72) {
219  UCTTowerIndex t = UCTTowerIndex(caloEta, caloPhi);
220  uint32_t featureBits = 0;
221  if (absCaloEta > 29) {
222  if (fg)
223  featureBits |= 0b01;
224  // fg2 should only be set for HF
225  if (fg2)
226  featureBits |= 0b10;
227  } else if (absCaloEta < 16)
228  featureBits |= (fg | ((!fg2) & (fg3 | fg4))); // depth | (!prompt & (delay1 | delay2))
229  if (!layer1->setHCALData(t, featureBits, et)) {
230  LOG_ERROR << "caloEta = " << caloEta << "; caloPhi =" << caloPhi << std::endl;
231  LOG_ERROR << "UCT: Failed loading an HCAL tower" << std::endl;
232  return;
233  }
234  } else {
235  LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << "; caloPhi =" << caloPhi << "; et = " << et
236  << std::endl;
237  }
238  } else {
239  LOG_ERROR << "Illegal Tower: caloEta = " << caloEta << std::endl;
240  }
241  }
242  }
243 
244  //Process
245  if (!layer1->process()) {
246  LOG_ERROR << "UCT: Failed to process layer 1" << std::endl;
247  }
248 
249  int theBX = 0; // Currently we only read and process the "hit" BX only
250 
251  for (uint32_t twr = 0; twr < twrList.size(); twr++) {
252  CaloTower caloTower;
253  caloTower.setHwPt(twrList[twr]->et()); // Bits 0-8 of the 16-bit word per the interface protocol document
254  caloTower.setHwEtRatio(twrList[twr]->er()); // Bits 9-11 of the 16-bit word per the interface protocol document
255  caloTower.setHwQual(twrList[twr]->miscBits()); // Bits 12-15 of the 16-bit word per the interface protocol document
256  caloTower.setHwEta(twrList[twr]->caloEta()); // caloEta = 1-28 and 30-41
257  caloTower.setHwPhi(twrList[twr]->caloPhi()); // caloPhi = 1-72
258  caloTower.setHwEtEm(twrList[twr]->getEcalET()); // This is provided as a courtesy - not available to hardware
259  caloTower.setHwEtHad(twrList[twr]->getHcalET()); // This is provided as a courtesy - not available to hardware
260  towersColl.push_back(theBX, caloTower);
261  }
262 
263  iEvent.emplace(towerPutToken, std::move(towersColl));
264 
265  UCTGeometry g;
266  vector<UCTCrate*> crates = layer1->getCrates();
267  for (uint32_t crt = 0; crt < crates.size(); crt++) {
268  vector<UCTCard*> cards = crates[crt]->getCards();
269  for (uint32_t crd = 0; crd < cards.size(); crd++) {
270  vector<UCTRegion*> regions = cards[crd]->getRegions();
271  for (uint32_t rgn = 0; rgn < regions.size(); rgn++) {
272  uint32_t rawData = regions[rgn]->rawData();
273  uint32_t regionData = rawData & 0x0000FFFF;
274  uint32_t crate = regions[rgn]->getCrate();
275  uint32_t card = regions[rgn]->getCard();
276  uint32_t region = regions[rgn]->getRegion();
277  bool negativeEta = regions[rgn]->isNegativeEta();
278  uint32_t rPhi = g.getUCTRegionPhiIndex(crate, card);
279  if (region < NRegionsInCard) { // We only store the Barrel and Endcap - HF has changed in the upgrade
280  uint32_t rEta =
281  10 -
282  region; // UCT region is 0-6 for B/E but GCT eta goes 0-21, 0-3 -HF, 4-10 -B/E, 11-17 +B/E, 18-21 +HF
283  if (!negativeEta)
284  rEta = 11 + region; // Positive eta portion is offset by 11
285  rgnCollection.push_back(L1CaloRegion((uint16_t)regionData, (unsigned)rEta, (unsigned)rPhi, (int16_t)0));
286  }
287  }
288  }
289  }
290  iEvent.emplace(regionPutToken, std::move(rgnCollection));
291 }
292 
293 // ------------ method called when starting to processes a run ------------
294 void L1TCaloLayer1::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
296  iSetup,
297  ecalLUT,
298  hcalLUT,
299  hfLUT,
300  hcalFBLUT,
301  ePhiMap,
302  hPhiMap,
303  hfPhiMap,
304  useLSB,
305  useCalib,
306  useECALLUT,
307  useHCALLUT,
308  useHFLUT,
309  useHCALFBLUT,
310  fwVersion)) {
311  LOG_ERROR << "L1TCaloLayer1::beginRun: failed to fetch LUTS - using unity" << std::endl;
312  std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> eCalLayer1EtaSideEtArray;
313  std::array<std::array<std::array<uint32_t, nEtBins>, nCalSideBins>, nCalEtaBins> hCalLayer1EtaSideEtArray;
314  std::array<std::array<uint32_t, nEtBins>, nHfEtaBins> hfLayer1EtaEtArray;
315  ecalLUT.push_back(eCalLayer1EtaSideEtArray);
316  hcalLUT.push_back(hCalLayer1EtaSideEtArray);
317  hfLUT.push_back(hfLayer1EtaEtArray);
318  }
319  for (uint32_t twr = 0; twr < twrList.size(); twr++) {
320  // Map goes minus 1 .. 72 plus 1 .. 72 -> 0 .. 143
321  int iphi = twrList[twr]->caloPhi();
322  int ieta = twrList[twr]->caloEta();
323  if (ieta < 0) {
324  iphi -= 1;
325  } else {
326  iphi += 71;
327  }
328  twrList[twr]->setECALLUT(&ecalLUT[ePhiMap[iphi]]);
329  twrList[twr]->setHCALLUT(&hcalLUT[hPhiMap[iphi]]);
330  twrList[twr]->setHFLUT(&hfLUT[hfPhiMap[iphi]]);
331  }
332 }
333 
334 // ------------ method called when ending the processing of a run ------------
335 /*
336  void
337  L1TCaloLayer1::endRun(edm::Run const&, edm::EventSetup const&)
338  {
339  }
340 */
341 
342 // ------------ method called when starting to processes a luminosity block ------------
343 /*
344  void
345  L1TCaloLayer1::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
346  {
347  }
348 */
349 
350 // ------------ method called when ending the processing of a luminosity block ------------
351 /*
352  void
353  L1TCaloLayer1::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
354  {
355  }
356 */
357 
358 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
360  //Description set to reflect default present in simCaloStage2Layer1Digis_cfi.py
361  //Currently redundant, but could be adjusted to provide defaults in case additional LUT
362  //checks are added and before other configurations adjust to match.
364  desc.add<edm::InputTag>("ecalToken", edm::InputTag("simEcalTriggerPrimitiveDigis"));
365  desc.add<edm::InputTag>("hcalToken", edm::InputTag("simHcalTriggerPrimitiveDigis"));
366  desc.add<bool>("useLSB", true);
367  desc.add<bool>("useCalib", true);
368  desc.add<bool>("useECALLUT", true);
369  desc.add<bool>("useHCALLUT", true);
370  desc.add<bool>("useHFLUT", true);
371  desc.add<bool>("useHCALFBLUT", false);
372  desc.addUntracked<bool>("verbose", false);
373  desc.add<bool>("unpackEcalMask", false);
374  desc.add<bool>("unpackHcalMask", false);
375  desc.add<int>("firmwareVersion", 1);
376  descriptions.addDefault(desc);
377 }
378 
379 //define this as a plug-in
381 /* vim: set ts=8 sw=2 tw=0 et :*/
std::vector< std::array< std::array< uint32_t, nEtBins >, nHfEtaBins > > hfLUT
std::vector< unsigned int > hfPhiMap
bool verbose
edm::EDGetTokenT< HcalTrigPrimDigiCollection > hcalTPSource
void setHwQual(int qual)
Definition: L1Candidate.h:31
delete x;
Definition: CaloConfig.h:22
std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > ecalLUT
std::vector< unsigned long long int > hcalFBLUT
void setHwEtHad(int et)
Definition: CaloTower.cc:29
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
std::unique_ptr< UCTLayer1 > layer1
edm::EDPutTokenT< L1CaloRegionCollection > regionPutToken
void produce(edm::Event &, const edm::EventSetup &) override
int iEvent
Definition: GenABIO.cc:224
void addDefault(ParameterSetDescription const &psetDescription)
std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > hcalLUT
std::vector< UCTTower * > twrList
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void setHwEtRatio(int ratio)
Definition: CaloTower.cc:31
edm::EDGetTokenT< EcalTrigPrimDigiCollection > ecalTPSource
void setHwPhi(int phi)
Definition: L1Candidate.h:30
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const L1TCaloLayer1FetchLUTsTokens lutsTokens
double b
Definition: hdecay.h:120
edm::EDPutTokenT< CaloTowerBxCollection > towerPutToken
std::vector< unsigned int > hPhiMap
bool isValid() const
Definition: HandleBase.h:70
L1TCaloLayer1(const edm::ParameterSet &)
HLT enums.
void setHwPt(int pt)
Definition: L1Candidate.h:28
double a
Definition: hdecay.h:121
void beginRun(edm::Run const &, edm::EventSetup const &) override
A calorimeter trigger region (sum of 4x4 trigger towers)
Definition: L1CaloRegion.h:21
void setHwEta(int eta)
Definition: L1Candidate.h:29
std::vector< L1CaloRegion > L1CaloRegionCollection
void setHwEtEm(int et)
Definition: CaloTower.cc:27
bool L1TCaloLayer1FetchLUTs(const L1TCaloLayer1FetchLUTsTokens &iTokens, const edm::EventSetup &iSetup, std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &eLUT, std::vector< std::array< std::array< std::array< uint32_t, nEtBins >, nCalSideBins >, nCalEtaBins > > &hLUT, std::vector< std::array< std::array< uint32_t, nEtBins >, nHfEtaBins > > &hfLUT, std::vector< unsigned long long int > &hcalFBLUT, std::vector< unsigned int > &ePhiMap, std::vector< unsigned int > &hPhiMap, std::vector< unsigned int > &hfPhiMap, bool useLSB, bool useCalib, bool useECALLUT, bool useHCALLUT, bool useHFLUT, bool useHCALFBLUT, int fwVersion)
std::vector< unsigned int > ePhiMap
def move(src, dest)
Definition: eostools.py:511
#define LOG_ERROR
Definition: CSCDQM_Logger.h:40
Definition: Run.h:45
void push_back(int bx, T object)