Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-06-11 03:00:14

0001 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "DataFormats/L1TrackTrigger/interface/TTBV.h"
0004 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0005 
0006 #include <cmath>
0007 #include <algorithm>
0008 #include <numeric>
0009 #include <vector>
0010 #include <set>
0011 
0012 namespace tt {
0013 
0014   Setup::Setup(const Config& iConfig,
0015                const TrackerGeometry& trackerGeometry,
0016                const TrackerTopology& trackerTopology,
0017                const TrackerDetToDTCELinkCablingMap& cablingMap,
0018                const StubAlgorithmOfficial& stubAlgorithm,
0019                const edm::ParameterSet& pSetStubAlgorithm)
0020       : trackerGeometry_(&trackerGeometry),
0021         trackerTopology_(&trackerTopology),
0022         cablingMap_(&cablingMap),
0023         stubAlgorithm_(&stubAlgorithm),
0024         pSetSA_(&pSetStubAlgorithm),
0025         // Common track finding parameter
0026         beamWindowZ_(iConfig.beamWindowZ_),
0027         minPt_(iConfig.minPt_),
0028         minPtCand_(iConfig.minPtCand_),
0029         maxEta_(iConfig.maxEta_),
0030         maxD0_(iConfig.maxD0_),
0031         chosenRofPhi_(iConfig.chosenRofPhi_),
0032         numLayers_(iConfig.numLayers_),
0033         minLayers_(iConfig.minLayers_),
0034         // TMTT specific parameter
0035         tmttWidthR_(iConfig.tmttWidthR_),
0036         tmttWidthPhi_(iConfig.tmttWidthPhi_),
0037         tmttWidthZ_(iConfig.tmttWidthZ_),
0038         // Hybrid specific parameter
0039         hybridNumLayers_(iConfig.hybridNumLayers_),
0040         hybridNumRingsPS_(iConfig.hybridNumRingsPS_),
0041         hybridWidthsR_(iConfig.hybridWidthsR_),
0042         hybridWidthsZ_(iConfig.hybridWidthsZ_),
0043         hybridWidthsPhi_(iConfig.hybridWidthsPhi_),
0044         hybridWidthsAlpha_(iConfig.hybridWidthsAlpha_),
0045         hybridWidthsBend_(iConfig.hybridWidthsBend_),
0046         hybridRangesR_(iConfig.hybridRangesR_),
0047         hybridRangesZ_(iConfig.hybridRangesZ_),
0048         hybridRangesAlpha_(iConfig.hybridRangesAlpha_),
0049         hybridLayerRs_(iConfig.hybridLayerRs_),
0050         hybridDiskZs_(iConfig.hybridDiskZs_),
0051         hybridDisk2SRsSet_(iConfig.hybridDisk2SRsSet_),
0052         tbBarrelHalfLength_(iConfig.tbBarrelHalfLength_),
0053         tbInnerRadius_(iConfig.tbInnerRadius_),
0054         tbWidthsR_(iConfig.tbWidthsR_),
0055         // Fimrware specific Parameter
0056         enableTruncation_(iConfig.enableTruncation_),
0057         useHybrid_(iConfig.useHybrid_),
0058         widthDSPa_(iConfig.widthDSPa_),
0059         widthDSPb_(iConfig.widthDSPb_),
0060         widthDSPc_(iConfig.widthDSPc_),
0061         widthAddrBRAM36_(iConfig.widthAddrBRAM36_),
0062         widthAddrBRAM18_(iConfig.widthAddrBRAM18_),
0063         numFramesInfra_(iConfig.numFramesInfra_),
0064         freqLHC_(iConfig.freqLHC_),
0065         freqBEHigh_(iConfig.freqBEHigh_),
0066         freqBELow_(iConfig.freqBELow_),
0067         tmpFE_(iConfig.tmpFE_),
0068         tmpTFP_(iConfig.tmpTFP_),
0069         speedOfLight_(iConfig.speedOfLight_),
0070         // Tracker specific Paramter
0071         bField_(iConfig.bField_),
0072         bFieldError_(iConfig.bFieldError_),
0073         outerRadius_(iConfig.outerRadius_),
0074         innerRadius_(iConfig.innerRadius_),
0075         halfLength_(iConfig.halfLength_),
0076         tiltApproxSlope_(iConfig.tiltApproxSlope_),
0077         tiltApproxIntercept_(iConfig.tiltApproxIntercept_),
0078         tiltUncertaintyR_(iConfig.tiltUncertaintyR_),
0079         scattering_(iConfig.scattering_),
0080         pitchRow2S_(iConfig.pitchRow2S_),
0081         pitchRowPS_(iConfig.pitchRowPS_),
0082         pitchCol2S_(iConfig.pitchCol2S_),
0083         pitchColPS_(iConfig.pitchColPS_),
0084         limitPSBarrel_(iConfig.limitPSBarrel_),
0085         limitsTiltedR_(iConfig.limitsTiltedR_),
0086         limitsTiltedZ_(iConfig.limitsTiltedZ_),
0087         limitsPSDiksZ_(iConfig.limitsPSDiksZ_),
0088         limitsPSDiksR_(iConfig.limitsPSDiksR_),
0089         tiltedLayerLimitsZ_(iConfig.tiltedLayerLimitsZ_),
0090         psDiskLimitsR_(iConfig.psDiskLimitsR_),
0091         // Parmeter specifying front-end
0092         widthBend_(iConfig.widthBend_),
0093         widthCol_(iConfig.widthCol_),
0094         widthRow_(iConfig.widthRow_),
0095         baseBend_(iConfig.baseBend_),
0096         baseCol_(iConfig.baseCol_),
0097         baseRow_(iConfig.baseRow_),
0098         baseWindowSize_(iConfig.baseWindowSize_),
0099         bendCut_(iConfig.bendCut_),
0100         // Parmeter specifying DTC
0101         numRegions_(iConfig.numRegions_),
0102         numOverlappingRegions_(iConfig.numOverlappingRegions_),
0103         numATCASlots_(iConfig.numATCASlots_),
0104         numDTCsPerRegion_(iConfig.numDTCsPerRegion_),
0105         numModulesPerDTC_(iConfig.numModulesPerDTC_),
0106         dtcNumRoutingBlocks_(iConfig.dtcNumRoutingBlocks_),
0107         dtcDepthMemory_(iConfig.dtcDepthMemory_),
0108         dtcWidthRowLUT_(iConfig.dtcWidthRowLUT_),
0109         dtcWidthInv2R_(iConfig.dtcWidthInv2R_),
0110         offsetDetIdDSV_(iConfig.offsetDetIdDSV_),
0111         offsetDetIdTP_(iConfig.offsetDetIdTP_),
0112         offsetLayerDisks_(iConfig.offsetLayerDisks_),
0113         offsetLayerId_(iConfig.offsetLayerId_),
0114         numBarrelLayer_(iConfig.numBarrelLayer_),
0115         numBarrelLayerPS_(iConfig.numBarrelLayerPS_),
0116         slotLimitPS_(iConfig.slotLimitPS_),
0117         slotLimit10gbps_(iConfig.slotLimit10gbps_),
0118         // Parmeter specifying TFP
0119         tfpWidthPhi0_(iConfig.tfpWidthPhi0_),
0120         tfpWidthInvR_(iConfig.tfpWidthInvR_),
0121         tfpWidthCot_(iConfig.tfpWidthCot_),
0122         tfpWidthZ0_(iConfig.tfpWidthZ0_),
0123         tfpNumChannel_(iConfig.tfpNumChannel_),
0124         // Parmeter specifying GeometricProcessor
0125         gpNumBinsPhiT_(iConfig.gpNumBinsPhiT_),
0126         gpNumBinsZT_(iConfig.gpNumBinsZT_),
0127         chosenRofZ_(iConfig.chosenRofZ_),
0128         gpDepthMemory_(iConfig.gpDepthMemory_),
0129         gpWidthModule_(iConfig.gpWidthModule_),
0130         gpPosPS_(iConfig.gpPosPS_),
0131         gpPosBarrel_(iConfig.gpPosBarrel_),
0132         gpPosTilted_(iConfig.gpPosTilted_),
0133         // Parmeter specifying HoughTransform
0134         htNumBinsInv2R_(iConfig.htNumBinsInv2R_),
0135         htNumBinsPhiT_(iConfig.htNumBinsPhiT_),
0136         htMinLayers_(iConfig.htMinLayers_),
0137         htDepthMemory_(iConfig.htDepthMemory_),
0138         // Parameter specifying Track Builder
0139         ctbNumBinsInv2R_(iConfig.ctbNumBinsInv2R_),
0140         ctbNumBinsPhiT_(iConfig.ctbNumBinsPhiT_),
0141         ctbNumBinsCot_(iConfig.ctbNumBinsCot_),
0142         ctbNumBinsZT_(iConfig.ctbNumBinsZT_),
0143         ctbMinLayers_(iConfig.ctbMinLayers_),
0144         ctbMaxTracks_(iConfig.ctbMaxTracks_),
0145         ctbMaxStubs_(iConfig.ctbMaxStubs_),
0146         ctbDepthMemory_(iConfig.ctbDepthMemory_),
0147         // Parmeter specifying KalmanFilter
0148         kfUse5ParameterFit_(iConfig.kfUse5ParameterFit_),
0149         kfUseSimmulation_(iConfig.kfUseSimmulation_),
0150         kfUseTTStubResiduals_(iConfig.kfUseTTStubResiduals_),
0151         kfUseTTStubParameters_(iConfig.kfUseTTStubParameters_),
0152         kfApplyNonLinearCorrection_(iConfig.kfApplyNonLinearCorrection_),
0153         kfNumWorker_(iConfig.kfNumWorker_),
0154         kfMaxTracks_(iConfig.kfMaxTracks_),
0155         kfMinLayers_(iConfig.kfMinLayers_),
0156         kfMinLayersPS_(iConfig.kfMinLayersPS_),
0157         kfMaxLayers_(iConfig.kfMaxLayers_),
0158         kfMaxGaps_(iConfig.kfMaxGaps_),
0159         kfMaxSeedingLayer_(iConfig.kfMaxSeedingLayer_),
0160         kfNumSeedStubs_(iConfig.kfNumSeedStubs_),
0161         kfMinSeedDeltaR_(iConfig.kfMinSeedDeltaR_),
0162         kfRangeFactor_(iConfig.kfRangeFactor_),
0163         kfShiftInitialC00_(iConfig.kfShiftInitialC00_),
0164         kfShiftInitialC11_(iConfig.kfShiftInitialC11_),
0165         kfShiftInitialC22_(iConfig.kfShiftInitialC22_),
0166         kfShiftInitialC33_(iConfig.kfShiftInitialC33_),
0167         kfShiftChi20_(iConfig.kfShiftChi20_),
0168         kfShiftChi21_(iConfig.kfShiftChi21_),
0169         kfCutChi2_(iConfig.kfCutChi2_),
0170         kfWidthChi2_(iConfig.kfWidthChi2_),
0171         // Parmeter specifying DuplicateRemoval
0172         drDepthMemory_(iConfig.drDepthMemory_),
0173         // Parmeter specifying Track Quality
0174         tqNumChannel_(iConfig.tqNumChannel_) {
0175     // derive constants
0176     calculateConstants();
0177     // convert configuration of TTStubAlgorithm
0178     consumeStubAlgorithm();
0179     // create all possible encodingsBend
0180     encodingsBendPS_.reserve(maxWindowSize_ + 1);
0181     encodingsBend2S_.reserve(maxWindowSize_ + 1);
0182     encodeBend(encodingsBendPS_, true);
0183     encodeBend(encodingsBend2S_, false);
0184     // create sensor modules
0185     produceSensorModules();
0186   }
0187 
0188   // converts tk layout id into dtc id
0189   int Setup::dtcId(int tkLayoutId) const {
0190     checkTKLayoutId(tkLayoutId);
0191     const int tkId = tkLayoutId - 1;
0192     const int side = tkId / (numRegions_ * numATCASlots_);
0193     const int region = (tkId % (numRegions_ * numATCASlots_)) / numATCASlots_;
0194     const int slot = tkId % numATCASlots_;
0195     return region * numDTCsPerRegion_ + side * numATCASlots_ + slot;
0196   }
0197 
0198   // converts dtc id into tk layout id
0199   int Setup::tkLayoutId(int dtcId) const {
0200     checkDTCId(dtcId);
0201     const int slot = dtcId % numATCASlots_;
0202     const int region = dtcId / numDTCsPerRegion_;
0203     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0204     return (side * numRegions_ + region) * numATCASlots_ + slot + 1;
0205   }
0206 
0207   // converts TFP identifier (region[0-8], channel[0-47]) into dtc id
0208   int Setup::dtcId(int tfpRegion, int tfpChannel) const {
0209     checkTFPIdentifier(tfpRegion, tfpChannel);
0210     const int dtcChannel = numOverlappingRegions_ - (tfpChannel / numDTCsPerRegion_) - 1;
0211     const int dtcBoard = tfpChannel % numDTCsPerRegion_;
0212     const int dtcRegion = tfpRegion - dtcChannel >= 0 ? tfpRegion - dtcChannel : tfpRegion - dtcChannel + numRegions_;
0213     return dtcRegion * numDTCsPerRegion_ + dtcBoard;
0214   }
0215 
0216   // checks if given DTC id is connected to PS or 2S sensormodules
0217   bool Setup::psModule(int dtcId) const {
0218     checkDTCId(dtcId);
0219     // from tklayout: first 3 are 10 gbps PS, next 3 are 5 gbps PS and residual 6 are 5 gbps 2S modules
0220     return slot(dtcId) < slotLimitPS_;
0221   }
0222 
0223   // return sensor moduel type
0224   SensorModule::Type Setup::type(const TTStubRef& ttStubRef) const {
0225     const bool barrel = this->barrel(ttStubRef);
0226     const bool psModule = this->psModule(ttStubRef);
0227     SensorModule::Type type;
0228     if (barrel && psModule)
0229       type = SensorModule::BarrelPS;
0230     if (barrel && !psModule)
0231       type = SensorModule::Barrel2S;
0232     if (!barrel && psModule)
0233       type = SensorModule::DiskPS;
0234     if (!barrel && !psModule)
0235       type = SensorModule::Disk2S;
0236     return type;
0237   }
0238 
0239   // checks if given dtcId is connected via 10 gbps link
0240   bool Setup::gbps10(int dtcId) const {
0241     checkDTCId(dtcId);
0242     return slot(dtcId) < slotLimit10gbps_;
0243   }
0244 
0245   // checks if given dtcId is connected to -z (false) or +z (true)
0246   bool Setup::side(int dtcId) const {
0247     checkDTCId(dtcId);
0248     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0249     // from tkLayout: first 12 +z, next 12 -z
0250     return side == 0;
0251   }
0252 
0253   // ATCA slot number [0-11] of given dtcId
0254   int Setup::slot(int dtcId) const {
0255     checkDTCId(dtcId);
0256     return dtcId % numATCASlots_;
0257   }
0258 
0259   // sensor module for det id
0260   SensorModule* Setup::sensorModule(const DetId& detId) const {
0261     const auto it = detIdToSensorModule_.find(detId);
0262     if (it == detIdToSensorModule_.end()) {
0263       cms::Exception exception("NullPtr");
0264       exception << "Unknown DetId used.";
0265       exception.addContext("tt::Setup::sensorModule");
0266       throw exception;
0267     }
0268     return it->second;
0269   }
0270 
0271   // sensor module for ttStubRef
0272   SensorModule* Setup::sensorModule(const TTStubRef& ttStubRef) const {
0273     const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_;
0274     return this->sensorModule(detId);
0275   }
0276 
0277   // index = encoded bend, value = decoded bend for given window size and module type
0278   const std::vector<double>& Setup::encodingBend(int windowSize, bool psModule) const {
0279     const std::vector<std::vector<double>>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_;
0280     return encodingsBend.at(windowSize);
0281   }
0282 
0283   // convert configuration of TTStubAlgorithm
0284   void Setup::consumeStubAlgorithm() {
0285     numTiltedLayerRings_ = pSetSA_->getParameter<std::vector<double>>("NTiltedRings");
0286     windowSizeBarrelLayers_ = pSetSA_->getParameter<std::vector<double>>("BarrelCut");
0287     const auto& pSetsTiltedLayer = pSetSA_->getParameter<std::vector<edm::ParameterSet>>("TiltedBarrelCutSet");
0288     const auto& pSetsEncapDisks = pSetSA_->getParameter<std::vector<edm::ParameterSet>>("EndcapCutSet");
0289     windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size());
0290     for (const auto& pSet : pSetsTiltedLayer)
0291       windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter<std::vector<double>>("TiltedCut"));
0292     windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size());
0293     for (const auto& pSet : pSetsEncapDisks)
0294       windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter<std::vector<double>>("EndcapCut"));
0295     maxWindowSize_ = -1;
0296     for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}})
0297       for (const auto& windows : windowss)
0298         for (const auto& window : windows)
0299           maxWindowSize_ = std::max(maxWindowSize_, static_cast<int>(window / baseWindowSize_));
0300   }
0301 
0302   // create bend encodings
0303   void Setup::encodeBend(std::vector<std::vector<double>>& encodings, bool ps) const {
0304     for (int window = 0; window < maxWindowSize_ + 1; window++) {
0305       std::set<double> encoding;
0306       for (int bend = 0; bend < window + 1; bend++)
0307         encoding.insert(stubAlgorithm_->degradeBend(ps, window, bend));
0308       encodings.emplace_back(encoding.begin(), encoding.end());
0309     }
0310   }
0311 
0312   // create sensor modules
0313   void Setup::produceSensorModules() {
0314     sensorModules_.reserve(numModules_);
0315     dtcModules_ = std::vector<std::vector<SensorModule*>>(numDTCs_);
0316     for (std::vector<SensorModule*>& dtcModules : dtcModules_)
0317       dtcModules.reserve(numModulesPerDTC_);
0318     enum SubDetId { pixelBarrel = 1, pixelDisks = 2 };
0319     // loop over all tracker modules
0320     for (const DetId& detId : trackerGeometry_->detIds()) {
0321       // skip pixel detector
0322       if (detId.subdetId() == pixelBarrel || detId.subdetId() == pixelDisks)
0323         continue;
0324       // skip multiple detIds per module
0325       if (!trackerTopology_->isLower(detId))
0326         continue;
0327       // lowerDetId - 1 = tk layout det id
0328       const DetId detIdTkLayout = detId + offsetDetIdTP_;
0329       // tk layout dtc id, lowerDetId - 1 = tk lyout det id
0330       const int tklId = cablingMap_->detIdToDTCELinkId(detIdTkLayout).first->second.dtc_id();
0331       // track trigger dtc id [0-215]
0332       const int dtcId = Setup::dtcId(tklId);
0333       // collection of so far connected modules to this dtc
0334       std::vector<SensorModule*>& dtcModules = dtcModules_[dtcId];
0335       // construct sendor module
0336       sensorModules_.emplace_back(this, detId, dtcId, dtcModules.size());
0337       SensorModule* sensorModule = &sensorModules_.back();
0338       // store connection between detId and sensor module
0339       detIdToSensorModule_.emplace(detId, sensorModule);
0340       // store connection between dtcId and sensor module
0341       dtcModules.push_back(sensorModule);
0342     }
0343     for (std::vector<SensorModule*>& dtcModules : dtcModules_) {
0344       dtcModules.shrink_to_fit();
0345       // check configuration
0346       if ((int)dtcModules.size() > numModulesPerDTC_) {
0347         cms::Exception exception("overflow");
0348         exception << "Cabling map connects more than " << numModulesPerDTC_ << " modules to a DTC.";
0349         exception.addContext("tt::Setup::Setup");
0350         throw exception;
0351       }
0352     }
0353   }
0354 
0355   // stub layer id (barrel: 1 - 6, endcap: 11 - 15)
0356   int Setup::layerId(const TTStubRef& ttStubRef) const {
0357     const DetId& detId = ttStubRef->getDetId();
0358     return detId.subdetId() == StripSubdetector::TOB ? trackerTopology_->layer(detId)
0359                                                      : trackerTopology_->tidWheel(detId) + offsetLayerDisks_;
0360   }
0361 
0362   // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef
0363   int Setup::trackletLayerId(const TTStubRef& ttStubRef) const {
0364     static constexpr int offsetBarrel = 1;
0365     static constexpr int offsetDisks = 5;
0366     return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetBarrel : offsetDisks);
0367   }
0368 
0369   // return index layerId (barrel: [0-5], endcap: [0-6]) for given TTStubRef
0370   int Setup::indexLayerId(const TTStubRef& ttStubRef) const {
0371     static constexpr int offsetBarrel = 1;
0372     static constexpr int offsetDisks = 11;
0373     return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetBarrel : offsetDisks);
0374   }
0375 
0376   // true if stub from barrel module
0377   bool Setup::barrel(const TTStubRef& ttStubRef) const {
0378     const DetId& detId = ttStubRef->getDetId();
0379     return detId.subdetId() == StripSubdetector::TOB;
0380   }
0381 
0382   // true if stub from barrel module
0383   bool Setup::psModule(const TTStubRef& ttStubRef) const {
0384     const DetId& detId = ttStubRef->getDetId();
0385     SensorModule* sm = sensorModule(detId + 1);
0386     return sm->psModule();
0387   }
0388 
0389   //
0390   TTBV Setup::layerMap(const std::vector<int>& ints) const {
0391     TTBV ttBV;
0392     for (int layer = numLayers_ - 1; layer >= 0; layer--) {
0393       const int i = ints[layer];
0394       ttBV += TTBV(i, ctbWidthLayerCount_);
0395     }
0396     return ttBV;
0397   }
0398 
0399   //
0400   TTBV Setup::layerMap(const TTBV& hitPattern, const std::vector<int>& ints) const {
0401     TTBV ttBV;
0402     for (int layer = numLayers_ - 1; layer >= 0; layer--) {
0403       const int i = ints[layer];
0404       ttBV += TTBV((hitPattern[layer] ? i - 1 : 0), ctbWidthLayerCount_);
0405     }
0406     return ttBV;
0407   }
0408 
0409   //
0410   std::vector<int> Setup::layerMap(const TTBV& hitPattern, const TTBV& ttBV) const {
0411     TTBV bv(ttBV);
0412     std::vector<int> ints(numLayers_, 0);
0413     for (int layer = 0; layer < numLayers_; layer++) {
0414       const int i = bv.extract(ctbWidthLayerCount_);
0415       ints[layer] = i + (hitPattern[layer] ? 1 : 0);
0416     }
0417     return ints;
0418   }
0419 
0420   //
0421   std::vector<int> Setup::layerMap(const TTBV& ttBV) const {
0422     TTBV bv(ttBV);
0423     std::vector<int> ints(numLayers_, 0);
0424     for (int layer = 0; layer < numLayers_; layer++)
0425       ints[layer] = bv.extract(ctbWidthLayerCount_);
0426     return ints;
0427   }
0428 
0429   // stub projected phi uncertainty
0430   double Setup::dPhi(const TTStubRef& ttStubRef, double inv2R) const {
0431     const DetId& detId = ttStubRef->getDetId();
0432     SensorModule* sm = sensorModule(detId + 1);
0433     return sm->dPhi(inv2R);
0434   }
0435 
0436   // stub projected z uncertainty
0437   double Setup::dZ(const TTStubRef& ttStubRef) const {
0438     const DetId& detId = ttStubRef->getDetId();
0439     SensorModule* sm = sensorModule(detId + 1);
0440     const double dZ = sm->dZ();
0441     return dZ;
0442   }
0443 
0444   // stub projected chi2phi wheight
0445   double Setup::v0(const TTStubRef& ttStubRef, double inv2R) const {
0446     const DetId& detId = ttStubRef->getDetId();
0447     SensorModule* sm = sensorModule(detId + 1);
0448     const double r = stubPos(ttStubRef).perp();
0449     const double sigma = std::pow(sm->pitchRow() / r, 2) / 12.;
0450     const double scat = std::pow(scattering_ * inv2R, 2);
0451     const double extra = sm->barrel() ? 0. : std::pow(sm->pitchCol() * inv2R, 2);
0452     const double digi = std::pow(tmttBasePhi_ / 12., 2);
0453     return sigma + scat + extra + digi;
0454   }
0455 
0456   // stub projected chi2z wheight
0457   double Setup::v1(const TTStubRef& ttStubRef, double cot) const {
0458     const DetId& detId = ttStubRef->getDetId();
0459     SensorModule* sm = sensorModule(detId + 1);
0460     const double sigma = std::pow(sm->pitchCol() * sm->tiltCorrection(cot), 2) / 12.;
0461     const double digi = std::pow(tmttBaseZ_ / 12., 2);
0462     return sigma + digi;
0463   }
0464 
0465   // checks if stub collection is considered forming a reconstructable track
0466   bool Setup::reconstructable(const std::vector<TTStubRef>& ttStubRefs) const {
0467     std::set<int> hitPattern;
0468     for (const TTStubRef& ttStubRef : ttStubRefs)
0469       hitPattern.insert(layerId(ttStubRef));
0470     return (int)hitPattern.size() >= minLayers_;
0471   }
0472 
0473   //
0474   TTBV Setup::module(double r, double z) const {
0475     static constexpr int layer1 = 0;
0476     static constexpr int layer2 = 1;
0477     static constexpr int layer3 = 2;
0478     static constexpr int disk1 = 0;
0479     static constexpr int disk2 = 1;
0480     static constexpr int disk3 = 2;
0481     static constexpr int disk4 = 3;
0482     static constexpr int disk5 = 4;
0483     bool ps(false);
0484     bool barrel(false);
0485     bool tilted(false);
0486     if (std::abs(z) < limitPSBarrel_) {
0487       barrel = true;
0488       if (r < limitsTiltedR_[layer3])
0489         ps = true;
0490       if (r < limitsTiltedR_[layer1])
0491         tilted = std::abs(z) > limitsTiltedZ_[layer1];
0492       else if (r < limitsTiltedR_[layer2])
0493         tilted = std::abs(z) > limitsTiltedZ_[layer2];
0494       else if (r < limitsTiltedR_[layer3])
0495         tilted = std::abs(z) > limitsTiltedZ_[layer3];
0496     } else if (std::abs(z) > limitsPSDiksZ_[disk5])
0497       ps = r < limitsPSDiksR_[disk5];
0498     else if (std::abs(z) > limitsPSDiksZ_[disk4])
0499       ps = r < limitsPSDiksR_[disk4];
0500     else if (std::abs(z) > limitsPSDiksZ_[disk3])
0501       ps = r < limitsPSDiksR_[disk3];
0502     else if (std::abs(z) > limitsPSDiksZ_[disk2])
0503       ps = r < limitsPSDiksR_[disk2];
0504     else if (std::abs(z) > limitsPSDiksZ_[disk1])
0505       ps = r < limitsPSDiksR_[disk1];
0506     TTBV module(0, gpWidthModule_);
0507     if (ps)
0508       module.set(gpPosPS_);
0509     if (barrel)
0510       module.set(gpPosBarrel_);
0511     if (tilted)
0512       module.set(gpPosTilted_);
0513     return module;
0514   }
0515 
0516   // stub projected phi uncertainty for given module type, stub radius and track curvature
0517   double Setup::dPhi(const TTBV& module, double r, double inv2R) const {
0518     const double sigma = (ps(module) ? pitchRowPS_ : pitchRow2S_) / r;
0519     const double dR = scattering_ + (barrel(module) ? (tilted(module) ? tiltUncertaintyR_ : 0.0)
0520                                                     : (ps(module) ? pitchColPS_ : pitchCol2S_));
0521     const double dPhi = sigma + dR * abs(inv2R) + tmttBasePhi_;
0522     return dPhi;
0523   }
0524 
0525   // derive constants
0526   void Setup::calculateConstants() {
0527     // emp
0528     const int numFramesPerBXHigh = freqBEHigh_ / freqLHC_;
0529     numFramesHigh_ = numFramesPerBXHigh * tmpTFP_ - 1;
0530     numFramesIOHigh_ = numFramesPerBXHigh * tmpTFP_ - numFramesInfra_;
0531     const int numFramesPerBXLow = freqBELow_ / freqLHC_;
0532     numFramesLow_ = numFramesPerBXLow * tmpTFP_ - 1;
0533     numFramesIOLow_ = numFramesPerBXLow * tmpTFP_ - numFramesInfra_;
0534     numFramesFE_ = numFramesPerBXHigh * tmpFE_ - numFramesInfra_;
0535     // dsp
0536     widthDSPab_ = widthDSPa_ - 1;
0537     widthDSPau_ = widthDSPab_ - 1;
0538     widthDSPbb_ = widthDSPb_ - 1;
0539     widthDSPbu_ = widthDSPbb_ - 1;
0540     widthDSPcb_ = widthDSPc_ - 1;
0541     widthDSPcu_ = widthDSPcb_ - 1;
0542     // firmware
0543     maxPitchRow_ = std::max(pitchRowPS_, pitchRow2S_);
0544     maxPitchCol_ = std::max(pitchColPS_, pitchCol2S_);
0545     // common track finding
0546     invPtToDphi_ = speedOfLight_ * bField_ / 2000.;
0547     baseRegion_ = 2. * M_PI / numRegions_;
0548     maxCot_ = beamWindowZ_ / chosenRofZ_ + std::sinh(maxEta_);
0549     // gp
0550     baseSector_ = baseRegion_ / gpNumBinsPhiT_;
0551     maxRphi_ = std::max(std::abs(outerRadius_ - chosenRofPhi_), std::abs(innerRadius_ - chosenRofPhi_));
0552     maxRz_ = std::max(std::abs(outerRadius_ - chosenRofZ_), std::abs(innerRadius_ - chosenRofZ_));
0553     numSectors_ = gpNumBinsPhiT_ * gpNumBinsZT_;
0554     // tmtt
0555     const double rangeInv2R = 2. * invPtToDphi_ / minPt_;
0556     tmttBaseInv2R_ = rangeInv2R / htNumBinsInv2R_;
0557     tmttBasePhiT_ = baseSector_ / htNumBinsPhiT_;
0558     const double baseRgen = tmttBasePhiT_ / tmttBaseInv2R_;
0559     const double rangeR = 2. * maxRphi_;
0560     const int baseShiftR = std::ceil(std::log2(rangeR / baseRgen / std::pow(2., tmttWidthR_)));
0561     tmttBaseR_ = baseRgen * std::pow(2., baseShiftR);
0562     const double rangeZ = 2. * halfLength_;
0563     const int baseShiftZ = std::ceil(std::log2(rangeZ / tmttBaseR_ / std::pow(2., tmttWidthZ_)));
0564     tmttBaseZ_ = tmttBaseR_ * std::pow(2., baseShiftZ);
0565     const double rangePhi = baseRegion_ + rangeInv2R * rangeR / 2.;
0566     const int baseShiftPhi = std::ceil(std::log2(rangePhi / tmttBasePhiT_ / std::pow(2., tmttWidthPhi_)));
0567     tmttBasePhi_ = tmttBasePhiT_ * std::pow(2., baseShiftPhi);
0568     tmttWidthLayer_ = std::ceil(std::log2(numLayers_));
0569     tmttWidthSectorEta_ = std::ceil(std::log2(gpNumBinsZT_));
0570     tmttWidthInv2R_ = std::ceil(std::log2(htNumBinsInv2R_));
0571     tmttNumUnusedBits_ = TTBV::S_ - tmttWidthLayer_ - 2 * tmttWidthSectorEta_ - tmttWidthR_ - tmttWidthPhi_ -
0572                          tmttWidthZ_ - 2 * tmttWidthInv2R_ - gpNumBinsPhiT_ - 1;
0573     // hybrid
0574     const double hybridRangeInv2R = 2. * invPtToDphi_ / minPt_;
0575     const double hybridRangeR =
0576         2. * std::max(std::abs(outerRadius_ - chosenRofPhi_), std::abs(innerRadius_ - chosenRofPhi_));
0577     hybridRangePhi_ = baseRegion_ + (hybridRangeR * hybridRangeInv2R) / 2.;
0578     hybridWidthLayerId_ = std::ceil(std::log2(hybridNumLayers_));
0579     hybridBasesZ_.reserve(SensorModule::NumTypes);
0580     for (int type = 0; type < SensorModule::NumTypes; type++)
0581       hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / std::pow(2., hybridWidthsZ_.at(type)));
0582     hybridBasesR_.reserve(SensorModule::NumTypes);
0583     for (int type = 0; type < SensorModule::NumTypes; type++)
0584       hybridBasesR_.emplace_back(hybridRangesR_.at(type) / std::pow(2., hybridWidthsR_.at(type)));
0585     hybridBasesR_[SensorModule::Disk2S] = 1.;
0586     hybridBasesPhi_.reserve(SensorModule::NumTypes);
0587     for (int type = 0; type < SensorModule::NumTypes; type++)
0588       hybridBasesPhi_.emplace_back(hybridRangePhi_ / std::pow(2., hybridWidthsPhi_.at(type)));
0589     hybridBasesAlpha_.reserve(SensorModule::NumTypes);
0590     for (int type = 0; type < SensorModule::NumTypes; type++)
0591       hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / std::pow(2., hybridWidthsAlpha_.at(type)));
0592     hybridNumsUnusedBits_.reserve(SensorModule::NumTypes);
0593     for (int type = 0; type < SensorModule::NumTypes; type++)
0594       hybridNumsUnusedBits_.emplace_back(TTBV::S_ - hybridWidthsR_.at(type) - hybridWidthsZ_.at(type) -
0595                                          hybridWidthsPhi_.at(type) - hybridWidthsAlpha_.at(type) -
0596                                          hybridWidthsBend_.at(type) - hybridWidthLayerId_ - 1);
0597     hybridBaseR_ = *std::min_element(hybridBasesR_.begin(), hybridBasesR_.end());
0598     hybridBasePhi_ = *std::min_element(hybridBasesPhi_.begin(), hybridBasesPhi_.end());
0599     hybridBaseZ_ = *std::min_element(hybridBasesZ_.begin(), hybridBasesZ_.end());
0600     hybridMaxCot_ = std::sinh(maxEta_);
0601     disk2SRs_.reserve(hybridDisk2SRsSet_.size());
0602     for (const auto& pSet : hybridDisk2SRsSet_)
0603       disk2SRs_.emplace_back(pSet.getParameter<std::vector<double>>("Disk2SRs"));
0604     // dtc
0605     numDTCs_ = numRegions_ * numDTCsPerRegion_;
0606     numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_;
0607     numModules_ = numDTCs_ * numModulesPerDTC_;
0608     dtcNumModulesPerRoutingBlock_ = numModulesPerDTC_ / dtcNumRoutingBlocks_;
0609     dtcNumMergedRows_ = std::pow(2, widthRow_ - dtcWidthRowLUT_);
0610     const double maxRangeInv2R = std::max(rangeInv2R, hybridRangeInv2R);
0611     const int baseShiftInv2R =
0612         std::ceil(std::log2(htNumBinsInv2R_)) - dtcWidthInv2R_ + std::ceil(std::log2(maxRangeInv2R / rangeInv2R));
0613     dtcBaseInv2R_ = tmttBaseInv2R_ * std::pow(2., baseShiftInv2R);
0614     const int baseDiffM = dtcWidthRowLUT_ - widthRow_;
0615     dtcBaseM_ = tmttBasePhi_ * std::pow(2., baseDiffM);
0616     const double x1 = std::pow(2, widthRow_) * baseRow_ * maxPitchRow_ / 2.;
0617     const double x0 = x1 - std::pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitchRow_;
0618     const double maxM = std::atan2(x1, innerRadius_) - std::atan2(x0, innerRadius_);
0619     dtcWidthM_ = std::ceil(std::log2(maxM / dtcBaseM_));
0620     dtcNumStreams_ = numDTCs_ * numOverlappingRegions_;
0621     // ctb
0622     ctbWidthLayerCount_ = std::ceil(std::log2(ctbMaxStubs_));
0623     // kf
0624   }
0625 
0626   // returns bit accurate hybrid stub radius for given TTStubRef and h/w bit word
0627   double Setup::stubR(const TTBV& hw, const TTStubRef& ttStubRef) const {
0628     const bool barrel = this->barrel(ttStubRef);
0629     const int layerId = this->indexLayerId(ttStubRef);
0630     const SensorModule::Type type = this->type(ttStubRef);
0631     const int widthR = hybridWidthsR_.at(type);
0632     const double baseR = hybridBasesR_.at(type);
0633     const TTBV hwR(hw, widthR, 0, barrel);
0634     double r = hwR.val(baseR) + (barrel ? hybridLayerRs_.at(layerId) : 0.);
0635     if (type == SensorModule::Disk2S)
0636       r = disk2SRs_.at(layerId).at((int)r);
0637     return r;
0638   }
0639 
0640   // returns bit accurate position of a stub from a given tfp region [0-8]
0641   GlobalPoint Setup::stubPos(const FrameStub& frame, int region) const {
0642     GlobalPoint p;
0643     if (frame.first.isNull())
0644       return p;
0645     TTBV bv(frame.second);
0646     if (useHybrid_) {
0647       const bool barrel = this->barrel(frame.first);
0648       const int layerId = this->indexLayerId(frame.first);
0649       const GlobalPoint gp = this->stubPos(frame.first);
0650       const bool side = gp.z() > 0.;
0651       const SensorModule::Type type = this->type(frame.first);
0652       const int widthBend = hybridWidthsBend_.at(type);
0653       const int widthAlpha = hybridWidthsAlpha_.at(type);
0654       const int widthPhi = hybridWidthsPhi_.at(type);
0655       const int widthZ = hybridWidthsZ_.at(type);
0656       const int widthR = hybridWidthsR_.at(type);
0657       const double basePhi = hybridBasesPhi_.at(type);
0658       const double baseZ = hybridBasesZ_.at(type);
0659       const double baseR = hybridBasesR_.at(type);
0660       // parse bit vector
0661       bv >>= 1 + hybridWidthLayerId_ + widthBend + widthAlpha;
0662       double phi = bv.val(basePhi, widthPhi) - hybridRangePhi_ / 2.;
0663       bv >>= widthPhi;
0664       double z = bv.val(baseZ, widthZ, 0, true);
0665       bv >>= widthZ;
0666       double r = bv.val(baseR, widthR, 0, barrel);
0667       if (barrel)
0668         r += hybridLayerRs_.at(layerId);
0669       else
0670         z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.);
0671       phi = deltaPhi(phi + region * baseRegion_);
0672       if (type == SensorModule::Disk2S) {
0673         r = bv.val(widthR);
0674         r = disk2SRs_.at(layerId).at((int)r);
0675       }
0676       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0677     } else {
0678       bv >>= 2 * tmttWidthInv2R_ + 2 * tmttWidthSectorEta_ + gpNumBinsPhiT_ + tmttWidthLayer_;
0679       double z = (bv.val(tmttWidthZ_, 0, true) + .5) * tmttBaseZ_;
0680       bv >>= tmttWidthZ_;
0681       double phi = (bv.val(tmttWidthPhi_, 0, true) + .5) * tmttBasePhi_;
0682       bv >>= tmttWidthPhi_;
0683       double r = (bv.val(tmttWidthR_, 0, true) + .5) * tmttBaseR_;
0684       bv >>= tmttWidthR_;
0685       r = r + chosenRofPhi_;
0686       phi = deltaPhi(phi + region * baseRegion_);
0687       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0688     }
0689     return p;
0690   }
0691 
0692   // returns global TTStub position
0693   GlobalPoint Setup::stubPos(const TTStubRef& ttStubRef) const {
0694     const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_;
0695     const GeomDetUnit* det = trackerGeometry_->idToDetUnit(detId);
0696     const PixelTopology* topol =
0697         dynamic_cast<const PixelTopology*>(&(dynamic_cast<const PixelGeomDetUnit*>(det)->specificTopology()));
0698     const Plane& plane = dynamic_cast<const PixelGeomDetUnit*>(det)->surface();
0699     const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
0700     return plane.toGlobal(topol->localPosition(mp));
0701   }
0702 
0703   // range check of dtc id
0704   void Setup::checkDTCId(int dtcId) const {
0705     if (dtcId < 0 || dtcId >= numDTCsPerRegion_ * numRegions_) {
0706       cms::Exception exception("out_of_range");
0707       exception.addContext("tt::Setup::checkDTCId");
0708       exception << "Used DTC Id (" << dtcId << ") "
0709                 << "is out of range 0 to " << numDTCsPerRegion_ * numRegions_ - 1 << ".";
0710       throw exception;
0711     }
0712   }
0713 
0714   // range check of tklayout id
0715   void Setup::checkTKLayoutId(int tkLayoutId) const {
0716     if (tkLayoutId <= 0 || tkLayoutId > numDTCsPerRegion_ * numRegions_) {
0717       cms::Exception exception("out_of_range");
0718       exception.addContext("tt::Setup::checkTKLayoutId");
0719       exception << "Used TKLayout Id (" << tkLayoutId << ") "
0720                 << "is out of range 1 to " << numDTCsPerRegion_ * numRegions_ << ".";
0721       throw exception;
0722     }
0723   }
0724 
0725   // range check of tfp identifier
0726   void Setup::checkTFPIdentifier(int tfpRegion, int tfpChannel) const {
0727     const bool oorRegion = tfpRegion >= numRegions_ || tfpRegion < 0;
0728     const bool oorChannel = tfpChannel >= numDTCsPerTFP_ || tfpChannel < 0;
0729     if (oorRegion || oorChannel) {
0730       cms::Exception exception("out_of_range");
0731       exception.addContext("tt::Setup::checkTFPIdentifier");
0732       if (oorRegion)
0733         exception << "Requested Processing Region "
0734                   << "(" << tfpRegion << ") "
0735                   << "is out of range 0 to " << numRegions_ - 1 << ".";
0736       if (oorChannel)
0737         exception << "Requested TFP Channel "
0738                   << "(" << tfpChannel << ") "
0739                   << "is out of range 0 to " << numDTCsPerTFP_ - 1 << ".";
0740       throw exception;
0741     }
0742   }
0743 }  // namespace tt