Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:54:52

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/skeleton
0004 // Class:      skeleton
0005 //
0006 /**\class skeleton skeleton.cc L1Trigger/skeleton/plugins/skeleton.cc
0007 
0008  Description: [one line class summary]
0009 
0010  Implementation:
0011      [Notes on implementation]
0012 */
0013 //
0014 // Original Author:  James Brooke
0015 //         Created:  Thu, 05 Dec 2013 17:39:27 GMT
0016 //
0017 //
0018 
0019 // system include files
0020 #include <memory>
0021 
0022 // user include files
0023 
0024 #include "FWCore/Framework/interface/EventSetup.h"
0025 #include "FWCore/Framework/interface/Frameworkfwd.h"
0026 #include "FWCore/Framework/interface/stream/EDProducer.h"
0027 #include "FWCore/Framework/interface/ESHandle.h"
0028 #include "FWCore/Framework/interface/Event.h"
0029 #include "FWCore/Framework/interface/MakerMacros.h"
0030 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0031 #include "FWCore/Utilities/interface/EDGetToken.h"
0032 #include "FWCore/Utilities/interface/InputTag.h"
0033 #include "FWCore/Utilities/interface/ESGetToken.h"
0034 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0035 
0036 #include "L1Trigger/L1TCalorimeter/interface/Stage2Layer1FirmwareFactory.h"
0037 #include "L1Trigger/L1TCalorimeter/interface/Stage2PreProcessor.h"
0038 
0039 #include "L1Trigger/L1TCalorimeter/interface/CaloParamsHelper.h"
0040 #include "CondFormats/DataRecord/interface/L1TCaloParamsRcd.h"
0041 
0042 #include "CondFormats/L1TObjects/interface/L1CaloEcalScale.h"
0043 #include "CondFormats/DataRecord/interface/L1CaloEcalScaleRcd.h"
0044 #include "CondFormats/L1TObjects/interface/L1CaloHcalScale.h"
0045 #include "CondFormats/DataRecord/interface/L1CaloHcalScaleRcd.h"
0046 
0047 #include "CalibFormats/CaloTPG/interface/CaloTPGTranscoder.h"
0048 #include "CalibFormats/CaloTPG/interface/CaloTPGRecord.h"
0049 
0050 #include "DataFormats/EcalDigi/interface/EcalDigiCollections.h"
0051 #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
0052 
0053 #include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
0054 
0055 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0056 
0057 //
0058 // class declaration
0059 //
0060 
0061 using namespace l1t;
0062 
0063 class L1TStage2Layer1Producer : public edm::stream::EDProducer<> {
0064 public:
0065   explicit L1TStage2Layer1Producer(const edm::ParameterSet& ps);
0066   ~L1TStage2Layer1Producer() override;
0067 
0068   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0069 
0070 private:
0071   void produce(edm::Event&, const edm::EventSetup&) override;
0072 
0073   void beginRun(edm::Run const&, edm::EventSetup const&) override;
0074   void endRun(edm::Run const&, edm::EventSetup const&) override;
0075   //virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0076   //virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0077 
0078   // ----------member data ---------------------------
0079 
0080   int verbosity_;
0081   bool rctConditions_;
0082 
0083   int bxFirst_, bxLast_;  // bx range to process
0084 
0085   std::vector<edm::EDGetToken> ecalToken_;  // this is a crazy way to store multi-BX info
0086   std::vector<edm::EDGetToken> hcalToken_;  // should be replaced with a BXVector< > or similar
0087 
0088   edm::ESGetToken<L1CaloEcalScale, L1CaloEcalScaleRcd> ecalScaleToken_;
0089   edm::ESGetToken<L1CaloHcalScale, L1CaloHcalScaleRcd> hcalScaleToken_;
0090   edm::ESGetToken<CaloTPGTranscoder, CaloTPGRecord> decoderToken_;
0091   edm::ESGetToken<CaloParams, L1TCaloParamsRcd> paramsToken_;
0092   // parameters
0093   unsigned long long paramsCacheId_;
0094   unsigned fwv_;
0095   CaloParamsHelper* params_;
0096 
0097   // the processor
0098   Stage2Layer1FirmwareFactory factory_;
0099   std::shared_ptr<Stage2PreProcessor> processor_;
0100 };
0101 
0102 L1TStage2Layer1Producer::L1TStage2Layer1Producer(const edm::ParameterSet& ps)
0103     : verbosity_(ps.getParameter<int>("verbosity")),
0104       rctConditions_(ps.getParameter<bool>("rctConditions")),
0105       bxFirst_(ps.getParameter<int>("bxFirst")),
0106       bxLast_(ps.getParameter<int>("bxLast")),
0107       ecalToken_(bxLast_ + 1 - bxFirst_),
0108       hcalToken_(bxLast_ + 1 - bxFirst_),
0109       paramsCacheId_(0),
0110       params_(nullptr) {
0111   // register what you produce
0112   produces<CaloTowerBxCollection>();
0113 
0114   // register what you consume and keep token for later access:
0115   for (int ibx = 0; ibx < bxLast_ + 1 - bxFirst_; ibx++) {
0116     ecalToken_[ibx] = consumes<EcalTrigPrimDigiCollection>(ps.getParameter<edm::InputTag>("ecalToken"));
0117     hcalToken_[ibx] = consumes<HcalTrigPrimDigiCollection>(ps.getParameter<edm::InputTag>("hcalToken"));
0118   }
0119   if (rctConditions_) {
0120     ecalScaleToken_ = esConsumes<L1CaloEcalScale, L1CaloEcalScaleRcd>();
0121     hcalScaleToken_ = esConsumes<L1CaloHcalScale, L1CaloHcalScaleRcd>();
0122   } else {
0123     decoderToken_ = esConsumes<CaloTPGTranscoder, CaloTPGRecord>();
0124   }
0125   paramsToken_ = esConsumes<CaloParams, L1TCaloParamsRcd, edm::Transition::BeginRun>();
0126   // placeholder for the parameters
0127   params_ = new CaloParamsHelper;
0128 
0129   // set firmware version from python config for now
0130   fwv_ = ps.getParameter<int>("firmware");
0131 }
0132 
0133 L1TStage2Layer1Producer::~L1TStage2Layer1Producer() { delete params_; }
0134 
0135 // ------------ method called to produce the data  ------------
0136 void L1TStage2Layer1Producer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0137   LogDebug("l1t|stage 2") << "L1TStage2Layer1Producer::produce function called..." << std::endl;
0138 
0139   // do event setup
0140   // get RCT input scale objects
0141   edm::ESHandle<L1CaloEcalScale> ecalScale;
0142   edm::ESHandle<L1CaloHcalScale> hcalScale;
0143 
0144   edm::ESHandle<CaloTPGTranscoder> decoder;
0145 
0146   if (rctConditions_) {
0147     ecalScale = iSetup.getHandle(ecalScaleToken_);
0148     hcalScale = iSetup.getHandle(hcalScaleToken_);
0149   } else {
0150     decoder = iSetup.getHandle(decoderToken_);
0151   }
0152 
0153   LogDebug("L1TDebug") << "First BX=" << bxFirst_ << ", last BX=" << bxLast_ << ", LSB(E)=" << params_->towerLsbE()
0154                        << ", LSB(H)=" << params_->towerLsbH() << std::endl;
0155 
0156   // output collection
0157   std::unique_ptr<CaloTowerBxCollection> towersColl(new CaloTowerBxCollection);
0158 
0159   // loop over crossings
0160   for (int bx = bxFirst_; bx < bxLast_ + 1; ++bx) {
0161     int ibx = bx - bxFirst_;
0162 
0163     edm::Handle<EcalTrigPrimDigiCollection> ecalTPs;
0164     edm::Handle<HcalTrigPrimDigiCollection> hcalTPs;
0165 
0166     iEvent.getByToken(hcalToken_[ibx], hcalTPs);
0167     iEvent.getByToken(ecalToken_[ibx], ecalTPs);
0168 
0169     // create input and output tower vectors for this BX
0170     std::unique_ptr<std::vector<CaloTower> > localInTowers(
0171         new std::vector<CaloTower>(CaloTools::caloTowerHashMax() + 1));
0172     std::unique_ptr<std::vector<CaloTower> > localOutTowers(
0173         new std::vector<CaloTower>());  //this is later filled to the same size as localInTowers
0174 
0175     // loop over ECAL TPs
0176     EcalTrigPrimDigiCollection::const_iterator ecalItr;
0177     int nEcal = 0;
0178     for (ecalItr = ecalTPs->begin(); ecalItr != ecalTPs->end(); ++ecalItr, ++nEcal) {
0179       int ieta = ecalItr->id().ieta();
0180       int iphi = ecalItr->id().iphi();
0181 
0182       int ietIn = ecalItr->compressedEt();
0183       bool ifg = ecalItr->fineGrain();
0184 
0185       // decompress
0186       double et = 0.;
0187       if (rctConditions_) {
0188         et = ecalScale->et(ietIn, abs(ieta), (ieta > 0));
0189       } else {
0190         et = 0.5 * ietIn;
0191       }
0192 
0193       int ietOut = floor(et / params_->towerLsbE());
0194 
0195       int itow = CaloTools::caloTowerHash(ieta, iphi);
0196       localInTowers->at(itow).setHwEtEm(ietOut);
0197       localInTowers->at(itow).setHwQual(localInTowers->at(itow).hwQual() |
0198                                         (ifg ? 0x8 : 0x0));  //ECAL FG bit is supposed to be on bit 3
0199     }
0200 
0201     // loop over HCAL TPs
0202     HcalTrigPrimDigiCollection::const_iterator hcalItr;
0203     int nHcal = 0;
0204     for (hcalItr = hcalTPs->begin(); hcalItr != hcalTPs->end(); ++hcalItr, ++nHcal) {
0205       int ieta = hcalItr->id().ieta();
0206       int iphi = hcalItr->id().iphi();
0207       int ver = hcalItr->id().version();
0208 
0209       // check for old HF TPs
0210       if (abs(ieta) >= CaloTools::kHFBegin && ver != 1)
0211         continue;
0212 
0213       int ietIn = hcalItr->SOI_compressedEt();
0214       int ifg = hcalItr->SOI_fineGrain();
0215 
0216       // decompress
0217       double et = 0.;
0218 
0219       if (rctConditions_) {
0220         if (abs(ieta) >= CaloTools::kHFBegin)
0221           et = hcalScale->et(ietIn, CaloTools::kHFBegin, (ieta > 0));
0222         else
0223           et = hcalScale->et(ietIn, abs(ieta), (ieta > 0));
0224       } else {
0225         et = decoder->hcaletValue(hcalItr->id(), hcalItr->t0());
0226       }
0227 
0228       int ietOut = floor(et / params_->towerLsbH());
0229 
0230       // get tower index
0231       unsigned itow = CaloTools::caloTowerHash(ieta, iphi);
0232 
0233       if (ietOut > 0)
0234         LogDebug("L1TDebug") << " HCAL TP : " << ieta << ", " << iphi << ", " << ietIn << ", " << et << ", " << ietOut
0235                              << ", " << itow << ", " << CaloTools::caloTowerHashMax() << ", " << localInTowers->size()
0236                              << std::endl;
0237 
0238       localInTowers->at(itow).setHwEtHad(ietOut);
0239       localInTowers->at(itow).setHwQual(localInTowers->at(itow).hwQual() |
0240                                         (ifg ? 0x4 : 0x0));  //HCAL FG bit is supposed to be on bit 2
0241     }
0242 
0243     // now calculate remaining tower quantities
0244     for (int ieta = -1 * CaloTools::kHFEnd; ieta <= CaloTools::kHFEnd; ieta++) {
0245       for (int iphi = 0; iphi <= CaloTools::kHBHENrPhi; iphi++) {
0246         if (!CaloTools::isValidIEtaIPhi(ieta, iphi))
0247           continue;
0248 
0249         unsigned itow = CaloTools::caloTowerHash(ieta, iphi);
0250 
0251         // get ECAL/HCAL raw numbers
0252         int ietEcal = localInTowers->at(itow).hwEtEm();
0253         int ietHcal = localInTowers->at(itow).hwEtHad();
0254 
0255         int iet = ietEcal + ietHcal;
0256 
0257         if (ietHcal > 0)
0258           LogDebug("L1TDebug") << " L1Tow : " << ieta << ", " << iphi << ", " << itow << ", " << iet << ", " << ietEcal
0259                                << ", " << ietHcal << std::endl;
0260 
0261         localInTowers->at(itow).setHwPt(iet);
0262         localInTowers->at(itow).setHwEta(ieta);
0263         localInTowers->at(itow).setHwPhi(iphi);
0264 
0265         int ietby2 = round(double(ietHcal) / 2.);
0266         int ietby4 = round(double(ietHcal) / 4.);
0267 
0268         // if HF, divide energy by two and give half to adjacent tower
0269         if (abs(ieta) > 29 && iphi % 2 == 1) {
0270           localInTowers->at(itow).setHwPt(ietby2);
0271           localInTowers->at(itow).setHwEtHad(ietby2);
0272           int itow_next = CaloTools::caloTowerHash(ieta, iphi + 1);
0273           localInTowers->at(itow_next).setHwPt(ietby2);
0274           localInTowers->at(itow_next).setHwEtHad(ietby2);
0275         }
0276 
0277         if (abs(ieta) > 39 && iphi % 4 == 3) {
0278           localInTowers->at(itow).setHwPt(ietby4);
0279           localInTowers->at(itow).setHwEtHad(ietby4);
0280           int itow_next = CaloTools::caloTowerHash(ieta, iphi + 1);
0281           localInTowers->at(itow_next).setHwPt(ietby4);
0282           localInTowers->at(itow_next).setHwEtHad(ietby4);
0283           itow_next = CaloTools::caloTowerHash(ieta, iphi - 1);
0284           localInTowers->at(itow_next).setHwPt(ietby4);
0285           localInTowers->at(itow_next).setHwEtHad(ietby4);
0286           itow_next = CaloTools::caloTowerHash(ieta, iphi - 2);
0287           localInTowers->at(itow_next).setHwPt(ietby4);
0288           localInTowers->at(itow_next).setHwEtHad(ietby4);
0289         }
0290       }
0291     }
0292 
0293     //    for(std::vector<CaloTower>::const_iterator tower = localInTowers->begin();
0294     //  tower != localInTowers->end();
0295     //  ++tower) {
0296     //      if (tower->hwEta()>30) std::cout << "HF in : " << tower->hwEta() << "," << tower->hwPhi() << "," << tower->hwPt() << "," << tower->hwEtHad() << std::endl;
0297     //    }
0298 
0299     // do the decompression
0300     processor_->processEvent(*localInTowers, *localOutTowers);
0301 
0302     // copy towers to output collection
0303     for (std::vector<CaloTower>::const_iterator tower = localOutTowers->begin(); tower != localOutTowers->end();
0304          ++tower) {
0305       //     if (tower->hwEta()>30) std::cout << "HF out : " << tower->hwEta() << "," << tower->hwPhi() << "," << tower->hwPt() << "," << tower->etHad() << std::endl;
0306       towersColl->push_back(ibx, *tower);
0307     }
0308     LogDebug("L1TDebug") << "BX=" << ibx << ", N(Tower in)=" << localInTowers->size()
0309                          << ", N(Tower out)=" << localOutTowers->size() << std::endl;
0310   }
0311 
0312   iEvent.put(std::move(towersColl));
0313 }
0314 
0315 // ------------ method called when starting to processes a run  ------------
0316 void L1TStage2Layer1Producer::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {
0317   // update parameters and algorithms at run start, if they have changed
0318   // update params first because the firmware factory relies on pointer to params
0319 
0320   // parameters
0321 
0322   unsigned long long id = iSetup.get<L1TCaloParamsRcd>().cacheIdentifier();
0323 
0324   if (id != paramsCacheId_) {
0325     paramsCacheId_ = id;
0326 
0327     edm::ESHandle<CaloParams> paramsHandle = iSetup.getHandle(paramsToken_);
0328 
0329     // replace our local copy of the parameters with a new one using placement new
0330     params_->~CaloParamsHelper();
0331     params_ = new (params_) CaloParamsHelper(*paramsHandle.product());
0332 
0333     LogDebug("L1TDebug") << *params_ << std::endl;
0334 
0335     if (!params_) {
0336       edm::LogError("l1t|caloStage2") << "Could not retrieve params from Event Setup" << std::endl;
0337     }
0338   }
0339 
0340   // firmware
0341 
0342   if (!processor_) {  // in future, also check if the firmware cache ID has changed !
0343 
0344     //     m_fwv = ; // get new firmware version in future
0345 
0346     // Set the current algorithm version based on DB pars from database:
0347     processor_ = factory_.create(fwv_, params_);
0348 
0349     LogDebug("L1TDebug") << "Processor object : " << (processor_ ? 1 : 0) << std::endl;
0350 
0351     if (!processor_) {
0352       // we complain here once per run
0353       edm::LogError("l1t|caloStage2") << "Layer 1 firmware could not be configured.\n";
0354     }
0355   }
0356 }
0357 
0358 // ------------ method called when ending the processing of a run  ------------
0359 void L1TStage2Layer1Producer::endRun(edm::Run const&, edm::EventSetup const&) {}
0360 
0361 // ------------ method called when starting to processes a luminosity block  ------------
0362 /*
0363 void
0364 L1TStage2Layer1Producer::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup cons
0365 t&)
0366 {
0367 }
0368 */
0369 
0370 // ------------ method called when ending the processing of a luminosity block  ------------
0371 /*
0372 void
0373 L1TStage2Layer1Producer::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&
0374 )
0375 {
0376 }
0377 */
0378 
0379 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0380 void L1TStage2Layer1Producer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0381   //The following says we do not know what parameters are allowed so do no validation
0382   // Please change this to state exactly what you do use, even if it is no parameters
0383   edm::ParameterSetDescription desc;
0384   desc.setUnknown();
0385   descriptions.addDefault(desc);
0386 }
0387 
0388 //define this as a plug-in
0389 DEFINE_FWK_MODULE(L1TStage2Layer1Producer);