Back to home page

Project CMSSW displayed by LXR

 
 

    


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

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/DuplicateRemoval.h"
0017 
0018 #include <string>
0019 #include <numeric>
0020 
0021 namespace trackerTFP {
0022 
0023   /*! \class  trackerTFP::ProducerDR
0024    *  \brief  L1TrackTrigger duplicate removal emulator
0025    *  \author Thomas Schuh
0026    *  \date   2023, Feb
0027    */
0028   class ProducerDR : public edm::stream::EDProducer<> {
0029   public:
0030     explicit ProducerDR(const edm::ParameterSet&);
0031     ~ProducerDR() override = default;
0032 
0033   private:
0034     void beginRun(const edm::Run&, const edm::EventSetup&) override;
0035     void produce(edm::Event&, const edm::EventSetup&) override;
0036     // ED input token of sf stubs and tracks
0037     edm::EDGetTokenT<tt::StreamsStub> edGetTokenStubs_;
0038     edm::EDGetTokenT<tt::StreamsTrack> edGetTokenTracks_;
0039     // ED output token for accepted stubs and tracks
0040     edm::EDPutTokenT<tt::StreamsStub> edPutTokenStubs_;
0041     edm::EDPutTokenT<tt::StreamsTrack> edPutTokenTracks_;
0042     // Setup token
0043     edm::ESGetToken<tt::Setup, tt::SetupRcd> esGetTokenSetup_;
0044     // DataFormats token
0045     edm::ESGetToken<DataFormats, DataFormatsRcd> esGetTokenDataFormats_;
0046     // number of input channel
0047     int numChannelIn_;
0048     // number of output channel
0049     int numChannelOut_;
0050     // number ofprocessing regions
0051     int numRegions_;
0052     // number of kf layers
0053     int numLayers_;
0054   };
0055 
0056   ProducerDR::ProducerDR(const edm::ParameterSet& iConfig) {
0057     const std::string& label = iConfig.getParameter<std::string>("InputLabelDR");
0058     const std::string& branchStubs = iConfig.getParameter<std::string>("BranchStubs");
0059     const std::string& branchTracks = iConfig.getParameter<std::string>("BranchTracks");
0060     // book in- and output ED products
0061     edGetTokenStubs_ = consumes<tt::StreamsStub>(edm::InputTag(label, branchStubs));
0062     edGetTokenTracks_ = consumes<tt::StreamsTrack>(edm::InputTag(label, branchTracks));
0063     edPutTokenStubs_ = produces<tt::StreamsStub>(branchStubs);
0064     edPutTokenTracks_ = produces<tt::StreamsTrack>(branchTracks);
0065     // book ES products
0066     esGetTokenSetup_ = esConsumes();
0067     esGetTokenDataFormats_ = esConsumes();
0068   }
0069 
0070   void ProducerDR::beginRun(const edm::Run& iRun, const edm::EventSetup& iSetup) {
0071     // helper class to store configurations
0072     const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_);
0073     numRegions_ = setup->numRegions();
0074     numLayers_ = setup->numLayers();
0075     // helper class to extract structured data from tt::Frames
0076     const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_);
0077     numChannelIn_ = dataFormats->numChannel(Process::kf);
0078     numChannelOut_ = dataFormats->numChannel(Process::dr);
0079   }
0080 
0081   void ProducerDR::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0082     const tt::Setup* setup = &iSetup.getData(esGetTokenSetup_);
0083     const DataFormats* dataFormats = &iSetup.getData(esGetTokenDataFormats_);
0084     // empty DR products
0085     tt::StreamsStub acceptedStubs(numRegions_ * numChannelOut_ * numLayers_);
0086     tt::StreamsTrack acceptedTracks(numRegions_ * numChannelOut_);
0087     // read in KF Product and produce DR product
0088     const tt::StreamsStub& allStubs = iEvent.get(edGetTokenStubs_);
0089     const tt::StreamsTrack& allTracks = iEvent.get(edGetTokenTracks_);
0090     // helper
0091     auto validFrameT = [](int sum, const tt::FrameTrack& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0092     auto validFrameS = [](int sum, const tt::FrameStub& frame) { return sum + (frame.first.isNonnull() ? 1 : 0); };
0093     auto putT = [](const std::vector<TrackDR*>& objects, tt::StreamTrack& stream) {
0094       auto toFrame = [](TrackDR* object) { return object ? object->frame() : tt::FrameTrack(); };
0095       stream.reserve(objects.size());
0096       std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame);
0097     };
0098     auto putS = [](const std::vector<StubDR*>& objects, tt::StreamStub& stream) {
0099       auto toFrame = [](StubDR* object) { return object ? object->frame() : tt::FrameStub(); };
0100       stream.reserve(objects.size());
0101       std::transform(objects.begin(), objects.end(), std::back_inserter(stream), toFrame);
0102     };
0103     for (int region = 0; region < numRegions_; region++) {
0104       const int offsetIn = region * numChannelIn_;
0105       const int offsetOut = region * numChannelOut_;
0106       // count input objects
0107       int nTracks(0);
0108       int nStubs(0);
0109       for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0110         const int index = offsetIn + channelIn;
0111         const int offset = index * numLayers_;
0112         const tt::StreamTrack& tracks = allTracks[index];
0113         nTracks += std::accumulate(tracks.begin(), tracks.end(), 0, validFrameT);
0114         for (int layer = 0; layer < numLayers_; layer++) {
0115           const tt::StreamStub& stubs = allStubs[offset + layer];
0116           nStubs += std::accumulate(stubs.begin(), stubs.end(), 0, validFrameS);
0117         }
0118       }
0119       // storage of input data
0120       std::vector<TrackKF> tracksKF;
0121       tracksKF.reserve(nTracks);
0122       std::vector<StubKF> stubsKF;
0123       stubsKF.reserve(nStubs);
0124       // h/w liked organized pointer to input data
0125       std::vector<std::vector<TrackKF*>> regionTracks(numChannelIn_);
0126       std::vector<std::vector<StubKF*>> regionStubs(numChannelIn_ * numLayers_);
0127       // read input data
0128       for (int channelIn = 0; channelIn < numChannelIn_; channelIn++) {
0129         const int index = offsetIn + channelIn;
0130         const int offsetAll = index * numLayers_;
0131         const int offsetRegion = channelIn * numLayers_;
0132         const tt::StreamTrack& streamTrack = allTracks[index];
0133         std::vector<TrackKF*>& tracks = regionTracks[channelIn];
0134         tracks.reserve(streamTrack.size());
0135         for (const tt::FrameTrack& frame : streamTrack) {
0136           TrackKF* track = nullptr;
0137           if (frame.first.isNonnull()) {
0138             tracksKF.emplace_back(frame, dataFormats);
0139             track = &tracksKF.back();
0140           }
0141           tracks.push_back(track);
0142         }
0143         for (int layer = 0; layer < numLayers_; layer++) {
0144           for (const tt::FrameStub& frame : allStubs[offsetAll + layer]) {
0145             StubKF* stub = nullptr;
0146             if (frame.first.isNonnull()) {
0147               stubsKF.emplace_back(frame, dataFormats);
0148               stub = &stubsKF.back();
0149             }
0150             regionStubs[offsetRegion + layer].push_back(stub);
0151           }
0152         }
0153       }
0154       // empty storage of output data
0155       std::vector<TrackDR> tracksDR;
0156       tracksDR.reserve(nTracks);
0157       std::vector<StubDR> stubsDR;
0158       stubsDR.reserve(nStubs);
0159       // object to remove duplicates in a processing region
0160       DuplicateRemoval dr(setup, dataFormats, tracksDR, stubsDR);
0161       // empty h/w liked organized pointer to output data
0162       std::vector<std::vector<TrackDR*>> streamsTrack(numChannelOut_);
0163       std::vector<std::vector<StubDR*>> streamsStub(numChannelOut_ * numLayers_);
0164       // fill output data
0165       dr.produce(regionTracks, regionStubs, streamsTrack, streamsStub);
0166       // convert data to ed products
0167       for (int channelOut = 0; channelOut < numChannelOut_; channelOut++) {
0168         const int index = offsetOut + channelOut;
0169         const int offsetRegion = channelOut * numLayers_;
0170         const int offsetAll = index * numLayers_;
0171         putT(streamsTrack[channelOut], acceptedTracks[index]);
0172         for (int layer = 0; layer < numLayers_; layer++)
0173           putS(streamsStub[offsetRegion + layer], acceptedStubs[offsetAll + layer]);
0174       }
0175     }
0176     // store products
0177     iEvent.emplace(edPutTokenStubs_, std::move(acceptedStubs));
0178     iEvent.emplace(edPutTokenTracks_, std::move(acceptedTracks));
0179   }
0180 
0181 }  // namespace trackerTFP
0182 
0183 DEFINE_FWK_MODULE(trackerTFP::ProducerDR);