Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-11-21 00:28:57

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/L1TZDC
0004 // Class:      L1TZDC
0005 //
0006 /**\class L1TZDC L1TZDCProducer.cc L1Trigger/L1TZDC/plugins/L1TZDCProducer.cc
0007 
0008  Description: ZDC Producer for L1 Trigger emulation
0009 
0010  Implementation:
0011      Below text meant to indicate this was largely copied from some original work by James;
0012 modified to be appropriate for producing ZDC Et Sums
0013 */
0014 //
0015 // Original Author:  James Brooke
0016 //         Created:  Thu, 05 Dec 2013 17:39:27 GMT
0017 //
0018 // Copied for ZDC by: Chris McGinn
0019 //        Copy Made: Wed, 03 Aug 2023
0020 //        Contact: christopher.mc.ginn@cern.ch or
0021 //                 cfmcginn on github for bugs/issues
0022 //
0023 #include <memory>
0024 #include <iostream>
0025 // user include files
0026 
0027 #include "FWCore/Framework/interface/EventSetup.h"
0028 #include "FWCore/Framework/interface/Frameworkfwd.h"
0029 #include "FWCore/Framework/interface/stream/EDProducer.h"
0030 #include "FWCore/Framework/interface/ESHandle.h"
0031 #include "FWCore/Framework/interface/Event.h"
0032 #include "FWCore/Framework/interface/MakerMacros.h"
0033 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0034 #include "FWCore/Utilities/interface/EDGetToken.h"
0035 #include "FWCore/Utilities/interface/EDPutToken.h"
0036 #include "FWCore/Utilities/interface/InputTag.h"
0037 #include "FWCore/Utilities/interface/ESGetToken.h"
0038 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0039 
0040 #include "L1Trigger/L1TCalorimeter/interface/Stage2Layer2FirmwareFactory.h"
0041 #include "L1Trigger/L1TCalorimeter/interface/Stage2MainProcessor.h"
0042 #include "L1Trigger/L1TCalorimeter/interface/CaloTools.h"
0043 
0044 #include "L1Trigger/L1TCalorimeter/interface/CaloParamsHelper.h"
0045 #include "CondFormats/DataRecord/interface/L1TCaloParamsRcd.h"
0046 #include "CondFormats/DataRecord/interface/L1TCaloParamsO2ORcd.h"
0047 
0048 #include "DataFormats/L1TCalorimeter/interface/CaloTower.h"
0049 #include "DataFormats/L1Trigger/interface/EGamma.h"
0050 #include "DataFormats/L1Trigger/interface/Tau.h"
0051 #include "DataFormats/L1Trigger/interface/Jet.h"
0052 #include "DataFormats/L1Trigger/interface/EtSum.h"
0053 
0054 #include "DataFormats/HcalDigi/interface/HcalDigiCollections.h"
0055 
0056 //
0057 // class declaration
0058 //
0059 
0060 using namespace l1t;
0061 
0062 class L1TZDCProducer : public edm::stream::EDProducer<> {
0063 public:
0064   explicit L1TZDCProducer(const edm::ParameterSet& ps);
0065   ~L1TZDCProducer() override = default;
0066 
0067   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0068 
0069 private:
0070   void produce(edm::Event&, const edm::EventSetup&) override;
0071 
0072   void beginRun(edm::Run const&, edm::EventSetup const&) override;
0073   //  void endRun(edm::Run const&, edm::EventSetup const&) override;
0074 
0075   int zdcLUTIndexHelper(int iDetPos, int iBXPos);
0076 
0077   // ----------member data ---------------------------
0078 
0079   // input tokens
0080   //Add the ZDC token, candidateToken for caloParamsHelper
0081   edm::EDGetTokenT<QIE10DigiCollection> zdcToken_;
0082   edm::ESGetToken<CaloParams, L1TCaloParamsRcd> candidateToken_;
0083 
0084   //input ints
0085   int bxFirst_;
0086   int bxLast_;
0087   int sampleToCenterBX_;
0088 
0089   // put tokens
0090   edm::EDPutTokenT<EtSumBxCollection> etToken_;
0091 
0092   //Following the L1TStage2Layer2Producer
0093   std::unique_ptr<CaloParamsHelper> params_;
0094   int scaleFactor_;
0095 };
0096 
0097 L1TZDCProducer::L1TZDCProducer(const edm::ParameterSet& ps) {
0098   // register what you produce
0099   etToken_ = produces<EtSumBxCollection>();
0100 
0101   // register what you consume and keep token for later access:
0102   zdcToken_ = consumes<QIE10DigiCollection>(ps.getParameter<edm::InputTag>("zdcDigis"));
0103   candidateToken_ = esConsumes<CaloParams, L1TCaloParamsRcd, edm::Transition::BeginRun>();
0104 
0105   bxFirst_ = ps.getParameter<int>("bxFirst");
0106   bxLast_ = ps.getParameter<int>("bxLast");
0107   sampleToCenterBX_ = ps.getParameter<int>("sampleToCenterBX");
0108 }
0109 
0110 // ------------ method called to produce the data  ------------
0111 void L1TZDCProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0112   using namespace edm;
0113   using namespace l1t;
0114 
0115   LogDebug("L1TZDCProducer") << "L1TZDCProducer::produce function called..." << std::endl;
0116 
0117   // reduced collection to be emplaced in output
0118   EtSumBxCollection etsumsReduced(0, bxFirst_, bxLast_);
0119 
0120   //inputs
0121   Handle<QIE10DigiCollection> zdcDigiCollection;
0122   iEvent.getByToken(zdcToken_, zdcDigiCollection);
0123 
0124   //Produce ZDC EtSums IF input zdcDigiCollection is valid
0125   if (zdcDigiCollection.isValid()) {
0126     //In lieu of bxFirst, bxLast, use the number of the timeslice samples
0127     const QIE10DataFrame& frametest = (*zdcDigiCollection)[0];
0128     int nSamples = frametest.samples();
0129 
0130     //Check if the sample requested as center bx is valid
0131     int sampleToCenterBXChecked = sampleToCenterBX_;
0132 
0133     if (sampleToCenterBXChecked < 0) {
0134       edm::LogWarning("L1TZDCProducer") << "sampleToCenterBX LT 0; Set bx 0 to sample 0 (minimum allowed)" << std::endl;
0135       sampleToCenterBXChecked = 0;
0136     } else if (sampleToCenterBXChecked >= nSamples) {
0137       edm::LogWarning("L1TZDCProducer")
0138           << "sampleToCenterBX GE nsamples; Set bx 0 to sample nsamples-1 (maximum allowed)" << std::endl;
0139       sampleToCenterBXChecked = nSamples - 1;
0140     }
0141 
0142     //rawadc[detector index][time slices]
0143     unsigned short rawadc[18][10];
0144 
0145     // the loop below loops over all the elements of the QIE10DigiCollection. Each entry corresponds to one channel
0146     for (QIE10DigiCollection::const_iterator it = zdcDigiCollection->begin(); it != zdcDigiCollection->end(); it++) {
0147       const QIE10DataFrame& frame(*it);
0148       HcalZDCDetId cell = frame.id();
0149       int zside = cell.zside();
0150       int section = cell.section();
0151       int channel = cell.channel();
0152 
0153       if (zside != -1 && zside != 1)
0154         continue;
0155       if (section != 1 && section != 2)
0156         continue;
0157       if (section == 1 && (channel < 1 || channel > 5))
0158         continue;
0159       if (section == 2 && (channel < 1 || channel > 4))
0160         continue;
0161 
0162       int ihitid = (zside == 1 ? 9 : 0) + (section == 2 ? 5 : 0) + (channel - 1);
0163       //the loop below iterates over the time slices
0164       for (int iTS = 0; iTS < nSamples; iTS++) {
0165         unsigned short adc = (unsigned short)frame[iTS].adc();
0166         rawadc[ihitid][iTS] = adc;
0167       }  // end of loop over iTS
0168     }    //end of loop over channels
0169 
0170     for (int ibx = 0; ibx < nSamples; ibx++) {
0171       double cEMP = 0, cEMM = 0, cHDP = 0, cHDM = 0;
0172       double sumcEMP = 0, sumcEMM = 0, sumcHDP = 0, sumcHDM = 0;
0173       //idet=0-4 correpond to the EM channels
0174       for (int idet = 0; idet < 5; idet++) {
0175         unsigned short EMP = rawadc[idet + 9][ibx];
0176         unsigned short EMM = rawadc[idet][ibx];
0177 
0178         int cEMP_LUTIndex = zdcLUTIndexHelper(idet + 9, (int)EMP);
0179         int cEMM_LUTIndex = zdcLUTIndexHelper(idet, (int)EMM);
0180 
0181         cEMP = ((double)params_->zdcLUT()->data(cEMP_LUTIndex)) / ((double)scaleFactor_);
0182         cEMM = ((double)params_->zdcLUT()->data(cEMM_LUTIndex)) / ((double)scaleFactor_);
0183 
0184         sumcEMP = sumcEMP + cEMP;
0185         sumcEMM = sumcEMM + cEMM;
0186       }
0187       //idet=5-8 correspond to HAD channels
0188       for (int idet = 5; idet < 9; idet++) {
0189         unsigned short HDP = rawadc[idet + 9][ibx];
0190         unsigned short HDM = rawadc[idet][ibx];
0191 
0192         int cHDP_LUTIndex = zdcLUTIndexHelper(idet + 9, (int)HDP);
0193         int cHDM_LUTIndex = zdcLUTIndexHelper(idet, (int)HDM);
0194 
0195         cHDP = ((double)params_->zdcLUT()->data(cHDP_LUTIndex)) / ((double)scaleFactor_);
0196         cHDM = ((double)params_->zdcLUT()->data(cHDM_LUTIndex)) / ((double)scaleFactor_);
0197 
0198         sumcHDP = sumcHDP + cHDP;
0199         sumcHDM = sumcHDM + cHDM;
0200       }
0201       double sumM = sumcEMM + sumcHDM;
0202       double sumP = sumcEMP + sumcHDP;
0203 
0204       if (ibx == 4) {
0205         edm::LogInfo("L1TZDCProducer") << ", sumM= " << sumM << std::endl;
0206         edm::LogInfo("L1TZDCProducer") << ", sumP= " << sumP << std::endl;
0207       }
0208       l1t::EtSum tempEtM = l1t::EtSum();
0209       tempEtM.setHwPt(sumM);
0210       tempEtM.setHwEta(-1.);
0211       tempEtM.setHwPhi(0.);
0212       tempEtM.setType(EtSum::EtSumType::kZDCM);
0213 
0214       l1t::EtSum tempEtP = l1t::EtSum();
0215       tempEtP.setHwPt(sumP);
0216       tempEtP.setHwEta(1.);
0217       tempEtP.setHwPhi(0.);
0218       tempEtP.setType(EtSum::EtSumType::kZDCP);
0219 
0220       if (ibx >= sampleToCenterBXChecked + bxFirst_ && ibx <= sampleToCenterBXChecked + bxLast_) {
0221         etsumsReduced.push_back(ibx - sampleToCenterBXChecked, CaloTools::etSumP4Demux(tempEtP));
0222         etsumsReduced.push_back(ibx - sampleToCenterBXChecked, CaloTools::etSumP4Demux(tempEtM));
0223       }
0224     }  // end of loop over bunch crossings
0225   }    // end if(zdcDigiCollection.isValid())
0226   else {
0227     // If the collection is not valid issue a warning before putting an empty collection
0228     edm::LogWarning("L1TZDCProducer") << "zdcDigis not valid; return empty ZDC Et Sum BXCollection" << std::endl;
0229   }
0230 
0231   // Emplace even if !zdcDigiCollection.isValid()
0232   // Output in this case will be an empty collection
0233   iEvent.emplace(etToken_, std::move(etsumsReduced));
0234 }
0235 
0236 // ------------ method called when starting to processes a run  ------------
0237 void L1TZDCProducer::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup) {
0238   edm::ESHandle<CaloParams> candidateHandle = iSetup.getHandle(candidateToken_);
0239 
0240   params_ = std::make_unique<CaloParamsHelper>(*candidateHandle.product());
0241   scaleFactor_ = params_->zdcLUT()->data(0);  //First position is the integer scaling factor
0242   edm::LogInfo("L1TZDCProducer") << "SCALE FACTOR FOR LUT: " << scaleFactor_ << std::endl;
0243 }
0244 
0245 // LUT HELPER METHOD
0246 int L1TZDCProducer::zdcLUTIndexHelper(int iDetPos, int iBxPos) { return 1 + iDetPos * 256 + iBxPos; }
0247 
0248 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0249 void L1TZDCProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0250   edm::ParameterSetDescription desc;
0251   desc.add<edm::InputTag>("zdcDigis", edm::InputTag("hcalDigis", "ZDC"));
0252   desc.add<int>("bxFirst", -2);
0253   desc.add<int>("bxLast", 2);
0254   desc.add<int>("sampleToCenterBX", 4);
0255   descriptions.add("l1tZDCProducer", desc);
0256 }
0257 
0258 //define this as a plug-in
0259 DEFINE_FWK_MODULE(L1TZDCProducer);