Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-11-23 02:09:01

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/L1TTrackMatch
0004 // Class:      L1TrackVertexAssociationProducer
0005 //
0006 /**\class L1TrackVertexAssociationProducer L1TrackVertexAssociationProducer.cc L1Trigger/L1TTrackMatch/plugins/L1TrackVertexAssociationProducer.cc
0007 
0008  Description: Selects a set of L1Tracks based on a set of predefined criteria.
0009 
0010  Implementation:
0011      Inputs:
0012          std::vector<TTTrack> - Each floating point TTTrack inside this collection inherits from
0013                                 a bit-accurate TTTrack_TrackWord, used for emulation purposes.
0014      Outputs:
0015          std::vector<TTTrack> - A collection of TTTracks selected from cuts on the TTTrack properties
0016          std::vector<TTTrack> - A collection of TTTracks selected from cuts on the TTTrack_TrackWord properties
0017 */
0018 //
0019 // Original Author:  Alexx Perloff
0020 //         Created:  Thu, 16 Dec 2021 19:02:50 GMT
0021 // Derivative Author: Nick Manganelli
0022 //         Created: Thu, 14 Oct 2023 16:32:32 GMT
0023 //
0024 //
0025 
0026 // system include files
0027 #include <algorithm>
0028 #include <memory>
0029 #include <string>
0030 #include <vector>
0031 
0032 // Xilinx HLS includes
0033 #include <ap_fixed.h>
0034 #include <ap_int.h>
0035 
0036 // user include files
0037 #include "DataFormats/Common/interface/Handle.h"
0038 #include "DataFormats/Common/interface/Ref.h"
0039 #include "DataFormats/Common/interface/RefVector.h"
0040 #include "DataFormats/Common/interface/RefToPtr.h"
0041 #include "DataFormats/Common/interface/Ptr.h"
0042 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0043 #include "DataFormats/L1Trigger/interface/Vertex.h"
0044 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0045 #include "L1Trigger/VertexFinder/interface/L1Track.h"
0046 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0047 #include "CommonTools/Utils/interface/AndSelector.h"
0048 #include "CommonTools/Utils/interface/EtaRangeSelector.h"
0049 #include "CommonTools/Utils/interface/MinSelector.h"
0050 #include "CommonTools/Utils/interface/MinFunctionSelector.h"
0051 #include "CommonTools/Utils/interface/MinNumberSelector.h"
0052 #include "CommonTools/Utils/interface/PtMinSelector.h"
0053 #include "CommonTools/Utils/interface/Selection.h"
0054 #include "FWCore/Framework/interface/Frameworkfwd.h"
0055 #include "FWCore/Framework/interface/global/EDProducer.h"
0056 #include "FWCore/Framework/interface/Event.h"
0057 #include "FWCore/Framework/interface/MakerMacros.h"
0058 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0059 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0060 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0061 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0062 #include "FWCore/Utilities/interface/EDMException.h"
0063 #include "FWCore/Utilities/interface/StreamID.h"
0064 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0065 #include "L1Trigger/DemonstratorTools/interface/codecs/tracks.h"
0066 
0067 //
0068 // class declaration
0069 //
0070 
0071 class L1TrackVertexAssociationProducer : public edm::global::EDProducer<> {
0072 public:
0073   explicit L1TrackVertexAssociationProducer(const edm::ParameterSet&);
0074   ~L1TrackVertexAssociationProducer() override;
0075 
0076   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0077 
0078 private:
0079   // ----------constants, enums and typedefs ---------
0080   // Relevant constants for the converted track word
0081   enum TrackBitWidths {
0082     kPtSize = TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1,  // Width of pt
0083     kPtMagSize = 9,                                              // Width of pt magnitude (unsigned)
0084     kEtaSize = TTTrack_TrackWord::TrackBitWidths::kTanlSize,     // Width of eta
0085     kEtaMagSize = 3,                                             // Width of eta magnitude (signed)
0086   };
0087 
0088   typedef TTTrack<Ref_Phase2TrackerDigi_> TTTrackType;
0089   typedef std::vector<TTTrackType> TTTrackCollectionType;
0090   typedef edm::Handle<TTTrackCollectionType> TTTrackCollectionHandle;
0091   typedef edm::RefVector<TTTrackCollectionType> TTTrackRefCollectionType;
0092   typedef std::unique_ptr<TTTrackRefCollectionType> TTTrackRefCollectionUPtr;
0093 
0094   // ----------member functions ----------------------
0095   void printDebugInfo(const edm::Handle<TTTrackRefCollectionType>& l1SelectedTracksHandle,
0096                       const edm::Handle<TTTrackRefCollectionType>& l1SelectedTracksEmulationHandle,
0097                       const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput,
0098                       const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const;
0099   void printTrackInfo(edm::LogInfo& log, const TTTrackType& track, bool printEmulation = false) const;
0100   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0101 
0102   // ----------selectors -----------------------------
0103   // Based on recommendations from https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideGenericSelectors
0104   struct TTTrackDeltaZMaxSelector {
0105     TTTrackDeltaZMaxSelector(const std::vector<double>& deltaZMaxEtaBounds, const std::vector<double>& deltaZMax)
0106         : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {}
0107     TTTrackDeltaZMaxSelector(const edm::ParameterSet& cfg)
0108         : deltaZMaxEtaBounds_(cfg.template getParameter<double>("deltaZMaxEtaBounds")),
0109           deltaZMax_(cfg.template getParameter<double>("deltaZMax")) {}
0110     bool operator()(const TTTrackType& t, const l1t::Vertex& v) const {
0111       size_t etaIndex =
0112           std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) -
0113           deltaZMaxEtaBounds_.begin() - 1;
0114       if (etaIndex > deltaZMax_.size() - 1)
0115         etaIndex = deltaZMax_.size() - 1;
0116       return std::abs(v.z0() - t.z0()) <= deltaZMax_[etaIndex];
0117     }
0118 
0119   private:
0120     std::vector<double> deltaZMaxEtaBounds_;
0121     std::vector<double> deltaZMax_;
0122   };
0123   struct TTTrackWordDeltaZMaxSelector {
0124     TTTrackWordDeltaZMaxSelector(const std::vector<double>& deltaZMaxEtaBounds, const std::vector<double>& deltaZMax)
0125         : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {}
0126     TTTrackWordDeltaZMaxSelector(const edm::ParameterSet& cfg)
0127         : deltaZMaxEtaBounds_(cfg.template getParameter<double>("deltaZMaxEtaBounds")),
0128           deltaZMax_(cfg.template getParameter<double>("deltaZMax")) {}
0129     bool operator()(const TTTrackType& t, const l1t::VertexWord& v) const {
0130       TTTrack_TrackWord::tanl_t etaEmulationBits = t.getTanlWord();
0131       ap_fixed<TrackBitWidths::kEtaSize, TrackBitWidths::kEtaMagSize> etaEmulation;
0132       etaEmulation.V = etaEmulationBits.range();
0133       size_t etaIndex =
0134           std::upper_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(etaEmulation.to_double())) -
0135           deltaZMaxEtaBounds_.begin() - 1;
0136       if (etaIndex > deltaZMax_.size() - 1)
0137         etaIndex = deltaZMax_.size() - 1;
0138       l1t::VertexWord::vtxz0_t fixedTkZ0 = t.undigitizeSignedValue(
0139           t.getZ0Bits(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, TTTrack_TrackWord::stepZ0, 0.0);
0140 
0141       ap_uint<TrackBitWidths::kPtSize> ptEmulationBits = t.getTrackWord()(
0142           TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0143       ap_ufixed<TrackBitWidths::kPtSize, TrackBitWidths::kPtMagSize> ptEmulation;
0144       ptEmulation.V = ptEmulationBits.range();
0145       return std::abs(v.z0() - fixedTkZ0.to_double()) <= deltaZMax_[etaIndex];
0146     }
0147 
0148   private:
0149     std::vector<double> deltaZMaxEtaBounds_;
0150     std::vector<double> deltaZMax_;
0151   };
0152   struct TTTrackWordLinkLimitSelector {
0153     TTTrackWordLinkLimitSelector(const unsigned int fwNTrackSetsTVA) : fwNTrackSetsTVA_(fwNTrackSetsTVA) {
0154       //create a counter for all 18 GTT input links, 2 per phiSector of the TrackFindingProcessors
0155       for (int idx = 0; idx < 18; idx++) {
0156         processedTracksPerLink_.push_back(0);
0157         truncatedTracksPerLink_.push_back(0);
0158       }
0159     }
0160     TTTrackWordLinkLimitSelector(const edm::ParameterSet& cfg)
0161         : fwNTrackSetsTVA_(cfg.template getParameter<unsigned int>("fwNTrackSetsTVA")) {
0162       for (int idx = 0; idx < 18; idx++) {
0163         processedTracksPerLink_.push_back(0);
0164       }
0165     }
0166     bool operator()(const TTTrackType& t) {
0167       unsigned int gttLinkID = l1t::demo::codecs::gttLinkID(t);
0168       //increment the counter of processed tracks
0169       processedTracksPerLink_.at(gttLinkID)++;
0170       //fwNTrackSetsTVA_ tracks may be processed in firmware, no more (<= used intentionally to match the off-by-one indexing versus LibHLS)
0171       if ((processedTracksPerLink_[gttLinkID] > fwNTrackSetsTVA_) && (t.getValidWord()))
0172         truncatedTracksPerLink_[gttLinkID]++;
0173       return processedTracksPerLink_[gttLinkID] <= fwNTrackSetsTVA_;
0174     }
0175     void log() {
0176       edm::LogInfo log("L1TrackVertexAssociationProducer");
0177       log << "Processed track link counters:\t[";
0178       for (int idx = 0; idx < 18; idx++) {
0179         if (idx > 0)
0180           log << ", ";
0181         log << processedTracksPerLink_.at(idx);
0182       }
0183       log << "]\n";
0184       log << "Truncated track link counters:\t[";
0185       for (int idx = 0; idx < 18; idx++) {
0186         if (idx > 0)
0187           log << ", ";
0188         log << truncatedTracksPerLink_.at(idx);
0189       }
0190       log << "]\n";
0191     }
0192 
0193   private:
0194     unsigned int fwNTrackSetsTVA_;
0195     std::vector<unsigned int> processedTracksPerLink_;
0196     std::vector<unsigned int> truncatedTracksPerLink_;
0197   };
0198 
0199   // ----------member data ---------------------------
0200   const bool processSimulatedTracks_, processEmulatedTracks_;
0201   const edm::EDGetTokenT<TTTrackCollectionType> l1TracksToken_;
0202   const edm::EDGetTokenT<l1t::VertexCollection> l1VerticesToken_;
0203   const edm::EDGetTokenT<TTTrackRefCollectionType> l1SelectedTracksToken_;
0204   const edm::EDGetTokenT<l1t::VertexWordCollection> l1VerticesEmulationToken_;
0205   const edm::EDGetTokenT<TTTrackRefCollectionType> l1SelectedTracksEmulationToken_;
0206   const std::string outputCollectionName_;
0207   const edm::ParameterSet cutSet_;
0208   std::vector<double> deltaZMaxEtaBounds_, deltaZMax_;
0209   const double useDisplacedTracksDeltaZOverride_;
0210   // corresponds to N_TRACK_SETS_TVA in LibHLS https://gitlab.cern.ch/GTT/LibHLS/-/blob/master/DataFormats/Track/interface/TrackConstants.h
0211   const unsigned int fwNTrackSetsTVA_;
0212   int debug_;
0213 };
0214 
0215 //
0216 // constructors and destructor
0217 //
0218 L1TrackVertexAssociationProducer::L1TrackVertexAssociationProducer(const edm::ParameterSet& iConfig)
0219     : processSimulatedTracks_(iConfig.getParameter<bool>("processSimulatedTracks")),
0220       processEmulatedTracks_(iConfig.getParameter<bool>("processEmulatedTracks")),
0221       l1TracksToken_(consumes<TTTrackCollectionType>(iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
0222       l1VerticesToken_(processSimulatedTracks_
0223                            ? consumes<l1t::VertexCollection>(iConfig.getParameter<edm::InputTag>("l1VerticesInputTag"))
0224                            : edm::EDGetTokenT<l1t::VertexCollection>()),
0225       l1SelectedTracksToken_(
0226           processSimulatedTracks_
0227               ? consumes<TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>("l1SelectedTracksInputTag"))
0228               : edm::EDGetTokenT<TTTrackRefCollectionType>()),
0229       l1VerticesEmulationToken_(
0230           processEmulatedTracks_
0231               ? consumes<l1t::VertexWordCollection>(iConfig.getParameter<edm::InputTag>("l1VerticesEmulationInputTag"))
0232               : edm::EDGetTokenT<l1t::VertexWordCollection>()),
0233       l1SelectedTracksEmulationToken_(processEmulatedTracks_
0234                                           ? consumes<TTTrackRefCollectionType>(iConfig.getParameter<edm::InputTag>(
0235                                                 "l1SelectedTracksEmulationInputTag"))
0236                                           : edm::EDGetTokenT<TTTrackRefCollectionType>()),
0237       outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")),
0238       cutSet_(iConfig.getParameter<edm::ParameterSet>("cutSet")),
0239 
0240       deltaZMaxEtaBounds_(cutSet_.getParameter<std::vector<double>>("deltaZMaxEtaBounds")),
0241       deltaZMax_(cutSet_.getParameter<std::vector<double>>("deltaZMax")),
0242       useDisplacedTracksDeltaZOverride_(iConfig.getParameter<double>("useDisplacedTracksDeltaZOverride")),
0243       fwNTrackSetsTVA_(iConfig.getParameter<unsigned int>("fwNTrackSetsTVA")),
0244       debug_(iConfig.getParameter<int>("debug")) {
0245   // Confirm the the configuration makes sense
0246   if (!processSimulatedTracks_ && !processEmulatedTracks_) {
0247     throw cms::Exception("You must process at least one of the track collections (simulated or emulated).");
0248   }
0249 
0250   if (deltaZMax_.size() != deltaZMaxEtaBounds_.size() - 1) {
0251     throw cms::Exception("The number of deltaZ cuts does not match the number of eta bins!");
0252   }
0253 
0254   if (useDisplacedTracksDeltaZOverride_ >= 0) {
0255     deltaZMax_ = std::vector<double>(deltaZMax_.size(), useDisplacedTracksDeltaZOverride_);
0256   }
0257 
0258   // Get additional input tags and define the EDM output based on the previous configuration parameters
0259   if (processSimulatedTracks_)
0260     produces<TTTrackRefCollectionType>(outputCollectionName_);
0261   if (processEmulatedTracks_)
0262     produces<TTTrackRefCollectionType>(outputCollectionName_ + "Emulation");
0263 }
0264 
0265 L1TrackVertexAssociationProducer::~L1TrackVertexAssociationProducer() {}
0266 
0267 //
0268 // member functions
0269 //
0270 
0271 void L1TrackVertexAssociationProducer::printDebugInfo(
0272     const edm::Handle<TTTrackRefCollectionType>& l1SelectedTracksHandle,
0273     const edm::Handle<TTTrackRefCollectionType>& l1SelectedTracksEmulationHandle,
0274     const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput,
0275     const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const {
0276   edm::LogInfo log("L1TrackVertexAssociationProducer");
0277   if (processSimulatedTracks_) {
0278     log << "The original selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are "
0279            "... \n";
0280     for (const auto& track : *l1SelectedTracksHandle) {
0281       printTrackInfo(log, *track, debug_ >= 4);
0282     }
0283     log << "\t---\n\tNumber of tracks in this selection = " << l1SelectedTracksHandle->size() << "\n\n";
0284   }
0285   if (processEmulatedTracks_) {
0286     log << "The original selected emulated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) "
0287            "values are ... \n";
0288     for (const auto& track : *l1SelectedTracksEmulationHandle) {
0289       printTrackInfo(log, *track, debug_ >= 4);
0290     }
0291     log << "\t---\n\tNumber of tracks in this selection = " << l1SelectedTracksEmulationHandle->size() << "\n\n";
0292   }
0293   if (processSimulatedTracks_ && processEmulatedTracks_) {
0294     TTTrackRefCollectionType inSimButNotEmu;
0295     TTTrackRefCollectionType inEmuButNotSim;
0296     std::set_difference(l1SelectedTracksHandle->begin(),
0297                         l1SelectedTracksHandle->end(),
0298                         l1SelectedTracksEmulationHandle->begin(),
0299                         l1SelectedTracksEmulationHandle->end(),
0300                         std::back_inserter(inSimButNotEmu));
0301     std::set_difference(l1SelectedTracksEmulationHandle->begin(),
0302                         l1SelectedTracksEmulationHandle->end(),
0303                         l1SelectedTracksHandle->begin(),
0304                         l1SelectedTracksHandle->end(),
0305                         std::back_inserter(inEmuButNotSim));
0306     log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected "
0307            "by cutting on the emulated values ... \n";
0308     for (const auto& track : inSimButNotEmu) {
0309       printTrackInfo(log, *track, debug_ >= 3);
0310     }
0311     log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n"
0312         << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected "
0313            "by cutting on the simulated values ... \n";
0314     for (const auto& track : inEmuButNotSim) {
0315       printTrackInfo(log, *track, debug_ >= 3);
0316     }
0317     log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n";
0318   }
0319   if (processSimulatedTracks_) {
0320     log << "The selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, "
0321            "chi2rphi, z0) values are ... \n";
0322     for (const auto& track : *vTTTrackAssociatedOutput) {
0323       printTrackInfo(log, *track, debug_ >= 4);
0324     }
0325     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedOutput->size() << "\n\n";
0326   }
0327   if (processEmulatedTracks_) {
0328     log << "The emulation selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, "
0329            "chi2rz, chi2rphi, z0) values are "
0330            "... \n";
0331     for (const auto& track : *vTTTrackAssociatedEmulationOutput) {
0332       printTrackInfo(log, *track, debug_ >= 4);
0333     }
0334     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedEmulationOutput->size() << "\n\n";
0335   }
0336   if (processSimulatedTracks_ && processEmulatedTracks_) {
0337     TTTrackRefCollectionType inSimButNotEmu;
0338     TTTrackRefCollectionType inEmuButNotSim;
0339     std::set_difference(vTTTrackAssociatedOutput->begin(),
0340                         vTTTrackAssociatedOutput->end(),
0341                         vTTTrackAssociatedEmulationOutput->begin(),
0342                         vTTTrackAssociatedEmulationOutput->end(),
0343                         std::back_inserter(inSimButNotEmu));
0344     std::set_difference(vTTTrackAssociatedEmulationOutput->begin(),
0345                         vTTTrackAssociatedEmulationOutput->end(),
0346                         vTTTrackAssociatedOutput->begin(),
0347                         vTTTrackAssociatedOutput->end(),
0348                         std::back_inserter(inEmuButNotSim));
0349     log << "The set of vertex associated tracks selected via cuts on the simulated values which are not in the set of "
0350            "tracks selected "
0351            "by cutting on the emulated values ... \n";
0352     for (const auto& track : inSimButNotEmu) {
0353       printTrackInfo(log, *track, debug_ >= 3);
0354     }
0355     log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n"
0356         << "The set of vertex associated tracks selected via cuts on the emulated values which are not in the set of "
0357            "tracks selected "
0358            "by cutting on the simulated values ... \n";
0359     for (const auto& track : inEmuButNotSim) {
0360       printTrackInfo(log, *track, debug_ >= 3);
0361     }
0362     log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n";
0363   }
0364 }
0365 
0366 void L1TrackVertexAssociationProducer::printTrackInfo(edm::LogInfo& log,
0367                                                       const TTTrackType& track,
0368                                                       bool printEmulation) const {
0369   log << "\t(" << track.momentum().perp() << ", " << track.momentum().eta() << ", " << track.momentum().phi() << ", "
0370       << track.getStubRefs().size() << ", " << track.stubPtConsistency() << ", " << track.chi2ZRed() << ", "
0371       << track.chi2XYRed() << ", " << track.z0() << ")\n";
0372 
0373   if (printEmulation) {
0374     ap_uint<TrackBitWidths::kPtSize> ptEmulationBits = track.getTrackWord()(
0375         TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0376     ap_ufixed<TrackBitWidths::kPtSize, TrackBitWidths::kPtMagSize> ptEmulation;
0377     ptEmulation.V = ptEmulationBits.range();
0378     TTTrack_TrackWord::tanl_t etaEmulationBits = track.getTanlWord();
0379     ap_fixed<TrackBitWidths::kEtaSize, TrackBitWidths::kEtaMagSize> etaEmulation;
0380     etaEmulation.V = etaEmulationBits.range();
0381     double floatTkZ0 = track.undigitizeSignedValue(
0382         track.getZ0Bits(), TTTrack_TrackWord::TrackBitWidths::kZ0Size, TTTrack_TrackWord::stepZ0, 0.0);
0383     double floatTkPhi = track.undigitizeSignedValue(
0384         track.getPhiBits(), TTTrack_TrackWord::TrackBitWidths::kPhiSize, TTTrack_TrackWord::stepPhi0, 0.0);
0385     log << "\t\t(" << ptEmulation.to_double() << ", " << etaEmulation.to_double() << ", " << floatTkPhi << ", "
0386         << track.getNStubs() << ", " << track.getBendChi2() << ", " << track.getChi2RZ() << ", " << track.getChi2RPhi()
0387         << ", " << floatTkZ0 << ")\n";
0388   }
0389 }
0390 
0391 // ------------ method called to produce the data  ------------
0392 void L1TrackVertexAssociationProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0393   auto vTTTrackAssociatedOutput = std::make_unique<TTTrackRefCollectionType>();
0394   auto vTTTrackAssociatedEmulationOutput = std::make_unique<TTTrackRefCollectionType>();
0395 
0396   TTTrackCollectionHandle l1TracksHandle;
0397   edm::Handle<TTTrackRefCollectionType> l1SelectedTracksHandle;
0398   edm::Handle<TTTrackRefCollectionType> l1SelectedTracksEmulationHandle;
0399   edm::Handle<l1t::VertexCollection> l1VerticesHandle;
0400   edm::Handle<l1t::VertexWordCollection> l1VerticesEmulationHandle;
0401 
0402   l1t::Vertex leadingVertex;
0403   l1t::VertexWord leadingEmulationVertex;
0404 
0405   TTTrackWordLinkLimitSelector linkLimitSel(fwNTrackSetsTVA_);     //stateful functor for simulated tracks
0406   TTTrackWordLinkLimitSelector linkLimitSelEmu(fwNTrackSetsTVA_);  //stateful functor for emulated tracks
0407 
0408   TTTrackDeltaZMaxSelector deltaZSel(deltaZMaxEtaBounds_, deltaZMax_);
0409   TTTrackWordDeltaZMaxSelector deltaZSelEmu(deltaZMaxEtaBounds_, deltaZMax_);
0410 
0411   iEvent.getByToken(l1TracksToken_, l1TracksHandle);
0412   size_t nOutputApproximate = l1TracksHandle->size();
0413 
0414   if (processSimulatedTracks_) {
0415     iEvent.getByToken(l1SelectedTracksToken_, l1SelectedTracksHandle);
0416     iEvent.getByToken(l1VerticesToken_, l1VerticesHandle);
0417     leadingVertex = l1VerticesHandle->at(0);
0418     if (debug_ >= 2) {
0419       edm::LogInfo("L1TrackVertexAssociationProducer") << "leading vertex z0 = " << leadingVertex.z0();
0420     }
0421     vTTTrackAssociatedOutput->reserve(nOutputApproximate);
0422   }
0423   if (processEmulatedTracks_) {
0424     iEvent.getByToken(l1SelectedTracksEmulationToken_, l1SelectedTracksEmulationHandle);
0425     iEvent.getByToken(l1VerticesEmulationToken_, l1VerticesEmulationHandle);
0426     leadingEmulationVertex = l1VerticesEmulationHandle->at(0);
0427     if (debug_ >= 2) {
0428       edm::LogInfo("L1TrackVertexAssociationProducer")
0429           << "leading emulation vertex z0 = " << leadingEmulationVertex.z0();
0430     }
0431     vTTTrackAssociatedEmulationOutput->reserve(nOutputApproximate);
0432   }
0433   for (size_t i = 0; i < nOutputApproximate; i++) {
0434     const auto& track = l1TracksHandle->at(i);
0435     if (processSimulatedTracks_) {
0436       // Limit the number of processed tracks according to the firmware capability: must be run on non-selected tracks (i.e. GTTConverted tracks)
0437       bool passLinkLimit = linkLimitSel(track);
0438       // Only match Selected tracks, by testing that the track is in the SelectedTracks collection
0439       auto itr = std::find_if(l1SelectedTracksHandle->begin(), l1SelectedTracksHandle->end(), [track](const auto& ref) {
0440         return (*ref).getTrackWord() == track.getTrackWord();
0441       });
0442       bool passSelection = (itr != l1SelectedTracksHandle->end());
0443       // Associate tracks based on the simulation delta Z
0444       if (passLinkLimit && passSelection && deltaZSel(track, leadingVertex)) {
0445         vTTTrackAssociatedOutput->push_back(TTTrackRef(l1TracksHandle, i));
0446       }
0447     }  //end if (processSimulatedTracks_)
0448     if (processEmulatedTracks_) {
0449       // Limit the number of processed tracks according to the firmware capability: must be run on non-selected tracks (i.e. GTTConverted tracks)
0450       bool passLinkLimitEmu = linkLimitSelEmu(track);
0451       // Only match Selected tracks, by testing that the track is in the SelectedTracks collection
0452       auto itrEmu = std::find_if(l1SelectedTracksEmulationHandle->begin(),
0453                                  l1SelectedTracksEmulationHandle->end(),
0454                                  [track](const auto& ref) { return (*ref).getTrackWord() == track.getTrackWord(); });
0455       bool passSelectionEmu = (itrEmu != l1SelectedTracksEmulationHandle->end());
0456       // Associated tracks based on the bitwise accurate TTTrack_TrackWord
0457       if (passLinkLimitEmu && passSelectionEmu && deltaZSelEmu(track, l1VerticesEmulationHandle->at(0))) {
0458         vTTTrackAssociatedEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i));
0459       }  //end block for satisfying LinkLimitEmu and SelectionEmu criteria
0460     }    //end if (processEmulatedTracks_)
0461   }      //end loop over input converted tracks
0462 
0463   if (processSimulatedTracks_) {
0464     iEvent.put(std::move(vTTTrackAssociatedOutput), outputCollectionName_);
0465   }
0466 
0467   if (processEmulatedTracks_) {
0468     iEvent.put(std::move(vTTTrackAssociatedEmulationOutput), outputCollectionName_ + "Emulation");
0469     if (debug_ >= 2)
0470       linkLimitSelEmu.log();
0471   }
0472 
0473   if (processSimulatedTracks_ && processEmulatedTracks_ && debug_ >= 2) {
0474     printDebugInfo(l1SelectedTracksHandle,
0475                    l1SelectedTracksEmulationHandle,
0476                    vTTTrackAssociatedOutput,
0477                    vTTTrackAssociatedEmulationOutput);
0478   }
0479 }
0480 
0481 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0482 void L1TrackVertexAssociationProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0483   edm::ParameterSetDescription desc;
0484   desc.add<edm::InputTag>("l1TracksInputTag", edm::InputTag("l1tGTTInputProducer", "Level1TTTracksConverted"));
0485   desc.add<edm::InputTag>("l1SelectedTracksInputTag",
0486                           edm::InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelected"));
0487   desc.add<edm::InputTag>("l1SelectedTracksEmulationInputTag",
0488                           edm::InputTag("l1tTrackSelectionProducer", "Level1TTTracksSelectedEmulation"));
0489   desc.add<edm::InputTag>("l1VerticesInputTag", edm::InputTag("l1tVertexFinder", "L1Vertices"));
0490   desc.add<edm::InputTag>("l1VerticesEmulationInputTag",
0491                           edm::InputTag("l1tVertexFinderEmulator", "L1VerticesEmulation"));
0492   desc.add<std::string>("outputCollectionName", "Level1TTTracksSelectedAssociated");
0493   {
0494     edm::ParameterSetDescription descCutSet;
0495     descCutSet.add<std::vector<double>>("deltaZMaxEtaBounds", {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4})
0496         ->setComment("these values define the bin boundaries in |eta|");
0497     descCutSet.add<std::vector<double>>("deltaZMax", {0.37, 0.50, 0.60, 0.75, 1.00, 1.60})
0498         ->setComment(
0499             "delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, "
0500             "[cm]");
0501     desc.add<edm::ParameterSetDescription>("cutSet", descCutSet);
0502   }
0503   desc.add<double>("useDisplacedTracksDeltaZOverride", -1.0)
0504       ->setComment("override the deltaZ cut value for displaced tracks");
0505   desc.add<bool>("processSimulatedTracks", true)
0506       ->setComment("return selected tracks after cutting on the floating point values");
0507   desc.add<bool>("processEmulatedTracks", true)
0508       ->setComment("return selected tracks after cutting on the bitwise emulated values");
0509   desc.add<unsigned int>("fwNTrackSetsTVA", 94)->setComment("firmware limit on processed tracks per GTT input link");
0510   desc.add<int>("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3");
0511   descriptions.addWithDefaultLabel(desc);
0512 }
0513 
0514 //define this as a plug-in
0515 DEFINE_FWK_MODULE(L1TrackVertexAssociationProducer);