Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-08-26 00:19:29

0001 // -*- C++ -*-
0002 //
0003 // Package:    L1Trigger/L1TTrackMatch
0004 // Class:      L1TrackSelectionProducer
0005 //
0006 /**\class L1TrackSelectionProducer L1TrackSelectionProducer.cc L1Trigger/L1TTrackMatch/plugins/L1TrackSelectionProducer.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 //
0022 //
0023 
0024 // system include files
0025 #include <algorithm>
0026 #include <memory>
0027 #include <string>
0028 #include <vector>
0029 
0030 // Xilinx HLS includes
0031 #include <ap_fixed.h>
0032 #include <ap_int.h>
0033 
0034 // user include files
0035 #include "DataFormats/Common/interface/Handle.h"
0036 #include "DataFormats/Common/interface/Ref.h"
0037 #include "DataFormats/Common/interface/RefVector.h"
0038 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0039 #include "DataFormats/L1Trigger/interface/Vertex.h"
0040 #include "DataFormats/L1Trigger/interface/VertexWord.h"
0041 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0042 #include "CommonTools/Utils/interface/AndSelector.h"
0043 #include "CommonTools/Utils/interface/EtaRangeSelector.h"
0044 #include "CommonTools/Utils/interface/MinSelector.h"
0045 #include "CommonTools/Utils/interface/MinFunctionSelector.h"
0046 #include "CommonTools/Utils/interface/MinNumberSelector.h"
0047 #include "CommonTools/Utils/interface/PtMinSelector.h"
0048 #include "CommonTools/Utils/interface/Selection.h"
0049 #include "FWCore/Framework/interface/Frameworkfwd.h"
0050 #include "FWCore/Framework/interface/global/EDProducer.h"
0051 #include "FWCore/Framework/interface/Event.h"
0052 #include "FWCore/Framework/interface/MakerMacros.h"
0053 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0054 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0055 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0056 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0057 #include "FWCore/Utilities/interface/EDMException.h"
0058 #include "FWCore/Utilities/interface/StreamID.h"
0059 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0060 
0061 //
0062 // class declaration
0063 //
0064 
0065 class L1TrackSelectionProducer : public edm::global::EDProducer<> {
0066 public:
0067   explicit L1TrackSelectionProducer(const edm::ParameterSet&);
0068   ~L1TrackSelectionProducer() override;
0069 
0070   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0071 
0072 private:
0073   // ----------constants, enums and typedefs ---------
0074   // Relevant constants for the converted track word
0075   enum TrackBitWidths {
0076     kPtSize = TTTrack_TrackWord::TrackBitWidths::kRinvSize - 1,  // Width of pt
0077     kPtMagSize = 9,                                              // Width of pt magnitude (unsigned)
0078     kEtaSize = TTTrack_TrackWord::TrackBitWidths::kTanlSize,     // Width of eta
0079     kEtaMagSize = 3,                                             // Width of eta magnitude (signed)
0080   };
0081 
0082   typedef TTTrack<Ref_Phase2TrackerDigi_> L1Track;
0083   typedef std::vector<L1Track> TTTrackCollection;
0084   typedef edm::Handle<TTTrackCollection> TTTrackCollectionHandle;
0085   typedef edm::Ref<TTTrackCollection> TTTrackRef;
0086   typedef edm::RefVector<TTTrackCollection> TTTrackRefCollection;
0087   typedef std::unique_ptr<TTTrackRefCollection> TTTrackRefCollectionUPtr;
0088 
0089   // ----------member functions ----------------------
0090   void printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle,
0091                       const TTTrackRefCollectionUPtr& vTTTrackOutput,
0092                       const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput,
0093                       const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput,
0094                       const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const;
0095   void printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation = false) const;
0096   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0097 
0098   // ----------selectors -----------------------------
0099   // Based on recommendations from https://twiki.cern.ch/twiki/bin/view/CMSPublic/SWGuideGenericSelectors
0100   struct TTTrackPtMinSelector {
0101     TTTrackPtMinSelector(double ptMin) : ptMin_(ptMin) {}
0102     TTTrackPtMinSelector(const edm::ParameterSet& cfg) : ptMin_(cfg.template getParameter<double>("ptMin")) {}
0103     bool operator()(const L1Track& t) const { return t.momentum().perp() >= ptMin_; }
0104 
0105   private:
0106     double ptMin_;
0107   };
0108   struct TTTrackWordPtMinSelector {
0109     TTTrackWordPtMinSelector(double ptMin) : ptMin_(ptMin) {}
0110     TTTrackWordPtMinSelector(const edm::ParameterSet& cfg) : ptMin_(cfg.template getParameter<double>("ptMin")) {}
0111     bool operator()(const L1Track& t) const {
0112       ap_uint<TrackBitWidths::kPtSize> ptEmulationBits = t.getTrackWord()(
0113           TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0114       ap_ufixed<TrackBitWidths::kPtSize, TrackBitWidths::kPtMagSize> ptEmulation;
0115       ptEmulation.V = ptEmulationBits.range();
0116       //edm::LogInfo("L1TrackSelectionProducer") << "produce::Emulation track properties::ap_uint(bits) = " << ptEmulationBits.to_string(2)
0117       //                                         << " ap_ufixed(bits) = " << ptEmulation.to_string(2) << " ap_ufixed(float) = " << ptEmulation.to_double();
0118       return ptEmulation.to_double() >= ptMin_;
0119     }
0120 
0121   private:
0122     double ptMin_;
0123   };
0124   struct TTTrackAbsEtaMaxSelector {
0125     TTTrackAbsEtaMaxSelector(double absEtaMax) : absEtaMax_(absEtaMax) {}
0126     TTTrackAbsEtaMaxSelector(const edm::ParameterSet& cfg)
0127         : absEtaMax_(cfg.template getParameter<double>("absEtaMax")) {}
0128     bool operator()(const L1Track& t) const { return std::abs(t.momentum().eta()) <= absEtaMax_; }
0129 
0130   private:
0131     double absEtaMax_;
0132   };
0133   struct TTTrackWordAbsEtaMaxSelector {
0134     TTTrackWordAbsEtaMaxSelector(double absEtaMax) : absEtaMax_(absEtaMax) {}
0135     TTTrackWordAbsEtaMaxSelector(const edm::ParameterSet& cfg)
0136         : absEtaMax_(cfg.template getParameter<double>("absEtaMax")) {}
0137     bool operator()(const L1Track& t) const {
0138       TTTrack_TrackWord::tanl_t etaEmulationBits = t.getTanlWord();
0139       ap_fixed<TrackBitWidths::kEtaSize, TrackBitWidths::kEtaMagSize> etaEmulation;
0140       etaEmulation.V = etaEmulationBits.range();
0141       return std::abs(etaEmulation.to_double()) <= absEtaMax_;
0142     }
0143 
0144   private:
0145     double absEtaMax_;
0146   };
0147   struct TTTrackAbsZ0MaxSelector {
0148     TTTrackAbsZ0MaxSelector(double absZ0Max) : absZ0Max_(absZ0Max) {}
0149     TTTrackAbsZ0MaxSelector(const edm::ParameterSet& cfg) : absZ0Max_(cfg.template getParameter<double>("absZ0Max")) {}
0150     bool operator()(const L1Track& t) const { return std::abs(t.z0()) <= absZ0Max_; }
0151 
0152   private:
0153     double absZ0Max_;
0154   };
0155   struct TTTrackWordAbsZ0MaxSelector {
0156     TTTrackWordAbsZ0MaxSelector(double absZ0Max) : absZ0Max_(absZ0Max) {}
0157     TTTrackWordAbsZ0MaxSelector(const edm::ParameterSet& cfg)
0158         : absZ0Max_(cfg.template getParameter<double>("absZ0Max")) {}
0159     bool operator()(const L1Track& t) const { return std::abs(t.getZ0()) <= absZ0Max_; }
0160 
0161   private:
0162     double absZ0Max_;
0163   };
0164   struct TTTrackNStubsMinSelector {
0165     TTTrackNStubsMinSelector(double nStubsMin) : nStubsMin_(nStubsMin) {}
0166     TTTrackNStubsMinSelector(const edm::ParameterSet& cfg)
0167         : nStubsMin_(cfg.template getParameter<double>("nStubsMin")) {}
0168     bool operator()(const L1Track& t) const { return t.getStubRefs().size() >= nStubsMin_; }
0169 
0170   private:
0171     double nStubsMin_;
0172   };
0173   struct TTTrackWordNStubsMinSelector {
0174     TTTrackWordNStubsMinSelector(double nStubsMin) : nStubsMin_(nStubsMin) {}
0175     TTTrackWordNStubsMinSelector(const edm::ParameterSet& cfg)
0176         : nStubsMin_(cfg.template getParameter<double>("nStubsMin")) {}
0177     bool operator()(const L1Track& t) const { return t.getNStubs() >= nStubsMin_; }
0178 
0179   private:
0180     double nStubsMin_;
0181   };
0182   struct TTTrackNPSStubsMinSelector {
0183     TTTrackNPSStubsMinSelector(double nStubsMin, const TrackerTopology& tTopo)
0184         : nPSStubsMin_(nStubsMin), tTopo_(tTopo) {}
0185     TTTrackNPSStubsMinSelector(const edm::ParameterSet& cfg, const TrackerTopology& tTopo)
0186         : nPSStubsMin_(cfg.template getParameter<double>("nPSStubsMin")), tTopo_(tTopo) {}
0187     bool operator()(const L1Track& t) const {
0188       int nPSStubs = 0;
0189       for (const auto& stub : t.getStubRefs()) {
0190         DetId detId(stub->getDetId());
0191         if (detId.det() == DetId::Detector::Tracker) {
0192           if ((detId.subdetId() == StripSubdetector::TOB && tTopo_.tobLayer(detId) <= 3) ||
0193               (detId.subdetId() == StripSubdetector::TID && tTopo_.tidRing(detId) <= 9))
0194             nPSStubs++;
0195         }
0196       }
0197       return nPSStubs >= nPSStubsMin_;
0198     }
0199 
0200   private:
0201     double nPSStubsMin_;
0202     const TrackerTopology& tTopo_;
0203   };
0204   struct TTTrackBendChi2MaxSelector {
0205     TTTrackBendChi2MaxSelector(double bendChi2Max) : bendChi2Max_(bendChi2Max) {}
0206     TTTrackBendChi2MaxSelector(const edm::ParameterSet& cfg)
0207         : bendChi2Max_(cfg.template getParameter<double>("reducedBendChi2Max")) {}
0208     bool operator()(const L1Track& t) const { return t.stubPtConsistency() < bendChi2Max_; }
0209 
0210   private:
0211     double bendChi2Max_;
0212   };
0213   struct TTTrackWordBendChi2MaxSelector {
0214     TTTrackWordBendChi2MaxSelector(double bendChi2Max) : bendChi2Max_(bendChi2Max) {}
0215     TTTrackWordBendChi2MaxSelector(const edm::ParameterSet& cfg)
0216         : bendChi2Max_(cfg.template getParameter<double>("reducedBendChi2Max")) {}
0217     bool operator()(const L1Track& t) const { return t.getBendChi2() < bendChi2Max_; }
0218 
0219   private:
0220     double bendChi2Max_;
0221   };
0222   struct TTTrackChi2RZMaxSelector {
0223     TTTrackChi2RZMaxSelector(double reducedChi2RZMax) : reducedChi2RZMax_(reducedChi2RZMax) {}
0224     TTTrackChi2RZMaxSelector(const edm::ParameterSet& cfg)
0225         : reducedChi2RZMax_(cfg.template getParameter<double>("reducedChi2RZMax")) {}
0226     bool operator()(const L1Track& t) const { return t.chi2ZRed() < reducedChi2RZMax_; }
0227 
0228   private:
0229     double reducedChi2RZMax_;
0230   };
0231   struct TTTrackWordChi2RZMaxSelector {
0232     TTTrackWordChi2RZMaxSelector(double reducedChi2RZMax) : reducedChi2RZMax_(reducedChi2RZMax) {}
0233     TTTrackWordChi2RZMaxSelector(const edm::ParameterSet& cfg)
0234         : reducedChi2RZMax_(cfg.template getParameter<double>("reducedChi2RZMax")) {}
0235     bool operator()(const L1Track& t) const { return t.getChi2RZ() < reducedChi2RZMax_; }
0236 
0237   private:
0238     double reducedChi2RZMax_;
0239   };
0240   struct TTTrackChi2RPhiMaxSelector {
0241     TTTrackChi2RPhiMaxSelector(double reducedChi2RPhiMax) : reducedChi2RPhiMax_(reducedChi2RPhiMax) {}
0242     TTTrackChi2RPhiMaxSelector(const edm::ParameterSet& cfg)
0243         : reducedChi2RPhiMax_(cfg.template getParameter<double>("reducedChi2RPhiMax")) {}
0244     bool operator()(const L1Track& t) const { return t.chi2XYRed() < reducedChi2RPhiMax_; }
0245 
0246   private:
0247     double reducedChi2RPhiMax_;
0248   };
0249   struct TTTrackWordChi2RPhiMaxSelector {
0250     TTTrackWordChi2RPhiMaxSelector(double reducedChi2RPhiMax) : reducedChi2RPhiMax_(reducedChi2RPhiMax) {}
0251     TTTrackWordChi2RPhiMaxSelector(const edm::ParameterSet& cfg)
0252         : reducedChi2RPhiMax_(cfg.template getParameter<double>("reducedChi2RPhiMax")) {}
0253     bool operator()(const L1Track& t) const { return t.getChi2RPhi() < reducedChi2RPhiMax_; }
0254 
0255   private:
0256     double reducedChi2RPhiMax_;
0257   };
0258   struct TTTrackDeltaZMaxSelector {
0259     TTTrackDeltaZMaxSelector(const std::vector<double>& deltaZMaxEtaBounds, const std::vector<double>& deltaZMax)
0260         : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {}
0261     TTTrackDeltaZMaxSelector(const edm::ParameterSet& cfg)
0262         : deltaZMaxEtaBounds_(cfg.template getParameter<double>("deltaZMaxEtaBounds")),
0263           deltaZMax_(cfg.template getParameter<double>("deltaZMax")) {}
0264     bool operator()(const L1Track& t, const l1t::Vertex& v) const {
0265       size_t etaIndex =
0266           std::lower_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) -
0267           deltaZMaxEtaBounds_.begin() - 1;
0268       if (etaIndex > deltaZMax_.size() - 1)
0269         etaIndex = deltaZMax_.size() - 1;
0270       return std::abs(v.z0() - t.z0()) <= deltaZMax_[etaIndex];
0271     }
0272 
0273   private:
0274     std::vector<double> deltaZMaxEtaBounds_;
0275     std::vector<double> deltaZMax_;
0276   };
0277   struct TTTrackWordDeltaZMaxSelector {
0278     TTTrackWordDeltaZMaxSelector(const std::vector<double>& deltaZMaxEtaBounds, const std::vector<double>& deltaZMax)
0279         : deltaZMaxEtaBounds_(deltaZMaxEtaBounds), deltaZMax_(deltaZMax) {}
0280     TTTrackWordDeltaZMaxSelector(const edm::ParameterSet& cfg)
0281         : deltaZMaxEtaBounds_(cfg.template getParameter<double>("deltaZMaxEtaBounds")),
0282           deltaZMax_(cfg.template getParameter<double>("deltaZMax")) {}
0283     bool operator()(const L1Track& t, const l1t::VertexWord& v) const {
0284       size_t etaIndex =
0285           std::lower_bound(deltaZMaxEtaBounds_.begin(), deltaZMaxEtaBounds_.end(), std::abs(t.momentum().eta())) -
0286           deltaZMaxEtaBounds_.begin() - 1;
0287       if (etaIndex > deltaZMax_.size() - 1)
0288         etaIndex = deltaZMax_.size() - 1;
0289       return std::abs(v.z0() - t.getZ0()) <= deltaZMax_[etaIndex];
0290     }
0291 
0292   private:
0293     std::vector<double> deltaZMaxEtaBounds_;
0294     std::vector<double> deltaZMax_;
0295   };
0296 
0297   typedef AndSelector<TTTrackPtMinSelector, TTTrackAbsEtaMaxSelector, TTTrackAbsZ0MaxSelector, TTTrackNStubsMinSelector>
0298       TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector;
0299   typedef AndSelector<TTTrackWordPtMinSelector,
0300                       TTTrackWordAbsEtaMaxSelector,
0301                       TTTrackWordAbsZ0MaxSelector,
0302                       TTTrackWordNStubsMinSelector>
0303       TTTrackWordPtMinEtaMaxZ0MaxNStubsMinSelector;
0304   typedef AndSelector<TTTrackBendChi2MaxSelector, TTTrackChi2RZMaxSelector, TTTrackChi2RPhiMaxSelector>
0305       TTTrackBendChi2Chi2RZChi2RPhiMaxSelector;
0306   typedef AndSelector<TTTrackWordBendChi2MaxSelector, TTTrackWordChi2RZMaxSelector, TTTrackWordChi2RPhiMaxSelector>
0307       TTTrackWordBendChi2Chi2RZChi2RPhiMaxSelector;
0308 
0309   // ----------member data ---------------------------
0310   const edm::EDGetTokenT<TTTrackCollection> l1TracksToken_;
0311   edm::EDGetTokenT<l1t::VertexCollection> l1VerticesToken_;
0312   edm::EDGetTokenT<l1t::VertexWordCollection> l1VerticesEmulationToken_;
0313   edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> tTopoToken_;
0314   const std::string outputCollectionName_;
0315   const edm::ParameterSet cutSet_;
0316   const double ptMin_, absEtaMax_, absZ0Max_, bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_;
0317   const int nStubsMin_, nPSStubsMin_;
0318   std::vector<double> deltaZMaxEtaBounds_, deltaZMax_;
0319   const double useDisplacedTracksDeltaZOverride_;
0320   bool processSimulatedTracks_, processEmulatedTracks_, doDeltaZCutSim_, doDeltaZCutEmu_;
0321   int debug_;
0322 };
0323 
0324 //
0325 // constructors and destructor
0326 //
0327 L1TrackSelectionProducer::L1TrackSelectionProducer(const edm::ParameterSet& iConfig)
0328     : l1TracksToken_(consumes<TTTrackCollection>(iConfig.getParameter<edm::InputTag>("l1TracksInputTag"))),
0329       tTopoToken_(esConsumes<TrackerTopology, TrackerTopologyRcd>(edm::ESInputTag("", ""))),
0330       outputCollectionName_(iConfig.getParameter<std::string>("outputCollectionName")),
0331       cutSet_(iConfig.getParameter<edm::ParameterSet>("cutSet")),
0332 
0333       ptMin_(cutSet_.getParameter<double>("ptMin")),
0334       absEtaMax_(cutSet_.getParameter<double>("absEtaMax")),
0335       absZ0Max_(cutSet_.getParameter<double>("absZ0Max")),
0336       bendChi2Max_(cutSet_.getParameter<double>("reducedBendChi2Max")),
0337       reducedChi2RZMax_(cutSet_.getParameter<double>("reducedChi2RZMax")),
0338       reducedChi2RPhiMax_(cutSet_.getParameter<double>("reducedChi2RPhiMax")),
0339       nStubsMin_(cutSet_.getParameter<int>("nStubsMin")),
0340       nPSStubsMin_(cutSet_.getParameter<int>("nPSStubsMin")),
0341       deltaZMaxEtaBounds_(cutSet_.getParameter<std::vector<double>>("deltaZMaxEtaBounds")),
0342       deltaZMax_(cutSet_.getParameter<std::vector<double>>("deltaZMax")),
0343 
0344       useDisplacedTracksDeltaZOverride_(iConfig.getParameter<double>("useDisplacedTracksDeltaZOverride")),
0345       processSimulatedTracks_(iConfig.getParameter<bool>("processSimulatedTracks")),
0346       processEmulatedTracks_(iConfig.getParameter<bool>("processEmulatedTracks")),
0347       debug_(iConfig.getParameter<int>("debug")) {
0348   // Confirm the the configuration makes sense
0349   if (!processSimulatedTracks_ && !processEmulatedTracks_) {
0350     throw cms::Exception("You must process at least one of the track collections (simulated or emulated).");
0351   }
0352 
0353   if (deltaZMax_.size() != deltaZMaxEtaBounds_.size() - 1) {
0354     throw cms::Exception("The number of deltaZ cuts does not match the number of eta bins!");
0355   }
0356 
0357   if (useDisplacedTracksDeltaZOverride_ >= 0) {
0358     deltaZMax_ = std::vector<double>(deltaZMax_.size(), useDisplacedTracksDeltaZOverride_);
0359   }
0360 
0361   // Get additional input tags and define the EDM output based on the previous configuration parameters
0362   doDeltaZCutSim_ = false;
0363   doDeltaZCutEmu_ = false;
0364   if (processSimulatedTracks_) {
0365     produces<TTTrackRefCollection>(outputCollectionName_);
0366     if (iConfig.exists("l1VerticesInputTag")) {
0367       l1VerticesToken_ = consumes<l1t::VertexCollection>(iConfig.getParameter<edm::InputTag>("l1VerticesInputTag"));
0368       doDeltaZCutSim_ = true;
0369       produces<TTTrackRefCollection>(outputCollectionName_ + "Associated");
0370     }
0371   }
0372   if (processEmulatedTracks_) {
0373     produces<TTTrackRefCollection>(outputCollectionName_ + "Emulation");
0374     if (iConfig.exists("l1VerticesEmulationInputTag")) {
0375       l1VerticesEmulationToken_ =
0376           consumes<l1t::VertexWordCollection>(iConfig.getParameter<edm::InputTag>("l1VerticesEmulationInputTag"));
0377       doDeltaZCutEmu_ = true;
0378       produces<TTTrackRefCollection>(outputCollectionName_ + "AssociatedEmulation");
0379     }
0380   }
0381 }
0382 
0383 L1TrackSelectionProducer::~L1TrackSelectionProducer() {}
0384 
0385 //
0386 // member functions
0387 //
0388 
0389 void L1TrackSelectionProducer::printDebugInfo(const TTTrackCollectionHandle& l1TracksHandle,
0390                                               const TTTrackRefCollectionUPtr& vTTTrackOutput,
0391                                               const TTTrackRefCollectionUPtr& vTTTrackEmulationOutput,
0392                                               const TTTrackRefCollectionUPtr& vTTTrackAssociatedOutput,
0393                                               const TTTrackRefCollectionUPtr& vTTTrackAssociatedEmulationOutput) const {
0394   edm::LogInfo log("L1TrackSelectionProducer");
0395   log << "The original track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are ... \n";
0396   for (const auto& track : *l1TracksHandle) {
0397     printTrackInfo(log, track, debug_ >= 4);
0398   }
0399   log << "\t---\n\tNumber of tracks in this selection = " << l1TracksHandle->size() << "\n\n";
0400   if (processSimulatedTracks_) {
0401     log << "The selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are ... \n";
0402     for (const auto& track : *vTTTrackOutput) {
0403       printTrackInfo(log, *track, debug_ >= 4);
0404     }
0405     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackOutput->size() << "\n\n";
0406   }
0407   if (processEmulatedTracks_) {
0408     log << "The emulation selected track collection (pt, eta, phi, nstub, bendchi2, chi2rz, chi2rphi, z0) values are "
0409            "... \n";
0410     for (const auto& track : *vTTTrackEmulationOutput) {
0411       printTrackInfo(log, *track, debug_ >= 4);
0412     }
0413     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackEmulationOutput->size() << "\n\n";
0414   }
0415   if (processSimulatedTracks_ && processEmulatedTracks_) {
0416     TTTrackRefCollection inSimButNotEmu;
0417     TTTrackRefCollection inEmuButNotSim;
0418     std::set_difference(vTTTrackOutput->begin(),
0419                         vTTTrackOutput->end(),
0420                         vTTTrackEmulationOutput->begin(),
0421                         vTTTrackEmulationOutput->end(),
0422                         std::back_inserter(inSimButNotEmu));
0423     std::set_difference(vTTTrackEmulationOutput->begin(),
0424                         vTTTrackEmulationOutput->end(),
0425                         vTTTrackOutput->begin(),
0426                         vTTTrackOutput->end(),
0427                         std::back_inserter(inEmuButNotSim));
0428     log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected "
0429            "by cutting on the emulated values ... \n";
0430     for (const auto& track : inSimButNotEmu) {
0431       printTrackInfo(log, *track, debug_ >= 3);
0432     }
0433     log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n"
0434         << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected "
0435            "by cutting on the simulated values ... \n";
0436     for (const auto& track : inEmuButNotSim) {
0437       printTrackInfo(log, *track, debug_ >= 3);
0438     }
0439     log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n";
0440   }
0441   if (processSimulatedTracks_) {
0442     log << "The selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, chi2rz, "
0443            "chi2rphi, z0) values are ... \n";
0444     for (const auto& track : *vTTTrackAssociatedOutput) {
0445       printTrackInfo(log, *track, debug_ >= 4);
0446     }
0447     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedOutput->size() << "\n\n";
0448   }
0449   if (processEmulatedTracks_) {
0450     log << "The emulation selected and leading vertex associated track collection (pt, eta, phi, nstub, bendchi2, "
0451            "chi2rz, chi2rphi, z0) values are "
0452            "... \n";
0453     for (const auto& track : *vTTTrackAssociatedEmulationOutput) {
0454       printTrackInfo(log, *track, debug_ >= 4);
0455     }
0456     log << "\t---\n\tNumber of tracks in this selection = " << vTTTrackAssociatedEmulationOutput->size() << "\n\n";
0457   }
0458   if (processSimulatedTracks_ && processEmulatedTracks_) {
0459     TTTrackRefCollection inSimButNotEmu;
0460     TTTrackRefCollection inEmuButNotSim;
0461     std::set_difference(vTTTrackAssociatedOutput->begin(),
0462                         vTTTrackAssociatedOutput->end(),
0463                         vTTTrackAssociatedEmulationOutput->begin(),
0464                         vTTTrackAssociatedEmulationOutput->end(),
0465                         std::back_inserter(inSimButNotEmu));
0466     std::set_difference(vTTTrackAssociatedEmulationOutput->begin(),
0467                         vTTTrackAssociatedEmulationOutput->end(),
0468                         vTTTrackAssociatedOutput->begin(),
0469                         vTTTrackAssociatedOutput->end(),
0470                         std::back_inserter(inEmuButNotSim));
0471     log << "The set of tracks selected via cuts on the simulated values which are not in the set of tracks selected "
0472            "by cutting on the emulated values ... \n";
0473     for (const auto& track : inSimButNotEmu) {
0474       printTrackInfo(log, *track, debug_ >= 3);
0475     }
0476     log << "\t---\n\tNumber of tracks in this selection = " << inSimButNotEmu.size() << "\n\n"
0477         << "The set of tracks selected via cuts on the emulated values which are not in the set of tracks selected "
0478            "by cutting on the simulated values ... \n";
0479     for (const auto& track : inEmuButNotSim) {
0480       printTrackInfo(log, *track, debug_ >= 3);
0481     }
0482     log << "\t---\n\tNumber of tracks in this selection = " << inEmuButNotSim.size() << "\n\n";
0483   }
0484 }
0485 
0486 void L1TrackSelectionProducer::printTrackInfo(edm::LogInfo& log, const L1Track& track, bool printEmulation) const {
0487   log << "\t(" << track.momentum().perp() << ", " << track.momentum().eta() << ", " << track.momentum().phi() << ", "
0488       << track.getStubRefs().size() << ", " << track.stubPtConsistency() << ", " << track.chi2ZRed() << ", "
0489       << track.chi2XYRed() << ", " << track.z0() << ")\n";
0490 
0491   if (printEmulation) {
0492     ap_uint<TrackBitWidths::kPtSize> ptEmulationBits = track.getTrackWord()(
0493         TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1, TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
0494     ap_ufixed<TrackBitWidths::kPtSize, TrackBitWidths::kPtMagSize> ptEmulation;
0495     ptEmulation.V = ptEmulationBits.range();
0496     TTTrack_TrackWord::tanl_t etaEmulationBits = track.getTanlWord();
0497     ap_fixed<TrackBitWidths::kEtaSize, TrackBitWidths::kEtaMagSize> etaEmulation;
0498     etaEmulation.V = etaEmulationBits.range();
0499     log << "\t\t(" << ptEmulation.to_double() << ", " << etaEmulation.to_double() << ", " << track.getPhi() << ", "
0500         << track.getNStubs() << ", " << track.getBendChi2() << ", " << track.getChi2RZ() << ", " << track.getChi2RPhi()
0501         << ", " << track.getZ0() << ")\n";
0502   }
0503 }
0504 
0505 // ------------ method called to produce the data  ------------
0506 void L1TrackSelectionProducer::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
0507   auto vTTTrackOutput = std::make_unique<TTTrackRefCollection>();
0508   auto vTTTrackAssociatedOutput = std::make_unique<TTTrackRefCollection>();
0509   auto vTTTrackEmulationOutput = std::make_unique<TTTrackRefCollection>();
0510   auto vTTTrackAssociatedEmulationOutput = std::make_unique<TTTrackRefCollection>();
0511 
0512   // Tracker Topology
0513   const TrackerTopology& tTopo = iSetup.getData(tTopoToken_);
0514 
0515   TTTrackCollectionHandle l1TracksHandle;
0516   edm::Handle<l1t::VertexCollection> l1VerticesHandle;
0517   edm::Handle<l1t::VertexWordCollection> l1VerticesEmulationHandle;
0518 
0519   l1t::Vertex leadingVertex;
0520   l1t::VertexWord leadingEmulationVertex;
0521 
0522   iEvent.getByToken(l1TracksToken_, l1TracksHandle);
0523   size_t nOutputApproximate = l1TracksHandle->size();
0524   if (processSimulatedTracks_) {
0525     if (doDeltaZCutSim_) {
0526       iEvent.getByToken(l1VerticesToken_, l1VerticesHandle);
0527       leadingVertex = l1VerticesHandle->at(0);
0528       if (debug_ >= 2) {
0529         edm::LogInfo("L1TrackSelectionProducer") << "leading vertex z0 = " << leadingVertex.z0();
0530       }
0531     }
0532     vTTTrackOutput->reserve(nOutputApproximate);
0533     vTTTrackAssociatedOutput->reserve(nOutputApproximate);
0534   }
0535   if (processEmulatedTracks_) {
0536     if (doDeltaZCutEmu_) {
0537       iEvent.getByToken(l1VerticesEmulationToken_, l1VerticesEmulationHandle);
0538       leadingEmulationVertex = l1VerticesEmulationHandle->at(0);
0539       if (debug_ >= 2) {
0540         edm::LogInfo("L1TrackSelectionProducer") << "leading emulation vertex z0 = " << leadingEmulationVertex.z0();
0541       }
0542     }
0543     vTTTrackEmulationOutput->reserve(nOutputApproximate);
0544     vTTTrackAssociatedEmulationOutput->reserve(nOutputApproximate);
0545   }
0546 
0547   TTTrackPtMinEtaMaxZ0MaxNStubsMinSelector kinSel(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_);
0548   TTTrackWordPtMinEtaMaxZ0MaxNStubsMinSelector kinSelEmu(ptMin_, absEtaMax_, absZ0Max_, nStubsMin_);
0549   TTTrackBendChi2Chi2RZChi2RPhiMaxSelector chi2Sel(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_);
0550   TTTrackWordBendChi2Chi2RZChi2RPhiMaxSelector chi2SelEmu(bendChi2Max_, reducedChi2RZMax_, reducedChi2RPhiMax_);
0551   TTTrackDeltaZMaxSelector deltaZSel(deltaZMaxEtaBounds_, deltaZMax_);
0552   TTTrackWordDeltaZMaxSelector deltaZSelEmu(deltaZMaxEtaBounds_, deltaZMax_);
0553   TTTrackNPSStubsMinSelector nPSStubsSel(nPSStubsMin_, tTopo);
0554 
0555   for (size_t i = 0; i < nOutputApproximate; i++) {
0556     const auto& track = l1TracksHandle->at(i);
0557 
0558     // Select tracks based on the floating point TTTrack
0559     if (processSimulatedTracks_ && kinSel(track) && nPSStubsSel(track) && chi2Sel(track)) {
0560       vTTTrackOutput->push_back(TTTrackRef(l1TracksHandle, i));
0561       if (doDeltaZCutSim_ && deltaZSel(track, leadingVertex)) {
0562         vTTTrackAssociatedOutput->push_back(TTTrackRef(l1TracksHandle, i));
0563       }
0564     }
0565 
0566     // Select tracks based on the bitwise accurate TTTrack_TrackWord
0567     if (processEmulatedTracks_ && kinSelEmu(track) && chi2SelEmu(track)) {
0568       vTTTrackEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i));
0569       if (doDeltaZCutEmu_ && deltaZSelEmu(track, leadingEmulationVertex)) {
0570         vTTTrackAssociatedEmulationOutput->push_back(TTTrackRef(l1TracksHandle, i));
0571       }
0572     }
0573   }
0574 
0575   if (debug_ >= 2) {
0576     printDebugInfo(l1TracksHandle,
0577                    vTTTrackOutput,
0578                    vTTTrackEmulationOutput,
0579                    vTTTrackAssociatedOutput,
0580                    vTTTrackAssociatedEmulationOutput);
0581   }
0582 
0583   // Put the outputs into the event
0584   if (processSimulatedTracks_) {
0585     iEvent.put(std::move(vTTTrackOutput), outputCollectionName_);
0586     if (doDeltaZCutSim_) {
0587       iEvent.put(std::move(vTTTrackAssociatedOutput), outputCollectionName_ + "Associated");
0588     }
0589   }
0590   if (processEmulatedTracks_) {
0591     iEvent.put(std::move(vTTTrackEmulationOutput), outputCollectionName_ + "Emulation");
0592     if (doDeltaZCutEmu_) {
0593       iEvent.put(std::move(vTTTrackAssociatedEmulationOutput), outputCollectionName_ + "AssociatedEmulation");
0594     }
0595   }
0596 }
0597 
0598 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
0599 void L1TrackSelectionProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0600   //L1TrackSelectionProducer
0601   edm::ParameterSetDescription desc;
0602   desc.add<edm::InputTag>("l1TracksInputTag", edm::InputTag("TTTracksFromTrackletEmulation", "Level1TTTracks"));
0603   desc.addOptional<edm::InputTag>("l1VerticesInputTag", edm::InputTag("L1VertexFinder", "l1vertices"));
0604   desc.addOptional<edm::InputTag>("l1VerticesEmulationInputTag",
0605                                   edm::InputTag("L1VertexFinderEmulator", "l1verticesEmulation"));
0606   desc.add<std::string>("outputCollectionName", "Level1TTTracksSelected");
0607   {
0608     edm::ParameterSetDescription descCutSet;
0609     descCutSet.add<double>("ptMin", 2.0)->setComment("pt must be greater than this value, [GeV]");
0610     descCutSet.add<double>("absEtaMax", 2.4)->setComment("absolute value of eta must be less than this value");
0611     descCutSet.add<double>("absZ0Max", 15.0)->setComment("z0 must be less than this value, [cm]");
0612     descCutSet.add<int>("nStubsMin", 4)->setComment("number of stubs must be greater than or equal to this value");
0613     descCutSet.add<int>("nPSStubsMin", 0)
0614         ->setComment("number of stubs in the PS Modules must be greater than or equal to this value");
0615 
0616     descCutSet.add<double>("reducedBendChi2Max", 2.25)->setComment("bend chi2 must be less than this value");
0617     descCutSet.add<double>("reducedChi2RZMax", 5.0)->setComment("chi2rz/dof must be less than this value");
0618     descCutSet.add<double>("reducedChi2RPhiMax", 20.0)->setComment("chi2rphi/dof must be less than this value");
0619 
0620     descCutSet.add<std::vector<double>>("deltaZMaxEtaBounds", {0.0, 0.7, 1.0, 1.2, 1.6, 2.0, 2.4})
0621         ->setComment("these values define the bin boundaries in |eta|");
0622     descCutSet.add<std::vector<double>>("deltaZMax", {0.37, 0.50, 0.60, 0.75, 1.00, 1.60})
0623         ->setComment(
0624             "delta z must be less than these values, there will be one less value here than in deltaZMaxEtaBounds, "
0625             "[cm]");
0626     desc.add<edm::ParameterSetDescription>("cutSet", descCutSet);
0627   }
0628   desc.add<double>("useDisplacedTracksDeltaZOverride", -1.0)
0629       ->setComment("override the deltaZ cut value for displaced tracks");
0630   desc.add<bool>("processSimulatedTracks", true)
0631       ->setComment("return selected tracks after cutting on the floating point values");
0632   desc.add<bool>("processEmulatedTracks", true)
0633       ->setComment("return selected tracks after cutting on the bitwise emulated values");
0634   desc.add<int>("debug", 0)->setComment("Verbosity levels: 0, 1, 2, 3");
0635   descriptions.addWithDefaultLabel(desc);
0636 }
0637 
0638 //define this as a plug-in
0639 DEFINE_FWK_MODULE(L1TrackSelectionProducer);