Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:30:45

0001 ///=== This is the global Linear Regression for 4 helix parameters track fit algorithm.
0002 
0003 ///=== Written by: Davide Cieri
0004 
0005 #include "L1Trigger/TrackFindingTMTT/interface/SimpleLR4.h"
0006 #include "L1Trigger/TrackFindingTMTT/interface/Stub.h"
0007 #include "L1Trigger/TrackFindingTMTT/interface/L1fittedTrack.h"
0008 #include "L1Trigger/TrackFindingTMTT/interface/L1track3D.h"
0009 #include "L1Trigger/TrackFindingTMTT/interface/PrintL1trk.h"
0010 #include "DataFormats/Math/interface/deltaPhi.h"
0011 
0012 #include <vector>
0013 #include <set>
0014 #include <algorithm>
0015 #include <limits>
0016 
0017 using namespace std;
0018 
0019 namespace tmtt {
0020 
0021   SimpleLR4::SimpleLR4(const Settings* settings) : TrackFitGeneric(settings) {
0022     // Initialize digitization parameters
0023     phiMult_ = pow(2., settings_->phiSBits()) / settings_->phiSRange();
0024     rTMult_ = pow(2., settings_->rtBits()) / settings_->rtRange();
0025     zMult_ = pow(2., settings_->zBits()) / settings_->zRange();
0026     z0Mult_ = pow(2., settings_->slr_z0Bits()) / settings_->slr_z0Range();
0027     phiTMult_ = pow(2., settings_->slr_phi0Bits()) / settings_->slr_phi0Range();
0028 
0029     qOverPtMult_ = pow(2., settings_->slr_oneOver2rBits()) / settings_->slr_oneOver2rRange();
0030     tanLambdaMult_ = pow(2., settings_->slr_tanlambdaBits()) / settings_->slr_tanlambdaRange();
0031     chi2Mult_ = pow(2., settings_->slr_chisquaredBits()) / settings_->slr_chisquaredRange();
0032 
0033     numeratorPtMult_ = rTMult_ * phiMult_;
0034     numeratorPhiMult_ = rTMult_ * rTMult_ * phiMult_;
0035     numeratorZ0Mult_ = rTMult_ * rTMult_ * z0Mult_;
0036     numeratorLambdaMult_ = rTMult_ * z0Mult_;
0037     denominatorMult_ = rTMult_ * rTMult_;
0038     resMult_ = rTMult_ * qOverPtMult_;
0039 
0040     dividerBitsHelix_ = settings_->dividerBitsHelix();
0041     dividerBitsHelixZ_ = settings_->dividerBitsHelixZ();
0042     shiftingBitsDenRPhi_ = settings_->ShiftingBitsDenRPhi();
0043     shiftingBitsDenRZ_ = settings_->ShiftingBitsDenRZ();
0044     shiftingBitsPhi_ = settings_->ShiftingBitsPhi();
0045     shiftingBitsz0_ = settings_->ShiftingBitsZ0();
0046     shiftingBitsPt_ = settings_->ShiftingBitsPt();
0047     shiftingBitsLambda_ = settings_->ShiftingBitsLambda();
0048     digitize_ = settings_->digitizeSLR() and settings_->enableDigitize();
0049 
0050     phiSectorWidth_ = 2. * M_PI / float(settings_->numPhiSectors());
0051     phiNonantWidth_ = 2. * M_PI / float(settings_->numPhiNonants());
0052 
0053     chi2cut_ = settings_->slr_chi2cut();
0054     chosenRofPhi_ = settings_->chosenRofPhi();
0055     if (digitize_)
0056       chosenRofPhi_ = floor(chosenRofPhi_ * rTMult_) / rTMult_;
0057 
0058     debug_ = false;  // Enable debug printout.
0059   };
0060 
0061   static bool pair_compare(std::pair<const Stub*, float> a, std::pair<const Stub*, float> b) {
0062     return (a.second < b.second);
0063   }
0064 
0065   L1fittedTrack SimpleLR4::fit(const L1track3D& l1track3D) {
0066     if (debug_)
0067       PrintL1trk() << "=============== FITTING SimpleLR TRACK ====================";
0068 
0069     minStubLayersRed_ = Utility::numLayerCut(Utility::AlgoStep::FIT,
0070                                              settings_,
0071                                              l1track3D.iPhiSec(),
0072                                              l1track3D.iEtaReg(),
0073                                              std::abs(l1track3D.qOverPt()),
0074                                              l1track3D.eta());
0075 
0076     invPtToDPhi_ = -settings_->invPtToDphi();
0077 
0078     double phiCentreSec0 = -0.5 * phiNonantWidth_ + 0.5 * phiSectorWidth_;
0079     phiSectorCentre_ = phiSectorWidth_ * double(l1track3D.iPhiSec()) - phiCentreSec0;
0080 
0081     if (digitize_)
0082       phiSectorCentre_ = floor(phiSectorCentre_ * phiTMult_) / phiTMult_;
0083 
0084     // Inizialise track fit parameters
0085     double qOverPt = 0.;
0086     double phiT = 0.;
0087     double phi0 = 0.;
0088     double z0 = 0.;
0089     double zT = 0.;
0090     double tanLambda = 0.;
0091 
0092     // Inizialise Sums
0093     double SumRPhi = 0.;
0094     double SumR = 0.;
0095     double SumPhi = 0.;
0096     double SumR2 = 0.;
0097     double SumRZ = 0.;
0098     double SumZ = 0.;
0099 
0100     unsigned int numStubs = 0;
0101     // Calc helix parameters on Rphi Plane (STEP 1)
0102     // This loop calculates the sums needed to calculate the numerators and the denominator to compute the helix parameters in the R-Phi plane (q/pT, phiT)
0103     for (Stub* stub : l1track3D.stubs()) {
0104       numStubs++;
0105 
0106       if (digitize_) {
0107         const DigitalStub* digiStub = stub->digitalStub();
0108 
0109         SumRPhi = SumRPhi + digiStub->rt_SF_TF() * digiStub->phiS();
0110         SumR = SumR + digiStub->rt_SF_TF();
0111         SumPhi = SumPhi + digiStub->phiS();
0112         SumR2 = SumR2 + digiStub->rt_SF_TF() * digiStub->rt_SF_TF();
0113         if (debug_)
0114           PrintL1trk() << "Input stub (digi): phiS " << digiStub->iDigi_PhiS() << " rT " << digiStub->iDigi_Rt()
0115                        << " z " << digiStub->iDigi_Z();
0116       } else {
0117         float phi = 0;
0118         if (l1track3D.iPhiSec() == 0 and stub->phi() > 0) {
0119           phi = stub->phi() - 2 * M_PI;
0120         } else if (l1track3D.iPhiSec() == settings_->numPhiSectors() and stub->phi() < 0) {
0121           phi = stub->phi() + 2 * M_PI;
0122         } else {
0123           phi = stub->phi();
0124         }
0125         SumRPhi = SumRPhi + stub->r() * phi;
0126         SumR = SumR + stub->r();
0127         SumPhi = SumPhi + phi;
0128         SumR2 = SumR2 + stub->r() * stub->r();
0129         if (debug_)
0130           PrintL1trk() << "InputStub (float): phi " << phi << " r " << stub->r() << " z " << stub->z();
0131       }
0132     }
0133 
0134     double numeratorPt, digiNumeratorPt;
0135     double denominator, digiDenominator;
0136     double numeratorPhi, digiNumeratorPhi;
0137     double reciprocal, digiReciprocal;
0138     double numeratorZ0;
0139     double numeratorLambda;
0140 
0141     digiNumeratorPt = (numStubs * SumRPhi - SumR * SumPhi);
0142     digiDenominator = (numStubs * SumR2 - SumR * SumR);
0143     digiNumeratorPhi = (SumR2 * SumPhi - SumR * SumRPhi);
0144 
0145     if (!digitize_) {
0146       qOverPt = (numStubs * SumRPhi - SumR * SumPhi) / (numStubs * SumR2 - SumR * SumR);
0147       phi0 = (SumR2 * SumPhi - SumR * SumRPhi) / (numStubs * SumR2 - SumR * SumR);
0148     } else {
0149       digiNumeratorPt /= pow(2., shiftingBitsPt_);
0150       digiNumeratorPt = floor(digiNumeratorPt * numeratorPtMult_);
0151       numeratorPt = digiNumeratorPt / numeratorPtMult_;
0152 
0153       digiNumeratorPhi /= pow(2., shiftingBitsPhi_);
0154       digiNumeratorPhi = floor(digiNumeratorPhi * numeratorPhiMult_);
0155       numeratorPhi = digiNumeratorPhi / numeratorPhiMult_;
0156 
0157       digiDenominator /= pow(2., shiftingBitsDenRPhi_);
0158       digiDenominator = (floor(digiDenominator * denominatorMult_) + 0.5);
0159       denominator = digiDenominator / denominatorMult_;
0160       digiReciprocal = (pow(2., dividerBitsHelix_) - 1) / (denominator);  // To be moved
0161       digiReciprocal = floor(digiReciprocal / denominatorMult_);
0162       reciprocal = digiReciprocal * denominatorMult_;
0163 
0164       qOverPt = numeratorPt * reciprocal / pow(2., dividerBitsHelix_ + shiftingBitsDenRPhi_ - shiftingBitsPt_);
0165       phiT = numeratorPhi * reciprocal / pow(2., dividerBitsHelix_ + shiftingBitsDenRPhi_ - shiftingBitsPhi_);
0166 
0167       qOverPt = floor(qOverPt * qOverPtMult_) / (qOverPtMult_);
0168       phiT = floor(phiT * phiTMult_) / phiTMult_;
0169     }
0170 
0171     if (debug_) {
0172       if (digitize_) {
0173         PrintL1trk() << setw(10) << "Input helix (digi): qOverPt = " << qOverPt << " (" << floor(qOverPt * qOverPtMult_)
0174                      << "), phiT = " << phiT << " (" << floor(phiT * phiTMult_) << ") ";
0175       } else {
0176         PrintL1trk() << "Input Helix (float): qOverPt = " << qOverPt << " phi0 " << phi0;
0177       }
0178     }
0179 
0180     // ================== RESIDUAL CALCULATION ON RPHI ========================
0181     std::vector<std::pair<Stub*, double> > vRes;
0182     unsigned int psStubs = 0;
0183     for (Stub* stub : l1track3D.stubs()) {
0184       if (stub->psModule())
0185         psStubs++;
0186       double ResPhi;
0187 
0188       if (digitize_) {
0189         const DigitalStub* digiStub = stub->digitalStub();
0190 
0191         ResPhi =
0192             digiStub->iDigi_PhiS() * pow(2., shiftingBitsDenRPhi_ - shiftingBitsPt_) -
0193             floor(phiT * phiTMult_) *
0194                 pow(2., shiftingBitsDenRPhi_ - shiftingBitsPt_ - settings_->slr_phi0Bits() + settings_->phiSBits()) -
0195             floor(qOverPt * qOverPtMult_) * digiStub->iDigi_Rt();
0196 
0197         ResPhi = floor(ResPhi) / resMult_;
0198       }
0199 
0200       else {
0201         ResPhi = reco::deltaPhi(stub->phi(), phi0 + qOverPt * stub->r());
0202       }
0203 
0204       double Res = std::abs(ResPhi);
0205 
0206       std::pair<Stub*, double> ResStubPair(stub, Res);
0207       vRes.push_back(ResStubPair);
0208       if (debug_) {
0209         if (stub->assocTP() != nullptr)
0210           PrintL1trk() << " Stub rphi residual " << Res << " TP " << stub->assocTP()->index();
0211         else
0212           PrintL1trk() << " Stub rphi residual " << Res << " TP nullptr";
0213       }
0214     }
0215 
0216     double largestResidual = 9999.;
0217     // Find largest residuals
0218     while (vRes.size() > minStubLayersRed_ and largestResidual > settings_->ResidualCut()) {
0219       std::vector<std::pair<Stub*, double> >::iterator maxResIt = max_element(vRes.begin(), vRes.end(), pair_compare);
0220       largestResidual = (*maxResIt).second;
0221       if (debug_)
0222         PrintL1trk() << "Largest Residual " << largestResidual;
0223 
0224       if (largestResidual > settings_->ResidualCut()) {
0225         if ((*maxResIt).first->psModule()) {
0226           if (psStubs > 2) {
0227             if (debug_)
0228               PrintL1trk() << "removing PS residual " << (*maxResIt).second;
0229             vRes.erase(maxResIt);
0230             psStubs--;
0231           } else {
0232             if (debug_)
0233               PrintL1trk() << "residual " << (*maxResIt).second << " set to -1. ";
0234             (*maxResIt).second = -1.;
0235           }
0236         } else {
0237           vRes.erase(maxResIt);
0238           if (debug_)
0239             PrintL1trk() << "removing residual " << (*maxResIt).second;
0240         }
0241       }
0242     }
0243 
0244     std::vector<Stub*> fitStubs;
0245     fitStubs.reserve(vRes.size());
0246     for (std::pair<Stub*, double> ResStubPair : vRes) {
0247       fitStubs.push_back(ResStubPair.first);
0248     }
0249 
0250     phiT = 0.;
0251     zT = 0.;
0252 
0253     SumRPhi = 0.;
0254     SumR = 0.;
0255     SumPhi = 0.;
0256     SumR2 = 0.;
0257     SumRZ = 0.;
0258     SumZ = 0.;
0259     double SumR_ps = 0.;
0260     double SumR2_ps = 0.;
0261 
0262     numStubs = 0;
0263     psStubs = 0;
0264 
0265     for (const Stub* stub : fitStubs) {
0266       if (stub->psModule())
0267         psStubs++;
0268 
0269       numStubs++;
0270       if (digitize_) {
0271         const DigitalStub* digiStub = stub->digitalStub();
0272         SumRPhi += digiStub->rt_SF_TF() * digiStub->phiS();
0273         SumR += digiStub->rt_SF_TF();
0274         SumPhi += digiStub->phiS();
0275         SumR2 += digiStub->rt_SF_TF() * digiStub->rt_SF_TF();
0276         if (stub->psModule()) {
0277           SumRZ += digiStub->rt_SF_TF() * digiStub->z();
0278           SumZ += digiStub->z();
0279           SumR_ps += digiStub->rt_SF_TF();
0280           SumR2_ps += digiStub->rt_SF_TF() * digiStub->rt_SF_TF();
0281         }
0282         if (debug_) {
0283           PrintL1trk() << "phiS " << digiStub->iDigi_PhiS() << " rT " << digiStub->iDigi_Rt() << " z "
0284                        << digiStub->iDigi_Z();
0285         }
0286       } else {
0287         float phi = 0;
0288         if (l1track3D.iPhiSec() == 0 and stub->phi() > 0) {
0289           phi = stub->phi() - 2 * M_PI;
0290         } else if (l1track3D.iPhiSec() == settings_->numPhiSectors() and stub->phi() < 0) {
0291           phi = stub->phi() + 2 * M_PI;
0292         } else {
0293           phi = stub->phi();
0294         }
0295 
0296         SumRPhi += stub->r() * phi;
0297         SumR += stub->r();
0298         SumPhi += phi;
0299         SumR2 += stub->r() * stub->r();
0300         if (stub->psModule()) {
0301           SumRZ += stub->r() * stub->z();
0302           SumZ += stub->z();
0303           SumR_ps += stub->r();
0304           SumR2_ps += stub->r() * stub->r();
0305         }
0306         if (debug_)
0307           PrintL1trk() << "phi " << phi << " r " << stub->r() << " z " << stub->z();
0308       }
0309     }
0310 
0311     numeratorZ0 = (SumR2_ps * SumZ - SumR_ps * SumRZ);
0312     numeratorLambda = (psStubs * SumRZ - SumR_ps * SumZ);
0313     numeratorPt = (numStubs * SumRPhi - SumR * SumPhi);
0314     denominator = (numStubs * SumR2 - SumR * SumR);
0315     double denominatorZ = (psStubs * SumR2_ps - SumR_ps * SumR_ps);
0316     numeratorPhi = (SumR2 * SumPhi - SumR * SumRPhi);
0317     double reciprocalZ;
0318     if (!digitize_) {
0319       z0 = numeratorZ0 / denominatorZ;
0320       tanLambda = numeratorLambda / denominatorZ;
0321       qOverPt = (numStubs * SumRPhi - SumR * SumPhi) / (numStubs * SumR2 - SumR * SumR);
0322       phi0 = (SumR2 * SumPhi - SumR * SumRPhi) / (numStubs * SumR2 - SumR * SumR);
0323     } else {
0324       numeratorPt /= pow(2., shiftingBitsPt_);
0325       numeratorPt = floor(numeratorPt * numeratorPtMult_) / numeratorPtMult_;
0326 
0327       numeratorPhi /= pow(2., shiftingBitsPhi_);
0328       numeratorPhi = floor(numeratorPhi * numeratorPhiMult_) / numeratorPhiMult_;
0329 
0330       numeratorLambda /= pow(2., shiftingBitsLambda_);
0331       numeratorLambda = floor(numeratorLambda * numeratorLambdaMult_) / numeratorLambdaMult_;
0332 
0333       numeratorZ0 /= pow(2., shiftingBitsz0_);
0334       numeratorZ0 = floor(numeratorZ0 * numeratorZ0Mult_) / numeratorZ0Mult_;
0335 
0336       denominator /= pow(2., shiftingBitsDenRPhi_);
0337       denominator = (floor(denominator * denominatorMult_) + 0.5) / denominatorMult_;
0338       reciprocal = (pow(2., dividerBitsHelix_) - 1) / (denominator);
0339       reciprocal = floor(reciprocal / denominatorMult_) * denominatorMult_;
0340 
0341       denominatorZ /= pow(2., shiftingBitsDenRZ_);
0342       denominatorZ = (floor(denominatorZ * denominatorMult_) + 0.5) / denominatorMult_;
0343       reciprocalZ = (pow(2., dividerBitsHelixZ_) - 1) / (denominatorZ);
0344       reciprocalZ = floor(reciprocalZ / denominatorMult_) * denominatorMult_;
0345 
0346       qOverPt = numeratorPt * reciprocal / pow(2., dividerBitsHelix_ + shiftingBitsDenRPhi_ - shiftingBitsPt_);
0347       phiT = numeratorPhi * reciprocal / pow(2., dividerBitsHelix_ + shiftingBitsDenRPhi_ - shiftingBitsPhi_);
0348 
0349       tanLambda =
0350           numeratorLambda * reciprocalZ / pow(2., dividerBitsHelixZ_ + shiftingBitsDenRZ_ - shiftingBitsLambda_);
0351       zT = numeratorZ0 * reciprocalZ / pow(2., dividerBitsHelixZ_ + shiftingBitsDenRZ_ - shiftingBitsz0_);
0352 
0353       phi0 = phiSectorCentre_ + phiT - qOverPt * settings_->chosenRofPhi();
0354       z0 = zT - tanLambda * settings_->chosenRofPhi();
0355 
0356       qOverPt = floor(qOverPt * qOverPtMult_) / qOverPtMult_;
0357       phiT = floor(phiT * phiTMult_) / phiTMult_;
0358     }
0359 
0360     if (debug_ and digitize_) {
0361       PrintL1trk() << "HT mbin " << int(l1track3D.cellLocationHT().first) - 16 << " cbin "
0362                    << int(l1track3D.cellLocationHT().second) - 32 << " iPhi " << l1track3D.iPhiSec() << " iEta "
0363                    << l1track3D.iEtaReg();
0364       PrintL1trk() << "Second Helix variables: numeratorPt = " << numeratorPt << ", numeratorPhi = " << numeratorPhi
0365                    << ", numeratorZ0 = " << numeratorZ0 << " numeratorLambda = " << numeratorLambda
0366                    << " denominator =  " << denominator << " reciprocal = " << reciprocal
0367                    << " denominatorZ =  " << denominatorZ << " reciprocalZ = " << reciprocalZ;
0368       PrintL1trk() << setw(10) << "Final Helix parameters: qOverPt = " << qOverPt << " ("
0369                    << floor(qOverPt * qOverPtMult_) << "), phiT = " << phiT << " (" << floor(phiT * phiTMult_)
0370                    << "), zT = " << zT << " (" << floor(zT * z0Mult_) << "), tanLambda = " << tanLambda << " ("
0371                    << floor(tanLambda * tanLambdaMult_) << ")"
0372                    << " z0 " << z0;
0373     } else if (debug_) {
0374       PrintL1trk() << setw(10) << "Final Helix parameters: qOverPt = " << qOverPt << ", phi0 = " << phi0
0375                    << ", z0 = " << z0 << ", tanLambda = " << tanLambda;
0376     }
0377 
0378     double chi2_phi = 0.;
0379     double chi2_z = 0.;
0380 
0381     for (const Stub* stub : fitStubs) {
0382       double ResPhi = 0.;
0383       double ResZ = 0.;
0384       if (digitize_) {
0385         const DigitalStub* digiStub = stub->digitalStub();
0386         ResPhi = digiStub->phiS() - phiT - qOverPt * digiStub->rt_SF_TF();
0387         ResZ = digiStub->z() - zT - tanLambda * digiStub->rt_SF_TF();
0388       } else {
0389         ResPhi = reco::deltaPhi(stub->phi(), phi0 + qOverPt * stub->r());
0390         ResZ = stub->z() - z0 - tanLambda * stub->r();
0391       }
0392 
0393       double RPhiSigma = 0.0002;
0394       float RZSigma = stub->sigmaZ() + std::abs(tanLambda) * stub->sigmaR();
0395 
0396       if (not stub->barrel())
0397         RPhiSigma = 0.0004;
0398 
0399       if (digitize_) {
0400         RPhiSigma = floor(RPhiSigma * phiMult_) / phiMult_;
0401       }
0402 
0403       ResPhi /= RPhiSigma;
0404       ResZ /= RZSigma;
0405 
0406       chi2_phi += std::abs(ResPhi * ResPhi);
0407       chi2_z += std::abs(ResZ * ResZ);
0408       if (debug_) {
0409         PrintL1trk() << "Stub ResPhi " << ResPhi * RPhiSigma << " ResSigma " << RPhiSigma << " Res " << ResPhi
0410                      << " chi2 " << chi2_phi;
0411         PrintL1trk() << "Stub ResZ " << ResZ * RZSigma << " ResSigma " << RZSigma << " Res " << ResZ << " chi2 "
0412                      << chi2_z;
0413       }
0414     }
0415     qOverPt /= invPtToDPhi_;
0416 
0417     bool accepted = false;
0418 
0419     //double chi2 = chi2_phi;  // Ignore r-z residuals due to poor 2S resolution?
0420     double chi2 = chi2_phi + chi2_z;
0421     if (digitize_)
0422       chi2 = floor(chi2 * chi2Mult_) / chi2Mult_;
0423 
0424     constexpr unsigned int nHelixPar = 4;
0425     float dof = 2 * fitStubs.size() - nHelixPar;
0426     float chi2dof = chi2 / dof;
0427     if (chi2 < chi2cut_)
0428       accepted = true;
0429 
0430     if (debug_)
0431       PrintL1trk() << "qOverPt " << qOverPt << " phiT " << phiT;
0432 
0433     // This condition can only happen if cfg param TrackFitCheat = True.
0434     if (fitStubs.size() < minStubLayersRed_)
0435       accepted = false;
0436 
0437     // Kinematic cuts -- NOT YET IN FIRMWARE!!!
0438     constexpr float tolerance = 0.1;
0439     if (std::abs(qOverPt) > 1. / (settings_->houghMinPt() - tolerance))
0440       accepted = false;
0441     if (std::abs(z0) > 20.)
0442       accepted = false;
0443 
0444     if (accepted) {
0445       // Create the L1fittedTrack object
0446       const unsigned int hitPattern = 0;  // FIX: Needs setting
0447       L1fittedTrack fitTrk(
0448           settings_, &l1track3D, fitStubs, hitPattern, qOverPt, 0., phi0, z0, tanLambda, chi2_phi, chi2_z, nHelixPar);
0449 
0450       if (settings_->enableDigitize())
0451         fitTrk.digitizeTrack("SimpleLR4");
0452 
0453       if (debug_ and digitize_) {
0454         PrintL1trk() << "Digitized parameters ";
0455         PrintL1trk() << "HT mbin " << int(l1track3D.cellLocationHT().first) - 16 << " cbin "
0456                      << int(l1track3D.cellLocationHT().second) - 32 << " iPhi " << l1track3D.iPhiSec() << " iEta "
0457                      << l1track3D.iEtaReg();
0458         PrintL1trk() << setw(10) << "First Helix parameters: qOverPt = " << fitTrk.qOverPt() << " oneOver2r "
0459                      << fitTrk.digitaltrack()->oneOver2r() << " ("
0460                      << floor(fitTrk.digitaltrack()->oneOver2r() * qOverPtMult_)
0461                      << "), phi0 = " << fitTrk.digitaltrack()->phi0() << " (" << fitTrk.digitaltrack()->iDigi_phi0rel()
0462                      << "), zT = " << zT << " (" << floor(zT * z0Mult_) << "), tanLambda = " << tanLambda << " ("
0463                      << floor(tanLambda * tanLambdaMult_) << ")";
0464       }
0465 
0466       if (debug_) {
0467         PrintL1trk() << "FitTrack helix parameters " << int(fitTrk.cellLocationFit().first) - 16 << ", "
0468                      << int(fitTrk.cellLocationFit().second) - 32 << " HT parameters "
0469                      << int(fitTrk.cellLocationHT().first) - 16 << ", " << int(fitTrk.cellLocationHT().second) - 32;
0470 
0471         if (fitTrk.matchedTP() != nullptr) {
0472           PrintL1trk() << "True track: chi2/ndf " << chi2dof;
0473           PrintL1trk() << "TP qOverPt " << fitTrk.matchedTP()->qOverPt() << " phi0 " << fitTrk.matchedTP()->phi0();
0474           if (!accepted)
0475             PrintL1trk() << "Track rejected " << chi2 << " chi2/ndof " << chi2dof;
0476         } else {
0477           PrintL1trk() << "Fake track!!! " << chi2 << " chi2/ndof " << chi2dof;
0478         }
0479         PrintL1trk() << "layers in track " << fitTrk.numLayers();
0480       }
0481 
0482       return fitTrk;
0483 
0484     } else {
0485       L1fittedTrack rejectedTrk;
0486       return rejectedTrk;
0487     }
0488   }
0489 
0490 }  // namespace tmtt