Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:14:05

0001 #include "L1Trigger/TrackTrigger/interface/Setup.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0004 #include "DataFormats/L1TrackTrigger/interface/TTBV.h"
0005 #include "DataFormats/L1TrackTrigger/interface/TTTypes.h"
0006 
0007 #include <cmath>
0008 #include <algorithm>
0009 #include <vector>
0010 #include <set>
0011 #include <unordered_map>
0012 #include <string>
0013 #include <sstream>
0014 
0015 using namespace std;
0016 using namespace edm;
0017 
0018 namespace tt {
0019 
0020   Setup::Setup(const ParameterSet& iConfig,
0021                const MagneticField& magneticField,
0022                const TrackerGeometry& trackerGeometry,
0023                const TrackerTopology& trackerTopology,
0024                const TrackerDetToDTCELinkCablingMap& cablingMap,
0025                const StubAlgorithmOfficial& stubAlgorithm,
0026                const ParameterSet& pSetStubAlgorithm,
0027                const ParameterSet& pSetGeometryConfiguration,
0028                const ParameterSetID& pSetIdTTStubAlgorithm,
0029                const ParameterSetID& pSetIdGeometryConfiguration)
0030       : magneticField_(&magneticField),
0031         trackerGeometry_(&trackerGeometry),
0032         trackerTopology_(&trackerTopology),
0033         cablingMap_(&cablingMap),
0034         stubAlgorithm_(&stubAlgorithm),
0035         pSetSA_(&pSetStubAlgorithm),
0036         pSetGC_(&pSetGeometryConfiguration),
0037         pSetIdTTStubAlgorithm_(pSetIdTTStubAlgorithm),
0038         pSetIdGeometryConfiguration_(pSetIdGeometryConfiguration),
0039         // DD4hep
0040         fromDD4hep_(iConfig.getParameter<bool>("fromDD4hep")),
0041         // Parameter to check if configured Tracker Geometry is supported
0042         pSetSG_(iConfig.getParameter<ParameterSet>("UnSupportedGeometry")),
0043         sgXMLLabel_(pSetSG_.getParameter<string>("XMLLabel")),
0044         sgXMLPath_(pSetSG_.getParameter<string>("XMLPath")),
0045         sgXMLFile_(pSetSG_.getParameter<string>("XMLFile")),
0046         sgXMLVersions_(pSetSG_.getParameter<vector<string>>("XMLVersions")),
0047         // Parameter to check if Process History is consistent with process configuration
0048         pSetPH_(iConfig.getParameter<ParameterSet>("ProcessHistory")),
0049         phGeometryConfiguration_(pSetPH_.getParameter<string>("GeometryConfiguration")),
0050         phTTStubAlgorithm_(pSetPH_.getParameter<string>("TTStubAlgorithm")),
0051         // Common track finding parameter
0052         pSetTF_(iConfig.getParameter<ParameterSet>("TrackFinding")),
0053         beamWindowZ_(pSetTF_.getParameter<double>("BeamWindowZ")),
0054         matchedLayers_(pSetTF_.getParameter<int>("MatchedLayers")),
0055         matchedLayersPS_(pSetTF_.getParameter<int>("MatchedLayersPS")),
0056         unMatchedStubs_(pSetTF_.getParameter<int>("UnMatchedStubs")),
0057         unMatchedStubsPS_(pSetTF_.getParameter<int>("UnMatchedStubsPS")),
0058         scattering_(pSetTF_.getParameter<double>("Scattering")),
0059         // TMTT specific parameter
0060         pSetTMTT_(iConfig.getParameter<ParameterSet>("TMTT")),
0061         minPt_(pSetTMTT_.getParameter<double>("MinPt")),
0062         maxEta_(pSetTMTT_.getParameter<double>("MaxEta")),
0063         chosenRofPhi_(pSetTMTT_.getParameter<double>("ChosenRofPhi")),
0064         numLayers_(pSetTMTT_.getParameter<int>("NumLayers")),
0065         tmttWidthR_(pSetTMTT_.getParameter<int>("WidthR")),
0066         tmttWidthPhi_(pSetTMTT_.getParameter<int>("WidthPhi")),
0067         tmttWidthZ_(pSetTMTT_.getParameter<int>("WidthZ")),
0068         // Hybrid specific parameter
0069         pSetHybrid_(iConfig.getParameter<ParameterSet>("Hybrid")),
0070         hybridMinPtStub_(pSetHybrid_.getParameter<double>("MinPtStub")),
0071         hybridMinPtCand_(pSetHybrid_.getParameter<double>("MinPtCand")),
0072         hybridMaxEta_(pSetHybrid_.getParameter<double>("MaxEta")),
0073         hybridChosenRofPhi_(pSetHybrid_.getParameter<double>("ChosenRofPhi")),
0074         hybridNumLayers_(pSetHybrid_.getParameter<int>("NumLayers")),
0075         hybridNumRingsPS_(pSetHybrid_.getParameter<vector<int>>("NumRingsPS")),
0076         hybridWidthsR_(pSetHybrid_.getParameter<vector<int>>("WidthsR")),
0077         hybridWidthsZ_(pSetHybrid_.getParameter<vector<int>>("WidthsZ")),
0078         hybridWidthsPhi_(pSetHybrid_.getParameter<vector<int>>("WidthsPhi")),
0079         hybridWidthsAlpha_(pSetHybrid_.getParameter<vector<int>>("WidthsAlpha")),
0080         hybridWidthsBend_(pSetHybrid_.getParameter<vector<int>>("WidthsBend")),
0081         hybridRangesR_(pSetHybrid_.getParameter<vector<double>>("RangesR")),
0082         hybridRangesZ_(pSetHybrid_.getParameter<vector<double>>("RangesZ")),
0083         hybridRangesAlpha_(pSetHybrid_.getParameter<vector<double>>("RangesAlpha")),
0084         hybridLayerRs_(pSetHybrid_.getParameter<vector<double>>("LayerRs")),
0085         hybridDiskZs_(pSetHybrid_.getParameter<vector<double>>("DiskZs")),
0086         hybridDisk2SRsSet_(pSetHybrid_.getParameter<vector<ParameterSet>>("Disk2SRsSet")),
0087         tbInnerRadius_(pSetHybrid_.getParameter<double>("InnerRadius")),
0088         // Parameter specifying TrackingParticle used for Efficiency measurements
0089         pSetTP_(iConfig.getParameter<ParameterSet>("TrackingParticle")),
0090         tpMinPt_(pSetTP_.getParameter<double>("MinPt")),
0091         tpMaxEta_(pSetTP_.getParameter<double>("MaxEta")),
0092         tpMaxVertR_(pSetTP_.getParameter<double>("MaxVertR")),
0093         tpMaxVertZ_(pSetTP_.getParameter<double>("MaxVertZ")),
0094         tpMaxD0_(pSetTP_.getParameter<double>("MaxD0")),
0095         tpMinLayers_(pSetTP_.getParameter<int>("MinLayers")),
0096         tpMinLayersPS_(pSetTP_.getParameter<int>("MinLayersPS")),
0097         tpMaxBadStubs2S_(pSetTP_.getParameter<int>("MaxBadStubs2S")),
0098         tpMaxBadStubsPS_(pSetTP_.getParameter<int>("MaxBadStubsPS")),
0099         // Fimrware specific Parameter
0100         pSetFW_(iConfig.getParameter<ParameterSet>("Firmware")),
0101         widthDSPa_(pSetFW_.getParameter<int>("WidthDSPa")),
0102         widthDSPb_(pSetFW_.getParameter<int>("WidthDSPb")),
0103         widthDSPc_(pSetFW_.getParameter<int>("WidthDSPc")),
0104         widthAddrBRAM36_(pSetFW_.getParameter<int>("WidthAddrBRAM36")),
0105         widthAddrBRAM18_(pSetFW_.getParameter<int>("WidthAddrBRAM18")),
0106         numFramesInfra_(pSetFW_.getParameter<int>("NumFramesInfra")),
0107         freqLHC_(pSetFW_.getParameter<double>("FreqLHC")),
0108         freqBE_(pSetFW_.getParameter<double>("FreqBE")),
0109         tmpFE_(pSetFW_.getParameter<int>("TMP_FE")),
0110         tmpTFP_(pSetFW_.getParameter<int>("TMP_TFP")),
0111         speedOfLight_(pSetFW_.getParameter<double>("SpeedOfLight")),
0112         bField_(pSetFW_.getParameter<double>("BField")),
0113         bFieldError_(pSetFW_.getParameter<double>("BFieldError")),
0114         outerRadius_(pSetFW_.getParameter<double>("OuterRadius")),
0115         innerRadius_(pSetFW_.getParameter<double>("InnerRadius")),
0116         halfLength_(pSetFW_.getParameter<double>("HalfLength")),
0117         tiltApproxSlope_(pSetFW_.getParameter<double>("TiltApproxSlope")),
0118         tiltApproxIntercept_(pSetFW_.getParameter<double>("TiltApproxIntercept")),
0119         tiltUncertaintyR_(pSetFW_.getParameter<double>("TiltUncertaintyR")),
0120         mindPhi_(pSetFW_.getParameter<double>("MindPhi")),
0121         maxdPhi_(pSetFW_.getParameter<double>("MaxdPhi")),
0122         mindZ_(pSetFW_.getParameter<double>("MindZ")),
0123         maxdZ_(pSetFW_.getParameter<double>("MaxdZ")),
0124         pitch2S_(pSetFW_.getParameter<double>("Pitch2S")),
0125         pitchPS_(pSetFW_.getParameter<double>("PitchPS")),
0126         length2S_(pSetFW_.getParameter<double>("Length2S")),
0127         lengthPS_(pSetFW_.getParameter<double>("LengthPS")),
0128         tiltedLayerLimitsZ_(pSetFW_.getParameter<vector<double>>("TiltedLayerLimitsZ")),
0129         psDiskLimitsR_(pSetFW_.getParameter<vector<double>>("PSDiskLimitsR")),
0130         // Parmeter specifying front-end
0131         pSetFE_(iConfig.getParameter<ParameterSet>("FrontEnd")),
0132         widthBend_(pSetFE_.getParameter<int>("WidthBend")),
0133         widthCol_(pSetFE_.getParameter<int>("WidthCol")),
0134         widthRow_(pSetFE_.getParameter<int>("WidthRow")),
0135         baseBend_(pSetFE_.getParameter<double>("BaseBend")),
0136         baseCol_(pSetFE_.getParameter<double>("BaseCol")),
0137         baseRow_(pSetFE_.getParameter<double>("BaseRow")),
0138         baseWindowSize_(pSetFE_.getParameter<double>("BaseWindowSize")),
0139         bendCut_(pSetFE_.getParameter<double>("BendCut")),
0140         // Parmeter specifying DTC
0141         pSetDTC_(iConfig.getParameter<ParameterSet>("DTC")),
0142         numRegions_(pSetDTC_.getParameter<int>("NumRegions")),
0143         numOverlappingRegions_(pSetDTC_.getParameter<int>("NumOverlappingRegions")),
0144         numATCASlots_(pSetDTC_.getParameter<int>("NumATCASlots")),
0145         numDTCsPerRegion_(pSetDTC_.getParameter<int>("NumDTCsPerRegion")),
0146         numModulesPerDTC_(pSetDTC_.getParameter<int>("NumModulesPerDTC")),
0147         dtcNumRoutingBlocks_(pSetDTC_.getParameter<int>("NumRoutingBlocks")),
0148         dtcDepthMemory_(pSetDTC_.getParameter<int>("DepthMemory")),
0149         dtcWidthRowLUT_(pSetDTC_.getParameter<int>("WidthRowLUT")),
0150         dtcWidthInv2R_(pSetDTC_.getParameter<int>("WidthInv2R")),
0151         offsetDetIdDSV_(pSetDTC_.getParameter<int>("OffsetDetIdDSV")),
0152         offsetDetIdTP_(pSetDTC_.getParameter<int>("OffsetDetIdTP")),
0153         offsetLayerDisks_(pSetDTC_.getParameter<int>("OffsetLayerDisks")),
0154         offsetLayerId_(pSetDTC_.getParameter<int>("OffsetLayerId")),
0155         numBarrelLayer_(pSetDTC_.getParameter<int>("NumBarrelLayer")),
0156         slotLimitPS_(pSetDTC_.getParameter<int>("SlotLimitPS")),
0157         slotLimit10gbps_(pSetDTC_.getParameter<int>("SlotLimit10gbps")),
0158         // Parmeter specifying TFP
0159         pSetTFP_(iConfig.getParameter<ParameterSet>("TFP")),
0160         tfpWidthPhi0_(pSetTFP_.getParameter<int>("WidthPhi0")),
0161         tfpWidthInv2R_(pSetTFP_.getParameter<int>("WidthInv2R")),
0162         tfpWidthCot_(pSetTFP_.getParameter<int>("WidthCot")),
0163         tfpWidthZ0_(pSetTFP_.getParameter<int>("WidthZ0")),
0164         tfpNumChannel_(pSetTFP_.getParameter<int>("NumChannel")),
0165         // Parmeter specifying GeometricProcessor
0166         pSetGP_(iConfig.getParameter<ParameterSet>("GeometricProcessor")),
0167         numSectorsPhi_(pSetGP_.getParameter<int>("NumSectorsPhi")),
0168         chosenRofZ_(pSetGP_.getParameter<double>("ChosenRofZ")),
0169         neededRangeChiZ_(pSetGP_.getParameter<double>("RangeChiZ")),
0170         gpDepthMemory_(pSetGP_.getParameter<int>("DepthMemory")),
0171         boundariesEta_(pSetGP_.getParameter<vector<double>>("BoundariesEta")),
0172         // Parmeter specifying HoughTransform
0173         pSetHT_(iConfig.getParameter<ParameterSet>("HoughTransform")),
0174         htNumBinsInv2R_(pSetHT_.getParameter<int>("NumBinsInv2R")),
0175         htNumBinsPhiT_(pSetHT_.getParameter<int>("NumBinsPhiT")),
0176         htMinLayers_(pSetHT_.getParameter<int>("MinLayers")),
0177         htDepthMemory_(pSetHT_.getParameter<int>("DepthMemory")),
0178         // Parmeter specifying MiniHoughTransform
0179         pSetMHT_(iConfig.getParameter<ParameterSet>("MiniHoughTransform")),
0180         mhtNumBinsInv2R_(pSetMHT_.getParameter<int>("NumBinsInv2R")),
0181         mhtNumBinsPhiT_(pSetMHT_.getParameter<int>("NumBinsPhiT")),
0182         mhtNumDLBs_(pSetMHT_.getParameter<int>("NumDLBs")),
0183         mhtNumDLBNodes_(pSetMHT_.getParameter<int>("NumDLBNodes")),
0184         mhtNumDLBChannel_(pSetMHT_.getParameter<int>("NumDLBChannel")),
0185         mhtMinLayers_(pSetMHT_.getParameter<int>("MinLayers")),
0186         // Parmeter specifying ZHoughTransform
0187         pSetZHT_(iConfig.getParameter<ParameterSet>("ZHoughTransform")),
0188         zhtNumBinsZT_(pSetZHT_.getParameter<int>("NumBinsZT")),
0189         zhtNumBinsCot_(pSetZHT_.getParameter<int>("NumBinsCot")),
0190         zhtNumStages_(pSetZHT_.getParameter<int>("NumStages")),
0191         zhtMinLayers_(pSetZHT_.getParameter<int>("MinLayers")),
0192         zhtMaxTracks_(pSetZHT_.getParameter<int>("MaxTracks")),
0193         zhtMaxStubsPerLayer_(pSetZHT_.getParameter<int>("MaxStubsPerLayer")),
0194         // Parameter specifying KalmanFilter Input Formatter
0195         pSetKFin_(iConfig.getParameter<ParameterSet>("KalmanFilterIn")),
0196         kfinShiftRangePhi_(pSetKFin_.getParameter<int>("ShiftRangePhi")),
0197         kfinShiftRangeZ_(pSetKFin_.getParameter<int>("ShiftRangeZ")),
0198         // Parmeter specifying KalmanFilter
0199         pSetKF_(iConfig.getParameter<ParameterSet>("KalmanFilter")),
0200         kfNumWorker_(pSetKF_.getParameter<int>("NumWorker")),
0201         kfMinLayers_(pSetKF_.getParameter<int>("MinLayers")),
0202         kfMaxLayers_(pSetKF_.getParameter<int>("MaxLayers")),
0203         kfRangeFactor_(pSetKF_.getParameter<double>("RangeFactor")),
0204         // Parmeter specifying KalmanFilter Output Formatter
0205         pSetKFOut_(iConfig.getParameter<ParameterSet>("KalmanFilterOut")),
0206         kfoutchi2rphiBins_(pSetKFOut_.getParameter<vector<double>>("chi2rphiBins")),
0207         kfoutchi2rzBins_(pSetKFOut_.getParameter<vector<double>>("chi2rzBins")),
0208         kfoutchi2rphiConv_(pSetKFOut_.getParameter<int>("chi2rphiConv")),
0209         kfoutchi2rzConv_(pSetKFOut_.getParameter<int>("chi2rzConv")),
0210         tttrackBits_(pSetKFOut_.getParameter<int>("TTTrackBits")),
0211         weightBinFraction_(pSetKFOut_.getParameter<int>("WeightBinFraction")),
0212         // Parmeter specifying DuplicateRemoval
0213         pSetDR_(iConfig.getParameter<ParameterSet>("DuplicateRemoval")),
0214         drDepthMemory_(pSetDR_.getParameter<int>("DepthMemory")) {
0215     configurationSupported_ = true;
0216     // check if bField is supported
0217     checkMagneticField();
0218     // check if geometry is supported
0219     checkGeometry();
0220     if (!configurationSupported_)
0221       return;
0222     // derive constants
0223     calculateConstants();
0224     // convert configuration of TTStubAlgorithm
0225     consumeStubAlgorithm();
0226     // create all possible encodingsBend
0227     encodingsBendPS_.reserve(maxWindowSize_ + 1);
0228     encodingsBend2S_.reserve(maxWindowSize_ + 1);
0229     encodeBend(encodingsBendPS_, true);
0230     encodeBend(encodingsBend2S_, false);
0231     // create sensor modules
0232     produceSensorModules();
0233     // configure TPSelector
0234     configureTPSelector();
0235   }
0236 
0237   // checks current configuration vs input sample configuration
0238   void Setup::checkHistory(const ProcessHistory& processHistory) const {
0239     const pset::Registry* psetRegistry = pset::Registry::instance();
0240     // check used TTStubAlgorithm in input producer
0241     checkHistory(processHistory, psetRegistry, phTTStubAlgorithm_, pSetIdTTStubAlgorithm_);
0242     // check used GeometryConfiguration in input producer
0243     checkHistory(processHistory, psetRegistry, phGeometryConfiguration_, pSetIdGeometryConfiguration_);
0244   }
0245 
0246   // checks consitency between history and current configuration for a specific module
0247   void Setup::checkHistory(const ProcessHistory& ph,
0248                            const pset::Registry* pr,
0249                            const string& label,
0250                            const ParameterSetID& pSetId) const {
0251     vector<pair<string, ParameterSet>> pSets;
0252     pSets.reserve(ph.size());
0253     for (const ProcessConfiguration& pc : ph) {
0254       const ParameterSet* pSet = pr->getMapped(pc.parameterSetID());
0255       if (pSet && pSet->exists(label))
0256         pSets.emplace_back(pc.processName(), pSet->getParameterSet(label));
0257     }
0258     if (pSets.empty()) {
0259       cms::Exception exception("BadConfiguration");
0260       exception << label << " not found in process history.";
0261       exception.addContext("tt::Setup::checkHistory");
0262       throw exception;
0263     }
0264     auto consistent = [&pSetId](const pair<string, ParameterSet>& p) { return p.second.id() == pSetId; };
0265     if (!all_of(pSets.begin(), pSets.end(), consistent)) {
0266       const ParameterSet& pSetProcess = getParameterSet(pSetId);
0267       cms::Exception exception("BadConfiguration");
0268       exception.addContext("tt::Setup::checkHistory");
0269       exception << label << " inconsistent with History." << endl;
0270       exception << "Current Configuration:" << endl << pSetProcess.dump() << endl;
0271       for (const pair<string, ParameterSet>& p : pSets)
0272         if (!consistent(p))
0273           exception << "Process " << p.first << " Configuration:" << endl << dumpDiff(p.second, pSetProcess) << endl;
0274       throw exception;
0275     }
0276   }
0277 
0278   // dumps pSetHistory where incosistent lines with pSetProcess are highlighted
0279   string Setup::dumpDiff(const ParameterSet& pSetHistory, const ParameterSet& pSetProcess) const {
0280     stringstream ssHistory, ssProcess, ss;
0281     ssHistory << pSetHistory.dump();
0282     ssProcess << pSetProcess.dump();
0283     string lineHistory, lineProcess;
0284     for (; getline(ssHistory, lineHistory) && getline(ssProcess, lineProcess);)
0285       ss << (lineHistory != lineProcess ? "\033[1;31m" : "") << lineHistory << "\033[0m" << endl;
0286     return ss.str();
0287   }
0288 
0289   // converts tk layout id into dtc id
0290   int Setup::dtcId(int tkLayoutId) const {
0291     checkTKLayoutId(tkLayoutId);
0292     const int tkId = tkLayoutId - 1;
0293     const int side = tkId / (numRegions_ * numATCASlots_);
0294     const int region = (tkId % (numRegions_ * numATCASlots_)) / numATCASlots_;
0295     const int slot = tkId % numATCASlots_;
0296     return region * numDTCsPerRegion_ + side * numATCASlots_ + slot;
0297   }
0298 
0299   // converts dtc id into tk layout id
0300   int Setup::tkLayoutId(int dtcId) const {
0301     checkDTCId(dtcId);
0302     const int slot = dtcId % numATCASlots_;
0303     const int region = dtcId / numDTCsPerRegion_;
0304     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0305     return (side * numRegions_ + region) * numATCASlots_ + slot + 1;
0306   }
0307 
0308   // converts TFP identifier (region[0-8], channel[0-47]) into dtc id
0309   int Setup::dtcId(int tfpRegion, int tfpChannel) const {
0310     checkTFPIdentifier(tfpRegion, tfpChannel);
0311     const int dtcChannel = numOverlappingRegions_ - (tfpChannel / numDTCsPerRegion_) - 1;
0312     const int dtcBoard = tfpChannel % numDTCsPerRegion_;
0313     const int dtcRegion = tfpRegion - dtcChannel >= 0 ? tfpRegion - dtcChannel : tfpRegion - dtcChannel + numRegions_;
0314     return dtcRegion * numDTCsPerRegion_ + dtcBoard;
0315   }
0316 
0317   // checks if given DTC id is connected to PS or 2S sensormodules
0318   bool Setup::psModule(int dtcId) const {
0319     checkDTCId(dtcId);
0320     // from tklayout: first 3 are 10 gbps PS, next 3 are 5 gbps PS and residual 6 are 5 gbps 2S modules
0321     return slot(dtcId) < slotLimitPS_;
0322   }
0323 
0324   // return sensor moduel type
0325   SensorModule::Type Setup::type(const TTStubRef& ttStubRef) const {
0326     const bool barrel = this->barrel(ttStubRef);
0327     const bool psModule = this->psModule(ttStubRef);
0328     SensorModule::Type type;
0329     if (barrel && psModule)
0330       type = SensorModule::BarrelPS;
0331     if (barrel && !psModule)
0332       type = SensorModule::Barrel2S;
0333     if (!barrel && psModule)
0334       type = SensorModule::DiskPS;
0335     if (!barrel && !psModule)
0336       type = SensorModule::Disk2S;
0337     return type;
0338   }
0339 
0340   // checks if given dtcId is connected via 10 gbps link
0341   bool Setup::gbps10(int dtcId) const {
0342     checkDTCId(dtcId);
0343     return slot(dtcId) < slotLimit10gbps_;
0344   }
0345 
0346   // checks if given dtcId is connected to -z (false) or +z (true)
0347   bool Setup::side(int dtcId) const {
0348     checkDTCId(dtcId);
0349     const int side = (dtcId % numDTCsPerRegion_) / numATCASlots_;
0350     // from tkLayout: first 12 +z, next 12 -z
0351     return side == 0;
0352   }
0353 
0354   // ATCA slot number [0-11] of given dtcId
0355   int Setup::slot(int dtcId) const {
0356     checkDTCId(dtcId);
0357     return dtcId % numATCASlots_;
0358   }
0359 
0360   // sensor module for det id
0361   SensorModule* Setup::sensorModule(const DetId& detId) const {
0362     const auto it = detIdToSensorModule_.find(detId);
0363     if (it == detIdToSensorModule_.end()) {
0364       cms::Exception exception("NullPtr");
0365       exception << "Unknown DetId used.";
0366       exception.addContext("tt::Setup::sensorModule");
0367       throw exception;
0368     }
0369     return it->second;
0370   }
0371 
0372   // index = encoded bend, value = decoded bend for given window size and module type
0373   const vector<double>& Setup::encodingBend(int windowSize, bool psModule) const {
0374     const vector<vector<double>>& encodingsBend = psModule ? encodingsBendPS_ : encodingsBend2S_;
0375     return encodingsBend.at(windowSize);
0376   }
0377 
0378   // check if bField is supported
0379   void Setup::checkMagneticField() {
0380     const double bFieldES = magneticField_->inTesla(GlobalPoint(0., 0., 0.)).z();
0381     if (abs(bField_ - bFieldES) > bFieldError_) {
0382       configurationSupported_ = false;
0383       LogWarning("ConfigurationNotSupported")
0384           << "Magnetic Field from EventSetup (" << bFieldES << ") differs more then " << bFieldError_
0385           << " from supported value (" << bField_ << "). ";
0386     }
0387   }
0388 
0389   // check if geometry is supported
0390   void Setup::checkGeometry() {
0391     //FIX ME: Can we assume that geometry used in dd4hep wf supports L1Track?
0392     if (!fromDD4hep_) {
0393       const vector<string>& geomXMLFiles = pSetGC_->getParameter<vector<string>>(sgXMLLabel_);
0394       string version;
0395       for (const string& geomXMLFile : geomXMLFiles) {
0396         const auto begin = geomXMLFile.find(sgXMLPath_) + sgXMLPath_.size();
0397         const auto end = geomXMLFile.find(sgXMLFile_);
0398         if (begin != string::npos && end != string::npos)
0399           version = geomXMLFile.substr(begin, end - begin - 1);
0400       }
0401       if (version.empty()) {
0402         cms::Exception exception("LogicError");
0403         exception << "No " << sgXMLPath_ << "*/" << sgXMLFile_ << " found in GeometryConfiguration";
0404         exception.addContext("tt::Setup::checkGeometry");
0405         throw exception;
0406       }
0407       if (find(sgXMLVersions_.begin(), sgXMLVersions_.end(), version) != sgXMLVersions_.end()) {
0408         configurationSupported_ = false;
0409         LogWarning("ConfigurationNotSupported")
0410             << "Geometry Configuration " << sgXMLPath_ << version << "/" << sgXMLFile_ << " is not supported. ";
0411       }
0412     }
0413   }
0414 
0415   // convert configuration of TTStubAlgorithm
0416   void Setup::consumeStubAlgorithm() {
0417     numTiltedLayerRings_ = pSetSA_->getParameter<vector<double>>("NTiltedRings");
0418     windowSizeBarrelLayers_ = pSetSA_->getParameter<vector<double>>("BarrelCut");
0419     const auto& pSetsTiltedLayer = pSetSA_->getParameter<vector<ParameterSet>>("TiltedBarrelCutSet");
0420     const auto& pSetsEncapDisks = pSetSA_->getParameter<vector<ParameterSet>>("EndcapCutSet");
0421     windowSizeTiltedLayerRings_.reserve(pSetsTiltedLayer.size());
0422     for (const auto& pSet : pSetsTiltedLayer)
0423       windowSizeTiltedLayerRings_.emplace_back(pSet.getParameter<vector<double>>("TiltedCut"));
0424     windowSizeEndcapDisksRings_.reserve(pSetsEncapDisks.size());
0425     for (const auto& pSet : pSetsEncapDisks)
0426       windowSizeEndcapDisksRings_.emplace_back(pSet.getParameter<vector<double>>("EndcapCut"));
0427     maxWindowSize_ = -1;
0428     for (const auto& windowss : {windowSizeTiltedLayerRings_, windowSizeEndcapDisksRings_, {windowSizeBarrelLayers_}})
0429       for (const auto& windows : windowss)
0430         for (const auto& window : windows)
0431           maxWindowSize_ = max(maxWindowSize_, (int)(window / baseWindowSize_));
0432   }
0433 
0434   // create bend encodings
0435   void Setup::encodeBend(vector<vector<double>>& encodings, bool ps) const {
0436     for (int window = 0; window < maxWindowSize_ + 1; window++) {
0437       set<double> encoding;
0438       for (int bend = 0; bend < window + 1; bend++)
0439         encoding.insert(stubAlgorithm_->degradeBend(ps, window, bend));
0440       encodings.emplace_back(encoding.begin(), encoding.end());
0441     }
0442   }
0443 
0444   // create sensor modules
0445   void Setup::produceSensorModules() {
0446     sensorModules_.reserve(numModules_);
0447     dtcModules_ = vector<vector<SensorModule*>>(numDTCs_);
0448     for (vector<SensorModule*>& dtcModules : dtcModules_)
0449       dtcModules.reserve(numModulesPerDTC_);
0450     enum SubDetId { pixelBarrel = 1, pixelDisks = 2 };
0451     // loop over all tracker modules
0452     for (const DetId& detId : trackerGeometry_->detIds()) {
0453       // skip pixel detector
0454       if (detId.subdetId() == pixelBarrel || detId.subdetId() == pixelDisks)
0455         continue;
0456       // skip multiple detIds per module
0457       if (!trackerTopology_->isLower(detId))
0458         continue;
0459       // lowerDetId - 1 = tk layout det id
0460       const DetId detIdTkLayout = detId + offsetDetIdTP_;
0461       // tk layout dtc id, lowerDetId - 1 = tk lyout det id
0462       const int tklId = cablingMap_->detIdToDTCELinkId(detIdTkLayout).first->second.dtc_id();
0463       // track trigger dtc id [0-215]
0464       const int dtcId = Setup::dtcId(tklId);
0465       // collection of so far connected modules to this dtc
0466       vector<SensorModule*>& dtcModules = dtcModules_[dtcId];
0467       // construct sendor module
0468       sensorModules_.emplace_back(this, detId, dtcId, dtcModules.size());
0469       SensorModule* sensorModule = &sensorModules_.back();
0470       // store connection between detId and sensor module
0471       detIdToSensorModule_.emplace(detId, sensorModule);
0472       // store connection between dtcId and sensor module
0473       dtcModules.push_back(sensorModule);
0474     }
0475     for (vector<SensorModule*>& dtcModules : dtcModules_) {
0476       dtcModules.shrink_to_fit();
0477       // check configuration
0478       if ((int)dtcModules.size() > numModulesPerDTC_) {
0479         cms::Exception exception("overflow");
0480         exception << "Cabling map connects more than " << numModulesPerDTC_ << " modules to a DTC.";
0481         exception.addContext("tt::Setup::Setup");
0482         throw exception;
0483       }
0484     }
0485   }
0486 
0487   // configure TPSelector
0488   void Setup::configureTPSelector() {
0489     // configure TrackingParticleSelector
0490     const double ptMin = tpMinPt_;
0491     constexpr double ptMax = 9.e9;
0492     const double etaMax = tpMaxEta_;
0493     const double tip = tpMaxVertR_;
0494     const double lip = tpMaxVertZ_;
0495     constexpr int minHit = 0;
0496     constexpr bool signalOnly = true;
0497     constexpr bool intimeOnly = true;
0498     constexpr bool chargedOnly = true;
0499     constexpr bool stableOnly = false;
0500     tpSelector_ = TrackingParticleSelector(
0501         ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, signalOnly, intimeOnly, chargedOnly, stableOnly);
0502     tpSelectorLoose_ =
0503         TrackingParticleSelector(ptMin, ptMax, -etaMax, etaMax, tip, lip, minHit, false, false, false, stableOnly);
0504   }
0505 
0506   // stub layer id (barrel: 1 - 6, endcap: 11 - 15)
0507   int Setup::layerId(const TTStubRef& ttStubRef) const {
0508     const DetId& detId = ttStubRef->getDetId();
0509     return detId.subdetId() == StripSubdetector::TOB ? trackerTopology_->layer(detId)
0510                                                      : trackerTopology_->tidWheel(detId) + offsetLayerDisks_;
0511   }
0512 
0513   // return tracklet layerId (barrel: [0-5], endcap: [6-10]) for given TTStubRef
0514   int Setup::trackletLayerId(const TTStubRef& ttStubRef) const {
0515     return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : numBarrelLayer_ - offsetLayerId_);
0516   }
0517 
0518   // return index layerId (barrel: [0-5], endcap: [0-6]) for given TTStubRef
0519   int Setup::indexLayerId(const TTStubRef& ttStubRef) const {
0520     return this->layerId(ttStubRef) - (this->barrel(ttStubRef) ? offsetLayerId_ : offsetLayerId_ + offsetLayerDisks_);
0521   }
0522 
0523   // true if stub from barrel module
0524   bool Setup::barrel(const TTStubRef& ttStubRef) const {
0525     const DetId& detId = ttStubRef->getDetId();
0526     return detId.subdetId() == StripSubdetector::TOB;
0527   }
0528 
0529   // true if stub from barrel module
0530   bool Setup::psModule(const TTStubRef& ttStubRef) const {
0531     const DetId& detId = ttStubRef->getDetId();
0532     return trackerGeometry_->getDetectorType(detId) == TrackerGeometry::ModuleType::Ph2PSP;
0533   }
0534 
0535   //
0536   TTBV Setup::layerMap(const vector<int>& ints) const {
0537     TTBV ttBV;
0538     for (int layer = numLayers_ - 1; layer >= 0; layer--) {
0539       const int i = ints[layer];
0540       ttBV += TTBV(i, kfWidthLayerCount_);
0541     }
0542     return ttBV;
0543   }
0544 
0545   //
0546   TTBV Setup::layerMap(const TTBV& hitPattern, const vector<int>& ints) const {
0547     TTBV ttBV;
0548     for (int layer = numLayers_ - 1; layer >= 0; layer--) {
0549       const int i = ints[layer];
0550       ttBV += TTBV((hitPattern[layer] ? i - 1 : 0), kfWidthLayerCount_);
0551     }
0552     return ttBV;
0553   }
0554 
0555   //
0556   vector<int> Setup::layerMap(const TTBV& hitPattern, const TTBV& ttBV) const {
0557     TTBV bv(ttBV);
0558     vector<int> ints(numLayers_, 0);
0559     for (int layer = 0; layer < numLayers_; layer++) {
0560       const int i = bv.extract(kfWidthLayerCount_);
0561       ints[layer] = i + (hitPattern[layer] ? 1 : 0);
0562     }
0563     return ints;
0564   }
0565 
0566   //
0567   vector<int> Setup::layerMap(const TTBV& ttBV) const {
0568     TTBV bv(ttBV);
0569     vector<int> ints(numLayers_, 0);
0570     for (int layer = 0; layer < numLayers_; layer++)
0571       ints[layer] = bv.extract(kfWidthLayerCount_);
0572     return ints;
0573   }
0574 
0575   // stub projected phi uncertainty
0576   double Setup::dPhi(const TTStubRef& ttStubRef, double inv2R) const {
0577     const DetId& detId = ttStubRef->getDetId();
0578     SensorModule* sm = sensorModule(detId + 1);
0579     const double r = stubPos(ttStubRef).perp();
0580     const double sigma = sm->pitchRow() / r;
0581     const double scat = scattering_ * abs(inv2R);
0582     const double extra = sm->barrel() ? 0. : sm->pitchCol() * abs(inv2R);
0583     const double digi = tmttBasePhi_;
0584     const double dPhi = sigma + scat + extra + digi;
0585     if (dPhi >= maxdPhi_ || dPhi < mindPhi_) {
0586       cms::Exception exception("out_of_range");
0587       exception.addContext("tt::Setup::dPhi");
0588       exception << "Stub phi uncertainty " << dPhi << " "
0589                 << "is out of range " << mindPhi_ << " to " << maxdPhi_ << ".";
0590       throw exception;
0591     }
0592     return dPhi;
0593   }
0594 
0595   // stub projected z uncertainty
0596   double Setup::dZ(const TTStubRef& ttStubRef, double cot) const {
0597     const DetId& detId = ttStubRef->getDetId();
0598     SensorModule* sm = sensorModule(detId + 1);
0599     const double sigma = sm->pitchCol() * sm->tiltCorrection(cot);
0600     const double digi = tmttBaseZ_;
0601     const double dZ = sigma + digi;
0602     if (dZ >= maxdZ_ || dZ < mindZ_) {
0603       cms::Exception exception("out_of_range");
0604       exception.addContext("tt::Setup::dZ");
0605       exception << "Stub z uncertainty " << dZ << " "
0606                 << "is out of range " << mindZ_ << " to " << maxdZ_ << ".";
0607       throw exception;
0608     }
0609     return dZ;
0610   }
0611 
0612   // stub projected chi2phi wheight
0613   double Setup::v0(const TTStubRef& ttStubRef, double inv2R) const {
0614     const DetId& detId = ttStubRef->getDetId();
0615     SensorModule* sm = sensorModule(detId + 1);
0616     const double r = stubPos(ttStubRef).perp();
0617     const double sigma = pow(sm->pitchRow() / r, 2) / 12.;
0618     const double scat = pow(scattering_ * inv2R, 2);
0619     const double extra = sm->barrel() ? 0. : pow(sm->pitchCol() * inv2R, 2);
0620     const double digi = pow(tmttBasePhi_ / 12., 2);
0621     return sigma + scat + extra + digi;
0622   }
0623 
0624   // stub projected chi2z wheight
0625   double Setup::v1(const TTStubRef& ttStubRef, double cot) const {
0626     const DetId& detId = ttStubRef->getDetId();
0627     SensorModule* sm = sensorModule(detId + 1);
0628     const double sigma = pow(sm->pitchCol() * sm->tiltCorrection(cot), 2) / 12.;
0629     const double digi = pow(tmttBaseZ_ / 12., 2);
0630     return sigma + digi;
0631   }
0632 
0633   // checks if stub collection is considered forming a reconstructable track
0634   bool Setup::reconstructable(const vector<TTStubRef>& ttStubRefs) const {
0635     set<int> hitPattern;
0636     for (const TTStubRef& ttStubRef : ttStubRefs)
0637       hitPattern.insert(layerId(ttStubRef));
0638     return (int)hitPattern.size() >= tpMinLayers_;
0639   }
0640 
0641   // checks if tracking particle is selected for efficiency measurements
0642   bool Setup::useForAlgEff(const TrackingParticle& tp) const {
0643     const bool selected = tpSelector_(tp);
0644     const double cot = sinh(tp.eta());
0645     const double s = sin(tp.phi());
0646     const double c = cos(tp.phi());
0647     const TrackingParticle::Point& v = tp.vertex();
0648     const double z0 = v.z() - (v.x() * c + v.y() * s) * cot;
0649     const double d0 = v.x() * s - v.y() * c;
0650     return selected && (abs(d0) < tpMaxD0_) && (abs(z0) < tpMaxVertZ_);
0651   }
0652 
0653   // derive constants
0654   void Setup::calculateConstants() {
0655     // emp
0656     const int numFramesPerBX = freqBE_ / freqLHC_;
0657     numFrames_ = numFramesPerBX * tmpTFP_ - 1;
0658     numFramesIO_ = numFramesPerBX * tmpTFP_ - numFramesInfra_;
0659     numFramesFE_ = numFramesPerBX * tmpFE_ - numFramesInfra_;
0660     // dsp
0661     widthDSPab_ = widthDSPa_ - 1;
0662     widthDSPau_ = widthDSPab_ - 1;
0663     widthDSPbb_ = widthDSPb_ - 1;
0664     widthDSPbu_ = widthDSPbb_ - 1;
0665     widthDSPcb_ = widthDSPc_ - 1;
0666     widthDSPcu_ = widthDSPcb_ - 1;
0667     // firmware
0668     maxPitch_ = max(pitchPS_, pitch2S_);
0669     maxLength_ = max(lengthPS_, length2S_);
0670     // common track finding
0671     invPtToDphi_ = speedOfLight_ * bField_ / 2000.;
0672     baseRegion_ = 2. * M_PI / numRegions_;
0673     // gp
0674     baseSector_ = baseRegion_ / numSectorsPhi_;
0675     maxCot_ = sinh(maxEta_);
0676     maxZT_ = maxCot_ * chosenRofZ_;
0677     numSectorsEta_ = boundariesEta_.size() - 1;
0678     numSectors_ = numSectorsPhi_ * numSectorsEta_;
0679     sectorCots_.reserve(numSectorsEta_);
0680     for (int eta = 0; eta < numSectorsEta_; eta++)
0681       sectorCots_.emplace_back((sinh(boundariesEta_.at(eta)) + sinh(boundariesEta_.at(eta + 1))) / 2.);
0682     // tmtt
0683     const double rangeInv2R = 2. * invPtToDphi_ / minPt_;
0684     tmttBaseInv2R_ = rangeInv2R / htNumBinsInv2R_;
0685     tmttBasePhiT_ = baseSector_ / htNumBinsPhiT_;
0686     const double baseRgen = tmttBasePhiT_ / tmttBaseInv2R_;
0687     const double rangeR = 2. * max(abs(outerRadius_ - chosenRofPhi_), abs(innerRadius_ - chosenRofPhi_));
0688     const int baseShiftR = ceil(log2(rangeR / baseRgen / pow(2., tmttWidthR_)));
0689     tmttBaseR_ = baseRgen * pow(2., baseShiftR);
0690     const double rangeZ = 2. * halfLength_;
0691     const int baseShiftZ = ceil(log2(rangeZ / tmttBaseR_ / pow(2., tmttWidthZ_)));
0692     tmttBaseZ_ = tmttBaseR_ * pow(2., baseShiftZ);
0693     const double rangePhi = baseRegion_ + rangeInv2R * rangeR / 2.;
0694     const int baseShiftPhi = ceil(log2(rangePhi / tmttBasePhiT_ / pow(2., tmttWidthPhi_)));
0695     tmttBasePhi_ = tmttBasePhiT_ * pow(2., baseShiftPhi);
0696     tmttWidthLayer_ = ceil(log2(numLayers_));
0697     tmttWidthSectorEta_ = ceil(log2(numSectorsEta_));
0698     tmttWidthInv2R_ = ceil(log2(htNumBinsInv2R_));
0699     tmttNumUnusedBits_ = TTBV::S_ - tmttWidthLayer_ - 2 * tmttWidthSectorEta_ - tmttWidthR_ - tmttWidthPhi_ -
0700                          tmttWidthZ_ - 2 * tmttWidthInv2R_ - numSectorsPhi_ - 1;
0701     // hybrid
0702     const double hybridRangeInv2R = 2. * invPtToDphi_ / hybridMinPtStub_;
0703     const double hybridRangeR =
0704         2. * max(abs(outerRadius_ - hybridChosenRofPhi_), abs(innerRadius_ - hybridChosenRofPhi_));
0705     hybridRangePhi_ = baseRegion_ + (hybridRangeR * hybridRangeInv2R) / 2.;
0706     hybridWidthLayerId_ = ceil(log2(hybridNumLayers_));
0707     hybridBasesZ_.reserve(SensorModule::NumTypes);
0708     for (int type = 0; type < SensorModule::NumTypes; type++)
0709       hybridBasesZ_.emplace_back(hybridRangesZ_.at(type) / pow(2., hybridWidthsZ_.at(type)));
0710     hybridBasesR_.reserve(SensorModule::NumTypes);
0711     for (int type = 0; type < SensorModule::NumTypes; type++)
0712       hybridBasesR_.emplace_back(hybridRangesR_.at(type) / pow(2., hybridWidthsR_.at(type)));
0713     hybridBasesR_[SensorModule::Disk2S] = 1.;
0714     hybridBasesPhi_.reserve(SensorModule::NumTypes);
0715     for (int type = 0; type < SensorModule::NumTypes; type++)
0716       hybridBasesPhi_.emplace_back(hybridRangePhi_ / pow(2., hybridWidthsPhi_.at(type)));
0717     hybridBasesAlpha_.reserve(SensorModule::NumTypes);
0718     for (int type = 0; type < SensorModule::NumTypes; type++)
0719       hybridBasesAlpha_.emplace_back(hybridRangesAlpha_.at(type) / pow(2., hybridWidthsAlpha_.at(type)));
0720     hybridNumsUnusedBits_.reserve(SensorModule::NumTypes);
0721     for (int type = 0; type < SensorModule::NumTypes; type++)
0722       hybridNumsUnusedBits_.emplace_back(TTBV::S_ - hybridWidthsR_.at(type) - hybridWidthsZ_.at(type) -
0723                                          hybridWidthsPhi_.at(type) - hybridWidthsAlpha_.at(type) -
0724                                          hybridWidthsBend_.at(type) - hybridWidthLayerId_ - 1);
0725     hybridMaxCot_ = sinh(hybridMaxEta_);
0726     disk2SRs_.reserve(hybridDisk2SRsSet_.size());
0727     for (const auto& pSet : hybridDisk2SRsSet_)
0728       disk2SRs_.emplace_back(pSet.getParameter<vector<double>>("Disk2SRs"));
0729     // dtc
0730     numDTCs_ = numRegions_ * numDTCsPerRegion_;
0731     numDTCsPerTFP_ = numDTCsPerRegion_ * numOverlappingRegions_;
0732     numModules_ = numDTCs_ * numModulesPerDTC_;
0733     dtcNumModulesPerRoutingBlock_ = numModulesPerDTC_ / dtcNumRoutingBlocks_;
0734     dtcNumMergedRows_ = pow(2, widthRow_ - dtcWidthRowLUT_);
0735     const double maxRangeInv2R = max(rangeInv2R, hybridRangeInv2R);
0736     const int baseShiftInv2R = ceil(log2(htNumBinsInv2R_)) - dtcWidthInv2R_ + ceil(log2(maxRangeInv2R / rangeInv2R));
0737     dtcBaseInv2R_ = tmttBaseInv2R_ * pow(2., baseShiftInv2R);
0738     const int baseDiffM = dtcWidthRowLUT_ - widthRow_;
0739     dtcBaseM_ = tmttBasePhi_ * pow(2., baseDiffM);
0740     const double x1 = pow(2, widthRow_) * baseRow_ * maxPitch_ / 2.;
0741     const double x0 = x1 - pow(2, dtcWidthRowLUT_) * baseRow_ * maxPitch_;
0742     const double maxM = atan2(x1, innerRadius_) - atan2(x0, innerRadius_);
0743     dtcWidthM_ = ceil(log2(maxM / dtcBaseM_));
0744     dtcNumStreams_ = numDTCs_ * numOverlappingRegions_;
0745     // mht
0746     mhtNumCells_ = mhtNumBinsInv2R_ * mhtNumBinsPhiT_;
0747     // zht
0748     zhtNumCells_ = zhtNumBinsCot_ * zhtNumBinsZT_;
0749     //
0750     kfWidthLayerCount_ = ceil(log2(zhtMaxStubsPerLayer_));
0751   }
0752 
0753   // returns bit accurate hybrid stub radius for given TTStubRef and h/w bit word
0754   double Setup::stubR(const TTBV& hw, const TTStubRef& ttStubRef) const {
0755     const bool barrel = this->barrel(ttStubRef);
0756     const int layerId = this->indexLayerId(ttStubRef);
0757     const SensorModule::Type type = this->type(ttStubRef);
0758     const int widthR = hybridWidthsR_.at(type);
0759     const double baseR = hybridBasesR_.at(type);
0760     const TTBV hwR(hw, widthR, 0, barrel);
0761     double r = hwR.val(baseR) + (barrel ? hybridLayerRs_.at(layerId) : 0.);
0762     if (type == SensorModule::Disk2S)
0763       r = disk2SRs_.at(layerId).at((int)r);
0764     return r;
0765   }
0766 
0767   // returns bit accurate position of a stub from a given tfp region [0-8]
0768   GlobalPoint Setup::stubPos(bool hybrid, const FrameStub& frame, int region) const {
0769     GlobalPoint p;
0770     if (frame.first.isNull())
0771       return p;
0772     TTBV bv(frame.second);
0773     if (hybrid) {
0774       const bool barrel = this->barrel(frame.first);
0775       const int layerId = this->indexLayerId(frame.first);
0776       const GlobalPoint gp = this->stubPos(frame.first);
0777       const bool side = gp.z() > 0.;
0778       const SensorModule::Type type = this->type(frame.first);
0779       const int widthBend = hybridWidthsBend_.at(type);
0780       const int widthAlpha = hybridWidthsAlpha_.at(type);
0781       const int widthPhi = hybridWidthsPhi_.at(type);
0782       const int widthZ = hybridWidthsZ_.at(type);
0783       const int widthR = hybridWidthsR_.at(type);
0784       const double basePhi = hybridBasesPhi_.at(type);
0785       const double baseZ = hybridBasesZ_.at(type);
0786       const double baseR = hybridBasesR_.at(type);
0787       // parse bit vector
0788       bv >>= 1 + hybridWidthLayerId_ + widthBend + widthAlpha;
0789       double phi = bv.val(basePhi, widthPhi) - hybridRangePhi_ / 2.;
0790       bv >>= widthPhi;
0791       double z = bv.val(baseZ, widthZ, 0, true);
0792       bv >>= widthZ;
0793       double r = bv.val(baseR, widthR, 0, barrel);
0794       if (barrel)
0795         r += hybridLayerRs_.at(layerId);
0796       else
0797         z += hybridDiskZs_.at(layerId) * (side ? 1. : -1.);
0798       phi = deltaPhi(phi + region * baseRegion_);
0799       if (type == SensorModule::Disk2S) {
0800         r = bv.val(widthR);
0801         r = disk2SRs_.at(layerId).at((int)r);
0802       }
0803       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0804     } else {
0805       bv >>= 2 * tmttWidthInv2R_ + 2 * tmttWidthSectorEta_ + numSectorsPhi_ + tmttWidthLayer_;
0806       double z = (bv.val(tmttWidthZ_, 0, true) + .5) * tmttBaseZ_;
0807       bv >>= tmttWidthZ_;
0808       double phi = (bv.val(tmttWidthPhi_, 0, true) + .5) * tmttBasePhi_;
0809       bv >>= tmttWidthPhi_;
0810       double r = (bv.val(tmttWidthR_, 0, true) + .5) * tmttBaseR_;
0811       bv >>= tmttWidthR_;
0812       r = r + chosenRofPhi_;
0813       phi = deltaPhi(phi + region * baseRegion_);
0814       p = GlobalPoint(GlobalPoint::Cylindrical(r, phi, z));
0815     }
0816     return p;
0817   }
0818 
0819   // returns global TTStub position
0820   GlobalPoint Setup::stubPos(const TTStubRef& ttStubRef) const {
0821     const DetId detId = ttStubRef->getDetId() + offsetDetIdDSV_;
0822     const GeomDetUnit* det = trackerGeometry_->idToDetUnit(detId);
0823     const PixelTopology* topol =
0824         dynamic_cast<const PixelTopology*>(&(dynamic_cast<const PixelGeomDetUnit*>(det)->specificTopology()));
0825     const Plane& plane = dynamic_cast<const PixelGeomDetUnit*>(det)->surface();
0826     const MeasurementPoint& mp = ttStubRef->clusterRef(0)->findAverageLocalCoordinatesCentered();
0827     return plane.toGlobal(topol->localPosition(mp));
0828   }
0829 
0830   // range check of dtc id
0831   void Setup::checkDTCId(int dtcId) const {
0832     if (dtcId < 0 || dtcId >= numDTCsPerRegion_ * numRegions_) {
0833       cms::Exception exception("out_of_range");
0834       exception.addContext("tt::Setup::checkDTCId");
0835       exception << "Used DTC Id (" << dtcId << ") "
0836                 << "is out of range 0 to " << numDTCsPerRegion_ * numRegions_ - 1 << ".";
0837       throw exception;
0838     }
0839   }
0840 
0841   // range check of tklayout id
0842   void Setup::checkTKLayoutId(int tkLayoutId) const {
0843     if (tkLayoutId <= 0 || tkLayoutId > numDTCsPerRegion_ * numRegions_) {
0844       cms::Exception exception("out_of_range");
0845       exception.addContext("tt::Setup::checkTKLayoutId");
0846       exception << "Used TKLayout Id (" << tkLayoutId << ") "
0847                 << "is out of range 1 to " << numDTCsPerRegion_ * numRegions_ << ".";
0848       throw exception;
0849     }
0850   }
0851 
0852   // range check of tfp identifier
0853   void Setup::checkTFPIdentifier(int tfpRegion, int tfpChannel) const {
0854     const bool oorRegion = tfpRegion >= numRegions_ || tfpRegion < 0;
0855     const bool oorChannel = tfpChannel >= numDTCsPerTFP_ || tfpChannel < 0;
0856     if (oorRegion || oorChannel) {
0857       cms::Exception exception("out_of_range");
0858       exception.addContext("tt::Setup::checkTFPIdentifier");
0859       if (oorRegion)
0860         exception << "Requested Processing Region "
0861                   << "(" << tfpRegion << ") "
0862                   << "is out of range 0 to " << numRegions_ - 1 << ".";
0863       if (oorChannel)
0864         exception << "Requested TFP Channel "
0865                   << "(" << tfpChannel << ") "
0866                   << "is out of range 0 to " << numDTCsPerTFP_ - 1 << ".";
0867       throw exception;
0868     }
0869   }
0870 }  // namespace tt