Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #include "L1Trigger/TrackFindingTMTT/interface/Settings.h"
0002 #include "L1Trigger/TrackFindingTMTT/interface/DigitalStub.h"
0003 
0004 #include "DataFormats/Math/interface/deltaPhi.h"
0005 #include "FWCore/Utilities/interface/Exception.h"
0006 
0007 #include <atomic>
0008 
0009 using namespace std;
0010 
0011 namespace tmtt {
0012 
0013   //=== Hybrid tracking: simplified digitization for KF.
0014 
0015   DigitalStub::DigitalStub(const Settings* settings, double r, double phi, double z, unsigned int iPhiSec)
0016       : phiSBits_(settings->phiSBits()),    // No. of bits to store phiS coord.
0017         phiSRange_(settings->phiSRange()),  // Range of phiS coord. in radians.
0018         rtBits_(settings->rtBits()),        // No. of bits to store rT coord.
0019         rtRange_(settings->rtRange()),      // Range of rT coord. in cm.
0020         zBits_(settings->zBits()),          // No. of bits to store z coord.
0021         zRange_(settings->zRange()),        // Range of z coord in cm.
0022         phiSMult_(pow(2, phiSBits_) / phiSRange_),
0023         rtMult_(pow(2, rtBits_) / rtRange_),
0024         zMult_(pow(2, zBits_) / zRange_),
0025         numPhiSectors_(settings->numPhiSectors()),
0026         numPhiNonants_(9),
0027         phiSectorWidth_(2. * M_PI / double(numPhiSectors_)),
0028         chosenRofPhi_(settings->chosenRofPhi()) {
0029     // Centre of this sector in phi. (Nonant 0 is centred on x-axis).
0030     phiCentreSec0_ = -M_PI / double(numPhiNonants_) + M_PI / double(numPhiSectors_);
0031     phiSectorCentre_ = phiSectorWidth_ * double(iPhiSec) + phiCentreSec0_;
0032 
0033     // Used to check if new digi requests are for same sector as old
0034     iPhiSec_done_ = iPhiSec;
0035 
0036     r_orig_ = r;
0037     phi_orig_ = phi;
0038     z_orig_ = z;
0039 
0040     rt_orig_ = r_orig_ - chosenRofPhi_;
0041     phiS_orig_ = reco::deltaPhi(phi_orig_, phiSectorCentre_);
0042 
0043     // Digitize
0044     iDigi_Rt_ = floor(rt_orig_ * rtMult_);
0045     iDigi_PhiS_ = floor(phiS_orig_ * phiSMult_);
0046     iDigi_Z_ = floor(z_orig_ * zMult_);
0047   }
0048 
0049   //=== TMTT tracking algorithm: digitisaton for entire L1 tracking chain.
0050   // Initialize stub with floating point stub coords, range of HT m-bin values consistent with bend,
0051   // bend and phi sector.
0052 
0053   DigitalStub::DigitalStub(const Settings* settings,
0054                            double phi_orig,
0055                            double r_orig,
0056                            double z_orig,
0057                            unsigned int mbin_min_orig,
0058                            unsigned int mbin_max_orig,
0059                            double bend_orig,
0060                            unsigned int iPhiSec) {
0061     // Set cfg params
0062     this->setCfgParams(settings);
0063 
0064     // Store variable prior to digitisation
0065     r_orig_ = r_orig;
0066     rt_orig_ = r_orig_ - chosenRofPhi_;
0067     phi_orig_ = phi_orig;
0068     z_orig_ = z_orig;
0069     mbin_min_orig_ = mbin_min_orig;
0070     mbin_max_orig_ = mbin_max_orig;
0071     bend_orig_ = bend_orig;
0072 
0073     // Phi of centre of phi sector and of nonant.
0074     unsigned int iNonant = this->iNonant(iPhiSec);
0075     phiSectorCentre_ = phiSectorWidth_ * double(iPhiSec) + phiCentreSec0_;
0076     phiNonantCentre_ = phiNonantWidth_ * double(iNonant);
0077 
0078     phiS_orig_ = reco::deltaPhi(phi_orig_, phiSectorCentre_);
0079     phiN_orig_ = reco::deltaPhi(phi_orig_, phiNonantCentre_);
0080 
0081     // Used to check if new digi requests are for same sector as old
0082     iPhiSec_done_ = iPhiSec;
0083 
0084     // Check that stub coords. are within assumed digitization range.
0085     this->checkInRange();
0086 
0087     // Digitize and then undigitize stub.
0088     this->digitize(iPhiSec);
0089     this->undigitize(iPhiSec);
0090 
0091     // Check that digitization followed by undigitization doesn't change results too much.
0092     this->checkAccuracy();
0093   }
0094 
0095   //=== Redo phi digitisation assigning stub to a different phi sector;
0096 
0097   bool DigitalStub::changePhiSec(unsigned int iPhiSec) {
0098     bool doUpdate = (iPhiSec != iPhiSec_done_);
0099 
0100     if (doUpdate) {
0101       // phi sector has changed since last time digitisation was done, so update.
0102       iPhiSec_done_ = iPhiSec;
0103       unsigned int iNonant = this->iNonant(iPhiSec);
0104       // Update original, floating point phi w.r.t. phi sector/nonant centre.
0105       phiSectorCentre_ = phiSectorWidth_ * double(iPhiSec) + phiCentreSec0_;
0106       phiNonantCentre_ = phiNonantWidth_ * double(iNonant);
0107       phiS_orig_ = reco::deltaPhi(phi_orig_, phiSectorCentre_);
0108       phiN_orig_ = reco::deltaPhi(phi_orig_, phiNonantCentre_);
0109       // Update digitised phi.
0110       iDigi_PhiN_ = floor(phiN_orig_ * phiNMult_);
0111       iDigi_PhiS_ = floor(phiS_orig_ * phiSMult_);
0112       // Update digitized then undigitized phi.
0113       phiN_ = (iDigi_PhiN_ + 0.5) / phiNMult_;
0114       phi_GP_ = reco::deltaPhi(phiN_, -phiNonantCentre_);
0115       phiS_ = (iDigi_PhiS_ + 0.5) / phiSMult_;
0116       phi_HT_TF_ = reco::deltaPhi(phiS_, -phiSectorCentre_);
0117     }
0118     return doUpdate;
0119   }
0120 
0121   //=== Set configuration parameters.
0122 
0123   void DigitalStub::setCfgParams(const Settings* settings) {
0124     // Digitization configuration parameters
0125     phiSectorBits_ = settings->phiSectorBits();  // No. of bits to store phi sector number
0126     //--- Parameters available in HT board.
0127     phiSBits_ = settings->phiSBits();    // No. of bits to store phiS coord.
0128     phiSRange_ = settings->phiSRange();  // Range of phiS coord. in radians.
0129     rtBits_ = settings->rtBits();        // No. of bits to store rT coord.
0130     rtRange_ = settings->rtRange();      // Range of rT coord. in cm.
0131     zBits_ = settings->zBits();          // No. of bits to store z coord.
0132     zRange_ = settings->zRange();        // Range of z coord in cm.
0133     //--- Parameters available in GP board (excluding any in common with HT specified above).
0134     phiNBits_ = settings->phiNBits();    // No. of bits to store phiN parameter.
0135     phiNRange_ = settings->phiNRange();  // Range of phiN parameter
0136     bendBits_ = settings->bendBits();    // No. of bits to store stub bend.
0137 
0138     // Number of phi sectors and phi nonants.
0139     numPhiSectors_ = settings->numPhiSectors();
0140     numPhiNonants_ = settings->numPhiNonants();
0141     // Phi sector and phi nonant width (radians)
0142     phiSectorWidth_ = 2. * M_PI / double(numPhiSectors_);
0143     phiNonantWidth_ = 2. * M_PI / double(numPhiNonants_);
0144     // Centre of phi sector 0.
0145     phiCentreSec0_ = -M_PI / double(numPhiNonants_) + M_PI / double(numPhiSectors_);
0146     // Radius from beamline with respect to which stub r coord. is measured.
0147     chosenRofPhi_ = settings->chosenRofPhi();
0148 
0149     // Number of q/Pt bins in Hough  transform array.
0150     nbinsPt_ = (int)settings->houghNbinsPt();
0151     // Min. of m-bin range in firmware,
0152     min_array_mbin_ = (nbinsPt_ % 2 == 0) ? -(nbinsPt_ / 2) : -(nbinsPt_ - 1) / 2;
0153 
0154     // Calculate multipliers to digitize the floating point numbers.
0155     phiSMult_ = pow(2, phiSBits_) / phiSRange_;
0156     rtMult_ = pow(2, rtBits_) / rtRange_;
0157     zMult_ = pow(2, zBits_) / zRange_;
0158     phiNMult_ = pow(2, phiNBits_) / phiNRange_;
0159 
0160     // No precision lost by digitization, since original bend (after encoding) has steps of 0.25 (in units of pitch).
0161     bendMult_ = 4.;
0162     bendRange_ = round(pow(2, bendBits_) / bendMult_);  // discrete values, so digitisation different
0163   }
0164 
0165   //=== Digitize stub
0166 
0167   void DigitalStub::digitize(unsigned int iPhiSec) {
0168     //--- Digitize variables used exclusively in GP input.
0169     iDigi_PhiN_ = floor(phiN_orig_ * phiNMult_);
0170     iDigi_Bend_ = round(bend_orig_ * bendMult_);  // discrete values, so digitisation different
0171 
0172     //--- Digitize variables used exclusively in HT input.
0173     iDigi_PhiS_ = floor(phiS_orig_ * phiSMult_);
0174 
0175     // Offset m-bin range allowed by bend to correspond to firmware.
0176     mbin_min_ = mbin_min_orig_ + min_array_mbin_;
0177     mbin_max_ = mbin_max_orig_ + min_array_mbin_;
0178 
0179     //--- Digitize variables used in both GP & HT input.
0180     iDigi_Rt_ = floor(rt_orig_ * rtMult_);
0181 
0182     //-- Digitize variables used by SF & TF input
0183     iDigi_R_ = iDigi_Rt_ + std::round(chosenRofPhi_ * rtMult_);
0184 
0185     //-- Digitize variables used by everything
0186     iDigi_Z_ = floor(z_orig_ * zMult_);
0187   }
0188 
0189   //=== Undigitize stub again.
0190 
0191   void DigitalStub::undigitize(unsigned int iPhiSec) {
0192     //--- Undigitize variables used exclusively in GP.
0193     phiN_ = (iDigi_PhiN_ + 0.5) / phiNMult_;
0194     phi_GP_ = reco::deltaPhi(phiN_, -phiNonantCentre_);
0195     bend_ = iDigi_Bend_ / bendMult_;  // discrete values, so digitisation different
0196 
0197     //--- Undigitize variables used exclusively by HT & SF/TF
0198     phiS_ = (iDigi_PhiS_ + 0.5) / phiSMult_;
0199     phi_HT_TF_ = reco::deltaPhi(phiS_, -phiSectorCentre_);
0200 
0201     //--- Undigitize variables used in both GP & HT.
0202     rt_GP_HT_ = (iDigi_Rt_ + 0.5) / rtMult_;
0203     r_GP_HT_ = rt_GP_HT_ + chosenRofPhi_;
0204 
0205     //--- Undigitize variables used exclusively by  SF/TF.
0206     r_SF_TF_ = (iDigi_R_ + 0.5) / rtMult_;
0207     rt_SF_TF_ = r_SF_TF_ - chosenRofPhi_;
0208 
0209     //--- Undigitize variables used exclusively by everything.
0210     z_ = (iDigi_Z_ + 0.5) / zMult_;
0211   }
0212 
0213   //=== Check that stub coords. are within assumed digitization range.
0214 
0215   void DigitalStub::checkInRange() const {
0216     if (std::abs(rt_orig_) >= 0.5 * rtRange_)
0217       throw cms::Exception("BadConfig") << "DigitalStub: Stub rT is out of assumed digitization range."
0218                                         << " |rt| = " << std::abs(rt_orig_) << " > " << 0.5 * rtRange_;
0219     if (std::abs(z_orig_) >= 0.5 * zRange_)
0220       throw cms::Exception("BadConfig") << "DigitalStub: Stub z is out of assumed digitization range."
0221                                         << " |z| = " << std::abs(z_orig_) << " > " << 0.5 * zRange_;
0222     if (std::abs(bend_orig_) >= 0.5 * bendRange_)
0223       throw cms::Exception("BadConfig") << "DigitalStub: Stub bend is out of assumed digitization range."
0224                                         << " |bend| = " << std::abs(bend_orig_) << " > " << 0.5 * bendRange_;
0225     //--- Can't check phi range, as DigitalStub called for stubs before sector assignment.
0226     //if (std::abs(phiS_orig_) >= 0.5 * phiSRange_)
0227     //  throw cms::Exception("BadConfig") << "DigitalStub: Stub phiS is out of assumed digitization range."
0228     //                    << " |phiS| = " << std::abs(phiS_orig_) << " > " << 0.5 * phiSRange_;
0229     //if (std::abs(phiN_orig_) >= 0.5 * phiNRange_)
0230     //  throw cms::Exception("BadConfig") << "DigitalStub: Stub phiN is out of assumed digitization range."
0231     //                << " |phiN| = " << std::abs(phiN_orig_) << " > " << 0.5 * phiNRange_;
0232   }
0233 
0234   //=== Check that digitisation followed by undigitisation doesn't change significantly the stub coordinates.
0235 
0236   void DigitalStub::checkAccuracy() const {
0237     double TA = reco::deltaPhi(phi_HT_TF_, phi_orig_);
0238     double TB = r_GP_HT_ - r_orig_;
0239     double TC = z_ - z_orig_;
0240     double TD = bend_ - bend_orig_;
0241 
0242     // Compare to small numbers, representing acceptable precision loss.
0243     constexpr double smallTA = 0.001, smallTB = 0.3, smallTC = 0.25, smallTD = 0.01;
0244     if (std::abs(TA) > smallTA || std::abs(TB) > smallTB || std::abs(TC) > smallTC || std::abs(TD) > smallTD) {
0245       throw cms::Exception("LogicError") << "WARNING: DigitalStub lost precision: " << TA << " " << TB << " " << TC
0246                                          << " " << TD;
0247     }
0248   }
0249 
0250 }  // namespace tmtt