CMS 3D CMS Logo

L1TStage2Layer1Producer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: L1Trigger/skeleton
4 // Class: skeleton
5 //
13 //
14 // Original Author: James Brooke
15 // Created: Thu, 05 Dec 2013 17:39:27 GMT
16 //
17 //
18 
19 
20 // system include files
21 #include <memory>
22 
23 // user include files
24 
35 
38 
41 
46 
49 
52 
54 
56 
57 //
58 // class declaration
59 //
60 
61 using namespace l1t;
62 
63 
65  public:
66  explicit L1TStage2Layer1Producer(const edm::ParameterSet& ps);
67  ~L1TStage2Layer1Producer() override;
68 
69  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions)
70  ;
71 
72  private:
73  void beginJob() override;
74  void produce(edm::Event&, const edm::EventSetup&) override;
75  void endJob() override;
76 
77  void beginRun(edm::Run const&, edm::EventSetup const&) override;
78  void endRun(edm::Run const&, edm::EventSetup const&) override;
79  //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
80  //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
81 
82  // ----------member data ---------------------------
83 
86 
87  int bxFirst_, bxLast_; // bx range to process
88 
89  std::vector<edm::EDGetToken> ecalToken_; // this is a crazy way to store multi-BX info
90  std::vector<edm::EDGetToken> hcalToken_; // should be replaced with a BXVector< > or similar
91 
92  // parameters
93  unsigned long long paramsCacheId_;
94  unsigned fwv_;
96 
97  // the processor
99  std::shared_ptr<Stage2PreProcessor> processor_;
100 
101  };
102 
103 
104 
106  verbosity_(ps.getParameter<int>("verbosity")),
107  rctConditions_(ps.getParameter<bool>("rctConditions")),
108  bxFirst_(ps.getParameter<int>("bxFirst")),
109  bxLast_(ps.getParameter<int>("bxLast")),
110  ecalToken_(bxLast_+1-bxFirst_),
111  hcalToken_(bxLast_+1-bxFirst_),
112  paramsCacheId_(0),
113  params_(nullptr)
114 {
115 
116  // register what you produce
117  produces<CaloTowerBxCollection> ();
118 
119  // register what you consume and keep token for later access:
120  for (int ibx=0; ibx<bxLast_+1-bxFirst_; ibx++) {
121  ecalToken_[ibx] = consumes<EcalTrigPrimDigiCollection>(ps.getParameter<edm::InputTag>("ecalToken"));
122  hcalToken_[ibx] = consumes<HcalTrigPrimDigiCollection>(ps.getParameter<edm::InputTag>("hcalToken"));
123  }
124 
125  // placeholder for the parameters
127 
128  // set firmware version from python config for now
129  fwv_ = ps.getParameter<int>("firmware");
130 
131 }
132 
134 
135  delete params_;
136 
137 }
138 
139 // ------------ method called to produce the data ------------
140 void
142 {
143 
144  LogDebug("l1t|stage 2") << "L1TStage2Layer1Producer::produce function called..." << std::endl;
145 
146  // do event setup
147  // get RCT input scale objects
150 
152 
153  if (rctConditions_) {
154  iSetup.get<L1CaloEcalScaleRcd>().get(ecalScale);
155  iSetup.get<L1CaloHcalScaleRcd>().get(hcalScale);
156  }
157  else {
158  iSetup.get<CaloTPGRecord>().get(decoder);
159  }
160 
161 
162  LogDebug("L1TDebug") << "First BX=" << bxFirst_ << ", last BX=" << bxLast_ << ", LSB(E)=" << params_->towerLsbE() << ", LSB(H)=" << params_->towerLsbH() << std::endl;
163 
164 
165  // output collection
166  std::unique_ptr<CaloTowerBxCollection> towersColl (new CaloTowerBxCollection);
167 
168 
169  // loop over crossings
170  for (int bx = bxFirst_; bx < bxLast_+1; ++bx) {
171 
172  int ibx = bx-bxFirst_;
173 
176 
177  iEvent.getByToken(hcalToken_[ibx], hcalTPs);
178  iEvent.getByToken(ecalToken_[ibx], ecalTPs);
179 
180  // create input and output tower vectors for this BX
181  std::unique_ptr< std::vector<CaloTower> > localInTowers (new std::vector<CaloTower>(CaloTools::caloTowerHashMax()+1));
182  std::unique_ptr< std::vector<CaloTower> > localOutTowers (new std::vector<CaloTower>()); //this is later filled to the same size as localInTowers
183 
184  // loop over ECAL TPs
186  int nEcal=0;
187  for (ecalItr=ecalTPs->begin(); ecalItr!=ecalTPs->end(); ++ecalItr, ++nEcal) {
188 
189  int ieta = ecalItr->id().ieta();
190  int iphi = ecalItr->id().iphi();
191 
192  int ietIn = ecalItr->compressedEt();
193  bool ifg = ecalItr->fineGrain();
194 
195  // decompress
196  double et = 0.;
197  if (rctConditions_) {
198  et = ecalScale->et( ietIn, abs(ieta), (ieta>0) );
199  }
200  else {
201  et = 0.5 * ietIn;
202  }
203 
204  int ietOut = floor( et / params_->towerLsbE() );
205 
206 
207  int itow = CaloTools::caloTowerHash(ieta, iphi);
208  localInTowers->at(itow).setHwEtEm(ietOut);
209  localInTowers->at(itow).setHwQual( localInTowers->at(itow).hwQual() | (ifg ? 0x8 : 0x0) ); //ECAL FG bit is supposed to be on bit 3
210 
211  }
212 
213  // loop over HCAL TPs
215  int nHcal=0;
216  for (hcalItr=hcalTPs->begin(); hcalItr!=hcalTPs->end(); ++hcalItr, ++nHcal) {
217 
218  int ieta = hcalItr->id().ieta();
219  int iphi = hcalItr->id().iphi();
220  int ver = hcalItr->id().version();
221 
222  // check for old HF TPs
223  if (abs(ieta)>=CaloTools::kHFBegin && ver!=1) continue;
224 
225  int ietIn = hcalItr->SOI_compressedEt();
226  int ifg = hcalItr->SOI_fineGrain();
227 
228  // decompress
229  double et = 0.;
230 
231  if (rctConditions_) {
232  if (abs(ieta) >= CaloTools::kHFBegin)
233  et = hcalScale->et( ietIn, CaloTools::kHFBegin, (ieta>0) );
234  else
235  et = hcalScale->et( ietIn, abs(ieta), (ieta>0) );
236  }
237  else {
238  et = decoder->hcaletValue(hcalItr->id(), hcalItr->t0());
239  }
240 
241  int ietOut = floor( et / params_->towerLsbH() );
242 
243  // get tower index
244  unsigned itow = CaloTools::caloTowerHash(ieta, iphi);
245 
246  if (ietOut>0)
247  LogDebug("L1TDebug") << " HCAL TP : " << ieta << ", " << iphi << ", " << ietIn << ", " << et << ", " << ietOut << ", " << itow << ", " << CaloTools::caloTowerHashMax() << ", " << localInTowers->size() << std::endl;
248 
249  localInTowers->at(itow).setHwEtHad(ietOut);
250  localInTowers->at(itow).setHwQual( localInTowers->at(itow).hwQual() | (ifg ? 0x4 : 0x0) ); //HCAL FG bit is supposed to be on bit 2
251 
252  }
253 
254  // now calculate remaining tower quantities
255  for (int ieta=-1*CaloTools::kHFEnd; ieta<=CaloTools::kHFEnd; ieta++) {
256 
257  for (int iphi=0; iphi<=CaloTools::kHBHENrPhi; iphi++) {
258 
259  if(!CaloTools::isValidIEtaIPhi(ieta,iphi)) continue;
260 
261  unsigned itow = CaloTools::caloTowerHash(ieta, iphi);
262 
263  // get ECAL/HCAL raw numbers
264  int ietEcal = localInTowers->at(itow).hwEtEm();
265  int ietHcal = localInTowers->at(itow).hwEtHad();
266 
267  int iet = ietEcal + ietHcal;
268 
269  if (ietHcal>0)
270  LogDebug("L1TDebug") << " L1Tow : " << ieta << ", " << iphi << ", " << itow << ", " << iet << ", " << ietEcal << ", " << ietHcal << std::endl;
271 
272  localInTowers->at(itow).setHwPt(iet);
273  localInTowers->at(itow).setHwEta(ieta);
274  localInTowers->at(itow).setHwPhi(iphi);
275 
276  int ietby2 = round( double(ietHcal) / 2. );
277  int ietby4 = round( double(ietHcal) / 4. );
278 
279  // if HF, divide energy by two and give half to adjacent tower
280  if ( abs(ieta)>29 && iphi % 2 == 1) {
281  localInTowers->at(itow).setHwPt(ietby2);
282  localInTowers->at(itow).setHwEtHad(ietby2);
283  int itow_next = CaloTools::caloTowerHash(ieta, iphi+1);
284  localInTowers->at(itow_next).setHwPt(ietby2);
285  localInTowers->at(itow_next).setHwEtHad(ietby2);
286  }
287 
288  if (abs(ieta)>39 && iphi % 4 == 3) {
289  localInTowers->at(itow).setHwPt(ietby4);
290  localInTowers->at(itow).setHwEtHad(ietby4);
291  int itow_next = CaloTools::caloTowerHash(ieta, iphi+1);
292  localInTowers->at(itow_next).setHwPt(ietby4);
293  localInTowers->at(itow_next).setHwEtHad(ietby4);
294  itow_next = CaloTools::caloTowerHash(ieta, iphi-1);
295  localInTowers->at(itow_next).setHwPt(ietby4);
296  localInTowers->at(itow_next).setHwEtHad(ietby4);
297  itow_next = CaloTools::caloTowerHash(ieta, iphi-2);
298  localInTowers->at(itow_next).setHwPt(ietby4);
299  localInTowers->at(itow_next).setHwEtHad(ietby4);
300  }
301 
302  }
303  }
304 
305  // for(std::vector<CaloTower>::const_iterator tower = localInTowers->begin();
306  // tower != localInTowers->end();
307  // ++tower) {
308  // if (tower->hwEta()>30) std::cout << "HF in : " << tower->hwEta() << "," << tower->hwPhi() << "," << tower->hwPt() << "," << tower->hwEtHad() << std::endl;
309  // }
310 
311 
312  // do the decompression
313  processor_->processEvent(*localInTowers, *localOutTowers);
314 
315  // copy towers to output collection
316  for(std::vector<CaloTower>::const_iterator tower = localOutTowers->begin();
317  tower != localOutTowers->end();
318  ++tower) {
319  // if (tower->hwEta()>30) std::cout << "HF out : " << tower->hwEta() << "," << tower->hwPhi() << "," << tower->hwPt() << "," << tower->etHad() << std::endl;
320  towersColl->push_back(ibx, *tower);
321  }
322  LogDebug("L1TDebug") << "BX=" << ibx << ", N(Tower in)=" << localInTowers->size() << ", N(Tower out)=" << localOutTowers->size() << std::endl;
323 
324  }
325 
326  iEvent.put(std::move(towersColl));
327 
328 }
329 
330 // ------------ method called once each job just before starting event loop ------------
331 void
333 {
334 }
335 
336 // ------------ method called once each job just after ending the event loop ------------
337 void
339 }
340 
341 // ------------ method called when starting to processes a run ------------
342 void
344 {
345 
346  // update parameters and algorithms at run start, if they have changed
347  // update params first because the firmware factory relies on pointer to params
348 
349  // parameters
350 
351  unsigned long long id = iSetup.get<L1TCaloParamsRcd>().cacheIdentifier();
352 
353  if (id != paramsCacheId_) {
354 
355  paramsCacheId_ = id;
356 
357  edm::ESHandle<CaloParams> paramsHandle;
358  iSetup.get<L1TCaloParamsRcd>().get(paramsHandle);
359 
360  // replace our local copy of the parameters with a new one using placement new
362  params_ = new (params_) CaloParamsHelper(*paramsHandle.product());
363 
364  LogDebug("L1TDebug") << *params_ << std::endl;
365 
366  if (! params_){
367  edm::LogError("l1t|caloStage2") << "Could not retrieve params from Event Setup" << std::endl;
368  }
369 
370  }
371 
372  // firmware
373 
374  if ( !processor_ ) { // in future, also check if the firmware cache ID has changed !
375 
376  // m_fwv = ; // get new firmware version in future
377 
378  // Set the current algorithm version based on DB pars from database:
380 
381  LogDebug("L1TDebug") << "Processor object : " << (processor_?1:0) << std::endl;
382 
383  if (! processor_) {
384  // we complain here once per run
385  edm::LogError("l1t|caloStage2") << "Layer 1 firmware could not be configured.\n";
386  }
387 
388  }
389 
390 
391 }
392 
393 
394 // ------------ method called when ending the processing of a run ------------
395 void
397 {
398 }
399 
400 // ------------ method called when starting to processes a luminosity block ------------
401 /*
402 void
403 L1TStage2Layer1Producer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup cons
404 t&)
405 {
406 }
407 */
408 
409 // ------------ method called when ending the processing of a luminosity block ------------
410 /*
411 void
412 L1TStage2Layer1Producer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&
413 )
414 {
415 }
416 */
417 
418 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
419 void
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
#define LogDebug(id)
T getParameter(std::string const &) const
std::vector< edm::EDGetToken > ecalToken_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
#define nullptr
std::vector< T >::const_iterator const_iterator
delete x;
Definition: CaloConfig.h:22
double et(unsigned short rank, unsigned short eta, short etaSign) const
convert from rank to physically meaningful quantity
void beginJob()
Definition: Breakpoints.cc:14
L1TStage2Layer1Producer(const edm::ParameterSet &ps)
ReturnType create(unsigned fwv, CaloParamsHelper const *params)
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void addDefault(ParameterSetDescription const &psetDescription)
Stage2Layer1FirmwareFactory factory_
double et(unsigned short rank, unsigned short eta, short etaSign) const
convert from rank to physically meaningful quantity
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::shared_ptr< Stage2PreProcessor > processor_
std::vector< edm::EDGetToken > hcalToken_
const_iterator end() const
void beginRun(edm::Run const &, edm::EventSetup const &) override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
et
define resolution functions of each parameter
void endRun(edm::Run const &, edm::EventSetup const &) override
T get() const
Definition: EventSetup.h:71
double towerLsbE() const
virtual double hcaletValue(const int &ieta, const int &iphi, const int &version, const int &compressedValue) const =0
void produce(edm::Event &, const edm::EventSetup &) override
T const * product() const
Definition: ESHandle.h:86
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
def move(src, dest)
Definition: eostools.py:511
const_iterator begin() const
Definition: Run.h:45
double towerLsbH() const