Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-03 00:12:15

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/Run.h"
0003 #include "FWCore/Framework/interface/EventSetup.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/Utilities/interface/EDGetToken.h"
0007 #include "FWCore/Utilities/interface/EDPutToken.h"
0008 #include "FWCore/Utilities/interface/ESGetToken.h"
0009 #include "FWCore/Utilities/interface/InputTag.h"
0010 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0011 #include "DataFormats/Common/interface/Handle.h"
0012 
0013 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0014 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0015 #include "L1Trigger/TrackerTFP/interface/DataFormats.h"
0016 #include "L1Trigger/TrackerTFP/interface/LayerEncoding.h"
0017 #include "L1Trigger/TrackerTFP/interface/GeometricProcessor.h"
0018 
0019 #include <string>
0020 #include <vector>
0021 #include <deque>
0022 #include <numeric>
0023 #include <algorithm>
0024 #include <iterator>
0025 
0026 namespace trackerTFP {
0027 
0028   /*! \class  trackerTFP::ProducerGP
0029    *  \brief  L1TrackTrigger Geometric Processor emulator
0030    *  \author Thomas Schuh
0031    *  \date   2020, March
0032    */
0033   class ProducerGP : public edm::stream::EDProducer<> {
0034   public:
0035     explicit ProducerGP(const edm::ParameterSet&);
0036     ~ProducerGP() override = default;
0037 
0038   private:
0039     void beginRun(const edm::Run&, const edm::EventSetup&) override;
0040     void produce(edm::Event&, const edm::EventSetup&) override;
0041     // ED input token of pp objects
0042     edm::EDGetTokenT<tt::StreamsStub> edGetToken_;
0043     // ED output token for accepted objects
0044     edm::EDPutTokenT<tt::StreamsStub> edPutToken_;
0045     // Setup token
0046     edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0047     // DataFormats token
0048     edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0049     // LayerEncoding token
0050     edm::ESGetToken<LayerEncoding, DataFormatsRcd> esGetTokenLayerEncoding_;
0051     // number of input channel
0052     int numChannelIn_;
0053     // number of output channel
0054     int numChannelOut_;
0055     // number of processing regions
0056     int numRegions_;
0057   };
0058 
0059   ProducerGP::ProducerGP(const edm::ParameterSet& iConfig) {
0060     const std::string& label = iConfig.getParameter<std::string>("InputLabelGP");
0061     const std::string& branch = iConfig.getParameter<std::string>("BranchStubs");
0062     // book in- and output ED products
0063     edGetToken_ = consumes<tt::StreamsStub>(edm::InputTag(label, branch));
0064     edPutToken_ = produces<tt::StreamsStub>(branch);
0065     // book ES products
0066     esGetTokenSetup_ = esConsumes();
0067     esGetTokenDataFormats_ = esConsumes();
0068     esGetTokenLayerEncoding_ = esConsumes();
0069   }
0070 
0071   void ProducerGP::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0072     // helper classe to store configurations
0073     const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_);
0074     numRegions_ = setup->numRegions();
0075     // helper class to extract structured data from tt::Frames
0076     const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_);
0077     numChannelIn_ = dataFormats->numChannel(Process::pp);
0078     numChannelOut_ = dataFormats->numChannel(Process::gp);
0079   }
0080 
0081   void ProducerGP::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0082     // helper classe to store configurations
0083     const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_);
0084     // helper class to extract structured data from tt::Frames
0085     const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_);
0086     // helper class to encode layer
0087     const LayerEncoding* layerEncoding = &iSetup.getData(esGetTokenLayerEncoding_);
0088     // empty GP products
0089     tt::StreamsStub accepted(numRegions_ * numChannelOut_);
0090     // read in DTC Product and produce TFP product
0091     const tt::StreamsStub& streamsStub = iEvent.get(edGetToken_);
0092     // helper
0093     auto validFrame = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0094     auto nSectors = [](int sum, const StubPP& object) {
0095       const int nPhiT = object.phiTMax() - object.phiTMin() + 1;
0096       const int nZT = object.zTMax() - object.zTMin() + 1;
0097       return sum + nPhiT * nZT;
0098     };
0099     auto toFrame = [](StubGP* object) { return object ? object->frame() : tt::FrameStub(); };
0100     // produce GP product per region
0101     for (int region = 0; region < numRegions_; region++) {
0102       const int offsetIn = region * numChannelIn_;
0103       const int offsetOut = region * numChannelOut_;
0104       // count input objects
0105       int nStubsPP(0);
0106       for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0107         const tt::StreamStub& stream = streamsStub[offsetIn + channelIn];
0108         nStubsPP += std::accumulate(stream.begin(), stream.end(), 0, validFrame);
0109       }
0110       // storage of input data
0111       std::vector<StubPP> stubsPP;
0112       stubsPP.reserve(nStubsPP);
0113       // h/w liked organized pointer to input data
0114       std::vector<std::vector<StubPP*>> streamsIn(numChannelIn_);
0115       // read input data
0116       for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0117         const tt::StreamStub& streamStub = streamsStub[offsetIn + channelIn];
0118         std::vector<StubPP*>& stream = streamsIn[channelIn];
0119         stream.reserve(streamStub.size());
0120         for (const tt::FrameStub& frame : streamStub) {
0121           StubPP* stubPP = nullptr;
0122           if (frame.first.isNonnull()) {
0123             stubsPP.emplace_back(frame, dataFormats);
0124             stubPP = &stubsPP.back();
0125           }
0126           stream.push_back(stubPP);
0127         }
0128       }
0129       // predict upper limit of GP stubs
0130       const int nStubsGP = std::accumulate(stubsPP.begin(), stubsPP.end(), 0, nSectors);
0131       // container of GP stubs
0132       std::vector<StubGP> stubsGP;
0133       stubsGP.reserve(nStubsGP);
0134       // object to route Stubs of one region to one stream per sector
0135       GeometricProcessor gp(setup, dataFormats, layerEncoding, stubsGP);
0136       // empty h/w liked organized pointer to output data
0137       std::vector<std::deque<StubGP*>> streamsOut(numChannelOut_);
0138       // fill output data
0139       gp.produce(streamsIn, streamsOut);
0140       // convert data to ed products
0141       for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) {
0142         const std::deque<StubGP*>& objects = streamsOut[channelOut];
0143         tt::StreamStub& stream = accepted[offsetOut + channelOut];
0144         stream.reserve(objects.size());
0145         std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame);
0146       }
0147     }
0148     // store products
0149     iEvent.emplace(edPutToken_, std::move(accepted));
0150   }
0151 
0152 }  // namespace trackerTFP
0153 
0154 DEFINE_FWK_MODULE(trackerTFP::ProducerGP);