File indexing completed on 2024-04-06 12:21:51
0001 #include "L1Trigger/TrackFindingTMTT/interface/Sector.h"
0002 #include "L1Trigger/TrackFindingTMTT/interface/Stub.h"
0003 #include "L1Trigger/TrackFindingTMTT/interface/Settings.h"
0004
0005 #include "DataFormats/Math/interface/deltaPhi.h"
0006
0007 using namespace std;
0008
0009 namespace tmtt {
0010
0011
0012
0013 Sector::Sector(const Settings* settings, unsigned int iPhiSec, unsigned int iEtaReg)
0014 : settings_(settings),
0015
0016 iPhiSec_(iPhiSec),
0017 iEtaReg_(iEtaReg),
0018
0019 beamWindowZ_(settings->beamWindowZ()),
0020
0021
0022
0023
0024 etaMin_(settings->etaRegions()[iEtaReg]),
0025 etaMax_(settings->etaRegions()[iEtaReg + 1]),
0026 chosenRofZ_(settings->chosenRofZ()),
0027
0028 zOuterMin_(chosenRofZ_ / tan(2. * atan(exp(-etaMin_)))),
0029 zOuterMax_(chosenRofZ_ / tan(2. * atan(exp(-etaMax_)))),
0030
0031
0032 chosenRofPhi_(settings->chosenRofPhi()),
0033 minPt_(settings->houghMinPt()),
0034 assumedPhiTrkRes_(settings->assumedPhiTrkRes()),
0035 useStubPhi_(settings->useStubPhi()),
0036 useStubPhiTrk_(settings->useStubPhiTrk()),
0037 calcPhiTrkRes_(settings->calcPhiTrkRes()),
0038
0039 numSubSecsEta_(settings->numSubSecsEta()) {
0040
0041
0042 float phiCentreSec0 = -M_PI / float(settings->numPhiNonants()) + M_PI / float(settings->numPhiSectors());
0043
0044 phiCentre_ = 2. * M_PI * float(iPhiSec) / float(settings->numPhiSectors()) + phiCentreSec0;
0045 sectorHalfWidth_ = M_PI / float(settings->numPhiSectors());
0046
0047
0048 float subSecWidth = (etaMax_ - etaMin_) / float(numSubSecsEta_);
0049 for (unsigned int i = 0; i < numSubSecsEta_; i++) {
0050 float subSecEtaMin = etaMin_ + i * subSecWidth;
0051 float subSecEtaMax = subSecEtaMin + subSecWidth;
0052 float subSecZmin = chosenRofZ_ / tan(2. * atan(exp(-subSecEtaMin)));
0053 float subSecZmax = chosenRofZ_ / tan(2. * atan(exp(-subSecEtaMax)));
0054 zOuterMinSub_.push_back(subSecZmin);
0055 zOuterMaxSub_.push_back(subSecZmax);
0056 }
0057 }
0058
0059
0060
0061 bool Sector::insideEta(const Stub* stub) const {
0062
0063
0064
0065 bool inside = this->insideEtaRange(stub, zOuterMin_, zOuterMax_);
0066 return inside;
0067 }
0068
0069
0070
0071 vector<bool> Sector::insideEtaSubSecs(const Stub* stub) const {
0072 if (settings_->enableDigitize() && numSubSecsEta_ == 2) {
0073
0074 return subEtaFwCalc(stub->digitalStub()->iDigi_Rt(), stub->digitalStub()->iDigi_Z());
0075
0076 } else {
0077
0078
0079 vector<bool> insideVec;
0080
0081
0082 for (unsigned int i = 0; i < numSubSecsEta_; i++) {
0083 bool inside = this->insideEtaRange(stub, zOuterMinSub_[i], zOuterMaxSub_[i]);
0084 insideVec.push_back(inside);
0085 }
0086
0087 return insideVec;
0088 }
0089 }
0090
0091
0092
0093 bool Sector::insideEtaRange(const Stub* stub, float zRangeMin, float zRangeMax) const {
0094
0095
0096
0097 float zMin, zMax;
0098 bool inside;
0099
0100
0101 zMin = (zRangeMin * stub->r() - beamWindowZ_ * std::abs(stub->r() - chosenRofZ_)) / chosenRofZ_;
0102
0103 zMax = (zRangeMax * stub->r() + beamWindowZ_ * std::abs(stub->r() - chosenRofZ_)) / chosenRofZ_;
0104
0105 inside = (stub->z() > zMin && stub->z() < zMax);
0106 return inside;
0107 }
0108
0109
0110
0111 bool Sector::insidePhi(const Stub* stub) const {
0112
0113
0114
0115 bool okPhi = true;
0116 bool okPhiTrk = true;
0117
0118 if (useStubPhi_) {
0119 float delPhi =
0120 reco::deltaPhi(stub->phi(), phiCentre_);
0121 float tolerancePhi = stub->phiDiff(
0122 chosenRofPhi_, minPt_);
0123 float outsidePhi = std::abs(delPhi) - sectorHalfWidth_ -
0124 tolerancePhi;
0125 if (outsidePhi > 0)
0126 okPhi = false;
0127 }
0128
0129 if (useStubPhiTrk_) {
0130
0131 float phiTrk = stub->trkPhiAtR(chosenRofPhi_);
0132
0133 float delPhiTrk = reco::deltaPhi(phiTrk, phiCentre_);
0134
0135 float tolerancePhiTrk = assumedPhiTrkRes_ * (2 * sectorHalfWidth_);
0136 if (calcPhiTrkRes_) {
0137
0138 float phiTrkRes = stub->trkPhiAtRcut(chosenRofPhi_);
0139
0140 tolerancePhiTrk = min(tolerancePhiTrk, phiTrkRes);
0141 }
0142
0143 float outsidePhiTrk = std::abs(delPhiTrk) - sectorHalfWidth_ - tolerancePhiTrk;
0144
0145 if (outsidePhiTrk > 0)
0146 okPhiTrk = false;
0147 }
0148
0149 return (okPhi && okPhiTrk);
0150 }
0151
0152
0153
0154
0155
0156 unordered_map<const Stub*, pair<bool, bool> > Sector::stubsInside(const TP& tp) const {
0157 unordered_map<const Stub*, pair<bool, bool> > inside;
0158
0159 const vector<const Stub*>& assStubs = tp.assocStubs();
0160 for (const Stub* stub : assStubs) {
0161
0162 inside[stub] = pair<bool, bool>(this->insidePhi(stub), this->insideEta(stub));
0163 }
0164 return inside;
0165 }
0166
0167
0168
0169
0170
0171 void Sector::numStubsInside(const TP& tp,
0172 unsigned int& nStubsInsideEtaPhi,
0173 unsigned int& nStubsInsideEta,
0174 unsigned int& nStubsInsidePhi) const {
0175 nStubsInsideEtaPhi = 0;
0176 nStubsInsideEta = 0;
0177 nStubsInsidePhi = 0;
0178 for (const auto& iter : this->stubsInside(tp)) {
0179 bool insidePhi = iter.second.first;
0180 bool insideEta = iter.second.second;
0181 if (insidePhi && insideEta)
0182 nStubsInsideEtaPhi++;
0183 if (insideEta)
0184 nStubsInsideEta++;
0185 if (insidePhi)
0186 nStubsInsidePhi++;
0187 }
0188 }
0189
0190
0191
0192 int64_t Sector::forceBitWidth(const float value, const UInt_t nBits) const {
0193
0194 int64_t sign = 1;
0195 if (value < 0)
0196 sign = -1;
0197 int64_t iValue = int64_t(std::abs(value));
0198 int64_t mask = (int64_t(1) << nBits) - int64_t(1);
0199 int64_t result = sign * (iValue & mask);
0200 if (std::abs(result - value) > 1)
0201 throw cms::Exception("LogicError")
0202 << "Sector::forceBitWidth is messing up by using too few bits to digitize number"
0203 << " nBits=" << nBits << " Input float=" << value << " Output digi = " << result;
0204 return result;
0205
0206 }
0207
0208
0209
0210
0211 vector<bool> Sector::subEtaFwCalc(const int rT, const int z) const {
0212
0213 unsigned int rtBitsRef = 10;
0214 unsigned int zBitsRef = 12;
0215
0216
0217 unsigned int rtBits = settings_->rtBits();
0218 unsigned int zBits = settings_->zBits();
0219 float rtRange = settings_->rtRange();
0220 float zRange = settings_->zRange();
0221 constexpr float cm_to_mm = 10.;
0222 float zBase = cm_to_mm / (pow(2, zBits) / zRange);
0223 float rTBase = cm_to_mm / (pow(2, rtBits) / rtRange);
0224
0225
0226 constexpr unsigned int nDSPa = 27;
0227
0228 constexpr unsigned int nDSPc = 48;
0229 constexpr unsigned int nDSPd = 48;
0230
0231
0232 float BeamWindow = cm_to_mm * beamWindowZ_;
0233 float T_rphi = cm_to_mm * chosenRofPhi_;
0234 float T_rz = cm_to_mm * chosenRofZ_;
0235
0236
0237 float Beam_over_T = BeamWindow / T_rz;
0238
0239 unsigned int nShiftA = 24;
0240
0241 nShiftA += (rtBits - rtBitsRef) - (zBits - zBitsRef);
0242 float Beam_over_T_base = 1. / (1 << nShiftA);
0243 int64_t bot = forceBitWidth(Beam_over_T * rTBase / zBase / Beam_over_T_base, nDSPa);
0244 int64_t bw = forceBitWidth(BeamWindow / zBase / Beam_over_T_base, nDSPc);
0245 float etaSecMid = (settings_->etaRegions()[iEtaReg_] + settings_->etaRegions()[iEtaReg_ + 1]) / 2.0;
0246 float tanlSecMid = 1.0 / tan(2.0 * atan(exp(-etaSecMid)));
0247
0248 unsigned int nShiftB = 16;
0249
0250 nShiftB += (rtBits - rtBitsRef) - (zBits - zBitsRef);
0251 float tanlSecBase = 1. / (1 << nShiftB);
0252 int64_t tanlSec_Mid = forceBitWidth(int(tanlSecMid * rTBase / zBase / tanlSecBase), nDSPa);
0253
0254 constexpr unsigned int nExtraBitsR = 2;
0255 unsigned int rBits = rtBits + nExtraBitsR;
0256 int64_t r = forceBitWidth(rT + T_rphi / rTBase, rBits);
0257 int64_t g = forceBitWidth(bot * r - bw, nDSPd);
0258 int64_t absg = abs(g);
0259
0260 const unsigned nBitsRemainingA = nDSPd - nShiftA;
0261 int64_t shift_g = forceBitWidth((absg >> nShiftA), nBitsRemainingA);
0262
0263 int64_t tlsr = forceBitWidth(tanlSec_Mid * r, nDSPa + rBits);
0264
0265 const unsigned nBitsRemainingB = (nDSPa + rBits) - nShiftB;
0266 int64_t shift_tlsr = forceBitWidth((tlsr >> nShiftB), nBitsRemainingB);
0267
0268 vector<bool> insideVec;
0269 insideVec.push_back(z <= (shift_tlsr + shift_g));
0270 insideVec.push_back(z >= (shift_tlsr - shift_g));
0271 return insideVec;
0272 }
0273
0274 }