Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:21:53

0001 #include "L1Trigger/TrackFindingTMTT/interface/Utility.h"
0002 #include "L1Trigger/TrackFindingTMTT/interface/TP.h"
0003 #include "L1Trigger/TrackFindingTMTT/interface/Stub.h"
0004 #include "L1Trigger/TrackFindingTMTT/interface/Settings.h"
0005 
0006 #include "FWCore/Utilities/interface/Exception.h"
0007 
0008 #include <unordered_set>
0009 
0010 using namespace std;
0011 
0012 namespace tmtt {
0013 
0014   //=== Count number of tracker layers a given list of stubs are in.
0015   //=== By default, consider both PS+2S modules, but optionally consider only the PS ones.
0016 
0017   unsigned int Utility::countLayers(const Settings* settings,
0018                                     const std::vector<Stub*>& stubs,
0019                                     bool disableReducedLayerID,
0020                                     bool onlyPS) {
0021     std::vector<const Stub*> stubsConst(stubs.begin(), stubs.end());
0022     return countLayers(settings, stubsConst, disableReducedLayerID, onlyPS);
0023   }
0024 
0025   unsigned int Utility::countLayers(const Settings* settings,
0026                                     const vector<const Stub*>& vstubs,
0027                                     bool disableReducedLayerID,
0028                                     bool onlyPS) {
0029     //=== Unpack configuration parameters
0030 
0031     // Note if using reduced layer ID, so tracker layer can be encoded in 3 bits.
0032     const bool reduceLayerID = settings->reduceLayerID();
0033 
0034     // Disable use of reduced layer ID if requested, otherwise take from cfg.
0035     bool reduce = (disableReducedLayerID) ? false : reduceLayerID;
0036 
0037     // Count layers using CMSSW layer ID.
0038     unordered_set<unsigned int> foundLayers;
0039     for (const Stub* stub : vstubs) {
0040       if ((!onlyPS) || stub->psModule()) {  // Consider only stubs in PS modules if that option specified.
0041         // Use either normal or reduced layer ID depending on request.
0042         int layerID = reduce ? stub->layerIdReduced() : stub->layerId();
0043         foundLayers.insert(layerID);
0044       }
0045     }
0046 
0047     return foundLayers.size();
0048   }
0049 
0050   //=== Given a set of stubs (presumably on a reconstructed track candidate)
0051   //=== return the best matching Tracking Particle (if any),
0052   //=== the number of tracker layers in which one of the stubs matched one from this tracking particle,
0053   //=== and the list of the subset of the stubs which match those on the tracking particle.
0054 
0055   const TP* Utility::matchingTP(const Settings* settings,
0056                                 const std::vector<Stub*>& vstubs,
0057                                 unsigned int& nMatchedLayersBest,
0058                                 std::vector<const Stub*>& matchedStubsBest) {
0059     std::vector<const Stub*> stubsConst(vstubs.begin(), vstubs.end());
0060     return matchingTP(settings, stubsConst, nMatchedLayersBest, matchedStubsBest);
0061   }
0062 
0063   const TP* Utility::matchingTP(const Settings* settings,
0064                                 const vector<const Stub*>& vstubs,
0065                                 unsigned int& nMatchedLayersBest,
0066                                 vector<const Stub*>& matchedStubsBest) {
0067     // Get matching criteria
0068     const double minFracMatchStubsOnReco = settings->minFracMatchStubsOnReco();
0069     const double minFracMatchStubsOnTP = settings->minFracMatchStubsOnTP();
0070     const unsigned int minNumMatchLayers = settings->minNumMatchLayers();
0071     const unsigned int minNumMatchPSLayers = settings->minNumMatchPSLayers();
0072 
0073     // Loop over the given stubs, looking at the TP that produced each one.
0074 
0075     map<const TP*, vector<const Stub*> > tpsToStubs;
0076     map<const TP*, vector<const Stub*> > tpsToStubsStrict;
0077 
0078     for (const Stub* s : vstubs) {
0079       // If this stub was produced by one or more TPs, store a link from the TPs to the stub.
0080       // (The assocated TPs here are influenced by config param "StubMatchStrict").
0081       for (const TP* tp_i : s->assocTPs()) {
0082         tpsToStubs[tp_i].push_back(s);
0083       }
0084       // To resolve tie-break situations, do the same, but now only considering strictly associated TP, where the TP contributed
0085       // to both clusters making up stub.
0086       if (s->assocTP() != nullptr) {
0087         tpsToStubsStrict[s->assocTP()].push_back(s);
0088       }
0089     }
0090 
0091     // Loop over all the TP that matched the given stubs, looking for the best matching TP.
0092 
0093     nMatchedLayersBest = 0;
0094     unsigned int nMatchedLayersStrictBest = 0;
0095     matchedStubsBest.clear();
0096     const TP* tpBest = nullptr;
0097 
0098     for (const auto& iter : tpsToStubs) {
0099       const TP* tp = iter.first;
0100       const vector<const Stub*> matchedStubsFromTP = iter.second;
0101 
0102       const vector<const Stub*> matchedStubsStrictFromTP =
0103           tpsToStubsStrict[tp];  // Empty vector, if this TP didnt produce both clusters in stub.
0104 
0105       // Count number of the given stubs that came from this TP.
0106       unsigned int nMatchedStubs = matchedStubsFromTP.size();
0107       // Count number of tracker layers in which the given stubs came from this TP.
0108       unsigned int nMatchedLayers = Utility::countLayers(settings, matchedStubsFromTP, true);
0109       unsigned int nMatchedPSLayers = Utility::countLayers(settings, matchedStubsFromTP, true, true);
0110 
0111       // For tie-breaks, count number of tracker layers in which both clusters of the given stubs came from this TP.
0112       unsigned int nMatchedLayersStrict = Utility::countLayers(settings, matchedStubsStrictFromTP, true);
0113 
0114       // If enough layers matched, then accept this tracking particle.
0115       // Of the three criteria used here, usually only one is used, with the cuts on the other two set ultra loose.
0116 
0117       if (nMatchedStubs >=
0118               minFracMatchStubsOnReco * vstubs.size() &&  // Fraction of matched stubs relative to number of given stubs
0119           nMatchedStubs >= minFracMatchStubsOnTP *
0120                                tp->numAssocStubs() &&  // Fraction of matched stubs relative to number of stubs on TP.
0121           nMatchedLayers >= minNumMatchLayers &&
0122           nMatchedPSLayers >= minNumMatchPSLayers) {  // Number of matched layers
0123         // In case more than one matching TP found in this cell, note best match based on number of matching layers.
0124         // In tie-break situation, count layers in which both clusters in stub came from same TP.
0125         if (nMatchedLayersBest < nMatchedLayers ||
0126             (nMatchedLayersBest == nMatchedLayers && nMatchedLayersStrictBest < nMatchedLayersStrict)) {
0127           // Store data for this TP match.
0128           nMatchedLayersBest = nMatchedLayers;
0129           matchedStubsBest = matchedStubsFromTP;
0130           tpBest = tp;
0131         }
0132       }
0133     }
0134 
0135     return tpBest;
0136   }
0137 
0138   //=== Determine min number of layers a track candidate must have stubs in to be defined as a track.
0139   //=== 1st argument indicates from which step in chain this function is called: HT, SEED, DUP or FIT.
0140 
0141   unsigned int Utility::numLayerCut(Utility::AlgoStep algo,
0142                                     const Settings* settings,
0143                                     unsigned int iPhiSec,
0144                                     unsigned int iEtaReg,
0145                                     float invPt,
0146                                     float eta) {
0147     if (algo == HT || algo == SEED || algo == DUP || algo == FIT) {
0148       unsigned int nLayCut = settings->minStubLayers();
0149 
0150       //--- Check if should reduce cut on number of layers by 1 for any reason.
0151 
0152       bool reduce = false;
0153 
0154       // to increase efficiency for high Pt tracks.
0155       bool applyMinPt = (settings->minPtToReduceLayers() > 0);
0156       if (applyMinPt && std::abs(invPt) < 1 / settings->minPtToReduceLayers())
0157         reduce = true;
0158 
0159       // or to increase efficiency in the barrel-endcap transition or very forward regions.
0160       const vector<unsigned int>& etaSecsRed = settings->etaSecsReduceLayers();
0161       if (std::count(etaSecsRed.begin(), etaSecsRed.end(), iEtaReg) != 0)
0162         reduce = true;
0163 
0164       // or to increase efficiency in sectors containing dead modules (hard-wired in KF only)
0165       // Not implemented here.
0166 
0167       if (reduce)
0168         nLayCut--;
0169 
0170       constexpr unsigned int minLayCut = 4;  // Minimum viable layer cut.
0171       nLayCut = std::max(nLayCut, minLayCut);
0172 
0173       // Seed Filter & Track Fitters require only 4 layers.
0174       constexpr unsigned int nFitLayCut = 4;
0175       if (algo == SEED || algo == FIT)
0176         nLayCut = nFitLayCut;
0177 
0178       return nLayCut;
0179     } else {
0180       throw cms::Exception("LogicError") << "Utility::numLayerCut() called with invalid algo argument! " << algo;
0181     }
0182   }
0183 
0184 }  // namespace tmtt