Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "L1Trigger/TrackFindingTMTT/interface/HTbase.h"
0002 #include "L1Trigger/TrackFindingTMTT/interface/InputData.h"
0003 #include "L1Trigger/TrackFindingTMTT/interface/Settings.h"
0004 
0005 #include "DataFormats/Math/interface/deltaPhi.h"
0006 
0007 #include <unordered_set>
0008 
0009 using namespace std;
0010 
0011 namespace tmtt {
0012 
0013   // Initialization.
0014   HTbase::HTbase(
0015       const Settings* settings, unsigned int iPhiSec, unsigned int iEtaReg, unsigned int nBinsX, unsigned int nBinsY)
0016       : settings_(settings),
0017         iPhiSec_(iPhiSec),
0018         iEtaReg_(iEtaReg),
0019         nBinsX_(nBinsX),
0020         nBinsY_(nBinsY),
0021         htArray_(nBinsX, nBinsY),
0022         optoLinkID_(this->calcOptoLinkID()) {}
0023 
0024   //=== Termination. Causes HT array to search for tracks etc.
0025 
0026   void HTbase::end() {
0027     // Calculate useful info about each cell in array.
0028     for (unsigned int i = 0; i < nBinsX_; i++) {
0029       for (unsigned int j = 0; j < nBinsY_; j++) {
0030         htArray_(i, j)->end();  // Calls HTcell::end()
0031       }
0032     }
0033 
0034     // Produce a list of all track candidates found in this array, each containing all the stubs on each one
0035     // and the track helix parameters, plus the associated truth particle (if any).
0036     trackCands2D_ = this->calcTrackCands2D();
0037 
0038     // If requested, kill those tracks in this sector that can't be read out during the time-multiplexed period, because
0039     // the HT has associated too many stubs to tracks.
0040     if (settings_->busySectorKill()) {
0041       trackCands2D_ = this->killTracksBusySec(trackCands2D_);
0042     }
0043   }
0044 
0045   //=== Number of filtered stubs in each cell summed over all cells in HT array.
0046   //=== If a stub appears in multiple cells, it will be counted multiple times.
0047   unsigned int HTbase::numStubsInc() const {
0048     unsigned int nStubs = 0;
0049 
0050     // Loop over cells in HT array.
0051     for (unsigned int i = 0; i < nBinsX_; i++) {
0052       for (unsigned int j = 0; j < nBinsY_; j++) {
0053         nStubs += htArray_(i, j)->numStubs();  // Calls HTcell::numStubs()
0054       }
0055     }
0056 
0057     return nStubs;
0058   }
0059 
0060   //=== Number of filtered stubs in HT array.
0061   //=== If a stub appears in multiple cells, it will be counted only once.
0062   unsigned int HTbase::numStubsExc() const {
0063     unordered_set<unsigned int> stubIDs;  // Each ID stored only once, no matter how often it is added.
0064 
0065     // Loop over cells in HT array.
0066     for (unsigned int i = 0; i < nBinsX_; i++) {
0067       for (unsigned int j = 0; j < nBinsY_; j++) {
0068         // Loop over stubs in each cells, storing their IDs.
0069         const vector<Stub*>& vStubs = htArray_(i, j)->stubs();  // Calls HTcell::stubs()
0070         for (const Stub* stub : vStubs) {
0071           stubIDs.insert(stub->index());
0072         }
0073       }
0074     }
0075 
0076     return stubIDs.size();
0077   }
0078 
0079   //=== Get number of filtered stubs assigned to track candidates found in this HT array.
0080 
0081   unsigned int HTbase::numStubsOnTrackCands2D() const {
0082     unsigned int nStubs = 0;
0083 
0084     // Loop over track candidates
0085     for (const L1track2D& trk : trackCands2D_) {
0086       nStubs += trk.stubs().size();
0087     }
0088 
0089     return nStubs;
0090   }
0091 
0092   //=== Get all reconstructed tracks that were associated to the given tracking particle.
0093   //=== (If the vector is empty, then the tracking particle was not reconstructed in this sector).
0094 
0095   vector<const L1track2D*> HTbase::assocTrackCands2D(const TP& tp) const {
0096     vector<const L1track2D*> assocRecoTrk;
0097 
0098     // Loop over track candidates, looking for those associated to given TP.
0099     for (const L1track2D& trk : trackCands2D_) {
0100       if (trk.matchedTP() != nullptr) {
0101         if (trk.matchedTP()->index() == tp.index())
0102           assocRecoTrk.push_back(&trk);
0103       }
0104     }
0105 
0106     return assocRecoTrk;
0107   }
0108 
0109   //=== Disable filters (used for debugging).
0110 
0111   void HTbase::disableBendFilter() {
0112     // Loop over cells in HT array.
0113     for (unsigned int i = 0; i < nBinsX_; i++) {
0114       for (unsigned int j = 0; j < nBinsY_; j++) {
0115         htArray_(i, j)->disableBendFilter();
0116       }
0117     }
0118   }
0119 
0120   //=== Given a range in one of the coordinates specified by coordRange, calculate the corresponding range of bins. The other arguments specify the axis. And also if some cells nominally associated to stub are to be killed.
0121 
0122   pair<unsigned int, unsigned int> HTbase::convertCoordRangeToBinRange(pair<float, float> coordRange,
0123                                                                        unsigned int nBinsAxis,
0124                                                                        float coordAxisMin,
0125                                                                        float coordAxisBinSize,
0126                                                                        unsigned int killSomeHTcells) const {
0127     float coordMin = coordRange.first;
0128     float coordMax = coordRange.second;
0129     float coordAvg = (coordRange.first + coordRange.second) / 2.;
0130 
0131     int iCoordBinMin, iCoordBinMax;
0132 
0133     //--- There are various options for doing this.
0134     //--- Option killSomeHTcells = 0 is the obvious one.
0135     //--- If killSomeHTcells > 0, then some of the cells nominally associated with the stub are killed.
0136 
0137     if (killSomeHTcells == 0) {
0138       // Take the full range of phi bins consistent with the stub.
0139       iCoordBinMin = floor((coordMin - coordAxisMin) / coordAxisBinSize);
0140       iCoordBinMax = floor((coordMax - coordAxisMin) / coordAxisBinSize);
0141     } else if (killSomeHTcells == 1) {
0142       // Use the reduced range of bins.
0143       // This algorithm, proposed by Ian, should reduce the rate, at the cost of some efficiency.
0144       const float fracCut = 0.3;
0145       iCoordBinMin = floor((coordMin - coordAxisMin) / coordAxisBinSize);
0146       iCoordBinMax = floor((coordMax - coordAxisMin) / coordAxisBinSize);
0147       unsigned int nbins = iCoordBinMax - iCoordBinMin + 1;
0148       if (nbins >= 2) {                                                      // Can't reduce range if already only 1 bin
0149         float lower = coordAxisMin + (iCoordBinMin + 1) * coordAxisBinSize;  // upper edge of lowest bin
0150         float upper = coordAxisMin + (iCoordBinMax)*coordAxisBinSize;        // lower edge of highest bin.
0151         // Calculate fractional amount of min and max bin that this stub uses.
0152         float extraLow = (lower - coordMin) / coordAxisBinSize;
0153         float extraUp = (coordMax - upper) / coordAxisBinSize;
0154         constexpr float small = 0.001;  // allow tolerance on floating point precision.
0155         if (min(extraLow, extraUp) < -small || max(extraLow, extraUp) > (1.0 + small))
0156           throw cms::Exception("LogicError") << "HTbase: convertCoordRangeToBinRange error";
0157         if (extraLow < fracCut && (nbins >= 3 || extraLow < extraUp))
0158           iCoordBinMin += 1;
0159         if (extraUp < fracCut && (nbins >= 3 || extraUp < extraLow))
0160           iCoordBinMax -= 1;
0161       }
0162     } else if (killSomeHTcells == 2) {
0163       // This corresponds to Thomas's firmware implementation, which can't fill more than one HT cell per column.
0164       iCoordBinMin = floor((coordAvg - coordAxisMin) / coordAxisBinSize);
0165       iCoordBinMax = iCoordBinMin;
0166     } else {
0167       throw cms::Exception("BadConfig") << "HT: invalid KillSomeHTCells option in cfg";
0168     }
0169 
0170     // Limit range to dimensions of HT array.
0171     iCoordBinMin = max(iCoordBinMin, 0);
0172     iCoordBinMax = min(iCoordBinMax, int(nBinsAxis) - 1);
0173 
0174     // If whole range is outside HT array, flag this by setting range to specific values with min > max.
0175     if (iCoordBinMin > int(nBinsAxis) - 1 || iCoordBinMax < 0) {
0176       iCoordBinMin = int(nBinsAxis) - 1;
0177       iCoordBinMax = 0;
0178     }
0179 
0180     return pair<unsigned int, unsigned int>(iCoordBinMin, iCoordBinMax);
0181   }
0182 
0183   //=== Return a list of all track candidates found in this array, giving access to all the stubs on each one
0184   //=== and the track helix parameters, plus the associated truth particle (if any).
0185 
0186   list<L1track2D> HTbase::calcTrackCands2D() const {
0187     list<L1track2D> trackCands2D;
0188 
0189     // Check if the hardware processes rows of the HT array in a specific order when outputting track candidates.
0190     // Currently this is by decreasing Pt for r-phi HT and unordered for r-z HT.
0191     const vector<unsigned int> iOrder = this->rowOrder(nBinsX_);
0192     bool wantOrdering = (not iOrder.empty());
0193 
0194     // Loop over cells in HT array.
0195     for (unsigned int i = 0; i < nBinsX_; i++) {
0196       // Access rows in specific order if required.
0197       unsigned int iPos = wantOrdering ? iOrder[i] : i;
0198 
0199       for (unsigned int j = 0; j < nBinsY_; j++) {
0200         if (htArray_(iPos, j)->trackCandFound()) {  // track candidate found in this cell.
0201 
0202           // Note if this corresponds to a merged HT cell (e.g. 2x2).
0203           const bool merged = htArray_(iPos, j)->mergedCell();
0204 
0205           // Get stubs on this track candidate.
0206           const vector<Stub*>& stubs = htArray_(iPos, j)->stubs();
0207 
0208           // And note location of cell inside HT array.
0209           const pair<unsigned int, unsigned int> cellLocation(iPos, j);
0210 
0211           // Get (q/Pt, phi0) or (tan_lambda, z0) corresponding to middle of this cell.
0212           const pair<float, float> helixParams2D = this->helix2Dconventional(iPos, j);
0213 
0214           // Create track and store it.
0215           trackCands2D.emplace_back(
0216               settings_, stubs, cellLocation, helixParams2D, iPhiSec_, iEtaReg_, optoLinkID_, merged);
0217         }
0218       }
0219     }
0220 
0221     return trackCands2D;
0222   }
0223 
0224 }  // namespace tmtt